* Handles element mutation (and measurement) APIs in the Resources system. * * @param {!Element} element * @param {?function()} measurer * @param {function()} mutator * @param {boolean} skipRemeasure * @return {!Promise}
(
element,
measurer,
mutator,
skipRemeasure = false
)
| 178 | * @return {!Promise} |
| 179 | */ |
| 180 | measureMutateElementResources_( |
| 181 | element, |
| 182 | measurer, |
| 183 | mutator, |
| 184 | skipRemeasure = false |
| 185 | ) { |
| 186 | const calcRelayoutTop = () => { |
| 187 | const box = this.viewport_.getLayoutRect(element); |
| 188 | if (box.width != 0 && box.height != 0) { |
| 189 | return box.top; |
| 190 | } |
| 191 | return -1; |
| 192 | }; |
| 193 | let relayoutTop = -1; |
| 194 | // TODO(jridgewell): support state |
| 195 | return this.vsync_.runPromise({ |
| 196 | measure: () => { |
| 197 | if (measurer) { |
| 198 | measurer(); |
| 199 | } |
| 200 | |
| 201 | if (!skipRemeasure) { |
| 202 | relayoutTop = calcRelayoutTop(); |
| 203 | } |
| 204 | }, |
| 205 | mutate: () => { |
| 206 | mutator(); |
| 207 | |
| 208 | // `skipRemeasure` is set by callers when we know that `mutator` |
| 209 | // cannot cause a change in size/position e.g. toggleLoading(). |
| 210 | if (skipRemeasure) { |
| 211 | return; |
| 212 | } |
| 213 | |
| 214 | if (element.classList.contains('i-amphtml-element')) { |
| 215 | const r = Resource.forElement(element); |
| 216 | r.requestMeasure(); |
| 217 | } |
| 218 | const ampElements = element.getElementsByClassName('i-amphtml-element'); |
| 219 | for (let i = 0; i < ampElements.length; i++) { |
| 220 | const r = Resource.forElement(ampElements[i]); |
| 221 | r.requestMeasure(); |
| 222 | } |
| 223 | this.resources_.schedulePass(FOUR_FRAME_DELAY_); |
| 224 | |
| 225 | if (relayoutTop != -1) { |
| 226 | this.resources_.setRelayoutTop(relayoutTop); |
| 227 | } |
| 228 | // Need to measure again in case the element has become visible or |
| 229 | // shifted. |
| 230 | this.vsync_.measure(() => { |
| 231 | const updatedRelayoutTop = calcRelayoutTop(); |
| 232 | if (updatedRelayoutTop != -1 && updatedRelayoutTop != relayoutTop) { |
| 233 | this.resources_.setRelayoutTop(updatedRelayoutTop); |
| 234 | this.resources_.schedulePass(FOUR_FRAME_DELAY_); |
| 235 | } |
| 236 | this.resources_.maybeHeightChanged(); |
| 237 | }); |
no test coverage detected