From 5c1f6ff206c82186b0ab8be67eafb048e7253b19 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 30 Dec 2017 10:38:10 -0500 Subject: [PATCH 1/3] add option to disable two-way binding (#54) --- src/parse/index.ts | 5 +++++ src/parse/state/tag.ts | 4 ++++ test/parser/index.js | 6 ++++-- test/parser/samples/error-binding-disabled/error.json | 8 ++++++++ test/parser/samples/error-binding-disabled/input.html | 1 + test/parser/samples/error-binding-disabled/options.json | 3 +++ 6 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/parser/samples/error-binding-disabled/error.json create mode 100644 test/parser/samples/error-binding-disabled/input.html create mode 100644 test/parser/samples/error-binding-disabled/options.json diff --git a/src/parse/index.ts b/src/parse/index.ts index 995a38f675..6711e9929f 100644 --- a/src/parse/index.ts +++ b/src/parse/index.ts @@ -22,6 +22,7 @@ class ParseError extends CompileError { interface ParserOptions { filename?: string; + bind?: boolean; } type ParserState = (parser: Parser) => (ParserState | void); @@ -38,6 +39,8 @@ export class Parser { js: Node; metaTags: {}; + allowBindings: boolean; + constructor(template: string, options: ParserOptions) { if (typeof template !== 'string') { throw new TypeError('Template must be a string'); @@ -46,6 +49,8 @@ export class Parser { this.template = template.replace(/\s+$/, ''); this.filename = options.filename; + this.allowBindings = options.bind !== false; + this.index = 0; this.stack = []; this.metaTags = {}; diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index 1e39a51059..dae32bc3df 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -182,6 +182,10 @@ export default function tag(parser: Parser) { let attribute; while ((attribute = readAttribute(parser, uniqueNames))) { + if (attribute.type === 'Binding' && !parser.allowBindings) { + parser.error(`Two-way binding is disabled`, attribute.start); + } + element.attributes.push(attribute); parser.allowWhitespace(); } diff --git a/test/parser/index.js b/test/parser/index.js index 1ce8165009..93060ef1ff 100644 --- a/test/parser/index.js +++ b/test/parser/index.js @@ -1,6 +1,6 @@ import assert from 'assert'; import fs from 'fs'; -import { svelte } from '../helpers.js'; +import { svelte, tryToLoadJson } from '../helpers.js'; describe('parse', () => { fs.readdirSync('test/parser/samples').forEach(dir => { @@ -20,8 +20,10 @@ describe('parse', () => { .readFileSync(`test/parser/samples/${dir}/input.html`, 'utf-8') .replace(/\s+$/, ''); + const options = tryToLoadJson(`test/parser/samples/${dir}/options.json`) || {}; + try { - const actual = svelte.parse(input); + const actual = svelte.parse(input, options); fs.writeFileSync( `test/parser/samples/${dir}/_actual.json`, JSON.stringify(actual, null, '\t') diff --git a/test/parser/samples/error-binding-disabled/error.json b/test/parser/samples/error-binding-disabled/error.json new file mode 100644 index 0000000000..36ad59d26f --- /dev/null +++ b/test/parser/samples/error-binding-disabled/error.json @@ -0,0 +1,8 @@ +{ + "message": "Two-way binding is disabled", + "loc": { + "line": 1, + "column": 7 + }, + "pos": 7 +} \ No newline at end of file diff --git a/test/parser/samples/error-binding-disabled/input.html b/test/parser/samples/error-binding-disabled/input.html new file mode 100644 index 0000000000..6a7bf8566c --- /dev/null +++ b/test/parser/samples/error-binding-disabled/input.html @@ -0,0 +1 @@ + diff --git a/test/parser/samples/error-binding-disabled/options.json b/test/parser/samples/error-binding-disabled/options.json new file mode 100644 index 0000000000..02fc50c2f2 --- /dev/null +++ b/test/parser/samples/error-binding-disabled/options.json @@ -0,0 +1,3 @@ +{ + "bind": false +} \ No newline at end of file From 71ce4ab9728725c8d4ab5caeb41362cb864e423f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 30 Dec 2017 10:43:26 -0500 Subject: [PATCH 2/3] update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d7a517fa30..813d47e800 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ The Svelte compiler optionally takes a second argument, an object of configurati | | | | | `onerror` | `function` | Specify a callback for when Svelte encounters an error while compiling the component. Passed two arguments: the error object, and another function that is Svelte's default onerror handling. | (exception is thrown) | | `onwarn` | `function` | Specify a callback for when Svelte encounters a non-fatal warning while compiling the component. Passed two arguments: the warning object, and another function that is Svelte's default onwarn handling. | (warning is logged to console) | +| `bind` | `boolean` | If `false`, disallows `bind:` directives | ### Preprocessor options From d119b48a906345fb54272076c28bd0e22052a126 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 30 Dec 2017 11:21:33 -0500 Subject: [PATCH 3/3] fix README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 813d47e800..ee5a4c1b77 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ The Svelte compiler optionally takes a second argument, an object of configurati | `hydratable` | `true`, `false` | Whether to support hydration on the compiled component. | `false` | | `customElement` | `true`, `false`, `{ tag, props }` | Whether to compile this component to a custom element. If `tag`/`props` are passed, compiles to a custom element and overrides the values exported by the component. | `false` | | `cascade` | `true`, `false` | Whether to cascade all of the component's styles to child components. If `false`, only selectors wrapped in `:global(...)` and keyframe IDs beginning with `-global-` are cascaded. | `true` | +| `bind` | `boolean` | If `false`, disallows `bind:` directives | `true` | | | | | | `shared` | `true`, `false`, `string` | Whether to import various helpers from a shared external library. When you have a project with multiple components, this reduces the overall size of your JavaScript bundle, at the expense of having immediately-usable component. You can pass a string of the module path to use, or `true` will import from `'svelte/shared.js'`. | `false` | | `legacy` | `true`, `false` | Ensures compatibility with very old browsers, at the cost of some extra code. | `false` | @@ -93,7 +94,6 @@ The Svelte compiler optionally takes a second argument, an object of configurati | | | | | `onerror` | `function` | Specify a callback for when Svelte encounters an error while compiling the component. Passed two arguments: the error object, and another function that is Svelte's default onerror handling. | (exception is thrown) | | `onwarn` | `function` | Specify a callback for when Svelte encounters a non-fatal warning while compiling the component. Passed two arguments: the warning object, and another function that is Svelte's default onwarn handling. | (warning is logged to console) | -| `bind` | `boolean` | If `false`, disallows `bind:` directives | ### Preprocessor options