From 73321465c126a44a515a2be89b098e270dade668 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Sun, 4 Aug 2019 20:49:35 +0900 Subject: [PATCH 01/11] on:* --- src/compiler/compile/nodes/EventHandler.ts | 2 +- src/compiler/compile/render_dom/Block.ts | 15 +++++++++++++++ .../wrappers/shared/add_event_handlers.ts | 6 ++++++ src/runtime/internal/Component.ts | 10 ++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 0c65e463ba4a..0f9ff0dfd930 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -17,7 +17,7 @@ export default class EventHandler extends Node { constructor(component: Component, parent, template_scope, info) { super(component, parent, template_scope, info); - this.name = info.name; + this.name = info.name !== '*' ? info.name : 'any'; this.modifiers = new Set(info.modifiers); if (info.expression) { diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index 59beae1a39d6..a9a0eee8c751 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -45,6 +45,7 @@ export default class Block { }; event_listeners: string[] = []; + any_event_elements: string[] = []; maintain_context: boolean; has_animation: boolean; @@ -325,6 +326,20 @@ export default class Block { `); } + if (this.variables.size > 0) { + const listens = Array.from(this.variables.keys()) + .filter(key => this.any_event_elements.includes(key)) + .join(', '); + + if (listens.length > 0) { + properties.add_block(deindent` + ${method_name('bbl', 'bubble')}() { + return [listen, [${listens}]]; + }, + `); + } + } + if (this.has_intro_method || this.has_outro_method) { if (this.builders.intro.is_empty()) { properties.add_line(`i: @noop,`); diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts index 6b7e62d2123e..9cc24836af20 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts @@ -21,6 +21,12 @@ export default function add_event_handlers( block.event_listeners.push( `@listen(${target}, "${handler.name}", ${snippet}, ${opts_string})` ); + } else if (handler.name === 'any') { + block.any_event_elements.push(target); + // This isn't required but listen is treeshaken otherwise + block.event_listeners.push( + `@listen(${target}, "${handler.name}", ${snippet})` + ); } else { block.event_listeners.push( `@listen(${target}, "${handler.name}", ${snippet})` diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 92e227e57cc6..79d89c2428d4 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -43,6 +43,16 @@ export function mount_component(component, target, anchor) { run_all(new_on_destroy); } component.$$.on_mount = []; + + if (fragment.bbl) { + Object.keys(component.$$.callbacks).forEach(type => { + if (!component.$$.ctx[`${type}_handler`]) { + const [listen, els] = fragment.bbl(); + + els.forEach(el => component.$$.callbacks[type].forEach(cb => listen(el, type, cb))); + } + }); + } }); after_update.forEach(add_render_callback); From 0b9928476f17c788a889c950ad6e733e5c933454 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Sun, 4 Aug 2019 22:06:41 +0900 Subject: [PATCH 02/11] any -> $$any --- src/compiler/compile/nodes/EventHandler.ts | 14 ++++++++------ .../wrappers/shared/add_event_handlers.ts | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 0f9ff0dfd930..6cf867daa509 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -17,7 +17,7 @@ export default class EventHandler extends Node { constructor(component: Component, parent, template_scope, info) { super(component, parent, template_scope, info); - this.name = info.name !== '*' ? info.name : 'any'; + this.name = info.name !== '*' ? info.name : '$$any'; this.modifiers = new Set(info.modifiers); if (info.expression) { @@ -50,11 +50,13 @@ export default class EventHandler extends Node { referenced: true }); - component.partly_hoisted.push(deindent` - function ${name}(event) { - @bubble($$self, event); - } - `); + if (this.name !== '$$any') { + component.partly_hoisted.push(deindent` + function ${name}(event) { + @bubble($$self, event); + } + `); + } this.handler_name = name; } diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts index 9cc24836af20..cf46366ca231 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts @@ -21,7 +21,7 @@ export default function add_event_handlers( block.event_listeners.push( `@listen(${target}, "${handler.name}", ${snippet}, ${opts_string})` ); - } else if (handler.name === 'any') { + } else if (handler.name === '$$any') { block.any_event_elements.push(target); // This isn't required but listen is treeshaken otherwise block.event_listeners.push( From 3825b9e9a4ee49c327d4a346c2f78eaddb95ec48 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Sun, 4 Aug 2019 22:15:10 +0900 Subject: [PATCH 03/11] fix for any event --- src/compiler/compile/nodes/EventHandler.ts | 12 ++++++------ .../render_dom/wrappers/shared/add_event_handlers.ts | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 6cf867daa509..144a3a97ca54 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -44,13 +44,13 @@ export default class EventHandler extends Node { } else { const name = component.get_unique_name(`${sanitize(this.name)}_handler`); - component.add_var({ - name, - internal: true, - referenced: true - }); - if (this.name !== '$$any') { + component.add_var({ + name, + internal: true, + referenced: true + }); + component.partly_hoisted.push(deindent` function ${name}(event) { @bubble($$self, event); diff --git a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts index cf46366ca231..862f02b6742d 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/add_event_handlers.ts @@ -24,9 +24,7 @@ export default function add_event_handlers( } else if (handler.name === '$$any') { block.any_event_elements.push(target); // This isn't required but listen is treeshaken otherwise - block.event_listeners.push( - `@listen(${target}, "${handler.name}", ${snippet})` - ); + block.event_listeners.push(`@listen`); } else { block.event_listeners.push( `@listen(${target}, "${handler.name}", ${snippet})` From 085a97c9f2336f835a25841a01e2497cb8672d18 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Mon, 5 Aug 2019 12:31:59 +0900 Subject: [PATCH 04/11] push bubbles for if/each blocks --- src/compiler/compile/render_dom/Block.ts | 6 ++++- .../compile/render_dom/wrappers/EachBlock.ts | 4 ++++ .../compile/render_dom/wrappers/IfBlock.ts | 4 ++++ src/runtime/ambient.ts | 1 + src/runtime/internal/Component.ts | 24 +++++++++++-------- src/runtime/internal/scheduler.ts | 4 +++- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index a9a0eee8c751..763fa4e20869 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -35,6 +35,7 @@ export default class Block { claim: CodeBuilder; hydrate: CodeBuilder; mount: CodeBuilder; + bubble: CodeBuilder; measure: CodeBuilder; fix: CodeBuilder; animate: CodeBuilder; @@ -84,6 +85,7 @@ export default class Block { claim: new CodeBuilder(), hydrate: new CodeBuilder(), mount: new CodeBuilder(), + bubble: new CodeBuilder(), measure: new CodeBuilder(), fix: new CodeBuilder(), animate: new CodeBuilder(), @@ -334,7 +336,9 @@ export default class Block { if (listens.length > 0) { properties.add_block(deindent` ${method_name('bbl', 'bubble')}() { - return [listen, [${listens}]]; + let bubbles = [${listens}]; + ${this.builders.bubble} + return bubbles; }, `); } diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 42792efce714..28f30cbc5847 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -218,6 +218,10 @@ export default class EachBlockWrapper extends Wrapper { `); } + block.builders.bubble.add_block(deindent` + for (#i = 0; #i < ${this.vars.data_length}; #i += 1) bubbles.push(...${this.vars.iterations}[#i].bbl()); + `); + if (needs_anchor) { block.add_element( update_anchor_node, diff --git a/src/compiler/compile/render_dom/wrappers/IfBlock.ts b/src/compiler/compile/render_dom/wrappers/IfBlock.ts index fe870df862d1..351d16e5c3e1 100644 --- a/src/compiler/compile/render_dom/wrappers/IfBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/IfBlock.ts @@ -431,6 +431,10 @@ export default class IfBlockWrapper extends Wrapper { } `; + block.builders.bubble.add_line( + `if (${name}) bubbles.push(...${name}.bbl());` + ); + // no `p()` here — we don't want to update outroing nodes, // as that will typically result in glitching if (branch.block.has_outro_method) { diff --git a/src/runtime/ambient.ts b/src/runtime/ambient.ts index b094056c5959..28e55686fe48 100644 --- a/src/runtime/ambient.ts +++ b/src/runtime/ambient.ts @@ -13,6 +13,7 @@ declare module '*.svelte' { $set(props: Props): void; $on(event: string, callback: (event: CustomEvent) => void): () => void; $destroy(): void; + $bubble(): void; [accessor: string]: any; } diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 79d89c2428d4..d61a04d72d61 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -1,7 +1,7 @@ import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler'; import { current_component, set_current_component } from './lifecycle'; import { blank_object, is_function, run, run_all, noop } from './utils'; -import { children } from './dom'; +import { children, listen } from './dom'; import { transition_in } from './transitions'; // eslint-disable-next-line @typescript-eslint/class-name-casing @@ -27,6 +27,18 @@ export function bind(component, name, callback) { callback(component.$$.ctx[name]); } +function attach_any_listeners($$) { + $$.bubble = () => Object.keys($$.callbacks).forEach(type => { + if ($$.ctx[`${type}_handler`]) return; + + $$.fragment.bbl().forEach(el => { + $$.callbacks[type].forEach(cb => listen(el, type, cb)); + }); + }); + + $$.bubble(); +} + export function mount_component(component, target, anchor) { const { fragment, on_mount, on_destroy, after_update } = component.$$; @@ -44,15 +56,7 @@ export function mount_component(component, target, anchor) { } component.$$.on_mount = []; - if (fragment.bbl) { - Object.keys(component.$$.callbacks).forEach(type => { - if (!component.$$.ctx[`${type}_handler`]) { - const [listen, els] = fragment.bbl(); - - els.forEach(el => component.$$.callbacks[type].forEach(cb => listen(el, type, cb))); - } - }); - } + if (fragment.bbl) attach_any_listeners(component.$$); }); after_update.forEach(add_render_callback); diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index e3d7181fcbec..66ca63143c44 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -76,6 +76,8 @@ function update($$) { $$.fragment.p($$.dirty, $$.ctx); $$.dirty = null; + $$.bubble && $$.bubble(); + $$.after_update.forEach(add_render_callback); } -} +} \ No newline at end of file From 9118bbb897cf761faf37acda7b81ba59ccffe79a Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Mon, 6 Jan 2020 12:40:24 +0900 Subject: [PATCH 05/11] strict order option --- site/content/docs/04-compile-time.md | 1 + src/compiler/compile/index.ts | 3 +- src/compiler/preprocess/index.ts | 150 ++++++++++++++++++++------- 3 files changed, 113 insertions(+), 41 deletions(-) diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md index e9126ccf1316..c6d950cd95d4 100644 --- a/site/content/docs/04-compile-time.md +++ b/site/content/docs/04-compile-time.md @@ -203,6 +203,7 @@ result: { }>, options?: { filename?: string + strictOrder?: boolean } ) ``` diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 12b161aeeb0e..781bad71e92b 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -26,7 +26,8 @@ const valid_options = [ 'css', 'loopGuardTimeout', 'preserveComments', - 'preserveWhitespace' + 'preserveWhitespace', + 'strictOrder' ]; function validate_options(options: CompileOptions, warnings: Warning[]) { diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 1a13b869e7af..26c89f01d609 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -67,32 +67,31 @@ async function replace_async(str: string, re: RegExp, func: (...any) => Promise< return out; } -export default async function preprocess( +async function process_markup( source: string, - preprocessor: PreprocessorGroup | PreprocessorGroup[], - options?: { filename?: string } + func: (...any) => Processed | Promise, + filename: string, ) { - // @ts-ignore todo: doublecheck - const filename = (options && options.filename) || preprocessor.filename; // legacy - const dependencies = []; - const preprocessors = Array.isArray(preprocessor) ? preprocessor : [preprocessor]; + const processed: Processed = await func({ + content: source, + filename + }); - const markup = preprocessors.map(p => p.markup).filter(Boolean); - const script = preprocessors.map(p => p.script).filter(Boolean); - const style = preprocessors.map(p => p.style).filter(Boolean); - - for (const fn of markup) { - const processed = await fn({ - content: source, - filename - }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); - source = processed ? processed.code : source; - } + return { + source: processed ? processed.code : source, + dependencies: processed.dependencies, + }; +} + +async function process_script( + source: string, + func: (...any) => Processed | Promise, + filename: string, +) { + const dependencies = []; - for (const fn of script) { - source = await replace_async( + const s = await replace_async( source, /|([^]*?)<\/script>/gi, async (match, attributes = '', content) => { @@ -100,7 +99,7 @@ export default async function preprocess( return match; } attributes = attributes || ''; - const processed = await fn({ + const processed: Processed = await func({ content, attributes: parse_attributes(attributes), filename @@ -109,26 +108,97 @@ export default async function preprocess( return processed ? `${processed.code}` : match; } ); - } - for (const fn of style) { - source = await replace_async( - source, - /|([^]*?)<\/style>/gi, - async (match, attributes = '', content) => { - if (!attributes && !content) { - return match; - } - const processed: Processed = await fn({ - content, - attributes: parse_attributes(attributes), - filename - }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); - return processed ? `${processed.code}` : match; + console.log(s, 'RETURREND'); + + return { + source: s, + dependencies, + }; +} + +async function process_style( + source: string, + func: (...any) => Processed | Promise, + filename: string, +) { + const dependencies = []; + + const s = await replace_async( + source, + /|([^]*?)<\/style>/gi, + async (match, attributes = '', content) => { + if (!attributes && !content) { + return match; } - ); - } + const processed: Processed = await func({ + content, + attributes: parse_attributes(attributes), + filename + }); + + if (processed && processed.dependencies) dependencies.push(...processed.dependencies); + return processed ? `${processed.code}` : match; + } + ); + + return { + source: s, + dependencies, + }; +} + +async function asyncForEach(array, callback) { + // eslint-disable-next-line + for (let index = 0; index < array.length; index++) { + // eslint-disable-next-line + await callback(array[index], index, array); + } +} + + +export default async function preprocess( + source: string, + preprocessor: PreprocessorGroup | PreprocessorGroup[], + options?: { filename?: string; strictOrder?: boolean } +) { + // @ts-ignore todo: doublecheck + const filename = (options && options.filename) || preprocessor.filename; // legacy + const dependencies = []; + + const preprocessors = Array.isArray(preprocessor) ? preprocessor : [preprocessor]; + + const order = options.strictOrder + ? preprocessors + : [ + ...preprocessors.map(({ markup }) => ({ markup })), + ...preprocessors.map(({ script }) => ({ script })), + ...preprocessors.map(({ style }) => ({ style })), + ]; + + console.log(preprocessors); + + await asyncForEach(order, async p => { + let processed; + + if (p.markup) { + processed = await process_markup(source, p.markup, filename); + source = processed.source; + dependencies.push(processed.dependencies); + } + + if (p.script) { + processed = await process_script(source, p.script, filename); + source = processed.source; + dependencies.push(processed.dependencies); + } + + if (p.style) { + processed = await process_style(source, p.style, filename); + source = processed.source; + dependencies.push(processed.dependencies); + } + }); return { // TODO return separated output, in future version where svelte.compile supports it: From 4c4a39ca83ee735eac17b1b117ddc262c9432d4f Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Mon, 6 Jan 2020 13:17:50 +0900 Subject: [PATCH 06/11] lint --- src/compiler/preprocess/index.ts | 66 ++++++++++++++++---------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 26c89f01d609..0b83c05deb99 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -80,7 +80,7 @@ async function process_markup( return { source: processed ? processed.code : source, - dependencies: processed.dependencies, + dependencies: processed.dependencies }; } @@ -91,28 +91,29 @@ async function process_script( ) { const dependencies = []; - const s = await replace_async( - source, - /|([^]*?)<\/script>/gi, - async (match, attributes = '', content) => { - if (!attributes && !content) { - return match; - } - attributes = attributes || ''; - const processed: Processed = await func({ - content, - attributes: parse_attributes(attributes), - filename - }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); - return processed ? `${processed.code}` : match; + source = await replace_async( + source, + /|([^]*?)<\/script>/gi, + async (match, attributes = '', content) => { + if (!attributes && !content) { + return match; + } + attributes = attributes || ''; + const processed: Processed = await func({ + content, + attributes: parse_attributes(attributes), + filename + }); + if (processed && processed.dependencies) { + dependencies.push(...processed.dependencies); } - ); - console.log(s, 'RETURREND'); + return processed ? `${processed.code}` : match; + } + ); return { - source: s, + source, dependencies, }; } @@ -124,7 +125,7 @@ async function process_style( ) { const dependencies = []; - const s = await replace_async( + source = await replace_async( source, /|([^]*?)<\/style>/gi, async (match, attributes = '', content) => { @@ -137,26 +138,26 @@ async function process_style( filename }); - if (processed && processed.dependencies) dependencies.push(...processed.dependencies); + if (processed && processed.dependencies) { + dependencies.push(...processed.dependencies); + } + return processed ? `${processed.code}` : match; } ); return { - source: s, + source, dependencies, }; } -async function asyncForEach(array, callback) { - // eslint-disable-next-line +async function async_for_each(array, callback) { for (let index = 0; index < array.length; index++) { - // eslint-disable-next-line await callback(array[index], index, array); } } - export default async function preprocess( source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], @@ -164,11 +165,12 @@ export default async function preprocess( ) { // @ts-ignore todo: doublecheck const filename = (options && options.filename) || preprocessor.filename; // legacy + const strictOrder = options && options.strictOrder; const dependencies = []; const preprocessors = Array.isArray(preprocessor) ? preprocessor : [preprocessor]; - const order = options.strictOrder + const order = strictOrder ? preprocessors : [ ...preprocessors.map(({ markup }) => ({ markup })), @@ -176,27 +178,25 @@ export default async function preprocess( ...preprocessors.map(({ style }) => ({ style })), ]; - console.log(preprocessors); - - await asyncForEach(order, async p => { + await async_for_each(order, async p => { let processed; if (p.markup) { processed = await process_markup(source, p.markup, filename); source = processed.source; - dependencies.push(processed.dependencies); + if (processed.dependencies.length) dependencies.push(...processed.dependencies); } if (p.script) { processed = await process_script(source, p.script, filename); source = processed.source; - dependencies.push(processed.dependencies); + if (processed.dependencies.length) dependencies.push(...processed.dependencies); } if (p.style) { processed = await process_style(source, p.style, filename); source = processed.source; - dependencies.push(processed.dependencies); + if (processed.dependencies.length) dependencies.push(...processed.dependencies); } }); From cf39b8b3a43427929de526343406683f8c6b5d04 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Mon, 6 Jan 2020 13:27:58 +0900 Subject: [PATCH 07/11] add test --- src/compiler/preprocess/index.ts | 12 +++++++++--- test/preprocess/samples/strict-order/_config.js | 11 +++++++++++ test/preprocess/samples/strict-order/input.svelte | 11 +++++++++++ test/preprocess/samples/strict-order/output.svelte | 11 +++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 test/preprocess/samples/strict-order/_config.js create mode 100644 test/preprocess/samples/strict-order/input.svelte create mode 100644 test/preprocess/samples/strict-order/output.svelte diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 0b83c05deb99..60609f02753f 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -184,19 +184,25 @@ export default async function preprocess( if (p.markup) { processed = await process_markup(source, p.markup, filename); source = processed.source; - if (processed.dependencies.length) dependencies.push(...processed.dependencies); + if (processed.dependencies && processed.dependencies.length) { + dependencies.push(...processed.dependencies); + } } if (p.script) { processed = await process_script(source, p.script, filename); source = processed.source; - if (processed.dependencies.length) dependencies.push(...processed.dependencies); + if (processed.dependencies && processed.dependencies.length) { + dependencies.push(...processed.dependencies); + } } if (p.style) { processed = await process_style(source, p.style, filename); source = processed.source; - if (processed.dependencies.length) dependencies.push(...processed.dependencies); + if (processed.dependencies && processed.dependencies.length) { + dependencies.push(...processed.dependencies); + } } }); diff --git a/test/preprocess/samples/strict-order/_config.js b/test/preprocess/samples/strict-order/_config.js new file mode 100644 index 000000000000..e47e14b929a8 --- /dev/null +++ b/test/preprocess/samples/strict-order/_config.js @@ -0,0 +1,11 @@ +export default { + strictOrder: false, + preprocess: [ + { + style: ({ content }) => ({ code: content.replace(/one/g, 'two') }), + }, + { + markup: ({ content }) => ({ code: content.replace(/two/g, 'three') }), + }, + ], +}; diff --git a/test/preprocess/samples/strict-order/input.svelte b/test/preprocess/samples/strict-order/input.svelte new file mode 100644 index 000000000000..3bf89c6b959b --- /dev/null +++ b/test/preprocess/samples/strict-order/input.svelte @@ -0,0 +1,11 @@ +

one

+ + + + \ No newline at end of file diff --git a/test/preprocess/samples/strict-order/output.svelte b/test/preprocess/samples/strict-order/output.svelte new file mode 100644 index 000000000000..3bf89c6b959b --- /dev/null +++ b/test/preprocess/samples/strict-order/output.svelte @@ -0,0 +1,11 @@ +

one

+ + + + \ No newline at end of file From 54f9a79ff5e26a3cbd59b04494d8c2b7c27913c8 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Tue, 7 Jan 2020 15:06:31 +0900 Subject: [PATCH 08/11] normal order test --- test/preprocess/index.js | 16 +++++++++++++--- test/preprocess/samples/normal-order/_config.js | 14 ++++++++++++++ .../preprocess/samples/normal-order/input.svelte | 11 +++++++++++ .../samples/normal-order/output.svelte | 11 +++++++++++ test/preprocess/samples/strict-order/_config.js | 4 +++- .../preprocess/samples/strict-order/input.svelte | 2 +- .../samples/strict-order/output.svelte | 2 +- 7 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 test/preprocess/samples/normal-order/_config.js create mode 100644 test/preprocess/samples/normal-order/input.svelte create mode 100644 test/preprocess/samples/normal-order/output.svelte diff --git a/test/preprocess/index.js b/test/preprocess/index.js index 5d83bb60590d..a3b37b00f0f9 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.js @@ -14,10 +14,20 @@ describe('preprocess', () => { } (config.skip ? it.skip : solo ? it.only : it)(dir, async () => { - const input = fs.readFileSync(`${__dirname}/samples/${dir}/input.svelte`, 'utf-8'); - const expected = fs.readFileSync(`${__dirname}/samples/${dir}/output.svelte`, 'utf-8'); + const input = fs.readFileSync( + `${__dirname}/samples/${dir}/input.svelte`, + 'utf-8' + ); + const expected = fs.readFileSync( + `${__dirname}/samples/${dir}/output.svelte`, + 'utf-8' + ); - const result = await svelte.preprocess(input, config.preprocess); + const result = await svelte.preprocess( + input, + config.preprocess, + config.options + ); fs.writeFileSync(`${__dirname}/samples/${dir}/_actual.html`, result.code); assert.equal(result.code, expected); diff --git a/test/preprocess/samples/normal-order/_config.js b/test/preprocess/samples/normal-order/_config.js new file mode 100644 index 000000000000..c3668385e6bd --- /dev/null +++ b/test/preprocess/samples/normal-order/_config.js @@ -0,0 +1,14 @@ +export default { + solo: true, + options: { + strictOrder: false, + }, + preprocess: [ + { + style: ({ content }) => ({ code: content.replace(/one/g, 'two') }), + }, + { + markup: ({ content }) => ({ code: content.replace(/two/g, 'three') }), + }, + ], +}; diff --git a/test/preprocess/samples/normal-order/input.svelte b/test/preprocess/samples/normal-order/input.svelte new file mode 100644 index 000000000000..6dbbfb47a9cf --- /dev/null +++ b/test/preprocess/samples/normal-order/input.svelte @@ -0,0 +1,11 @@ +

one

+ + + + \ No newline at end of file diff --git a/test/preprocess/samples/normal-order/output.svelte b/test/preprocess/samples/normal-order/output.svelte new file mode 100644 index 000000000000..3bf89c6b959b --- /dev/null +++ b/test/preprocess/samples/normal-order/output.svelte @@ -0,0 +1,11 @@ +

one

+ + + + \ No newline at end of file diff --git a/test/preprocess/samples/strict-order/_config.js b/test/preprocess/samples/strict-order/_config.js index e47e14b929a8..faa6371149e7 100644 --- a/test/preprocess/samples/strict-order/_config.js +++ b/test/preprocess/samples/strict-order/_config.js @@ -1,5 +1,7 @@ export default { - strictOrder: false, + options: { + strictOrder: true, + }, preprocess: [ { style: ({ content }) => ({ code: content.replace(/one/g, 'two') }), diff --git a/test/preprocess/samples/strict-order/input.svelte b/test/preprocess/samples/strict-order/input.svelte index 3bf89c6b959b..6dbbfb47a9cf 100644 --- a/test/preprocess/samples/strict-order/input.svelte +++ b/test/preprocess/samples/strict-order/input.svelte @@ -1,7 +1,7 @@

one

diff --git a/test/preprocess/samples/strict-order/output.svelte b/test/preprocess/samples/strict-order/output.svelte index 3bf89c6b959b..1ca1a0d4c1c8 100644 --- a/test/preprocess/samples/strict-order/output.svelte +++ b/test/preprocess/samples/strict-order/output.svelte @@ -1,7 +1,7 @@

one

From 16edc673c177f430e86c9d8a6915d6aa16f00c43 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Tue, 7 Jan 2020 19:09:20 +0900 Subject: [PATCH 09/11] remove solo: true --- test/preprocess/samples/normal-order/_config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/preprocess/samples/normal-order/_config.js b/test/preprocess/samples/normal-order/_config.js index c3668385e6bd..cbac27884385 100644 --- a/test/preprocess/samples/normal-order/_config.js +++ b/test/preprocess/samples/normal-order/_config.js @@ -1,5 +1,4 @@ export default { - solo: true, options: { strictOrder: false, }, From 7f2b68e53df52a97f2f7b3bb2aec65189b18b333 Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Tue, 7 Jan 2020 19:14:19 +0900 Subject: [PATCH 10/11] add docs --- site/content/docs/04-compile-time.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/site/content/docs/04-compile-time.md b/site/content/docs/04-compile-time.md index c6d950cd95d4..45e4d3a4b424 100644 --- a/site/content/docs/04-compile-time.md +++ b/site/content/docs/04-compile-time.md @@ -306,6 +306,30 @@ const { code } = svelte.preprocess(source, [ }); ``` +--- + +User may override default preprocessor order by passing `strictOrder` option. + +```js +const svelte = require('svelte/compiler'); + +const { code } = svelte.preprocess(source, [ + { + style: () => { + console.log('this runs first'); + } + }, + { + markup: () => { + console.log('this runs second'); + } + } +], { + filename: 'App.svelte', + strictOrder: true +}); +``` + ### `svelte.walk` From 00910fe792211112382384b28674544f3717d13a Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Tue, 7 Jan 2020 19:19:50 +0900 Subject: [PATCH 11/11] tests reversed --- test/preprocess/samples/normal-order/output.svelte | 2 +- test/preprocess/samples/strict-order/output.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/preprocess/samples/normal-order/output.svelte b/test/preprocess/samples/normal-order/output.svelte index 3bf89c6b959b..1ca1a0d4c1c8 100644 --- a/test/preprocess/samples/normal-order/output.svelte +++ b/test/preprocess/samples/normal-order/output.svelte @@ -1,7 +1,7 @@

one

diff --git a/test/preprocess/samples/strict-order/output.svelte b/test/preprocess/samples/strict-order/output.svelte index 1ca1a0d4c1c8..3bf89c6b959b 100644 --- a/test/preprocess/samples/strict-order/output.svelte +++ b/test/preprocess/samples/strict-order/output.svelte @@ -1,7 +1,7 @@

one