All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.polyfill-support.js.map Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
{"version":3,"file":"polyfill-support.js","sources":["../reactive-element/src/polyfill-support.ts","../lit-html/src/polyfill-support.ts","src/polyfill-support.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * ReactiveElement patch to support browsers without native web components.\n *\n * This module should be used in addition to loading the web components\n * polyfills via @webcomponents/webcomponentjs. When using those polyfills\n * support for polyfilled Shadow DOM is automatic via the ShadyDOM polyfill, but\n * support for Shadow DOM like css scoping is opt-in. This module uses ShadyCSS\n * to scope styles defined via the `static styles` property.\n *\n * @packageDocumentation\n */\n\nexport {};\n\ninterface RenderOptions {\n  readonly renderBefore?: ChildNode | null;\n  scope?: string;\n}\n\nconst SCOPED = '__scoped';\n\ntype CSSResults = Array<{cssText: string} | CSSStyleSheet>;\n\ninterface PatchableReactiveElementConstructor {\n  [SCOPED]: boolean;\n  elementStyles: CSSResults;\n  shadowRootOptions: ShadowRootInit;\n  _$handlesPrepareStyles?: boolean;\n}\n\ninterface PatchableReactiveElement extends HTMLElement {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-misused-new\n  new (...args: any[]): PatchableReactiveElement;\n  constructor: PatchableReactiveElementConstructor;\n  connectedCallback(): void;\n  hasUpdated: boolean;\n  _$didUpdate(changedProperties: unknown): void;\n  createRenderRoot(): Element | ShadowRoot;\n  renderOptions: RenderOptions;\n}\n\n// Note, explicitly use `var` here so that this can be re-defined when\n// bundled.\n// eslint-disable-next-line no-var\nvar DEV_MODE = true;\n\nconst polyfillSupport = ({\n  ReactiveElement,\n}: {\n  ReactiveElement: PatchableReactiveElement;\n}) => {\n  // polyfill-support is only needed if ShadyCSS or the ApplyShim is in use\n  // We test at the point of patching, which makes it safe to load\n  // webcomponentsjs and polyfill-support in either order\n  if (\n    window.ShadyCSS === undefined ||\n    (window.ShadyCSS.nativeShadow && !window.ShadyCSS.ApplyShim)\n  ) {\n    return;\n  }\n\n  // console.log(\n  //   '%c Making ReactiveElement compatible with ShadyDOM/CSS.',\n  //   'color: lightgreen; font-style: italic'\n  // );\n\n  const elementProto = ReactiveElement.prototype;\n\n  // In noPatch mode, patch the ReactiveElement prototype so that no\n  // ReactiveElements must be wrapped.\n  if (\n    window.ShadyDOM &&\n    window.ShadyDOM.inUse &&\n    window.ShadyDOM.noPatch === true\n  ) {\n    window.ShadyDOM.patchElementProto(elementProto);\n  }\n\n  /**\n   * Patch to apply adoptedStyleSheets via ShadyCSS\n   */\n  const createRenderRoot = elementProto.createRenderRoot;\n  elementProto.createRenderRoot = function (this: PatchableReactiveElement) {\n    // Pass the scope to render options so that it gets to lit-html for proper\n    // scoping via ShadyCSS.\n    const name = this.localName;\n    // If using native Shadow DOM must adoptStyles normally,\n    // otherwise do nothing.\n    if (window.ShadyCSS!.nativeShadow) {\n      return createRenderRoot.call(this);\n    } else {\n      if (!this.constructor.hasOwnProperty(SCOPED)) {\n        (this.constructor as PatchableReactiveElementConstructor)[SCOPED] =\n          true;\n        // Use ShadyCSS's `prepareAdoptedCssText` to shim adoptedStyleSheets.\n        const css = (\n          this.constructor as PatchableReactiveElementConstructor\n        ).elementStyles.map((v) =>\n          v instanceof CSSStyleSheet\n            ? Array.from(v.cssRules).reduce(\n                (a: string, r: CSSRule) => (a += r.cssText),\n                ''\n              )\n            : v.cssText\n        );\n        window.ShadyCSS?.ScopingShim?.prepareAdoptedCssText(css, name);\n        if (this.constructor._$handlesPrepareStyles === undefined) {\n          window.ShadyCSS!.prepareTemplateStyles(\n            document.createElement('template'),\n            name\n          );\n        }\n      }\n      return (\n        this.shadowRoot ??\n        this.attachShadow(\n          (this.constructor as PatchableReactiveElementConstructor)\n            .shadowRootOptions\n        )\n      );\n    }\n  };\n\n  /**\n   * Patch connectedCallback to apply ShadyCSS custom properties shimming.\n   */\n  const connectedCallback = elementProto.connectedCallback;\n  elementProto.connectedCallback = function (this: PatchableReactiveElement) {\n    connectedCallback.call(this);\n    // Note, must do first update separately so that we're ensured\n    // that rendering has completed before calling this.\n    if (this.hasUpdated) {\n      window.ShadyCSS!.styleElement(this);\n    }\n  };\n\n  /**\n   * Patch update to apply ShadyCSS custom properties shimming for first\n   * update.\n   */\n  const didUpdate = elementProto._$didUpdate;\n  elementProto._$didUpdate = function (\n    this: PatchableReactiveElement,\n    changedProperties: unknown\n  ) {\n    // Note, must do first update here so rendering has completed before\n    // calling this and styles are correct by updated/firstUpdated.\n    if (!this.hasUpdated) {\n      window.ShadyCSS!.styleElement(this);\n    }\n    didUpdate.call(this, changedProperties);\n  };\n};\n\nif (DEV_MODE) {\n  globalThis.reactiveElementPolyfillSupportDevMode ??= polyfillSupport;\n} else {\n  globalThis.reactiveElementPolyfillSupport ??= polyfillSupport;\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * lit-html patch to support browsers without native web components.\n *\n * This module should be used in addition to loading the web components\n * polyfills via @webcomponents/webcomponentjs. When using those polyfills\n * support for polyfilled Shadow DOM is automatic via the ShadyDOM polyfill.\n * Scoping classes are added to DOM nodes to facilitate CSS scoping that\n * simulates the style scoping Shadow DOM provides. ShadyDOM does this scoping\n * to all elements added to the DOM. This module provides an important\n * optimization for this process by pre-scoping lit-html template\n * DOM. This means ShadyDOM does not have to scope each instance of the\n * template DOM. Instead, each template is scoped only once.\n *\n * Creating scoped CSS is not covered by this module. It is, however, integrated\n * into the lit-element and @lit/reactive-element packages. See the ShadyCSS docs\n * for how to apply scoping to CSS:\n * https://github.com/webcomponents/polyfills/tree/master/packages/shadycss#usage.\n *\n * @packageDocumentation\n */\n\nexport {};\n\ninterface RenderOptions {\n  readonly renderBefore?: ChildNode | null;\n  scope?: string;\n}\n\ninterface ShadyTemplateResult {\n  strings: TemplateStringsArray;\n  // This property needs to remain unminified.\n  ['_$litType$']?: string;\n}\n\n// Note, this is a dummy type as the full type here is big.\ninterface Directive {\n  __directive?: Directive;\n}\n\ninterface DirectiveParent {\n  _$parent?: DirectiveParent;\n  __directive?: Directive;\n  __directives?: Array;\n}\n\ninterface PatchableChildPartConstructor {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-misused-new\n  new (...args: any[]): PatchableChildPart;\n}\n\ninterface PatchableChildPart {\n  __directive?: Directive;\n  _$committedValue: unknown;\n  _$startNode: ChildNode;\n  _$endNode: ChildNode | null;\n  options: RenderOptions;\n  _$setValue(value: unknown, directiveParent: DirectiveParent): void;\n  _$getTemplate(result: ShadyTemplateResult): HTMLTemplateElement;\n}\n\ninterface PatchableTemplate {\n  el: HTMLTemplateElement;\n}\n\ninterface PatchableTemplateConstructor {\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-misused-new\n  new (...args: any[]): PatchableTemplate;\n  createElement(html: string, options?: RenderOptions): HTMLTemplateElement;\n}\n\ninterface PatchableTemplateInstance {\n  _$template: PatchableTemplate;\n}\n\n// Scopes that have had styling prepared. Note, must only be done once per\n// scope.\nconst styledScopes = new Set();\n// Map of css per scope. This is collected during first scope render, used when\n// styling is prepared, and then discarded.\nconst scopeCssStore = new Map();\n\nconst ENABLE_SHADYDOM_NOPATCH = true;\n\n// Note, explicitly use `var` here so that this can be re-defined when\n// bundled.\n// eslint-disable-next-line no-var\nvar DEV_MODE = true;\n\n/**\n * lit-html patches. These properties cannot be renamed.\n * * ChildPart.prototype._$getTemplate\n * * ChildPart.prototype._$setValue\n */\nconst polyfillSupport: NonNullable = (\n  Template: PatchableTemplateConstructor,\n  ChildPart: PatchableChildPartConstructor,\n) => {\n  // polyfill-support is only needed if ShadyCSS or the ApplyShim is in use\n  // We test at the point of patching, which makes it safe to load\n  // webcomponentsjs and polyfill-support in either order\n  if (\n    window.ShadyCSS === undefined ||\n    (window.ShadyCSS.nativeShadow && !window.ShadyCSS.ApplyShim)\n  ) {\n    return;\n  }\n\n  // console.log(\n  //   '%c Making lit-html compatible with ShadyDOM/CSS.',\n  //   'color: lightgreen; font-style: italic'\n  // );\n\n  const wrap =\n    ENABLE_SHADYDOM_NOPATCH &&\n    window.ShadyDOM?.inUse &&\n    window.ShadyDOM?.noPatch === true\n      ? window.ShadyDOM!.wrap\n      : (node: Node) => node;\n\n  const needsPrepareStyles = (name: string | undefined) =>\n    name !== undefined && !styledScopes.has(name);\n\n  const cssForScope = (name: string) => {\n    let scopeCss = scopeCssStore.get(name);\n    if (scopeCss === undefined) {\n      scopeCssStore.set(name, (scopeCss = []));\n    }\n    return scopeCss;\n  };\n\n  const prepareStyles = (name: string, template: HTMLTemplateElement) => {\n    // Get styles\n    const scopeCss = cssForScope(name);\n    const hasScopeCss = scopeCss.length !== 0;\n    if (hasScopeCss) {\n      const style = document.createElement('style');\n      style.textContent = scopeCss.join('\\n');\n      // Note, it's important to add the style to the *end* of the template so\n      // it doesn't mess up part indices.\n      template.content.appendChild(style);\n    }\n    // Mark this scope as styled.\n    styledScopes.add(name);\n    // Remove stored data since it's no longer needed.\n    scopeCssStore.delete(name);\n    // ShadyCSS removes scopes and removes the style under ShadyDOM and leaves\n    // it under native Shadow DOM\n    window.ShadyCSS!.prepareTemplateStyles(template, name);\n    // Note, under native Shadow DOM, the style is added to the beginning of the\n    // template. It must be moved to the *end* of the template so it doesn't\n    // mess up part indices.\n    if (hasScopeCss && window.ShadyCSS!.nativeShadow) {\n      // If there were styles but the CSS text was empty, ShadyCSS will\n      // eliminate the style altogether, so the style here could be null\n      const style = template.content.querySelector('style');\n      if (style !== null) {\n        template.content.appendChild(style);\n      }\n    }\n  };\n\n  const scopedTemplateCache = new Map<\n    string | undefined,\n    Map\n  >();\n\n  /**\n   * Override to extract style elements from the template\n   * and store all style.textContent in the shady scope data.\n   * Note, it's ok to patch Template since it's only used via ChildPart.\n   */\n  const originalCreateElement = Template.createElement;\n  Template.createElement = function (html: string, options?: RenderOptions) {\n    const element = originalCreateElement.call(Template, html, options);\n    const scope = options?.scope;\n    if (scope !== undefined) {\n      if (!window.ShadyCSS!.nativeShadow) {\n        window.ShadyCSS!.prepareTemplateDom(element, scope);\n      }\n      // Process styles only if this scope is being prepared. Otherwise,\n      // leave styles as is for back compat with Lit1.\n      if (needsPrepareStyles(scope)) {\n        const scopeCss = cssForScope(scope);\n        // Remove styles and store textContent.\n        const styles = element.content.querySelectorAll(\n          'style',\n        ) as NodeListOf;\n        // Store the css in this template in the scope css and remove the