From 53ed35ddf0de5e802489167ff5e117cd32f7564e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 12:50:12 -0500 Subject: [PATCH 01/43] implement Store --- .eslintignore | 1 + store.js | 87 +++++++++++++++++++++++++++++++++++++++++ test/store/index.js | 95 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 store.js create mode 100644 test/store/index.js diff --git a/.eslintignore b/.eslintignore index bc31435419..4a113378ce 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,6 @@ src/shared shared.js +store.js test/test.js test/setup.js **/_actual.js diff --git a/store.js b/store.js new file mode 100644 index 0000000000..4fee967aaf --- /dev/null +++ b/store.js @@ -0,0 +1,87 @@ +import { + assign, + blankObject, + differs, + dispatchObservers, + get, + observe +} from './shared.js'; + +function Store(state) { + this._state = state ? assign({}, state) : {}; + this._observers = { pre: blankObject(), post: blankObject() }; + this._changeHandlers = []; + this._dependents = []; +} + +assign(Store.prototype, { + get, + observe +}, { + _add: function(component, props) { + this._dependents.push({ + component: component, + props: props + }); + }, + + _remove: function(component) { + let i = this._dependents.length; + while (i--) { + if (this._dependents[i].component === component) { + this._dependents.splice(i, 1); + return; + } + } + }, + + onchange: function(callback) { + this._changeHandlers.push(callback); + return { + cancel: function() { + var index = this._changeHandlers.indexOf(callback); + if (~index) this._changeHandlers.splice(index, 1); + } + }; + }, + + set: function(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); + + for (var i = 0; i < this._changeHandlers.length; i += 1) { + this._changeHandlers[i](this._state, changed); + } + + dispatchObservers(this, this._observers.pre, changed, this._state, oldState); + + var dependents = this._dependents.slice(); // guard against mutations + for (var i = 0; i < dependents.length; i += 1) { + var dependent = dependents[i]; + var componentState = {}; + dirty = false; + + for (var j = 0; j < dependent.props.length; j += 1) { + var prop = dependent.props[j]; + if (prop in changed) { + componentState['$' + prop] = this._state[prop]; + dirty = true; + } + } + + if (dirty) dependent.component.set(componentState); + } + + dispatchObservers(this, this._observers.post, changed, this._state, oldState); + } +}); + +export default Store; \ No newline at end of file diff --git a/test/store/index.js b/test/store/index.js new file mode 100644 index 0000000000..414e49bae4 --- /dev/null +++ b/test/store/index.js @@ -0,0 +1,95 @@ +import assert from 'assert'; +import Store from '../../store.js'; + +describe('store', () => { + describe('get', () => { + it('gets a specific key', () => { + const store = new Store({ + foo: 'bar' + }); + + assert.equal(store.get('foo'), 'bar'); + }); + + it('gets the entire state object', () => { + const store = new Store({ + foo: 'bar' + }); + + assert.deepEqual(store.get(), { foo: 'bar' }); + }); + }); + + describe('set', () => { + it('sets state', () => { + const store = new Store(); + + store.set({ + foo: 'bar' + }); + + assert.equal(store.get('foo'), 'bar'); + }); + }); + + describe('observe', () => { + it('observes state', () => { + let newFoo; + let oldFoo; + + const store = new Store({ + foo: 'bar' + }); + + store.observe('foo', (n, o) => { + newFoo = n; + oldFoo = o; + }); + + assert.equal(newFoo, 'bar'); + assert.equal(oldFoo, undefined); + + store.set({ + foo: 'baz' + }); + + assert.equal(newFoo, 'baz'); + assert.equal(oldFoo, 'bar'); + }); + }); + + describe('onchange', () => { + it('fires a callback when state changes', () => { + const store = new Store(); + + let count = 0; + let args; + + store.onchange((state, changed) => { + count += 1; + args = { state, changed }; + }); + + store.set({ foo: 'bar' }); + + assert.equal(count, 1); + assert.deepEqual(args, { + state: { foo: 'bar' }, + changed: { foo: true } + }); + + // this should be a noop + store.set({ foo: 'bar' }); + assert.equal(count, 1); + + // this shouldn't + store.set({ foo: 'baz' }); + + assert.equal(count, 2); + assert.deepEqual(args, { + state: { foo: 'baz' }, + changed: { foo: true } + }); + }); + }); +}); From a9353a769c8ca8c329834692a077be28eb860b54 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 13:56:32 -0500 Subject: [PATCH 02/43] add _init method --- store.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/store.js b/store.js index 4fee967aaf..3a4a516e46 100644 --- a/store.js +++ b/store.js @@ -25,6 +25,15 @@ assign(Store.prototype, { }); }, + _init: function(props) { + var state = {}; + for (let i = 0; i < props.length; i += 1) { + var prop = props[i]; + state['$' + prop] = this._state[prop]; + } + return state; + }, + _remove: function(component) { let i = this._dependents.length; while (i--) { From 1bd56a591fe5605194b764156521e17020053d44 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 13:57:07 -0500 Subject: [PATCH 03/43] client-side store subscriptions --- src/generators/dom/index.ts | 19 ++++++++++++++++--- src/interfaces.ts | 1 + src/shared/index.js | 9 +++++++-- test/runtime/index.js | 12 +++++++----- test/runtime/samples/store/_config.js | 19 +++++++++++++++++++ test/runtime/samples/store/main.html | 1 + 6 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 test/runtime/samples/store/_config.js create mode 100644 test/runtime/samples/store/main.html diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index f6c007c79d..2bf0c21c4b 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -184,15 +184,23 @@ export default function dom( const debugName = `<${generator.customElement ? generator.tag : name}>`; // generate initial state object - const globals = Array.from(generator.expectedProperties).filter(prop => globalWhitelist.has(prop)); + const expectedProperties = Array.from(generator.expectedProperties); + const globals = expectedProperties.filter(prop => globalWhitelist.has(prop)); + const storeProps = options.store ? expectedProperties.filter(prop => prop[0] === '$') : []; + const initialState = []; + if (globals.length > 0) { initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`); } + if (storeProps.length > 0) { + initialState.push(`this.store._init([${storeProps.map(prop => `"${prop.slice(1)}"`)}])`); + } + if (templateProperties.data) { initialState.push(`%data()`); - } else if (globals.length === 0) { + } else if (globals.length === 0 && storeProps.length === 0) { initialState.push('{}'); } @@ -205,6 +213,7 @@ export default function dom( @init(this, options); ${generator.usesRefs && `this.refs = {};`} this._state = @assign(${initialState.join(', ')}); + ${storeProps.length > 0 && `this.store._add(this, [${storeProps.map(prop => `"${prop.slice(1)}"`)}]);`} ${generator.metaBindings} ${computations.length && `this._recompute({ ${Array.from(computationDeps).map(dep => `${dep}: 1`).join(', ')} }, this._state);`} ${options.dev && @@ -215,7 +224,11 @@ export default function dom( ${generator.bindingGroups.length && `this._bindingGroups = [${Array(generator.bindingGroups.length).fill('[]').join(', ')}];`} - ${templateProperties.ondestroy && `this._handlers.destroy = [%ondestroy]`} + ${(templateProperties.ondestroy || storeProps.length) && ( + `this._handlers.destroy = [${ + [templateProperties.ondestroy && `%ondestroy`, storeProps.length && `@removeFromStore`].filter(Boolean).join(', ') + }]` + )} ${generator.slots.size && `this._slotted = options.slots || {};`} diff --git a/src/interfaces.ts b/src/interfaces.ts index fff52e8da4..3a9280df3c 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -56,6 +56,7 @@ export interface CompileOptions { legacy?: boolean; customElement?: CustomElementOptions | true; css?: boolean; + store?: boolean; onerror?: (error: Error) => void; onwarn?: (warning: Warning) => void; diff --git a/src/shared/index.js b/src/shared/index.js index f9d0f91998..9825972b82 100644 --- a/src/shared/index.js +++ b/src/shared/index.js @@ -65,12 +65,13 @@ export function get(key) { } export 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; + + component.options = options; + component.store = component._root.options.store; } export function observe(key, callback, options) { @@ -187,6 +188,10 @@ export function _unmount() { this._fragment.u(); } +export function removeFromStore() { + this.store._remove(this); +} + export var proto = { destroy: destroy, get: get, diff --git a/test/runtime/index.js b/test/runtime/index.js index 122fe645b6..a82f5b6975 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.js @@ -63,6 +63,7 @@ describe("runtime", () => { compileOptions.shared = shared; compileOptions.hydratable = hydrate; compileOptions.dev = config.dev; + compileOptions.store = !!config.store; // check that no ES2015+ syntax slipped in if (!config.allowES2015) { @@ -88,7 +89,7 @@ describe("runtime", () => { } } catch (err) { failed.add(dir); - showOutput(cwd, { shared }, svelte); // eslint-disable-line no-console + showOutput(cwd, { shared, store: !!compileOptions.store }, svelte); // eslint-disable-line no-console throw err; } } @@ -134,7 +135,7 @@ describe("runtime", () => { try { SvelteComponent = require(`./samples/${dir}/main.html`); } catch (err) { - showOutput(cwd, { shared, hydratable: hydrate }, svelte); // eslint-disable-line no-console + showOutput(cwd, { shared, hydratable: hydrate, store: !!compileOptions.store }, svelte); // eslint-disable-line no-console throw err; } @@ -154,7 +155,8 @@ describe("runtime", () => { const options = Object.assign({}, { target, hydrate, - data: config.data + data: config.data, + store: config.store }, config.options || {}); const component = new SvelteComponent(options); @@ -188,12 +190,12 @@ describe("runtime", () => { config.error(assert, err); } else { failed.add(dir); - showOutput(cwd, { shared, hydratable: hydrate }, svelte); // eslint-disable-line no-console + showOutput(cwd, { shared, hydratable: hydrate, store: !!compileOptions.store }, svelte); // eslint-disable-line no-console throw err; } } - if (config.show) showOutput(cwd, { shared, hydratable: hydrate }, svelte); + if (config.show) showOutput(cwd, { shared, hydratable: hydrate, store: !!compileOptions.store }, svelte); }); } diff --git a/test/runtime/samples/store/_config.js b/test/runtime/samples/store/_config.js new file mode 100644 index 0000000000..55d01fc125 --- /dev/null +++ b/test/runtime/samples/store/_config.js @@ -0,0 +1,19 @@ +import Store from '../../../../store.js'; + +const store = new Store({ + name: 'world' +}); + +export default { + solo: true, + + store, + + html: `

Hello world!

`, + + test(assert, component, target) { + store.set({ name: 'everybody' }); + + assert.htmlEqual(target.innerHTML, `

Hello everybody!

`); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store/main.html b/test/runtime/samples/store/main.html new file mode 100644 index 0000000000..28154934b8 --- /dev/null +++ b/test/runtime/samples/store/main.html @@ -0,0 +1 @@ +

Hello {{$name}}!

\ No newline at end of file From 2ade424988f64a3dce88329e231587b3a41a61f8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 14:23:45 -0500 Subject: [PATCH 04/43] update snapshot tests --- .../collapses-text-around-comments/expected-bundle.js | 5 +++-- test/js/samples/component-static/expected-bundle.js | 5 +++-- test/js/samples/computed-collapsed-if/expected-bundle.js | 5 +++-- test/js/samples/css-media-query/expected-bundle.js | 5 +++-- test/js/samples/css-shadow-dom-keyframes/expected-bundle.js | 5 +++-- test/js/samples/do-use-dataset/expected-bundle.js | 5 +++-- .../js/samples/dont-use-dataset-in-legacy/expected-bundle.js | 5 +++-- test/js/samples/each-block-changed-check/expected-bundle.js | 5 +++-- test/js/samples/event-handlers-custom/expected-bundle.js | 5 +++-- test/js/samples/if-block-no-update/expected-bundle.js | 5 +++-- test/js/samples/if-block-simple/expected-bundle.js | 5 +++-- .../inline-style-optimized-multiple/expected-bundle.js | 5 +++-- .../js/samples/inline-style-optimized-url/expected-bundle.js | 5 +++-- test/js/samples/inline-style-optimized/expected-bundle.js | 5 +++-- test/js/samples/inline-style-unoptimized/expected-bundle.js | 5 +++-- .../samples/input-without-blowback-guard/expected-bundle.js | 5 +++-- test/js/samples/legacy-input-type/expected-bundle.js | 5 +++-- test/js/samples/legacy-quote-class/expected-bundle.js | 5 +++-- test/js/samples/media-bindings/expected-bundle.js | 5 +++-- test/js/samples/non-imported-component/expected-bundle.js | 5 +++-- .../samples/onrender-onteardown-rewritten/expected-bundle.js | 5 +++-- test/js/samples/setup-method/expected-bundle.js | 5 +++-- test/js/samples/use-elements-as-anchors/expected-bundle.js | 5 +++-- test/js/samples/window-binding-scroll/expected-bundle.js | 5 +++-- 24 files changed, 72 insertions(+), 48 deletions(-) diff --git a/test/js/samples/collapses-text-around-comments/expected-bundle.js b/test/js/samples/collapses-text-around-comments/expected-bundle.js index a5776bc195..c54a4508e7 100644 --- a/test/js/samples/collapses-text-around-comments/expected-bundle.js +++ b/test/js/samples/collapses-text-around-comments/expected-bundle.js @@ -91,12 +91,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/component-static/expected-bundle.js b/test/js/samples/component-static/expected-bundle.js index 94f69ca2ca..27d4a5d5df 100644 --- a/test/js/samples/component-static/expected-bundle.js +++ b/test/js/samples/component-static/expected-bundle.js @@ -67,12 +67,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/computed-collapsed-if/expected-bundle.js b/test/js/samples/computed-collapsed-if/expected-bundle.js index c378d78026..9129d64ebf 100644 --- a/test/js/samples/computed-collapsed-if/expected-bundle.js +++ b/test/js/samples/computed-collapsed-if/expected-bundle.js @@ -67,12 +67,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/css-media-query/expected-bundle.js b/test/js/samples/css-media-query/expected-bundle.js index 11ffa87f21..3eb06a7baa 100644 --- a/test/js/samples/css-media-query/expected-bundle.js +++ b/test/js/samples/css-media-query/expected-bundle.js @@ -87,12 +87,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js b/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js index 86edac7465..a8a14c254a 100644 --- a/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js +++ b/test/js/samples/css-shadow-dom-keyframes/expected-bundle.js @@ -79,12 +79,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/do-use-dataset/expected-bundle.js b/test/js/samples/do-use-dataset/expected-bundle.js index 42de89fd93..1baf806a52 100644 --- a/test/js/samples/do-use-dataset/expected-bundle.js +++ b/test/js/samples/do-use-dataset/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js b/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js index 2d25e23a10..3ebad459d3 100644 --- a/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js +++ b/test/js/samples/dont-use-dataset-in-legacy/expected-bundle.js @@ -87,12 +87,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/each-block-changed-check/expected-bundle.js b/test/js/samples/each-block-changed-check/expected-bundle.js index c9723db616..dae7830ecb 100644 --- a/test/js/samples/each-block-changed-check/expected-bundle.js +++ b/test/js/samples/each-block-changed-check/expected-bundle.js @@ -99,12 +99,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/event-handlers-custom/expected-bundle.js b/test/js/samples/event-handlers-custom/expected-bundle.js index 46c109100a..b1974ae869 100644 --- a/test/js/samples/event-handlers-custom/expected-bundle.js +++ b/test/js/samples/event-handlers-custom/expected-bundle.js @@ -79,12 +79,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/if-block-no-update/expected-bundle.js b/test/js/samples/if-block-no-update/expected-bundle.js index 0277095a83..12822a4ed3 100644 --- a/test/js/samples/if-block-no-update/expected-bundle.js +++ b/test/js/samples/if-block-no-update/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/if-block-simple/expected-bundle.js b/test/js/samples/if-block-simple/expected-bundle.js index 40acbe3959..0985260579 100644 --- a/test/js/samples/if-block-simple/expected-bundle.js +++ b/test/js/samples/if-block-simple/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/inline-style-optimized-multiple/expected-bundle.js b/test/js/samples/inline-style-optimized-multiple/expected-bundle.js index eff6f53cfa..6260246cc0 100644 --- a/test/js/samples/inline-style-optimized-multiple/expected-bundle.js +++ b/test/js/samples/inline-style-optimized-multiple/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/inline-style-optimized-url/expected-bundle.js b/test/js/samples/inline-style-optimized-url/expected-bundle.js index 3a126946ad..921d377bf9 100644 --- a/test/js/samples/inline-style-optimized-url/expected-bundle.js +++ b/test/js/samples/inline-style-optimized-url/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/inline-style-optimized/expected-bundle.js b/test/js/samples/inline-style-optimized/expected-bundle.js index 0c127a6391..8ddc55d215 100644 --- a/test/js/samples/inline-style-optimized/expected-bundle.js +++ b/test/js/samples/inline-style-optimized/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/inline-style-unoptimized/expected-bundle.js b/test/js/samples/inline-style-unoptimized/expected-bundle.js index d6f545111a..c3ca9e6957 100644 --- a/test/js/samples/inline-style-unoptimized/expected-bundle.js +++ b/test/js/samples/inline-style-unoptimized/expected-bundle.js @@ -83,12 +83,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/input-without-blowback-guard/expected-bundle.js b/test/js/samples/input-without-blowback-guard/expected-bundle.js index 1918f9f6d1..a7a7d25e0c 100644 --- a/test/js/samples/input-without-blowback-guard/expected-bundle.js +++ b/test/js/samples/input-without-blowback-guard/expected-bundle.js @@ -87,12 +87,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/legacy-input-type/expected-bundle.js b/test/js/samples/legacy-input-type/expected-bundle.js index 7211738f45..54a4c3c02d 100644 --- a/test/js/samples/legacy-input-type/expected-bundle.js +++ b/test/js/samples/legacy-input-type/expected-bundle.js @@ -85,12 +85,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/legacy-quote-class/expected-bundle.js b/test/js/samples/legacy-quote-class/expected-bundle.js index 1575bf4064..c6f7bb8405 100644 --- a/test/js/samples/legacy-quote-class/expected-bundle.js +++ b/test/js/samples/legacy-quote-class/expected-bundle.js @@ -102,12 +102,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/media-bindings/expected-bundle.js b/test/js/samples/media-bindings/expected-bundle.js index 80545b9402..bdac2a8f2a 100644 --- a/test/js/samples/media-bindings/expected-bundle.js +++ b/test/js/samples/media-bindings/expected-bundle.js @@ -95,12 +95,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/non-imported-component/expected-bundle.js b/test/js/samples/non-imported-component/expected-bundle.js index 575be613fa..fd201d65b3 100644 --- a/test/js/samples/non-imported-component/expected-bundle.js +++ b/test/js/samples/non-imported-component/expected-bundle.js @@ -81,12 +81,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js index f1e701bd04..364ee2901d 100644 --- a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js +++ b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js @@ -67,12 +67,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/setup-method/expected-bundle.js b/test/js/samples/setup-method/expected-bundle.js index 0c545ea70c..df267db975 100644 --- a/test/js/samples/setup-method/expected-bundle.js +++ b/test/js/samples/setup-method/expected-bundle.js @@ -67,12 +67,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/use-elements-as-anchors/expected-bundle.js b/test/js/samples/use-elements-as-anchors/expected-bundle.js index 8805cc3847..272e039772 100644 --- a/test/js/samples/use-elements-as-anchors/expected-bundle.js +++ b/test/js/samples/use-elements-as-anchors/expected-bundle.js @@ -91,12 +91,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { diff --git a/test/js/samples/window-binding-scroll/expected-bundle.js b/test/js/samples/window-binding-scroll/expected-bundle.js index 6c357ef732..3a11deb1b6 100644 --- a/test/js/samples/window-binding-scroll/expected-bundle.js +++ b/test/js/samples/window-binding-scroll/expected-bundle.js @@ -87,12 +87,13 @@ function get(key) { } 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; + + component.options = options; + component.store = component._root.options.store; } function observe(key, callback, options) { From ff543bd171b03c1fd002088bc411ea867a156f5e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 14:26:46 -0500 Subject: [PATCH 05/43] reenable all tests --- test/runtime/samples/store/_config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/runtime/samples/store/_config.js b/test/runtime/samples/store/_config.js index 55d01fc125..0e1663315b 100644 --- a/test/runtime/samples/store/_config.js +++ b/test/runtime/samples/store/_config.js @@ -5,8 +5,6 @@ const store = new Store({ }); export default { - solo: true, - store, html: `

Hello world!

`, From 30093ce0365ef9b8a6494dbcc8eac227279f04a2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 14:49:16 -0500 Subject: [PATCH 06/43] use store in SSR mode --- src/generators/server-side-rendering/index.ts | 14 ++++++++++---- .../server-side-rendering/visitors/Component.ts | 11 ++++++++++- src/server-side-rendering/register.js | 12 ++++++++++-- .../samples/ssr-no-oncreate-etc/expected-bundle.js | 2 +- test/js/samples/ssr-no-oncreate-etc/expected.js | 2 +- test/server-side-rendering/index.js | 11 +++++++++-- 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/generators/server-side-rendering/index.ts b/src/generators/server-side-rendering/index.ts index 2accc2bc7e..c6741cb958 100644 --- a/src/generators/server-side-rendering/index.ts +++ b/src/generators/server-side-rendering/index.ts @@ -73,16 +73,22 @@ export default function ssr( generator.stylesheet.render(options.filename, true); // generate initial state object - // TODO this doesn't work, because expectedProperties isn't populated - const globals = Array.from(generator.expectedProperties).filter(prop => globalWhitelist.has(prop)); + const expectedProperties = Array.from(generator.expectedProperties); + const globals = expectedProperties.filter(prop => globalWhitelist.has(prop)); + const storeProps = options.store ? expectedProperties.filter(prop => prop[0] === '$') : []; + const initialState = []; if (globals.length > 0) { initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`); } + if (storeProps.length > 0) { + initialState.push(`options.store._init([${storeProps.map(prop => `"${prop.slice(1)}"`)}])`); + } + if (templateProperties.data) { initialState.push(`%data()`); - } else if (globals.length === 0) { + } else if (globals.length === 0 && storeProps.length === 0) { initialState.push('{}'); } @@ -99,7 +105,7 @@ export default function ssr( return ${templateProperties.data ? `%data()` : `{}`}; }; - ${name}.render = function(state, options) { + ${name}.render = function(state, options = {}) { state = Object.assign(${initialState.join(', ')}); ${computations.map( diff --git a/src/generators/server-side-rendering/visitors/Component.ts b/src/generators/server-side-rendering/visitors/Component.ts index b582dc13d9..74c7e239e4 100644 --- a/src/generators/server-side-rendering/visitors/Component.ts +++ b/src/generators/server-side-rendering/visitors/Component.ts @@ -79,6 +79,11 @@ export default function visitComponent( let open = `\${${expression}.render({${props}}`; + const options = []; + if (generator.options.store) { + options.push(`store: options.store`); + } + if (node.children.length) { const appendTarget: AppendTarget = { slots: { default: '' }, @@ -95,11 +100,15 @@ export default function visitComponent( .map(name => `${name}: () => \`${appendTarget.slots[name]}\``) .join(', '); - open += `, { slotted: { ${slotted} } }`; + options.push(`slotted: { ${slotted} }`); generator.appendTargets.pop(); } + if (options.length) { + open += `, { ${options.join(', ')} }`; + } + generator.append(open); generator.append(')}'); } diff --git a/src/server-side-rendering/register.js b/src/server-side-rendering/register.js index 254c1e4419..bb4ea61e7b 100644 --- a/src/server-side-rendering/register.js +++ b/src/server-side-rendering/register.js @@ -2,16 +2,22 @@ import * as fs from 'fs'; import * as path from 'path'; import { compile } from '../index.ts'; +const compileOptions = {}; + function capitalise(name) { return name[0].toUpperCase() + name.slice(1); } export default function register(options) { const { extensions } = options; + if (extensions) { _deregister('.html'); extensions.forEach(_register); } + + // TODO make this the default and remove in v2 + if ('store' in options) compileOptions.store = options.store; } function _deregister(extension) { @@ -20,13 +26,15 @@ function _deregister(extension) { function _register(extension) { require.extensions[extension] = function(module, filename) { - const {code} = compile(fs.readFileSync(filename, 'utf-8'), { + const options = Object.assign({}, compileOptions, { filename, name: capitalise(path.basename(filename) .replace(new RegExp(`${extension.replace('.', '\\.')}$`), '')), - generate: 'ssr', + generate: 'ssr' }); + const {code} = compile(fs.readFileSync(filename, 'utf-8'), options); + return module._compile(code, filename); }; } diff --git a/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js b/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js index 9a466e06ae..1dfa59b423 100644 --- a/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js +++ b/test/js/samples/ssr-no-oncreate-etc/expected-bundle.js @@ -4,7 +4,7 @@ SvelteComponent.data = function() { return {}; }; -SvelteComponent.render = function(state, options) { +SvelteComponent.render = function(state, options = {}) { state = Object.assign({}, state); return ``.trim(); diff --git a/test/js/samples/ssr-no-oncreate-etc/expected.js b/test/js/samples/ssr-no-oncreate-etc/expected.js index 51c10c7656..c64b3877ab 100644 --- a/test/js/samples/ssr-no-oncreate-etc/expected.js +++ b/test/js/samples/ssr-no-oncreate-etc/expected.js @@ -6,7 +6,7 @@ SvelteComponent.data = function() { return {}; }; -SvelteComponent.render = function(state, options) { +SvelteComponent.render = function(state, options = {}) { state = Object.assign({}, state); return ``.trim(); diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js index a9bf847b29..b6bd109c0e 100644 --- a/test/server-side-rendering/index.js +++ b/test/server-side-rendering/index.js @@ -22,7 +22,8 @@ function tryToReadFile(file) { describe("ssr", () => { before(() => { require("../../ssr/register")({ - extensions: ['.svelte', '.html'] + extensions: ['.svelte', '.html'], + store: true }); return setupHtmlEqual(); @@ -98,9 +99,15 @@ describe("ssr", () => { delete require.cache[resolved]; }); + require("../../ssr/register")({ + store: !!config.store + }); + try { const component = require(`../runtime/samples/${dir}/main.html`); - const html = component.render(config.data); + const html = component.render(config.data, { + store: config.store + }); if (config.html) { assert.htmlEqual(html, config.html); From fd63a56d523d72078f12f439f013561ff9013b08 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 16:07:38 -0500 Subject: [PATCH 07/43] store bindings --- src/generators/dom/index.ts | 2 +- .../dom/visitors/Element/addBindings.ts | 42 ++++++++++++++++--- .../onrender-onteardown-rewritten/expected.js | 2 +- .../samples/store-binding/NameInput.html | 1 + test/runtime/samples/store-binding/_config.js | 28 +++++++++++++ test/runtime/samples/store-binding/main.html | 10 +++++ 6 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 test/runtime/samples/store-binding/NameInput.html create mode 100644 test/runtime/samples/store-binding/_config.js create mode 100644 test/runtime/samples/store-binding/main.html diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index 2bf0c21c4b..c6d9e94df2 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -227,7 +227,7 @@ export default function dom( ${(templateProperties.ondestroy || storeProps.length) && ( `this._handlers.destroy = [${ [templateProperties.ondestroy && `%ondestroy`, storeProps.length && `@removeFromStore`].filter(Boolean).join(', ') - }]` + }];` )} ${generator.slots.size && `this._slotted = options.slots || {};`} diff --git a/src/generators/dom/visitors/Element/addBindings.ts b/src/generators/dom/visitors/Element/addBindings.ts index a2433abf93..2e41cd1b19 100644 --- a/src/generators/dom/visitors/Element/addBindings.ts +++ b/src/generators/dom/visitors/Element/addBindings.ts @@ -195,13 +195,19 @@ export default function addBindings( const usesContext = group.bindings.some(binding => binding.handler.usesContext); const usesState = group.bindings.some(binding => binding.handler.usesState); + const usesStore = group.bindings.some(binding => binding.handler.usesStore); const mutations = group.bindings.map(binding => binding.handler.mutation).filter(Boolean).join('\n'); const props = new Set(); + const storeProps = new Set(); group.bindings.forEach(binding => { binding.handler.props.forEach(prop => { props.add(prop); }); + + binding.handler.storeProps.forEach(prop => { + storeProps.add(prop); + }); }); // TODO use stringifyProps here, once indenting is fixed // media bindings — awkward special case. The native timeupdate events @@ -222,9 +228,11 @@ export default function addBindings( } ${usesContext && `var context = ${node.var}._svelte;`} ${usesState && `var state = #component.get();`} + ${usesStore && `var $ = #component.store.get();`} ${needsLock && `${lock} = true;`} ${mutations.length > 0 && mutations} - #component.set({ ${Array.from(props).join(', ')} }); + ${props.size > 0 && `#component.set({ ${Array.from(props).join(', ')} });`} + ${storeProps.size > 0 && `#component.store.set({ ${Array.from(storeProps).join(', ')} });`} ${needsLock && `${lock} = false;`} } `); @@ -307,6 +315,13 @@ function getEventHandler( dependencies: string[], value: string, ) { + let storeDependencies = []; + + if (generator.options.store) { + storeDependencies = dependencies.filter(prop => prop[0] === '$').map(prop => prop.slice(1)); + dependencies = dependencies.filter(prop => prop[0] !== '$'); + } + if (block.contexts.has(name)) { const tail = attribute.value.type === 'MemberExpression' ? getTailSnippet(attribute.value) @@ -318,8 +333,10 @@ function getEventHandler( return { usesContext: true, usesState: true, + usesStore: storeDependencies.length > 0, mutation: `${list}[${index}]${tail} = ${value};`, - props: dependencies.map(prop => `${prop}: state.${prop}`) + props: dependencies.map(prop => `${prop}: state.${prop}`), + storeProps: storeDependencies.map(prop => `${prop}: $.${prop}`) }; } @@ -336,16 +353,31 @@ function getEventHandler( return { usesContext: false, usesState: true, + usesStore: storeDependencies.length > 0, mutation: `${snippet} = ${value}`, - props: dependencies.map((prop: string) => `${prop}: state.${prop}`) + props: dependencies.map((prop: string) => `${prop}: state.${prop}`), + storeProps: storeDependencies.map(prop => `${prop}: $.${prop}`) }; } + let props; + let storeProps; + + if (generator.options.store && name[0] === '$') { + props = []; + storeProps = [`${name.slice(1)}: ${value}`]; + } else { + props = [`${name}: ${value}`]; + storeProps = []; + } + return { usesContext: false, usesState: false, + usesStore: false, mutation: null, - props: [`${name}: ${value}`] + props, + storeProps }; } @@ -393,4 +425,4 @@ function isComputed(node: Node) { } return false; -} +} \ No newline at end of file diff --git a/test/js/samples/onrender-onteardown-rewritten/expected.js b/test/js/samples/onrender-onteardown-rewritten/expected.js index 19b85a62e0..ae6046dddb 100644 --- a/test/js/samples/onrender-onteardown-rewritten/expected.js +++ b/test/js/samples/onrender-onteardown-rewritten/expected.js @@ -24,7 +24,7 @@ function SvelteComponent(options) { init(this, options); this._state = assign({}, options.data); - this._handlers.destroy = [ondestroy] + this._handlers.destroy = [ondestroy]; var _oncreate = oncreate.bind(this); diff --git a/test/runtime/samples/store-binding/NameInput.html b/test/runtime/samples/store-binding/NameInput.html new file mode 100644 index 0000000000..a5e4f5e48c --- /dev/null +++ b/test/runtime/samples/store-binding/NameInput.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/store-binding/_config.js b/test/runtime/samples/store-binding/_config.js new file mode 100644 index 0000000000..c9ae020777 --- /dev/null +++ b/test/runtime/samples/store-binding/_config.js @@ -0,0 +1,28 @@ +import Store from '../../../../store.js'; + +const store = new Store({ + name: 'world' +}); + +export default { + store, + + html: ` +

Hello world!

+ + `, + + test(assert, component, target, window) { + const input = target.querySelector('input'); + const event = new window.Event('input'); + + input.value = 'everybody'; + input.dispatchEvent(event); + + assert.equal(store.get('name'), 'everybody'); + assert.htmlEqual(target.innerHTML, ` +

Hello everybody!

+ + `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store-binding/main.html b/test/runtime/samples/store-binding/main.html new file mode 100644 index 0000000000..06410ea770 --- /dev/null +++ b/test/runtime/samples/store-binding/main.html @@ -0,0 +1,10 @@ +

Hello {{$name}}!

+ + + \ No newline at end of file From fbc1785e364692714e10fd6adc73ae74e3e359a5 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 16:23:32 -0500 Subject: [PATCH 08/43] allow event handlers to call store methods --- src/validate/html/validateEventHandler.ts | 10 +++++- src/validate/index.ts | 6 ++-- .../samples/store-event/NameInput.html | 1 + test/runtime/samples/store-event/_config.js | 34 +++++++++++++++++++ test/runtime/samples/store-event/main.html | 10 ++++++ .../samples/store-unexpected/input.html | 1 + .../samples/store-unexpected/warnings.json | 8 +++++ 7 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 test/runtime/samples/store-event/NameInput.html create mode 100644 test/runtime/samples/store-event/_config.js create mode 100644 test/runtime/samples/store-event/main.html create mode 100644 test/validator/samples/store-unexpected/input.html create mode 100644 test/validator/samples/store-unexpected/warnings.json diff --git a/src/validate/html/validateEventHandler.ts b/src/validate/html/validateEventHandler.ts index 2339f801d9..8e8a6122b3 100644 --- a/src/validate/html/validateEventHandler.ts +++ b/src/validate/html/validateEventHandler.ts @@ -1,6 +1,6 @@ import flattenReference from '../../utils/flattenReference'; import list from '../../utils/list'; -import { Validator } from '../index'; +import validate, { Validator } from '../index'; import validCalleeObjects from '../../utils/validCalleeObjects'; import { Node } from '../../interfaces'; @@ -28,6 +28,13 @@ export default function validateEventHandlerCallee( return; } + if (name === 'store' && attribute.expression.callee.type === 'MemberExpression') { + if (!validator.options.store) { + validator.warn('compile with `store: true` in order to call store methods', attribute.expression.start); + } + return; + } + if ( (callee.type === 'Identifier' && validBuiltins.has(callee.name)) || validator.methods.has(callee.name) @@ -35,6 +42,7 @@ export default function validateEventHandlerCallee( return; const validCallees = ['this.*', 'event.*', 'options.*', 'console.*'].concat( + validator.options.store ? 'store.*' : [], Array.from(validBuiltins), Array.from(validator.methods.keys()) ); diff --git a/src/validate/index.ts b/src/validate/index.ts index 17c3e83be9..5ed4d58bd9 100644 --- a/src/validate/index.ts +++ b/src/validate/index.ts @@ -22,6 +22,7 @@ export class Validator { readonly source: string; readonly filename: string; + options: CompileOptions; onwarn: ({}) => void; locator?: (pos: number) => Location; @@ -37,8 +38,8 @@ export class Validator { constructor(parsed: Parsed, source: string, options: CompileOptions) { this.source = source; this.filename = options.filename; - this.onwarn = options.onwarn; + this.options = options; this.namespace = null; this.defaultExport = null; @@ -78,7 +79,7 @@ export default function validate( stylesheet: Stylesheet, options: CompileOptions ) { - const { onwarn, onerror, name, filename } = options; + const { onwarn, onerror, name, filename, store } = options; try { if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) { @@ -99,6 +100,7 @@ export default function validate( onwarn, name, filename, + store }); if (parsed.js) { diff --git a/test/runtime/samples/store-event/NameInput.html b/test/runtime/samples/store-event/NameInput.html new file mode 100644 index 0000000000..ecd95d0364 --- /dev/null +++ b/test/runtime/samples/store-event/NameInput.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/runtime/samples/store-event/_config.js b/test/runtime/samples/store-event/_config.js new file mode 100644 index 0000000000..6f192ff76f --- /dev/null +++ b/test/runtime/samples/store-event/_config.js @@ -0,0 +1,34 @@ +import Store from '../../../../store.js'; + +class MyStore extends Store { + setName(name) { + this.set({ name }); + } +} + +const store = new MyStore({ + name: 'world' +}); + +export default { + store, + + html: ` +

Hello world!

+ + `, + + test(assert, component, target, window) { + const input = target.querySelector('input'); + const event = new window.Event('input'); + + input.value = 'everybody'; + input.dispatchEvent(event); + + assert.equal(store.get('name'), 'everybody'); + assert.htmlEqual(target.innerHTML, ` +

Hello everybody!

+ + `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store-event/main.html b/test/runtime/samples/store-event/main.html new file mode 100644 index 0000000000..06410ea770 --- /dev/null +++ b/test/runtime/samples/store-event/main.html @@ -0,0 +1,10 @@ +

Hello {{$name}}!

+ + + \ No newline at end of file diff --git a/test/validator/samples/store-unexpected/input.html b/test/validator/samples/store-unexpected/input.html new file mode 100644 index 0000000000..589f28e647 --- /dev/null +++ b/test/validator/samples/store-unexpected/input.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/validator/samples/store-unexpected/warnings.json b/test/validator/samples/store-unexpected/warnings.json new file mode 100644 index 0000000000..bac2841dc9 --- /dev/null +++ b/test/validator/samples/store-unexpected/warnings.json @@ -0,0 +1,8 @@ +[{ + "message": "compile with `store: true` in order to call store methods", + "loc": { + "line": 1, + "column": 18 + }, + "pos": 18 +}] \ No newline at end of file From 5ec57f8b9ad336fe1b3b8c2b63482939c5b32f1c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 16:49:37 -0500 Subject: [PATCH 09/43] allow computed properties to depend on store props --- src/generators/Generator.ts | 3 + test/runtime/samples/store-computed/Todo.html | 15 +++++ .../runtime/samples/store-computed/_config.js | 65 +++++++++++++++++++ test/runtime/samples/store-computed/main.html | 11 ++++ 4 files changed, 94 insertions(+) create mode 100644 test/runtime/samples/store-computed/Todo.html create mode 100644 test/runtime/samples/store-computed/_config.js create mode 100644 test/runtime/samples/store-computed/main.html diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts index a8775d41b2..99f7597276 100644 --- a/src/generators/Generator.ts +++ b/src/generators/Generator.ts @@ -536,6 +536,9 @@ export default class Generator { (param: Node) => param.type === 'AssignmentPattern' ? param.left.name : param.name ); + deps.forEach(dep => { + this.expectedProperties.add(dep); + }); dependencies.set(key, deps); }); diff --git a/test/runtime/samples/store-computed/Todo.html b/test/runtime/samples/store-computed/Todo.html new file mode 100644 index 0000000000..2ad67420ca --- /dev/null +++ b/test/runtime/samples/store-computed/Todo.html @@ -0,0 +1,15 @@ +{{#if isVisible}} +
{{todo.description}}
+{{/if}} + + \ No newline at end of file diff --git a/test/runtime/samples/store-computed/_config.js b/test/runtime/samples/store-computed/_config.js new file mode 100644 index 0000000000..2906ff4bf8 --- /dev/null +++ b/test/runtime/samples/store-computed/_config.js @@ -0,0 +1,65 @@ +import Store from '../../../../store.js'; + +class MyStore extends Store { + setFilter(filter) { + this.set({ filter }); + } + + toggleTodo(todo) { + todo.done = !todo.done; + this.set({ todos: this.get('todos') }); + } +} + +const todos = [ + { + description: 'Buy some milk', + done: true, + }, + { + description: 'Do the laundry', + done: true, + }, + { + description: "Find life's true purpose", + done: false, + } +]; + +const store = new MyStore({ + filter: 'all', + todos +}); + +export default { + solo: true, + + store, + + html: ` +
Buy some milk
+
Do the laundry
+
Find life's true purpose
+ `, + + test(assert, component, target) { + store.setFilter('pending'); + + assert.htmlEqual(target.innerHTML, ` +
Find life's true purpose
+ `); + + store.toggleTodo(todos[1]); + + assert.htmlEqual(target.innerHTML, ` +
Do the laundry
+
Find life's true purpose
+ `); + + store.setFilter('done'); + + assert.htmlEqual(target.innerHTML, ` +
Buy some milk
+ `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store-computed/main.html b/test/runtime/samples/store-computed/main.html new file mode 100644 index 0000000000..5c50839ba3 --- /dev/null +++ b/test/runtime/samples/store-computed/main.html @@ -0,0 +1,11 @@ +{{#each $todos as todo}} + +{{/each}} + + \ No newline at end of file From cfe5c66244363b0ff434c46774224c2a529a4f42 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 16:49:57 -0500 Subject: [PATCH 10/43] add store.js to package --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6bf9fae197..7b1937020d 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "compiler", "ssr", "shared.js", + "store.js", "README.md" ], "scripts": { From e53b4f5386d7674aaf334898ad84ae38235c83e3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 17:03:22 -0500 Subject: [PATCH 11/43] fix tests, now that computed prop dependencies are expected --- .../samples/dev-warning-readonly-computed/_config.js | 6 ++++++ test/runtime/samples/set-clones-input/_config.js | 6 +++++- test/runtime/samples/store-computed/_config.js | 2 -- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/test/runtime/samples/dev-warning-readonly-computed/_config.js b/test/runtime/samples/dev-warning-readonly-computed/_config.js index 2706b9610a..5cf4899db1 100644 --- a/test/runtime/samples/dev-warning-readonly-computed/_config.js +++ b/test/runtime/samples/dev-warning-readonly-computed/_config.js @@ -1,6 +1,12 @@ export default { + solo: true, + dev: true, + data: { + a: 42 + }, + test ( assert, component ) { try { component.set({ foo: 1 }); diff --git a/test/runtime/samples/set-clones-input/_config.js b/test/runtime/samples/set-clones-input/_config.js index af04f4b73e..8f365f6330 100644 --- a/test/runtime/samples/set-clones-input/_config.js +++ b/test/runtime/samples/set-clones-input/_config.js @@ -1,10 +1,14 @@ export default { dev: true, + data: { + a: 42 + }, + test ( assert, component ) { const obj = { a: 1 }; component.set( obj ); component.set( obj ); // will fail if the object is not cloned component.destroy(); } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/test/runtime/samples/store-computed/_config.js b/test/runtime/samples/store-computed/_config.js index 2906ff4bf8..13fd745f53 100644 --- a/test/runtime/samples/store-computed/_config.js +++ b/test/runtime/samples/store-computed/_config.js @@ -32,8 +32,6 @@ const store = new MyStore({ }); export default { - solo: true, - store, html: ` From 7e725b11b78e6c5988a6de178ea0a796caf719e6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Fri, 24 Nov 2017 17:05:52 -0500 Subject: [PATCH 12/43] remove solo: true --- test/runtime/samples/dev-warning-readonly-computed/_config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/runtime/samples/dev-warning-readonly-computed/_config.js b/test/runtime/samples/dev-warning-readonly-computed/_config.js index 5cf4899db1..95d4ea15c4 100644 --- a/test/runtime/samples/dev-warning-readonly-computed/_config.js +++ b/test/runtime/samples/dev-warning-readonly-computed/_config.js @@ -1,6 +1,4 @@ export default { - solo: true, - dev: true, data: { From df5b9bdf6ce1d432f83eab69f471c4d87dc23e2b Mon Sep 17 00:00:00 2001 From: Emil Tholin Date: Sat, 25 Nov 2017 18:01:25 +0100 Subject: [PATCH 13/43] Add 'current' to the list of aria attributes --- src/validate/html/a11y.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validate/html/a11y.ts b/src/validate/html/a11y.ts index 94061e9b19..aec8f50e81 100644 --- a/src/validate/html/a11y.ts +++ b/src/validate/html/a11y.ts @@ -5,7 +5,7 @@ import validateEventHandler from './validateEventHandler'; import { Validator } from '../index'; import { Node } from '../../interfaces'; -const ariaAttributes = 'activedescendant atomic autocomplete busy checked controls describedby disabled dropeffect expanded flowto grabbed haspopup hidden invalid label labelledby level live multiline multiselectable orientation owns posinset pressed readonly relevant required selected setsize sort valuemax valuemin valuenow valuetext'.split(' '); +const ariaAttributes = 'activedescendant atomic autocomplete busy checked controls current describedby disabled dropeffect expanded flowto grabbed haspopup hidden invalid label labelledby level live multiline multiselectable orientation owns posinset pressed readonly relevant required selected setsize sort valuemax valuemin valuenow valuetext'.split(' '); const ariaAttributeSet = new Set(ariaAttributes); const ariaRoles = 'alert alertdialog application article banner button checkbox columnheader combobox command complementary composite contentinfo definition dialog directory document form grid gridcell group heading img input landmark link list listbox listitem log main marquee math menu menubar menuitem menuitemcheckbox menuitemradio navigation note option presentation progressbar radio radiogroup range region roletype row rowgroup rowheader scrollbar search section sectionhead select separator slider spinbutton status structure tab tablist tabpanel textbox timer toolbar tooltip tree treegrid treeitem widget window'.split(' '); From 5ed6ed2a2958ee4b0ddc116afb609fc42dc73531 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 12:07:28 -0500 Subject: [PATCH 14/43] computed properties --- store.js | 75 +++++++++++++++++++++++++++++++++++++++++++-- test/store/index.js | 51 ++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/store.js b/store.js index 3a4a516e46..91603bb15b 100644 --- a/store.js +++ b/store.js @@ -8,10 +8,20 @@ import { } from './shared.js'; function Store(state) { - this._state = state ? assign({}, state) : {}; this._observers = { pre: blankObject(), post: blankObject() }; this._changeHandlers = []; this._dependents = []; + + this._proto = blankObject(); + this._changed = blankObject(); + this._dependentProps = blankObject(); + this._dirty = blankObject(); + this._state = Object.create(this._proto); + + for (var key in state) { + this._changed[key] = true; + this._state[key] = state[key]; + } } assign(Store.prototype, { @@ -25,6 +35,17 @@ assign(Store.prototype, { }); }, + _makeDirty: function(prop) { + var dependentProps = this._dependentProps[prop]; + if (dependentProps) { + for (var i = 0; i < dependentProps.length; i += 1) { + var dependentProp = dependentProps[i]; + this._dirty[dependentProp] = this._changed[dependentProp] = true; + this._makeDirty(dependentProp); + } + } + }, + _init: function(props) { var state = {}; for (let i = 0; i < props.length; i += 1) { @@ -44,6 +65,52 @@ assign(Store.prototype, { } }, + compute: function(key, deps, fn) { + var store = this; + var value; + + store._dirty[key] = true; + + for (var i = 0; i < deps.length; i += 1) { + var dep = deps[i]; + if (!this._dependentProps[dep]) this._dependentProps[dep] = []; + this._dependentProps[dep].push(key); + } + + Object.defineProperty(this._proto, key, { + get: function() { + if (store._dirty[key]) { + var values = deps.map(function(dep) { + if (dep in store._changed) changed = true; + return store._state[dep]; + }); + + var newValue = fn.apply(null, values); + + if (differs(newValue, value)) { + value = newValue; + store._changed[key] = true; + + var dependentProps = store._dependentProps[key]; + if (dependentProps) { + for (var i = 0; i < dependentProps.length; i += 1) { + var prop = dependentProps[i]; + store._dirty[prop] = store._changed[prop] = true; + } + } + } + + store._dirty[key] = false; + } + + return value; + }, + set: function() { + throw new Error(`'${key}' is a read-only property`); + } + }); + }, + onchange: function(callback) { this._changeHandlers.push(callback); return { @@ -56,7 +123,7 @@ assign(Store.prototype, { set: function(newState) { var oldState = this._state, - changed = {}, + changed = this._changed = {}, dirty = false; for (var key in newState) { @@ -64,7 +131,9 @@ assign(Store.prototype, { } if (!dirty) return; - this._state = assign({}, oldState, newState); + this._state = assign(Object.create(this._proto), oldState, newState); + + for (var key in changed) this._makeDirty(key); for (var i = 0; i < this._changeHandlers.length; i += 1) { this._changeHandlers[i](this._state, changed); diff --git a/test/store/index.js b/test/store/index.js index 414e49bae4..50b6572774 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -92,4 +92,55 @@ describe('store', () => { }); }); }); + + describe('computed', () => { + it('computes a property based on data', () => { + const store = new Store({ + foo: 1 + }); + + store.compute('bar', ['foo'], foo => foo * 2); + assert.equal(store.get('bar'), 2); + + const values = []; + + store.observe('bar', bar => { + values.push(bar); + }); + + store.set({ foo: 2 }); + assert.deepEqual(values, [2, 4]); + }); + + it('computes a property based on another computed property', () => { + const store = new Store({ + foo: 1 + }); + + store.compute('bar', ['foo'], foo => foo * 2); + store.compute('baz', ['bar'], bar => bar * 2); + assert.equal(store.get('baz'), 4); + + const values = []; + + store.observe('baz', baz => { + values.push(baz); + }); + + store.set({ foo: 2 }); + assert.deepEqual(values, [4, 8]); + }); + + it('prevents computed properties from being set', () => { + const store = new Store({ + foo: 1 + }); + + store.compute('bar', ['foo'], foo => foo * 2); + + assert.throws(() => { + store.set({ bar: 'whatever' }); + }, /'bar' is a read-only property/); + }); + }); }); From f3d5becac88b94f260ccd270d399789358fede32 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 13:21:55 -0500 Subject: [PATCH 15/43] add combineStores function --- store.js | 23 ++++++++++- test/runtime/samples/store-binding/_config.js | 2 +- .../runtime/samples/store-computed/_config.js | 2 +- test/runtime/samples/store-event/_config.js | 2 +- test/runtime/samples/store/_config.js | 2 +- test/store/index.js | 38 ++++++++++++++++++- 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/store.js b/store.js index 91603bb15b..e285439ddf 100644 --- a/store.js +++ b/store.js @@ -78,6 +78,7 @@ assign(Store.prototype, { } Object.defineProperty(this._proto, key, { + enumerable: true, get: function() { if (store._dirty[key]) { var values = deps.map(function(dep) { @@ -162,4 +163,24 @@ assign(Store.prototype, { } }); -export default Store; \ No newline at end of file +function combineStores(store, children) { + var updates = {}; + + for (const key in children) { + const child = children[key]; + updates[key] = child.get(); + + child.onchange(state => { + var update = {}; + update[key] = state; + store.set(update); + }); + } + + console.log('updates', updates); + + store.set(updates); + return store; +} + +export { Store, combineStores }; \ No newline at end of file diff --git a/test/runtime/samples/store-binding/_config.js b/test/runtime/samples/store-binding/_config.js index c9ae020777..aefc4ec652 100644 --- a/test/runtime/samples/store-binding/_config.js +++ b/test/runtime/samples/store-binding/_config.js @@ -1,4 +1,4 @@ -import Store from '../../../../store.js'; +import { Store } from '../../../../store.js'; const store = new Store({ name: 'world' diff --git a/test/runtime/samples/store-computed/_config.js b/test/runtime/samples/store-computed/_config.js index 13fd745f53..f4e6f49e54 100644 --- a/test/runtime/samples/store-computed/_config.js +++ b/test/runtime/samples/store-computed/_config.js @@ -1,4 +1,4 @@ -import Store from '../../../../store.js'; +import { Store } from '../../../../store.js'; class MyStore extends Store { setFilter(filter) { diff --git a/test/runtime/samples/store-event/_config.js b/test/runtime/samples/store-event/_config.js index 6f192ff76f..2779db5fc2 100644 --- a/test/runtime/samples/store-event/_config.js +++ b/test/runtime/samples/store-event/_config.js @@ -1,4 +1,4 @@ -import Store from '../../../../store.js'; +import { Store } from '../../../../store.js'; class MyStore extends Store { setName(name) { diff --git a/test/runtime/samples/store/_config.js b/test/runtime/samples/store/_config.js index 0e1663315b..4e266ff095 100644 --- a/test/runtime/samples/store/_config.js +++ b/test/runtime/samples/store/_config.js @@ -1,4 +1,4 @@ -import Store from '../../../../store.js'; +import { Store } from '../../../../store.js'; const store = new Store({ name: 'world' diff --git a/test/store/index.js b/test/store/index.js index 50b6572774..258bc01c7c 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import Store from '../../store.js'; +import { Store, combineStores } from '../../store.js'; describe('store', () => { describe('get', () => { @@ -143,4 +143,40 @@ describe('store', () => { }, /'bar' is a read-only property/); }); }); + + describe('combineStores', () => { + it('merges stores', () => { + const a = new Store({ + x: 1, + y: 2 + }); + + a.compute('z', ['x', 'y'], (x, y) => x + y); + + const b = new Store({ + x: 3, + y: 4 + }); + + b.compute('z', ['x', 'y'], (x, y) => x + y); + + const c = combineStores(new Store(), { a, b }); + + c.compute('total', ['a', 'b'], (a, b) => a.z + b.z); + + assert.deepEqual(c.get(), { + a: { + x: 1, + y: 2, + z: 3 + }, + b: { + x: 3, + y: 4, + z: 7 + }, + total: 10 + }); + }); + }); }); From e1867e11e24d6a0af46a83e92048216b793d9f52 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 13:55:20 -0500 Subject: [PATCH 16/43] better implementation of computed properties --- store.js | 102 +++++++++++++++++++------------------------- test/store/index.js | 13 +++++- 2 files changed, 55 insertions(+), 60 deletions(-) diff --git a/store.js b/store.js index e285439ddf..2c573b247f 100644 --- a/store.js +++ b/store.js @@ -12,16 +12,10 @@ function Store(state) { this._changeHandlers = []; this._dependents = []; - this._proto = blankObject(); - this._changed = blankObject(); - this._dependentProps = blankObject(); - this._dirty = blankObject(); - this._state = Object.create(this._proto); - - for (var key in state) { - this._changed[key] = true; - this._state[key] = state[key]; - } + this._computed = blankObject(); + this._sortedComputedProperties = []; + + this._state = assign({}, state); } assign(Store.prototype, { @@ -35,17 +29,6 @@ assign(Store.prototype, { }); }, - _makeDirty: function(prop) { - var dependentProps = this._dependentProps[prop]; - if (dependentProps) { - for (var i = 0; i < dependentProps.length; i += 1) { - var dependentProp = dependentProps[i]; - this._dirty[dependentProp] = this._changed[dependentProp] = true; - this._makeDirty(dependentProp); - } - } - }, - _init: function(props) { var state = {}; for (let i = 0; i < props.length; i += 1) { @@ -65,51 +48,51 @@ assign(Store.prototype, { } }, - compute: function(key, deps, fn) { - var store = this; - var value; + _sortComputedProperties() { + var computed = this._computed; + var sorted = this._sortedComputedProperties = []; + var visited = blankObject(); - store._dirty[key] = true; + function visit(key) { + if (visited[key]) return; + var c = computed[key]; - for (var i = 0; i < deps.length; i += 1) { - var dep = deps[i]; - if (!this._dependentProps[dep]) this._dependentProps[dep] = []; - this._dependentProps[dep].push(key); + if (c) { + c.deps.forEach(visit); + sorted.push(c); + } } - Object.defineProperty(this._proto, key, { - enumerable: true, - get: function() { - if (store._dirty[key]) { - var values = deps.map(function(dep) { - if (dep in store._changed) changed = true; - return store._state[dep]; - }); + for (var key in this._computed) visit(key); + }, - var newValue = fn.apply(null, values); + compute: function(key, deps, fn) { + var store = this; + var value; + + var c = { + deps: deps, + update: function(state, changed, dirty) { + var values = deps.map(function(dep) { + if (dep in changed) dirty = true; + return state[dep]; + }); + if (dirty) { + var newValue = fn.apply(null, values); if (differs(newValue, value)) { value = newValue; - store._changed[key] = true; - - var dependentProps = store._dependentProps[key]; - if (dependentProps) { - for (var i = 0; i < dependentProps.length; i += 1) { - var prop = dependentProps[i]; - store._dirty[prop] = store._changed[prop] = true; - } - } + changed[key] = true; + state[key] = value; } - - store._dirty[key] = false; } - - return value; - }, - set: function() { - throw new Error(`'${key}' is a read-only property`); } - }); + }; + + c.update(this._state, {}, true); + + this._computed[key] = c; + this._sortComputedProperties(); }, onchange: function(callback) { @@ -128,13 +111,16 @@ assign(Store.prototype, { dirty = false; for (var key in newState) { + if (this._computed[key]) throw new Error("'" + key + "' is a read-only property"); if (differs(newState[key], oldState[key])) changed[key] = dirty = true; } if (!dirty) return; - this._state = assign(Object.create(this._proto), oldState, newState); + this._state = assign({}, oldState, newState); - for (var key in changed) this._makeDirty(key); + for (var i = 0; i < this._sortedComputedProperties.length; i += 1) { + this._sortedComputedProperties[i].update(this._state, changed); + } for (var i = 0; i < this._changeHandlers.length; i += 1) { this._changeHandlers[i](this._state, changed); @@ -177,8 +163,6 @@ function combineStores(store, children) { }); } - console.log('updates', updates); - store.set(updates); return store; } diff --git a/test/store/index.js b/test/store/index.js index 258bc01c7c..2f5666152c 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -1,7 +1,7 @@ import assert from 'assert'; import { Store, combineStores } from '../../store.js'; -describe('store', () => { +describe.only('store', () => { describe('get', () => { it('gets a specific key', () => { const store = new Store({ @@ -177,6 +177,17 @@ describe('store', () => { }, total: 10 }); + + const values = []; + + c.observe('total', total => { + values.push(total); + }); + + a.set({ x: 2, y: 3 }); + b.set({ x: 5, y: 6 }); + + assert.deepEqual(values, [10, 12, 16]); }); }); }); From 5b8387553e23c32e87a2b7bb307c82af36b9376d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 14:02:24 -0500 Subject: [PATCH 17/43] make target store optional --- store.js | 3 ++- test/store/index.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/store.js b/store.js index 2c573b247f..9c3962d63b 100644 --- a/store.js +++ b/store.js @@ -149,7 +149,8 @@ assign(Store.prototype, { } }); -function combineStores(store, children) { +function combineStores(children, store) { + if (!store) store = new Store(); var updates = {}; for (const key in children) { diff --git a/test/store/index.js b/test/store/index.js index 2f5666152c..246e655229 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -160,7 +160,7 @@ describe.only('store', () => { b.compute('z', ['x', 'y'], (x, y) => x + y); - const c = combineStores(new Store(), { a, b }); + const c = combineStores({ a, b }); c.compute('total', ['a', 'b'], (a, b) => a.z + b.z); From 6c085c0c6423c854de1cfa2e40db125a7c9531c6 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 14:09:41 -0500 Subject: [PATCH 18/43] remove ES2015+ from store.js --- store.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/store.js b/store.js index 9c3962d63b..025d96a5ce 100644 --- a/store.js +++ b/store.js @@ -19,9 +19,6 @@ function Store(state) { } assign(Store.prototype, { - get, - observe -}, { _add: function(component, props) { this._dependents.push({ component: component, @@ -31,7 +28,7 @@ assign(Store.prototype, { _init: function(props) { var state = {}; - for (let i = 0; i < props.length; i += 1) { + for (var i = 0; i < props.length; i += 1) { var prop = props[i]; state['$' + prop] = this._state[prop]; } @@ -39,7 +36,7 @@ assign(Store.prototype, { }, _remove: function(component) { - let i = this._dependents.length; + var i = this._dependents.length; while (i--) { if (this._dependents[i].component === component) { this._dependents.splice(i, 1); @@ -48,7 +45,7 @@ assign(Store.prototype, { } }, - _sortComputedProperties() { + _sortComputedProperties: function() { var computed = this._computed; var sorted = this._sortedComputedProperties = []; var visited = blankObject(); @@ -95,6 +92,10 @@ assign(Store.prototype, { this._sortComputedProperties(); }, + get: get, + + observe: observe, + onchange: function(callback) { this._changeHandlers.push(callback); return { @@ -153,11 +154,11 @@ function combineStores(children, store) { if (!store) store = new Store(); var updates = {}; - for (const key in children) { - const child = children[key]; + for (var key in children) { + var child = children[key]; updates[key] = child.get(); - child.onchange(state => { + child.onchange(function(state) { var update = {}; update[key] = state; store.set(update); From 5d612c50b01510ed994dc5fd7c6091e120cc4599 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 14:23:57 -0500 Subject: [PATCH 19/43] fix ES5 scoping bug --- store.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/store.js b/store.js index 025d96a5ce..d3f3a3a5d9 100644 --- a/store.js +++ b/store.js @@ -154,7 +154,7 @@ function combineStores(children, store) { if (!store) store = new Store(); var updates = {}; - for (var key in children) { + function addChild(key) { var child = children[key]; updates[key] = child.get(); @@ -165,6 +165,8 @@ function combineStores(children, store) { }); } + for (var key in children) addChild(key); + store.set(updates); return store; } From f6d8e2acd9349c31c192f9691ed71c1fe55e99fc Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 17:12:10 -0500 Subject: [PATCH 20/43] remove combineStores --- store.js | 23 +-------------------- test/store/index.js | 49 +-------------------------------------------- 2 files changed, 2 insertions(+), 70 deletions(-) diff --git a/store.js b/store.js index d3f3a3a5d9..a1d6dc4d2e 100644 --- a/store.js +++ b/store.js @@ -150,25 +150,4 @@ assign(Store.prototype, { } }); -function combineStores(children, store) { - if (!store) store = new Store(); - var updates = {}; - - function addChild(key) { - var child = children[key]; - updates[key] = child.get(); - - child.onchange(function(state) { - var update = {}; - update[key] = state; - store.set(update); - }); - } - - for (var key in children) addChild(key); - - store.set(updates); - return store; -} - -export { Store, combineStores }; \ No newline at end of file +export { Store }; \ No newline at end of file diff --git a/test/store/index.js b/test/store/index.js index 246e655229..25099a9066 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -1,7 +1,7 @@ import assert from 'assert'; import { Store, combineStores } from '../../store.js'; -describe.only('store', () => { +describe('store', () => { describe('get', () => { it('gets a specific key', () => { const store = new Store({ @@ -143,51 +143,4 @@ describe.only('store', () => { }, /'bar' is a read-only property/); }); }); - - describe('combineStores', () => { - it('merges stores', () => { - const a = new Store({ - x: 1, - y: 2 - }); - - a.compute('z', ['x', 'y'], (x, y) => x + y); - - const b = new Store({ - x: 3, - y: 4 - }); - - b.compute('z', ['x', 'y'], (x, y) => x + y); - - const c = combineStores({ a, b }); - - c.compute('total', ['a', 'b'], (a, b) => a.z + b.z); - - assert.deepEqual(c.get(), { - a: { - x: 1, - y: 2, - z: 3 - }, - b: { - x: 3, - y: 4, - z: 7 - }, - total: 10 - }); - - const values = []; - - c.observe('total', total => { - values.push(total); - }); - - a.set({ x: 2, y: 3 }); - b.set({ x: 5, y: 6 }); - - assert.deepEqual(values, [10, 12, 16]); - }); - }); }); From 8947e5a9355d3ab7afd360d009fe3505cb78a40f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 25 Nov 2017 17:52:45 -0500 Subject: [PATCH 21/43] -> v1.43.0 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ab7be640a..f90c160485 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Svelte changelog +## 1.43.0 + +* Export `Store` class to manage global state ([#930](https://github.com/sveltejs/svelte/issues/930)) +* Recognise `aria-current` ([#953](https://github.com/sveltejs/svelte/pull/953)) +* Support SSR register options including `extensions` ([#939](https://github.com/sveltejs/svelte/issues/939)) +* Friendlier error for illegal contexts ([#934](https://github.com/sveltejs/svelte/issues/934)) +* Remove whitespace around `<:Window>` components ([#943](https://github.com/sveltejs/svelte/issues/943)) + ## 1.42.1 * Correctly append items inside a slotted `each` block ([#932](https://github.com/sveltejs/svelte/pull/932)) diff --git a/package.json b/package.json index 7b1937020d..bd4c27afec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "1.42.1", + "version": "1.43.0", "description": "The magical disappearing UI framework", "main": "compiler/svelte.js", "files": [ From cd8d144818ed631d525d27aeb29b8849799cdbbb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 06:57:38 -0500 Subject: [PATCH 22/43] allow parameterised transitions - fixes #962 --- src/generators/Generator.ts | 5 +++++ .../dom/visitors/Element/addTransitions.ts | 6 +++--- .../transition-js-parameterised/_config.js | 19 +++++++++++++++++++ .../transition-js-parameterised/main.html | 18 ++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 test/runtime/samples/transition-js-parameterised/_config.js create mode 100644 test/runtime/samples/transition-js-parameterised/main.html diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts index 99f7597276..44b93f85c5 100644 --- a/src/generators/Generator.ts +++ b/src/generators/Generator.ts @@ -755,6 +755,11 @@ export default class Generator { }); this.skip(); } + + if (node.type === 'Transition' && node.expression) { + node.metadata = contextualise(node.expression, contextDependencies, indexes); + this.skip(); + } }, leave(node: Node, parent: Node) { diff --git a/src/generators/dom/visitors/Element/addTransitions.ts b/src/generators/dom/visitors/Element/addTransitions.ts index 26ff6f048e..10d0b90f50 100644 --- a/src/generators/dom/visitors/Element/addTransitions.ts +++ b/src/generators/dom/visitors/Element/addTransitions.ts @@ -21,7 +21,7 @@ export default function addTransitions( if (intro === outro) { const name = block.getUniqueName(`${node.var}_transition`); const snippet = intro.expression - ? intro.expression.metadata.snippet + ? intro.metadata.snippet : '{}'; block.addVariable(name); @@ -51,7 +51,7 @@ export default function addTransitions( if (intro) { block.addVariable(introName); const snippet = intro.expression - ? intro.expression.metadata.snippet + ? intro.metadata.snippet : '{}'; const fn = `%transitions-${intro.name}`; // TODO add built-in transitions? @@ -76,7 +76,7 @@ export default function addTransitions( if (outro) { block.addVariable(outroName); const snippet = outro.expression - ? intro.expression.metadata.snippet + ? outro.metadata.snippet : '{}'; const fn = `%transitions-${outro.name}`; diff --git a/test/runtime/samples/transition-js-parameterised/_config.js b/test/runtime/samples/transition-js-parameterised/_config.js new file mode 100644 index 0000000000..fbfebdae5a --- /dev/null +++ b/test/runtime/samples/transition-js-parameterised/_config.js @@ -0,0 +1,19 @@ +export default { + solo: true, + + test(assert, component, target, window, raf) { + component.set({ visible: true }); + const div = target.querySelector('div'); + assert.equal(div.foo, 0); + + raf.tick(50); + assert.equal(div.foo, 100); + + raf.tick(100); + assert.equal(div.foo, 200); + + raf.tick(101); + + component.destroy(); + }, +}; diff --git a/test/runtime/samples/transition-js-parameterised/main.html b/test/runtime/samples/transition-js-parameterised/main.html new file mode 100644 index 0000000000..de713ae963 --- /dev/null +++ b/test/runtime/samples/transition-js-parameterised/main.html @@ -0,0 +1,18 @@ +{{#if visible}} +
fades in
+{{/if}} + + \ No newline at end of file From e2286da150f3cb91ca9d6ee26379bba99160b588 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 07:21:06 -0500 Subject: [PATCH 23/43] prevent cyclical store computations, and computation duplication --- store.js | 13 ++++++++++++- test/store/index.js | 26 +++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/store.js b/store.js index a1d6dc4d2e..fefc13cd9a 100644 --- a/store.js +++ b/store.js @@ -48,19 +48,30 @@ assign(Store.prototype, { _sortComputedProperties: function() { var computed = this._computed; var sorted = this._sortedComputedProperties = []; + var cycles; var visited = blankObject(); function visit(key) { + if (cycles[key]) { + throw new Error(`Cyclical dependency detected — a computed property cannot indirectly depend on itself`); + } + if (visited[key]) return; + visited[key] = true; + var c = computed[key]; if (c) { + cycles[key] = true; c.deps.forEach(visit); sorted.push(c); } } - for (var key in this._computed) visit(key); + for (var key in this._computed) { + cycles = blankObject(); + visit(key); + } }, compute: function(key, deps, fn) { diff --git a/test/store/index.js b/test/store/index.js index 25099a9066..fabaa64c4b 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import { Store, combineStores } from '../../store.js'; +import { Store } from '../../store.js'; describe('store', () => { describe('get', () => { @@ -142,5 +142,29 @@ describe('store', () => { store.set({ bar: 'whatever' }); }, /'bar' is a read-only property/); }); + + it('allows multiple dependents to depend on the same computed property', () => { + const store = new Store({ + a: 1 + }); + + store.compute('b', ['a'], a => a * 2); + store.compute('c', ['b'], b => b * 3); + store.compute('d', ['b'], b => b * 4); + + assert.deepEqual(store.get(), { a: 1, b: 2, c: 6, d: 8 }); + + // bit cheeky, testing a private property, but whatever + assert.equal(store._sortedComputedProperties.length, 3); + }); + + it('prevents cyclical dependencies', () => { + const store = new Store(); + + assert.throws(() => { + store.compute('a', ['b'], b => b + 1); + store.compute('b', ['a'], a => a + 1); + }, /Cyclical dependency detected — a computed property cannot indirectly depend on itself/); + }); }); }); From a35436579862690fc4cc83734c9b3287c8e59d3b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 07:22:02 -0500 Subject: [PATCH 24/43] gah i always forget this. need a pre-commit hook --- test/runtime/samples/transition-js-parameterised/_config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/runtime/samples/transition-js-parameterised/_config.js b/test/runtime/samples/transition-js-parameterised/_config.js index fbfebdae5a..d12aa06b89 100644 --- a/test/runtime/samples/transition-js-parameterised/_config.js +++ b/test/runtime/samples/transition-js-parameterised/_config.js @@ -1,6 +1,4 @@ export default { - solo: true, - test(assert, component, target, window, raf) { component.set({ visible: true }); const div = target.querySelector('div'); From 8a9044a848fa844be90be1c6998a47f2e878a8f9 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 07:38:29 -0500 Subject: [PATCH 25/43] fix test failures resulting from new JSDOM version --- .../_config.js | 20 ++++---- .../binding-input-checkbox-group/_config.js | 20 ++++---- .../binding-input-radio-group/_config.js | 20 ++++---- yarn.lock | 50 +++++++++++-------- 4 files changed, 55 insertions(+), 55 deletions(-) diff --git a/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js b/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js index bff66c903b..a0ef755fb6 100644 --- a/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js +++ b/test/runtime/samples/binding-input-checkbox-group-outside-each/_config.js @@ -10,19 +10,17 @@ export default { selected: [ values[1] ] }, - 'skip-ssr': true, // values are rendered as [object Object] - html: `

Beta

`, @@ -40,15 +38,15 @@ export default { assert.htmlEqual( target.innerHTML, `

Alpha, Beta

@@ -61,15 +59,15 @@ export default { assert.htmlEqual( target.innerHTML, `

Beta, Gamma

diff --git a/test/runtime/samples/binding-input-checkbox-group/_config.js b/test/runtime/samples/binding-input-checkbox-group/_config.js index bff66c903b..a0ef755fb6 100644 --- a/test/runtime/samples/binding-input-checkbox-group/_config.js +++ b/test/runtime/samples/binding-input-checkbox-group/_config.js @@ -10,19 +10,17 @@ export default { selected: [ values[1] ] }, - 'skip-ssr': true, // values are rendered as [object Object] - html: `

Beta

`, @@ -40,15 +38,15 @@ export default { assert.htmlEqual( target.innerHTML, `

Alpha, Beta

@@ -61,15 +59,15 @@ export default { assert.htmlEqual( target.innerHTML, `

Beta, Gamma

diff --git a/test/runtime/samples/binding-input-radio-group/_config.js b/test/runtime/samples/binding-input-radio-group/_config.js index b557496533..b88dd10d4c 100644 --- a/test/runtime/samples/binding-input-radio-group/_config.js +++ b/test/runtime/samples/binding-input-radio-group/_config.js @@ -10,19 +10,17 @@ export default { selected: values[1] }, - 'skip-ssr': true, // values are rendered as [object Object] - html: `

Beta

`, @@ -40,15 +38,15 @@ export default { assert.htmlEqual( target.innerHTML, `

Alpha

@@ -65,15 +63,15 @@ export default { assert.htmlEqual( target.innerHTML, `

Gamma

diff --git a/yarn.lock b/yarn.lock index ae736a946c..4a8c3799e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,7 +10,7 @@ version "8.0.53" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" -"@types/node@^7.0.18", "@types/node@^7.0.48": +"@types/node@^7.0.18": version "7.0.48" resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.48.tgz#24bfdc0aa82e8f6dbd017159c58094a2e06d0abb" @@ -64,8 +64,8 @@ ajv@^4.9.1: json-stable-stringify "^1.0.1" ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.4.0.tgz#32d1cf08dbc80c432f426f12e10b2511f6b46474" + version "5.5.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -441,8 +441,8 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: supports-color "^4.0.0" chardet@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.0.tgz#0bbe1355ac44d7a3ed4a925707c4ef70f8190f6c" + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" chokidar@^1.7.0: version "1.7.0" @@ -538,10 +538,8 @@ commander@2.9.0: graceful-readlink ">= 1.0.0" commander@^2.9.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.0.tgz#2f13615c39c687a77926aa68ef25c099db1e72fb" - dependencies: - "@types/node" "^7.0.48" + version "2.12.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.1.tgz#468635c4168d06145b9323356d1da84d14ac4a7a" commondir@^1.0.1: version "1.0.1" @@ -580,8 +578,8 @@ content-type-parser@^1.0.1: resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" convert-source-map@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" core-js@^2.4.0: version "2.5.1" @@ -744,12 +742,11 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" +doctrine@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.2.tgz#68f96ce8efc56cc42651f1faadb4f175273b0075" dependencies: esutils "^2.0.2" - isarray "^1.0.0" dom-serializer@0: version "0.1.0" @@ -890,8 +887,8 @@ eslint-scope@^3.7.1: estraverse "^4.1.1" eslint@^4.3.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.11.0.tgz#39a8c82bc0a3783adf5a39fa27fdd9d36fac9a34" + version "4.12.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.0.tgz#a7ce78eba8cc8f2443acfbbc870cc31a65135884" dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -899,7 +896,7 @@ eslint@^4.3.0: concat-stream "^1.6.0" cross-spawn "^5.1.0" debug "^3.0.1" - doctrine "^2.0.0" + doctrine "^2.0.2" eslint-scope "^3.7.1" espree "^3.5.2" esquery "^1.0.0" @@ -908,7 +905,7 @@ eslint@^4.3.0: file-entry-cache "^2.0.0" functional-red-black-tree "^1.0.1" glob "^7.1.2" - globals "^9.17.0" + globals "^11.0.1" ignore "^3.3.3" imurmurhash "^0.1.4" inquirer "^3.0.6" @@ -1272,7 +1269,11 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.17.0, globals@^9.18.0: +globals@^11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.0.1.tgz#12a87bb010e5154396acc535e1e43fc753b0e5e8" + +globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -1723,8 +1724,8 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" jsdom@^11.1.0: - version "11.4.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.4.0.tgz#a3941a9699cbb0d61f8ab86f6f28f4ad5ea60d04" + version "11.5.1" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.5.1.tgz#5df753b8d0bca20142ce21f4f6c039f99a992929" dependencies: abab "^1.0.3" acorn "^5.1.2" @@ -1737,6 +1738,7 @@ jsdom@^11.1.0: domexception "^1.0.0" escodegen "^1.9.0" html-encoding-sniffer "^1.0.1" + left-pad "^1.2.0" nwmatcher "^1.4.3" parse5 "^3.0.2" pn "^1.0.0" @@ -1839,6 +1841,10 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +left-pad@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" From 4054b875347fce8017b67549701c21f9362214b2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 07:43:30 -0500 Subject: [PATCH 26/43] shorter error message, remove ES6 template string --- store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/store.js b/store.js index fefc13cd9a..f31c659080 100644 --- a/store.js +++ b/store.js @@ -53,7 +53,7 @@ assign(Store.prototype, { function visit(key) { if (cycles[key]) { - throw new Error(`Cyclical dependency detected — a computed property cannot indirectly depend on itself`); + throw new Error('Cyclical dependency detected'); } if (visited[key]) return; From 27e3e3330fba174c82af4781077316ca800760b3 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 07:50:33 -0500 Subject: [PATCH 27/43] guard against introducing ES6+isms into store.js --- test/store/index.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/store/index.js b/test/store/index.js index fabaa64c4b..f8467e9e89 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -1,7 +1,27 @@ +import fs from 'fs'; import assert from 'assert'; +import MagicString from 'magic-string'; +import { parse } from 'acorn'; import { Store } from '../../store.js'; describe('store', () => { + it('is written in ES5', () => { + const source = fs.readFileSync('store.js', 'utf-8'); + + const ast = parse(source, { + sourceType: 'module' + }); + + const magicString = new MagicString(source); + ast.body.forEach(node => { + if (/^(Im|Ex)port/.test(node.type)) magicString.remove(node.start, node.end); + }); + + parse(magicString.toString(), { + ecmaVersion: 5 + }); + }); + describe('get', () => { it('gets a specific key', () => { const store = new Store({ From 0b8ef112ca94c1807641c977ce1faea9976c86b5 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 08:12:11 -0500 Subject: [PATCH 28/43] prevent boolean attributes breaking shapes inside estree-walker - fixes #961 --- src/generators/Generator.ts | 11 ++--------- .../Link.html | 1 + .../_config.js | 3 +++ .../main.html | 10 ++++++++++ 4 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 test/runtime/samples/component-data-static-boolean-regression/Link.html create mode 100644 test/runtime/samples/component-data-static-boolean-regression/_config.js create mode 100644 test/runtime/samples/component-data-static-boolean-regression/main.html diff --git a/src/generators/Generator.ts b/src/generators/Generator.ts index 44b93f85c5..3cd6d5da25 100644 --- a/src/generators/Generator.ts +++ b/src/generators/Generator.ts @@ -72,15 +72,8 @@ function removeIndentation( // We need to tell estree-walker that it should always // look for an `else` block, otherwise it might get // the wrong idea about the shape of each/if blocks -childKeys.EachBlock = [ - 'children', - 'else' -]; - -childKeys.IfBlock = [ - 'children', - 'else' -]; +childKeys.EachBlock = childKeys.IfBlock = ['children', 'else']; +childKeys.Attribute = ['value']; export default class Generator { ast: Parsed; diff --git a/test/runtime/samples/component-data-static-boolean-regression/Link.html b/test/runtime/samples/component-data-static-boolean-regression/Link.html new file mode 100644 index 0000000000..ecdf709900 --- /dev/null +++ b/test/runtime/samples/component-data-static-boolean-regression/Link.html @@ -0,0 +1 @@ +link \ No newline at end of file diff --git a/test/runtime/samples/component-data-static-boolean-regression/_config.js b/test/runtime/samples/component-data-static-boolean-regression/_config.js new file mode 100644 index 0000000000..61f8ba0a06 --- /dev/null +++ b/test/runtime/samples/component-data-static-boolean-regression/_config.js @@ -0,0 +1,3 @@ +export default { + html: `link` +}; diff --git a/test/runtime/samples/component-data-static-boolean-regression/main.html b/test/runtime/samples/component-data-static-boolean-regression/main.html new file mode 100644 index 0000000000..5f51d903b3 --- /dev/null +++ b/test/runtime/samples/component-data-static-boolean-regression/main.html @@ -0,0 +1,10 @@ + + + \ No newline at end of file From a075bb552c9be6ebe6aae94f9f5207ace95bf374 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 08:18:09 -0500 Subject: [PATCH 29/43] update test --- test/store/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/store/index.js b/test/store/index.js index f8467e9e89..d8053367a9 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -184,7 +184,7 @@ describe('store', () => { assert.throws(() => { store.compute('a', ['b'], b => b + 1); store.compute('b', ['a'], a => a + 1); - }, /Cyclical dependency detected — a computed property cannot indirectly depend on itself/); + }, /Cyclical dependency detected/); }); }); }); From 9c4386b3da6a1efa3f1883b46c6a69e674c7bb8a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 27 Nov 2017 08:25:09 -0500 Subject: [PATCH 30/43] -> v1.43.1 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f90c160485..50b5a7bbe6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Svelte changelog +## 1.43.1 + +* Fix parameterised transitions ([#962](https://github.com/sveltejs/svelte/issues/962)) +* Prevent boolean attributes breaking estree-walker expectations ([#961](https://github.com/sveltejs/svelte/issues/961)) +* Throw error on cyclical store computations ([#964](https://github.com/sveltejs/svelte/pull/964)) + ## 1.43.0 * Export `Store` class to manage global state ([#930](https://github.com/sveltejs/svelte/issues/930)) diff --git a/package.json b/package.json index bd4c27afec..6684fdbd4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "1.43.0", + "version": "1.43.1", "description": "The magical disappearing UI framework", "main": "compiler/svelte.js", "files": [ From 6500b460e807c3de3689d9057d13ccf1ec993a95 Mon Sep 17 00:00:00 2001 From: Efthymis Sarmpanis Date: Mon, 20 Nov 2017 12:16:34 +0200 Subject: [PATCH 31/43] Basic support for style and script preprocessors Suggestion for #181 and #876 --- package.json | 5 + src/index.ts | 80 ++- src/interfaces.ts | 13 +- test/preprocess/index.js | 169 ++++++ .../use-coffeescript-preprocessor/_config.js | 19 + .../expected.html | 1 + .../use-coffeescript-preprocessor/input.html | 8 + .../samples/use-pug-preprocessor/_config.js | 15 + .../samples/use-pug-preprocessor/expected.css | 1 + .../samples/use-pug-preprocessor/input.pug | 10 + .../_config.js | 26 + .../_variables.scss | 2 + .../expected.css | 1 + .../input.html | 13 + .../samples/use-scss-preprocessor/_config.js | 26 + .../use-scss-preprocessor/expected.css | 1 + .../samples/use-scss-preprocessor/input.html | 14 + .../_config.js | 24 + .../expected.css | 1 + .../input.html | 12 + .../variables.styl | 2 + .../use-stylus-preprocessor/_config.js | 20 + .../use-stylus-preprocessor/expected.css | 1 + .../use-stylus-preprocessor/input.html | 13 + yarn.lock | 540 ++++++++++++++++-- 25 files changed, 970 insertions(+), 47 deletions(-) create mode 100644 test/preprocess/index.js create mode 100644 test/preprocess/samples/use-coffeescript-preprocessor/_config.js create mode 100644 test/preprocess/samples/use-coffeescript-preprocessor/expected.html create mode 100644 test/preprocess/samples/use-coffeescript-preprocessor/input.html create mode 100644 test/preprocess/samples/use-pug-preprocessor/_config.js create mode 100644 test/preprocess/samples/use-pug-preprocessor/expected.css create mode 100644 test/preprocess/samples/use-pug-preprocessor/input.pug create mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js create mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss create mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css create mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html create mode 100644 test/preprocess/samples/use-scss-preprocessor/_config.js create mode 100644 test/preprocess/samples/use-scss-preprocessor/expected.css create mode 100644 test/preprocess/samples/use-scss-preprocessor/input.html create mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js create mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css create mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html create mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl create mode 100644 test/preprocess/samples/use-stylus-preprocessor/_config.js create mode 100644 test/preprocess/samples/use-stylus-preprocessor/expected.css create mode 100644 test/preprocess/samples/use-stylus-preprocessor/input.html diff --git a/package.json b/package.json index 6684fdbd4d..6e3f0f9304 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "acorn": "^5.1.1", "chalk": "^2.0.1", "codecov": "^2.2.0", + "coffeescript": "^2.0.2", "console-group": "^0.3.2", "css-tree": "1.0.0-alpha22", "eslint": "^4.3.0", @@ -55,13 +56,16 @@ "estree-walker": "^0.5.1", "glob": "^7.1.1", "jsdom": "^11.1.0", + "less": "^2.7.3", "locate-character": "^2.0.0", "magic-string": "^0.22.3", "mocha": "^3.2.0", "nightmare": "^2.10.0", "node-resolve": "^1.3.3", + "node-sass": "^4.7.1", "nyc": "^11.1.0", "prettier": "^1.7.0", + "pug": "^2.0.0-rc.4", "reify": "^0.12.3", "rollup": "^0.48.2", "rollup-plugin-buble": "^0.15.0", @@ -74,6 +78,7 @@ "rollup-watch": "^4.3.1", "source-map": "^0.5.6", "source-map-support": "^0.4.8", + "stylus": "^0.54.5", "ts-node": "^3.3.0", "tslib": "^1.8.0", "typescript": "^2.6.1" diff --git a/src/index.ts b/src/index.ts index 529be61618..a6b1ccc32e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,12 +4,13 @@ import generate from './generators/dom/index'; import generateSSR from './generators/server-side-rendering/index'; import { assign } from './shared/index.js'; import Stylesheet from './css/Stylesheet'; -import { Parsed, CompileOptions, Warning } from './interfaces'; +import { Parsed, CompileOptions, Warning, PreprocessOptions, Preprocessor } from './interfaces'; +import { SourceMap } from 'magic-string'; const version = '__VERSION__'; function normalizeOptions(options: CompileOptions): CompileOptions { - let normalizedOptions = assign({ generate: 'dom' }, options); + let normalizedOptions = assign({ generate: 'dom', preprocessor: false }, options); const { onwarn, onerror } = normalizedOptions; normalizedOptions.onwarn = onwarn ? (warning: Warning) => onwarn(warning, defaultOnwarn) @@ -34,9 +35,78 @@ function defaultOnerror(error: Error) { throw error; } +function _parseAttributeValue(value: string | boolean) { + const curated = (value).replace(/"/ig, ''); + if (curated === 'true' || curated === 'false') { + return curated === 'true'; + } + return curated; +} + +function _parseStyleAttributes(str: string) { + const attrs = {}; + str.split(/\s+/).filter(Boolean).forEach(attr => { + const [name, value] = attr.split('='); + attrs[name] = _parseAttributeValue(value); + }); + return attrs; +} + +async function _doPreprocess(source, type: 'script' | 'style', preprocessor: Preprocessor) { + const exp = new RegExp(`<${type}([\\S\\s]*?)>([\\S\\s]*?)<\\/${type}>`, 'ig'); + const match = exp.exec(source); + if (match) { + const attributes: Record = _parseStyleAttributes(match[1]); + const content: string = match[2]; + const processed: { code: string, map?: SourceMap | string } = await preprocessor({ + content, + attributes + }); + return source.replace(content, processed.code || content); + } +} + +export async function preprocess(source: string, options: PreprocessOptions) { + const { markup, style, script } = options; + if (!!markup) { + try { + const processed: { code: string, map?: SourceMap | string } = await markup({ content: source }); + source = processed.code; + } catch (error) { + defaultOnerror(error); + } + } + + if (!!style) { + try { + source = await _doPreprocess(source, 'style', style); + } catch (error) { + defaultOnerror(error); + } + } + + if (!!script) { + try { + source = await _doPreprocess(source, 'script', script); + } catch (error) { + defaultOnerror(error); + } + } + + return { + // TODO return separated output, in future version where svelte.compile supports it: + // style: { code: styleCode, map: styleMap }, + // script { code: scriptCode, map: scriptMap }, + // markup { code: markupCode, map: markupMap }, + + toString() { + return source; + } + }; +} + export function compile(source: string, _options: CompileOptions) { const options = normalizeOptions(_options); - let parsed: Parsed; try { @@ -53,7 +123,7 @@ export function compile(source: string, _options: CompileOptions) { const compiler = options.generate === 'ssr' ? generateSSR : generate; return compiler(parsed, source, stylesheet, options); -} +}; export function create(source: string, _options: CompileOptions = {}) { _options.format = 'eval'; @@ -65,7 +135,7 @@ export function create(source: string, _options: CompileOptions = {}) { } try { - return (0,eval)(compiled.code); + return (0, eval)(compiled.code); } catch (err) { if (_options.onerror) { _options.onerror(err); diff --git a/src/interfaces.ts b/src/interfaces.ts index 3a9280df3c..bcfb24f568 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -1,3 +1,5 @@ +import {SourceMap} from 'magic-string'; + export interface Node { start: number; end: number; @@ -60,6 +62,7 @@ export interface CompileOptions { onerror?: (error: Error) => void; onwarn?: (warning: Warning) => void; + preprocessor?: ((raw: string) => string) | false ; } export interface GenerateOptions { @@ -78,4 +81,12 @@ export interface Visitor { export interface CustomElementOptions { tag?: string; props?: string[]; -} \ No newline at end of file +} + +export interface PreprocessOptions { + markup?: (options: {content: string}) => { code: string, map?: SourceMap | string }; + style?: Preprocessor; + script?: Preprocessor; +} + +export type Preprocessor = (options: {content: string, attributes: Record}) => { code: string, map?: SourceMap | string }; diff --git a/test/preprocess/index.js b/test/preprocess/index.js new file mode 100644 index 0000000000..209e81070b --- /dev/null +++ b/test/preprocess/index.js @@ -0,0 +1,169 @@ +import assert from 'assert'; +import * as fs from 'fs'; +import {parse} from 'acorn'; +import {addLineNumbers, env, normalizeHtml, svelte} from '../helpers.js'; + +function tryRequire(file) { + try { + const mod = require(file); + return mod.default || mod; + } catch (err) { + if (err.code !== 'MODULE_NOT_FOUND') throw err; + return null; + } +} + +function normalizeWarning(warning) { + warning.frame = warning.frame.replace(/^\n/, ''). + replace(/^\t+/gm, ''). + replace(/\s+$/gm, ''); + delete warning.filename; + delete warning.toString; + return warning; +} + +function checkCodeIsValid(code) { + try { + parse(code); + } catch (err) { + console.error(addLineNumbers(code)); + throw new Error(err.message); + } +} + +describe('preprocess', () => { + fs.readdirSync('test/preprocess/samples').forEach(dir => { + if (dir[0] === '.') return; + + // add .solo to a sample directory name to only run that test + const solo = /\.solo/.test(dir); + const skip = /\.skip/.test(dir); + + if (solo && process.env.CI) { + throw new Error('Forgot to remove `solo: true` from test'); + } + + (solo ? it.only : skip ? it.skip : it)(dir, () => { + const config = tryRequire(`./samples/${dir}/_config.js`) || {}; + const input = fs.existsSync(`test/preprocess/samples/${dir}/input.pug`) ? + fs.readFileSync(`test/preprocess/samples/${dir}/input.pug`, + 'utf-8').replace(/\s+$/, '') : + fs.readFileSync(`test/preprocess/samples/${dir}/input.html`, + 'utf-8').replace(/\s+$/, ''); + + svelte.preprocess(input, config). + then(processed => processed.toString()). + then(processed => { + + const expectedWarnings = (config.warnings || []).map( + normalizeWarning); + const domWarnings = []; + const ssrWarnings = []; + + const dom = svelte.compile( + processed, + Object.assign(config, { + format: 'iife', + name: 'SvelteComponent', + onwarn: warning => { + domWarnings.push(warning); + }, + }) + ); + + const ssr = svelte.compile( + processed, + Object.assign(config, { + format: 'iife', + generate: 'ssr', + name: 'SvelteComponent', + onwarn: warning => { + ssrWarnings.push(warning); + }, + }) + ); + + // check the code is valid + checkCodeIsValid(dom.code); + checkCodeIsValid(ssr.code); + + assert.equal(dom.css, ssr.css); + + assert.deepEqual( + domWarnings.map(normalizeWarning), + ssrWarnings.map(normalizeWarning) + ); + assert.deepEqual(domWarnings.map(normalizeWarning), expectedWarnings); + + const expected = { + html: read(`test/preprocess/samples/${dir}/expected.html`), + css: read(`test/preprocess/samples/${dir}/expected.css`), + }; + + if (expected.css !== null) { + fs.writeFileSync(`test/preprocess/samples/${dir}/_actual.css`, + dom.css); + assert.equal(dom.css.replace(/svelte-\d+/g, 'svelte-xyz'), + expected.css); + } + + // verify that the right elements have scoping selectors + if (expected.html !== null) { + const window = env(); + + // dom + try { + const Component = eval( + `(function () { ${dom.code}; return SvelteComponent; }())` + ); + const target = window.document.querySelector('main'); + + new Component({target, data: config.data}); + const html = target.innerHTML; + + fs.writeFileSync(`test/preprocess/samples/${dir}/_actual.html`, + html); + + assert.equal( + normalizeHtml(window, + html.replace(/svelte-\d+/g, 'svelte-xyz')), + normalizeHtml(window, expected.html) + ); + } catch (err) { + console.log(dom.code); + throw err; + } + + // ssr + try { + const component = eval( + `(function () { ${ssr.code}; return SvelteComponent; }())` + ); + + assert.equal( + normalizeHtml( + window, + component.render(config.data). + replace(/svelte-\d+/g, 'svelte-xyz') + ), + normalizeHtml(window, expected.html) + ); + } catch (err) { + console.log(ssr.code); + throw err; + } + } + }).catch(error => { + throw error; + }); + }); + }); +}); + +function read(file) { + try { + return fs.readFileSync(file, 'utf-8'); + } catch (err) { + return null; + } +} diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/_config.js b/test/preprocess/samples/use-coffeescript-preprocessor/_config.js new file mode 100644 index 0000000000..1865fe4086 --- /dev/null +++ b/test/preprocess/samples/use-coffeescript-preprocessor/_config.js @@ -0,0 +1,19 @@ +import * as CoffeeScript from 'coffeescript'; + +export default { + cascade: false, + script: ({content, attributes}) => { + if (attributes.type !== 'text/coffeescript') { + return {code: content}; + } + + return new Promise((fulfil, reject) => { + try { + const code = CoffeeScript.compile(content, {}); + fulfil({code}); + } catch (error) { + reject(error); + } + }); + }, +}; diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/expected.html b/test/preprocess/samples/use-coffeescript-preprocessor/expected.html new file mode 100644 index 0000000000..2c473ea019 --- /dev/null +++ b/test/preprocess/samples/use-coffeescript-preprocessor/expected.html @@ -0,0 +1 @@ +

Hello foo!

diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/input.html b/test/preprocess/samples/use-coffeescript-preprocessor/input.html new file mode 100644 index 0000000000..50c7f64347 --- /dev/null +++ b/test/preprocess/samples/use-coffeescript-preprocessor/input.html @@ -0,0 +1,8 @@ +

Hello {{name}}!

+ + \ No newline at end of file diff --git a/test/preprocess/samples/use-pug-preprocessor/_config.js b/test/preprocess/samples/use-pug-preprocessor/_config.js new file mode 100644 index 0000000000..7a345bfd91 --- /dev/null +++ b/test/preprocess/samples/use-pug-preprocessor/_config.js @@ -0,0 +1,15 @@ +import * as pug from 'pug'; + +export default { + cascade: false, + markup: ({content}) => { + return new Promise((fulfil, reject) => { + try { + const code = pug.render(content); + fulfil({code}); + } catch (error) { + reject(error); + } + }); + }, +}; diff --git a/test/preprocess/samples/use-pug-preprocessor/expected.css b/test/preprocess/samples/use-pug-preprocessor/expected.css new file mode 100644 index 0000000000..2217e804d9 --- /dev/null +++ b/test/preprocess/samples/use-pug-preprocessor/expected.css @@ -0,0 +1 @@ +[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue} \ No newline at end of file diff --git a/test/preprocess/samples/use-pug-preprocessor/input.pug b/test/preprocess/samples/use-pug-preprocessor/input.pug new file mode 100644 index 0000000000..d32e76527d --- /dev/null +++ b/test/preprocess/samples/use-pug-preprocessor/input.pug @@ -0,0 +1,10 @@ +div(foo="bar") +div(baz) + +style(type="text/css") + |[foo] { + | color: red; + | } + |[baz] { + | color: blue; + |} diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js b/test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js new file mode 100644 index 0000000000..6daae7c7a3 --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js @@ -0,0 +1,26 @@ +import * as sass from 'node-sass'; +import * as path from 'path'; + +export default { + cascade: false, + style: ({ content, attributes }) => { + if (attributes.type !== 'text/scss') { + return {code: content}; + } + + return new Promise((fulfil, reject) => { + sass.render({ + data: content, + includePaths: [ + path.resolve(__dirname) + ] + }, (err, result) => { + if (err) { + reject(err); + } else { + fulfil({ code: result.css.toString(), map: result.map }); + } + }); + }); + } +}; diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss b/test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss new file mode 100644 index 0000000000..be7eddc5a4 --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss @@ -0,0 +1,2 @@ +$foo-color: red; +$baz-color: blue; diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css b/test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css new file mode 100644 index 0000000000..2217e804d9 --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css @@ -0,0 +1 @@ +[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue} \ No newline at end of file diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html b/test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html new file mode 100644 index 0000000000..2db43e1c6f --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html @@ -0,0 +1,13 @@ +
+
+ + diff --git a/test/preprocess/samples/use-scss-preprocessor/_config.js b/test/preprocess/samples/use-scss-preprocessor/_config.js new file mode 100644 index 0000000000..cb3a1a505a --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor/_config.js @@ -0,0 +1,26 @@ +import * as sass from 'node-sass'; + +export default { + cascade: false, + style: ({ content, attributes }) => { + if (attributes.type !== 'text/scss') { + return {code: content}; + } + + if (attributes['aria-hidden'] !== true) { + throw new Error('aria-hidden is supposed to be true'); + } + + return new Promise((fulfil, reject) => { + sass.render({ + data: content, + }, (err, result) => { + if (err) { + reject(err); + } else { + fulfil({ code: result.css.toString(), map: result.map }); + } + }); + }); + } +}; diff --git a/test/preprocess/samples/use-scss-preprocessor/expected.css b/test/preprocess/samples/use-scss-preprocessor/expected.css new file mode 100644 index 0000000000..2217e804d9 --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor/expected.css @@ -0,0 +1 @@ +[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue} \ No newline at end of file diff --git a/test/preprocess/samples/use-scss-preprocessor/input.html b/test/preprocess/samples/use-scss-preprocessor/input.html new file mode 100644 index 0000000000..4e6384ebdc --- /dev/null +++ b/test/preprocess/samples/use-scss-preprocessor/input.html @@ -0,0 +1,14 @@ +
+
+ + diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js new file mode 100644 index 0000000000..3806a407f2 --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js @@ -0,0 +1,24 @@ +import * as stylus from 'stylus'; +import * as path from 'path'; + +export default { + preprocessor: (styles) => + stylus(styles).include(path.resolve(__dirname)).render(), + cascade: false, + style: ({content, attributes}) => { + if (attributes.type !== 'text/stylus') { + return {code: content}; + } + + return new Promise((fulfil, reject) => { + stylus(content).include(path.resolve(__dirname)). + render((err, result) => { + if (err) { + reject(err); + } else { + fulfil({code: result}); + } + }); + }); + }, +}; diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css new file mode 100644 index 0000000000..8bfade2024 --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css @@ -0,0 +1 @@ +[foo][svelte-xyz]{color:#f00}[baz][svelte-xyz]{color:#00f} \ No newline at end of file diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html new file mode 100644 index 0000000000..2dffa65b3b --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html @@ -0,0 +1,12 @@ +
+
+ + diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl new file mode 100644 index 0000000000..d9ff4b9275 --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl @@ -0,0 +1,2 @@ +foo-color = red +baz-color = blue diff --git a/test/preprocess/samples/use-stylus-preprocessor/_config.js b/test/preprocess/samples/use-stylus-preprocessor/_config.js new file mode 100644 index 0000000000..8e92e4ad60 --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor/_config.js @@ -0,0 +1,20 @@ +import * as stylus from 'stylus'; + +export default { + cascade: false, + style: ({content, attributes}) => { + if (attributes.type !== 'text/stylus') { + return {code: content}; + } + + return new Promise((fulfil, reject) => { + stylus(content).render((err, result) => { + if (err) { + reject(err); + } else { + fulfil({code: result}); + } + }); + }); + }, +}; diff --git a/test/preprocess/samples/use-stylus-preprocessor/expected.css b/test/preprocess/samples/use-stylus-preprocessor/expected.css new file mode 100644 index 0000000000..8bfade2024 --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor/expected.css @@ -0,0 +1 @@ +[foo][svelte-xyz]{color:#f00}[baz][svelte-xyz]{color:#00f} \ No newline at end of file diff --git a/test/preprocess/samples/use-stylus-preprocessor/input.html b/test/preprocess/samples/use-stylus-preprocessor/input.html new file mode 100644 index 0000000000..259c0d45ed --- /dev/null +++ b/test/preprocess/samples/use-stylus-preprocessor/input.html @@ -0,0 +1,13 @@ +
+
+ + diff --git a/yarn.lock b/yarn.lock index 4a8c3799e3..0e3f324f0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,6 +22,12 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +acorn-globals@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" + dependencies: + acorn "^4.0.4" + acorn-globals@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" @@ -40,10 +46,14 @@ acorn-object-spread@^1.0.0: dependencies: acorn "^3.1.0" -acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0: +acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0, acorn@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^4.0.4, acorn@~4.0.2: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + acorn@^5.0.0, acorn@^5.1.1, acorn@^5.1.2, acorn@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" @@ -180,6 +190,10 @@ arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -196,6 +210,10 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + async@^1.4.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -403,6 +421,10 @@ camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -440,6 +462,12 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +character-parser@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" + dependencies: + is-regex "^1.0.3" + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -463,6 +491,13 @@ circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" +clean-css@^3.3.0: + version "3.4.28" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" + dependencies: + commander "2.8.x" + source-map "0.4.x" + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -509,6 +544,10 @@ codecov@^2.2.0: request "2.77.0" urlgrey "0.4.4" +coffeescript@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.0.3.tgz#760f02724f5f0911be7cefa34a8e0e10c5d8512a" + color-convert@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" @@ -531,6 +570,12 @@ commander@1.0.4: dependencies: keypress "0.1.x" +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + dependencies: + graceful-readlink ">= 1.0.0" + commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -569,6 +614,13 @@ console-group@^0.3.2: version "0.3.3" resolved "https://registry.yarnpkg.com/console-group/-/console-group-0.3.3.tgz#6d8eb6b9d6b757a2895284f62d09c7ad43f2bbce" +constantinople@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.0.tgz#7569caa8aa3f8d5935d62e1fa96f9f702cd81c79" + dependencies: + acorn "^3.1.0" + is-expression "^2.0.1" + contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" @@ -589,6 +641,13 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cross-spawn@^4: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -616,6 +675,10 @@ cryptiles@3.x.x: dependencies: boom "5.x.x" +css-parse@1.7.x: + version "1.7.0" + resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b" + css-tree@1.0.0-alpha22: version "1.0.0-alpha22" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha22.tgz#338a006e331c7b4f9dab7b6af539ece56ff78af2" @@ -649,6 +712,12 @@ debug-log@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" +debug@*, debug@^3.0.1, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + debug@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" @@ -661,12 +730,6 @@ debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.6.8: dependencies: ms "2.0.0" -debug@^3.0.1, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -748,6 +811,10 @@ doctrine@^2.0.2: dependencies: esutils "^2.0.2" +doctypes@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" + dom-serializer@0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -818,6 +885,12 @@ entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" +errno@^0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + dependencies: + prr "~0.0.0" + error-ex@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" @@ -1206,6 +1279,12 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +gaze@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" + dependencies: + globule "^1.0.0" + generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" @@ -1247,6 +1326,17 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" +glob@7.0.x: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" @@ -1258,7 +1348,17 @@ glob@7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: +glob@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -1288,6 +1388,14 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globule@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" + dependencies: + glob "~7.1.1" + lodash "~4.17.4" + minimatch "~3.0.2" + graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -1450,10 +1558,18 @@ ignore@^3.3.3: version "3.3.7" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -1534,6 +1650,20 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" +is-expression@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-2.1.0.tgz#91be9d47debcfef077977e9722be6dcfb4465ef0" + dependencies: + acorn "~3.3.0" + object-assign "^4.0.1" + +is-expression@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f" + dependencies: + acorn "~4.0.2" + object-assign "^4.0.1" + is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -1613,7 +1743,7 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" -is-promise@^2.1.0: +is-promise@^2.0.0, is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -1621,6 +1751,12 @@ is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" +is-regex@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" @@ -1708,6 +1844,14 @@ istanbul-reports@^1.1.3: dependencies: handlebars "^4.0.3" +js-base64@^2.1.8: + version "2.3.2" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf" + +js-stringify@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" + js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -1809,6 +1953,13 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" +jstransformer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" + dependencies: + is-promise "^2.0.0" + promise "^7.0.1" + keypress@0.1.x: version "0.1.0" resolved "https://registry.yarnpkg.com/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a" @@ -1845,6 +1996,19 @@ left-pad@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" +less@^2.7.3: + version "2.7.3" + resolved "https://registry.yarnpkg.com/less/-/less-2.7.3.tgz#cc1260f51c900a9ec0d91fb6998139e02507b63b" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + mime "^1.2.11" + mkdirp "^0.5.0" + promise "^7.1.1" + request "2.81.0" + source-map "^0.5.3" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1905,6 +2069,14 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + +lodash.clonedeep@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" @@ -1933,6 +2105,10 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" +lodash.mergewith@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -1941,7 +2117,7 @@ lodash@3.0.x: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.0.1.tgz#14d49028a38bc740241d11e2ecd57ec06d73c19a" -lodash@^4.13.1, lodash@^4.17.4, lodash@^4.3.0: +lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -2009,7 +2185,7 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" -meow@^3.1.0: +meow@^3.1.0, meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: @@ -2058,11 +2234,15 @@ mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: dependencies: mime-db "~1.30.0" +mime@^1.2.11: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -2104,7 +2284,7 @@ mkdirp@0.5.0: dependencies: minimist "0.0.8" -mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -2135,7 +2315,7 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.3.0: +nan@^2.3.0, nan@^2.3.2: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" @@ -2161,6 +2341,24 @@ nightmare@^2.10.0: sliced "1.0.1" split2 "^2.0.1" +node-gyp@^3.3.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "2" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + node-pre-gyp@^0.6.39: version "0.6.39" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" @@ -2184,10 +2382,40 @@ node-resolve@^1.3.3: is-builtin-module "^1.0.0" lodash "^4.13.1" +node-sass@^4.7.1: + version "4.7.2" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e" + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + lodash.mergewith "^4.6.0" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.3.2" + node-gyp "^3.3.1" + npmlog "^4.0.0" + request "~2.79.0" + sass-graph "^2.2.4" + stdout-stream "^1.4.0" + "true-case-path" "^1.0.2" + node-uuid@~1.4.7: version "1.4.8" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -2216,7 +2444,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^4.0.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -2330,6 +2558,12 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -2342,7 +2576,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@^0.1.4: +osenv@0, osenv@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" dependencies: @@ -2502,10 +2736,113 @@ progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" +promise@^7.0.1, promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +pug-attrs@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.2.tgz#8be2b2225568ffa75d1b866982bff9f4111affcb" + dependencies: + constantinople "^3.0.1" + js-stringify "^1.0.1" + pug-runtime "^2.0.3" + +pug-code-gen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.0.tgz#96aea39a9e62f1ec5d2b6a5b42a29d528c70b43d" + dependencies: + constantinople "^3.0.1" + doctypes "^1.1.0" + js-stringify "^1.0.1" + pug-attrs "^2.0.2" + pug-error "^1.3.2" + pug-runtime "^2.0.3" + void-elements "^2.0.1" + with "^5.0.0" + +pug-error@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.2.tgz#53ae7d9d29bb03cf564493a026109f54c47f5f26" + +pug-filters@^2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-2.1.5.tgz#66bf6e80d97fbef829bab0aa35eddff33fc964f3" + dependencies: + clean-css "^3.3.0" + constantinople "^3.0.1" + jstransformer "1.0.0" + pug-error "^1.3.2" + pug-walk "^1.1.5" + resolve "^1.1.6" + uglify-js "^2.6.1" + +pug-lexer@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-3.1.0.tgz#fd087376d4a675b4f59f8fef422883434e9581a2" + dependencies: + character-parser "^2.1.1" + is-expression "^3.0.0" + pug-error "^1.3.2" + +pug-linker@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.3.tgz#25f59eb750237f0368e59c3379764229c0189c41" + dependencies: + pug-error "^1.3.2" + pug-walk "^1.1.5" + +pug-load@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.9.tgz#ee217c914cc1d9324d44b86c32d1df241d36de7a" + dependencies: + object-assign "^4.1.0" + pug-walk "^1.1.5" + +pug-parser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-4.0.0.tgz#c9f52322e4eabe4bf5beeba64ed18373bb627801" + dependencies: + pug-error "^1.3.2" + token-stream "0.0.1" + +pug-runtime@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.3.tgz#98162607b0fce9e254d427f33987a5aee7168bda" + +pug-strip-comments@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz#d313afa01bcc374980e1399e23ebf2eb9bdc8513" + dependencies: + pug-error "^1.3.2" + +pug-walk@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.5.tgz#90e943acbcf7021e6454cf1b32245891cba6f851" + +pug@^2.0.0-rc.4: + version "2.0.0-rc.4" + resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.0-rc.4.tgz#b7b08f6599bd5302568042b7436984fb28c80a13" + dependencies: + pug-code-gen "^2.0.0" + pug-filters "^2.1.5" + pug-lexer "^3.1.0" + pug-linker "^3.0.3" + pug-load "^2.0.9" + pug-parser "^4.0.0" + pug-runtime "^2.0.3" + pug-strip-comments "^1.0.2" + punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -2572,7 +2909,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: +readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -2659,6 +2996,33 @@ request-promise-native@^1.0.3: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" +request@2, request@^2.45.0, request@^2.83.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + request@2.77.0: version "2.77.0" resolved "https://registry.yarnpkg.com/request/-/request-2.77.0.tgz#2b00d82030ededcc97089ffa5d8810a9c2aa314b" @@ -2711,32 +3075,30 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@^2.45.0, request@^2.83.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" +request@~2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" combined-stream "~1.0.5" - extend "~3.0.1" + extend "~3.0.0" forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" require-directory@^2.1.1: version "2.1.1" @@ -2894,14 +3256,38 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +sass-graph@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sax@0.5.x: + version "0.5.8" + resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" + sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -2966,7 +3352,13 @@ source-map-support@^0.4.0, source-map-support@^0.4.8: dependencies: source-map "^0.5.6" -source-map@^0.4.4: +source-map@0.1.x: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@0.4.x, source-map@^0.4.2, source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: @@ -3029,6 +3421,12 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" +stdout-stream@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" + dependencies: + readable-stream "^2.0.1" + stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -3098,6 +3496,17 @@ strip-json-comments@^2.0.0, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +stylus@^0.54.5: + version "0.54.5" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" + dependencies: + css-parse "1.7.x" + debug "*" + glob "7.0.x" + mkdirp "0.5.x" + sax "0.5.x" + source-map "0.1.x" + sumchecker@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d" @@ -3155,7 +3564,7 @@ tar-pack@^3.4.0: tar "^2.2.1" uid-number "^0.0.6" -tar@^2.2.1: +tar@^2.0.0, tar@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" dependencies: @@ -3213,6 +3622,10 @@ to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" +token-stream@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" + tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" @@ -3233,6 +3646,12 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +"true-case-path@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" + dependencies: + glob "^6.0.4" + tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" @@ -3295,7 +3714,7 @@ typescript@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.1.tgz#ef39cdea27abac0b500242d6726ab90e0c846631" -uglify-js@^2.6: +uglify-js@^2.6, uglify-js@^2.6.1: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: @@ -3349,6 +3768,10 @@ vlq@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" +void-elements@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" + webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -3367,11 +3790,15 @@ whatwg-url@^6.3.0: tr46 "^1.0.0" webidl-conversions "^4.0.1" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@^1.2.4, which@^1.2.9: +which@1, which@^1.2.4, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -3387,6 +3814,13 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +with@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe" + dependencies: + acorn "^3.1.0" + acorn-globals "^3.0.0" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -3450,6 +3884,12 @@ yallist@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + dependencies: + camelcase "^3.0.0" + yargs-parser@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" @@ -3473,6 +3913,24 @@ yargs@^10.0.3: y18n "^3.2.1" yargs-parser "^8.0.0" +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" From 0469de3418a4990c848bcc6f988943a8b99d3bc2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 22:56:57 -0500 Subject: [PATCH 32/43] remove redundant try-catch --- src/index.ts | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/index.ts b/src/index.ts index a6b1ccc32e..a2664c9293 100644 --- a/src/index.ts +++ b/src/index.ts @@ -69,28 +69,16 @@ async function _doPreprocess(source, type: 'script' | 'style', preprocessor: Pre export async function preprocess(source: string, options: PreprocessOptions) { const { markup, style, script } = options; if (!!markup) { - try { - const processed: { code: string, map?: SourceMap | string } = await markup({ content: source }); - source = processed.code; - } catch (error) { - defaultOnerror(error); - } + const processed: { code: string, map?: SourceMap | string } = await markup({ content: source }); + source = processed.code; } if (!!style) { - try { - source = await _doPreprocess(source, 'style', style); - } catch (error) { - defaultOnerror(error); - } + source = await _doPreprocess(source, 'style', style); } if (!!script) { - try { - source = await _doPreprocess(source, 'script', script); - } catch (error) { - defaultOnerror(error); - } + source = await _doPreprocess(source, 'script', script); } return { From 3b244abb4473463d25209ee02420073427a0cb64 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 22:59:07 -0500 Subject: [PATCH 33/43] remove unused preprocessor option --- src/index.ts | 2 +- src/interfaces.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index a2664c9293..1ed88e1d65 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,7 +10,7 @@ import { SourceMap } from 'magic-string'; const version = '__VERSION__'; function normalizeOptions(options: CompileOptions): CompileOptions { - let normalizedOptions = assign({ generate: 'dom', preprocessor: false }, options); + let normalizedOptions = assign({ generate: 'dom' }, options); const { onwarn, onerror } = normalizedOptions; normalizedOptions.onwarn = onwarn ? (warning: Warning) => onwarn(warning, defaultOnwarn) diff --git a/src/interfaces.ts b/src/interfaces.ts index bcfb24f568..0d884f8472 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -62,7 +62,6 @@ export interface CompileOptions { onerror?: (error: Error) => void; onwarn?: (warning: Warning) => void; - preprocessor?: ((raw: string) => string) | false ; } export interface GenerateOptions { From 31e0d3f3b1a1eedbd597733eb243ade7225ec15e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:06:06 -0500 Subject: [PATCH 34/43] rename functions --- src/index.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1ed88e1d65..681df56fda 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,7 +35,7 @@ function defaultOnerror(error: Error) { throw error; } -function _parseAttributeValue(value: string | boolean) { +function parseAttributeValue(value: string | boolean) { const curated = (value).replace(/"/ig, ''); if (curated === 'true' || curated === 'false') { return curated === 'true'; @@ -43,26 +43,26 @@ function _parseAttributeValue(value: string | boolean) { return curated; } -function _parseStyleAttributes(str: string) { +function parseAttributes(str: string) { const attrs = {}; str.split(/\s+/).filter(Boolean).forEach(attr => { const [name, value] = attr.split('='); - attrs[name] = _parseAttributeValue(value); + attrs[name] = parseAttributeValue(value); }); return attrs; } -async function _doPreprocess(source, type: 'script' | 'style', preprocessor: Preprocessor) { +async function replaceTagContents(source, type: 'script' | 'style', preprocessor: Preprocessor) { const exp = new RegExp(`<${type}([\\S\\s]*?)>([\\S\\s]*?)<\\/${type}>`, 'ig'); const match = exp.exec(source); if (match) { - const attributes: Record = _parseStyleAttributes(match[1]); + const attributes: Record = parseAttributes(match[1]); const content: string = match[2]; const processed: { code: string, map?: SourceMap | string } = await preprocessor({ content, attributes }); - return source.replace(content, processed.code || content); + return source.slice(0, match.index) + (processed.code || content) + source.slice(0, match.index + match[0].length); } } @@ -74,11 +74,11 @@ export async function preprocess(source: string, options: PreprocessOptions) { } if (!!style) { - source = await _doPreprocess(source, 'style', style); + source = await replaceTagContents(source, 'style', style); } if (!!script) { - source = await _doPreprocess(source, 'script', script); + source = await replaceTagContents(source, 'script', script); } return { From 892028729d07d62f7aa03359cf9b096c74fc806c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:08:56 -0500 Subject: [PATCH 35/43] always return something --- src/index.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 681df56fda..1ce6595062 100644 --- a/src/index.ts +++ b/src/index.ts @@ -55,6 +55,7 @@ function parseAttributes(str: string) { async function replaceTagContents(source, type: 'script' | 'style', preprocessor: Preprocessor) { const exp = new RegExp(`<${type}([\\S\\s]*?)>([\\S\\s]*?)<\\/${type}>`, 'ig'); const match = exp.exec(source); + if (match) { const attributes: Record = parseAttributes(match[1]); const content: string = match[2]; @@ -62,8 +63,17 @@ async function replaceTagContents(source, type: 'script' | 'style', preprocessor content, attributes }); - return source.slice(0, match.index) + (processed.code || content) + source.slice(0, match.index + match[0].length); + + if (processed && processed.code) { + return ( + source.slice(0, match.index) + + processed.code + + source.slice(0, match.index + match[0].length) + ); + } } + + return source; } export async function preprocess(source: string, options: PreprocessOptions) { From 4f05a22cb334691b03b6505878a20667fad139ca Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:20:43 -0500 Subject: [PATCH 36/43] return promise, so that test results are correct --- test/preprocess/index.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/preprocess/index.js b/test/preprocess/index.js index 209e81070b..4f59e4fe6b 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.js @@ -31,7 +31,7 @@ function checkCodeIsValid(code) { } } -describe('preprocess', () => { +describe.only('preprocess', () => { fs.readdirSync('test/preprocess/samples').forEach(dir => { if (dir[0] === '.') return; @@ -51,9 +51,9 @@ describe('preprocess', () => { fs.readFileSync(`test/preprocess/samples/${dir}/input.html`, 'utf-8').replace(/\s+$/, ''); - svelte.preprocess(input, config). - then(processed => processed.toString()). - then(processed => { + return svelte.preprocess(input, config) + .then(processed => processed.toString()) + .then(processed => { const expectedWarnings = (config.warnings || []).map( normalizeWarning); @@ -153,8 +153,6 @@ describe('preprocess', () => { throw err; } } - }).catch(error => { - throw error; }); }); }); From d3c254f197ccb39f3412fce7e371611d433d9719 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:33:00 -0500 Subject: [PATCH 37/43] fix output --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 1ce6595062..ad1b6e255d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -67,8 +67,8 @@ async function replaceTagContents(source, type: 'script' | 'style', preprocessor if (processed && processed.code) { return ( source.slice(0, match.index) + - processed.code + - source.slice(0, match.index + match[0].length) + `<${type}>\n${processed.code}` + + source.slice(match.index + match[0].length) ); } } From 9dc02f1748850bac803ed29f5add7d339aeadbe0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:33:32 -0500 Subject: [PATCH 38/43] use helper --- test/preprocess/index.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/preprocess/index.js b/test/preprocess/index.js index 4f59e4fe6b..d01963a26f 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.js @@ -46,15 +46,12 @@ describe.only('preprocess', () => { (solo ? it.only : skip ? it.skip : it)(dir, () => { const config = tryRequire(`./samples/${dir}/_config.js`) || {}; const input = fs.existsSync(`test/preprocess/samples/${dir}/input.pug`) ? - fs.readFileSync(`test/preprocess/samples/${dir}/input.pug`, - 'utf-8').replace(/\s+$/, '') : - fs.readFileSync(`test/preprocess/samples/${dir}/input.html`, - 'utf-8').replace(/\s+$/, ''); + read(`test/preprocess/samples/${dir}/input.pug`) : + read(`test/preprocess/samples/${dir}/input.html`); return svelte.preprocess(input, config) .then(processed => processed.toString()) .then(processed => { - const expectedWarnings = (config.warnings || []).map( normalizeWarning); const domWarnings = []; From ab7550c4e2666a9eb665389e49fc45a14e5ec55c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:48:34 -0500 Subject: [PATCH 39/43] more direct tests --- src/index.ts | 2 +- test/preprocess/index.js | 299 +++++++++--------- .../use-coffeescript-preprocessor/_config.js | 13 +- .../samples/use-pug-preprocessor/_config.js | 11 +- .../samples/use-scss-preprocessor/_config.js | 2 +- 5 files changed, 150 insertions(+), 177 deletions(-) diff --git a/src/index.ts b/src/index.ts index ad1b6e255d..e4353fdff7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -67,7 +67,7 @@ async function replaceTagContents(source, type: 'script' | 'style', preprocessor if (processed && processed.code) { return ( source.slice(0, match.index) + - `<${type}>\n${processed.code}` + + `<${type}>${processed.code}` + source.slice(match.index + match[0].length) ); } diff --git a/test/preprocess/index.js b/test/preprocess/index.js index d01963a26f..ea1a519655 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.js @@ -1,164 +1,147 @@ import assert from 'assert'; -import * as fs from 'fs'; -import {parse} from 'acorn'; -import {addLineNumbers, env, normalizeHtml, svelte} from '../helpers.js'; - -function tryRequire(file) { - try { - const mod = require(file); - return mod.default || mod; - } catch (err) { - if (err.code !== 'MODULE_NOT_FOUND') throw err; - return null; - } -} - -function normalizeWarning(warning) { - warning.frame = warning.frame.replace(/^\n/, ''). - replace(/^\t+/gm, ''). - replace(/\s+$/gm, ''); - delete warning.filename; - delete warning.toString; - return warning; -} - -function checkCodeIsValid(code) { - try { - parse(code); - } catch (err) { - console.error(addLineNumbers(code)); - throw new Error(err.message); - } -} +import {svelte} from '../helpers.js'; describe.only('preprocess', () => { - fs.readdirSync('test/preprocess/samples').forEach(dir => { - if (dir[0] === '.') return; - - // add .solo to a sample directory name to only run that test - const solo = /\.solo/.test(dir); - const skip = /\.skip/.test(dir); - - if (solo && process.env.CI) { - throw new Error('Forgot to remove `solo: true` from test'); - } - - (solo ? it.only : skip ? it.skip : it)(dir, () => { - const config = tryRequire(`./samples/${dir}/_config.js`) || {}; - const input = fs.existsSync(`test/preprocess/samples/${dir}/input.pug`) ? - read(`test/preprocess/samples/${dir}/input.pug`) : - read(`test/preprocess/samples/${dir}/input.html`); - - return svelte.preprocess(input, config) - .then(processed => processed.toString()) - .then(processed => { - const expectedWarnings = (config.warnings || []).map( - normalizeWarning); - const domWarnings = []; - const ssrWarnings = []; - - const dom = svelte.compile( - processed, - Object.assign(config, { - format: 'iife', - name: 'SvelteComponent', - onwarn: warning => { - domWarnings.push(warning); - }, - }) - ); - - const ssr = svelte.compile( - processed, - Object.assign(config, { - format: 'iife', - generate: 'ssr', - name: 'SvelteComponent', - onwarn: warning => { - ssrWarnings.push(warning); - }, - }) - ); - - // check the code is valid - checkCodeIsValid(dom.code); - checkCodeIsValid(ssr.code); - - assert.equal(dom.css, ssr.css); - - assert.deepEqual( - domWarnings.map(normalizeWarning), - ssrWarnings.map(normalizeWarning) - ); - assert.deepEqual(domWarnings.map(normalizeWarning), expectedWarnings); - - const expected = { - html: read(`test/preprocess/samples/${dir}/expected.html`), - css: read(`test/preprocess/samples/${dir}/expected.css`), - }; - - if (expected.css !== null) { - fs.writeFileSync(`test/preprocess/samples/${dir}/_actual.css`, - dom.css); - assert.equal(dom.css.replace(/svelte-\d+/g, 'svelte-xyz'), - expected.css); - } - - // verify that the right elements have scoping selectors - if (expected.html !== null) { - const window = env(); - - // dom - try { - const Component = eval( - `(function () { ${dom.code}; return SvelteComponent; }())` - ); - const target = window.document.querySelector('main'); - - new Component({target, data: config.data}); - const html = target.innerHTML; - - fs.writeFileSync(`test/preprocess/samples/${dir}/_actual.html`, - html); - - assert.equal( - normalizeHtml(window, - html.replace(/svelte-\d+/g, 'svelte-xyz')), - normalizeHtml(window, expected.html) - ); - } catch (err) { - console.log(dom.code); - throw err; - } - - // ssr - try { - const component = eval( - `(function () { ${ssr.code}; return SvelteComponent; }())` - ); - - assert.equal( - normalizeHtml( - window, - component.render(config.data). - replace(/svelte-\d+/g, 'svelte-xyz') - ), - normalizeHtml(window, expected.html) - ); - } catch (err) { - console.log(ssr.code); - throw err; - } - } + it('preprocesses entire component', () => { + const source = ` +

Hello __NAME__!

+ `; + + const expected = ` +

Hello world!

+ `; + + return svelte.preprocess(source, { + markup: ({ content }) => { + return { + code: content.replace('__NAME__', 'world') + }; + } + }).then(processed => { + assert.equal(processed.toString(), expected); + }); + }); + + it('preprocesses style', () => { + const source = ` +
$brand
+ + + `; + + const expected = ` +
$brand
+ + + `; + + return svelte.preprocess(source, { + style: ({ content }) => { + return { + code: content.replace('$brand', 'purple') + }; + } + }).then(processed => { + assert.equal(processed.toString(), expected); + }); + }); + + it('preprocesses style asynchronously', () => { + const source = ` +
$brand
+ + + `; + + const expected = ` +
$brand
+ + + `; + + return svelte.preprocess(source, { + style: ({ content }) => { + return Promise.resolve({ + code: content.replace('$brand', 'purple') }); + } + }).then(processed => { + assert.equal(processed.toString(), expected); + }); + }); + + it('preprocesses script', () => { + const source = ` + + `; + + const expected = ` + + `; + + return svelte.preprocess(source, { + script: ({ content }) => { + return { + code: content.replace('__THE_ANSWER__', '42') + }; + } + }).then(processed => { + assert.equal(processed.toString(), expected); + }); + }); + + it('parses attributes', () => { + const source = ` + + `; + + return svelte.preprocess(source, { + style: ({ attributes }) => { + assert.deepEqual(attributes, { + type: 'text/scss', + bool: true + }); + } + }); + }); + + it('ignores null/undefined returned from preprocessor', () => { + const source = ` + + `; + + const expected = ` + + `; + + return svelte.preprocess(source, { + script: () => null + }).then(processed => { + assert.equal(processed.toString(), expected); }); }); -}); - -function read(file) { - try { - return fs.readFileSync(file, 'utf-8'); - } catch (err) { - return null; - } -} +}); \ No newline at end of file diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/_config.js b/test/preprocess/samples/use-coffeescript-preprocessor/_config.js index 1865fe4086..1fc6c44c64 100644 --- a/test/preprocess/samples/use-coffeescript-preprocessor/_config.js +++ b/test/preprocess/samples/use-coffeescript-preprocessor/_config.js @@ -4,16 +4,11 @@ export default { cascade: false, script: ({content, attributes}) => { if (attributes.type !== 'text/coffeescript') { - return {code: content}; + return null; } - return new Promise((fulfil, reject) => { - try { - const code = CoffeeScript.compile(content, {}); - fulfil({code}); - } catch (error) { - reject(error); - } - }); + return { + code: CoffeeScript.compile(content, {}) + }; }, }; diff --git a/test/preprocess/samples/use-pug-preprocessor/_config.js b/test/preprocess/samples/use-pug-preprocessor/_config.js index 7a345bfd91..99ac56ff7e 100644 --- a/test/preprocess/samples/use-pug-preprocessor/_config.js +++ b/test/preprocess/samples/use-pug-preprocessor/_config.js @@ -3,13 +3,8 @@ import * as pug from 'pug'; export default { cascade: false, markup: ({content}) => { - return new Promise((fulfil, reject) => { - try { - const code = pug.render(content); - fulfil({code}); - } catch (error) { - reject(error); - } - }); + return { + code: pug.render(content) + }; }, }; diff --git a/test/preprocess/samples/use-scss-preprocessor/_config.js b/test/preprocess/samples/use-scss-preprocessor/_config.js index cb3a1a505a..0aedea4659 100644 --- a/test/preprocess/samples/use-scss-preprocessor/_config.js +++ b/test/preprocess/samples/use-scss-preprocessor/_config.js @@ -4,7 +4,7 @@ export default { cascade: false, style: ({ content, attributes }) => { if (attributes.type !== 'text/scss') { - return {code: content}; + return null; } if (attributes['aria-hidden'] !== true) { From b5a87551028abf20f2f06935016187ff418eea0d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:50:06 -0500 Subject: [PATCH 40/43] remove tests of coffeescript etc --- package.json | 4 - .../use-coffeescript-preprocessor/_config.js | 14 - .../expected.html | 1 - .../use-coffeescript-preprocessor/input.html | 8 - .../samples/use-pug-preprocessor/_config.js | 10 - .../samples/use-pug-preprocessor/expected.css | 1 - .../samples/use-pug-preprocessor/input.pug | 10 - .../_config.js | 26 - .../_variables.scss | 2 - .../expected.css | 1 - .../input.html | 13 - .../samples/use-scss-preprocessor/_config.js | 26 - .../use-scss-preprocessor/expected.css | 1 - .../samples/use-scss-preprocessor/input.html | 14 - .../_config.js | 24 - .../expected.css | 1 - .../input.html | 12 - .../variables.styl | 2 - .../use-stylus-preprocessor/_config.js | 20 - .../use-stylus-preprocessor/expected.css | 1 - .../use-stylus-preprocessor/input.html | 13 - yarn.lock | 520 ++---------------- 22 files changed, 51 insertions(+), 673 deletions(-) delete mode 100644 test/preprocess/samples/use-coffeescript-preprocessor/_config.js delete mode 100644 test/preprocess/samples/use-coffeescript-preprocessor/expected.html delete mode 100644 test/preprocess/samples/use-coffeescript-preprocessor/input.html delete mode 100644 test/preprocess/samples/use-pug-preprocessor/_config.js delete mode 100644 test/preprocess/samples/use-pug-preprocessor/expected.css delete mode 100644 test/preprocess/samples/use-pug-preprocessor/input.pug delete mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js delete mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss delete mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css delete mode 100644 test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html delete mode 100644 test/preprocess/samples/use-scss-preprocessor/_config.js delete mode 100644 test/preprocess/samples/use-scss-preprocessor/expected.css delete mode 100644 test/preprocess/samples/use-scss-preprocessor/input.html delete mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js delete mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css delete mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html delete mode 100644 test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl delete mode 100644 test/preprocess/samples/use-stylus-preprocessor/_config.js delete mode 100644 test/preprocess/samples/use-stylus-preprocessor/expected.css delete mode 100644 test/preprocess/samples/use-stylus-preprocessor/input.html diff --git a/package.json b/package.json index 6e3f0f9304..41f998d238 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "acorn": "^5.1.1", "chalk": "^2.0.1", "codecov": "^2.2.0", - "coffeescript": "^2.0.2", "console-group": "^0.3.2", "css-tree": "1.0.0-alpha22", "eslint": "^4.3.0", @@ -56,16 +55,13 @@ "estree-walker": "^0.5.1", "glob": "^7.1.1", "jsdom": "^11.1.0", - "less": "^2.7.3", "locate-character": "^2.0.0", "magic-string": "^0.22.3", "mocha": "^3.2.0", "nightmare": "^2.10.0", "node-resolve": "^1.3.3", - "node-sass": "^4.7.1", "nyc": "^11.1.0", "prettier": "^1.7.0", - "pug": "^2.0.0-rc.4", "reify": "^0.12.3", "rollup": "^0.48.2", "rollup-plugin-buble": "^0.15.0", diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/_config.js b/test/preprocess/samples/use-coffeescript-preprocessor/_config.js deleted file mode 100644 index 1fc6c44c64..0000000000 --- a/test/preprocess/samples/use-coffeescript-preprocessor/_config.js +++ /dev/null @@ -1,14 +0,0 @@ -import * as CoffeeScript from 'coffeescript'; - -export default { - cascade: false, - script: ({content, attributes}) => { - if (attributes.type !== 'text/coffeescript') { - return null; - } - - return { - code: CoffeeScript.compile(content, {}) - }; - }, -}; diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/expected.html b/test/preprocess/samples/use-coffeescript-preprocessor/expected.html deleted file mode 100644 index 2c473ea019..0000000000 --- a/test/preprocess/samples/use-coffeescript-preprocessor/expected.html +++ /dev/null @@ -1 +0,0 @@ -

Hello foo!

diff --git a/test/preprocess/samples/use-coffeescript-preprocessor/input.html b/test/preprocess/samples/use-coffeescript-preprocessor/input.html deleted file mode 100644 index 50c7f64347..0000000000 --- a/test/preprocess/samples/use-coffeescript-preprocessor/input.html +++ /dev/null @@ -1,8 +0,0 @@ -

Hello {{name}}!

- - \ No newline at end of file diff --git a/test/preprocess/samples/use-pug-preprocessor/_config.js b/test/preprocess/samples/use-pug-preprocessor/_config.js deleted file mode 100644 index 99ac56ff7e..0000000000 --- a/test/preprocess/samples/use-pug-preprocessor/_config.js +++ /dev/null @@ -1,10 +0,0 @@ -import * as pug from 'pug'; - -export default { - cascade: false, - markup: ({content}) => { - return { - code: pug.render(content) - }; - }, -}; diff --git a/test/preprocess/samples/use-pug-preprocessor/expected.css b/test/preprocess/samples/use-pug-preprocessor/expected.css deleted file mode 100644 index 2217e804d9..0000000000 --- a/test/preprocess/samples/use-pug-preprocessor/expected.css +++ /dev/null @@ -1 +0,0 @@ -[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue} \ No newline at end of file diff --git a/test/preprocess/samples/use-pug-preprocessor/input.pug b/test/preprocess/samples/use-pug-preprocessor/input.pug deleted file mode 100644 index d32e76527d..0000000000 --- a/test/preprocess/samples/use-pug-preprocessor/input.pug +++ /dev/null @@ -1,10 +0,0 @@ -div(foo="bar") -div(baz) - -style(type="text/css") - |[foo] { - | color: red; - | } - |[baz] { - | color: blue; - |} diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js b/test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js deleted file mode 100644 index 6daae7c7a3..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor-with-external-files/_config.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as sass from 'node-sass'; -import * as path from 'path'; - -export default { - cascade: false, - style: ({ content, attributes }) => { - if (attributes.type !== 'text/scss') { - return {code: content}; - } - - return new Promise((fulfil, reject) => { - sass.render({ - data: content, - includePaths: [ - path.resolve(__dirname) - ] - }, (err, result) => { - if (err) { - reject(err); - } else { - fulfil({ code: result.css.toString(), map: result.map }); - } - }); - }); - } -}; diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss b/test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss deleted file mode 100644 index be7eddc5a4..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor-with-external-files/_variables.scss +++ /dev/null @@ -1,2 +0,0 @@ -$foo-color: red; -$baz-color: blue; diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css b/test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css deleted file mode 100644 index 2217e804d9..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor-with-external-files/expected.css +++ /dev/null @@ -1 +0,0 @@ -[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue} \ No newline at end of file diff --git a/test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html b/test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html deleted file mode 100644 index 2db43e1c6f..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor-with-external-files/input.html +++ /dev/null @@ -1,13 +0,0 @@ -
-
- - diff --git a/test/preprocess/samples/use-scss-preprocessor/_config.js b/test/preprocess/samples/use-scss-preprocessor/_config.js deleted file mode 100644 index 0aedea4659..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor/_config.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as sass from 'node-sass'; - -export default { - cascade: false, - style: ({ content, attributes }) => { - if (attributes.type !== 'text/scss') { - return null; - } - - if (attributes['aria-hidden'] !== true) { - throw new Error('aria-hidden is supposed to be true'); - } - - return new Promise((fulfil, reject) => { - sass.render({ - data: content, - }, (err, result) => { - if (err) { - reject(err); - } else { - fulfil({ code: result.css.toString(), map: result.map }); - } - }); - }); - } -}; diff --git a/test/preprocess/samples/use-scss-preprocessor/expected.css b/test/preprocess/samples/use-scss-preprocessor/expected.css deleted file mode 100644 index 2217e804d9..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor/expected.css +++ /dev/null @@ -1 +0,0 @@ -[foo][svelte-xyz]{color:red}[baz][svelte-xyz]{color:blue} \ No newline at end of file diff --git a/test/preprocess/samples/use-scss-preprocessor/input.html b/test/preprocess/samples/use-scss-preprocessor/input.html deleted file mode 100644 index 4e6384ebdc..0000000000 --- a/test/preprocess/samples/use-scss-preprocessor/input.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
- - diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js deleted file mode 100644 index 3806a407f2..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/_config.js +++ /dev/null @@ -1,24 +0,0 @@ -import * as stylus from 'stylus'; -import * as path from 'path'; - -export default { - preprocessor: (styles) => - stylus(styles).include(path.resolve(__dirname)).render(), - cascade: false, - style: ({content, attributes}) => { - if (attributes.type !== 'text/stylus') { - return {code: content}; - } - - return new Promise((fulfil, reject) => { - stylus(content).include(path.resolve(__dirname)). - render((err, result) => { - if (err) { - reject(err); - } else { - fulfil({code: result}); - } - }); - }); - }, -}; diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css deleted file mode 100644 index 8bfade2024..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/expected.css +++ /dev/null @@ -1 +0,0 @@ -[foo][svelte-xyz]{color:#f00}[baz][svelte-xyz]{color:#00f} \ No newline at end of file diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html deleted file mode 100644 index 2dffa65b3b..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/input.html +++ /dev/null @@ -1,12 +0,0 @@ -
-
- - diff --git a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl b/test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl deleted file mode 100644 index d9ff4b9275..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor-with-external-file/variables.styl +++ /dev/null @@ -1,2 +0,0 @@ -foo-color = red -baz-color = blue diff --git a/test/preprocess/samples/use-stylus-preprocessor/_config.js b/test/preprocess/samples/use-stylus-preprocessor/_config.js deleted file mode 100644 index 8e92e4ad60..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor/_config.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as stylus from 'stylus'; - -export default { - cascade: false, - style: ({content, attributes}) => { - if (attributes.type !== 'text/stylus') { - return {code: content}; - } - - return new Promise((fulfil, reject) => { - stylus(content).render((err, result) => { - if (err) { - reject(err); - } else { - fulfil({code: result}); - } - }); - }); - }, -}; diff --git a/test/preprocess/samples/use-stylus-preprocessor/expected.css b/test/preprocess/samples/use-stylus-preprocessor/expected.css deleted file mode 100644 index 8bfade2024..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor/expected.css +++ /dev/null @@ -1 +0,0 @@ -[foo][svelte-xyz]{color:#f00}[baz][svelte-xyz]{color:#00f} \ No newline at end of file diff --git a/test/preprocess/samples/use-stylus-preprocessor/input.html b/test/preprocess/samples/use-stylus-preprocessor/input.html deleted file mode 100644 index 259c0d45ed..0000000000 --- a/test/preprocess/samples/use-stylus-preprocessor/input.html +++ /dev/null @@ -1,13 +0,0 @@ -
-
- - diff --git a/yarn.lock b/yarn.lock index 0e3f324f0c..e819c49ef0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,12 +22,6 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" -acorn-globals@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" - dependencies: - acorn "^4.0.4" - acorn-globals@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" @@ -46,14 +40,10 @@ acorn-object-spread@^1.0.0: dependencies: acorn "^3.1.0" -acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0, acorn@~3.3.0: +acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.4, acorn@~4.0.2: - version "4.0.13" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" - acorn@^5.0.0, acorn@^5.1.1, acorn@^5.1.2, acorn@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" @@ -74,8 +64,8 @@ ajv@^4.9.1: json-stable-stringify "^1.0.1" ajv@^5.1.0, ajv@^5.2.3, ajv@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9" + version "5.5.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -190,10 +180,6 @@ arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" @@ -210,10 +196,6 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -async-foreach@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - async@^1.4.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -421,10 +403,6 @@ camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -462,12 +440,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" -character-parser@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" - dependencies: - is-regex "^1.0.3" - chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -491,13 +463,6 @@ circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" -clean-css@^3.3.0: - version "3.4.28" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" - dependencies: - commander "2.8.x" - source-map "0.4.x" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -544,10 +509,6 @@ codecov@^2.2.0: request "2.77.0" urlgrey "0.4.4" -coffeescript@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.0.3.tgz#760f02724f5f0911be7cefa34a8e0e10c5d8512a" - color-convert@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" @@ -570,12 +531,6 @@ commander@1.0.4: dependencies: keypress "0.1.x" -commander@2.8.x: - version "2.8.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" - dependencies: - graceful-readlink ">= 1.0.0" - commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -583,8 +538,8 @@ commander@2.9.0: graceful-readlink ">= 1.0.0" commander@^2.9.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.1.tgz#468635c4168d06145b9323356d1da84d14ac4a7a" + version "2.12.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" commondir@^1.0.1: version "1.0.1" @@ -614,13 +569,6 @@ console-group@^0.3.2: version "0.3.3" resolved "https://registry.yarnpkg.com/console-group/-/console-group-0.3.3.tgz#6d8eb6b9d6b757a2895284f62d09c7ad43f2bbce" -constantinople@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.0.tgz#7569caa8aa3f8d5935d62e1fa96f9f702cd81c79" - dependencies: - acorn "^3.1.0" - is-expression "^2.0.1" - contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" @@ -641,13 +589,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -cross-spawn@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - cross-spawn@^4: version "4.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" @@ -811,10 +752,6 @@ doctrine@^2.0.2: dependencies: esutils "^2.0.2" -doctypes@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" - dom-serializer@0: version "0.1.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" @@ -885,12 +822,6 @@ entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -errno@^0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" - dependencies: - prr "~0.0.0" - error-ex@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" @@ -960,8 +891,8 @@ eslint-scope@^3.7.1: estraverse "^4.1.1" eslint@^4.3.0: - version "4.12.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.0.tgz#a7ce78eba8cc8f2443acfbbc870cc31a65135884" + version "4.12.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.12.1.tgz#5ec1973822b4a066b353770c3c6d69a2a188e880" dependencies: ajv "^5.3.0" babel-code-frame "^6.22.0" @@ -1100,10 +1031,14 @@ extract-zip@^1.0.3: mkdirp "0.5.0" yauzl "2.4.1" -extsprintf@1.3.0, extsprintf@^1.2.0: +extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" @@ -1279,12 +1214,6 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -gaze@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" - dependencies: - globule "^1.0.0" - generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" @@ -1348,17 +1277,7 @@ glob@7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1: +glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -1388,14 +1307,6 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globule@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" - dependencies: - glob "~7.1.1" - lodash "~4.17.4" - minimatch "~3.0.2" - graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -1558,18 +1469,10 @@ ignore@^3.3.3: version "3.3.7" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.7.tgz#612289bfb3c220e186a58118618d5be8c1bab021" -image-size@~0.5.0: - version "0.5.5" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -in-publish@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" - indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -1650,20 +1553,6 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" -is-expression@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-2.1.0.tgz#91be9d47debcfef077977e9722be6dcfb4465ef0" - dependencies: - acorn "~3.3.0" - object-assign "^4.0.1" - -is-expression@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f" - dependencies: - acorn "~4.0.2" - object-assign "^4.0.1" - is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -1730,8 +1619,8 @@ is-path-in-cwd@^1.0.0: is-path-inside "^1.0.0" is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" dependencies: path-is-inside "^1.0.1" @@ -1743,7 +1632,7 @@ is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" -is-promise@^2.0.0, is-promise@^2.1.0: +is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -1751,12 +1640,6 @@ is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" -is-regex@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - dependencies: - has "^1.0.1" - is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" @@ -1844,14 +1727,6 @@ istanbul-reports@^1.1.3: dependencies: handlebars "^4.0.3" -js-base64@^2.1.8: - version "2.3.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf" - -js-stringify@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" - js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -1953,13 +1828,6 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.10.0" -jstransformer@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" - dependencies: - is-promise "^2.0.0" - promise "^7.0.1" - keypress@0.1.x: version "0.1.0" resolved "https://registry.yarnpkg.com/keypress/-/keypress-0.1.0.tgz#4a3188d4291b66b4f65edb99f806aa9ae293592a" @@ -1996,19 +1864,6 @@ left-pad@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" -less@^2.7.3: - version "2.7.3" - resolved "https://registry.yarnpkg.com/less/-/less-2.7.3.tgz#cc1260f51c900a9ec0d91fb6998139e02507b63b" - optionalDependencies: - errno "^0.1.1" - graceful-fs "^4.1.2" - image-size "~0.5.0" - mime "^1.2.11" - mkdirp "^0.5.0" - promise "^7.1.1" - request "2.81.0" - source-map "^0.5.3" - levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2036,8 +1891,8 @@ load-json-file@^2.0.0: strip-bom "^3.0.0" locate-character@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-2.0.1.tgz#48f9599f342daf26f73db32f45941eae37bae391" + version "2.0.3" + resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-2.0.3.tgz#85a5aedae26b3536c3e97016af164cdaa3ae5ae1" locate-path@^2.0.0: version "2.0.0" @@ -2069,14 +1924,6 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" -lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - -lodash.clonedeep@^4.3.2: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" @@ -2105,10 +1952,6 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash.mergewith@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -2117,7 +1960,7 @@ lodash@3.0.x: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.0.1.tgz#14d49028a38bc740241d11e2ecd57ec06d73c19a" -lodash@^4.0.0, lodash@^4.13.1, lodash@^4.17.4, lodash@^4.3.0, lodash@~4.17.4: +lodash@^4.13.1, lodash@^4.17.4, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -2185,7 +2028,7 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" -meow@^3.1.0, meow@^3.7.0: +meow@^3.1.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: @@ -2234,15 +2077,11 @@ mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: dependencies: mime-db "~1.30.0" -mime@^1.2.11: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -2315,7 +2154,7 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.3.0, nan@^2.3.2: +nan@^2.3.0: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" @@ -2341,24 +2180,6 @@ nightmare@^2.10.0: sliced "1.0.1" split2 "^2.0.1" -node-gyp@^3.3.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.6.2.tgz#9bfbe54562286284838e750eac05295853fa1c60" - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - minimatch "^3.0.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3 || 4" - osenv "0" - request "2" - rimraf "2" - semver "~5.3.0" - tar "^2.0.0" - which "1" - node-pre-gyp@^0.6.39: version "0.6.39" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" @@ -2382,40 +2203,10 @@ node-resolve@^1.3.3: is-builtin-module "^1.0.0" lodash "^4.13.1" -node-sass@^4.7.1: - version "4.7.2" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e" - dependencies: - async-foreach "^0.1.3" - chalk "^1.1.1" - cross-spawn "^3.0.0" - gaze "^1.0.0" - get-stdin "^4.0.1" - glob "^7.0.3" - in-publish "^2.0.0" - lodash.assign "^4.2.0" - lodash.clonedeep "^4.3.2" - lodash.mergewith "^4.6.0" - meow "^3.7.0" - mkdirp "^0.5.1" - nan "^2.3.2" - node-gyp "^3.3.1" - npmlog "^4.0.0" - request "~2.79.0" - sass-graph "^2.2.4" - stdout-stream "^1.4.0" - "true-case-path" "^1.0.2" - node-uuid@~1.4.7: version "1.4.8" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" -"nopt@2 || 3": - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -2444,7 +2235,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: +npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -2558,12 +2349,6 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - dependencies: - lcid "^1.0.0" - os-locale@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" @@ -2576,7 +2361,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@0, osenv@^0.1.4: +osenv@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" dependencies: @@ -2736,113 +2521,10 @@ progress@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" -promise@^7.0.1, promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - dependencies: - asap "~2.0.3" - -prr@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" - pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" -pug-attrs@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.2.tgz#8be2b2225568ffa75d1b866982bff9f4111affcb" - dependencies: - constantinople "^3.0.1" - js-stringify "^1.0.1" - pug-runtime "^2.0.3" - -pug-code-gen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.0.tgz#96aea39a9e62f1ec5d2b6a5b42a29d528c70b43d" - dependencies: - constantinople "^3.0.1" - doctypes "^1.1.0" - js-stringify "^1.0.1" - pug-attrs "^2.0.2" - pug-error "^1.3.2" - pug-runtime "^2.0.3" - void-elements "^2.0.1" - with "^5.0.0" - -pug-error@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.2.tgz#53ae7d9d29bb03cf564493a026109f54c47f5f26" - -pug-filters@^2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-2.1.5.tgz#66bf6e80d97fbef829bab0aa35eddff33fc964f3" - dependencies: - clean-css "^3.3.0" - constantinople "^3.0.1" - jstransformer "1.0.0" - pug-error "^1.3.2" - pug-walk "^1.1.5" - resolve "^1.1.6" - uglify-js "^2.6.1" - -pug-lexer@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-3.1.0.tgz#fd087376d4a675b4f59f8fef422883434e9581a2" - dependencies: - character-parser "^2.1.1" - is-expression "^3.0.0" - pug-error "^1.3.2" - -pug-linker@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.3.tgz#25f59eb750237f0368e59c3379764229c0189c41" - dependencies: - pug-error "^1.3.2" - pug-walk "^1.1.5" - -pug-load@^2.0.9: - version "2.0.9" - resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.9.tgz#ee217c914cc1d9324d44b86c32d1df241d36de7a" - dependencies: - object-assign "^4.1.0" - pug-walk "^1.1.5" - -pug-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-4.0.0.tgz#c9f52322e4eabe4bf5beeba64ed18373bb627801" - dependencies: - pug-error "^1.3.2" - token-stream "0.0.1" - -pug-runtime@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.3.tgz#98162607b0fce9e254d427f33987a5aee7168bda" - -pug-strip-comments@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz#d313afa01bcc374980e1399e23ebf2eb9bdc8513" - dependencies: - pug-error "^1.3.2" - -pug-walk@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.5.tgz#90e943acbcf7021e6454cf1b32245891cba6f851" - -pug@^2.0.0-rc.4: - version "2.0.0-rc.4" - resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.0-rc.4.tgz#b7b08f6599bd5302568042b7436984fb28c80a13" - dependencies: - pug-code-gen "^2.0.0" - pug-filters "^2.1.5" - pug-lexer "^3.1.0" - pug-linker "^3.0.3" - pug-load "^2.0.9" - pug-parser "^4.0.0" - pug-runtime "^2.0.3" - pug-strip-comments "^1.0.2" - punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -2909,7 +2591,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -2996,33 +2678,6 @@ request-promise-native@^1.0.3: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" -request@2, request@^2.45.0, request@^2.83.0: - version "2.83.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.6.0" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.1" - forever-agent "~0.6.1" - form-data "~2.3.1" - har-validator "~5.0.3" - hawk "~6.0.2" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.17" - oauth-sign "~0.8.2" - performance-now "^2.1.0" - qs "~6.5.1" - safe-buffer "^5.1.1" - stringstream "~0.0.5" - tough-cookie "~2.3.3" - tunnel-agent "^0.6.0" - uuid "^3.1.0" - request@2.77.0: version "2.77.0" resolved "https://registry.yarnpkg.com/request/-/request-2.77.0.tgz#2b00d82030ededcc97089ffa5d8810a9c2aa314b" @@ -3075,30 +2730,32 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@~2.79.0: - version "2.79.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" +request@^2.45.0, request@^2.83.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" combined-stream "~1.0.5" - extend "~3.0.0" + extend "~3.0.1" forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - uuid "^3.0.0" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" require-directory@^2.1.1: version "2.1.1" @@ -3256,15 +2913,6 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -sass-graph@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" - dependencies: - glob "^7.0.0" - lodash "^4.0.0" - scss-tokenizer "^0.2.3" - yargs "^7.0.0" - sax@0.5.x: version "0.5.8" resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" @@ -3273,21 +2921,10 @@ sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -scss-tokenizer@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" - dependencies: - js-base64 "^2.1.8" - source-map "^0.4.2" - "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -3358,7 +2995,7 @@ source-map@0.1.x: dependencies: amdefine ">=0.0.4" -source-map@0.4.x, source-map@^0.4.2, source-map@^0.4.4: +source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: @@ -3421,12 +3058,6 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -stdout-stream@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.0.tgz#a2c7c8587e54d9427ea9edb3ac3f2cd522df378b" - dependencies: - readable-stream "^2.0.1" - stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -3564,7 +3195,7 @@ tar-pack@^3.4.0: tar "^2.2.1" uid-number "^0.0.6" -tar@^2.0.0, tar@^2.2.1: +tar@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" dependencies: @@ -3622,10 +3253,6 @@ to-fast-properties@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" -token-stream@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" - tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.0, tough-cookie@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" @@ -3646,12 +3273,6 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -"true-case-path@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.2.tgz#7ec91130924766c7f573be3020c34f8fdfd00d62" - dependencies: - glob "^6.0.4" - tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" @@ -3711,10 +3332,10 @@ typescript@^1.8.9: resolved "https://registry.yarnpkg.com/typescript/-/typescript-1.8.10.tgz#b475d6e0dff0bf50f296e5ca6ef9fbb5c7320f1e" typescript@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.1.tgz#ef39cdea27abac0b500242d6726ab90e0c846631" + version "2.6.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4" -uglify-js@^2.6, uglify-js@^2.6.1: +uglify-js@^2.6: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: @@ -3768,10 +3389,6 @@ vlq@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26" -void-elements@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" - webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -3790,15 +3407,11 @@ whatwg-url@^6.3.0: tr46 "^1.0.0" webidl-conversions "^4.0.1" -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" -which@1, which@^1.2.4, which@^1.2.9: +which@^1.2.4, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -3814,13 +3427,6 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -with@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe" - dependencies: - acorn "^3.1.0" - acorn-globals "^3.0.0" - wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -3884,12 +3490,6 @@ yallist@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - dependencies: - camelcase "^3.0.0" - yargs-parser@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-8.0.0.tgz#21d476330e5a82279a4b881345bf066102e219c6" @@ -3913,24 +3513,6 @@ yargs@^10.0.3: y18n "^3.2.1" yargs-parser "^8.0.0" -yargs@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" - yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" From 2d72a50ad9a5b07ec41925183f0f8e68840da1c0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:54:11 -0500 Subject: [PATCH 41/43] fix attribute parsing --- src/index.ts | 12 +++++------- test/preprocess/index.js | 3 ++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index e4353fdff7..081660d3d8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,19 +35,17 @@ function defaultOnerror(error: Error) { throw error; } -function parseAttributeValue(value: string | boolean) { - const curated = (value).replace(/"/ig, ''); - if (curated === 'true' || curated === 'false') { - return curated === 'true'; - } - return curated; +function parseAttributeValue(value: string) { + return /^['"]/.test(value) ? + value.slice(1, -1) : + value; } function parseAttributes(str: string) { const attrs = {}; str.split(/\s+/).filter(Boolean).forEach(attr => { const [name, value] = attr.split('='); - attrs[name] = parseAttributeValue(value); + attrs[name] = value ? parseAttributeValue(value) : true; }); return attrs; } diff --git a/test/preprocess/index.js b/test/preprocess/index.js index ea1a519655..e07bc5e718 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.js @@ -112,13 +112,14 @@ describe.only('preprocess', () => { it('parses attributes', () => { const source = ` - + `; return svelte.preprocess(source, { style: ({ attributes }) => { assert.deepEqual(attributes, { type: 'text/scss', + 'data-foo': 'bar', bool: true }); } From 9613e3f50623d3f017ea4894852d723d96ef6c7e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:55:54 -0500 Subject: [PATCH 42/43] reenable all tests --- test/preprocess/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/preprocess/index.js b/test/preprocess/index.js index e07bc5e718..29eaff67f1 100644 --- a/test/preprocess/index.js +++ b/test/preprocess/index.js @@ -1,7 +1,7 @@ import assert from 'assert'; import {svelte} from '../helpers.js'; -describe.only('preprocess', () => { +describe('preprocess', () => { it('preprocesses entire component', () => { const source = `

Hello __NAME__!

From f40a458c119c4b7ec62181f1e0a806eecb6653f4 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 2 Dec 2017 23:59:27 -0500 Subject: [PATCH 43/43] remove stylus --- package.json | 1 - yarn.lock | 50 +++++++------------------------------------------- 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 41f998d238..6684fdbd4d 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,6 @@ "rollup-watch": "^4.3.1", "source-map": "^0.5.6", "source-map-support": "^0.4.8", - "stylus": "^0.54.5", "ts-node": "^3.3.0", "tslib": "^1.8.0", "typescript": "^2.6.1" diff --git a/yarn.lock b/yarn.lock index e819c49ef0..c38c354a78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -616,10 +616,6 @@ cryptiles@3.x.x: dependencies: boom "5.x.x" -css-parse@1.7.x: - version "1.7.0" - resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b" - css-tree@1.0.0-alpha22: version "1.0.0-alpha22" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha22.tgz#338a006e331c7b4f9dab7b6af539ece56ff78af2" @@ -653,12 +649,6 @@ debug-log@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -debug@*, debug@^3.0.1, debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - debug@2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" @@ -671,6 +661,12 @@ debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.6.8: dependencies: ms "2.0.0" +debug@^3.0.1, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1255,17 +1251,6 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@7.0.x: - version "7.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" @@ -2123,7 +2108,7 @@ mkdirp@0.5.0: dependencies: minimist "0.0.8" -mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -2913,10 +2898,6 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -sax@0.5.x: - version "0.5.8" - resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" - sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -2989,12 +2970,6 @@ source-map-support@^0.4.0, source-map-support@^0.4.8: dependencies: source-map "^0.5.6" -source-map@0.1.x: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - dependencies: - amdefine ">=0.0.4" - source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" @@ -3127,17 +3102,6 @@ strip-json-comments@^2.0.0, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -stylus@^0.54.5: - version "0.54.5" - resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" - dependencies: - css-parse "1.7.x" - debug "*" - glob "7.0.x" - mkdirp "0.5.x" - sax "0.5.x" - source-map "0.1.x" - sumchecker@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d"