From 7836f409aac8a3dc0bca42f1ecc3fc0241c90bff Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 17 Aug 2019 00:24:12 -0400 Subject: [PATCH] support is attribute, with a warning - fixes #3182 --- src/compiler/compile/nodes/Element.ts | 7 +++++++ .../render_dom/wrappers/Element/index.ts | 5 +++++ src/runtime/internal/dom.ts | 4 ++++ .../samples/extended-builtin/_config.js | 17 +++++++++++++++++ .../samples/extended-builtin/fancy-button.js | 2 ++ .../samples/extended-builtin/main.svelte | 7 +++++++ .../samples/extended-builtin/test.js | 15 +++++++++++++++ 7 files changed, 57 insertions(+) create mode 100644 test/custom-elements/samples/extended-builtin/_config.js create mode 100644 test/custom-elements/samples/extended-builtin/fancy-button.js create mode 100644 test/custom-elements/samples/extended-builtin/main.svelte create mode 100644 test/custom-elements/samples/extended-builtin/test.js diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index e08e1f963d..593f303a2f 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -415,6 +415,13 @@ export default class Element extends Node { } } + if (name === 'is') { + component.warn(attribute, { + code: 'avoid-is', + message: `The 'is' attribute is not supported cross-browser and should be avoided` + }); + } + attribute_map.set(attribute.name, attribute); }); diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 7480c31cc7..1d1729c18c 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -383,6 +383,11 @@ export default class ElementWrapper extends Wrapper { return `@_document.createElementNS("${namespace}", "${name}")`; } + const is = this.attributes.find(attr => attr.node.name === 'is'); + if (is) { + return `@element_is("${name}", ${is.render_chunks().join(' + ')});` + } + return `@element("${name}")`; } diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 25c804ff34..a918c3193d 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -20,6 +20,10 @@ export function element(name: K) { return document.createElement(name); } +export function element_is(name: K, is: string) { + return document.createElement(name, { is }); +} + export function object_without_properties(obj: T, exclude: K[]) { // eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion const target = {} as Pick>; diff --git a/test/custom-elements/samples/extended-builtin/_config.js b/test/custom-elements/samples/extended-builtin/_config.js new file mode 100644 index 0000000000..08580e780a --- /dev/null +++ b/test/custom-elements/samples/extended-builtin/_config.js @@ -0,0 +1,17 @@ +export default { + warnings: [{ + code: "avoid-is", + message: "The 'is' attribute is not supported cross-browser and should be avoided", + pos: 97, + start: { + character: 97, + column: 8, + line: 7 + }, + end: { + character: 114, + column: 25, + line: 7 + } + }] +}; diff --git a/test/custom-elements/samples/extended-builtin/fancy-button.js b/test/custom-elements/samples/extended-builtin/fancy-button.js new file mode 100644 index 0000000000..eaa7d84135 --- /dev/null +++ b/test/custom-elements/samples/extended-builtin/fancy-button.js @@ -0,0 +1,2 @@ +class FancyButton extends HTMLButtonElement {} +customElements.define('fancy-button', FancyButton, { extends: 'button' }); \ No newline at end of file diff --git a/test/custom-elements/samples/extended-builtin/main.svelte b/test/custom-elements/samples/extended-builtin/main.svelte new file mode 100644 index 0000000000..0919d9585e --- /dev/null +++ b/test/custom-elements/samples/extended-builtin/main.svelte @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/test/custom-elements/samples/extended-builtin/test.js b/test/custom-elements/samples/extended-builtin/test.js new file mode 100644 index 0000000000..d676fd137b --- /dev/null +++ b/test/custom-elements/samples/extended-builtin/test.js @@ -0,0 +1,15 @@ +import * as assert from 'assert'; +import CustomElement from './main.svelte'; + +export default function (target) { + new CustomElement({ + target + }); + + assert.equal(target.innerHTML, ''); + + const el = target.querySelector('custom-element'); + const button = el.shadowRoot.querySelector('button'); + + assert.ok(button instanceof customElements.get('fancy-button')); +} \ No newline at end of file