From 21e5aef321b9ef799a9b748245e3504f18581cb0 Mon Sep 17 00:00:00 2001 From: Niz Kuo Date: Sat, 3 Sep 2022 22:09:47 +0800 Subject: [PATCH] #69: Add observer for detecting head attribute mutation. --- dist/index.bundle.js | 20 ++- index.html | 4 +- packages/w-components/WComponent.js | 8 ++ packages/w-components/components/Code.js | 152 +++++++++++++++++++++-- packages/w-components/index.js | 25 +--- packages/w-components/util/DOM.js | 2 + packages/w-components/util/Theme.js | 52 ++++++++ 7 files changed, 228 insertions(+), 35 deletions(-) create mode 100644 packages/w-components/util/Theme.js diff --git a/dist/index.bundle.js b/dist/index.bundle.js index 28b0fe3..44c1508 100644 --- a/dist/index.bundle.js +++ b/dist/index.bundle.js @@ -374,7 +374,7 @@ eval("module.exports = __webpack_require__.p + \"assets/icon-font.ttf\";\n\n//# \*********************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getWTagName\": () => (/* binding */ getWTagName),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _util_DOM_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/DOM.js */ \"./packages/w-components/util/DOM.js\");\n\n\nclass WComponent extends HTMLElement{\n /**\n * Get observed attributes array by parsing attribute object\n * @param {Object} attrs - Class field attributes\n * @returns {Array} Array of observed attribute names\n */\n static getObservedAttributes(attrs) {\n const observedAttrs = Object.keys(attrs)\n .filter(key => attrs[key].observed !== false) // Default observed\n .map(key => attrs[key].name);\n return Array.isArray(observedAttrs) ? observedAttrs : [];\n }\n\n constructor(){\n super();\n this.createGettersAndSetters();\n this.attachShadow({ mode: 'open' });\n this.setStylesheet(this.stylesheet);\n this.init();\n this.key = new Date().getTime() + Math.random();\n }\n /**\n * Call update method in attribute changed callback if:\n * 1. The component is initialized (key is valid.)\n * 2. The attribute is defined in the component static field 'attributes'.\n */\n attributeChangedCallback(name, oldValue, newValue){\n if(oldValue !== newValue && this.key && this.hasDefinedAttribute(name)){\n this.update({name, oldValue, newValue});\n }\n }\n /**\n * Dynamically create getters & setters for property-attribute sync \n * by parsing class field attribute object.\n */\n createGettersAndSetters() {\n if(!Array.isArray(this.constructor.observedAttributes)) {\n return;\n }\n this.constructor.observedAttributes.forEach(attrName => {\n Object.defineProperty(this, attrName, {\n get: () => this.parseAttributeValueByName(attrName, this.getAttribute(attrName)),\n set: value => {\n this.setAttribute(attrName, this.parseAttributeValueByName(attrName, `${value}`));\n }\n });\n });\n }\n equals(component) {\n return this.key === component.key;\n }\n getAttributeParserByName(name) {\n if(typeof name !== 'string') {\n return undefined;\n }\n if(typeof this.constructor.attributes[name].parser !== 'function') {\n // Default parser: return value as is.\n return value => {\n if(typeof value === 'string') {\n return value;\n } else {\n return this.constructor.attributes[name].defaultValue;\n }\n };\n }\n return this.constructor.attributes[name].parser;\n }\n getDefaultAttributeValueByName(name) {\n if(typeof name !== 'string') {\n return undefined;\n }\n return this.constructor.attributes[name].defaultValue;\n }\n hasDefinedAttribute(name) {\n return typeof name === 'string' && typeof this.constructor.attributes[name] === 'object';\n }\n parseAttributeValueByName(name, value) {\n return this.getAttributeParserByName(name)(value, this.constructor.attributes[name]);\n }\n setStylesheet(stylesheet, id){ // id is optional, for style overwrite\n if(id){\n id=`w-stylesheet-${id}`;\n const styleElement=this.shadowRoot.querySelector(`#${id}`);\n if(styleElement){\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].modify(styleElement, { props: { textContent: stylesheet } });\n }else{\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].create('style', { props: { textContent: stylesheet, id:id } }, this.shadowRoot);\n }\n }else{\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].create('style', { props: { textContent: stylesheet } }, this.shadowRoot);\n }\n }\n /**\n * Life cycle hooker meant to be overridden.\n */\n update(){}\n\n}\n\nfunction getWTagName(tag) { \n let prefix = 'w';\n if(window.wconfig && typeof window.wconfig.prefix === 'string') {\n prefix = window.wconfig.prefix;\n }\n return `${prefix}-${tag}`; \n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (WComponent);\n\n\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/WComponent.js?"); +eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getWTagName\": () => (/* binding */ getWTagName),\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _util_DOM_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/DOM.js */ \"./packages/w-components/util/DOM.js\");\n/* harmony import */ var _util_Theme_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/Theme.js */ \"./packages/w-components/util/Theme.js\");\n\n\n\nclass WComponent extends HTMLElement{\n /**\n * Get observed attributes array by parsing attribute object\n * @param {Object} attrs - Class field attributes\n * @returns {Array} Array of observed attribute names\n */\n static getObservedAttributes(attrs) {\n const observedAttrs = Object.keys(attrs)\n .filter(key => attrs[key].observed !== false) // Default observed\n .map(key => attrs[key].name);\n return Array.isArray(observedAttrs) ? observedAttrs : [];\n }\n\n constructor(){\n super();\n this.createGettersAndSetters();\n this.attachShadow({ mode: 'open' });\n this.setStylesheet(this.stylesheet);\n this.init();\n this.key = new Date().getTime() + Math.random();\n }\n /**\n * Call update method in attribute changed callback if:\n * 1. The component is initialized (key is valid.)\n * 2. The attribute is defined in the component static field 'attributes'.\n */\n attributeChangedCallback(name, oldValue, newValue){\n if(oldValue !== newValue && this.key && this.hasDefinedAttribute(name)){\n this.update({name, oldValue, newValue});\n }\n }\n /**\n * Create & bind observer on head style theme changed.\n * @param {function} callback \n */\n bindThemeChangedObserver(callback) {\n _util_Theme_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].bindChangedObserver(callback);\n }\n /**\n * Dynamically create getters & setters for property-attribute sync \n * by parsing class field attribute object.\n */\n createGettersAndSetters() {\n if(!Array.isArray(this.constructor.observedAttributes)) {\n return;\n }\n this.constructor.observedAttributes.forEach(attrName => {\n Object.defineProperty(this, attrName, {\n get: () => this.parseAttributeValueByName(attrName, this.getAttribute(attrName)),\n set: value => {\n this.setAttribute(attrName, this.parseAttributeValueByName(attrName, `${value}`));\n }\n });\n });\n }\n equals(component) {\n return this.key === component.key;\n }\n getAttributeParserByName(name) {\n if(typeof name !== 'string') {\n return undefined;\n }\n if(typeof this.constructor.attributes[name].parser !== 'function') {\n // Default parser: return value as is.\n return value => {\n if(typeof value === 'string') {\n return value;\n } else {\n return this.constructor.attributes[name].defaultValue;\n }\n };\n }\n return this.constructor.attributes[name].parser;\n }\n getDefaultAttributeValueByName(name) {\n if(typeof name !== 'string') {\n return undefined;\n }\n return this.constructor.attributes[name].defaultValue;\n }\n hasDefinedAttribute(name) {\n return typeof name === 'string' && typeof this.constructor.attributes[name] === 'object';\n }\n parseAttributeValueByName(name, value) {\n return this.getAttributeParserByName(name)(value, this.constructor.attributes[name]);\n }\n setStylesheet(stylesheet, id){ // id is optional, for style overwrite\n if(id){\n id=`w-stylesheet-${id}`;\n const styleElement=this.shadowRoot.querySelector(`#${id}`);\n if(styleElement){\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].modify(styleElement, { props: { textContent: stylesheet } });\n }else{\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].create('style', { props: { textContent: stylesheet, id:id } }, this.shadowRoot);\n }\n }else{\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].create('style', { props: { textContent: stylesheet } }, this.shadowRoot);\n }\n }\n /**\n * Life cycle hooker meant to be overridden.\n */\n update(){}\n\n}\n\nfunction getWTagName(tag) { \n let prefix = 'w';\n if(window.wconfig && typeof window.wconfig.prefix === 'string') {\n prefix = window.wconfig.prefix;\n }\n return `${prefix}-${tag}`; \n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (WComponent);\n\n\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/WComponent.js?"); /***/ }), @@ -404,7 +404,7 @@ eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harm \**************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _WComponent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../WComponent.js */ \"./packages/w-components/WComponent.js\");\n/* harmony import */ var _WComponent_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../WComponent.js */ \"./packages/w-components/util/AttributeParser.js\");\n/* harmony import */ var _WComponent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../WComponent.js */ \"./packages/w-components/util/DOM.js\");\n\n\nconst stylesheet = `\n /*!\n Theme: GitHub\n Description: Light theme as seen on github.com\n Author: github.com\n Maintainer: @Hirse\n Updated: 2021-05-15\n Outdated base version: https://github.com/primer/github-syntax-light\n Current colors taken from GitHub's CSS\n */\n\n .hljs {\n color: #24292e;\n background: #ffffff;\n }\n\n .hljs-doctag,\n .hljs-keyword,\n .hljs-meta .hljs-keyword,\n .hljs-template-tag,\n .hljs-template-variable,\n .hljs-type,\n .hljs-variable.language_ {\n /* prettylights-syntax-keyword */\n color: #d73a49;\n }\n\n .hljs-title,\n .hljs-title.class_,\n .hljs-title.class_.inherited__,\n .hljs-title.function_ {\n /* prettylights-syntax-entity */\n color: #6f42c1;\n }\n\n .hljs-attr,\n .hljs-attribute,\n .hljs-literal,\n .hljs-meta,\n .hljs-number,\n .hljs-operator,\n .hljs-variable,\n .hljs-selector-attr,\n .hljs-selector-class,\n .hljs-selector-id {\n /* prettylights-syntax-constant */\n color: #005cc5;\n }\n\n .hljs-regexp,\n .hljs-string,\n .hljs-meta .hljs-string {\n /* prettylights-syntax-string */\n color: #032f62;\n }\n\n .hljs-built_in,\n .hljs-symbol {\n /* prettylights-syntax-variable */\n color: #e36209;\n }\n\n .hljs-comment,\n .hljs-code,\n .hljs-formula {\n /* prettylights-syntax-comment */\n color: #6a737d;\n }\n\n .hljs-name,\n .hljs-quote,\n .hljs-selector-tag,\n .hljs-selector-pseudo {\n /* prettylights-syntax-entity-tag */\n color: #22863a;\n }\n\n .hljs-subst {\n /* prettylights-syntax-storage-modifier-import */\n color: #24292e;\n }\n\n .hljs-section {\n /* prettylights-syntax-markup-heading */\n color: #005cc5;\n font-weight: bold;\n }\n\n .hljs-bullet {\n /* prettylights-syntax-markup-list */\n color: #735c0f;\n }\n\n .hljs-emphasis {\n /* prettylights-syntax-markup-italic */\n color: #24292e;\n font-style: italic;\n }\n\n .hljs-strong {\n /* prettylights-syntax-markup-bold */\n color: #24292e;\n font-weight: bold;\n }\n\n .hljs-addition {\n /* prettylights-syntax-markup-inserted */\n color: #22863a;\n background-color: #f0fff4;\n }\n\n .hljs-deletion {\n /* prettylights-syntax-markup-deleted */\n color: #b31d28;\n background-color: #ffeef0;\n }\n\n .hljs-char.escape_,\n .hljs-link,\n .hljs-params,\n .hljs-property,\n .hljs-punctuation,\n .hljs-tag {\n /* purposely ignored */\n }\n\n :host {\n display: block;\n color: var(--color-gray-80);\n background-color: var(--color-gray-10);\n border-radius: 4px;\n padding: 20px;\n white-space: pre-wrap;\n }\n`;\nclass Code extends _WComponent_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]{\n static title = 'Code';\n static description = 'Code with rich colors.';\n static tagName = 'code';\n static attributes = {\n lang: {\n name: 'lang', defaultValue: 'auto',\n possibleValues: '[Language Name]',\n parser: (value, attr) => _WComponent_js__WEBPACK_IMPORTED_MODULE_1__.parseStringAttr(\n value, attr.defaultValue, /^(?!\\s*$).+/ // Non-empty string\n )\n }\n };\n static methods = null;\n static childComponents = null;\n static get observedAttributes() {\n return this.getObservedAttributes(this.attributes);\n }\n\n constructor(){\n super();\n this.bindObserver();\n }\n \n bindObserver() {\n // Observe code content change\n const observer = new MutationObserver(this.loadHighlightContent.bind(this)); \n observer.observe(this, { childList: true });\n }\n\n init() {\n _WComponent_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create('code', { props: { id: 'code' } }, this.shadowRoot);\n __webpack_require__.e(/*! import() */ \"vendors-node_modules_highlight_js_es_index_js\").then(__webpack_require__.bind(__webpack_require__, /*! highlight.js */ \"./node_modules/highlight.js/es/index.js\"))\n .then(module => {\n hljs = module.default;\n this.loadHighlightContent();\n });\n }\n\n loadHighlightContent() {\n if(!hljs) { return; }\n\n const highlightHTML = this.lang === this.getDefaultAttributeValueByName('lang')\n ? hljs.highlightAuto(this.innerHTML).value // auto detect\n : hljs.highlight(this.innerHTML, { language: this.lang }).value; // assign language\n \n this.shadowRoot.querySelector('#code').innerHTML = highlightHTML;\n }\n \n update({ name, newValue }) {\n this.parseAttributeValueByName(name, newValue);\n this.loadHighlightContent();\n }\n}\nCode.prototype.stylesheet=stylesheet;\n\nlet hljs;\n_WComponent_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].defineCustomElement(Code);\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Code);\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/components/Code.js?"); +eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _WComponent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../WComponent.js */ \"./packages/w-components/WComponent.js\");\n/* harmony import */ var _WComponent_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../WComponent.js */ \"./packages/w-components/util/AttributeParser.js\");\n/* harmony import */ var _WComponent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../WComponent.js */ \"./packages/w-components/util/DOM.js\");\n/* harmony import */ var _util_Theme_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/Theme.js */ \"./packages/w-components/util/Theme.js\");\n\n\n\nconst stylesheet = `\n :host {\n display: block;\n color: var(--color-gray-80);\n background-color: var(--color-gray-10);\n border-radius: 4px;\n padding: 20px;\n white-space: pre-wrap;\n }\n`;\nconst lightThemeStylesheet = `\n /*!\n Theme: GitHub\n Description: Light theme as seen on github.com\n Author: github.com\n Maintainer: @Hirse\n Updated: 2021-05-15\n Outdated base version: https://github.com/primer/github-syntax-light\n Current colors taken from GitHub's CSS\n */\n\n .hljs {\n color: #24292e;\n background: #ffffff;\n }\n\n .hljs-doctag,\n .hljs-keyword,\n .hljs-meta .hljs-keyword,\n .hljs-template-tag,\n .hljs-template-variable,\n .hljs-type,\n .hljs-variable.language_ {\n /* prettylights-syntax-keyword */\n color: #d73a49;\n }\n\n .hljs-title,\n .hljs-title.class_,\n .hljs-title.class_.inherited__,\n .hljs-title.function_ {\n /* prettylights-syntax-entity */\n color: #6f42c1;\n }\n\n .hljs-attr,\n .hljs-attribute,\n .hljs-literal,\n .hljs-meta,\n .hljs-number,\n .hljs-operator,\n .hljs-variable,\n .hljs-selector-attr,\n .hljs-selector-class,\n .hljs-selector-id {\n /* prettylights-syntax-constant */\n color: #005cc5;\n }\n\n .hljs-regexp,\n .hljs-string,\n .hljs-meta .hljs-string {\n /* prettylights-syntax-string */\n color: #032f62;\n }\n\n .hljs-built_in,\n .hljs-symbol {\n /* prettylights-syntax-variable */\n color: #e36209;\n }\n\n .hljs-comment,\n .hljs-code,\n .hljs-formula {\n /* prettylights-syntax-comment */\n color: #6a737d;\n }\n\n .hljs-name,\n .hljs-quote,\n .hljs-selector-tag,\n .hljs-selector-pseudo {\n /* prettylights-syntax-entity-tag */\n color: #22863a;\n }\n\n .hljs-subst {\n /* prettylights-syntax-storage-modifier-import */\n color: #24292e;\n }\n\n .hljs-section {\n /* prettylights-syntax-markup-heading */\n color: #005cc5;\n font-weight: bold;\n }\n\n .hljs-bullet {\n /* prettylights-syntax-markup-list */\n color: #735c0f;\n }\n\n .hljs-emphasis {\n /* prettylights-syntax-markup-italic */\n color: #24292e;\n font-style: italic;\n }\n\n .hljs-strong {\n /* prettylights-syntax-markup-bold */\n color: #24292e;\n font-weight: bold;\n }\n\n .hljs-addition {\n /* prettylights-syntax-markup-inserted */\n color: #22863a;\n background-color: #f0fff4;\n }\n\n .hljs-deletion {\n /* prettylights-syntax-markup-deleted */\n color: #b31d28;\n background-color: #ffeef0;\n }\n\n .hljs-char.escape_,\n .hljs-link,\n .hljs-params,\n .hljs-property,\n .hljs-punctuation,\n .hljs-tag {\n /* purposely ignored */\n }\n`;\nconst darkThemeStylesheet = `\n /*!\n Theme: GitHub Dark\n Description: Dark theme as seen on github.com\n Author: github.com\n Maintainer: @Hirse\n Updated: 2021-05-15\n Outdated base version: https://github.com/primer/github-syntax-dark\n Current colors taken from GitHub's CSS\n */\n\n .hljs {\n color: #c9d1d9;\n background: #0d1117;\n }\n\n .hljs-doctag,\n .hljs-keyword,\n .hljs-meta .hljs-keyword,\n .hljs-template-tag,\n .hljs-template-variable,\n .hljs-type,\n .hljs-variable.language_ {\n /* prettylights-syntax-keyword */\n color: #ff7b72;\n }\n\n .hljs-title,\n .hljs-title.class_,\n .hljs-title.class_.inherited__,\n .hljs-title.function_ {\n /* prettylights-syntax-entity */\n color: #d2a8ff;\n }\n\n .hljs-attr,\n .hljs-attribute,\n .hljs-literal,\n .hljs-meta,\n .hljs-number,\n .hljs-operator,\n .hljs-variable,\n .hljs-selector-attr,\n .hljs-selector-class,\n .hljs-selector-id {\n /* prettylights-syntax-constant */\n color: #79c0ff;\n }\n\n .hljs-regexp,\n .hljs-string,\n .hljs-meta .hljs-string {\n /* prettylights-syntax-string */\n color: #a5d6ff;\n }\n\n .hljs-built_in,\n .hljs-symbol {\n /* prettylights-syntax-variable */\n color: #ffa657;\n }\n\n .hljs-comment,\n .hljs-code,\n .hljs-formula {\n /* prettylights-syntax-comment */\n color: #8b949e;\n }\n\n .hljs-name,\n .hljs-quote,\n .hljs-selector-tag,\n .hljs-selector-pseudo {\n /* prettylights-syntax-entity-tag */\n color: #7ee787;\n }\n\n .hljs-subst {\n /* prettylights-syntax-storage-modifier-import */\n color: #c9d1d9;\n }\n\n .hljs-section {\n /* prettylights-syntax-markup-heading */\n color: #1f6feb;\n font-weight: bold;\n }\n\n .hljs-bullet {\n /* prettylights-syntax-markup-list */\n color: #f2cc60;\n }\n\n .hljs-emphasis {\n /* prettylights-syntax-markup-italic */\n color: #c9d1d9;\n font-style: italic;\n }\n\n .hljs-strong {\n /* prettylights-syntax-markup-bold */\n color: #c9d1d9;\n font-weight: bold;\n }\n\n .hljs-addition {\n /* prettylights-syntax-markup-inserted */\n color: #aff5b4;\n background-color: #033a16;\n }\n\n .hljs-deletion {\n /* prettylights-syntax-markup-deleted */\n color: #ffdcd7;\n background-color: #67060c;\n }\n\n .hljs-char.escape_,\n .hljs-link,\n .hljs-params,\n .hljs-property,\n .hljs-punctuation,\n .hljs-tag {\n /* purposely ignored */\n }\n`;\nclass Code extends _WComponent_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]{\n static title = 'Code';\n static description = 'Code with rich colors.';\n static tagName = 'code';\n static attributes = {\n lang: {\n name: 'lang', defaultValue: 'auto',\n possibleValues: '[Language Name]',\n parser: (value, attr) => _WComponent_js__WEBPACK_IMPORTED_MODULE_1__.parseStringAttr(\n value, attr.defaultValue, /^(?!\\s*$).+/ // Non-empty string\n )\n }\n };\n static methods = null;\n static childComponents = null;\n static get observedAttributes() {\n return this.getObservedAttributes(this.attributes);\n }\n\n constructor(){\n super();\n this.bindObserver();\n this.bindThemeChangedObserver(theme => this.setThemeStylesheet(theme));\n }\n \n bindObserver() {\n // Observe code content change\n const observer = new MutationObserver(this.loadHighlightContent.bind(this)); \n observer.observe(this, { childList: true });\n }\n\n init() {\n _WComponent_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create('code', { props: { id: 'code' } }, this.shadowRoot);\n __webpack_require__.e(/*! import() */ \"vendors-node_modules_highlight_js_es_index_js\").then(__webpack_require__.bind(__webpack_require__, /*! highlight.js */ \"./node_modules/highlight.js/es/index.js\"))\n .then(module => {\n hljs = module.default;\n this.loadHighlightContent();\n });\n }\n\n loadHighlightContent() {\n if(!hljs) { return; }\n\n const highlightHTML = this.lang === this.getDefaultAttributeValueByName('lang')\n ? hljs.highlightAuto(this.innerHTML).value // auto detect\n : hljs.highlight(this.innerHTML, { language: this.lang }).value; // assign language\n \n this.shadowRoot.querySelector('#code').innerHTML = highlightHTML;\n }\n \n update({ name, newValue }) {\n this.parseAttributeValueByName(name, newValue);\n this.loadHighlightContent();\n }\n\n setThemeStylesheet(theme) {\n if(theme === _util_Theme_js__WEBPACK_IMPORTED_MODULE_3__.THEME_DARK_NAME) {\n this.setStylesheet(darkThemeStylesheet, 'theme');\n } else {\n this.setStylesheet(lightThemeStylesheet, 'theme');\n }\n this.loadHighlightContent();\n }\n}\nCode.prototype.stylesheet=stylesheet;\n\nlet hljs;\n_WComponent_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].defineCustomElement(Code);\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Code);\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/components/Code.js?"); /***/ }), @@ -724,7 +724,7 @@ eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harm \****************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"AlertDialog\": () => (/* reexport safe */ _components_dialog_AlertDialog_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"]),\n/* harmony export */ \"Button\": () => (/* reexport safe */ _components_button_Button_js__WEBPACK_IMPORTED_MODULE_4__[\"default\"]),\n/* harmony export */ \"Calendar\": () => (/* reexport safe */ _components_Calendar_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"]),\n/* harmony export */ \"Camera\": () => (/* reexport safe */ _components_Camera_js__WEBPACK_IMPORTED_MODULE_6__[\"default\"]),\n/* harmony export */ \"Card\": () => (/* reexport safe */ _components_layout_Card_js__WEBPACK_IMPORTED_MODULE_7__[\"default\"]),\n/* harmony export */ \"CheckBox\": () => (/* reexport safe */ _components_form_checkable_Checkbox_js__WEBPACK_IMPORTED_MODULE_8__[\"default\"]),\n/* harmony export */ \"Code\": () => (/* reexport safe */ _components_Code_js__WEBPACK_IMPORTED_MODULE_9__[\"default\"]),\n/* harmony export */ \"ConfirmDialog\": () => (/* reexport safe */ _components_dialog_ConfirmDialog_js__WEBPACK_IMPORTED_MODULE_10__[\"default\"]),\n/* harmony export */ \"Dialog\": () => (/* reexport safe */ _components_dialog_Dialog_js__WEBPACK_IMPORTED_MODULE_11__[\"default\"]),\n/* harmony export */ \"DisplayHeading\": () => (/* reexport safe */ _components_DisplayHeading_js__WEBPACK_IMPORTED_MODULE_12__[\"default\"]),\n/* harmony export */ \"Form\": () => (/* reexport safe */ _components_form_Form_js__WEBPACK_IMPORTED_MODULE_13__[\"default\"]),\n/* harmony export */ \"Grid\": () => (/* reexport safe */ _components_layout_Grid_js__WEBPACK_IMPORTED_MODULE_14__[\"default\"]),\n/* harmony export */ \"Heading\": () => (/* reexport safe */ _components_Heading_js__WEBPACK_IMPORTED_MODULE_15__[\"default\"]),\n/* harmony export */ \"Hero\": () => (/* reexport safe */ _components_layout_Hero_js__WEBPACK_IMPORTED_MODULE_16__[\"default\"]),\n/* harmony export */ \"Icon\": () => (/* reexport safe */ _components_Icon_js__WEBPACK_IMPORTED_MODULE_17__[\"default\"]),\n/* harmony export */ \"IconButton\": () => (/* reexport safe */ _components_button_IconButton_js__WEBPACK_IMPORTED_MODULE_18__[\"default\"]),\n/* harmony export */ \"List\": () => (/* reexport safe */ _components_List_js__WEBPACK_IMPORTED_MODULE_19__[\"default\"]),\n/* harmony export */ \"ListItem\": () => (/* reexport safe */ _components_ListItem_js__WEBPACK_IMPORTED_MODULE_20__[\"default\"]),\n/* harmony export */ \"Nav\": () => (/* reexport safe */ _components_layout_nav_Nav_js__WEBPACK_IMPORTED_MODULE_21__[\"default\"]),\n/* harmony export */ \"NavPart\": () => (/* reexport safe */ _components_layout_nav_NavPart_js__WEBPACK_IMPORTED_MODULE_22__[\"default\"]),\n/* harmony export */ \"Option\": () => (/* reexport safe */ _components_form_Option_js__WEBPACK_IMPORTED_MODULE_23__[\"default\"]),\n/* harmony export */ \"Quote\": () => (/* reexport safe */ _components_Quote_js__WEBPACK_IMPORTED_MODULE_24__[\"default\"]),\n/* harmony export */ \"Radio\": () => (/* reexport safe */ _components_form_checkable_Radio_js__WEBPACK_IMPORTED_MODULE_25__[\"default\"]),\n/* harmony export */ \"Section\": () => (/* reexport safe */ _components_layout_Section_js__WEBPACK_IMPORTED_MODULE_26__[\"default\"]),\n/* harmony export */ \"Select\": () => (/* reexport safe */ _components_form_Select_js__WEBPACK_IMPORTED_MODULE_27__[\"default\"]),\n/* harmony export */ \"SPALink\": () => (/* reexport safe */ _components_spa_SPALink_js__WEBPACK_IMPORTED_MODULE_28__[\"default\"]),\n/* harmony export */ \"SPAPage\": () => (/* reexport safe */ _components_spa_SPAPage_js__WEBPACK_IMPORTED_MODULE_29__[\"default\"]),\n/* harmony export */ \"SideMenu\": () => (/* reexport safe */ _components_layout_menu_SideMenu_js__WEBPACK_IMPORTED_MODULE_30__[\"default\"]),\n/* harmony export */ \"SideMenuContent\": () => (/* reexport safe */ _components_layout_menu_SideMenuContent_js__WEBPACK_IMPORTED_MODULE_31__[\"default\"]),\n/* harmony export */ \"SideMenuLayout\": () => (/* reexport safe */ _components_layout_menu_SideMenuLayout_js__WEBPACK_IMPORTED_MODULE_32__[\"default\"]),\n/* harmony export */ \"TextInput\": () => (/* reexport safe */ _components_form_TextInput_js__WEBPACK_IMPORTED_MODULE_33__[\"default\"]),\n/* harmony export */ \"TextArea\": () => (/* reexport safe */ _components_form_TextArea_js__WEBPACK_IMPORTED_MODULE_34__[\"default\"]),\n/* harmony export */ \"TypeWriter\": () => (/* reexport safe */ _components_TypeWriter_js__WEBPACK_IMPORTED_MODULE_35__[\"default\"])\n/* harmony export */ });\n/* harmony import */ var _util_DOM_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/DOM.js */ \"./packages/w-components/util/DOM.js\");\n/* harmony import */ var _theme_dark_css_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./theme/dark.css.js */ \"./packages/w-components/theme/dark.css.js\");\n/* harmony import */ var _theme_light_css_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./theme/light.css.js */ \"./packages/w-components/theme/light.css.js\");\n/* harmony import */ var _components_dialog_AlertDialog_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/dialog/AlertDialog.js */ \"./packages/w-components/components/dialog/AlertDialog.js\");\n/* harmony import */ var _components_button_Button_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/button/Button.js */ \"./packages/w-components/components/button/Button.js\");\n/* harmony import */ var _components_Calendar_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/Calendar.js */ \"./packages/w-components/components/Calendar.js\");\n/* harmony import */ var _components_Camera_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/Camera.js */ \"./packages/w-components/components/Camera.js\");\n/* harmony import */ var _components_layout_Card_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/layout/Card.js */ \"./packages/w-components/components/layout/Card.js\");\n/* harmony import */ var _components_form_checkable_Checkbox_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/form/checkable/Checkbox.js */ \"./packages/w-components/components/form/checkable/Checkbox.js\");\n/* harmony import */ var _components_Code_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/Code.js */ \"./packages/w-components/components/Code.js\");\n/* harmony import */ var _components_dialog_ConfirmDialog_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/dialog/ConfirmDialog.js */ \"./packages/w-components/components/dialog/ConfirmDialog.js\");\n/* harmony import */ var _components_dialog_Dialog_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/dialog/Dialog.js */ \"./packages/w-components/components/dialog/Dialog.js\");\n/* harmony import */ var _components_DisplayHeading_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/DisplayHeading.js */ \"./packages/w-components/components/DisplayHeading.js\");\n/* harmony import */ var _components_form_Form_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/form/Form.js */ \"./packages/w-components/components/form/Form.js\");\n/* harmony import */ var _components_layout_Grid_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/layout/Grid.js */ \"./packages/w-components/components/layout/Grid.js\");\n/* harmony import */ var _components_Heading_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/Heading.js */ \"./packages/w-components/components/Heading.js\");\n/* harmony import */ var _components_layout_Hero_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/layout/Hero.js */ \"./packages/w-components/components/layout/Hero.js\");\n/* harmony import */ var _components_Icon_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./components/Icon.js */ \"./packages/w-components/components/Icon.js\");\n/* harmony import */ var _components_button_IconButton_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./components/button/IconButton.js */ \"./packages/w-components/components/button/IconButton.js\");\n/* harmony import */ var _components_List_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./components/List.js */ \"./packages/w-components/components/List.js\");\n/* harmony import */ var _components_ListItem_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./components/ListItem.js */ \"./packages/w-components/components/ListItem.js\");\n/* harmony import */ var _components_layout_nav_Nav_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./components/layout/nav/Nav.js */ \"./packages/w-components/components/layout/nav/Nav.js\");\n/* harmony import */ var _components_layout_nav_NavPart_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./components/layout/nav/NavPart.js */ \"./packages/w-components/components/layout/nav/NavPart.js\");\n/* harmony import */ var _components_form_Option_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./components/form/Option.js */ \"./packages/w-components/components/form/Option.js\");\n/* harmony import */ var _components_Quote_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./components/Quote.js */ \"./packages/w-components/components/Quote.js\");\n/* harmony import */ var _components_form_checkable_Radio_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./components/form/checkable/Radio.js */ \"./packages/w-components/components/form/checkable/Radio.js\");\n/* harmony import */ var _components_layout_Section_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./components/layout/Section.js */ \"./packages/w-components/components/layout/Section.js\");\n/* harmony import */ var _components_form_Select_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./components/form/Select.js */ \"./packages/w-components/components/form/Select.js\");\n/* harmony import */ var _components_spa_SPALink_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./components/spa/SPALink.js */ \"./packages/w-components/components/spa/SPALink.js\");\n/* harmony import */ var _components_spa_SPAPage_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./components/spa/SPAPage.js */ \"./packages/w-components/components/spa/SPAPage.js\");\n/* harmony import */ var _components_layout_menu_SideMenu_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./components/layout/menu/SideMenu.js */ \"./packages/w-components/components/layout/menu/SideMenu.js\");\n/* harmony import */ var _components_layout_menu_SideMenuContent_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./components/layout/menu/SideMenuContent.js */ \"./packages/w-components/components/layout/menu/SideMenuContent.js\");\n/* harmony import */ var _components_layout_menu_SideMenuLayout_js__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./components/layout/menu/SideMenuLayout.js */ \"./packages/w-components/components/layout/menu/SideMenuLayout.js\");\n/* harmony import */ var _components_form_TextInput_js__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./components/form/TextInput.js */ \"./packages/w-components/components/form/TextInput.js\");\n/* harmony import */ var _components_form_TextArea_js__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! ./components/form/TextArea.js */ \"./packages/w-components/components/form/TextArea.js\");\n/* harmony import */ var _components_TypeWriter_js__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! ./components/TypeWriter.js */ \"./packages/w-components/components/TypeWriter.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst THEME_STYLESHEET_ID = \"wc-theme-stylesheet\";\n\nconst defaultWConfig={theme:\"light\", spa:{basename:\"\"}};\nconst wc={\n init: function(wconfig={}){\n window.wconfig=Object.assign(defaultWConfig, wconfig);\n window.wconfig.prefix='w'; // force prefix to 'w'\n \n this.initTheme(window.wconfig.theme);\n },\n initTheme:function(name){\n const head=document.querySelector(\"head\");\n const themeElement=head.querySelector(`#${THEME_STYLESHEET_ID}`);\n if(themeElement){\n themeElement.remove();\n }\n let stylesheet;\n if(name===\"dark\"){\n stylesheet=_theme_dark_css_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"];\n }else{\n stylesheet=_theme_light_css_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n }\n _util_DOM_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create(\"style\", {props:{\n id:THEME_STYLESHEET_ID, textContent:stylesheet\n }}, head);\n }\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (wc);\n\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"AlertDialog\": () => (/* reexport safe */ _components_dialog_AlertDialog_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"]),\n/* harmony export */ \"Button\": () => (/* reexport safe */ _components_button_Button_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"]),\n/* harmony export */ \"Calendar\": () => (/* reexport safe */ _components_Calendar_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"]),\n/* harmony export */ \"Camera\": () => (/* reexport safe */ _components_Camera_js__WEBPACK_IMPORTED_MODULE_4__[\"default\"]),\n/* harmony export */ \"Card\": () => (/* reexport safe */ _components_layout_Card_js__WEBPACK_IMPORTED_MODULE_5__[\"default\"]),\n/* harmony export */ \"CheckBox\": () => (/* reexport safe */ _components_form_checkable_Checkbox_js__WEBPACK_IMPORTED_MODULE_6__[\"default\"]),\n/* harmony export */ \"Code\": () => (/* reexport safe */ _components_Code_js__WEBPACK_IMPORTED_MODULE_7__[\"default\"]),\n/* harmony export */ \"ConfirmDialog\": () => (/* reexport safe */ _components_dialog_ConfirmDialog_js__WEBPACK_IMPORTED_MODULE_8__[\"default\"]),\n/* harmony export */ \"Dialog\": () => (/* reexport safe */ _components_dialog_Dialog_js__WEBPACK_IMPORTED_MODULE_9__[\"default\"]),\n/* harmony export */ \"DisplayHeading\": () => (/* reexport safe */ _components_DisplayHeading_js__WEBPACK_IMPORTED_MODULE_10__[\"default\"]),\n/* harmony export */ \"Form\": () => (/* reexport safe */ _components_form_Form_js__WEBPACK_IMPORTED_MODULE_11__[\"default\"]),\n/* harmony export */ \"Grid\": () => (/* reexport safe */ _components_layout_Grid_js__WEBPACK_IMPORTED_MODULE_12__[\"default\"]),\n/* harmony export */ \"Heading\": () => (/* reexport safe */ _components_Heading_js__WEBPACK_IMPORTED_MODULE_13__[\"default\"]),\n/* harmony export */ \"Hero\": () => (/* reexport safe */ _components_layout_Hero_js__WEBPACK_IMPORTED_MODULE_14__[\"default\"]),\n/* harmony export */ \"Icon\": () => (/* reexport safe */ _components_Icon_js__WEBPACK_IMPORTED_MODULE_15__[\"default\"]),\n/* harmony export */ \"IconButton\": () => (/* reexport safe */ _components_button_IconButton_js__WEBPACK_IMPORTED_MODULE_16__[\"default\"]),\n/* harmony export */ \"List\": () => (/* reexport safe */ _components_List_js__WEBPACK_IMPORTED_MODULE_17__[\"default\"]),\n/* harmony export */ \"ListItem\": () => (/* reexport safe */ _components_ListItem_js__WEBPACK_IMPORTED_MODULE_18__[\"default\"]),\n/* harmony export */ \"Nav\": () => (/* reexport safe */ _components_layout_nav_Nav_js__WEBPACK_IMPORTED_MODULE_19__[\"default\"]),\n/* harmony export */ \"NavPart\": () => (/* reexport safe */ _components_layout_nav_NavPart_js__WEBPACK_IMPORTED_MODULE_20__[\"default\"]),\n/* harmony export */ \"Option\": () => (/* reexport safe */ _components_form_Option_js__WEBPACK_IMPORTED_MODULE_21__[\"default\"]),\n/* harmony export */ \"Quote\": () => (/* reexport safe */ _components_Quote_js__WEBPACK_IMPORTED_MODULE_22__[\"default\"]),\n/* harmony export */ \"Radio\": () => (/* reexport safe */ _components_form_checkable_Radio_js__WEBPACK_IMPORTED_MODULE_23__[\"default\"]),\n/* harmony export */ \"Section\": () => (/* reexport safe */ _components_layout_Section_js__WEBPACK_IMPORTED_MODULE_24__[\"default\"]),\n/* harmony export */ \"Select\": () => (/* reexport safe */ _components_form_Select_js__WEBPACK_IMPORTED_MODULE_25__[\"default\"]),\n/* harmony export */ \"SPALink\": () => (/* reexport safe */ _components_spa_SPALink_js__WEBPACK_IMPORTED_MODULE_26__[\"default\"]),\n/* harmony export */ \"SPAPage\": () => (/* reexport safe */ _components_spa_SPAPage_js__WEBPACK_IMPORTED_MODULE_27__[\"default\"]),\n/* harmony export */ \"SideMenu\": () => (/* reexport safe */ _components_layout_menu_SideMenu_js__WEBPACK_IMPORTED_MODULE_28__[\"default\"]),\n/* harmony export */ \"SideMenuContent\": () => (/* reexport safe */ _components_layout_menu_SideMenuContent_js__WEBPACK_IMPORTED_MODULE_29__[\"default\"]),\n/* harmony export */ \"SideMenuLayout\": () => (/* reexport safe */ _components_layout_menu_SideMenuLayout_js__WEBPACK_IMPORTED_MODULE_30__[\"default\"]),\n/* harmony export */ \"TextInput\": () => (/* reexport safe */ _components_form_TextInput_js__WEBPACK_IMPORTED_MODULE_31__[\"default\"]),\n/* harmony export */ \"TextArea\": () => (/* reexport safe */ _components_form_TextArea_js__WEBPACK_IMPORTED_MODULE_32__[\"default\"]),\n/* harmony export */ \"TypeWriter\": () => (/* reexport safe */ _components_TypeWriter_js__WEBPACK_IMPORTED_MODULE_33__[\"default\"])\n/* harmony export */ });\n/* harmony import */ var _util_Theme_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/Theme.js */ \"./packages/w-components/util/Theme.js\");\n/* harmony import */ var _components_dialog_AlertDialog_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/dialog/AlertDialog.js */ \"./packages/w-components/components/dialog/AlertDialog.js\");\n/* harmony import */ var _components_button_Button_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/button/Button.js */ \"./packages/w-components/components/button/Button.js\");\n/* harmony import */ var _components_Calendar_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/Calendar.js */ \"./packages/w-components/components/Calendar.js\");\n/* harmony import */ var _components_Camera_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/Camera.js */ \"./packages/w-components/components/Camera.js\");\n/* harmony import */ var _components_layout_Card_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/layout/Card.js */ \"./packages/w-components/components/layout/Card.js\");\n/* harmony import */ var _components_form_checkable_Checkbox_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/form/checkable/Checkbox.js */ \"./packages/w-components/components/form/checkable/Checkbox.js\");\n/* harmony import */ var _components_Code_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/Code.js */ \"./packages/w-components/components/Code.js\");\n/* harmony import */ var _components_dialog_ConfirmDialog_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/dialog/ConfirmDialog.js */ \"./packages/w-components/components/dialog/ConfirmDialog.js\");\n/* harmony import */ var _components_dialog_Dialog_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./components/dialog/Dialog.js */ \"./packages/w-components/components/dialog/Dialog.js\");\n/* harmony import */ var _components_DisplayHeading_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./components/DisplayHeading.js */ \"./packages/w-components/components/DisplayHeading.js\");\n/* harmony import */ var _components_form_Form_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./components/form/Form.js */ \"./packages/w-components/components/form/Form.js\");\n/* harmony import */ var _components_layout_Grid_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./components/layout/Grid.js */ \"./packages/w-components/components/layout/Grid.js\");\n/* harmony import */ var _components_Heading_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./components/Heading.js */ \"./packages/w-components/components/Heading.js\");\n/* harmony import */ var _components_layout_Hero_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./components/layout/Hero.js */ \"./packages/w-components/components/layout/Hero.js\");\n/* harmony import */ var _components_Icon_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./components/Icon.js */ \"./packages/w-components/components/Icon.js\");\n/* harmony import */ var _components_button_IconButton_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./components/button/IconButton.js */ \"./packages/w-components/components/button/IconButton.js\");\n/* harmony import */ var _components_List_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./components/List.js */ \"./packages/w-components/components/List.js\");\n/* harmony import */ var _components_ListItem_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./components/ListItem.js */ \"./packages/w-components/components/ListItem.js\");\n/* harmony import */ var _components_layout_nav_Nav_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./components/layout/nav/Nav.js */ \"./packages/w-components/components/layout/nav/Nav.js\");\n/* harmony import */ var _components_layout_nav_NavPart_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./components/layout/nav/NavPart.js */ \"./packages/w-components/components/layout/nav/NavPart.js\");\n/* harmony import */ var _components_form_Option_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./components/form/Option.js */ \"./packages/w-components/components/form/Option.js\");\n/* harmony import */ var _components_Quote_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./components/Quote.js */ \"./packages/w-components/components/Quote.js\");\n/* harmony import */ var _components_form_checkable_Radio_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./components/form/checkable/Radio.js */ \"./packages/w-components/components/form/checkable/Radio.js\");\n/* harmony import */ var _components_layout_Section_js__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! ./components/layout/Section.js */ \"./packages/w-components/components/layout/Section.js\");\n/* harmony import */ var _components_form_Select_js__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! ./components/form/Select.js */ \"./packages/w-components/components/form/Select.js\");\n/* harmony import */ var _components_spa_SPALink_js__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! ./components/spa/SPALink.js */ \"./packages/w-components/components/spa/SPALink.js\");\n/* harmony import */ var _components_spa_SPAPage_js__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! ./components/spa/SPAPage.js */ \"./packages/w-components/components/spa/SPAPage.js\");\n/* harmony import */ var _components_layout_menu_SideMenu_js__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! ./components/layout/menu/SideMenu.js */ \"./packages/w-components/components/layout/menu/SideMenu.js\");\n/* harmony import */ var _components_layout_menu_SideMenuContent_js__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! ./components/layout/menu/SideMenuContent.js */ \"./packages/w-components/components/layout/menu/SideMenuContent.js\");\n/* harmony import */ var _components_layout_menu_SideMenuLayout_js__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! ./components/layout/menu/SideMenuLayout.js */ \"./packages/w-components/components/layout/menu/SideMenuLayout.js\");\n/* harmony import */ var _components_form_TextInput_js__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! ./components/form/TextInput.js */ \"./packages/w-components/components/form/TextInput.js\");\n/* harmony import */ var _components_form_TextArea_js__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! ./components/form/TextArea.js */ \"./packages/w-components/components/form/TextArea.js\");\n/* harmony import */ var _components_TypeWriter_js__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! ./components/TypeWriter.js */ \"./packages/w-components/components/TypeWriter.js\");\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst defaultWConfig={theme:\"light\", spa:{basename:\"\"}};\nconst wc={\n init: function(wconfig={}){\n window.wconfig=Object.assign(defaultWConfig, wconfig);\n window.wconfig.prefix='w'; // force prefix to 'w'\n this.setTheme(window.wconfig.theme);\n },\n setTheme: function(name) {\n _util_Theme_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].setElement(name);\n }\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (wc);\n\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/index.js?"); /***/ }), @@ -764,7 +764,7 @@ eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harm \*******************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst DOM={\n create:function(tagName, settings, parentElement){\n const element=document.createElement(tagName);\n this.modify(element, settings);\n if(parentElement instanceof Element || parentElement instanceof DocumentFragment){\n parentElement.appendChild(element);\n }\n return element;\n },\n modify:function(element, settings){\n if(!settings) { return element; }\n \n if(settings.props){\n this.setProperties(element, settings.props);\n }\n if(settings.attrs){\n this.setAttributes(element, settings.attrs);\n }\n if(settings.styles){\n this.setStyles(element, settings.styles);\n }\n if(settings.events){\n this.addListeners(element, settings.events);\n }\n return element;\n },\n replace:function(element, parentElement){\n if(parentElement instanceof Element || parentElement instanceof DocumentFragment){\n parentElement.appendChild(element);\n }\n return element;\n },\n setProperties:function(element, properties){\n for(const name in properties){\n element[name]=properties[name];\n }\n return element;\n },\n setAttributes:function(element, attributes){\n if(attributes.removes instanceof Array){\n attributes.removes.forEach((name)=>{\n element.removeAttribute(name);\n });\n delete attributes.removes;\n }\n for(const name in attributes){\n element.setAttribute(name, attributes[name]);\n }\n return element;\n },\n setStyles:function(element, styles){\n for(const name in styles){\n element.style[name]=styles[name];\n }\n return element;\n },\n addListeners:function(element, listeners, useCapture){\n for(const name in listeners){\n if(listeners[name] instanceof Array){\n listeners[name].forEach((handler)=>{\n element.addEventListener(name, handler, useCapture);\n });\n }else{\n element.addEventListener(name, listeners[name], useCapture);\n }\n }\n return element;\n },\n defineCustomElement(component) {\n const tag = `${customElementPrefix}-${component.tagName}`;\n if(!customElements.get(tag)) {\n customElements.define(tag, component);\n }\n }\n};\n\nconst customElementPrefix = 'w';\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (DOM);\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/util/DOM.js?"); +eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst DOM={\n create:function(tagName, settings, parentElement){\n const element=document.createElement(tagName);\n this.modify(element, settings);\n if(parentElement instanceof Element || parentElement instanceof DocumentFragment){\n parentElement.appendChild(element);\n }\n return element;\n },\n modify:function(element, settings){\n if(!settings) { return element; }\n \n if(settings.props){\n this.setProperties(element, settings.props);\n }\n if(settings.attrs){\n this.setAttributes(element, settings.attrs);\n }\n if(settings.styles){\n this.setStyles(element, settings.styles);\n }\n if(settings.events){\n this.addListeners(element, settings.events);\n }\n return element;\n },\n replace:function(element, parentElement){\n if(parentElement instanceof Element || parentElement instanceof DocumentFragment){\n parentElement.appendChild(element);\n }\n return element;\n },\n\n setProperties:function(element, properties){\n for(const name in properties){\n element[name]=properties[name];\n }\n return element;\n },\n setAttributes:function(element, attributes){\n if(attributes.removes instanceof Array){\n attributes.removes.forEach((name)=>{\n element.removeAttribute(name);\n });\n delete attributes.removes;\n }\n for(const name in attributes){\n element.setAttribute(name, attributes[name]);\n }\n return element;\n },\n setStyles:function(element, styles){\n for(const name in styles){\n element.style[name]=styles[name];\n }\n return element;\n },\n\n addListeners:function(element, listeners, useCapture){\n for(const name in listeners){\n if(listeners[name] instanceof Array){\n listeners[name].forEach((handler)=>{\n element.addEventListener(name, handler, useCapture);\n });\n }else{\n element.addEventListener(name, listeners[name], useCapture);\n }\n }\n return element;\n },\n defineCustomElement(component) {\n const tag = `${customElementPrefix}-${component.tagName}`;\n if(!customElements.get(tag)) {\n customElements.define(tag, component);\n }\n }\n};\n\nconst customElementPrefix = 'w';\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (DOM);\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/util/DOM.js?"); /***/ }), @@ -776,6 +776,16 @@ eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harm eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst DateTime={\n format:function(d){\n let year=d.getFullYear();\n let month=d.getMonth()+1;\n let date=d.getDate();\n return year+\"-\"+(month>9?month:\"0\"+month)+\"-\"+(date>9?date:\"0\"+date);\n }\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (DateTime);\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/util/DateTime.js?"); +/***/ }), + +/***/ "./packages/w-components/util/Theme.js": +/*!*********************************************!*\ + !*** ./packages/w-components/util/Theme.js ***! + \*********************************************/ +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__),\n/* harmony export */ \"THEME_DARK_NAME\": () => (/* binding */ DARK_NAME)\n/* harmony export */ });\n/* unused harmony exports THEME_STYLESHEET_ID, THEME_ATTR_NAME, THEME_LIGHT_NAME */\n/* harmony import */ var _DOM_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./DOM.js */ \"./packages/w-components/util/DOM.js\");\n/* harmony import */ var _theme_dark_css_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../theme/dark.css.js */ \"./packages/w-components/theme/dark.css.js\");\n/* harmony import */ var _theme_light_css_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../theme/light.css.js */ \"./packages/w-components/theme/light.css.js\");\n\n\n\n\nconst Theme = {\n bindChangedObserver(callback) {\n const handler = mutation => {\n const theme = this.getCurrentName();\n if(mutation[0].attributeName === ATTR_NAME && mutation[0].oldValue !== theme) {\n callback(theme);\n }\n };\n const observer = new MutationObserver(handler);\n observer.observe(document.head, { attributes: true, attributeOldValue: true });\n },\n createElement(stylesheet) {\n _DOM_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"].create(\"style\", {props:{\n id: STYLESHEET_ID, textContent: stylesheet\n }}, document.head);\n },\n getCurrentName() {\n return document.head.getAttribute(ATTR_NAME);\n },\n getElement() {\n return document.head.querySelector(`#${STYLESHEET_ID}`);\n },\n setElement(name) {\n const element = this.getElement();\n if(element){\n element.remove();\n }\n\n let stylesheet = _theme_light_css_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\n if(name === DARK_NAME){\n stylesheet=_theme_dark_css_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"];\n }\n this.createElement(stylesheet);\n document.head.setAttribute(ATTR_NAME, name)\n window.wconfig.theme = name;\n }\n};\n\nconst STYLESHEET_ID = 'w-theme-stylesheet';\nconst ATTR_NAME = 'theme';\nconst LIGHT_NAME = 'light';\nconst DARK_NAME = 'dark';\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Theme);\n\n\n//# sourceURL=webpack://@padax/w-components-project/./packages/w-components/util/Theme.js?"); + /***/ }) /******/ }); @@ -885,7 +895,7 @@ eval("/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harm /******/ /******/ /* webpack/runtime/getFullHash */ /******/ (() => { -/******/ __webpack_require__.h = () => ("d825827fc931861ffb8d") +/******/ __webpack_require__.h = () => ("5a1a94ef76d607029506") /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ diff --git a/index.html b/index.html index 0d39076..d1dba1e 100644 --- a/index.html +++ b/index.html @@ -193,12 +193,12 @@ document.querySelector('#btnDarkTheme').addEventListener('click', function(e) { this.style.display = 'none'; document.querySelector('#btnLightTheme').style.display = 'flex'; - wc.initTheme('dark'); + wc.setTheme('dark'); }); document.querySelector('#btnLightTheme').addEventListener('click', function(e) { this.style.display = 'none'; document.querySelector('#btnDarkTheme').style.display = 'flex'; - wc.initTheme('light'); + wc.setTheme('light'); }); // manipulate calendar diff --git a/packages/w-components/WComponent.js b/packages/w-components/WComponent.js index 2920c21..db9864d 100644 --- a/packages/w-components/WComponent.js +++ b/packages/w-components/WComponent.js @@ -1,4 +1,5 @@ import DOM from "./util/DOM.js"; +import Theme from './util/Theme.js'; class WComponent extends HTMLElement{ /** @@ -31,6 +32,13 @@ class WComponent extends HTMLElement{ this.update({name, oldValue, newValue}); } } + /** + * Create & bind observer on head style theme changed. + * @param {function} callback + */ + bindThemeChangedObserver(callback) { + Theme.bindChangedObserver(callback); + } /** * Dynamically create getters & setters for property-attribute sync * by parsing class field attribute object. diff --git a/packages/w-components/components/Code.js b/packages/w-components/components/Code.js index 1d501ad..01aa215 100644 --- a/packages/w-components/components/Code.js +++ b/packages/w-components/components/Code.js @@ -1,6 +1,17 @@ import WComponent, { DOM, AttributeParser } from "../WComponent.js"; +import Theme, { THEME_LIGHT_NAME, THEME_DARK_NAME } from '../util/Theme.js'; const stylesheet = ` + :host { + display: block; + color: var(--color-gray-80); + background-color: var(--color-gray-10); + border-radius: 4px; + padding: 20px; + white-space: pre-wrap; + } +`; +const lightThemeStylesheet = ` /*! Theme: GitHub Description: Light theme as seen on github.com @@ -125,14 +136,131 @@ const stylesheet = ` .hljs-tag { /* purposely ignored */ } +`; +const darkThemeStylesheet = ` + /*! + Theme: GitHub Dark + Description: Dark theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS + */ - :host { - display: block; - color: var(--color-gray-80); - background-color: var(--color-gray-10); - border-radius: 4px; - padding: 20px; - white-space: pre-wrap; + .hljs { + color: #c9d1d9; + background: #0d1117; + } + + .hljs-doctag, + .hljs-keyword, + .hljs-meta .hljs-keyword, + .hljs-template-tag, + .hljs-template-variable, + .hljs-type, + .hljs-variable.language_ { + /* prettylights-syntax-keyword */ + color: #ff7b72; + } + + .hljs-title, + .hljs-title.class_, + .hljs-title.class_.inherited__, + .hljs-title.function_ { + /* prettylights-syntax-entity */ + color: #d2a8ff; + } + + .hljs-attr, + .hljs-attribute, + .hljs-literal, + .hljs-meta, + .hljs-number, + .hljs-operator, + .hljs-variable, + .hljs-selector-attr, + .hljs-selector-class, + .hljs-selector-id { + /* prettylights-syntax-constant */ + color: #79c0ff; + } + + .hljs-regexp, + .hljs-string, + .hljs-meta .hljs-string { + /* prettylights-syntax-string */ + color: #a5d6ff; + } + + .hljs-built_in, + .hljs-symbol { + /* prettylights-syntax-variable */ + color: #ffa657; + } + + .hljs-comment, + .hljs-code, + .hljs-formula { + /* prettylights-syntax-comment */ + color: #8b949e; + } + + .hljs-name, + .hljs-quote, + .hljs-selector-tag, + .hljs-selector-pseudo { + /* prettylights-syntax-entity-tag */ + color: #7ee787; + } + + .hljs-subst { + /* prettylights-syntax-storage-modifier-import */ + color: #c9d1d9; + } + + .hljs-section { + /* prettylights-syntax-markup-heading */ + color: #1f6feb; + font-weight: bold; + } + + .hljs-bullet { + /* prettylights-syntax-markup-list */ + color: #f2cc60; + } + + .hljs-emphasis { + /* prettylights-syntax-markup-italic */ + color: #c9d1d9; + font-style: italic; + } + + .hljs-strong { + /* prettylights-syntax-markup-bold */ + color: #c9d1d9; + font-weight: bold; + } + + .hljs-addition { + /* prettylights-syntax-markup-inserted */ + color: #aff5b4; + background-color: #033a16; + } + + .hljs-deletion { + /* prettylights-syntax-markup-deleted */ + color: #ffdcd7; + background-color: #67060c; + } + + .hljs-char.escape_, + .hljs-link, + .hljs-params, + .hljs-property, + .hljs-punctuation, + .hljs-tag { + /* purposely ignored */ } `; class Code extends WComponent{ @@ -157,6 +285,7 @@ class Code extends WComponent{ constructor(){ super(); this.bindObserver(); + this.bindThemeChangedObserver(theme => this.setThemeStylesheet(theme)); } bindObserver() { @@ -188,6 +317,15 @@ class Code extends WComponent{ this.parseAttributeValueByName(name, newValue); this.loadHighlightContent(); } + + setThemeStylesheet(theme) { + if(theme === THEME_DARK_NAME) { + this.setStylesheet(darkThemeStylesheet, 'theme'); + } else { + this.setStylesheet(lightThemeStylesheet, 'theme'); + } + this.loadHighlightContent(); + } } Code.prototype.stylesheet=stylesheet; diff --git a/packages/w-components/index.js b/packages/w-components/index.js index 6053ed0..69dbfdc 100644 --- a/packages/w-components/index.js +++ b/packages/w-components/index.js @@ -1,6 +1,5 @@ import DOM from "./util/DOM.js"; -import DarkThemeStylesheet from "./theme/dark.css.js"; -import LightThemeStylesheet from "./theme/light.css.js"; +import Theme from "./util/Theme.js"; import AlertDialog from "./components/dialog/AlertDialog.js"; import Button from "./components/button/Button.js"; @@ -36,31 +35,15 @@ import TextInput from "./components/form/TextInput.js"; import TextArea from "./components/form/TextArea.js"; import TypeWriter from "./components/TypeWriter.js"; -const THEME_STYLESHEET_ID = "wc-theme-stylesheet"; - const defaultWConfig={theme:"light", spa:{basename:""}}; const wc={ init: function(wconfig={}){ window.wconfig=Object.assign(defaultWConfig, wconfig); window.wconfig.prefix='w'; // force prefix to 'w' - - this.initTheme(window.wconfig.theme); + this.setTheme(window.wconfig.theme); }, - initTheme:function(name){ - const head=document.querySelector("head"); - const themeElement=head.querySelector(`#${THEME_STYLESHEET_ID}`); - if(themeElement){ - themeElement.remove(); - } - let stylesheet; - if(name==="dark"){ - stylesheet=DarkThemeStylesheet; - }else{ - stylesheet=LightThemeStylesheet; - } - DOM.create("style", {props:{ - id:THEME_STYLESHEET_ID, textContent:stylesheet - }}, head); + setTheme: function(name) { + Theme.setElement(name); } }; diff --git a/packages/w-components/util/DOM.js b/packages/w-components/util/DOM.js index d5968d9..5c67f23 100644 --- a/packages/w-components/util/DOM.js +++ b/packages/w-components/util/DOM.js @@ -30,6 +30,7 @@ const DOM={ } return element; }, + setProperties:function(element, properties){ for(const name in properties){ element[name]=properties[name]; @@ -54,6 +55,7 @@ const DOM={ } return element; }, + addListeners:function(element, listeners, useCapture){ for(const name in listeners){ if(listeners[name] instanceof Array){ diff --git a/packages/w-components/util/Theme.js b/packages/w-components/util/Theme.js new file mode 100644 index 0000000..93f1029 --- /dev/null +++ b/packages/w-components/util/Theme.js @@ -0,0 +1,52 @@ +import DOM from './DOM.js'; +import DarkThemeStylesheet from "../theme/dark.css.js"; +import LightThemeStylesheet from "../theme/light.css.js"; + +const Theme = { + bindChangedObserver(callback) { + const handler = mutation => { + const theme = this.getCurrentName(); + if(mutation[0].attributeName === ATTR_NAME && mutation[0].oldValue !== theme) { + callback(theme); + } + }; + const observer = new MutationObserver(handler); + observer.observe(document.head, { attributes: true, attributeOldValue: true }); + }, + createElement(stylesheet) { + DOM.create("style", {props:{ + id: STYLESHEET_ID, textContent: stylesheet + }}, document.head); + }, + getCurrentName() { + return document.head.getAttribute(ATTR_NAME); + }, + getElement() { + return document.head.querySelector(`#${STYLESHEET_ID}`); + }, + setElement(name) { + const element = this.getElement(); + if(element){ + element.remove(); + } + + let stylesheet = LightThemeStylesheet; + if(name === DARK_NAME){ + stylesheet=DarkThemeStylesheet; + } + this.createElement(stylesheet); + document.head.setAttribute(ATTR_NAME, name) + window.wconfig.theme = name; + } +}; + +const STYLESHEET_ID = 'w-theme-stylesheet'; +const ATTR_NAME = 'theme'; +const LIGHT_NAME = 'light'; +const DARK_NAME = 'dark'; + +export default Theme; +export { + STYLESHEET_ID as THEME_STYLESHEET_ID, ATTR_NAME as THEME_ATTR_NAME, + LIGHT_NAME as THEME_LIGHT_NAME, DARK_NAME as THEME_DARK_NAME +}; \ No newline at end of file