From 7e5f008a78beb7727c8771ead390b0b44604be26 Mon Sep 17 00:00:00 2001 From: Admin Date: Tue, 7 Aug 2018 22:22:36 -0500 Subject: [PATCH 1/5] Adds DebugTag --- src/compile/nodes/DebugTag.ts | 25 ++++++++++++++++ src/compile/nodes/Element.ts | 39 ++++++++++++++++++++++++- src/compile/nodes/shared/mapChildren.ts | 2 ++ src/parse/state/mustache.ts | 14 +++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/compile/nodes/DebugTag.ts diff --git a/src/compile/nodes/DebugTag.ts b/src/compile/nodes/DebugTag.ts new file mode 100644 index 0000000000..ac12928e58 --- /dev/null +++ b/src/compile/nodes/DebugTag.ts @@ -0,0 +1,25 @@ +import Node from './shared/Node'; +import Tag from './shared/Tag'; +import Block from '../dom/Block'; +import deindent from '../../utils/deindent'; + +export default class DebugTag extends Tag { + build( + block: Block, + parentNode: string, + parentNodes: string, + ) { + const { dependencies } = this.expression; + + const condition = [...dependencies].map(d => `changed.${d}`).join(' || '); + + const identifiers = [...dependencies].join(', '); + + block.builders.update.addBlock(deindent` + if (${condition}) { + const { ${identifiers} } = ctx; + debugger; + } + `); + } +} \ No newline at end of file diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index 403b9cce8b..6fcf0c013b 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -21,7 +21,44 @@ import mapChildren from './shared/mapChildren'; import { dimensions } from '../../utils/patterns'; // source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7 -const booleanAttributes = new Set('async autocomplete autofocus autoplay border challenge checked compact contenteditable controls default defer disabled formnovalidate frameborder hidden indeterminate ismap loop multiple muted nohref noresize noshade novalidate nowrap open readonly required reversed scoped scrolling seamless selected sortable spellcheck translate'.split(' ')); +const booleanAttributes = new Set(['async', + 'autocomplete', + 'autofocus', + 'autoplay', + 'border', + 'challenge', + 'checked', + 'compact', + 'contenteditable', + 'controls', + 'default', + 'defer', + 'disabled', + 'formnovalidate', + 'frameborder', + 'hidden', + 'indeterminate', + 'ismap', + 'loop', + 'multiple', + 'muted', + 'nohref', + 'noresize', + 'noshade', + 'novalidate', + 'nowrap', + 'open', + 'readonly', + 'required', + 'reversed', + 'scoped', + 'scrolling', + 'seamless', + 'selected', + 'sortable', + 'spellcheck', + 'translate' +]); export default class Element extends Node { type: 'Element'; diff --git a/src/compile/nodes/shared/mapChildren.ts b/src/compile/nodes/shared/mapChildren.ts index 0a0a111322..9cd238644c 100644 --- a/src/compile/nodes/shared/mapChildren.ts +++ b/src/compile/nodes/shared/mapChildren.ts @@ -7,6 +7,7 @@ import Head from '../Head'; import IfBlock from '../IfBlock'; import MustacheTag from '../MustacheTag'; import RawMustacheTag from '../RawMustacheTag'; +import DebugTag from '../DebugTag'; import Slot from '../Slot'; import Text from '../Text'; import Title from '../Title'; @@ -24,6 +25,7 @@ function getConstructor(type): typeof Node { case 'IfBlock': return IfBlock; case 'MustacheTag': return MustacheTag; case 'RawMustacheTag': return RawMustacheTag; + case 'DebugTag': return DebugTag; case 'Slot': return Slot; case 'Text': return Text; case 'Title': return Title; diff --git a/src/parse/state/mustache.ts b/src/parse/state/mustache.ts index cbac76e6a1..211ca2a349 100644 --- a/src/parse/state/mustache.ts +++ b/src/parse/state/mustache.ts @@ -313,6 +313,20 @@ export default function mustache(parser: Parser) { type: 'RawMustacheTag', expression, }); + } else if (parser.eat('@debug')) { + const expression = readExpression(parser); + + parser.allowWhitespace(); + parser.eat('}', true); + + // console.error(expression); + + parser.current().children.push({ + start, + end: parser.index, + type: 'DebugTag', + expression + }); } else { const expression = readExpression(parser); From 622e7b019085b7ae6a5645c84f1cc860bd5ca802 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 8 Aug 2018 00:36:52 -0500 Subject: [PATCH 2/5] Adds debug all option to debug tag --- src/compile/nodes/DebugTag.ts | 22 ++++++++++++------- src/parse/state/mustache.ts | 6 ++--- src/validate/html/index.ts | 13 +++++++++++ .../samples/redundant-debug-all/errors.json | 15 +++++++++++++ .../samples/redundant-debug-all/input.html | 12 ++++++++++ 5 files changed, 56 insertions(+), 12 deletions(-) create mode 100644 test/validator/samples/redundant-debug-all/errors.json create mode 100644 test/validator/samples/redundant-debug-all/input.html diff --git a/src/compile/nodes/DebugTag.ts b/src/compile/nodes/DebugTag.ts index ac12928e58..e56eba171f 100644 --- a/src/compile/nodes/DebugTag.ts +++ b/src/compile/nodes/DebugTag.ts @@ -11,15 +11,21 @@ export default class DebugTag extends Tag { ) { const { dependencies } = this.expression; - const condition = [...dependencies].map(d => `changed.${d}`).join(' || '); + // Debug all + if (dependencies.has('_')) { + block.builders.create.addLine('debugger;'); + block.builders.update.addLine('debugger;'); + } else { + const condition = [...dependencies].map(d => `changed.${d}`).join(' || '); - const identifiers = [...dependencies].join(', '); + const identifiers = [...dependencies].join(', '); - block.builders.update.addBlock(deindent` - if (${condition}) { - const { ${identifiers} } = ctx; - debugger; - } - `); + block.builders.update.addBlock(deindent` + if (${condition}) { + const { ${identifiers} } = ctx; + debugger; + } + `); + } } } \ No newline at end of file diff --git a/src/parse/state/mustache.ts b/src/parse/state/mustache.ts index 211ca2a349..f3fb0c530b 100644 --- a/src/parse/state/mustache.ts +++ b/src/parse/state/mustache.ts @@ -315,17 +315,15 @@ export default function mustache(parser: Parser) { }); } else if (parser.eat('@debug')) { const expression = readExpression(parser); - + parser.allowWhitespace(); parser.eat('}', true); - // console.error(expression); - parser.current().children.push({ start, end: parser.index, type: 'DebugTag', - expression + expression, }); } else { const expression = readExpression(parser); diff --git a/src/validate/html/index.ts b/src/validate/html/index.ts index ed4eaf4d38..f4f8827785 100644 --- a/src/validate/html/index.ts +++ b/src/validate/html/index.ts @@ -74,6 +74,19 @@ export default function validateHtml(validator: Validator, html: Node) { }); } + else if (node.type === 'DebugTag') { + // Only allow the `_` expression if it's by itself + // i.e. {@debug _, name } is redundantredundant-debug-all + const names = node.expression.expressions.map(e => e.name); + + if (names.length > 0 && names.includes('_')) { + validator.error(node, { + code: 'redundant-debug-all', + message: `Combining other expressions with '_' is redundant` + }); + } + } + if (validator.options.dev && isEmptyBlock(node)) { validator.warn(node, { code: `empty-block`, diff --git a/test/validator/samples/redundant-debug-all/errors.json b/test/validator/samples/redundant-debug-all/errors.json new file mode 100644 index 0000000000..e7d9d783bd --- /dev/null +++ b/test/validator/samples/redundant-debug-all/errors.json @@ -0,0 +1,15 @@ +[{ + "message": "Combining other expressions with '_' is redundant", + "start": { + "line": 1, + "column": 0, + "character": 0 + }, + "end":{ + "line": 1, + "column": 16, + "character": 16 + }, + "pos": 0, + "code": "redundant-debug-all" +}] \ No newline at end of file diff --git a/test/validator/samples/redundant-debug-all/input.html b/test/validator/samples/redundant-debug-all/input.html new file mode 100644 index 0000000000..fc4f79832e --- /dev/null +++ b/test/validator/samples/redundant-debug-all/input.html @@ -0,0 +1,12 @@ +{@debug _, name} +
Hello {name}!
+ + \ No newline at end of file From 79c023e604039873d15ccde57f918618c006b38c Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 8 Aug 2018 00:41:36 -0500 Subject: [PATCH 3/5] Fixes small issue with Element's booleanAttributes --- src/compile/nodes/Element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index 6fcf0c013b..d8c7bb3a7a 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -21,7 +21,8 @@ import mapChildren from './shared/mapChildren'; import { dimensions } from '../../utils/patterns'; // source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7 -const booleanAttributes = new Set(['async', +const booleanAttributes = new Set([ + 'async', 'autocomplete', 'autofocus', 'autoplay', From a3c71af5c5860d4bfcdbfa63256b35a99a21a3e5 Mon Sep 17 00:00:00 2001 From: Admin Date: Wed, 8 Aug 2018 18:21:33 -0500 Subject: [PATCH 4/5] Changes {@debug _ } to {@debug} --- src/compile/nodes/DebugTag.ts | 21 +++++++++++++++---- src/parse/state/mustache.ts | 8 ++++++- src/validate/html/index.ts | 13 ------------ .../samples/redundant-debug-all/errors.json | 15 ------------- .../samples/redundant-debug-all/input.html | 12 ----------- 5 files changed, 24 insertions(+), 45 deletions(-) delete mode 100644 test/validator/samples/redundant-debug-all/errors.json delete mode 100644 test/validator/samples/redundant-debug-all/input.html diff --git a/src/compile/nodes/DebugTag.ts b/src/compile/nodes/DebugTag.ts index e56eba171f..7bd2742c4f 100644 --- a/src/compile/nodes/DebugTag.ts +++ b/src/compile/nodes/DebugTag.ts @@ -1,21 +1,34 @@ import Node from './shared/Node'; import Tag from './shared/Tag'; import Block from '../dom/Block'; +import Expression from './shared/Expression'; import deindent from '../../utils/deindent'; -export default class DebugTag extends Tag { +export default class DebugTag extends Node { + expression: Expression; + + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + if (info.expression !== null) + // Debug when expression nodes change + this.expression = new Expression(compiler, parent, scope, info.expression); + else + // "Debug all" + this.expression = info.expression + } + build( block: Block, parentNode: string, parentNodes: string, ) { - const { dependencies } = this.expression; - // Debug all - if (dependencies.has('_')) { + if (this.expression === null) { block.builders.create.addLine('debugger;'); block.builders.update.addLine('debugger;'); } else { + const { dependencies } = this.expression; + const condition = [...dependencies].map(d => `changed.${d}`).join(' || '); const identifiers = [...dependencies].join(', '); diff --git a/src/parse/state/mustache.ts b/src/parse/state/mustache.ts index f3fb0c530b..8450074c66 100644 --- a/src/parse/state/mustache.ts +++ b/src/parse/state/mustache.ts @@ -314,7 +314,13 @@ export default function mustache(parser: Parser) { expression, }); } else if (parser.eat('@debug')) { - const expression = readExpression(parser); + let expression; + + // Implies {@debug} which indicates "debug all" + if (/\s*}/.test(parser.template[parser.index])) + expression = null; + else + expression = readExpression(parser); parser.allowWhitespace(); parser.eat('}', true); diff --git a/src/validate/html/index.ts b/src/validate/html/index.ts index f4f8827785..ed4eaf4d38 100644 --- a/src/validate/html/index.ts +++ b/src/validate/html/index.ts @@ -74,19 +74,6 @@ export default function validateHtml(validator: Validator, html: Node) { }); } - else if (node.type === 'DebugTag') { - // Only allow the `_` expression if it's by itself - // i.e. {@debug _, name } is redundantredundant-debug-all - const names = node.expression.expressions.map(e => e.name); - - if (names.length > 0 && names.includes('_')) { - validator.error(node, { - code: 'redundant-debug-all', - message: `Combining other expressions with '_' is redundant` - }); - } - } - if (validator.options.dev && isEmptyBlock(node)) { validator.warn(node, { code: `empty-block`, diff --git a/test/validator/samples/redundant-debug-all/errors.json b/test/validator/samples/redundant-debug-all/errors.json deleted file mode 100644 index e7d9d783bd..0000000000 --- a/test/validator/samples/redundant-debug-all/errors.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "message": "Combining other expressions with '_' is redundant", - "start": { - "line": 1, - "column": 0, - "character": 0 - }, - "end":{ - "line": 1, - "column": 16, - "character": 16 - }, - "pos": 0, - "code": "redundant-debug-all" -}] \ No newline at end of file diff --git a/test/validator/samples/redundant-debug-all/input.html b/test/validator/samples/redundant-debug-all/input.html deleted file mode 100644 index fc4f79832e..0000000000 --- a/test/validator/samples/redundant-debug-all/input.html +++ /dev/null @@ -1,12 +0,0 @@ -{@debug _, name} -
Hello {name}!
- - \ No newline at end of file From 2d992b7e5568ff733ef43d13cfb0a6afeb437b51 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 10 Aug 2018 11:17:35 -0400 Subject: [PATCH 5/5] add some failing tests for #1635 --- .../js/samples/debug-empty/expected-bundle.js | 200 ++++++++++++ test/js/samples/debug-empty/expected.js | 56 ++++ test/js/samples/debug-empty/input.html | 2 + .../expected-bundle.js | 290 ++++++++++++++++++ .../debug-foo-bar-baz-things/expected.js | 140 +++++++++ .../debug-foo-bar-baz-things/input.html | 6 + .../samples/debug-invalid/errors.json | 15 + .../samples/debug-invalid/input.html | 4 + 8 files changed, 713 insertions(+) create mode 100644 test/js/samples/debug-empty/expected-bundle.js create mode 100644 test/js/samples/debug-empty/expected.js create mode 100644 test/js/samples/debug-empty/input.html create mode 100644 test/js/samples/debug-foo-bar-baz-things/expected-bundle.js create mode 100644 test/js/samples/debug-foo-bar-baz-things/expected.js create mode 100644 test/js/samples/debug-foo-bar-baz-things/input.html create mode 100644 test/validator/samples/debug-invalid/errors.json create mode 100644 test/validator/samples/debug-invalid/input.html diff --git a/test/js/samples/debug-empty/expected-bundle.js b/test/js/samples/debug-empty/expected-bundle.js new file mode 100644 index 0000000000..ba3b1dda59 --- /dev/null +++ b/test/js/samples/debug-empty/expected-bundle.js @@ -0,0 +1,200 @@ +function noop() {} + +function assign(tar, src) { + for (var k in src) tar[k] = src[k]; + return tar; +} + +function append(target, node) { + target.appendChild(node); +} + +function insert(target, node, anchor) { + target.insertBefore(node, anchor); +} + +function detachNode(node) { + node.parentNode.removeChild(node); +} + +function createElement(name) { + return document.createElement(name); +} + +function createText(data) { + return document.createTextNode(data); +} + +function setData(text, data) { + text.data = '' + data; +} + +function blankObject() { + return Object.create(null); +} + +function destroy(detach) { + this.destroy = noop; + this.fire('destroy'); + this.set = noop; + + this._fragment.d(detach !== false); + this._fragment = null; + this._state = {}; +} + +function _differs(a, b) { + return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); +} + +function fire(eventName, data) { + var handlers = + eventName in this._handlers && this._handlers[eventName].slice(); + if (!handlers) return; + + for (var i = 0; i < handlers.length; i += 1) { + var handler = handlers[i]; + + if (!handler.__calling) { + try { + handler.__calling = true; + handler.call(this, data); + } finally { + handler.__calling = false; + } + } + } +} + +function get() { + return this._state; +} + +function init(component, options) { + component._handlers = blankObject(); + component._bind = options._bind; + + component.options = options; + component.root = options.root || component; + component.store = options.store || component.root.store; +} + +function on(eventName, handler) { + var handlers = this._handlers[eventName] || (this._handlers[eventName] = []); + handlers.push(handler); + + return { + cancel: function() { + var index = handlers.indexOf(handler); + if (~index) handlers.splice(index, 1); + } + }; +} + +function set(newState) { + this._set(assign({}, newState)); + if (this.root._lock) return; + this.root._lock = true; + callAll(this.root._beforecreate); + callAll(this.root._oncreate); + callAll(this.root._aftercreate); + this.root._lock = false; +} + +function _set(newState) { + var oldState = this._state, + changed = {}, + dirty = false; + + for (var key in newState) { + if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true; + } + if (!dirty) return; + + this._state = assign(assign({}, oldState), newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + this.fire("state", { changed: changed, current: this._state, previous: oldState }); + this._fragment.p(changed, this._state); + this.fire("update", { changed: changed, current: this._state, previous: oldState }); + } +} + +function callAll(fns) { + while (fns && fns.length) fns.shift()(); +} + +function _mount(target, anchor) { + this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); +} + +var proto = { + destroy, + get, + fire, + on, + set, + _recompute: noop, + _set, + _mount, + _differs +}; + +/* generated by Svelte vX.Y.Z */ + +function create_main_fragment(component, ctx) { + var h1, text, text_1, text_2, text_3; + + return { + c() { + h1 = createElement("h1"); + text = createText("Hello "); + text_1 = createText(ctx.name); + text_2 = createText("!"); + text_3 = createText("\n"); + debugger; + }, + + m(target, anchor) { + insert(target, h1, anchor); + append(h1, text); + append(h1, text_1); + append(h1, text_2); + insert(target, text_3, anchor); + }, + + p(changed, ctx) { + if (changed.name) { + setData(text_1, ctx.name); + } + + debugger; + }, + + d(detach) { + if (detach) { + detachNode(h1); + detachNode(text_3); + } + } + }; +} + +function SvelteComponent(options) { + init(this, options); + this._state = assign({}, options.data); + this._intro = true; + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } +} + +assign(SvelteComponent.prototype, proto); + +export default SvelteComponent; diff --git a/test/js/samples/debug-empty/expected.js b/test/js/samples/debug-empty/expected.js new file mode 100644 index 0000000000..592f3a7a2b --- /dev/null +++ b/test/js/samples/debug-empty/expected.js @@ -0,0 +1,56 @@ +/* generated by Svelte vX.Y.Z */ +import { append, assign, createElement, createText, detachNode, init, insert, proto, setData } from "svelte/shared.js"; + +function create_main_fragment(component, ctx) { + var h1, text, text_1, text_2, text_3; + + return { + c() { + h1 = createElement("h1"); + text = createText("Hello "); + text_1 = createText(ctx.name); + text_2 = createText("!"); + text_3 = createText("\n"); + debugger; + }, + + m(target, anchor) { + insert(target, h1, anchor); + append(h1, text); + append(h1, text_1); + append(h1, text_2); + insert(target, text_3, anchor); + }, + + p(changed, ctx) { + if (changed.name) { + setData(text_1, ctx.name); + } + + debugger; + }, + + d(detach) { + if (detach) { + detachNode(h1); + detachNode(text_3); + } + } + }; +} + +function SvelteComponent(options) { + init(this, options); + this._state = assign({}, options.data); + this._intro = true; + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } +} + +assign(SvelteComponent.prototype, proto); +export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/debug-empty/input.html b/test/js/samples/debug-empty/input.html new file mode 100644 index 0000000000..11da4f6d15 --- /dev/null +++ b/test/js/samples/debug-empty/input.html @@ -0,0 +1,2 @@ +

Hello {name}!

+{@debug} \ No newline at end of file diff --git a/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js b/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js new file mode 100644 index 0000000000..e6796c685f --- /dev/null +++ b/test/js/samples/debug-foo-bar-baz-things/expected-bundle.js @@ -0,0 +1,290 @@ +function noop() {} + +function assign(tar, src) { + for (var k in src) tar[k] = src[k]; + return tar; +} + +function append(target, node) { + target.appendChild(node); +} + +function insert(target, node, anchor) { + target.insertBefore(node, anchor); +} + +function detachNode(node) { + node.parentNode.removeChild(node); +} + +function destroyEach(iterations, detach) { + for (var i = 0; i < iterations.length; i += 1) { + if (iterations[i]) iterations[i].d(detach); + } +} + +function createElement(name) { + return document.createElement(name); +} + +function createText(data) { + return document.createTextNode(data); +} + +function setData(text, data) { + text.data = '' + data; +} + +function blankObject() { + return Object.create(null); +} + +function destroy(detach) { + this.destroy = noop; + this.fire('destroy'); + this.set = noop; + + this._fragment.d(detach !== false); + this._fragment = null; + this._state = {}; +} + +function _differs(a, b) { + return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); +} + +function fire(eventName, data) { + var handlers = + eventName in this._handlers && this._handlers[eventName].slice(); + if (!handlers) return; + + for (var i = 0; i < handlers.length; i += 1) { + var handler = handlers[i]; + + if (!handler.__calling) { + try { + handler.__calling = true; + handler.call(this, data); + } finally { + handler.__calling = false; + } + } + } +} + +function get() { + return this._state; +} + +function init(component, options) { + component._handlers = blankObject(); + component._bind = options._bind; + + component.options = options; + component.root = options.root || component; + component.store = options.store || component.root.store; +} + +function on(eventName, handler) { + var handlers = this._handlers[eventName] || (this._handlers[eventName] = []); + handlers.push(handler); + + return { + cancel: function() { + var index = handlers.indexOf(handler); + if (~index) handlers.splice(index, 1); + } + }; +} + +function set(newState) { + this._set(assign({}, newState)); + if (this.root._lock) return; + this.root._lock = true; + callAll(this.root._beforecreate); + callAll(this.root._oncreate); + callAll(this.root._aftercreate); + this.root._lock = false; +} + +function _set(newState) { + var oldState = this._state, + changed = {}, + dirty = false; + + for (var key in newState) { + if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true; + } + if (!dirty) return; + + this._state = assign(assign({}, oldState), newState); + this._recompute(changed, this._state); + if (this._bind) this._bind(changed, this._state); + + if (this._fragment) { + this.fire("state", { changed: changed, current: this._state, previous: oldState }); + this._fragment.p(changed, this._state); + this.fire("update", { changed: changed, current: this._state, previous: oldState }); + } +} + +function callAll(fns) { + while (fns && fns.length) fns.shift()(); +} + +function _mount(target, anchor) { + this._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null); +} + +var proto = { + destroy, + get, + fire, + on, + set, + _recompute: noop, + _set, + _mount, + _differs +}; + +/* generated by Svelte vX.Y.Z */ + +function create_main_fragment(component, ctx) { + var text, p, text_1, text_2; + + var each_value = ctx.things; + + var each_blocks = []; + + for (var i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block(component, get_each_context(ctx, each_value, i)); + } + + return { + c() { + for (var i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + text = createText("\n\n"); + p = createElement("p"); + text_1 = createText("foo: "); + text_2 = createText(ctx.foo); + }, + + m(target, anchor) { + for (var i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(target, anchor); + } + + insert(target, text, anchor); + insert(target, p, anchor); + append(p, text_1); + append(p, text_2); + }, + + p(changed, ctx) { + if (changed.things) { + each_value = ctx.things; + + for (var i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(changed, child_ctx); + } else { + each_blocks[i] = create_each_block(component, child_ctx); + each_blocks[i].c(); + each_blocks[i].m(text.parentNode, text); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + each_blocks.length = each_value.length; + } + + if (changed.foo) { + setData(text_2, ctx.foo); + } + }, + + d(detach) { + destroyEach(each_blocks, detach); + + if (detach) { + detachNode(text); + detachNode(p); + } + } + }; +} + +// (1:0) {#each things as thing} +function create_each_block(component, ctx) { + var span, text_value = ctx.thing.name, text, text_1; + + return { + c() { + span = createElement("span"); + text = createText(text_value); + text_1 = createText("\n\t"); + + const { foo, bar, baz } = ctx; + console.log({ foo, bar, baz }); + debugger; + }, + + m(target, anchor) { + insert(target, span, anchor); + append(span, text); + insert(target, text_1, anchor); + }, + + p(changed, ctx) { + if ((changed.things) && text_value !== (text_value = ctx.thing.name)) { + setData(text, text_value); + } + + if (changed.foo || changed.bar || changed.baz) { + const { foo, bar, baz } = ctx; + console.log({ foo, bar, baz }); + debugger; + } + }, + + d(detach) { + if (detach) { + detachNode(span); + detachNode(text_1); + } + } + }; +} + +function get_each_context(ctx, list, i) { + const child_ctx = Object.create(ctx); + child_ctx.thing = list[i]; + child_ctx.each_value = list; + child_ctx.thing_index = i; + return child_ctx; +} + +function SvelteComponent(options) { + init(this, options); + this._state = assign({}, options.data); + this._intro = true; + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } +} + +assign(SvelteComponent.prototype, proto); + +export default SvelteComponent; diff --git a/test/js/samples/debug-foo-bar-baz-things/expected.js b/test/js/samples/debug-foo-bar-baz-things/expected.js new file mode 100644 index 0000000000..1406c3b927 --- /dev/null +++ b/test/js/samples/debug-foo-bar-baz-things/expected.js @@ -0,0 +1,140 @@ +/* generated by Svelte vX.Y.Z */ +import { append, assign, createElement, createText, destroyEach, detachNode, init, insert, proto, setData } from "svelte/shared.js"; + +function create_main_fragment(component, ctx) { + var text, p, text_1, text_2; + + var each_value = ctx.things; + + var each_blocks = []; + + for (var i = 0; i < each_value.length; i += 1) { + each_blocks[i] = create_each_block(component, get_each_context(ctx, each_value, i)); + } + + return { + c() { + for (var i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].c(); + } + + text = createText("\n\n"); + p = createElement("p"); + text_1 = createText("foo: "); + text_2 = createText(ctx.foo); + }, + + m(target, anchor) { + for (var i = 0; i < each_blocks.length; i += 1) { + each_blocks[i].m(target, anchor); + } + + insert(target, text, anchor); + insert(target, p, anchor); + append(p, text_1); + append(p, text_2); + }, + + p(changed, ctx) { + if (changed.things) { + each_value = ctx.things; + + for (var i = 0; i < each_value.length; i += 1) { + const child_ctx = get_each_context(ctx, each_value, i); + + if (each_blocks[i]) { + each_blocks[i].p(changed, child_ctx); + } else { + each_blocks[i] = create_each_block(component, child_ctx); + each_blocks[i].c(); + each_blocks[i].m(text.parentNode, text); + } + } + + for (; i < each_blocks.length; i += 1) { + each_blocks[i].d(1); + } + each_blocks.length = each_value.length; + } + + if (changed.foo) { + setData(text_2, ctx.foo); + } + }, + + d(detach) { + destroyEach(each_blocks, detach); + + if (detach) { + detachNode(text); + detachNode(p); + } + } + }; +} + +// (1:0) {#each things as thing} +function create_each_block(component, ctx) { + var span, text_value = ctx.thing.name, text, text_1; + + return { + c() { + span = createElement("span"); + text = createText(text_value); + text_1 = createText("\n\t"); + + const { foo, bar, baz, thing } = ctx; + console.log({ foo, bar, baz, thing }); + debugger; + }, + + m(target, anchor) { + insert(target, span, anchor); + append(span, text); + insert(target, text_1, anchor); + }, + + p(changed, ctx) { + if ((changed.things) && text_value !== (text_value = ctx.thing.name)) { + setData(text, text_value); + } + + if (changed.foo || changed.bar || changed.baz || changed.things) { + const { foo, bar, baz, thing } = ctx; + console.log({ foo, bar, baz, thing }); + debugger; + } + }, + + d(detach) { + if (detach) { + detachNode(span); + detachNode(text_1); + } + } + }; +} + +function get_each_context(ctx, list, i) { + const child_ctx = Object.create(ctx); + child_ctx.thing = list[i]; + child_ctx.each_value = list; + child_ctx.thing_index = i; + return child_ctx; +} + +function SvelteComponent(options) { + init(this, options); + this._state = assign({}, options.data); + this._intro = true; + + this._fragment = create_main_fragment(this, this._state); + + if (options.target) { + this._fragment.c(); + this._mount(options.target, options.anchor); + } +} + +assign(SvelteComponent.prototype, proto); +export default SvelteComponent; \ No newline at end of file diff --git a/test/js/samples/debug-foo-bar-baz-things/input.html b/test/js/samples/debug-foo-bar-baz-things/input.html new file mode 100644 index 0000000000..6fa8611415 --- /dev/null +++ b/test/js/samples/debug-foo-bar-baz-things/input.html @@ -0,0 +1,6 @@ +{#each things as thing} + {thing.name} + {@debug foo, bar, baz, thing} +{/each} + +

foo: {foo}

\ No newline at end of file diff --git a/test/validator/samples/debug-invalid/errors.json b/test/validator/samples/debug-invalid/errors.json new file mode 100644 index 0000000000..1dc4507a39 --- /dev/null +++ b/test/validator/samples/debug-invalid/errors.json @@ -0,0 +1,15 @@ +[{ + "code": "invalid-debug", + "message": "{@debug ...} arguments must be identifers, not arbitrary expressions", + "start": { + "line": 2, + "column": 9, + "character": 13 + }, + "end": { + "line": 2, + "column": 14, + "character": 18 + }, + "pos": 13 +}] \ No newline at end of file diff --git a/test/validator/samples/debug-invalid/input.html b/test/validator/samples/debug-invalid/input.html new file mode 100644 index 0000000000..5c89e7049d --- /dev/null +++ b/test/validator/samples/debug-invalid/input.html @@ -0,0 +1,4 @@ +

+ {@debug a + b} + {a + b} +

\ No newline at end of file