Merge branch 'master' into gh-910

pull/922/head
Rich Harris 8 years ago
commit 744a2bb7f3

@ -1,5 +1,12 @@
# Svelte changelog
## 1.41.4
* Handle self-destructive bindings ([#917](https://github.com/sveltejs/svelte/issues/917))
* Prevent `innerHTML` with `<option>` elements ([#915](https://github.com/sveltejs/svelte/issues/915))
* Use `dataset` unless `legacy` is true ([#858](https://github.com/sveltejs/svelte/issues/858))
* Add `prepare` script to facilitate installing from git ([#923](https://github.com/sveltejs/svelte/pull/923))
## 1.41.3
* Prevent argument name clashes ([#911](https://github.com/sveltejs/svelte/issues/911))

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "1.41.3",
"version": "1.41.4",
"description": "The magical disappearing UI framework",
"main": "compiler/svelte.js",
"files": [
@ -18,6 +18,7 @@
"precodecov": "npm run coverage",
"lint": "eslint src test/*.js",
"build": "node src/shared/_build.js && rollup -c",
"prepare": "npm run build",
"dev": "node src/shared/_build.js && rollup -c -w",
"pretest": "npm run build",
"prepublishOnly": "npm run lint && npm test",

@ -12,6 +12,7 @@ import namespaces from '../utils/namespaces';
import { removeNode, removeObjectKey } from '../utils/removeNode';
import wrapModule from './shared/utils/wrapModule';
import annotateWithScopes from '../utils/annotateWithScopes';
import getName from '../utils/getName';
import clone from '../utils/clone';
import DomBlock from './dom/Block';
import SsrBlock from './server-side-rendering/Block';
@ -497,13 +498,13 @@ export default class Generator {
if (defaultExport) {
defaultExport.declaration.properties.forEach((prop: Node) => {
templateProperties[prop.key.name] = prop;
templateProperties[getName(prop.key)] = prop;
});
['helpers', 'events', 'components', 'transitions'].forEach(key => {
if (templateProperties[key]) {
templateProperties[key].value.properties.forEach((prop: Node) => {
this[key].add(prop.key.name);
this[key].add(getName(prop.key));
});
}
});
@ -574,7 +575,7 @@ export default class Generator {
if (templateProperties.components) {
templateProperties.components.value.properties.forEach((property: Node) => {
addDeclaration(property.key.name, property.value, 'components');
addDeclaration(getName(property.key), property.value, 'components');
});
}
@ -582,7 +583,7 @@ export default class Generator {
const dependencies = new Map();
templateProperties.computed.value.properties.forEach((prop: Node) => {
const key = prop.key.name;
const key = getName(prop.key);
const value = prop.value;
const deps = value.params.map(
@ -605,12 +606,12 @@ export default class Generator {
computations.push({ key, deps });
const prop = templateProperties.computed.value.properties.find((prop: Node) => prop.key.name === key);
const prop = templateProperties.computed.value.properties.find((prop: Node) => getName(prop.key) === key);
addDeclaration(key, prop.value, 'computed');
};
templateProperties.computed.value.properties.forEach((prop: Node) =>
visit(prop.key.name)
visit(getName(prop.key))
);
}
@ -620,13 +621,13 @@ export default class Generator {
if (templateProperties.events && dom) {
templateProperties.events.value.properties.forEach((property: Node) => {
addDeclaration(property.key.name, property.value, 'events');
addDeclaration(getName(property.key), property.value, 'events');
});
}
if (templateProperties.helpers) {
templateProperties.helpers.value.properties.forEach((property: Node) => {
addDeclaration(property.key.name, property.value, 'helpers');
addDeclaration(getName(property.key), property.value, 'helpers');
});
}
@ -663,7 +664,7 @@ export default class Generator {
if (templateProperties.transitions) {
templateProperties.transitions.value.properties.forEach((property: Node) => {
addDeclaration(property.key.name, property.value, 'transitions');
addDeclaration(getName(property.key), property.value, 'transitions');
});
}
}

@ -309,7 +309,7 @@ const preprocessors = {
stripWhitespace: boolean,
nextSibling: Node
) => {
if (node.name === 'slot') {
if (node.name === 'slot' || node.name === 'option') {
cannotUseInnerHTML(node);
}
@ -358,6 +358,19 @@ const preprocessors = {
}
});
const valueAttribute = node.attributes.find((attribute: Node) => attribute.name === 'value');
// Treat these the same way:
// <option>{{foo}}</option>
// <option value='{{foo}}'>{{foo}}</option>
if (node.name === 'option' && !valueAttribute) {
node.attributes.push({
type: 'Attribute',
name: 'value',
value: node.children
});
}
// special case — in a case like this...
//
// <select bind:value='foo'>
@ -369,14 +382,9 @@ const preprocessors = {
// so that if `foo.qux` changes, we know that we need to
// mark `bar` and `baz` as dirty too
if (node.name === 'select') {
cannotUseInnerHTML(node);
const value = node.attributes.find(
(attribute: Node) => attribute.name === 'value'
);
if (value) {
if (valueAttribute) {
// TODO does this also apply to e.g. `<input type='checkbox' bind:group='foo'>`?
const dependencies = block.findDependencies(value.value);
const dependencies = block.findDependencies(valueAttribute.value);
state.selectBindingDependencies = dependencies;
dependencies.forEach((prop: string) => {
generator.indirectDependencies.set(prop, new Set());

@ -3,7 +3,6 @@ import deindent from '../../../../utils/deindent';
import visitStyleAttribute, { optimizeStyle } from './StyleAttribute';
import { stringify } from '../../../../utils/stringify';
import getExpressionPrecedence from '../../../../utils/getExpressionPrecedence';
import getStaticAttributeValue from '../../../../utils/getStaticAttributeValue';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
@ -56,6 +55,11 @@ export default function visitAttribute(
const isLegacyInputType = generator.legacy && name === 'type' && node.name === 'input';
const isDataSet = /^data-/.test(name) && !generator.legacy;
const camelCaseName = isDataSet ? name.replace('data-', '').replace(/(-\w)/g, function (m) {
return m[1].toUpperCase();
}) : name;
if (isDynamic) {
let value;
@ -163,6 +167,11 @@ export default function visitAttribute(
`${state.parentNode}.${propertyName} = ${init};`
);
updater = `${state.parentNode}.${propertyName} = ${shouldCache || isSelectValueAttribute ? last : value};`;
} else if (isDataSet) {
block.builders.hydrate.addLine(
`${state.parentNode}.dataset.${camelCaseName} = ${init};`
);
updater = `${state.parentNode}.dataset.${camelCaseName} = ${shouldCache || isSelectValueAttribute ? last : value};`;
} else {
block.builders.hydrate.addLine(
`${method}(${state.parentNode}, "${name}", ${init});`
@ -198,6 +207,7 @@ export default function visitAttribute(
const statement = (
isLegacyInputType ? `@setInputType(${state.parentNode}, ${value});` :
propertyName ? `${state.parentNode}.${propertyName} = ${value};` :
isDataSet ? `${state.parentNode}.dataset.${camelCaseName} = ${value};` :
`${method}(${state.parentNode}, "${name}", ${value});`
);
@ -221,4 +231,4 @@ export default function visitAttribute(
block.builders.hydrate.addLine(updateValue);
if (isDynamic) block.builders.update.addLine(updateValue);
}
}
}

@ -190,19 +190,6 @@ export default function visitElement(
visitAttributesAndAddProps();
}
// special case bound <option> without a value attribute
if (
node.name === 'option' &&
!node.attributes.find(
(attribute: Node) =>
attribute.type === 'Attribute' && attribute.name === 'value'
)
) {
// TODO check it's bound
const statement = `${name}.__value = ${name}.textContent;`;
node.initialUpdate = node.lateUpdate = statement;
}
if (!childState.namespace && node.canUseInnerHTML && node.children.length > 0) {
if (node.children.length === 1 && node.children[0].type === 'Text') {
block.builders.create.addLine(
@ -219,10 +206,6 @@ export default function visitElement(
});
}
if (node.lateUpdate) {
block.builders.update.addLine(node.lateUpdate);
}
if (node.name === 'select') {
visitAttributesAndAddProps();
}

@ -5,6 +5,7 @@ import Block from './Block';
import preprocess from './preprocess';
import visit from './visit';
import { removeNode, removeObjectKey } from '../../utils/removeNode';
import getName from '../../utils/getName';
import { Parsed, Node, CompileOptions } from '../../interfaces';
import { AppendTarget } from './interfaces';
import { stringify } from '../../utils/stringify';
@ -132,7 +133,7 @@ export default function ssr(
}
${templateProperties.components.value.properties.map((prop: Node) => {
return `addComponent(%components-${prop.key.name});`;
return `addComponent(%components-${getName(prop.key)});`;
})}
`}

@ -69,6 +69,19 @@ const preprocessors = {
if (slot && isChildOfComponent(node, generator)) {
node.slotted = true;
}
// Treat these the same way:
// <option>{{foo}}</option>
// <option value='{{foo}}'>{{foo}}</option>
const valueAttribute = node.attributes.find((attribute: Node) => attribute.name === 'value');
if (node.name === 'option' && !valueAttribute) {
node.attributes.push({
type: 'Attribute',
name: 'value',
value: node.children
});
}
}
if (node.children.length) {

@ -156,9 +156,12 @@ export function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
export function _setDev(newState) {

@ -0,0 +1,6 @@
import { Node } from '../interfaces';
export default function getMethodName(node: Node) {
if (node.type === 'Identifier') return node.name;
if (node.type === 'Literal') return String(node.value);
}

@ -1,4 +1,5 @@
import MagicString from 'magic-string';
import getName from '../utils/getName';
import { Node } from '../interfaces';
const keys = {
@ -51,7 +52,7 @@ export function removeObjectKey(code: MagicString, node: Node, key: string) {
let i = node.properties.length;
while (i--) {
const property = node.properties[i];
if (property.key.type === 'Identifier' && property.key.name === key) {
if (property.key.type === 'Identifier' && getName(property.key) === key) {
removeNode(code, node, property);
}
}

@ -3,6 +3,7 @@ import fuzzymatch from '../utils/fuzzymatch';
import checkForDupes from './utils/checkForDupes';
import checkForComputedKeys from './utils/checkForComputedKeys';
import namespaces from '../../utils/namespaces';
import getName from '../../utils/getName';
import { Validator } from '../';
import { Node } from '../../interfaces';
@ -29,7 +30,7 @@ export default function validateJs(validator: Validator, js: Node) {
const props = validator.properties;
node.declaration.properties.forEach((prop: Node) => {
props.set(prop.key.name, prop);
props.set(getName(prop.key), prop);
});
// Remove these checks in version 2
@ -49,25 +50,26 @@ export default function validateJs(validator: Validator, js: Node) {
// ensure all exported props are valid
node.declaration.properties.forEach((prop: Node) => {
const propValidator = propValidators[prop.key.name];
const name = getName(prop.key);
const propValidator = propValidators[name];
if (propValidator) {
propValidator(validator, prop);
} else {
const match = fuzzymatch(prop.key.name, validPropList);
const match = fuzzymatch(name, validPropList);
if (match) {
validator.error(
`Unexpected property '${prop.key.name}' (did you mean '${match}'?)`,
`Unexpected property '${name}' (did you mean '${match}'?)`,
prop.start
);
} else if (/FunctionExpression/.test(prop.value.type)) {
validator.error(
`Unexpected property '${prop.key.name}' (did you mean to include it in 'methods'?)`,
`Unexpected property '${name}' (did you mean to include it in 'methods'?)`,
prop.start
);
} else {
validator.error(
`Unexpected property '${prop.key.name}'`,
`Unexpected property '${name}'`,
prop.start
);
}
@ -86,7 +88,7 @@ export default function validateJs(validator: Validator, js: Node) {
['components', 'methods', 'helpers', 'transitions'].forEach(key => {
if (validator.properties.has(key)) {
validator.properties.get(key).value.properties.forEach((prop: Node) => {
validator[key].set(prop.key.name, prop.value);
validator[key].set(getName(prop.key), prop.value);
});
}
});

@ -1,5 +1,6 @@
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import getName from '../../../utils/getName';
import { Validator } from '../../';
import { Node } from '../../../interfaces';
@ -16,14 +17,16 @@ export default function components(validator: Validator, prop: Node) {
checkForComputedKeys(validator, prop.value.properties);
prop.value.properties.forEach((component: Node) => {
if (component.key.name === 'state') {
const name = getName(component.key);
if (name === 'state') {
validator.error(
`Component constructors cannot be called 'state' due to technical limitations`,
component.start
);
}
if (!/^[A-Z]/.test(component.key.name)) {
if (!/^[A-Z]/.test(name)) {
validator.warn(`Component names should be capitalised`, component.start);
}
});

@ -2,6 +2,7 @@ import checkForAccessors from '../utils/checkForAccessors';
import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys';
import usesThisOrArguments from '../utils/usesThisOrArguments';
import getName from '../../../utils/getName';
import { Validator } from '../../';
import { Node } from '../../../interfaces';
@ -21,9 +22,11 @@ export default function methods(validator: Validator, prop: Node) {
checkForComputedKeys(validator, prop.value.properties);
prop.value.properties.forEach((prop: Node) => {
if (builtin.has(prop.key.name)) {
const name = getName(prop.key);
if (builtin.has(name)) {
validator.error(
`Cannot overwrite built-in method '${prop.key.name}'`,
`Cannot overwrite built-in method '${name}'`,
prop.start
);
}

@ -1,5 +1,6 @@
import { Validator } from '../../';
import { Node } from '../../../interfaces';
import getName from '../../../utils/getName';
export default function checkForDupes(
validator: Validator,
@ -8,10 +9,12 @@ export default function checkForDupes(
const seen = new Set();
properties.forEach(prop => {
if (seen.has(prop.key.name)) {
validator.error(`Duplicate property '${prop.key.name}'`, prop.start);
const name = getName(prop.key);
if (seen.has(name)) {
validator.error(`Duplicate property '${name}'`, prop.start);
}
seen.add(prop.key.name);
seen.add(name);
});
}

@ -157,9 +157,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -133,9 +133,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -133,9 +133,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -153,9 +153,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -145,9 +145,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -0,0 +1,239 @@
function noop() {}
function assign(target) {
var k,
source,
i = 1,
len = arguments.length;
for (; i < len; i++) {
source = arguments[i];
for (k in source) target[k] = source[k];
}
return target;
}
function insertNode(node, target, 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 blankObject() {
return Object.create(null);
}
function destroy(detach) {
this.destroy = noop;
this.fire('destroy');
this.set = this.get = noop;
if (detach !== false) this._fragment.u();
this._fragment.d();
this._fragment = this._state = null;
}
function differs(a, b) {
return a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function dispatchObservers(component, group, changed, newState, oldState) {
for (var key in group) {
if (!changed[key]) continue;
var newValue = newState[key];
var oldValue = oldState[key];
var callbacks = group[key];
if (!callbacks) continue;
for (var i = 0; i < callbacks.length; i += 1) {
var callback = callbacks[i];
if (callback.__calling) continue;
callback.__calling = true;
callback.call(component, newValue, oldValue);
callback.__calling = false;
}
}
}
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) {
handlers[i].call(this, data);
}
}
function get(key) {
return key ? this._state[key] : this._state;
}
function init(component, options) {
component.options = options;
component._observers = { pre: blankObject(), post: blankObject() };
component._handlers = blankObject();
component._root = options._root || component;
component._bind = options._bind;
}
function observe(key, callback, options) {
var group = options && options.defer
? this._observers.post
: this._observers.pre;
(group[key] || (group[key] = [])).push(callback);
if (!options || options.init !== false) {
callback.__calling = true;
callback.call(this, this._state[key]);
callback.__calling = false;
}
return {
cancel: function() {
var index = group[key].indexOf(callback);
if (~index) group[key].splice(index, 1);
}
};
}
function on(eventName, handler) {
if (eventName === 'teardown') return this.on('destroy', 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 (differs(newState[key], oldState[key])) changed[key] = dirty = true;
}
if (!dirty) return;
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {
while (fns && fns.length) fns.pop()();
}
function _mount(target, anchor) {
this._fragment.m(target, anchor);
}
function _unmount() {
this._fragment.u();
}
var proto = {
destroy: destroy,
get: get,
fire: fire,
observe: observe,
on: on,
set: set,
teardown: destroy,
_recompute: noop,
_set: _set,
_mount: _mount,
_unmount: _unmount
};
/* generated by Svelte vX.Y.Z */
function create_main_fragment(state, component) {
var div, text, div_1;
return {
c: function create() {
div = createElement("div");
text = createText("\n");
div_1 = createElement("div");
this.h();
},
h: function hydrate() {
div.dataset.foo = "bar";
div_1.dataset.foo = state.bar;
},
m: function mount(target, anchor) {
insertNode(div, target, anchor);
insertNode(text, target, anchor);
insertNode(div_1, target, anchor);
},
p: function update(changed, state) {
if (changed.bar) {
div_1.dataset.foo = state.bar;
}
},
u: function unmount() {
detachNode(div);
detachNode(text);
detachNode(div_1);
},
d: noop
};
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._fragment = create_main_fragment(this._state, this);
if (options.target) {
this._fragment.c();
this._fragment.m(options.target, options.anchor || null);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,55 @@
/* generated by Svelte vX.Y.Z */
import { assign, createElement, createText, detachNode, init, insertNode, noop, proto } from "svelte/shared.js";
function create_main_fragment(state, component) {
var div, text, div_1;
return {
c: function create() {
div = createElement("div");
text = createText("\n");
div_1 = createElement("div");
this.h();
},
h: function hydrate() {
div.dataset.foo = "bar";
div_1.dataset.foo = state.bar;
},
m: function mount(target, anchor) {
insertNode(div, target, anchor);
insertNode(text, target, anchor);
insertNode(div_1, target, anchor);
},
p: function update(changed, state) {
if (changed.bar) {
div_1.dataset.foo = state.bar;
}
},
u: function unmount() {
detachNode(div);
detachNode(text);
detachNode(div_1);
},
d: noop
};
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._fragment = create_main_fragment(this._state, this);
if (options.target) {
this._fragment.c();
this._fragment.m(options.target, options.anchor || null);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,2 @@
<div data-foo='bar'/>
<div data-foo='{{bar}}'/>

@ -0,0 +1,5 @@
export default {
options: {
legacy: true
}
};

@ -0,0 +1,243 @@
function noop() {}
function assign(target) {
var k,
source,
i = 1,
len = arguments.length;
for (; i < len; i++) {
source = arguments[i];
for (k in source) target[k] = source[k];
}
return target;
}
function insertNode(node, target, 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 setAttribute(node, attribute, value) {
node.setAttribute(attribute, value);
}
function blankObject() {
return Object.create(null);
}
function destroy(detach) {
this.destroy = noop;
this.fire('destroy');
this.set = this.get = noop;
if (detach !== false) this._fragment.u();
this._fragment.d();
this._fragment = this._state = null;
}
function differs(a, b) {
return a !== b || ((a && typeof a === 'object') || typeof a === 'function');
}
function dispatchObservers(component, group, changed, newState, oldState) {
for (var key in group) {
if (!changed[key]) continue;
var newValue = newState[key];
var oldValue = oldState[key];
var callbacks = group[key];
if (!callbacks) continue;
for (var i = 0; i < callbacks.length; i += 1) {
var callback = callbacks[i];
if (callback.__calling) continue;
callback.__calling = true;
callback.call(component, newValue, oldValue);
callback.__calling = false;
}
}
}
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) {
handlers[i].call(this, data);
}
}
function get(key) {
return key ? this._state[key] : this._state;
}
function init(component, options) {
component.options = options;
component._observers = { pre: blankObject(), post: blankObject() };
component._handlers = blankObject();
component._root = options._root || component;
component._bind = options._bind;
}
function observe(key, callback, options) {
var group = options && options.defer
? this._observers.post
: this._observers.pre;
(group[key] || (group[key] = [])).push(callback);
if (!options || options.init !== false) {
callback.__calling = true;
callback.call(this, this._state[key]);
callback.__calling = false;
}
return {
cancel: function() {
var index = group[key].indexOf(callback);
if (~index) group[key].splice(index, 1);
}
};
}
function on(eventName, handler) {
if (eventName === 'teardown') return this.on('destroy', 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 (differs(newState[key], oldState[key])) changed[key] = dirty = true;
}
if (!dirty) return;
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {
while (fns && fns.length) fns.pop()();
}
function _mount(target, anchor) {
this._fragment.m(target, anchor);
}
function _unmount() {
this._fragment.u();
}
var proto = {
destroy: destroy,
get: get,
fire: fire,
observe: observe,
on: on,
set: set,
teardown: destroy,
_recompute: noop,
_set: _set,
_mount: _mount,
_unmount: _unmount
};
/* generated by Svelte vX.Y.Z */
function create_main_fragment(state, component) {
var div, text, div_1;
return {
c: function create() {
div = createElement("div");
text = createText("\n");
div_1 = createElement("div");
this.h();
},
h: function hydrate() {
setAttribute(div, "data-foo", "bar");
setAttribute(div_1, "data-foo", state.bar);
},
m: function mount(target, anchor) {
insertNode(div, target, anchor);
insertNode(text, target, anchor);
insertNode(div_1, target, anchor);
},
p: function update(changed, state) {
if (changed.bar) {
setAttribute(div_1, "data-foo", state.bar);
}
},
u: function unmount() {
detachNode(div);
detachNode(text);
detachNode(div_1);
},
d: noop
};
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._fragment = create_main_fragment(this._state, this);
if (options.target) {
this._fragment.c();
this._fragment.m(options.target, options.anchor || null);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,55 @@
/* generated by Svelte vX.Y.Z */
import { assign, createElement, createText, detachNode, init, insertNode, noop, proto, setAttribute } from "svelte/shared.js";
function create_main_fragment(state, component) {
var div, text, div_1;
return {
c: function create() {
div = createElement("div");
text = createText("\n");
div_1 = createElement("div");
this.h();
},
h: function hydrate() {
setAttribute(div, "data-foo", "bar");
setAttribute(div_1, "data-foo", state.bar);
},
m: function mount(target, anchor) {
insertNode(div, target, anchor);
insertNode(text, target, anchor);
insertNode(div_1, target, anchor);
},
p: function update(changed, state) {
if (changed.bar) {
setAttribute(div_1, "data-foo", state.bar);
}
},
u: function unmount() {
detachNode(div);
detachNode(text);
detachNode(div_1);
},
d: noop
};
}
function SvelteComponent(options) {
init(this, options);
this._state = assign({}, options.data);
this._fragment = create_main_fragment(this._state, this);
if (options.target) {
this._fragment.c();
this._fragment.m(options.target, options.anchor || null);
}
}
assign(SvelteComponent.prototype, proto);
export default SvelteComponent;

@ -0,0 +1,2 @@
<div data-foo='bar'/>
<div data-foo='{{bar}}'/>

@ -165,9 +165,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -145,9 +145,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -149,9 +149,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -149,9 +149,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -149,9 +149,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -149,9 +149,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -149,9 +149,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -149,9 +149,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -153,9 +153,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -151,9 +151,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -168,9 +168,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -161,9 +161,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -147,9 +147,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -133,9 +133,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -133,9 +133,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -157,9 +157,12 @@ function _set(newState) {
this._state = assign({}, oldState, newState);
this._recompute(changed, this._state);
if (this._bind) this._bind(changed, this._state);
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
if (this._fragment) {
dispatchObservers(this, this._observers.pre, changed, this._state, oldState);
this._fragment.p(changed, this._state);
dispatchObservers(this, this._observers.post, changed, this._state, oldState);
}
}
function callAll(fns) {

@ -0,0 +1,40 @@
export default {
data: {
values: [1, 2, 3],
foo: 2
},
html: `
<select>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
</select>
<p>foo: 2</p>
`,
test(assert, component, target, window) {
const select = target.querySelector('select');
const options = [...target.querySelectorAll('option')];
assert.ok(options[1].selected);
assert.equal(component.get('foo'), 2);
const change = new window.Event('change');
options[2].selected = true;
select.dispatchEvent(change);
assert.equal(component.get('foo'), 3);
assert.htmlEqual( target.innerHTML, `
<select>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
</select>
<p>foo: 3</p>
` );
}
};

@ -0,0 +1,7 @@
<select bind:value='foo'>
{{#each values as v}}
<option>{{v}}</option>
{{/each}}
</select>
<p>foo: {{foo}}</p>

@ -5,9 +5,9 @@ export default {
<p>selected: a</p>
<select>
<option>a</option>
<option>b</option>
<option>c</option>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
<p>selected: a</p>

@ -3,9 +3,9 @@ export default {
<p>selected: b</p>
<select>
<option>a</option>
<option>b</option>
<option>c</option>
<option value='a'>a</option>
<option value='b'>b</option>
<option value='c'>c</option>
</select>
<p>selected: b</p>

@ -22,9 +22,9 @@ export default {
assert.htmlEqual( target.innerHTML, `
<select>
<option>one</option>
<option>two</option>
<option>three</option>
<option value='one'>one</option>
<option value='two'>two</option>
<option value='three'>three</option>
</select>
<p>selected: two</p>
` );

@ -0,0 +1,39 @@
export default {
skip: true, // JSDOM
html: `
<h1>Hello Harry!</h1>
<select>
<option value="Harry">Harry</option>
<optgroup label="Group">
<option value="World">World</option>
</optgroup>
</select>
`,
test(assert, component, target, window) {
const select = target.querySelector('select');
const options = [...target.querySelectorAll('option')];
assert.deepEqual(options, select.options);
assert.equal(component.get('name'), 'Harry');
const change = new window.Event('change');
options[1].selected = true;
select.dispatchEvent(change);
assert.equal(component.get('name'), 'World');
assert.htmlEqual(target.innerHTML, `
<h1>Hello World!</h1>
<select>
<option value="Harry">Harry</option>
<optgroup label="Group">
<option value="World">World</option>
</optgroup>
</select>
`);
},
};

@ -0,0 +1,8 @@
<h1>Hello {{name}}!</h1>
<select bind:value="name">
<option value="Harry">Harry</option>
<optgroup label="Group">
<option value="World">World</option>
</optgroup>
</select>

@ -3,9 +3,9 @@ export default {
<p>selected: one</p>
<select>
<option>one</option>
<option>two</option>
<option>three</option>
<option value='one'>one</option>
<option value='two'>two</option>
<option value='three'>three</option>
</select>
<p>selected: one</p>
@ -32,9 +32,9 @@ export default {
<p>selected: two</p>
<select>
<option>one</option>
<option>two</option>
<option>three</option>
<option value='one'>one</option>
<option value='two'>two</option>
<option value='three'>three</option>
</select>
<p>selected: two</p>

@ -0,0 +1 @@
<button on:click="set({show:false})">Hide</button>

@ -0,0 +1,27 @@
export default {
data: {
show: true
},
html: `
<button>Hide</button>
`,
test(assert, component, target, window) {
const click = new window.MouseEvent('click');
target.querySelector('button').dispatchEvent(click);
assert.equal(component.get('show'), false);
assert.htmlEqual(target.innerHTML, `
<button>Show</button>
`);
target.querySelector('button').dispatchEvent(click);
assert.equal(component.get('show'), true);
assert.htmlEqual(target.innerHTML, `
<button>Hide</button>
`);
}
};

@ -0,0 +1,14 @@
{{#if show}}
<Nested bind:show/>
{{else}}
<button on:click="set({show:true})">Show</button>
{{/if}}
<script>
import Nested from './Nested.html';
export default {
components: {
Nested
}
};
</script>

@ -0,0 +1,10 @@
<button on:click='foo()'></button>
<script>
export default {
methods: {
'foo': () => {},
'bar': () => {}
}
};
</script>
Loading…
Cancel
Save