├── .builderrc
├── .gitignore
├── .npmignore
├── .npmrc
├── README.md
├── example
├── .babelrc
├── .editorconfig
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── App.vue
│ ├── Foo.vue
│ ├── assets
│ │ └── logo.png
│ └── main.js
└── webpack.config.js
├── global.js
├── package.json
└── src
├── index.js
└── test.js
/.builderrc:
--------------------------------------------------------------------------------
1 | ---
2 | archetypes:
3 | - builder-js-package
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | npm-debug.log
4 | package-lock.json
5 |
6 | # ignore build files
7 | /*.js
8 | /*.js.map
9 | !/global.js
10 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trusktr/vue-web-component/172895ee5984f5825b952364eda689a9423d299b/.npmignore
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | vue-web-component
3 | -----------------
4 |
5 | Generate custom elements from [Vue](https://vuejs.org) component definitions.
6 |
7 | #### `npm install vue-web-component --save`
8 |
9 | ### What?
10 |
11 | `vue-web-component` generates Web Components (Custom Elements) that are
12 | consumable in any sort of web application and can be manipulated by any view
13 | library like Vue, React, Angular, and others. Custom Elements are user-defined
14 | elements that the browser knows how to work with just like with builtin
15 | elements.
16 |
17 | Plus, it's just easy to write Web Components this way!
18 |
19 | `vue-web-component` takes the authoring of Custom Elements one step further by
20 | letting you define a Vue component from which to render the content of your
21 | Custom Element. Attribute changes on the generated custom element are
22 | automatically propagated to the underlying Vue component instance, and the
23 | elements are composable with ShadowDOM.
24 |
25 | Behind the scenes, utilities offered by [SkateJS](http://skatejs.netlify.com/)
26 | are used in wiring up the functionality. SkateJS provides a set of powerfully
27 | simple mixins that make defining custom elements super simple and convenient,
28 | on top of the browser's native Web Components APIs.
29 |
30 | #### Pros:
31 |
32 | 1. Using Vue makes it easy to describe how the DOM content of your custom
33 | element will change depending on attribute.
34 | 1. Morphing your DOM will be automatically fast thanks to Vue's dom diffing.
35 | 1. Modifying properties (attributes) of your element will re-render your
36 | component DOM content automatically, it's nice!
37 | 1. Vue single-file-component files are super nice to work with, and support a
38 | variety of languages like Pug, CoffeeScript, TypeScript, Sass, Less, Stylus,
39 | and more.
40 | 1. For a wide variety of elements, using this approach makes it dirt simple to
41 | write custom elements.
42 | 1. There's awesome tooling around Vue like loaders and syntax plugins for
43 | various editors, that make working with Vue magical.
44 | 1. There's many ways to define a Vue component, all of which work with
45 | `vue-web-component`. For example, see [7 Ways to Define a Component Template
46 | in
47 | VueJS](https://medium.com/js-dojo/7-ways-to-define-a-component-template-in-vuejs-c04e0c72900d).
48 |
49 | #### Cons:
50 |
51 | 1. Not all custom elements need a view layer for describing how their inner DOM
52 | changes. It can be leaner to just define the static DOM yourself in this
53 | case yourself, and [SkateJS](https://github.com/skatejs/skatejs/) is a great
54 | tool for that. Though, doing it with Vue will still be simple!
55 | 1. When writing a Vue-based component, you have less control of the Web
56 | Components APIs. Usually that's okay, but sometimes you may want more
57 | control. Well, the good thing is the that the output from `VueWebComponent`
58 | is a SkateJS class with useful methods and properties that you can set and
59 | override. See below for more detail.
60 | 1. A component doesn't always need DOM content. It might be a pure-JavaScript
61 | component. In that case using vanilla Web Components APIs can be preferable
62 | rather than loading a `new Vue`, but it depends on your case.
63 |
64 | ### But, [`vue-custom-element`](https://github.com/karol-f/vue-custom-element) already exists. Why another one?
65 |
66 | `vue-custom-element` didn't meet some requirements. I needed the following:
67 |
68 | 1. Elements are instantiated only once
69 | 1. Elements are nestable and composable
70 | 1. Elements distribute as expected with ShadowDOM.
71 |
72 | See here for details on [why `vue-custom-element` didn't meet these
73 | requirements](https://github.com/karol-f/vue-custom-element/issues/74).
74 |
75 | Requirements
76 | ============
77 |
78 | - You'll need a Web Component polyfill to run this in older browsers that don't
79 | yet have Custom Elements and/or ShadowDOM.
80 | - The source is not transpiled for older browsers so you may have to transpile
81 | this in your own build setup.
82 |
83 | Basic Usage
84 | ===========
85 |
86 | You can import a Vue component then make a custom element out of it:
87 |
88 | ```js
89 | import Foo from './Foo.vue'
90 | import VueWebComponent from 'vue-web-component'
91 |
92 | // define a custom element with the Vue component
93 | customElements.define('foo-element', VueWebComponent( Foo ) )
94 |
95 | // now use it with regular DOM APIs
96 | document.body.innerHTML = `
97 |
98 | `
99 | ```
100 |
101 | You can also define the custom element inline, using an object literal of the
102 | same format as a Vue component:
103 |
104 | ```js
105 | import VueWebComponent from 'vue-web-component'
106 |
107 | // define a custom element using an object literal
108 | customElements.define('foo-element', VueWebComponent( {
109 | props: {
110 | // ...
111 | },
112 | data: () => ({
113 | // ...
114 | }),
115 | methods: {
116 | // ...
117 | },
118 | mounted() {
119 | // ...
120 | },
121 | // etc
122 | } ) )
123 |
124 | // now use it with regular DOM APIs
125 | document.body.innerHTML = `
126 |
127 | `
128 | ```
129 |
130 | Usage inside other Vue components
131 | =================================
132 |
133 | Whether you create a Custom Element from a Vue component or not is your choice.
134 | You can use the Vue component inside another component without using it in the
135 | custom element form. The following example shows usage of both forms inside a
136 | Vue component, where the result is the same for all uses of the Foo component:
137 |
138 |
139 | ```vue
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
168 | ```
169 |
170 | Scoped styles
171 | =============
172 |
173 | Scoped styles (using `
57 |
--------------------------------------------------------------------------------
/example/src/Foo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | foo: {{message.n}}
4 |
5 |
6 |
11 |
12 |
22 |
--------------------------------------------------------------------------------
/example/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trusktr/vue-web-component/172895ee5984f5825b952364eda689a9423d299b/example/src/assets/logo.png
--------------------------------------------------------------------------------
/example/src/main.js:
--------------------------------------------------------------------------------
1 | import App from './App.vue'
2 | import Foo from './Foo.vue'
3 | import VueWebComponent from '../../src/index'
4 |
5 | console.log('App in main:', App)
6 | console.log('Foo in main:', Foo)
7 | console.log('Foo props sync 1', Foo.props)
8 |
9 | customElements.define('app-element', VueWebComponent( App ) )
10 | customElements.define('foo-element', VueWebComponent( Foo ) )
11 |
12 | console.log('Foo props sync 2', Foo.props)
13 |
14 | // finally, test the element, and you can also nest them (take a look at the
15 | // element inspector)
16 | document.body.innerHTML = `
17 |
18 |
19 |
20 |
21 | `
22 |
23 | console.log('Foo props sync 3', Foo.props)
24 |
25 | setTimeout(() => {
26 | console.log('Foo props async', Foo.props)
27 | console.log(test.props)
28 | }, 500)
29 |
30 | /////////////////////////////////////////////////////////////////////////////
31 | /////////////////////////////////////////////////////////////////////////////
32 |
33 | //import Foo from './Foo.vue'
34 | //import Vue from 'vue'
35 | //import VueWebComponent from '../../src/index'
36 |
37 | //document.body.innerHTML = '
'
38 | //const root = document.querySelector('#root')
39 |
40 | ////new Vue({
41 | ////el: root,
42 | ////components: { fooElement: Foo },
43 | ////})
44 |
45 | //customElements.define('foo-element', VueWebComponent(Foo))
46 |
47 | /////////////////////////////////////////////////////////////////////////////
48 | /////////////////////////////////////////////////////////////////////////////
49 |
50 | //import { props, withComponent } from 'skatejs'
51 | //import VueWebComponent from '../../src/index'
52 |
53 | //class MyEl extends withComponent(HTMLElement) {
54 | //static get props() {
55 | //return {
56 | //msg: props.object,
57 | //bool: props.boolean,
58 | //}
59 | //}
60 |
61 | //render() {
62 | //return `
63 | //msg: ${this.msg.n}
64 | //
65 | //
66 | //`
67 | //}
68 |
69 | //updated(...args) {
70 | //super.updated(...args)
71 | //console.log('updated!', this.msg, this.bool)
72 | //}
73 | //}
74 |
75 | //customElements.define('my-el', MyEl)
76 |
77 | //document.body.innerHTML = `
78 | //test
79 | //`
80 |
81 | //setTimeout(() => myel.msg = {n:65}, 2000)
82 |
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | module.exports = {
5 | entry: './src/main.js',
6 | output: {
7 | path: path.resolve(__dirname, './dist'),
8 | publicPath: '/dist/',
9 | filename: 'build.js'
10 | },
11 | module: {
12 | rules: [
13 | {
14 | test: /\.css$/,
15 | use: [
16 | 'vue-style-loader',
17 | 'css-loader'
18 | ],
19 | }, {
20 | test: /\.vue$/,
21 | loader: 'vue-loader',
22 | options: {
23 | loaders: {
24 | }
25 | // other vue-loader options go here
26 | }
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader',
31 |
32 | // see tips on including specific node_modules: https://github.com/webpack/webpack/issues/2031
33 | //exclude: /node_modules\/(?!(skatejs)\/).*/,
34 | exclude: function(modulePath) {
35 | return /node_modules/.test(modulePath) &&
36 | !/node_modules\/skatejs/.test(modulePath);
37 | },
38 |
39 | },
40 | {
41 | test: /\.(png|jpg|gif|svg)$/,
42 | loader: 'file-loader',
43 | options: {
44 | name: '[name].[ext]?[hash]'
45 | }
46 | }
47 | ]
48 | },
49 | resolve: {
50 | alias: {
51 | 'vue$': 'vue/dist/vue.esm.js',
52 | 'skatejs': 'skatejs/dist/esnext',
53 | },
54 | mainFields: ['esnext', 'browser', 'module', 'main'],
55 | extensions: ['*', '.js', '.vue', '.json']
56 | },
57 | devServer: {
58 | historyApiFallback: true,
59 | noInfo: true,
60 | overlay: true
61 | },
62 | performance: {
63 | hints: false
64 | },
65 | devtool: '#eval-source-map'
66 | }
67 |
68 | if (process.env.NODE_ENV === 'production') {
69 | module.exports.devtool = '#source-map'
70 | // http://vue-loader.vuejs.org/en/workflow/production.html
71 | module.exports.plugins = (module.exports.plugins || []).concat([
72 | new webpack.DefinePlugin({
73 | 'process.env': {
74 | NODE_ENV: '"production"'
75 | }
76 | }),
77 | new webpack.optimize.UglifyJsPlugin({
78 | sourceMap: true,
79 | compress: {
80 | warnings: false
81 | }
82 | }),
83 | new webpack.LoaderOptionsPlugin({
84 | minimize: true
85 | })
86 | ])
87 | }
88 |
--------------------------------------------------------------------------------
/global.js:
--------------------------------------------------------------------------------
1 | var vueWebComponent=function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e['default']}:function(){return e};return t.d(n,'a',n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p='',t(t.s=56)}([function(e){var t=e.exports={version:'2.5.3'};'number'==typeof __e&&(__e=t)},function(e){var t=e.exports='undefined'!=typeof window&&window.Math==Math?window:'undefined'!=typeof self&&self.Math==Math?self:Function('return this')();'number'==typeof __g&&(__g=t)},function(e){e.exports=function(e){return'object'==typeof e?null!==e:'function'==typeof e}},function(e,t,n){var o=n(1),r=n(0),a=n(35),i=n(9),s='prototype',d=function(e,t,n){var p=e&d.F,l=e&d.G,c=e&d.S,u=e&d.P,y=e&d.B,m=e&d.W,f=l?r:r[t]||(r[t]={}),_=f[s],h=l?o:c?o[t]:(o[t]||{})[s],g,v,b;for(g in l&&(n=t),n)v=!p&&h&&void 0!==h[g],v&&g in f||(b=v?h[g]:n[g],f[g]=l&&'function'!=typeof h[g]?n[g]:y&&v?a(b,o):m&&h[g]==b?function(e){var t=function(t,n,o){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n);}return new e(t,n,o)}return e.apply(this,arguments)};return t[s]=e[s],t}(b):u&&'function'==typeof b?a(Function.call,b):b,u&&((f.virtual||(f.virtual={}))[g]=b,e&d.R&&_&&!_[g]&&i(_,g,b)))};d.F=1,d.G=2,d.S=4,d.P=8,d.B=16,d.W=32,d.U=64,d.R=128,e.exports=d},function(e,t,n){var o=n(10),r=n(36),a=n(18),i=Object.defineProperty;t.f=n(5)?Object.defineProperty:function(e,t,n){if(o(e),t=a(t,!0),o(n),r)try{return i(e,t,n)}catch(t){}if('get'in n||'set'in n)throw TypeError('Accessors not supported!');return'value'in n&&(e[t]=n.value),e}},function(e,t,n){e.exports=!n(6)(function(){return 7!=Object.defineProperty({},'a',{get:function(){return 7}}).a})},function(e){e.exports=function(e){try{return!!e()}catch(t){return!0}}},function(e){var t={}.hasOwnProperty;e.exports=function(e,n){return t.call(e,n)}},function(e,t,n){var o=n(39),r=n(19);e.exports=function(e){return o(r(e))}},function(e,t,n){var o=n(4),r=n(12);e.exports=n(5)?function(e,t,n){return o.f(e,t,r(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var o=n(2);e.exports=function(e){if(!o(e))throw TypeError(e+' is not an object!');return e}},function(e,t,n){var o=n(22)('wks'),r=n(15),a=n(1).Symbol,i='function'==typeof a,s=e.exports=function(e){return o[e]||(o[e]=i&&a[e]||(i?a:r)('Symbol.'+e))};s.store=o},function(e){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var o=n(10),r=n(60),a=n(23),i=n(21)('IE_PROTO'),s=function(){},d='prototype',p=function(){var e=n(37)('iframe'),t=a.length,o='<',r='>',i;for(e.style.display='none',n(64).appendChild(e),e.src='javascript:',i=e.contentWindow.document,i.open(),i.write(o+'script'+r+'document.F=Object'+o+'/script'+r),i.close(),p=i.F;t--;)delete p[d][a[t]];return p()};e.exports=Object.create||function(e,t){var n;return null===e?n=p():(s[d]=o(e),n=new s,s[d]=null,n[i]=e),void 0===t?n:r(n,t)}},function(e,t,n){var o=n(38),r=n(23);e.exports=Object.keys||function(e){return o(e,r)}},function(e){var t=0,n=Math.random();e.exports=function(e){return'Symbol('.concat(e===void 0?'':e,')_',(++t+n).toString(36))}},function(e,t){t.f={}.propertyIsEnumerable},function(e){e.exports=function(e){if('function'!=typeof e)throw TypeError(e+' is not a function!');return e}},function(e,t,n){var o=n(2);e.exports=function(e,t){if(!o(e))return e;var n,r;if(t&&'function'==typeof(n=e.toString)&&!o(r=n.call(e)))return r;if('function'==typeof(n=e.valueOf)&&!o(r=n.call(e)))return r;if(!t&&'function'==typeof(n=e.toString)&&!o(r=n.call(e)))return r;throw TypeError('Can\'t convert object to primitive value')}},function(e){e.exports=function(e){if(e==void 0)throw TypeError('Can\'t call method on '+e);return e}},function(e){var t=Math.ceil,n=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(0s;)o(n,p=t[s++])&&(~a(d,p)||d.push(p));return d}},function(e,t,n){var o=n(40);e.exports=Object('z').propertyIsEnumerable(0)?Object:function(e){return'String'==o(e)?e.split(''):Object(e)}},function(e){var t={}.toString;e.exports=function(e){return t.call(e).slice(8,-1)}},function(e,t,n){var o=n(15)('meta'),r=n(2),a=n(7),i=n(4).f,s=0,d=Object.isExtensible||function(){return!0},p=!n(6)(function(){return d(Object.preventExtensions({}))}),l=function(e){i(e,o,{value:{i:'O'+ ++s,w:{}}})},c=e.exports={KEY:o,NEED:!1,fastKey:function(e,t){if(!r(e))return'symbol'==typeof e?e:('string'==typeof e?'S':'P')+e;if(!a(e,o)){if(!d(e))return'F';if(!t)return'E';l(e)}return e[o].i},getWeak:function(e,t){if(!a(e,o)){if(!d(e))return!0;if(!t)return!1;l(e)}return e[o].w},onFreeze:function(e){return p&&c.NEED&&d(e)&&!a(e,o)&&l(e),e}}},function(e,t,n){e.exports={default:n(79),__esModule:!0}},function(e,t,n){var o=n(7),r=n(26),a=n(21)('IE_PROTO'),i=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=r(e),o(e,a)?e[a]:'function'==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?i:null}},function(e,t,n){'use strict';function o(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var r=n(86),a=o(r),i=n(95),s=o(i),d='function'==typeof s.default&&'symbol'==typeof a.default?function(e){return typeof e}:function(e){return e&&'function'==typeof s.default&&e.constructor===s.default&&e!==s.default.prototype?'symbol':typeof e};t.default='function'==typeof s.default&&'symbol'===d(a.default)?function(e){return'undefined'==typeof e?'undefined':d(e)}:function(e){return e&&'function'==typeof s.default&&e.constructor===s.default&&e!==s.default.prototype?'symbol':'undefined'==typeof e?'undefined':d(e)}},function(e,t,n){'use strict';var o=n(28),r=n(3),a=n(46),i=n(9),s=n(7),d=n(29),p=n(90),l=n(30),c=n(43),u=n(11)('iterator'),y=!([].keys&&'next'in[].keys()),m='keys',f='values',_=function(){return this};e.exports=function(e,t,n,h,g,v,b){p(n,t,h);var k=function(e){return!y&&e in N?N[e]:e===m?function(){return new n(this,e)}:e===f?function(){return new n(this,e)}:function(){return new n(this,e)}},E=t+' Iterator',O=g==f,x=!1,N=e.prototype,C=N[u]||N['@@iterator']||g&&N[g],w=!y&&C||k(g),P=g?O?k('entries'):w:void 0,$='Array'==t?N.entries||C:C,A,D,T;if($&&(T=c($.call(new e)),T!==Object.prototype&&T.next&&(l(T,E,!0),!o&&!s(T,u)&&i(T,u,_))),O&&C&&C.name!==f&&(x=!0,w=function(){return C.call(this)}),(!o||b)&&(y||x||!N[u])&&i(N,u,w),d[t]=w,d[E]=_,g)if(A={values:O?w:k(f),keys:v?w:k(m),entries:P},b)for(D in A)D in N||a(N,D,A[D]);else r(r.P+r.F*(y||x),t,A);return A}},function(e,t,n){e.exports=n(9)},function(e,t,n){var o=n(38),r=n(23).concat('length','prototype');t.f=Object.getOwnPropertyNames||function(e){return o(e,r)}},function(e){function t(){throw new Error('setTimeout has not been defined')}function n(){throw new Error('clearTimeout has not been defined')}function o(e){if(l===setTimeout)return setTimeout(e,0);if((l===t||!l)&&setTimeout)return l=setTimeout,setTimeout(e,0);try{return l(e,0)}catch(t){try{return l.call(null,e,0)}catch(t){return l.call(this,e,0)}}}function r(e){if(c===clearTimeout)return clearTimeout(e);if((c===n||!c)&&clearTimeout)return c=clearTimeout,clearTimeout(e);try{return c(e)}catch(t){try{return c.call(null,e)}catch(t){return c.call(this,e)}}}function a(){y&&f&&(y=!1,f.length?u=f.concat(u):m=-1,u.length&&s())}function s(){if(!y){var e=o(a);y=!0;for(var t=u.length;t;){for(f=u,u=[];++marguments.length?e:a(arguments[2]);if(u&&!c)return l(e,t,n);if(e==n){switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3]);}var o=[null];return o.push.apply(o,t),new(p.apply(e,o))}var d=n.prototype,y=r(s(d)?d:Object.prototype),m=Function.apply.call(e,y,t);return s(m)?m:y}})},function(e,t,n){var o=n(4),r=n(10),a=n(14);e.exports=n(5)?Object.defineProperties:function(e,t){r(e);for(var n=a(t),s=n.length,d=0,i;s>d;)o.f(e,i=n[d++],t[i]);return e}},function(e,t,n){var o=n(8),r=n(62),a=n(63);e.exports=function(e){return function(t,n,i){var s=o(t),d=r(s.length),p=a(i,d),l;if(e&&n!=n){for(;d>p;)if(l=s[p++],l!=l)return!0;}else for(;d>p;p++)if((e||p in s)&&s[p]===n)return e||p||0;return!e&&-1}}},function(e,t,n){var o=n(20),r=Math.min;e.exports=function(e){return 0e?r(e+t,0):a(e,t)}},function(e,t,n){var o=n(1).document;e.exports=o&&o.documentElement},function(e,t,n){'use strict';var o=n(17),r=n(2),a=n(66),i=[].slice,s={},d=function(e,t,o){if(!(t in s)){for(var r=[],n=0;nd;)for(var c=s(arguments[d++]),u=p?o(c).concat(p(c)):o(c),y=u.length,m=0,f;y>m;)l.call(c,f=u[m++])&&(t[f]=c[f]);return t}:d},function(e,t,n){'use strict';t.__esModule=!0;var o=n(75),r=function(e){return e&&e.__esModule?e:{default:e}}(o);t.default=function(){function e(e,t){for(var n=0,o;n=e.length?{value:void 0,done:!0}:(n=o(e,t),this._i+=n.length,{value:n,done:!1})})},function(e,t,n){var o=n(20),r=n(19);e.exports=function(e){return function(t,n){var d=r(t)+'',s=o(n),i=d.length,p,a;return 0>s||s>=i?e?'':void 0:(p=d.charCodeAt(s),55296>p||56319(a=d.charCodeAt(s+1))||57343=e.length?(this._t=void 0,r(1)):'keys'==t?r(0,n):'values'==t?r(0,e[n]):r(0,[n,e[n]])},'values'),a.Arguments=a.Array,o('keys'),o('values'),o('entries')},function(e){e.exports=function(){}},function(e){e.exports=function(e,t){return{value:t,done:!!e}}},function(e,t,n){e.exports={default:n(96),__esModule:!0}},function(e,t,n){n(97),n(101),n(102),n(103),e.exports=n(0).Symbol},function(e,t,n){'use strict';var o=n(1),r=n(7),a=n(5),i=n(3),s=n(46),d=n(41).KEY,p=n(6),l=n(22),c=n(30),u=n(15),y=n(11),m=n(31),f=n(32),_=n(98),h=n(99),g=n(10),v=n(2),b=n(8),O=n(18),E=n(12),x=n(13),N=n(100),C=n(27),w=n(4),P=n(14),$=C.f,A=w.f,D=N.f,T=o.Symbol,S=o.JSON,I=S&&S.stringify,V='prototype',M=y('_hidden'),L=y('toPrimitive'),R={}.propertyIsEnumerable,F=l('symbol-registry'),z=l('symbols'),H=l('op-symbols'),U=Object[V],K='function'==typeof T,Y=o.QObject,B=!Y||!Y[V]||!Y[V].findChild,G=a&&p(function(){return 7!=x(A({},'a',{get:function(){return A(this,'a',{value:7}).a}})).a})?function(e,t,n){var o=$(U,t);o&&delete U[t],A(e,t,n),o&&e!==U&&A(U,t,o)}:A,W=function(e){var t=z[e]=x(T[V]);return t._k=e,t},q=K&&'symbol'==typeof T.iterator?function(e){return'symbol'==typeof e}:function(e){return e instanceof T},J=function(e,t,n){return e===U&&J(H,t,n),g(e),t=O(t,!0),g(n),r(z,t)?(n.enumerable?(r(e,M)&&e[M][t]&&(e[M][t]=!1),n=x(n,{enumerable:E(0,!1)})):(!r(e,M)&&A(e,M,E(1,{})),e[M][t]=!0),G(e,t,n)):A(e,t,n)},X=function(e,t){g(e);for(var n=_(t=b(t)),o=0,r=n.length,a;r>o;)J(e,a=n[o++],t[a]);return e},Q=function(e){var t=R.call(this,e=O(e,!0));return this===U&&r(z,e)&&!r(H,e)?!1:t||!r(this,e)||!r(z,e)||r(this,M)&&this[M][e]?t:!0},Z=function(e,t){if(e=b(e),t=O(t,!0),e!==U||!r(z,t)||r(H,t)){var n=$(e,t);return n&&r(z,t)&&!(r(e,M)&&e[M][t])&&(n.enumerable=!0),n}},ee=function(e){for(var t=D(b(e)),n=[],o=0,a;t.length>o;)r(z,a=t[o++])||a==M||a==d||n.push(a);return n},te=function(e){for(var t=e===U,n=D(t?H:b(e)),o=[],a=0,i;n.length>a;)r(z,i=n[a++])&&(!t||r(U,i))&&o.push(z[i]);return o};K||(T=function(){if(this instanceof T)throw TypeError('Symbol is not a constructor!');var e=u(0oe;)y(ne[oe++]);for(var j=P(y.store),re=0;j.length>re;)f(j[re++]);i(i.S+i.F*!K,'Symbol',{for:function(e){return r(F,e+='')?F[e]:F[e]=T(e)},keyFor:function(e){if(!q(e))throw TypeError(e+' is not a symbol!');for(var t in F)if(F[t]===e)return t},useSetter:function(){B=!0},useSimple:function(){B=!1}}),i(i.S+i.F*!K,'Object',{create:function(e,t){return t===void 0?x(e):X(x(e),t)},defineProperty:J,defineProperties:X,getOwnPropertyDescriptor:Z,getOwnPropertyNames:ee,getOwnPropertySymbols:te}),S&&i(i.S+i.F*(!K||p(function(){var e=T();return'[null]'!=I([e])||'{}'!=I({a:e})||'{}'!=I(Object(e))})),'JSON',{stringify:function(e){for(var t=[e],n=1,o,r;arguments.length>n;)t.push(arguments[n++]);if(r=o=t[1],(v(o)||void 0!==e)&&!q(e))return h(o)||(o=function(e,t){if('function'==typeof r&&(t=r.call(this,e,t)),!q(t))return t}),t[1]=o,I.apply(S,t)}}),T[V][L]||n(9)(T[V],L,T[V].valueOf),c(T,'Symbol'),c(Math,'Math',!0),c(o.JSON,'JSON',!0)},function(e,t,n){var o=n(14),r=n(25),a=n(16);e.exports=function(e){var t=o(e),n=r.f;if(n)for(var s=n(e),d=a.f,p=0,i;s.length>p;)d.call(e,i=s[p++])&&t.push(i);return t}},function(e,t,n){var o=n(40);e.exports=Array.isArray||function(e){return'Array'==o(e)}},function(e,t,n){var o=n(8),r=n(47).f,a={}.toString,i='object'==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(e){try{return r(e)}catch(t){return i.slice()}};e.exports.f=function(e){return i&&'[object Window]'==a.call(e)?s(e):r(o(e))}},function(){},function(e,t,n){n(32)('asyncIterator')},function(e,t,n){n(32)('observable')},function(e,t,n){'use strict';function o(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var r=n(105),a=o(r),i=n(109),s=o(i),d=n(44),p=o(d);t.default=function(e,t){if('function'!=typeof t&&null!==t)throw new TypeError('Super expression must either be null or a function, not '+('undefined'==typeof t?'undefined':(0,p.default)(t)));e.prototype=(0,s.default)(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(a.default?(0,a.default)(e,t):e.__proto__=t)}},function(e,t,n){e.exports={default:n(106),__esModule:!0}},function(e,t,n){n(107),e.exports=n(0).Object.setPrototypeOf},function(e,t,n){var o=n(3);o(o.S,'Object',{setPrototypeOf:n(108).set})},function(e,t,n){var o=n(2),r=n(10),a=function(e,t){if(r(e),!o(t)&&null!==t)throw TypeError(t+': can\'t set as prototype!')};e.exports={set:Object.setPrototypeOf||('__proto__'in{}?function(e,t,o){try{o=n(35)(Function.call,n(27).f(Object.prototype,'__proto__').set,2),o(e,[]),t=!(e instanceof Array)}catch(n){t=!0}return function(e,n){return a(e,n),t?e.__proto__=n:o(e,n),e}}({},!1):void 0),check:a}},function(e,t,n){e.exports={default:n(110),__esModule:!0}},function(e,t,n){n(111);var o=n(0).Object;e.exports=function(e,t){return o.create(e,t)}},function(e,t,n){var o=n(3);o(o.S,'Object',{create:n(13)})},function(e,t,n){'use strict';var o=Math.max;(function(n,e,r){function s(e){return e===void 0||null===e}function d(e){return e!==void 0&&null!==e}function u(e){return!0===e}function a(e){return!1===e}function l(e){return'string'==typeof e||'number'==typeof e||'symbol'==typeof e||'boolean'==typeof e}function c(e){return null!==e&&'object'==typeof e}function y(e){return co.call(e).slice(8,-1)}function m(e){return'[object Object]'===co.call(e)}function i(e){return'[object RegExp]'===co.call(e)}function f(e){var t=parseFloat(e+'');return 0<=t&&Math.floor(t)===t&&isFinite(e)}function _(e){return null==e?'':'object'==typeof e?JSON.stringify(e,null,2):e+''}function h(e){var t=parseFloat(e);return isNaN(t)?e:t}function g(e,t){for(var n=Object.create(null),o=e.split(','),r=0;rVr)){Bo('You may have an infinite update loop '+(e.user?'in watcher with expression "'+e.expression+'"':'in a component render function.'),e.vm);break}var o=Lr.slice(),r=Mr.slice();Be(),Je(o),We(r),Ho&&No.devtools&&Ho.emit('flush')}function We(e){for(var t=e.length;t--;){var n=e[t],o=n.vm;o._watcher===n&&o._isMounted&&Ye(o,'updated')}}function qe(e){e._inactive=!1,Lr.push(e)}function Je(e){for(var t=0;tHr&&Mr[n].id>e.id;)n--;Mr.splice(n+1,0,e)}Fr||(Fr=!0,fe(Ge))}}function Qe(e,t,n){Br.get=function(){return this[t][n]},Br.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Br)}function Ze(e){e._watchers=[];var t=e.$options;t.props&&et(e,t.props),t.methods&&it(e,t.methods),t.data?tt(e):z(e._data={},!0),t.computed&&ot(e,t.computed),t.watch&&t.watch!==jo&&st(e,t.watch)}function et(e,t){var o=e.$options.propsData||{},r=e._props={},a=e.$options._propKeys=[],i=!e.$parent;pr.shouldConvert=i;var s=function(i){a.push(i);var s=re(i,t,o,e);if('production'!==n.env.NODE_ENV){var d=vo(i);(yo(d)||No.isReservedAttr(d))&&Bo('"'+d+'" is a reserved attribute and cannot be used as component prop.',e),H(r,i,s,function(){e.$parent&&!Ir&&Bo('Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop\'s value. Prop being mutated: "'+i+'"',e)})}else H(r,i,s);i in e||Qe(e,'_props',i)};for(var d in t)s(d);pr.shouldConvert=!0}function tt(e){var t=e.$options.data;t=e._data='function'==typeof t?nt(t,e):t||{},m(t)||(t={},'production'!==n.env.NODE_ENV&&Bo('data functions should return an object:\nhttps://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',e));for(var o=Object.keys(t),r=e.$options.props,a=e.$options.methods,s=o.length;s--;){var i=o[s];'production'!==n.env.NODE_ENV&&a&&b(a,i)&&Bo('Method "'+i+'" has already been defined as a data property.',e),r&&b(r,i)?'production'!==n.env.NODE_ENV&&Bo('The data property "'+i+'" is already declared as a prop. Use prop default value instead.',e):!A(i)&&Qe(e,'_data',i)}z(t,!0)}function nt(e,t){try{return e.call(t,t)}catch(n){return le(n,t,'data()'),{}}}function ot(e,t){var o=e._computedWatchers=Object.create(null),r=zo();for(var a in t){var i=t[a],s='function'==typeof i?i:i.get;'production'!==n.env.NODE_ENV&&null==s&&Bo('Getter is missing for computed property "'+a+'".',e),r||(o[a]=new Kr(e,s||C,C,Gr)),a in e?'production'!==n.env.NODE_ENV&&(a in e.$data?Bo('The computed property "'+a+'" is already defined in data.',e):e.$options.props&&a in e.$options.props&&Bo('The computed property "'+a+'" is already defined as a prop.',e)):rt(e,a,i)}}function rt(e,t,o){var r=!zo();'function'==typeof o?(Br.get=r?at(t):o,Br.set=C):(Br.get=o.get?r&&!1!==o.cache?at(t):o.get:C,Br.set=o.set?o.set:C),'production'!==n.env.NODE_ENV&&Br.set===C&&(Br.set=function(){Bo('Computed property "'+t+'" was assigned to but it has no setter.',this)}),Object.defineProperty(e,t,Br)}function at(e){return function(){var t=this._computedWatchers&&this._computedWatchers[e];if(t)return t.dirty&&t.evaluate(),tr.target&&t.depend(),t.value}}function it(e,t){var o=e.$options.props;for(var r in t)'production'!==n.env.NODE_ENV&&(null==t[r]&&Bo('Method "'+r+'" has an undefined value in the component definition. Did you reference the function correctly?',e),o&&b(o,r)&&Bo('Method "'+r+'" has already been defined as a prop.',e),r in e&&A(r)&&Bo('Method "'+r+'" conflicts with an existing Vue instance method. Avoid defining component methods that start with _ or $.')),e[r]=null==t[r]?C:E(t[r],e)}function st(e,t){for(var n in t){var o=t[n];if(Array.isArray(o))for(var r=0;rn.indexOf(e[r]))&&o.push(e[r]);return o}return e}function Rt(e){'production'===n.env.NODE_ENV||this instanceof Rt||Bo('Vue is a constructor and should be called with the `new` keyword'),this._init(e)}function Ft(e){e.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(-1a[n].indexOf(r)&&a[n].push(r):a[n]=[r]:a[n]=r}}function an(e,t){return e.key===t.key&&(e.tag===t.tag&&e.isComment===t.isComment&&d(e.data)===d(t.data)&&sn(e,t)||u(e.isAsyncPlaceholder)&&e.asyncFactory===t.asyncFactory&&s(t.asyncFactory.error))}function sn(e,t){if('input'!==e.tag)return!0;var n=d(r=e.data)&&d(r=r.attrs)&&r.type,o=d(r=t.data)&&d(r=r.attrs)&&r.type,r;return n===o||fa(n)&&fa(o)}function dn(e,t,n){var o={},r,a;for(r=t;r<=n;++r)a=e[r].key,d(a)&&(o[a]=r);return o}function pn(e,t){(e.data.directives||t.data.directives)&&ln(e,t)}function ln(e,t){var n=e===ha,o=cn(e.data.directives,e.context),r=cn(t.data.directives,t.context),a=[],s=[],i,d,p;for(i in r)d=o[i],p=r[i],d?(p.oldValue=d.value,yn(p,'update',t,e),p.def&&p.def.componentUpdated&&s.push(p)):(yn(p,'bind',t,e),p.def&&p.def.inserted&&a.push(p));if(a.length){var l=function(){for(var n=0;nn.indexOf(' '+t+' ')&&e.setAttribute('class',(n+t).trim())}}function Dn(e,t){if(t&&(t=t.trim()))if(e.classList)-1n.indexOf(t)&&(n.push(t),An(e,t))}function Vn(e,t){e._transitionClasses&&v(e._transitionClasses,t),Dn(e,t)}function Mn(t,e,n){var o=Ln(t,e),r=o.type,a=o.timeout,i=o.propCount;if(!r)return n();var s=r===Aa?Sa:Va,d=0,p=function(){t.removeEventListener(s,l),n()},l=function(n){n.target===t&&++d>=i&&p()};setTimeout(function(){dp?Aa:Da:null,c=u?u===Aa?a.length:d.length:0);var y=u===Aa&&Ra.test(n[Ta+'Property']);return{type:u,timeout:l,propCount:c,hasTransform:y}}function jn(e,t){for(;e.length explicit '+t+' duration is NaN - the duration expression might be incorrect.',n.context):Bo(' explicit '+t+' duration is not a valid number - got '+JSON.stringify(e)+'.',n.context)}function Un(e){return'number'==typeof e&&!isNaN(e)}function Kn(e){if(s(e))return!1;var t=e.fns;return d(t)?Kn(Array.isArray(t)?t[0]:t):1<(e._length||e.length)}function Yn(e,t){!0!==t.data.show&&Fn(t)}function Bn(e,t,n){Gn(e,t,n),(To||Io)&&setTimeout(function(){Gn(e,t,n)},0)}function Gn(e,t,o){var r=t.value,a=e.multiple;if(a&&!Array.isArray(r))return void('production'!==n.env.NODE_ENV&&Bo(' expects an Array value for its binding, but got '+Object.prototype.toString.call(r).slice(8,-1),o));for(var s=0,i=e.options.length,d,p;s';var n='function'==typeof e&&null!=e.cid?e.options:e._isVue?e.$options||e.constructor.options:e||{},o=n.name||n._componentTag,r=n.__file;if(!o&&r){var a=r.match(/([^/\\]+)\.vue$/);o=a&&a[1]}return(o?'<'+Qo(o)+'>':'')+(r&&!1!==t?' at '+r:'')};var Zo=function(e,t){for(var n='';t;)1==t%2&&(n+=e),1>=1;return n};Wo=function(e){if(e._isVue&&e.$parent){for(var t=[],n=0;e;){if(0 ':Zo(' ',5+2*t))+(Array.isArray(e)?qo(e[0])+'... ('+e[1]+' recursive calls)':qo(e))}).join('\n')}return'\n\n(found in '+qo(e)+')'}}var er=0,tr=function(){this.id=er++,this.subs=[]};tr.prototype.addSub=function(e){this.subs.push(e)},tr.prototype.removeSub=function(e){v(this.subs,e)},tr.prototype.depend=function(){tr.target&&tr.target.addDep(this)},tr.prototype.notify=function(){for(var e=this.subs.slice(),t=0,n=e.length;tparseInt(this.max)&&qt(d,p[0],p,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}},ta={KeepAlive:ea};(function(e){var t={};t.get=function(){return No},'production'!==n.env.NODE_ENV&&(t.set=function(){Bo('Do not replace the Vue.config object, set individual fields instead.')}),Object.defineProperty(e,'config',t),e.util={warn:Bo,extend:x,mergeOptions:ne,defineReactive:H},e.set=U,e.delete=K,e.nextTick=fe,e.options=Object.create(null),Oo.forEach(function(t){e.options[t+'s']=Object.create(null)}),e.options._base=e,x(e.options.components,ta),Ft(e),zt(e),Ht(e),Yt(e)})(Rt),Object.defineProperty(Rt.prototype,'$isServer',{get:zo}),Object.defineProperty(Rt.prototype,'$ssrContext',{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Rt.version='2.5.13';var na=g('style,class'),oa=g('input,textarea,option,select,progress'),ra=g('contenteditable,draggable,spellcheck'),aa=g('allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible'),ia='http://www.w3.org/1999/xlink',sa=function(e){return':'===e.charAt(5)&&'xlink'===e.slice(0,5)},da=function(e){return sa(e)?e.slice(6,e.length):''},pa=function(e){return null==e||!1===e},la={svg:'http://www.w3.org/2000/svg',math:'http://www.w3.org/1998/Math/MathML'},ca=g('html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot'),ua=g('svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',!0),ya=function(e){return ca(e)||ua(e)},ma=Object.create(null),fa=g('text,number,password,search,email,tel,url'),_a=Object.freeze({createElement:function(e,t){var n=document.createElement(e);return'select'===e?(t.data&&t.data.attrs&&void 0!==t.data.attrs.multiple&&n.setAttribute('multiple','multiple'),n):n},createElementNS:function(e,t){return document.createElementNS(la[e],t)},createTextNode:function(e){return document.createTextNode(e)},createComment:function(e){return document.createComment(e)},insertBefore:function(e,t,n){e.insertBefore(t,n)},removeChild:function(e,t){e.removeChild(t)},appendChild:function(e,t){e.appendChild(t)},parentNode:function(e){return e.parentNode},nextSibling:function(e){return e.nextSibling},tagName:function(e){return e.tagName},setTextContent:function(e,t){e.textContent=t},setAttribute:function(e,t,n){e.setAttribute(t,n)}}),ha=new or('',{},[]),ga=['create','activate','update','remove','destroy'],va=Object.create(null),ba='__r',ka='__c',Ea=k(function(e){var t={},n=/;(?![^(]*\))/g,o=/:(.+)/;return e.split(n).forEach(function(e){if(e){var n=e.split(o);1 - did you register the component correctly? For recursive components, make sure to provide the "name" option.',e.context)),e.elm=e.ns?I.createElementNS(e.ns,l):I.createElement(l,e),b(e),_(e,p,t),d(s)&&v(e,t),f(o,e.elm,r),'production'!==n.env.NODE_ENV&&s&&s.pre&&L--):u(e.isComment)?(e.elm=I.createComment(e.text),f(o,e.elm,r)):(e.elm=I.createTextNode(e.text),f(o,e.elm,r))}}function c(e,t,n,o){var r=e.data;if(d(r)){var a=d(e.componentInstance)&&r.keepAlive;if(d(r=r.hook)&&d(r=r.init)&&r(e,!1,n,o),d(e.componentInstance))return y(e,t),u(a)&&m(e,t,n,o),!0}}function y(e,t){d(e.data.pendingInsert)&&(t.push.apply(t,e.data.pendingInsert),e.data.pendingInsert=null),e.elm=e.componentInstance.$el,h(e)?(v(e,t),b(e)):(rn(e),t.push(e))}function m(e,t,n,o){for(var r=e,a;r.componentInstance;)if(r=r.componentInstance._vnode,d(a=r.data)&&d(a=a.transition)){for(a=0;ac?(E=s(o[m+1])?null:o[m+1].elm,k(e,E,o,l,m,r)):l>m&&O(e,t,i,c)}function C(e){for(var t={},n=0;n, or missing . Bailing hydration and performing full client-side render.')}e=t(e)}var _=e.elm,g=I.parentNode(_);if(p(o,m,_._leaveCb?null:g,I.nextSibling(_)),d(o.parent))for(var v=o.parent,b=h(o);v;){for(var k=0;k can only be used on a single element. Use for lists.',this.$parent);var r=this.mode;'production'!==n.env.NODE_ENV&&r&&'in-out'!==r&&'out-in'!==r&&Bo('invalid mode: '+r,this.$parent);var a=o[0];if(ro(this.$vnode))return a;var i=eo(a);if(!i)return a;if(this._leaving)return oo(e,a);var s='__transition-'+this._uid+'-';i.key=null==i.key?i.isComment?s+'comment':s+i.tag:l(i.key)?0===(i.key+'').indexOf(s)?i.key:s+i.key:i.key;var d=(i.data||(i.data={})).transition=to(this),p=this._vnode,c=eo(p);if(i.data.directives&&i.data.directives.some(function(e){return'show'===e.name})&&(i.data.show=!0),c&&c.data&&!ao(i,c)&&!Ae(c)&&!(c.componentInstance&&c.componentInstance._vnode.isComment)){var u=c.data.transition=x({},d);if('out-in'===r)return this._leaving=!0,be(u,'afterLeave',function(){t._leaving=!1,t.$forceUpdate()}),oo(e,a);if('in-out'===r){if(Ae(i))return p;var y=function(){m()},m;be(d,'afterEnter',y),be(d,'enterCancelled',y),be(u,'delayLeave',function(e){m=e})}}return a}}},TransitionGroup:{props:Ya,render:function(e){for(var t=this.tag||this.$vnode.data.tag||'span',o=Object.create(null),r=this.prevChildren=this.children,a=this.$slots.default||[],s=this.children=[],d=to(this),p=0,i;p children must be keyed: <'+c+'>')}if(r){for(var u=[],y=[],m=0,f;m",
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/trusktr/vue-web-component/issues"
23 | },
24 | "homepage": "https://github.com/trusktr/vue-web-component#readme",
25 | "dependencies": {
26 | "skatejs": "^5.1.1",
27 | "vue": "^2.5.11"
28 | },
29 | "devDependencies": {
30 | "@skatejs/bore": "^4.0.3",
31 | "@skatejs/ssr": "^0.19.1",
32 | "@skatejs/val": "^0.4.0",
33 | "builder": "^3.2.3",
34 | "builder-js-package": "trusktr/builder-js-package"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import { withLifecycle, withUpdate, withRenderer, props as skatePropTypes } from 'skatejs'
3 |
4 | // create a Custom Element class from a Vue component
5 | export default
6 | function VueWebComponent( vueComponent, ElementClass ) {
7 | ElementClass = ElementClass || class extends HTMLElement {}
8 |
9 | // NOTE! This mutates the given component spec, see
10 | // https://github.com/vuejs/vue/issues/7494. We do this up front (instead of
11 | // lazily in the element's renderer callback) so that when we're ready to
12 | // work with the spec it has already been mutated and there won't be any
13 | // surprises (or uglier code that conditionally checks for both forms of the
14 | // spec).
15 | const Component = Vue.extend( vueComponent )
16 |
17 | // map from Vue prop types to SkateJS prop types
18 | const vuePropTypes = makeVuePropTypes( vueComponent.props )
19 |
20 | // contains scope ID of this element's Vue component as well as sub component
21 | // IDs
22 | const scopeIds = getAllScopeIds( vueComponent )
23 |
24 | // this will contain all CSS rules for this element's Vue component and
25 | // sub-components
26 | let matchingRules = null
27 |
28 | return class VueWebComponent extends withUpdate( withRenderer( ElementClass ) ) {
29 |
30 | constructor(...args) {
31 | super(...args)
32 |
33 | console.log(' --- VueWebComponent.constructor')
34 |
35 | this.vue_instance = new Component
36 | this.vue_instancePromise = null
37 | this.vue_mounted = false
38 | }
39 |
40 | /**
41 | * Define a renderer that mounts a Vue component in this element's shadow
42 | * root.
43 | */
44 | renderer( root, render ) {
45 | console.log(' --- VueWebComponent.renderer')
46 | if ( this.vue_mounted ) return
47 |
48 | // mount the component
49 | this.vue_mountComponent( root )
50 |
51 | // bring in the global styling
52 | requestAnimationFrame(() => this.vue_applyStyle( root ))
53 | }
54 |
55 | /**
56 | * mount a Vue `component` inside the given `container`. This is analgous
57 | * to ReactDOM.render.
58 | */
59 | vue_mountComponent( container ) {
60 | console.log(' --- VueWebComponent.vue_mountComponent')
61 |
62 | // `tmp` will get replaced by the DOM generated from the component
63 | const tmp = document.createElement( 'tmp' )
64 | tmp.style.display = 'none'
65 | container.appendChild( tmp )
66 |
67 | this.vue_instance.$mount( tmp )
68 |
69 | this.vue_mounted = true
70 | }
71 |
72 | /**
73 | * finds the global style that contains this element's Vue instance's style
74 | * and style of its sub-components and copies the styles into this
75 | * element's shadow root, otherwise the global style will not penetrate
76 | * into the shadow root.
77 | */
78 | vue_applyStyle( root ) {
79 | console.log(' --- VueWebComponent.vue_applyStyle')
80 |
81 | // if no components have scoped style
82 | if (! scopeIds.length ) return
83 |
84 | const newStyle = document.createElement( 'style' )
85 |
86 | // WebKit hack, requires appending a text node
87 | newStyle.appendChild(document.createTextNode('/* Vue styles are inside this element\'s CSSStyleSheet */'))
88 |
89 | // newStyle.sheet won't exist unless the element is first appended
90 | root.appendChild( newStyle )
91 | const newSheet = newStyle.sheet
92 | const newRules = newSheet.cssRules || newSheet.rules
93 |
94 | // we have to initialize this here (not outside the class) because global
95 | // styles are added to DOM after the first Vue instance is created
96 | if (! matchingRules ) matchingRules = getMatchingCSSRules( scopeIds )
97 |
98 | for ( const rule of matchingRules )
99 | newSheet.insertRule(rule.cssText, newRules.length)
100 |
101 | // TODO: make sure this works with conditional content. Maybe
102 | // conditional content that isn't rendered yet doesn't have it's
103 | // styles inserted into DOM???
104 |
105 | }
106 |
107 | static get props() { return vuePropTypes }
108 |
109 | updated( prevProps, prevState ) {
110 | console.log(' --- VueWebComponent.updated')
111 | super.updated( prevProps, prevState )
112 |
113 | // pass this.props as first arg, whose keys are iterated on in
114 | // forChangedProps, otherwise nothing happens the first time
115 | // because prevProps is empty at first.
116 | forChangedProps( this.props, prevProps, ( name, oldVal ) => {
117 | // pass the value along
118 | this.vue_instance[ name ] = this[ name ]
119 | })
120 | }
121 |
122 | }
123 |
124 | }
125 |
126 | // a hack class used so we don't conflict with Vue's builtin component. Is there a better way?
127 | class RealSlot extends withLifecycle( withUpdate( HTMLElement ) ) {
128 | constructor(...args) {
129 | super(...args)
130 | this.style.display = 'contents'
131 | }
132 |
133 | connected() {
134 | if (this.actualSlot) return
135 | this.actualSlot = document.createElement('slot')
136 | this.appendChild(this.actualSlot)
137 | }
138 |
139 | static get props() {
140 | return {
141 | name: Object.assign({}, skatePropTypes.string, {attribute: true} )
142 | }
143 | }
144 |
145 | updated(prevProps) {
146 | if ( this.name && this.name !== prevProps.name )
147 | this.actualSlot.setAttribute('name', this.name)
148 | }
149 | }
150 | customElements.define('real-slot', RealSlot)
151 |
152 | function makeVuePropTypes( vueProps ) {
153 | console.log(' --- makeVuePropTypes')
154 | if (! vueProps ) return {}
155 |
156 | const result = {}
157 |
158 | const warn = () => console.warn('vue-web-component: The Vue component that you converted into a custom element will receive only string values from the "'+key+'" attribute. If you\'d like string values from attributes coerced into a certain type, define that type in your Vue component. For example: props: { "'+key+'": Number }')
159 |
160 | function getDefault( vueProp ) {
161 | // TODO: calling the default value factory and using that single value
162 | // causes all instanced of the element to use the same cached value for
163 | // Objects and Arrays. How to fix?
164 | if (typeof vueProp.default == 'function')
165 | return Object.freeze(vueProp.default())
166 | else
167 | return vueProp.default
168 | }
169 |
170 | for ( const key in vueProps ) {
171 | const prop = vueProps[ key ]
172 | const defaultVal = getDefault(prop)
173 |
174 | if ( prop.type === null ) {
175 | result[ key ] = skatePropTypes.any
176 | warn()
177 | console.warn('vue-web-component: You did not specify a prop type for the attribute mentioned in the previous warning. Any values for this attribute will be passed as a string value to the Vue component.')
178 | }
179 | else if ( prop.type === Number )
180 | result[ key ] = Object.assign({}, skatePropTypes.number, {default:defaultVal})
181 | else if ( prop.type === String )
182 | result[ key ] = Object.assign({}, skatePropTypes.string, {default:defaultVal})
183 | else if ( prop.type === Boolean )
184 | result[ key ] = Object.assign({}, skatePropTypes.boolean, {default:defaultVal})
185 | else if ( prop.type === Object )
186 | result[ key ] = Object.assign({}, skatePropTypes.object, {default:defaultVal})
187 | else if ( prop.type === Array )
188 | result[ key ] = Object.assign({}, skatePropTypes.array, {default:defaultVal})
189 | else {
190 | result[ key ] = skatePropTypes.any
191 | warn()
192 | console.warn('vue-web-component: You specified a type in your Vue component that is currently is not supported by vue-web-component. Any values for the attribute mentioned in the previous warning will be passed as string value to the Vue component.')
193 | }
194 |
195 | }
196 |
197 | return result
198 |
199 | }
200 |
201 | function getAllScopeIds( vueComponent ) {
202 | console.log(' --- getAllScopeIds')
203 |
204 | const result = []
205 |
206 | ~function _getAllScopeIds( vueComponent ) {
207 |
208 | if ( vueComponent._scopeId ) result.push( vueComponent._scopeId )
209 |
210 | for ( const subComponent in vueComponent.components )
211 | _getAllScopeIds( vueComponent.components[ subComponent ] )
212 |
213 | }( vueComponent )
214 |
215 | return result
216 |
217 | }
218 |
219 | function getMatchingCSSRules( scopeIds ) {
220 | console.log(' --- getMatchingCSSRules')
221 | const sheets = document.styleSheets
222 |
223 | const result = []
224 |
225 | Array.prototype.forEach.call( sheets, sheet => {
226 | const rules = sheet.cssRules || sheet.rules
227 |
228 | Array.prototype.forEach.call( rules, rule => {
229 |
230 | if ( scopeIds.some( id => rule.selectorText.indexOf( id ) > -1 ) ) {
231 | result.push( rule )
232 | }
233 |
234 | })
235 |
236 | })
237 |
238 | return result
239 | }
240 |
241 | function forChangedProps(oldProps, newProps, action) {
242 | console.log(' --- forChangedProps')
243 | for ( const oldKey in oldProps )
244 | if ( oldProps[ oldKey ] !== newProps[ oldKey ] )
245 | action( oldKey, oldProps[ oldKey ] )
246 | }
247 |
248 | // IMPORTANT! keep this line as the last line, it is auto-generated from package.json version.
249 | export const version = '1.2.0'
250 |
--------------------------------------------------------------------------------
/src/test.js:
--------------------------------------------------------------------------------
1 | import { mount } from '@skatejs/bore'
2 | import { h } from '@skatejs/val'
3 | import VueWebComponent from '.'
4 |
5 | const template = h('div', {}, '{{msg}} {{name}}!')
6 |
7 | const TestVue = {
8 | template,
9 | props: {
10 | name: {
11 | type: String,
12 | default: 'World',
13 | },
14 | },
15 | data: () => (console.log('SET UP THE DATA'), {
16 | msg: 'Hello'
17 | }),
18 | }
19 |
20 | const TestElement = VueWebComponent( TestVue )
21 | customElements.define('test-element', TestElement)
22 |
23 | test('VueWebComponent props', done => {
24 | const el = document.createElement('test-element')
25 |
26 | setTimeout(() => {
27 | console.log('TestElement content:', el.outerHTML)
28 | expect( el.nodeName.toLowerCase() ).toBe( 'test-element' )
29 | done()
30 | }, 1000)
31 | })
32 |
--------------------------------------------------------------------------------