mirror of https://github.com/sveltejs/svelte
add a <svelte:document> tag - #1484
parent
d1f35dfd85
commit
db37e3a84b
@ -0,0 +1,23 @@
|
|||||||
|
import Node from './shared/Node';
|
||||||
|
import EventHandler from './EventHandler';
|
||||||
|
|
||||||
|
export default class Document extends Node {
|
||||||
|
type: 'Document';
|
||||||
|
handlers: EventHandler[];
|
||||||
|
|
||||||
|
constructor(component, parent, scope, info) {
|
||||||
|
super(component, parent, scope, info);
|
||||||
|
|
||||||
|
this.handlers = [];
|
||||||
|
|
||||||
|
info.attributes.forEach(node => {
|
||||||
|
if (node.type === 'EventHandler') {
|
||||||
|
this.handlers.push(new EventHandler(component, this, scope, node));
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// TODO there shouldn't be anything else here...
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
import Renderer from '../Renderer';
|
||||||
|
import Block from '../Block';
|
||||||
|
import Node from '../../nodes/shared/Node';
|
||||||
|
import Wrapper from './shared/Wrapper';
|
||||||
|
import deindent from '../../../utils/deindent';
|
||||||
|
import Document from '../../nodes/Document';
|
||||||
|
|
||||||
|
export default class DocumentWrapper extends Wrapper {
|
||||||
|
node: Document;
|
||||||
|
|
||||||
|
constructor(renderer: Renderer, block: Block, parent: Wrapper, node: Node) {
|
||||||
|
super(renderer, block, parent, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(block: Block, parentNode: string, parentNodes: string) {
|
||||||
|
const { renderer } = this;
|
||||||
|
const { component } = renderer;
|
||||||
|
|
||||||
|
this.node.handlers.forEach(handler => {
|
||||||
|
// TODO verify that it's a valid callee (i.e. built-in or declared method)
|
||||||
|
component.addSourcemapLocations(handler.expression);
|
||||||
|
|
||||||
|
const isCustomEvent = component.events.has(handler.name);
|
||||||
|
|
||||||
|
let usesState = handler.dependencies.size > 0;
|
||||||
|
|
||||||
|
handler.render(component, block, 'document', false); // TODO hoist?
|
||||||
|
|
||||||
|
const handlerName = block.getUniqueName(`onwindow${handler.name}`);
|
||||||
|
const handlerBody = deindent`
|
||||||
|
${usesState && `var ctx = #component.get();`}
|
||||||
|
${handler.snippet};
|
||||||
|
`;
|
||||||
|
|
||||||
|
if (isCustomEvent) {
|
||||||
|
// TODO dry this out
|
||||||
|
block.addVariable(handlerName);
|
||||||
|
|
||||||
|
block.builders.hydrate.addBlock(deindent`
|
||||||
|
${handlerName} = %events-${handler.name}.call(#component, document, function(event) {
|
||||||
|
${handlerBody}
|
||||||
|
});
|
||||||
|
`);
|
||||||
|
|
||||||
|
block.builders.destroy.addLine(deindent`
|
||||||
|
${handlerName}.destroy();
|
||||||
|
`);
|
||||||
|
} else {
|
||||||
|
block.builders.init.addBlock(deindent`
|
||||||
|
function ${handlerName}(event) {
|
||||||
|
${handlerBody}
|
||||||
|
}
|
||||||
|
document.addEventListener("${handler.name}", ${handlerName});
|
||||||
|
`);
|
||||||
|
|
||||||
|
block.builders.destroy.addBlock(deindent`
|
||||||
|
document.removeEventListener("${handler.name}", ${handlerName});
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
export default {
|
||||||
|
test(assert, component, target, window) {
|
||||||
|
assert.equal(component.get().events.toString(), '');
|
||||||
|
const event1 = new window.Event('mouseenter');
|
||||||
|
window.document.dispatchEvent(event1);
|
||||||
|
assert.equal(component.get().events.toString(), 'enter');
|
||||||
|
const event2 = new window.Event('mouseleave');
|
||||||
|
window.document.dispatchEvent(event2);
|
||||||
|
assert.equal(component.get().events.toString(), 'enter,leave');
|
||||||
|
},
|
||||||
|
};
|
@ -0,0 +1,12 @@
|
|||||||
|
<svelte:document on:mouseenter='log("enter")' on:mouseleave='log("leave")'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data: () => ({ events: [] }),
|
||||||
|
methods: {
|
||||||
|
log(event) {
|
||||||
|
this.set({ events: this.get().events.concat(event) });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
Reference in new issue