Convert src/compiler/compile/render_dom/Block.ts to JavaScript

pull/8569/head
Simon Holthausen 3 years ago
parent f241b93ef3
commit da35939361

@ -1,385 +1,393 @@
import Renderer, { BindingGroup } from './Renderer';
import Wrapper from './wrappers/shared/Wrapper';
import { b, x } from 'code-red'; import { b, x } from 'code-red';
import { Node, Identifier, ArrayPattern } from 'estree'; import { is_head } from './wrappers/shared/is_head.js';
import { is_head } from './wrappers/shared/is_head'; import { regex_double_quotes } from '../../utils/patterns.js';
import { regex_double_quotes } from '../../utils/patterns';
export interface Bindings {
object: Identifier;
property: Identifier;
snippet: Node;
store: string;
modifier: (node: Node) => Node;
}
export interface BlockOptions {
parent?: Block;
name: Identifier;
type: string;
renderer?: Renderer;
comment?: string;
key?: Identifier;
bindings?: Map<string, Bindings>;
dependencies?: Set<string>;
}
export default class Block { export default class Block {
parent?: Block;
renderer: Renderer; /** @type {Block} */
name: Identifier; parent;
type: string;
comment?: string; /** @type {import('./Renderer.js').default} */
renderer;
wrappers: Wrapper[];
/** @type {import('estree').Identifier} */
key: Identifier; name;
first: Identifier;
/** @type {string} */
dependencies: Set<string> = new Set(); type;
bindings: Map<string, Bindings>; /** @type {string} */
binding_group_initialised: Set<string> = new Set(); comment;
binding_groups: Set<BindingGroup> = new Set();
/** @type {import('./wrappers/shared/Wrapper.js').default[]} */
chunks: { wrappers;
declarations: Array<Node | Node[]>;
init: Array<Node | Node[]>; /** @type {import('estree').Identifier} */
create: Array<Node | Node[]>; key;
claim: Array<Node | Node[]>;
hydrate: Array<Node | Node[]>; /** @type {import('estree').Identifier} */
mount: Array<Node | Node[]>; first;
measure: Array<Node | Node[]>;
restore_measurements: Array<Node | Node[]>; /** @type {Set<string>} */
fix: Array<Node | Node[]>; dependencies = new Set();
animate: Array<Node | Node[]>;
intro: Array<Node | Node[]>; /** @type {Map<string, Bindings>} */
update: Array<Node | Node[]>; bindings;
outro: Array<Node | Node[]>;
destroy: Array<Node | Node[]>; /** @type {Set<string>} */
}; binding_group_initialised = new Set();
event_listeners: Node[] = []; /** @type {Set<import('./Renderer.js').BindingGroup>} */
binding_groups = new Set();
maintain_context: boolean; /**
has_animation: boolean; * @type {{
has_intros: boolean; * declarations: Array<import('estree').Node | import('estree').Node[]>;
has_outros: boolean; * init: Array<import('estree').Node | import('estree').Node[]>;
has_intro_method: boolean; // could have the method without the transition, due to siblings * create: Array<import('estree').Node | import('estree').Node[]>;
has_outro_method: boolean; * claim: Array<import('estree').Node | import('estree').Node[]>;
outros: number; * hydrate: Array<import('estree').Node | import('estree').Node[]>;
* mount: Array<import('estree').Node | import('estree').Node[]>;
aliases: Map<string, Identifier>; * measure: Array<import('estree').Node | import('estree').Node[]>;
variables: Map<string, { id: Identifier; init?: Node }> = new Map(); * restore_measurements: Array<import('estree').Node | import('estree').Node[]>;
get_unique_name: (name: string) => Identifier; * fix: Array<import('estree').Node | import('estree').Node[]>;
* animate: Array<import('estree').Node | import('estree').Node[]>;
has_update_method = false; * intro: Array<import('estree').Node | import('estree').Node[]>;
autofocus?: { element_var: string; condition_expression?: any }; * update: Array<import('estree').Node | import('estree').Node[]>;
* outro: Array<import('estree').Node | import('estree').Node[]>;
constructor(options: BlockOptions) { * destroy: Array<import('estree').Node | import('estree').Node[]>;
this.parent = options.parent; * }}
this.renderer = options.renderer; */
this.name = options.name; chunks;
this.type = options.type;
this.comment = options.comment; /** @type {import('estree').Node[]} */
event_listeners = [];
this.wrappers = [];
/** @type {boolean} */
// for keyed each blocks maintain_context;
this.key = options.key;
this.first = null; /** @type {boolean} */
has_animation;
this.bindings = options.bindings;
/** @type {boolean} */
this.chunks = { has_intros;
declarations: [],
init: [], /** @type {boolean} */
create: [], has_outros;
claim: [],
hydrate: [], /** @type {boolean} */
mount: [], has_intro_method; // could have the method without the transition, due to siblings
measure: [],
restore_measurements: [], /** @type {boolean} */
fix: [], has_outro_method;
animate: [],
intro: [], /** @type {number} */
update: [], outros;
outro: [],
destroy: [] /** @type {Map<string, import('estree').Identifier>} */
}; aliases;
this.has_animation = false; /** @type {Map<string, { id: import('estree').Identifier; init?: import('estree').Node }>} */
this.has_intro_method = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros variables = new Map();
this.has_outro_method = false;
this.outros = 0; /** @type {(name: string) => import('estree').Identifier} */
get_unique_name;
this.get_unique_name = this.renderer.component.get_unique_name_maker(); /** */
has_update_method = false;
this.aliases = new Map();
if (this.key) this.aliases.set('key', this.get_unique_name('key')); /** @type {{ element_var: string; condition_expression?: any }} */
} autofocus;
assign_variable_names() { /** @param {BlockOptions} options */
const seen: Set<string> = new Set(); constructor(options) {
const dupes: Set<string> = new Set(); this.parent = options.parent;
this.renderer = options.renderer;
let i = this.wrappers.length; this.name = options.name;
this.type = options.type;
while (i--) { this.comment = options.comment;
const wrapper = this.wrappers[i]; this.wrappers = [];
// for keyed each blocks
if (!wrapper.var) continue; this.key = options.key;
this.first = null;
if (seen.has(wrapper.var.name)) { this.bindings = options.bindings;
dupes.add(wrapper.var.name); this.chunks = {
} declarations: [],
init: [],
seen.add(wrapper.var.name); create: [],
} claim: [],
hydrate: [],
const counts = new Map(); mount: [],
i = this.wrappers.length; measure: [],
restore_measurements: [],
while (i--) { fix: [],
const wrapper = this.wrappers[i]; animate: [],
intro: [],
if (!wrapper.var) continue; update: [],
outro: [],
let suffix = ''; destroy: []
if (dupes.has(wrapper.var.name)) { };
const i = counts.get(wrapper.var.name) || 0; this.has_animation = false;
counts.set(wrapper.var.name, i + 1); this.has_intro_method = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros
suffix = i; this.has_outro_method = false;
} this.outros = 0;
wrapper.var.name = this.get_unique_name(wrapper.var.name + suffix).name; this.get_unique_name = this.renderer.component.get_unique_name_maker();
} this.aliases = new Map();
} if (this.key)
this.aliases.set('key', this.get_unique_name('key'));
add_dependencies(dependencies: Set<string>) { }
dependencies.forEach((dependency) => { assign_variable_names() {
this.dependencies.add(dependency);
}); /** @type {Set<string>} */
const seen = new Set();
this.has_update_method = true;
if (this.parent) { /** @type {Set<string>} */
this.parent.add_dependencies(dependencies); const dupes = new Set();
} let i = this.wrappers.length;
} while (i--) {
const wrapper = this.wrappers[i];
add_element( if (!wrapper.var)
id: Identifier, continue;
render_statement: Node, if (seen.has(wrapper.var.name)) {
claim_statement: Node, dupes.add(wrapper.var.name);
parent_node: Node, }
no_detach?: boolean seen.add(wrapper.var.name);
) { }
this.add_variable(id); const counts = new Map();
this.chunks.create.push(b`${id} = ${render_statement};`); i = this.wrappers.length;
while (i--) {
if (this.renderer.options.hydratable) { const wrapper = this.wrappers[i];
this.chunks.claim.push(b`${id} = ${claim_statement || render_statement};`); if (!wrapper.var)
} continue;
let suffix = '';
if (parent_node) { if (dupes.has(wrapper.var.name)) {
this.chunks.mount.push(b`@append(${parent_node}, ${id});`); const i = counts.get(wrapper.var.name) || 0;
if (is_head(parent_node) && !no_detach) this.chunks.destroy.push(b`@detach(${id});`); counts.set(wrapper.var.name, i + 1);
} else { suffix = i;
this.chunks.mount.push(b`@insert(#target, ${id}, #anchor);`); }
if (!no_detach) this.chunks.destroy.push(b`if (detaching) @detach(${id});`); wrapper.var.name = this.get_unique_name(wrapper.var.name + suffix).name;
} }
} }
add_intro(local?: boolean) { /** @param {Set<string>} dependencies */
this.has_intros = this.has_intro_method = true; add_dependencies(dependencies) {
if (!local && this.parent) this.parent.add_intro(); dependencies.forEach((dependency) => {
} this.dependencies.add(dependency);
});
add_outro(local?: boolean) { this.has_update_method = true;
this.has_outros = this.has_outro_method = true; if (this.parent) {
this.outros += 1; this.parent.add_dependencies(dependencies);
if (!local && this.parent) this.parent.add_outro(); }
} }
add_animation() { /**
this.has_animation = true; * @param {import('estree').Identifier} id
} * @param {import('estree').Node} render_statement
* @param {import('estree').Node} claim_statement
add_variable(id: Identifier, init?: Node) { * @param {import('estree').Node} parent_node
if (this.variables.has(id.name)) { * @param {boolean} [no_detach]
throw new Error(`Variable '${id.name}' already initialised with a different value`); */
} add_element(id, render_statement, claim_statement, parent_node, no_detach) {
this.add_variable(id);
this.variables.set(id.name, { id, init }); this.chunks.create.push(b `${id} = ${render_statement};`);
} if (this.renderer.options.hydratable) {
this.chunks.claim.push(b `${id} = ${claim_statement || render_statement};`);
alias(name: string) { }
if (!this.aliases.has(name)) { if (parent_node) {
this.aliases.set(name, this.get_unique_name(name)); this.chunks.mount.push(b `@append(${parent_node}, ${id});`);
} if (is_head(parent_node) && !no_detach)
this.chunks.destroy.push(b `@detach(${id});`);
return this.aliases.get(name); }
} else {
this.chunks.mount.push(b `@insert(#target, ${id}, #anchor);`);
child(options: BlockOptions) { if (!no_detach)
return new Block(Object.assign({}, this, { key: null }, options, { parent: this })); this.chunks.destroy.push(b `if (detaching) @detach(${id});`);
} }
}
get_contents(key?: any) {
const { dev } = this.renderer.options; /** @param {boolean} [local] */
add_intro(local) {
if (this.has_outros) { this.has_intros = this.has_intro_method = true;
this.add_variable({ type: 'Identifier', name: '#current' }); if (!local && this.parent)
this.parent.add_intro();
if (this.chunks.intro.length > 0) { }
this.chunks.intro.push(b`#current = true;`);
this.chunks.mount.push(b`#current = true;`); /** @param {boolean} [local] */
} add_outro(local) {
this.has_outros = this.has_outro_method = true;
if (this.chunks.outro.length > 0) { this.outros += 1;
this.chunks.outro.push(b`#current = false;`); if (!local && this.parent)
} this.parent.add_outro();
} }
add_animation() {
if (this.autofocus) { this.has_animation = true;
if (this.autofocus.condition_expression) { }
this.chunks.mount.push(
b`if (${this.autofocus.condition_expression}) ${this.autofocus.element_var}.focus();` /**
); * @param {import('estree').Identifier} id
} else { * @param {import('estree').Node} [init]
this.chunks.mount.push(b`${this.autofocus.element_var}.focus();`); */
} add_variable(id, init) {
} if (this.variables.has(id.name)) {
throw new Error(`Variable '${id.name}' already initialised with a different value`);
this.render_binding_groups(); }
this.render_listeners(); this.variables.set(id.name, { id, init });
}
const properties: Record<string, any> = {};
/** @param {string} name */
const noop = x`@noop`; alias(name) {
if (!this.aliases.has(name)) {
properties.key = key; this.aliases.set(name, this.get_unique_name(name));
}
if (this.first) { return this.aliases.get(name);
properties.first = x`null`; }
this.chunks.hydrate.push(b`this.first = ${this.first};`);
} /** @param {BlockOptions} options */
child(options) {
if (this.chunks.create.length === 0 && this.chunks.hydrate.length === 0) { return new Block(Object.assign({}, this, { key: null }, options, { parent: this }));
properties.create = noop; }
} else {
const hydrate = /** @param {any} [key] */
this.chunks.hydrate.length > 0 && get_contents(key) {
(this.renderer.options.hydratable ? b`this.h();` : this.chunks.hydrate); const { dev } = this.renderer.options;
if (this.has_outros) {
properties.create = x`function #create() { this.add_variable({ type: 'Identifier', name: '#current' });
if (this.chunks.intro.length > 0) {
this.chunks.intro.push(b `#current = true;`);
this.chunks.mount.push(b `#current = true;`);
}
if (this.chunks.outro.length > 0) {
this.chunks.outro.push(b `#current = false;`);
}
}
if (this.autofocus) {
if (this.autofocus.condition_expression) {
this.chunks.mount.push(b `if (${this.autofocus.condition_expression}) ${this.autofocus.element_var}.focus();`);
}
else {
this.chunks.mount.push(b `${this.autofocus.element_var}.focus();`);
}
}
this.render_binding_groups();
this.render_listeners();
/** @type {Record<string, any>} */
const properties = {};
const noop = x `@noop`;
properties.key = key;
if (this.first) {
properties.first = x `null`;
this.chunks.hydrate.push(b `this.first = ${this.first};`);
}
if (this.chunks.create.length === 0 && this.chunks.hydrate.length === 0) {
properties.create = noop;
}
else {
const hydrate = this.chunks.hydrate.length > 0 &&
(this.renderer.options.hydratable ? b `this.h();` : this.chunks.hydrate);
properties.create = x `function #create() {
${this.chunks.create} ${this.chunks.create}
${hydrate} ${hydrate}
}`; }`;
} }
if (this.renderer.options.hydratable || this.chunks.claim.length > 0) {
if (this.renderer.options.hydratable || this.chunks.claim.length > 0) { if (this.chunks.claim.length === 0 && this.chunks.hydrate.length === 0) {
if (this.chunks.claim.length === 0 && this.chunks.hydrate.length === 0) { properties.claim = noop;
properties.claim = noop; }
} else { else {
properties.claim = x`function #claim(#nodes) { properties.claim = x `function #claim(#nodes) {
${this.chunks.claim} ${this.chunks.claim}
${this.renderer.options.hydratable && this.chunks.hydrate.length > 0 && b`this.h();`} ${this.renderer.options.hydratable && this.chunks.hydrate.length > 0 && b `this.h();`}
}`; }`;
} }
} }
if (this.renderer.options.hydratable && this.chunks.hydrate.length > 0) {
if (this.renderer.options.hydratable && this.chunks.hydrate.length > 0) { properties.hydrate = x `function #hydrate() {
properties.hydrate = x`function #hydrate() {
${this.chunks.hydrate} ${this.chunks.hydrate}
}`; }`;
} }
if (this.chunks.mount.length === 0) {
if (this.chunks.mount.length === 0) { properties.mount = noop;
properties.mount = noop; }
} else if (this.event_listeners.length === 0) { else if (this.event_listeners.length === 0) {
properties.mount = x`function #mount(#target, #anchor) { properties.mount = x `function #mount(#target, #anchor) {
${this.chunks.mount} ${this.chunks.mount}
}`; }`;
} else { }
properties.mount = x`function #mount(#target, #anchor) { else {
properties.mount = x `function #mount(#target, #anchor) {
${this.chunks.mount} ${this.chunks.mount}
}`; }`;
} }
if (this.has_update_method || this.maintain_context) {
if (this.has_update_method || this.maintain_context) { if (this.chunks.update.length === 0 && !this.maintain_context) {
if (this.chunks.update.length === 0 && !this.maintain_context) { properties.update = noop;
properties.update = noop; }
} else { else {
const ctx = this.maintain_context ? x`#new_ctx` : x`#ctx`; const ctx = this.maintain_context ? x `#new_ctx` : x `#ctx`;
let dirty: Identifier | ArrayPattern = { type: 'Identifier', name: '#dirty' }; /** @type {import('estree').Identifier | import('estree').ArrayPattern} */
if (!this.renderer.context_overflow && !this.parent) { let dirty = { type: 'Identifier', name: '#dirty' };
dirty = { type: 'ArrayPattern', elements: [dirty] }; if (!this.renderer.context_overflow && !this.parent) {
} dirty = { type: 'ArrayPattern', elements: [dirty] };
}
properties.update = x`function #update(${ctx}, ${dirty}) { properties.update = x `function #update(${ctx}, ${dirty}) {
${this.maintain_context && b`#ctx = ${ctx};`} ${this.maintain_context && b `#ctx = ${ctx};`}
${this.chunks.update} ${this.chunks.update}
}`; }`;
} }
} }
if (this.has_animation) {
if (this.has_animation) { properties.measure = x `function #measure() {
properties.measure = x`function #measure() {
${this.chunks.measure} ${this.chunks.measure}
}`; }`;
if (this.chunks.restore_measurements.length) {
if (this.chunks.restore_measurements.length) { properties.restore_measurements = x `function #restore_measurements(#measurement) {
properties.restore_measurements = x`function #restore_measurements(#measurement) {
${this.chunks.restore_measurements} ${this.chunks.restore_measurements}
}`; }`;
} }
properties.fix = x `function #fix() {
properties.fix = x`function #fix() {
${this.chunks.fix} ${this.chunks.fix}
}`; }`;
properties.animate = x `function #animate() {
properties.animate = x`function #animate() {
${this.chunks.animate} ${this.chunks.animate}
}`; }`;
} }
if (this.has_intro_method || this.has_outro_method) {
if (this.has_intro_method || this.has_outro_method) { if (this.chunks.intro.length === 0) {
if (this.chunks.intro.length === 0) { properties.intro = noop;
properties.intro = noop; }
} else { else {
properties.intro = x`function #intro(#local) { properties.intro = x `function #intro(#local) {
${this.has_outros && b`if (#current) return;`} ${this.has_outros && b `if (#current) return;`}
${this.chunks.intro} ${this.chunks.intro}
}`; }`;
} }
if (this.chunks.outro.length === 0) {
if (this.chunks.outro.length === 0) { properties.outro = noop;
properties.outro = noop; }
} else { else {
properties.outro = x`function #outro(#local) { properties.outro = x `function #outro(#local) {
${this.chunks.outro} ${this.chunks.outro}
}`; }`;
} }
} }
if (this.chunks.destroy.length === 0) {
if (this.chunks.destroy.length === 0) { properties.destroy = noop;
properties.destroy = noop; }
} else { else {
properties.destroy = x`function #destroy(detaching) { properties.destroy = x `function #destroy(detaching) {
${this.chunks.destroy} ${this.chunks.destroy}
}`; }`;
} }
if (!this.renderer.component.compile_options.dev) {
if (!this.renderer.component.compile_options.dev) { // allow shorthand names
// allow shorthand names for (const name in properties) {
for (const name in properties) { const property = properties[name];
const property = properties[name]; if (property)
if (property) property.id = null; property.id = null;
} }
} }
const return_value: any = x`{ /** @type {any} */
const return_value = x `{
key: ${properties.key}, key: ${properties.key},
first: ${properties.first}, first: ${properties.first},
c: ${properties.create}, c: ${properties.create},
@ -395,21 +403,18 @@ export default class Block {
o: ${properties.outro}, o: ${properties.outro},
d: ${properties.destroy} d: ${properties.destroy}
}`; }`;
const block = dev && this.get_unique_name('block');
const block = dev && this.get_unique_name('block'); const body = b `
const body = b`
${this.chunks.declarations} ${this.chunks.declarations}
${Array.from(this.variables.values()).map(({ id, init }) => { ${Array.from(this.variables.values()).map(({ id, init }) => {
return init ? b`let ${id} = ${init}` : b`let ${id}`; return init ? b `let ${id} = ${init}` : b `let ${id}`;
})} })}
${this.chunks.init} ${this.chunks.init}
${ ${dev
dev ? b `
? b`
const ${block} = ${return_value}; const ${block} = ${return_value};
@dispatch_dev("SvelteRegisterBlock", { @dispatch_dev("SvelteRegisterBlock", {
block: ${block}, block: ${block},
@ -419,72 +424,66 @@ export default class Block {
ctx: #ctx ctx: #ctx
}); });
return ${block};` return ${block};`
: b` : b `
return ${return_value};` return ${return_value};`}
}
`; `;
return body;
return body; }
}
/** @returns {boolean} */
has_content(): boolean { has_content() {
return ( return (!!this.first ||
!!this.first || this.event_listeners.length > 0 ||
this.event_listeners.length > 0 || this.chunks.intro.length > 0 ||
this.chunks.intro.length > 0 || this.chunks.outro.length > 0 ||
this.chunks.outro.length > 0 || this.chunks.create.length > 0 ||
this.chunks.create.length > 0 || this.chunks.hydrate.length > 0 ||
this.chunks.hydrate.length > 0 || this.chunks.claim.length > 0 ||
this.chunks.claim.length > 0 || this.chunks.mount.length > 0 ||
this.chunks.mount.length > 0 || this.chunks.update.length > 0 ||
this.chunks.update.length > 0 || this.chunks.destroy.length > 0 ||
this.chunks.destroy.length > 0 || this.has_animation);
this.has_animation }
); render() {
} const key = this.key && this.get_unique_name('key');
render() { /** @type {any[]} */
const key = this.key && this.get_unique_name('key'); const args = [x `#ctx`];
if (key)
const args: any[] = [x`#ctx`]; args.unshift(key);
if (key) args.unshift(key); const fn = b `function ${this.name}(${args}) {
const fn = b`function ${this.name}(${args}) {
${this.get_contents(key)} ${this.get_contents(key)}
}`; }`;
return this.comment
return this.comment ? b `
? b`
// ${this.comment} // ${this.comment}
${fn}` ${fn}`
: fn; : fn;
} }
render_listeners(chunk: string = '') { /** @param {string} chunk */
if (this.event_listeners.length > 0) { render_listeners(chunk = '') {
this.add_variable({ type: 'Identifier', name: '#mounted' }); if (this.event_listeners.length > 0) {
this.chunks.destroy.push(b`#mounted = false`); this.add_variable({ type: 'Identifier', name: '#mounted' });
this.chunks.destroy.push(b `#mounted = false`);
const dispose: Identifier = {
type: 'Identifier', /** @type {import('estree').Identifier} */
name: `#dispose${chunk}` const dispose = {
}; type: 'Identifier',
name: `#dispose${chunk}`
this.add_variable(dispose); };
this.add_variable(dispose);
if (this.event_listeners.length === 1) { if (this.event_listeners.length === 1) {
this.chunks.mount.push( this.chunks.mount.push(b `
b`
if (!#mounted) { if (!#mounted) {
${dispose} = ${this.event_listeners[0]}; ${dispose} = ${this.event_listeners[0]};
#mounted = true; #mounted = true;
} }
` `);
); this.chunks.destroy.push(b `${dispose}();`);
}
this.chunks.destroy.push(b`${dispose}();`); else {
} else { this.chunks.mount.push(b `
this.chunks.mount.push(b`
if (!#mounted) { if (!#mounted) {
${dispose} = [ ${dispose} = [
${this.event_listeners} ${this.event_listeners}
@ -492,15 +491,34 @@ export default class Block {
#mounted = true; #mounted = true;
} }
`); `);
this.chunks.destroy.push(b `@run_all(${dispose});`);
}
}
}
render_binding_groups() {
for (const binding_group of this.binding_groups) {
binding_group.render(this);
}
}
}
this.chunks.destroy.push(b`@run_all(${dispose});`);
}
}
}
render_binding_groups() {
for (const binding_group of this.binding_groups) {
binding_group.render(this); /** @typedef {Object} Bindings
} * @property {Identifier} object
} * @property {Identifier} property
} * @property {Node} snippet
* @property {string} store
* @property {(node:Node)=>Node} modifier
*/
/** @typedef {Object} BlockOptions
* @property {Block} [parent]
* @property {Identifier} name
* @property {string} type
* @property {Renderer} [renderer]
* @property {string} [comment]
* @property {Identifier} [key]
* @property {Map<string,Bindings>} [bindings]
* @property {Set<string>} [dependencies]
*/

@ -3,6 +3,7 @@ import { b, x } from 'code-red';
import add_event_handlers from './shared/add_event_handlers.js'; import add_event_handlers from './shared/add_event_handlers.js';
import add_actions from './shared/add_actions.js'; import add_actions from './shared/add_actions.js';
import EventHandler from './Element/EventHandler.js'; import EventHandler from './Element/EventHandler.js';
const associated_events = { const associated_events = {
innerWidth: 'resize', innerWidth: 'resize',
innerHeight: 'resize', innerHeight: 'resize',

Loading…
Cancel
Save