[WIP] #1748 - Custom elements light dom, open / closed

pull/4330/head
Cris Ward 6 years ago
parent efe8ab9ca5
commit 8cc67854b6

@ -14,7 +14,7 @@ import Stylesheet from './css/Stylesheet';
import { test } from '../config';
import Fragment from './nodes/Fragment';
import internal_exports from './internal_exports';
import { Ast, CompileOptions, Var, Warning, CssResult } from '../interfaces';
import { Ast, CompileOptions, Var, Warning, CssResult, ShadowDomMode } from '../interfaces';
import error from '../utils/error';
import get_code_frame from '../utils/get_code_frame';
import flatten_reference from './utils/flatten_reference';
@ -30,6 +30,7 @@ import check_graph_for_cycles from './utils/check_graph_for_cycles';
import { print, x, b } from 'code-red';
interface ComponentOptions {
shadowdom?: ShadowDomMode;
namespace?: string;
tag?: string;
immutable?: boolean;
@ -158,6 +159,7 @@ export default class Component {
});
}
this.tag = this.component_options.tag || compile_options.tag;
this.compile_options.shadowDom = this.component_options.shadowdom || "open";
} else {
this.tag = this.name.name;
}
@ -170,7 +172,7 @@ export default class Component {
this.walk_instance_js_post_template();
if (!compile_options.customElement) this.stylesheet.reify();
if (!compile_options.customElement || compile_options.shadowDom=="none") this.stylesheet.reify();
this.stylesheet.warn_on_unused_selectors(this);
}
@ -1414,7 +1416,16 @@ function process_component_options(component: Component, nodes) {
component_options[name] = value;
break;
}
case 'shadowdom':{
const code = 'invalid-shadowdom-attribute';
const message = `'shadowdom' must be set to 'open', 'closed or 'none'`;
const value = get_value(attribute, code, message)
if(value != "open" && value != "none" && value != "closed")
component.error(attribute, { code, message });
component_options[name] = value;
break;
}
default:
component.error(attribute, {
code: `invalid-options-attribute`,

@ -22,6 +22,7 @@ const valid_options = [
'hydratable',
'legacy',
'customElement',
'shadowDom',
'tag',
'css',
'loopGuardTimeout',

@ -20,7 +20,7 @@ export default function dom(
block.has_outro_method = true;
// prevent fragment being created twice (#1063)
if (options.customElement) block.chunks.create.push(b`this.c = @noop;`);
if (options.customElement && options.shadowDom !== "none") block.chunks.create.push(b`this.c = @noop;`);
const body = [];
@ -29,7 +29,7 @@ export default function dom(
body.push(b`const ${renderer.file_var} = ${file};`);
}
const css = component.stylesheet.render(options.filename, !options.customElement);
const css = component.stylesheet.render(options.filename, (!options.customElement || options.shadowDom === "none"));
const styles = component.stylesheet.has_styles && options.dev
? `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */`
: css.code;
@ -37,9 +37,9 @@ export default function dom(
const add_css = component.get_unique_name('add_css');
const should_add_css = (
!options.customElement &&
(!options.customElement &&
!!styles &&
options.css !== false
options.css !== false ) || options.shadowDom === "none"
);
if (should_add_css) {
@ -437,14 +437,19 @@ export default function dom(
}
if (options.customElement) {
const lightDom = options.shadowDom === 'none';
const declaration = b`
class ${name} extends @SvelteElement {
constructor(options) {
super();
${!lightDom && b`
this._root =this.attachShadow({ mode: '${options.shadowDom}' });
`}
${css.code && b`this.shadowRoot.innerHTML = \`<style>${css.code.replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
${css.code && !lightDom && b`this._root.innerHTML = \`<style>${css.code.replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
${should_add_css && lightDom && b`if (!@_document.getElementById("${component.stylesheet.id}-style")) ${add_css}();`}
@init(this, { target: this.shadowRoot }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty});
@init(this, { target: ${lightDom ? 'this' : 'this._root'} }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty});
${dev_props_check}

@ -120,6 +120,7 @@ export interface CompileOptions {
hydratable?: boolean;
legacy?: boolean;
customElement?: boolean;
shadowDom?: ShadowDomMode;
tag?: string;
css?: boolean;
loopGuardTimeout?: number;
@ -166,4 +167,8 @@ export interface Var {
export interface CssResult {
code: string;
map: SourceMap;
}
}
export type ShadowDomMode = 'none'
| 'open'
| 'closed'

@ -167,7 +167,6 @@ if (typeof HTMLElement === 'function') {
$$: T$$;
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {

@ -33,6 +33,7 @@ function create_fragment(ctx) {
class Component extends SvelteElement {
constructor(options) {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.innerHTML = `<style>div{animation:foo 1s}@keyframes foo{0%{opacity:0}100%{opacity:1}}</style>`;
init(this, { target: this.shadowRoot }, null, create_fragment, safe_not_equal, {});

Loading…
Cancel
Save