From 12a088b1caa0d0187948a82be71a265c8221a552 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 17 Jan 2017 14:14:33 -0500 Subject: [PATCH 01/14] handle multiline comments in CSS - fixes #252 --- src/generators/shared/css/transform.js | 2 +- test/generator/css-comments/_config.js | 7 +++++++ test/generator/css-comments/main.html | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/generator/css-comments/_config.js create mode 100644 test/generator/css-comments/main.html diff --git a/src/generators/shared/css/transform.js b/src/generators/shared/css/transform.js index 803c16d47a..12ae0981e5 100644 --- a/src/generators/shared/css/transform.js +++ b/src/generators/shared/css/transform.js @@ -1,6 +1,6 @@ // largely borrowed from Ractive – https://github.com/ractivejs/ractive/blob/2ec648aaf5296bb88c21812e947e0e42fcc456e3/src/Ractive/config/custom/css/transform.js const selectorsPattern = /(?:^|\})?\s*([^\{\}]+)\s*\{/g; -const commentsPattern = /\/\*.*?\*\//g; +const commentsPattern = /\/\*[\s\S]*?\*\//g; const selectorUnitPattern = /((?:(?:\[[^\]+]\])|(?:[^\s\+\>~:]))+)((?:::?[^\s\+\>\~\(:]+(?:\([^\)]+\))?)*\s*[\s\+\>\~]?)\s*/g; const excludePattern = /^(?:@|\d+%)/; diff --git a/test/generator/css-comments/_config.js b/test/generator/css-comments/_config.js new file mode 100644 index 0000000000..f6235d06a2 --- /dev/null +++ b/test/generator/css-comments/_config.js @@ -0,0 +1,7 @@ +// JSDOM makes this test pass when it should fail. weird +export default { + test ( assert, component, target, window ) { + const p = target.querySelector( 'p' ); + assert.equal( window.getComputedStyle( p ).color, 'red' ); + } +}; diff --git a/test/generator/css-comments/main.html b/test/generator/css-comments/main.html new file mode 100644 index 0000000000..68eebfdf38 --- /dev/null +++ b/test/generator/css-comments/main.html @@ -0,0 +1,11 @@ +

red

+ + From d5411f43d6ed5e8c40ac120142586beafc616b9c Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 17 Jan 2017 14:35:48 -0500 Subject: [PATCH 02/14] -> v1.6.4 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57f80501ab..d1391ba5b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Svelte changelog +## 1.6.4 + +* Fix updates of yields inside each blocks ([20e1b05](https://github.com/sveltejs/svelte/commit/20e1b05c45dc9fcddfe2e7c5c9fc3109f0d45fa9)) +* SSR: Handle attributes with values that begin with a number ([#248](https://github.com/sveltejs/svelte/issues/248)) +* Handle multiline comments in CSS ([#252](https://github.com/sveltejs/svelte/issues/252)) + ## 1.6.3 * Fix `{{yield}}` bugs for components inside `if` and `each` blocks ([#230](https://github.com/sveltejs/svelte/issues/230), [#231](https://github.com/sveltejs/svelte/issues/231)) diff --git a/package.json b/package.json index 95e2b0b1f3..c25a81ef72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "1.6.3", + "version": "1.6.4", "description": "The magical disappearing UI framework", "main": "compiler/svelte.js", "files": [ From 1b16c02fe02d9844cb7d7409a5e8febcb93e3826 Mon Sep 17 00:00:00 2001 From: Matt Steitle Date: Tue, 17 Jan 2017 17:16:07 -0700 Subject: [PATCH 03/14] dontThrowParseErrorOnDoctypeDeclaration: Adding unit test for doctype tag --- test/parser/elements/input.html | 1 + test/parser/elements/output.json | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 test/parser/elements/input.html create mode 100644 test/parser/elements/output.json diff --git a/test/parser/elements/input.html b/test/parser/elements/input.html new file mode 100644 index 0000000000..c50eddd41f --- /dev/null +++ b/test/parser/elements/input.html @@ -0,0 +1 @@ + diff --git a/test/parser/elements/output.json b/test/parser/elements/output.json new file mode 100644 index 0000000000..79608f9132 --- /dev/null +++ b/test/parser/elements/output.json @@ -0,0 +1,23 @@ +{ + "html": { + "start": 0, + "end": 15, + "type": "Fragment", + "children": [{ + "attributes": [{ + "end": 14, + "name": "html", + "start": 10, + "type": "Attribute", + "value": true + }], + "children": [], + "end": 15, + "name": "!doctype", + "start": 0, + "type": "Element" + }] + }, + "css": null, + "js": null +} From 522f293766a808a2630b7e8c8760336e6c535228 Mon Sep 17 00:00:00 2001 From: Matt Steitle Date: Tue, 17 Jan 2017 17:19:29 -0700 Subject: [PATCH 04/14] dontThrowParseErrorOnDoctypeDeclaration: Adding additional specification for doctype tag matching --- src/parse/state/tag.js | 2 +- src/utils/voidElementNames.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parse/state/tag.js b/src/parse/state/tag.js index 2db102ab0d..72f73f0651 100644 --- a/src/parse/state/tag.js +++ b/src/parse/state/tag.js @@ -6,7 +6,7 @@ import { trimStart, trimEnd } from '../utils/trim.js'; import { decodeCharacterReferences } from '../utils/html.js'; import voidElementNames from '../../utils/voidElementNames.js'; -const validTagName = /^[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; +const validTagName = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; const invalidUnquotedAttributeCharacters = /[\s"'=<>\/`]/; const specials = { diff --git a/src/utils/voidElementNames.js b/src/utils/voidElementNames.js index 7df1d452b6..46306ac8c3 100644 --- a/src/utils/voidElementNames.js +++ b/src/utils/voidElementNames.js @@ -1 +1 @@ -export default /^(?:area|base|br|col|command|doctype|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/; +export default /^(?:area|base|br|col|command|\!doctype|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/; From 9311d1b0a6034a445011c7a24b780ac3827124ab Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 17 Jan 2017 21:05:09 -0500 Subject: [PATCH 05/14] -> v1.6.5 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1391ba5b5..0d0733ef18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Svelte changelog +## 1.6.5 + +* Handle `` declarations ([#255](https://github.com/sveltejs/svelte/pull/255)) + ## 1.6.4 * Fix updates of yields inside each blocks ([20e1b05](https://github.com/sveltejs/svelte/commit/20e1b05c45dc9fcddfe2e7c5c9fc3109f0d45fa9)) diff --git a/package.json b/package.json index c25a81ef72..40c191f029 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svelte", - "version": "1.6.4", + "version": "1.6.5", "description": "The magical disappearing UI framework", "main": "compiler/svelte.js", "files": [ From cdb4a3568d68bbb834051473cb9485f87bc61b16 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 20 Dec 2016 23:21:28 -0500 Subject: [PATCH 06/14] use empty comments as anchors --- src/generators/dom/index.js | 4 ++-- src/generators/dom/visitors/EachBlock.js | 2 +- src/generators/dom/visitors/IfBlock.js | 2 +- src/generators/dom/visitors/YieldTag.js | 2 +- src/shared/dom.js | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index 929d737700..de0c5dc496 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -98,9 +98,9 @@ class DomGenerator extends Generator { ` ); } - createAnchor ( name, description = '' ) { + createAnchor ( name ) { this.uses.createComment = true; - const renderStatement = `createComment( ${JSON.stringify( description )} )`; + const renderStatement = `createComment()`; this.addElement( name, renderStatement, true ); } diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index 2799a421b8..700e16ef7a 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -21,7 +21,7 @@ export default { const { dependencies, snippet } = generator.contextualise( node.expression ); const anchor = `${name}_anchor`; - generator.createAnchor( anchor, `#each ${generator.source.slice( node.expression.start, node.expression.end )}` ); + generator.createAnchor( anchor ); generator.current.builders.init.addLine( `var ${name}_value = ${snippet};` ); generator.current.builders.init.addLine( `var ${iterations} = [];` ); diff --git a/src/generators/dom/visitors/IfBlock.js b/src/generators/dom/visitors/IfBlock.js index 02133e539d..5ceb42d48b 100644 --- a/src/generators/dom/visitors/IfBlock.js +++ b/src/generators/dom/visitors/IfBlock.js @@ -41,7 +41,7 @@ export default { const conditionsAndBlocks = getConditionsAndBlocks( generator, node, generator.getUniqueName( `renderIfBlock` ) ); const anchor = `${name}_anchor`; - generator.createAnchor( anchor, `#if ${generator.source.slice( node.expression.start, node.expression.end )}` ); + generator.createAnchor( anchor ); generator.current.builders.init.addBlock( deindent` function ${getBlock} ( ${params} ) { diff --git a/src/generators/dom/visitors/YieldTag.js b/src/generators/dom/visitors/YieldTag.js index 5fefcd73a3..98996486c1 100644 --- a/src/generators/dom/visitors/YieldTag.js +++ b/src/generators/dom/visitors/YieldTag.js @@ -1,7 +1,7 @@ export default { enter ( generator ) { const anchor = `yield_anchor`; - generator.createAnchor( anchor, 'yield' ); + generator.createAnchor( anchor ); generator.current.builders.mount.addLine( `component._yield && component._yield.mount( ${generator.current.target}, ${anchor} );` diff --git a/src/shared/dom.js b/src/shared/dom.js index 9d4231572f..4007e90289 100644 --- a/src/shared/dom.js +++ b/src/shared/dom.js @@ -34,8 +34,8 @@ export function createText ( data ) { return document.createTextNode( data ); } -export function createComment ( data ) { - return document.createComment( data ); +export function createComment () { + return document.createComment( '' ); } export function addEventListener ( node, event, handler ) { From 2316d7d3482ca3f31dfe3e0fe5cfd9eee9463364 Mon Sep 17 00:00:00 2001 From: Conduitry Date: Tue, 27 Dec 2016 20:59:43 -0500 Subject: [PATCH 07/14] fix unit tests --- test/generator/attribute-dynamic-multiple/_config.js | 2 +- test/generator/binding-input-text-contextual/_config.js | 6 +++--- .../generator/binding-input-text-deep-contextual/_config.js | 6 +++--- test/generator/component-yield-parent/_config.js | 6 +++--- test/generator/each-block-indexed/_config.js | 2 +- test/generator/each-block/_config.js | 6 +++--- test/generator/each-blocks-expression/_config.js | 2 +- test/generator/each-blocks-nested-b/_config.js | 2 +- test/generator/each-blocks-nested/_config.js | 2 +- test/generator/event-handler-removal/_config.js | 2 +- test/generator/event-handler/_config.js | 6 +++--- test/generator/if-block-widget/_config.js | 6 +++--- test/generator/if-block/_config.js | 6 +++--- 13 files changed, 27 insertions(+), 27 deletions(-) diff --git a/test/generator/attribute-dynamic-multiple/_config.js b/test/generator/attribute-dynamic-multiple/_config.js index 83c6a58a86..1a0c602cb6 100644 --- a/test/generator/attribute-dynamic-multiple/_config.js +++ b/test/generator/attribute-dynamic-multiple/_config.js @@ -7,5 +7,5 @@ export default { ] }, - html: `
1
2
3
` + html: `
1
2
3
` }; diff --git a/test/generator/binding-input-text-contextual/_config.js b/test/generator/binding-input-text-contextual/_config.js index 3f2d3f3fc0..332d2c6f39 100644 --- a/test/generator/binding-input-text-contextual/_config.js +++ b/test/generator/binding-input-text-contextual/_config.js @@ -6,7 +6,7 @@ export default { 'three' ] }, - html: `

one

two

three

`, + html: `

one

two

three

`, test ( assert, component, target, window ) { const inputs = [ ...target.querySelectorAll( 'input' ) ]; const items = component.get( 'items' ); @@ -18,12 +18,12 @@ export default { inputs[1].dispatchEvent( event ); assert.equal( items[1], 'four' ); - assert.equal( target.innerHTML, `

one

four

three

` ); + assert.equal( target.innerHTML, `

one

four

three

` ); items[2] = 'five'; component.set({ items }); assert.equal( inputs[2].value, 'five' ); - assert.equal( target.innerHTML, `

one

four

five

` ); + assert.equal( target.innerHTML, `

one

four

five

` ); } }; diff --git a/test/generator/binding-input-text-deep-contextual/_config.js b/test/generator/binding-input-text-deep-contextual/_config.js index f24902a962..587110786c 100644 --- a/test/generator/binding-input-text-deep-contextual/_config.js +++ b/test/generator/binding-input-text-deep-contextual/_config.js @@ -6,7 +6,7 @@ export default { { description: 'three' } ] }, - html: `

one

two

three

`, + html: `

one

two

three

`, test ( assert, component, target, window ) { const inputs = [ ...target.querySelectorAll( 'input' ) ]; @@ -17,13 +17,13 @@ export default { inputs[1].value = 'four'; inputs[1].dispatchEvent( event ); - assert.equal( target.innerHTML, `

one

four

three

` ); + assert.equal( target.innerHTML, `

one

four

three

` ); const items = component.get( 'items' ); items[2].description = 'five'; component.set({ items }); assert.equal( inputs[2].value, 'five' ); - assert.equal( target.innerHTML, `

one

four

five

` ); + assert.equal( target.innerHTML, `

one

four

five

` ); } }; diff --git a/test/generator/component-yield-parent/_config.js b/test/generator/component-yield-parent/_config.js index 28b8e175de..cc3b39ca81 100644 --- a/test/generator/component-yield-parent/_config.js +++ b/test/generator/component-yield-parent/_config.js @@ -2,8 +2,8 @@ export default { html: '

Hello

', test ( assert, component, target ) { assert.equal( component.get( 'data' ), 'Hello' ); - component.set({data: 'World'}) + component.set({data: 'World'}); assert.equal( component.get( 'data' ), 'World' ); - assert.equal( target.innerHTML, '

World

' ); + assert.equal( target.innerHTML, '

World

' ); } -} +}; diff --git a/test/generator/each-block-indexed/_config.js b/test/generator/each-block-indexed/_config.js index 34640e18cb..5aaadafb05 100644 --- a/test/generator/each-block-indexed/_config.js +++ b/test/generator/each-block-indexed/_config.js @@ -2,5 +2,5 @@ export default { data: { animals: [ 'adder', 'blue whale', 'chameleon' ] }, - html: `

0: adder

1: blue whale

2: chameleon

` + html: `

0: adder

1: blue whale

2: chameleon

` }; diff --git a/test/generator/each-block/_config.js b/test/generator/each-block/_config.js index 959bf88c04..655556bedf 100644 --- a/test/generator/each-block/_config.js +++ b/test/generator/each-block/_config.js @@ -2,11 +2,11 @@ export default { data: { animals: [ 'alpaca', 'baboon', 'capybara' ] }, - html: '

alpaca

baboon

capybara

', + html: '

alpaca

baboon

capybara

', test ( assert, component, target ) { component.set({ animals: [ 'alpaca', 'baboon', 'caribou', 'dogfish' ] }); - assert.equal( target.innerHTML, '

alpaca

baboon

caribou

dogfish

' ); + assert.equal( target.innerHTML, '

alpaca

baboon

caribou

dogfish

' ); component.set({ animals: [] }); - assert.equal( target.innerHTML, '' ); + assert.equal( target.innerHTML, '' ); } }; diff --git a/test/generator/each-blocks-expression/_config.js b/test/generator/each-blocks-expression/_config.js index b610b055b4..239a18b6dc 100644 --- a/test/generator/each-blocks-expression/_config.js +++ b/test/generator/each-blocks-expression/_config.js @@ -1,3 +1,3 @@ export default { - html: `

a

b

c

` + html: `

a

b

c

` }; diff --git a/test/generator/each-blocks-nested-b/_config.js b/test/generator/each-blocks-nested-b/_config.js index 806284ef2d..1ba0f685b8 100644 --- a/test/generator/each-blocks-nested-b/_config.js +++ b/test/generator/each-blocks-nested-b/_config.js @@ -28,7 +28,7 @@ export default { } ] }, - html: `

animals: aardvark

animals: buffalo

animals: chinchilla

countries: albania

countries: brazil

countries: china

people: alice

people: bob

people: carol

people: dave

`, + html: `

animals: aardvark

animals: buffalo

animals: chinchilla

countries: albania

countries: brazil

countries: china

people: alice

people: bob

people: carol

people: dave

`, test ( assert, component, target ) { // TODO } diff --git a/test/generator/each-blocks-nested/_config.js b/test/generator/each-blocks-nested/_config.js index 0c21561e75..5486c8274e 100644 --- a/test/generator/each-blocks-nested/_config.js +++ b/test/generator/each-blocks-nested/_config.js @@ -4,7 +4,7 @@ export default { rows: [ 1, 2, 3 ] }, - html: `
a, 1
a, 2
a, 3
b, 1
b, 2
b, 3
c, 1
c, 2
c, 3
`, + html: `
a, 1
a, 2
a, 3
b, 1
b, 2
b, 3
c, 1
c, 2
c, 3
`, test ( assert, component, target ) { // TODO diff --git a/test/generator/event-handler-removal/_config.js b/test/generator/event-handler-removal/_config.js index 91bc0452a5..b196db1765 100644 --- a/test/generator/event-handler-removal/_config.js +++ b/test/generator/event-handler-removal/_config.js @@ -1,7 +1,7 @@ // TODO gah, JSDOM appears to behave differently to real browsers here... probably need to raise an issue export default { - html: '', + html: '', test ( assert, component ) { component.refs.input.focus(); diff --git a/test/generator/event-handler/_config.js b/test/generator/event-handler/_config.js index 5fb7f6bc86..8aa60ff387 100644 --- a/test/generator/event-handler/_config.js +++ b/test/generator/event-handler/_config.js @@ -1,13 +1,13 @@ export default { - html: '\n\n', + html: '\n\n', test ( assert, component, target, window ) { const button = target.querySelector( 'button' ); const event = new window.MouseEvent( 'click' ); button.dispatchEvent( event ); - assert.equal( target.innerHTML, '\n\n

hello!

' ); + assert.equal( target.innerHTML, '\n\n

hello!

' ); button.dispatchEvent( event ); - assert.equal( target.innerHTML, '\n\n' ); + assert.equal( target.innerHTML, '\n\n' ); } }; diff --git a/test/generator/if-block-widget/_config.js b/test/generator/if-block-widget/_config.js index 674fefb0ba..40d9d050e9 100644 --- a/test/generator/if-block-widget/_config.js +++ b/test/generator/if-block-widget/_config.js @@ -2,11 +2,11 @@ export default { data: { visible: true }, - html: 'before\n

Widget

\nafter', + html: 'before\n

Widget

\nafter', test ( assert, component, target ) { component.set({ visible: false }); - assert.equal( target.innerHTML, 'before\n\nafter' ); + assert.equal( target.innerHTML, 'before\n\nafter' ); component.set({ visible: true }); - assert.equal( target.innerHTML, 'before\n

Widget

\nafter' ); + assert.equal( target.innerHTML, 'before\n

Widget

\nafter' ); } }; diff --git a/test/generator/if-block/_config.js b/test/generator/if-block/_config.js index f8014c5c9a..4194fd29bc 100644 --- a/test/generator/if-block/_config.js +++ b/test/generator/if-block/_config.js @@ -2,11 +2,11 @@ export default { data: { visible: true }, - html: '

i am visible

', + html: '

i am visible

', test ( assert, component, target ) { component.set({ visible: false }); - assert.equal( target.innerHTML, '' ); + assert.equal( target.innerHTML, '' ); component.set({ visible: true }); - assert.equal( target.innerHTML, '

i am visible

' ); + assert.equal( target.innerHTML, '

i am visible

' ); } }; From c4220d647f63f4bc98833ede160e92ca24e0bf88 Mon Sep 17 00:00:00 2001 From: Paul Sauve Date: Mon, 23 Jan 2017 16:09:20 -0600 Subject: [PATCH 08/14] xmlns should be added as an attribute for consistency --- .../dom/visitors/attributes/addElementAttributes.js | 6 ++++++ test/generator/svg-xmlns/_config.js | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/generators/dom/visitors/attributes/addElementAttributes.js b/src/generators/dom/visitors/attributes/addElementAttributes.js index 490d330348..fb549805c5 100644 --- a/src/generators/dom/visitors/attributes/addElementAttributes.js +++ b/src/generators/dom/visitors/attributes/addElementAttributes.js @@ -55,15 +55,21 @@ export default function addElementAttributes ( generator, node, local ) { // static attributes result = JSON.stringify( value.data ); + let addAttribute = false; if ( attribute.name === 'xmlns' ) { // special case // TODO this attribute must be static – enforce at compile time local.namespace = value.data; + addAttribute = true; } else if ( propertyName ) { local.init.addLine( `${local.name}.${propertyName} = ${result};` ); } else { + addAttribute = true; + } + + if (addAttribute) { generator.uses.setAttribute = true; local.init.addLine( `setAttribute( ${local.name}, '${attribute.name}', ${result} );` diff --git a/test/generator/svg-xmlns/_config.js b/test/generator/svg-xmlns/_config.js index 37d94a1609..a3ab702eaf 100644 --- a/test/generator/svg-xmlns/_config.js +++ b/test/generator/svg-xmlns/_config.js @@ -6,7 +6,7 @@ export default { height: 100 }, - html: ``, + html: ``, test ( assert, component, target ) { const svg = target.querySelector( 'svg' ); @@ -16,6 +16,6 @@ export default { assert.equal( rect.namespaceURI, 'http://www.w3.org/2000/svg' ); component.set({ width: 150, height: 50 }); - assert.equal( target.innerHTML, `` ); + assert.equal( target.innerHTML, `` ); } }; From fa705302616e511860401b98df76426e687be1c0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 24 Jan 2017 17:03:14 -0500 Subject: [PATCH 09/14] handle xlink attributes --- .../attributes/addElementAttributes.js | 51 +++++++++++-------- src/shared/dom.js | 4 ++ test/generator/svg-xlink/_config.js | 19 +++++++ test/generator/svg-xlink/main.html | 7 +++ test/helpers.js | 4 ++ 5 files changed, 64 insertions(+), 21 deletions(-) create mode 100644 test/generator/svg-xlink/_config.js create mode 100644 test/generator/svg-xlink/main.html diff --git a/src/generators/dom/visitors/attributes/addElementAttributes.js b/src/generators/dom/visitors/attributes/addElementAttributes.js index 490d330348..c6009ff2e8 100644 --- a/src/generators/dom/visitors/attributes/addElementAttributes.js +++ b/src/generators/dom/visitors/attributes/addElementAttributes.js @@ -5,15 +5,24 @@ import flattenReference from '../../../../utils/flattenReference.js'; export default function addElementAttributes ( generator, node, local ) { node.attributes.forEach( attribute => { + const name = attribute.name; + if ( attribute.type === 'Attribute' ) { - let metadata = local.namespace ? null : attributeLookup[ attribute.name ]; + let metadata = local.namespace ? null : attributeLookup[ name ]; if ( metadata && metadata.appliesTo && !~metadata.appliesTo.indexOf( node.name ) ) metadata = null; let dynamic = false; - const isBoundOptionValue = node.name === 'option' && attribute.name === 'value'; // TODO check it's actually bound + const isBoundOptionValue = node.name === 'option' && name === 'value'; // TODO check it's actually bound const propertyName = isBoundOptionValue ? '__value' : metadata && metadata.propertyName; + const isXlink = name.slice( 0, 6 ) === 'xlink:'; + + // xlink is a special case... we could maybe extend this to generic + // namespaced attributes but I'm not sure that's applicable in + // HTML5? + const helper = isXlink ? 'setXlinkAttribute' : 'setAttribute'; + if ( attribute.value === true ) { // attributes without values, e.g.