From bbe4ab7b7d58204edd4afef1fd711b50410e72ba Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 7 Apr 2019 12:55:14 -0400 Subject: [PATCH 1/8] apply namespace to foreignObject correctly - fixes #2340 --- src/compile/nodes/Element.ts | 24 +++++++++++++------ .../svg-foreignobject-namespace/_config.js | 3 +++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index 9711e2f6da..daf1e6a063 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -16,7 +16,7 @@ import list from '../../utils/list'; import Let from './Let'; import TemplateScope from './shared/TemplateScope'; -const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; +const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; const aria_attributes = 'activedescendant atomic autocomplete busy checked colindex controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowindex selected setsize sort valuemax valuemin valuenow valuetext'.split(' '); const aria_attribute_set = new Set(aria_attributes); @@ -73,6 +73,21 @@ const passive_events = new Set([ 'touchcancel' ]); +function get_namespace(parent: Element, element: Element) { + const parent_element = parent.find_nearest(/^Element/); + + if (!parent_element) { + return svg.test(element.name) + ? namespaces.svg + : null; + } + + if (element.name.toLowerCase() === 'svg') return namespaces.svg; + if (parent_element.name.toLowerCase() === 'foreignobject') return null; + + return parent_element.namespace; +} + export default class Element extends Node { type: 'Element'; name: string; @@ -93,12 +108,7 @@ export default class Element extends Node { super(component, parent, scope, info); this.name = info.name; - const parent_element = parent.find_nearest(/^Element/); - this.namespace = this.name === 'svg' || (!parent_element && svg.test(this.name)) - ? namespaces.svg - : this.name === 'foreignObject' - ? namespaces.html - : parent_element ? parent_element.namespace : this.component.namespace; + this.namespace = component.namespace || get_namespace(parent, this); if (this.name === 'textarea') { if (info.children.length > 0) { diff --git a/test/runtime/samples/svg-foreignobject-namespace/_config.js b/test/runtime/samples/svg-foreignobject-namespace/_config.js index a0185bae8e..950e35e79d 100644 --- a/test/runtime/samples/svg-foreignobject-namespace/_config.js +++ b/test/runtime/samples/svg-foreignobject-namespace/_config.js @@ -8,6 +8,9 @@ export default { `, test({ assert, target }) { + const foreignObject = target.querySelector('foreignObject'); + assert.equal(foreignObject.namespaceURI, 'http://www.w3.org/2000/svg'); + const p = target.querySelector('p'); assert.equal(p.namespaceURI, 'http://www.w3.org/1999/xhtml'); } From aac1f74d585a6b2fbaae33d29d4139b11886ef53 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 7 Apr 2019 12:59:31 -0400 Subject: [PATCH 2/8] only use explicit namespace for top-level elements --- src/compile/nodes/Element.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index daf1e6a063..bc1991c57e 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -73,13 +73,13 @@ const passive_events = new Set([ 'touchcancel' ]); -function get_namespace(parent: Element, element: Element) { +function get_namespace(parent: Element, element: Element, explicit_namespace: string) { const parent_element = parent.find_nearest(/^Element/); if (!parent_element) { - return svg.test(element.name) + return explicit_namespace || (svg.test(element.name) ? namespaces.svg - : null; + : null); } if (element.name.toLowerCase() === 'svg') return namespaces.svg; @@ -108,7 +108,7 @@ export default class Element extends Node { super(component, parent, scope, info); this.name = info.name; - this.namespace = component.namespace || get_namespace(parent, this); + this.namespace = get_namespace(parent, this, component.namespace); if (this.name === 'textarea') { if (info.children.length > 0) { From 100d7d422392bd3c04a644f204837ed0ef84d61a Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Mon, 8 Apr 2019 07:51:52 -0400 Subject: [PATCH 3/8] make dropdown clickable in Safari --- .../routes/tutorial/[slug]/_components/TableOfContents.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte b/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte index 0f9f810615..4dab3416d8 100644 --- a/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte +++ b/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte @@ -54,6 +54,7 @@ height: 100%; opacity: 0.0001; cursor: pointer; + -webkit-appearance: none; } From ecf1a4af8c26238d573bd3cbe41209b31f33b62e Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Mon, 8 Apr 2019 07:56:53 -0400 Subject: [PATCH 4/8] add menu icon to tutorial dropdown --- .../tutorial/[slug]/_components/TableOfContents.svelte | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte b/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte index 4dab3416d8..616738268c 100644 --- a/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte +++ b/site/src/routes/tutorial/[slug]/_components/TableOfContents.svelte @@ -28,7 +28,7 @@ a { display: block; - padding: 0.7em 0; + padding: 0.75em 0; text-align: center; opacity: 0.7; } @@ -64,7 +64,13 @@
- {selected.section.title} / {selected.chapter.title} + + + + {selected.section.title} / + + {selected.chapter.title} +