From 9118bbb897cf761faf37acda7b81ba59ccffe79a Mon Sep 17 00:00:00 2001 From: Maxim Matyunin Date: Mon, 6 Jan 2020 12:40:24 +0900 Subject: [PATCH] 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 e9126ccf13..c6d950cd95 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 12b161aeeb..781bad71e9 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 1a13b869e7..26c89f01d6 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: