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( block.chunks.destroy.push(
b`${resize_listener}.cancel();` b`${resize_listener}();`
); );
} else { } else {
block.event_listeners.push( block.event_listeners.push(

@ -57,7 +57,7 @@ export function empty() {
return text(''); 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); node.addEventListener(event, handler, options);
return () => node.removeEventListener(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); return [].map.call(select.querySelectorAll(':checked'), option => option.__value);
} }
export function add_resize_listener(element, fn) { // unfortunately this can't be a constant as that wouldn't be tree-shakeable
if (getComputedStyle(element).position === 'static') { // so we cache the result instead
element.style.position = 'relative'; 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'); return crossorigin;
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;
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 = () => { if (computed_style.position === 'static') {
win = object.contentDocument.defaultView; node.style.position = 'relative';
win.addEventListener('resize', fn); }
};
if (/Trident/.test(navigator.userAgent)) { const iframe = element('iframe');
element.appendChild(object); iframe.setAttribute('style',
object.data = 'about:blank'; `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 { } else {
object.data = 'about:blank'; iframe.src = 'about:blank';
element.appendChild(object); iframe.onload = () => {
unsubscribe = listen(iframe.contentWindow, 'resize', fn);
};
} }
return { append(node, iframe);
cancel: () => {
win && win.removeEventListener && win.removeEventListener('resize', fn); return () => {
element.removeChild(object); detach(iframe);
} if (unsubscribe) unsubscribe();
}; };
} }
@ -316,4 +340,4 @@ export class HtmlTag {
d() { d() {
this.n.forEach(detach); this.n.forEach(detach);
} }
} }

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

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

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

Loading…
Cancel
Save