diff --git a/.gitignore b/.gitignore
index fd4f2b0..a45a18c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
node_modules
.DS_Store
+.idea/
+package-lock.json
\ No newline at end of file
diff --git a/abas/README2.md b/abas/README2.md
new file mode 100644
index 0000000..3cbd50c
--- /dev/null
+++ b/abas/README2.md
@@ -0,0 +1,22 @@
+# This readme is only for abas
+
+1. Checkout this wrapper repo into the same level of the project what you want to convert. e.g. abas-elements
+2. To fix the icons styles
+ Put 'WcIconMixin.js' file into abas-elements/src/mixins
+ Add 'import WcIconMixin from '../mixins/WcIconMixin';' in Icon.vue
+ Add mixin 'mixins: [WcIconMixin],' in Icon.vue
+3. Adjust 'vue.config.js' in abas-elements project by adding alias for the '@vue/web-component-wrapper'
+
+ '''
+ configureWebpack: {
+ resolve: {
+ alias: {
+ '@vue/web-component-wrapper': path.join(__dirname, '../vue-web-component-wrapper'),
+ },
+ },
+ },
+ '''
+4. add dependency into package.json in block 'devDependencies'
+ '''
+ "eslint-plugin-vue-libs": "^2.1.0"
+ '''
diff --git a/abas/WcIconMixin.js b/abas/WcIconMixin.js
new file mode 100644
index 0000000..fc720dc
--- /dev/null
+++ b/abas/WcIconMixin.js
@@ -0,0 +1,28 @@
+import { dom } from '@fortawesome/fontawesome-svg-core'
+
+/**
+ * @mixin
+ */
+export default {
+ mounted () {
+ const id = 'fa-styles'
+ const shadowRoot = this.getShadowRoot(this)
+ if (shadowRoot && !shadowRoot.getElementById(id)) {
+ const faStyles = document.createElement('style')
+ faStyles.setAttribute('id', id)
+ faStyles.textContent = dom.css()
+ shadowRoot.appendChild(faStyles)
+ }
+ },
+ methods: {
+ getShadowRoot (obj) {
+ if (obj.$parent) {
+ if (obj.$parent.$options && obj.$parent.$options.shadowRoot) {
+ return obj.$parent.$options.shadowRoot
+ }
+ return this.getShadowRoot(obj.$parent)
+ }
+ return null
+ }
+ }
+}
diff --git a/dist/vue-wc-wrapper.global.js b/dist/vue-wc-wrapper.global.js
index db8253a..ab07537 100644
--- a/dist/vue-wc-wrapper.global.js
+++ b/dist/vue-wc-wrapper.global.js
@@ -98,6 +98,54 @@ function getAttributes (node) {
return res
}
+function spreadProps (component) {
+ const result = {};
+ spreadNext(result, component);
+ return result
+}
+
+function spreadNext (result, component) {
+ if (component.props) {
+ appendProps(result, component.props);
+ }
+
+ if (component.mixins) {
+ component.mixins.forEach(function (mixin) {
+ spreadNext(result, mixin);
+ });
+ }
+ if (component.extends) {
+ spreadNext(result, component.extends);
+ }
+}
+
+function appendProps (result, props) {
+ if (Array.isArray(props)) {
+ processArrayProps(result, props);
+ } else {
+ processObjectProps(result, props);
+ }
+}
+
+function processObjectProps (result, props) {
+ for (const key in props) {
+ const camelKey = camelize(key);
+ if (!(camelKey in result)) {
+ result[camelKey] = props[key];
+ }
+ }
+}
+function processArrayProps (result, props) {
+ props.forEach(function (prop) {
+ if (typeof prop === 'string') {
+ const camelKey = camelize(prop);
+ if (!(camelKey in result)) {
+ result[camelKey] = undefined;
+ }
+ }
+ });
+}
+
function wrap (Vue, Component) {
const isAsync = typeof Component === 'function' && !Component.cid;
let isInitialized = false;
@@ -112,13 +160,13 @@ function wrap (Vue, Component) {
? Component.options
: Component;
+ // spread props
+ options.props = spreadProps(options);
// extract props info
- const propsList = Array.isArray(options.props)
- ? options.props
- : Object.keys(options.props || {});
+ const propsList = Object.keys(options.props || {});
hyphenatedPropsList = propsList.map(hyphenate);
camelizedPropsList = propsList.map(camelize);
- const originalPropsAsObject = Array.isArray(options.props) ? {} : options.props || {};
+ const originalPropsAsObject = options.props || {};
camelizedPropsMap = camelizedPropsList.reduce((map, key, i) => {
map[key] = originalPropsAsObject[propsList[i]];
return map
@@ -169,13 +217,13 @@ function wrap (Vue, Component) {
class CustomElement extends HTMLElement {
constructor () {
- super();
- this.attachShadow({ mode: 'open' });
+ const self = super();
+ self.attachShadow({ mode: 'open' });
- const wrapper = this._wrapper = new Vue({
+ const wrapper = self._wrapper = new Vue({
name: 'shadow-root',
- customElement: this,
- shadowRoot: this.shadowRoot,
+ customElement: self,
+ shadowRoot: self.shadowRoot,
data () {
return {
props: {},
@@ -195,8 +243,8 @@ function wrap (Vue, Component) {
let hasChildrenChange = false;
for (let i = 0; i < mutations.length; i++) {
const m = mutations[i];
- if (isInitialized && m.type === 'attributes' && m.target === this) {
- syncAttribute(this, m.attributeName);
+ if (isInitialized && m.type === 'attributes' && m.target === self) {
+ syncAttribute(self, m.attributeName);
} else {
hasChildrenChange = true;
}
@@ -204,11 +252,11 @@ function wrap (Vue, Component) {
if (hasChildrenChange) {
wrapper.slotChildren = Object.freeze(toVNodes(
wrapper.$createElement,
- this.childNodes
+ self.childNodes
));
}
});
- observer.observe(this, {
+ observer.observe(self, {
childList: true,
subtree: true,
characterData: true,
diff --git a/dist/vue-wc-wrapper.js b/dist/vue-wc-wrapper.js
index 36b4469..ba33aef 100644
--- a/dist/vue-wc-wrapper.js
+++ b/dist/vue-wc-wrapper.js
@@ -95,6 +95,54 @@ function getAttributes (node) {
return res
}
+function spreadProps (component) {
+ const result = {};
+ spreadNext(result, component);
+ return result
+}
+
+function spreadNext (result, component) {
+ if (component.props) {
+ appendProps(result, component.props);
+ }
+
+ if (component.mixins) {
+ component.mixins.forEach(function (mixin) {
+ spreadNext(result, mixin);
+ });
+ }
+ if (component.extends) {
+ spreadNext(result, component.extends);
+ }
+}
+
+function appendProps (result, props) {
+ if (Array.isArray(props)) {
+ processArrayProps(result, props);
+ } else {
+ processObjectProps(result, props);
+ }
+}
+
+function processObjectProps (result, props) {
+ for (const key in props) {
+ const camelKey = camelize(key);
+ if (!(camelKey in result)) {
+ result[camelKey] = props[key];
+ }
+ }
+}
+function processArrayProps (result, props) {
+ props.forEach(function (prop) {
+ if (typeof prop === 'string') {
+ const camelKey = camelize(prop);
+ if (!(camelKey in result)) {
+ result[camelKey] = undefined;
+ }
+ }
+ });
+}
+
function wrap (Vue, Component) {
const isAsync = typeof Component === 'function' && !Component.cid;
let isInitialized = false;
@@ -109,13 +157,13 @@ function wrap (Vue, Component) {
? Component.options
: Component;
+ // spread props
+ options.props = spreadProps(options);
// extract props info
- const propsList = Array.isArray(options.props)
- ? options.props
- : Object.keys(options.props || {});
+ const propsList = Object.keys(options.props || {});
hyphenatedPropsList = propsList.map(hyphenate);
camelizedPropsList = propsList.map(camelize);
- const originalPropsAsObject = Array.isArray(options.props) ? {} : options.props || {};
+ const originalPropsAsObject = options.props || {};
camelizedPropsMap = camelizedPropsList.reduce((map, key, i) => {
map[key] = originalPropsAsObject[propsList[i]];
return map
@@ -166,13 +214,13 @@ function wrap (Vue, Component) {
class CustomElement extends HTMLElement {
constructor () {
- super();
- this.attachShadow({ mode: 'open' });
+ const self = super();
+ self.attachShadow({ mode: 'open' });
- const wrapper = this._wrapper = new Vue({
+ const wrapper = self._wrapper = new Vue({
name: 'shadow-root',
- customElement: this,
- shadowRoot: this.shadowRoot,
+ customElement: self,
+ shadowRoot: self.shadowRoot,
data () {
return {
props: {},
@@ -192,8 +240,8 @@ function wrap (Vue, Component) {
let hasChildrenChange = false;
for (let i = 0; i < mutations.length; i++) {
const m = mutations[i];
- if (isInitialized && m.type === 'attributes' && m.target === this) {
- syncAttribute(this, m.attributeName);
+ if (isInitialized && m.type === 'attributes' && m.target === self) {
+ syncAttribute(self, m.attributeName);
} else {
hasChildrenChange = true;
}
@@ -201,11 +249,11 @@ function wrap (Vue, Component) {
if (hasChildrenChange) {
wrapper.slotChildren = Object.freeze(toVNodes(
wrapper.$createElement,
- this.childNodes
+ self.childNodes
));
}
});
- observer.observe(this, {
+ observer.observe(self, {
childList: true,
subtree: true,
characterData: true,
diff --git a/package.json b/package.json
index f7ec743..6abe05e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@vue/web-component-wrapper",
- "version": "1.2.0",
+ "version": "1.3.0",
"description": "wrap a vue component as a web component.",
"main": "dist/vue-wc-wrapper.js",
"unpkg": "dist/vue-wc-wrapper.global.js",
diff --git a/src/index.js b/src/index.js
index 4409bd7..4788a1a 100644
--- a/src/index.js
+++ b/src/index.js
@@ -6,7 +6,8 @@ import {
injectHook,
getInitialProps,
createCustomEvent,
- convertAttributeValue
+ convertAttributeValue,
+ spreadProps
} from './utils.js'
export default function wrap (Vue, Component) {
@@ -23,13 +24,13 @@ export default function wrap (Vue, Component) {
? Component.options
: Component
+ // spread props
+ options.props = spreadProps(options)
// extract props info
- const propsList = Array.isArray(options.props)
- ? options.props
- : Object.keys(options.props || {})
+ const propsList = Object.keys(options.props || {})
hyphenatedPropsList = propsList.map(hyphenate)
camelizedPropsList = propsList.map(camelize)
- const originalPropsAsObject = Array.isArray(options.props) ? {} : options.props || {}
+ const originalPropsAsObject = options.props || {}
camelizedPropsMap = camelizedPropsList.reduce((map, key, i) => {
map[key] = originalPropsAsObject[propsList[i]]
return map
diff --git a/src/utils.js b/src/utils.js
index 0834f03..f202c68 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -94,3 +94,52 @@ function getAttributes (node) {
}
return res
}
+
+export function spreadProps (component) {
+ const result = {}
+ spreadNext(result, component)
+ return result
+}
+
+function spreadNext (result, component) {
+ if (component.props) {
+ appendProps(result, component.props)
+ }
+
+ if (component.mixins) {
+ component.mixins.forEach(function (mixin) {
+ spreadNext(result, mixin)
+ })
+ }
+ if (component.extends) {
+ spreadNext(result, component.extends)
+ }
+}
+
+function appendProps (result, props) {
+ if (Array.isArray(props)) {
+ processArrayProps(result, props)
+ } else {
+ processObjectProps(result, props)
+ }
+}
+
+function processObjectProps (result, props) {
+ for (const key in props) {
+ const camelKey = camelize(key)
+ if (!(camelKey in result)) {
+ result[camelKey] = props[key]
+ }
+ }
+}
+function processArrayProps (result, props) {
+ props.forEach(function (prop) {
+ if (typeof prop === 'string') {
+ const camelKey = camelize(prop)
+ if (!(camelKey in result)) {
+ result[camelKey] = undefined
+ }
+ }
+ })
+}
+
diff --git a/test/fixtures/spreadedProperties.html b/test/fixtures/spreadedProperties.html
new file mode 100644
index 0000000..e2d500f
--- /dev/null
+++ b/test/fixtures/spreadedProperties.html
@@ -0,0 +1,48 @@
+
+
+
+
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: