support dimension bindings in cross-origin mode (#2989)

pull/4704/head
Maurício Kishi 4 years ago committed by GitHub
parent cc3c7fa9f4
commit ff5f25249e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -586,7 +586,7 @@ export default class ElementWrapper extends Wrapper {
);
block.chunks.destroy.push(
b`${resize_listener}.cancel();`
b`${resize_listener}();`
);
} else {
block.event_listeners.push(

@ -57,7 +57,7 @@ export function empty() {
return text('');
}
export function listen(node: Node, event: string, handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | EventListenerOptions) {
export function listen(node: EventTarget, event: string, handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | EventListenerOptions) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
@ -234,37 +234,61 @@ export function select_multiple_value(select) {
return [].map.call(select.querySelectorAll(':checked'), option => option.__value);
}
export function add_resize_listener(element, fn) {
if (getComputedStyle(element).position === 'static') {
element.style.position = 'relative';
// unfortunately this can't be a constant as that wouldn't be tree-shakeable
// so we cache the result instead
let crossorigin: boolean;
export function is_crossorigin() {
if (crossorigin === undefined) {
crossorigin = false;
try {
if (typeof window !== 'undefined' && window.parent) {
void window.parent.document;
}
} catch (error) {
crossorigin = true;
}
}
const object = document.createElement('object');
object.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;');
object.setAttribute('aria-hidden', 'true');
object.type = 'text/html';
object.tabIndex = -1;
return crossorigin;
}
let win;
export function add_resize_listener(node: HTMLElement, fn: () => void) {
const computed_style = getComputedStyle(node);
const z_index = (parseInt(computed_style.zIndex) || 0) - 1;
object.onload = () => {
win = object.contentDocument.defaultView;
win.addEventListener('resize', fn);
};
if (computed_style.position === 'static') {
node.style.position = 'relative';
}
if (/Trident/.test(navigator.userAgent)) {
element.appendChild(object);
object.data = 'about:blank';
const iframe = element('iframe');
iframe.setAttribute('style',
`display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; ` +
`overflow: hidden; border: 0; opacity: 0; pointer-events: none; z-index: ${z_index};`
);
iframe.setAttribute('aria-hidden', 'true');
iframe.tabIndex = -1;
let unsubscribe: () => void;
if (is_crossorigin()) {
iframe.src = `data:text/html,<script>onresize=function(){parent.postMessage(0,'*')}</script>`;
unsubscribe = listen(window, 'message', (event: MessageEvent) => {
if (event.source === iframe.contentWindow) fn();
});
} else {
object.data = 'about:blank';
element.appendChild(object);
iframe.src = 'about:blank';
iframe.onload = () => {
unsubscribe = listen(iframe.contentWindow, 'resize', fn);
};
}
return {
cancel: () => {
win && win.removeEventListener && win.removeEventListener('resize', fn);
element.removeChild(object);
}
append(node, iframe);
return () => {
detach(iframe);
if (unsubscribe) unsubscribe();
};
}
@ -316,4 +340,4 @@ export class HtmlTag {
d() {
this.n.forEach(detach);
}
}
}

@ -30,7 +30,7 @@ function create_fragment(ctx) {
o: noop,
d(detaching) {
if (detaching) detach(div);
div_resize_listener.cancel();
div_resize_listener();
}
};
}

@ -59,7 +59,7 @@ function create_fragment(ctx) {
o: noop,
d(detaching) {
if (detaching) detach(video);
video_resize_listener.cancel();
video_resize_listener();
run_all(dispose);
}
};

@ -1,8 +1,8 @@
export default {
async test({ assert, target }) {
const object = target.querySelector('object');
const iframe = target.querySelector('iframe');
assert.equal(object.getAttribute('aria-hidden'), "true");
assert.equal(object.getAttribute('tabindex'), "-1");
assert.equal(iframe.getAttribute('aria-hidden'), "true");
assert.equal(iframe.getAttribute('tabindex'), "-1");
}
};

Loading…
Cancel
Save