Skip to content

Commit

Permalink
Merge branch 'gh-1147' into gh-1082-script-style-test
Browse files Browse the repository at this point in the history
  • Loading branch information
Conduitry committed Feb 8, 2018
2 parents 7193109 + 8f91648 commit 4b4737a
Show file tree
Hide file tree
Showing 110 changed files with 1,207 additions and 282 deletions.
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# Svelte changelog

## 1.54.1

* Hoist destructured references ([#1139](https://github.com/sveltejs/svelte/issues/1139))
* Add `bind:volume` for media elements ([#1143](https://github.com/sveltejs/svelte/issues/1143))

## 1.54.0

* Run `oncreate` hooks depth-first, top-to-bottom ([#1135](https://github.com/sveltejs/svelte/issues/1135))
* Render boolean attributes correctly in SSR mode ([#1109](https://github.com/sveltejs/svelte/issues/1109))
* Add `feed` aria role to expected roles when doing a11y checks ([#1124](https://github.com/sveltejs/svelte/pull/1124))
* More complete fix for case sensitive attributes ([#1062](https://github.com/sveltejs/svelte/issues/1062))
* Handle CLRF line endings in await block comments ([#1132](https://github.com/sveltejs/svelte/issues/1132))

## 1.53.0

* Base scoping selectors on `<style>` contents alone ([#1091](https://github.com/sveltejs/svelte/issues/1091))

## 1.52.0

* Deconflict referenced globals ([#1079](https://github.com/sveltejs/svelte/issues/1079))
* Validate contents of `await` blocks ([#1061](https://github.com/sveltejs/svelte/issues/1061))
* Fire `oncreate` for components in `await` blocks ([#1061](https://github.com/sveltejs/svelte/issues/1061))
* Automatically fix attribute casing ([#1062](https://github.com/sveltejs/svelte/issues/1062))
* Fix escaping in `<script>` and `<style>` ([#1082](https://github.com/sveltejs/svelte/issues/1082))
* Error if invalid characters are used in computed properties, and allow any valid identifier in props ([#1083](https://github.com/sveltejs/svelte/issues/1083))
* Don't run a11y tests on components ([#1110](https://github.com/sveltejs/svelte/issues/1110))
* Respect `store` option in SSR mode ([#1107](https://github.com/sveltejs/svelte/issues/1107))

## 1.51.1

* Only escape <, > and & characters ([#1082](https://github.com/sveltejs/svelte/issues/1082))

## 1.51.0

* Lock `scroll` bindings ([#1071](https://github.com/sveltejs/svelte/issues/1071))
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "1.51.0",
"version": "1.54.1",
"description": "The magical disappearing UI framework",
"main": "compiler/svelte.js",
"files": [
Expand Down Expand Up @@ -56,7 +56,8 @@
"eslint-plugin-import": "^2.2.0",
"estree-walker": "^0.5.1",
"glob": "^7.1.1",
"jsdom": "^11.1.0",
"is-reference": "^1.1.0",
"jsdom": "^11.6.1",
"locate-character": "^2.0.0",
"magic-string": "^0.22.3",
"mocha": "^3.2.0",
Expand Down
5 changes: 3 additions & 2 deletions src/css/Stylesheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { walk } from 'estree-walker';
import { getLocator } from 'locate-character';
import Selector from './Selector';
import getCodeFrame from '../utils/getCodeFrame';
import hash from '../utils/hash';
import Element from '../generators/nodes/Element';
import { Validator } from '../validate/index';
import { Node, Parsed, Warning } from '../interfaces';
Expand Down Expand Up @@ -269,12 +270,12 @@ export default class Stylesheet {
this.cascade = cascade;
this.filename = filename;

this.id = `svelte-${parsed.hash}`;

this.children = [];
this.keyframes = new Map();

if (parsed.css && parsed.css.children.length) {
this.id = `svelte-${hash(parsed.css.content.styles)}`;

this.hasStyles = true;

const stack: (Rule | Atrule)[] = [];
Expand Down
25 changes: 17 additions & 8 deletions src/generators/Generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,20 @@ export default class Generator {
} else if (contexts.has(name)) {
const contextName = contexts.get(name);
if (contextName !== name) {
// this is true for 'reserved' names like `state` and `component`
// this is true for 'reserved' names like `state` and `component`,
// also destructured contexts
code.overwrite(
node.start,
node.start + name.length,
contextName,
{ storeName: true, contentOnly: false }
);

const destructuredName = contextName.replace(/\[\d+\]/, '');
if (destructuredName !== contextName) {
// so that hoisting the context works correctly
usedContexts.add(destructuredName);
}
}

usedContexts.add(name);
Expand Down Expand Up @@ -410,11 +417,16 @@ export default class Generator {
const indentationLevel = getIndentationLevel(source, js.content.body[0].start);
const indentExclusionRanges = getIndentExclusionRanges(js.content);

const scope = annotateWithScopes(js.content);
const { scope, globals } = annotateWithScopes(js.content);

scope.declarations.forEach(name => {
this.userVars.add(name);
});

globals.forEach(name => {
this.userVars.add(name);
});

const body = js.content.body.slice(); // slice, because we're going to be mutating the original

// imports need to be hoisted out of the IIFE
Expand Down Expand Up @@ -666,7 +678,7 @@ export default class Generator {
isEventHandler: boolean
) => {
this.addSourcemapLocations(node); // TODO this involves an additional walk — can we roll it in somewhere else?
let scope = annotateWithScopes(node);
let { scope } = annotateWithScopes(node);

const dependencies: Set<string> = new Set();

Expand Down Expand Up @@ -767,12 +779,9 @@ export default class Generator {
contextDependencies.set(node.context, node.metadata.dependencies);

if (node.destructuredContexts) {
for (let i = 0; i < node.destructuredContexts.length; i += 1) {
const name = node.destructuredContexts[i];
const value = `${node.context}[${i}]`;

node.destructuredContexts.forEach((name: string) => {
contextDependencies.set(name, node.metadata.dependencies);
}
});
}

contextDependenciesStack.push(contextDependencies);
Expand Down
14 changes: 7 additions & 7 deletions src/generators/dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,20 +245,20 @@ export default function dom(
${(templateProperties.oncreate || generator.hasComponents || generator.hasComplexBindings || generator.hasIntroTransitions) && deindent`
if (!options.root) {
this._oncreate = [${templateProperties.oncreate && `_oncreate`}];
this._oncreate = [];
${(generator.hasComponents || generator.hasComplexBindings) && `this._beforecreate = [];`}
${(generator.hasComponents || generator.hasIntroTransitions) && `this._aftercreate = [];`}
} ${templateProperties.oncreate && deindent`
else {
this.root._oncreate.push(_oncreate);
}
`}
}
`}
${generator.slots.size && `this.slots = {};`}
this._fragment = @create_main_fragment(this._state, this);
${(templateProperties.oncreate) && deindent`
this.root._oncreate.push(_oncreate);
`}
${generator.customElement ? deindent`
this._fragment.c();
this._fragment.${block.hasIntroMethod ? 'i' : 'm'}(this.shadowRoot, null);
Expand Down Expand Up @@ -407,7 +407,7 @@ export default function dom(
const code = new MagicString(str);
const expression = parseExpressionAt(str, 0);

let scope = annotateWithScopes(expression);
let { scope } = annotateWithScopes(expression);

walk(expression, {
enter(node: Node, parent: Node) {
Expand Down
6 changes: 4 additions & 2 deletions src/generators/nodes/Attribute.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import deindent from '../../utils/deindent';
import { stringify } from '../../utils/stringify';
import fixAttributeCasing from '../../utils/fixAttributeCasing';
import getExpressionPrecedence from '../../utils/getExpressionPrecedence';
import { DomGenerator } from '../dom/index';
import Node from './shared/Node';
Expand Down Expand Up @@ -43,7 +44,7 @@ export default class Attribute {

render(block: Block) {
const node = this.parent;
const name = this.name;
const name = fixAttributeCasing(this.name);

if (name === 'style') {
const styleProps = optimizeStyle(this.value);
Expand Down Expand Up @@ -539,6 +540,7 @@ const attributeLookup = {
'textarea',
],
},
volume: { appliesTo: ['audio', 'video'] },
width: {
appliesTo: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'],
},
Expand Down Expand Up @@ -662,4 +664,4 @@ function getStyleValue(chunks: Node[]) {

function isDynamic(value: Node[]) {
return value.length > 1 || value[0].type !== 'Text';
}
}
8 changes: 8 additions & 0 deletions src/generators/nodes/AwaitBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export default class AwaitBlock extends Node {
block.addVariable(promise);
block.addVariable(resolved);

// the `#component.root.set({})` below is just a cheap way to flush
// any oncreate handlers. We could have a dedicated `flush()` method
// but it's probably not worth it

block.builders.init.addBlock(deindent`
function ${replace_await_block}(${token}, type, ${value}, ${params}) {
if (${token} !== ${await_token}) return;
Expand All @@ -113,6 +117,8 @@ export default class AwaitBlock extends Node {
${old_block}.d();
${await_block}.c();
${await_block}.m(${updateMountNode}, ${anchor});
#component.root.set({});
}
}
Expand All @@ -121,8 +127,10 @@ export default class AwaitBlock extends Node {
if (@isPromise(${promise})) {
${promise}.then(function(${value}) {
var state = #component.get();
${replace_await_block}(${token}, ${create_then_block}, ${value}, ${params});
}, function (${error}) {
var state = #component.get();
${replace_await_block}(${token}, ${create_catch_block}, ${error}, ${params});
});
Expand Down
8 changes: 5 additions & 3 deletions src/generators/nodes/Binding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ export default class Binding extends Node {
);
}

if (this.name === 'currentTime') {
if (this.name === 'currentTime' || this.name === 'volume') {
updateCondition = `!isNaN(${snippet})`;
initialUpdate = null;

if (this.name === 'currentTime')
initialUpdate = null;
}

if (this.name === 'paused') {
Expand Down Expand Up @@ -267,4 +269,4 @@ function isComputed(node: Node) {
}

return false;
}
}
11 changes: 9 additions & 2 deletions src/generators/nodes/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import flattenReference from '../../utils/flattenReference';
import isVoidElementName from '../../utils/isVoidElementName';
import validCalleeObjects from '../../utils/validCalleeObjects';
import reservedNames from '../../utils/reservedNames';
import fixAttributeCasing from '../../utils/fixAttributeCasing';
import Node from './shared/Node';
import Block from '../dom/Block';
import Attribute from './Attribute';
Expand Down Expand Up @@ -427,12 +428,12 @@ export default class Element extends Node {
}

node.attributes.forEach((attr: Node) => {
open += ` ${attr.name}${stringifyAttributeValue(attr.value)}`
open += ` ${fixAttributeCasing(attr.name)}${stringifyAttributeValue(attr.value)}`
});

if (isVoidElementName(node.name)) return open + '>';

if (node.name === 'script' || node.name === 'style') {
if (node.name === 'script') {
return `${open}>${node.data}</${node.name}>`;
}

Expand Down Expand Up @@ -759,5 +760,11 @@ const events = [
filter: (node: Element, name: string) =>
node.isMediaNode() &&
(name === 'buffered' || name === 'seekable')
},
{
eventNames: ['volumechange'],
filter: (node: Element, name: string) =>
node.isMediaNode() &&
name === 'volume'
}
];
2 changes: 1 addition & 1 deletion src/generators/server-side-rendering/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ export default function ssr(
}
var result = { head: '', addComponent };
${templateProperties.store && `options.store = %store();`}
var html = ${name}._render(result, state, options);
var cssCode = Array.from(components).map(c => c.css && c.css.code).filter(Boolean).join('\\n');
Expand All @@ -130,6 +129,7 @@ export default function ssr(
}
${name}._render = function(__result, state, options) {
${templateProperties.store && `options.store = %store();`}
__result.addComponent(${name});
state = Object.assign(${initialState.join(', ')});
Expand Down
26 changes: 17 additions & 9 deletions src/generators/server-side-rendering/visitors/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import Element from '../../nodes/Element';
import Block from '../Block';
import { Node } from '../../../interfaces';
import stringifyAttributeValue from './shared/stringifyAttributeValue';
import { escape } from '../../../utils/stringify';

// source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7
const booleanAttributes = new Set('async autocomplete autofocus autoplay border challenge checked compact contenteditable controls default defer disabled formnovalidate frameborder hidden indeterminate ismap loop multiple muted nohref noresize noshade novalidate nowrap open readonly required reversed scoped scrolling seamless selected sortable spellcheck translate'.split(' '));

export default function visitElement(
generator: SsrGenerator,
Expand Down Expand Up @@ -35,14 +39,18 @@ export default function visitElement(

if (attribute.name === 'value' && node.name === 'textarea') {
textareaContents = stringifyAttributeValue(block, attribute.value);
} else if (attribute.value === true) {
openingTag += ` ${attribute.name}`;
} else if (
booleanAttributes.has(attribute.name) &&
attribute.value.length === 1 &&
attribute.value[0].type !== 'Text'
) {
// a boolean attribute with one non-Text chunk
block.contextualise(attribute.value[0].expression);
openingTag += '${' + attribute.value[0].metadata.snippet + ' ? " ' + attribute.name + '" : "" }';
} else {
let str = ` ${attribute.name}`;

if (attribute.value !== true) {
str += `="${stringifyAttributeValue(block, attribute.value)}"`;
}

openingTag += str;
openingTag += ` ${attribute.name}="${stringifyAttributeValue(block, attribute.value)}"`;
}
});

Expand All @@ -60,8 +68,8 @@ export default function visitElement(

if (node.name === 'textarea' && textareaContents !== undefined) {
generator.append(textareaContents);
} else if (node.name === 'script' || node.name === 'style') {
generator.append(node.data);
} else if (node.name === 'script') {
generator.append(escape(node.data));
} else {
node.children.forEach((child: Node) => {
visit(generator, block, child);
Expand Down
Loading

0 comments on commit 4b4737a

Please sign in to comment.