├── .babelrc ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .npmignore ├── .nvmrc ├── .prettierignore ├── .yo-rc.json ├── LICENSE ├── README.md ├── config.json ├── dist ├── index.html └── vue-pell-editor.js ├── jest.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── prettier.config.js ├── src ├── js │ ├── app.vue │ ├── components │ │ └── VuePellEditor.vue │ ├── main.ts │ ├── shims-tsx.d.ts │ ├── shims-vue.d.ts │ └── vue-pell-editor.ts └── structure │ ├── index.html │ └── readme.txt ├── tests └── unit │ └── example.spec.js ├── tsconfig.json ├── tslint.json ├── webpack ├── stats.json ├── utils.js ├── webpack.config.base.babel.js ├── webpack.dev.babel.js └── webpack.prod.babel.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", { 5 | "useBuiltIns": "entry", 6 | "debug": false 7 | }] 8 | ], 9 | "plugins": [ 10 | "@babel/plugin-syntax-dynamic-import", 11 | "@babel/plugin-proposal-class-properties", 12 | "@babel/plugin-proposal-object-rest-spread" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 0.25% 2 | IE 11 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.php] 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parserOptions: { 6 | parser: 'typescript-eslint-parser', 7 | ecmaVersion: 2017, 8 | sourceType: 'module' 9 | }, 10 | env: { 11 | browser: true, 12 | node: true, 13 | es6: true, 14 | jquery: true, 15 | jest: true 16 | }, 17 | extends: [ 18 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 19 | 'standard', 20 | 'plugin:vue/recommended', 21 | 'plugin:prettier/recommended' 22 | ], 23 | plugins: ['typescript'], 24 | // check if imports actually resolve 25 | settings: { 26 | 'import/resolver': { 27 | webpack: { 28 | config: 'webpack/webpack.prod.babel.js' 29 | } 30 | } 31 | }, 32 | rules: { 33 | indent: 0, 34 | 'no-console': 0, 35 | 'object-curly-spacing': 0, 36 | 'space-before-function-paren': 0 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Node ### 2 | 3 | # Logs 4 | logs 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Optional npm cache directory 10 | .npm 11 | .config 12 | .node* 13 | 14 | # Dependency directories 15 | /node_modules 16 | /jspm_packages 17 | /bower_components 18 | 19 | # Yarn Integrity file 20 | .yarn-integrity 21 | 22 | # Optional eslint cache 23 | .eslintcache 24 | 25 | # dotenv environment variables file(s) 26 | .env 27 | .env.* 28 | 29 | # Build generated 30 | 31 | dist/index.html 32 | dist/app.css 33 | dist/app.js 34 | build/ 35 | doc/ 36 | 37 | # Map-Files 38 | *.js.map 39 | 40 | ### Sass-Files ### 41 | *.sassc 42 | .sass-cache 43 | *.css.map 44 | 45 | ### SublimeText ### 46 | # cache files for sublime text 47 | *.tmlanguage.cache 48 | *.tmPreferences.cache 49 | *.stTheme.cache 50 | 51 | ### Test Results ### 52 | tests/e2e/screenshots 53 | tests/e2e/videos 54 | 55 | # workspace files are user-specific 56 | *.sublime-workspace 57 | 58 | # project files should be checked into the repository, unless a significant 59 | # proportion of contributors will probably not be using SublimeText 60 | # *.sublime-project 61 | 62 | 63 | ### VisualStudioCode ### 64 | .vscode/* 65 | .v8flags.* 66 | !.vscode/settings.json 67 | !.vscode/tasks.json 68 | !.vscode/launch.json 69 | !.vscode/extensions.json 70 | 71 | ### WebStorm/IntelliJ ### 72 | /.idea 73 | modules.xml 74 | *.ipr 75 | 76 | 77 | ### System Files ### 78 | .DS_Store 79 | 80 | # Windows thumbnail cache files 81 | Thumbs.db 82 | ehthumbs.db 83 | ehthumbs_vista.db 84 | 85 | # Folder config file 86 | Desktop.ini 87 | 88 | # Recycle Bin used on file shares 89 | $RECYCLE.BIN/ 90 | 91 | # Thumbnails 92 | ._* 93 | 94 | # Files that might appear in the root of a volume 95 | .DocumentRevisions-V100 96 | .fseventsd 97 | .Spotlight-V100 98 | .TemporaryItems 99 | .Trashes 100 | .VolumeIcon.icns 101 | .com.apple.timemachine.donotpresent 102 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tests 2 | webpack 3 | dist/*.html 4 | dist/app.js 5 | src/structure 6 | src/js/app.vue 7 | src/js/main.ts 8 | src/js/shims-* 9 | .* 10 | *.config.js 11 | config.json 12 | tsconfig.json 13 | tslint.json 14 | *.lock 15 | package-lock.json 16 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.scss 2 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-kittn": { 3 | "promptValues": { 4 | "projectusage": "webpackApp", 5 | "projectcssstructure": "sassAtomic", 6 | "projectbreakpointunit": "em", 7 | "projectthemecolor": "#29b8f2", 8 | "projectstylelint": false, 9 | "projectprettier": true, 10 | "projecttypescript": true, 11 | "projecttestingunit": true, 12 | "projecttestinge2e": false, 13 | "projecttestingwallaby": false, 14 | "projectversion": "0.0.1", 15 | "projectmail": "larseichler.le@gmail.com", 16 | "projecturl": "https://github.com/CinKon/vue-pell-editor.git" 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Lars Eichler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-pell-editor 2 | 3 | > Vue wrapper for [pell WYSIWYG text editor](https://github.com/jaredreich/pell) 4 | 5 | ## Installation 6 | 7 | **Install via NPM or Yarn:** 8 | 9 | ```shell 10 | $ npm install --save vue-pell-editor 11 | # OR 12 | $ yarn add vue-pell-editor 13 | ``` 14 | 15 | ## Usage 16 | 17 | main.js: 18 | 19 | ```javascript 20 | import Vue from 'vue' 21 | import VuePellEditor from 'vue-pell-editor' 22 | 23 | Vue.use(VuePellEditor) 24 | ``` 25 | 26 | example.vue: 27 | 28 | ```vue 29 | 42 | 43 | 93 | ``` 94 | 95 | For the pell-editor-options have a look at the [pell repository](https://github.com/jaredreich/pell#api). 96 | 97 | ## License 98 | 99 | vue-pell-editor is open source and released under the [MIT License](LICENSE). 100 | 101 | Copyright (c) 2018 [Lars Eichler](https://twitter.com/cinkon). 102 | 103 | > _PS: You're a happy user of vue-pell-editor? Let me know via Twitter: [@cinkon](https://twitter.com/cinkon)_. 104 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "dist": { 3 | "img": "dist/img/", 4 | "dist": "dist/", 5 | "base": "dist/", 6 | "markup": "dist/", 7 | "assets": "dist/", 8 | "browserSyncDir": "dist/", 9 | "css": "dist/", 10 | "js": "dist/", 11 | "fonts": "dist/", 12 | "cssimg": "dist/", 13 | "bitmaps": "dist/assets/img/bitmaps/", 14 | "vectors": "dist/assets/img/svgfiles/", 15 | "contentimage": "dist/images/", 16 | "webpackassets": "./", 17 | "webpackpublic": "dist/" 18 | }, 19 | "template": { 20 | "globalTitle": "vue-pell-editor", 21 | "compiler": false 22 | }, 23 | "browsersync": { 24 | "openbrowser": false, 25 | "port": 3000 26 | }, 27 | "minify": { 28 | "images": { 29 | "svgoPlugins": [ 30 | { 31 | "cleanupIDs": false 32 | }, 33 | { 34 | "removeComments": true 35 | }, 36 | { 37 | "removeViewBox": false 38 | }, 39 | { 40 | "removeDesc": true 41 | }, 42 | { 43 | "removeUselessDefs": false 44 | }, 45 | { 46 | "removeDoctype": true 47 | }, 48 | { 49 | "removeEmptyText": true 50 | }, 51 | { 52 | "removeUnknownsAndDefaults": true 53 | }, 54 | { 55 | "removeEmptyContainers": true 56 | }, 57 | { 58 | "collapseGroups": true 59 | }, 60 | { 61 | "removeUselessStrokeAndFill": true 62 | }, 63 | { 64 | "convertStyleToAttrs": true 65 | } 66 | ] 67 | } 68 | }, 69 | "src": { 70 | "baseconf": { 71 | "type": "webpackApp", 72 | "methodology": "sassAtomic", 73 | "structure": "uncompiled", 74 | "themeColor": "#29b8f2" 75 | }, 76 | "base": "src/", 77 | "style": "src/style/", 78 | "template": "src/template/", 79 | "js": "src/js/", 80 | "scripts": "src/scripts", 81 | "structure": "src/structure/", 82 | "fonts": "src/fonts/", 83 | "images": { 84 | "base": "src/images/", 85 | "bitmapSprite": { 86 | "files": "src/images/bitmapSprite-assets/", 87 | "name": "sprite.png" 88 | }, 89 | "vectorSprite": { 90 | "files": "src/images/vectorSprite-assets/", 91 | "name": "vector-sprite.svg", 92 | "symbolName": "symbol-sprite.svg", 93 | "maxHeight": 30, 94 | "maxWidth": 30, 95 | "padding": 0 96 | }, 97 | "bitmaps": "src/images/bitmapSingle-assets/", 98 | "vectors": "src/images/vectorSingle-assets/" 99 | }, 100 | "contentimage": "src/images/htmlimages/", 101 | "system": "src/.system/", 102 | "jsEntryPoints": { 103 | "app": "./src/js/main.ts", 104 | "vue-pell-editor": "./src/js/vue-pell-editor.ts" 105 | } 106 | }, 107 | "files": { 108 | "launch": [ 109 | { 110 | "src": "favicons/**", 111 | "dest": "assets/img/system/" 112 | }, 113 | { 114 | "src": "facebook-og-image.jpg", 115 | "dest": "assets/img/system/" 116 | }, 117 | { 118 | "src": "twitter-og-image.jpg", 119 | "dest": "assets/img/system/" 120 | }, 121 | { 122 | "src": ".htaccess", 123 | "dest": "" 124 | }, 125 | { 126 | "src": "404.html", 127 | "dest": "" 128 | }, 129 | { 130 | "src": "robots.txt", 131 | "dest": "" 132 | } 133 | ] 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | vue-pell-editor

Hello World

-------------------------------------------------------------------------------- /dist/vue-pell-editor.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.VuePellEditor=e():t.VuePellEditor=e()}(window,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="./",n(n.s=83)}({23:function(t,e,n){"use strict";n.r(e);var r=n(24),o=n.n(r);for(var i in r)"default"!==i&&function(t){n.d(e,t,function(){return r[t]})}(i);e.default=o.a},24:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var r=function(t){return t&&t.__esModule?t:{default:t}}(n(85));var o={name:"VuePellEditor",props:{actions:{type:Array,default:function(){return[]}},content:{type:String,default:""},value:{type:String,default:""},placeholder:{type:String,default:"Write something amazing..."},editorHeight:{type:String,default:""},styleWithCss:{type:Boolean,default:!1},classes:{type:Object,default:function(){}},defaultParagraphSeparator:{type:String,default:"div"}},data:function(){return{vpContent:"",pell:void 0}},watch:{content:function(t,e){this.pell&&(t&&t!==this.vpContent?(this.vpContent=t,this.$refs.editor.content.innerHTML=t):t||(this.$refs.editor.content.innerHTML=""))},value:function(t,e){this.pell&&(t&&t!==this.vpContent?(this.vpContent=t,this.$refs.editor.content.innerHTML=t):t||(this.$refs.editor.content.innerHTML=""))}},beforeDestroy:function(){this.pell=void 0},mounted:function(){this.init(),this.$emit("mounted")},methods:{init:function(){var t=this;if(this.$el){var e={element:this.$refs.editor,onChange:function(e){t.vpContent=e,t.$emit("input",e),t.$emit("change",{editor:t.pell,html:e})},classes:this.classes,styleWithCSS:this.styleWithCss,defaultParagraphSeparator:this.defaultParagraphSeparator};this.actions&&this.actions.length>0&&(e.actions=this.actions);var n=r.default.init(e);this.pell=n,window.pell=r.default,(this.content||this.value)&&(this.$refs.editor.content.innerHTML=this.content||this.value,this.vpContent=this.content||this.value),""!==this.editorHeight&&(this.$refs.editor.content.style.height=this.editorHeight)}}}};e.default=o},25:function(t,e,n){var r=n(87);"string"==typeof r&&(r=[[t.i,r,""]]),r.locals&&(t.exports=r.locals);(0,n(89).default)("9cf24e90",r,!0,{})},35:function(t,e,n){"use strict";function r(t,e,n,r,o,i,u,a){var l,s="function"==typeof t?t.options:t;if(e&&(s.render=e,s.staticRenderFns=n,s._compiled=!0),r&&(s.functional=!0),i&&(s._scopeId="data-v-"+i),u?(l=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),o&&o.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(u)},s._ssrRegister=l):o&&(l=a?function(){o.call(this,this.$root.$options.shadowRoot)}:o),l)if(s.functional){s._injectStyles=l;var c=s.render;s.render=function(t,e){return l.call(e),c(t,e)}}else{var f=s.beforeCreate;s.beforeCreate=f?[].concat(f,l):[l]}return{exports:t,options:s}}n.d(e,"a",function(){return r})},36:function(t,e,n){"use strict";var r=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{ref:"editor",staticClass:"vp-editor"},[""!==t.vpContent&&"
"!==t.vpContent||!t.placeholder?t._e():n("div",{staticClass:"vp-editor__placeholder",on:{click:function(e){t.$refs.editor.content.focus()}}},[t._v("\n "+t._s(t.placeholder)+"\n ")])])},o=[];n.d(e,"a",function(){return r}),n.d(e,"b",function(){return o})},83:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0;var r=function(t){return t&&t.__esModule?t:{default:t}}(n(84));r.default.install=function(t,e){t.component("VuePellEditor",r.default)};var o=function(t){r.default.install(t)};e.default=o},84:function(t,e,n){"use strict";n.r(e);var r=n(36),o=n(23);for(var i in o)"default"!==i&&function(t){n.d(e,t,function(){return o[t]})}(i);n(86);var u=n(35),a=Object(u.a)(o.default,r.a,r.b,!1,null,null,null);a.options.__file="VuePellEditor.vue",e.default=a.exports},85:function(t,e,n){!function(t){"use strict";var e=Object.assign||function(t){for(var e=1;e1&&void 0!==arguments[1]?arguments[1]:null;return document.execCommand(t,!1,e)},a={bold:{icon:"B",title:"Bold",state:function(){return i("bold")},result:function(){return u("bold")}},italic:{icon:"I",title:"Italic",state:function(){return i("italic")},result:function(){return u("italic")}},underline:{icon:"U",title:"Underline",state:function(){return i("underline")},result:function(){return u("underline")}},strikethrough:{icon:"S",title:"Strike-through",state:function(){return i("strikeThrough")},result:function(){return u("strikeThrough")}},heading1:{icon:"H1",title:"Heading 1",result:function(){return u("formatBlock","

")}},heading2:{icon:"H2",title:"Heading 2",result:function(){return u("formatBlock","

")}},paragraph:{icon:"¶",title:"Paragraph",result:function(){return u("formatBlock","

")}},quote:{icon:"“ ”",title:"Quote",result:function(){return u("formatBlock","

")}},olist:{icon:"#",title:"Ordered List",result:function(){return u("insertOrderedList")}},ulist:{icon:"•",title:"Unordered List",result:function(){return u("insertUnorderedList")}},code:{icon:"</>",title:"Code",result:function(){return u("formatBlock","
")}},line:{icon:"―",title:"Horizontal Line",result:function(){return u("insertHorizontalRule")}},link:{icon:"🔗",title:"Link",result:function(){var t=window.prompt("Enter the link URL");t&&u("createLink",t)}},image:{icon:"📷",title:"Image",result:function(){var t=window.prompt("Enter the image URL");t&&u("insertImage",t)}}},l={actionbar:"pell-actionbar",button:"pell-button",content:"pell-content",selected:"pell-button-selected"},s=function(t){var i=t.actions?t.actions.map(function(t){return"string"==typeof t?a[t]:a[t.name]?e({},a[t.name],t):t}):Object.keys(a).map(function(t){return a[t]}),s=e({},l,t.classes),c=t.defaultParagraphSeparator||"div",f=o("div");f.className=s.actionbar,r(t.element,f);var d=t.element.content=o("div");return d.contentEditable=!0,d.className=s.content,d.oninput=function(e){var n=e.target.firstChild;n&&3===n.nodeType?u("formatBlock","<"+c+">"):"
"===d.innerHTML&&(d.innerHTML=""),t.onChange(d.innerHTML)},d.onkeydown=function(t){"Tab"===t.key?t.preventDefault():"Enter"===t.key&&"blockquote"===function(t){return document.queryCommandValue(t)}("formatBlock")&&setTimeout(function(){return u("formatBlock","<"+c+">")},0)},r(t.element,d),i.forEach(function(t){var e=o("button");if(e.className=s.button,e.innerHTML=t.icon,e.title=t.title,e.setAttribute("type","button"),e.onclick=function(){return t.result()&&d.focus()},t.state){var i=function(){return e.classList[t.state()?"add":"remove"](s.selected)};n(d,"keyup",i),n(d,"mouseup",i),n(e,"click",i)}r(f,e)}),t.styleWithCSS&&u("styleWithCSS"),u("defaultParagraphSeparator",c),t.element},c={exec:u,init:s};t.exec=u,t.init=s,t.default=c,Object.defineProperty(t,"__esModule",{value:!0})}(e)},86:function(t,e,n){"use strict";var r=n(25);n.n(r).a},87:function(t,e,n){(t.exports=n(88)(!1)).push([t.i,"\n.pell{border:1px solid rgba(10,10,10,.1)\n}\n.pell,.pell-content{box-sizing:border-box\n}\n.pell-content{height:300px;outline:0;overflow-y:auto;padding:10px\n}\n.pell-actionbar{background-color:#fff;border-bottom:1px solid rgba(10,10,10,.1)\n}\n.pell-button{background-color:transparent;border:none;cursor:pointer;height:30px;outline:0;vertical-align:bottom;width:30px\n}\n.pell-button-selected{background-color:#f0f0f0\n}\n.vp-editor{position:relative\n}\n.vp-editor__placeholder{color:#ddd;font-style:italic;left:10px;position:absolute;top:42px\n}",""])},88:function(t,e){t.exports=function(t){var e=[];return e.toString=function(){return this.map(function(e){var n=function(t,e){var n=t[1]||"",r=t[3];if(!r)return n;if(e&&"function"==typeof btoa){var o=function(t){return"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(t))))+" */"}(r),i=r.sources.map(function(t){return"/*# sourceURL="+r.sourceRoot+t+" */"});return[n].concat(i).concat([o]).join("\n")}return[n].join("\n")}(e,t);return e[2]?"@media "+e[2]+"{"+n+"}":n}).join("")},e.i=function(t,n){"string"==typeof t&&(t=[[null,t,""]]);for(var r={},o=0;on.parts.length&&(r.parts.length=n.parts.length)}else{var u=[];for(o=0;o=7.6.0" 127 | }, 128 | "title": "SiteTitle" 129 | } 130 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = ({ file, options, env }) => ({ 2 | parser: 'postcss-scss', 3 | plugins: { 4 | 'postcss-normalize': options && options.normalize !== false ? {} : false, 5 | 'postcss-custom-selectors': {}, 6 | 'postcss-custom-media': {}, 7 | 'postcss-pseudo-class-any-link': {}, 8 | 'postcss-custom-properties': { 9 | warnings: false 10 | }, 11 | 'postcss-calc': {}, 12 | 'postcss-aspect-ratio': {}, 13 | 'postcss-easings': {}, 14 | 'postcss-assets': { 15 | basePath: './', 16 | loadPaths: options.dist ? [options.dist.cssimg] : [] 17 | }, 18 | 'autoprefixer': { 19 | cascade: false, 20 | grid: true 21 | }, 22 | 'postcss-svg': {}, 23 | 'postcss-short-size': {}, 24 | 'postcss-flexbugs-fixes': {}, 25 | 'cssnano': env !== 'production' ? false : { 26 | discardComments: { removeAll: true }, 27 | zindex: false, 28 | discardUnused: false, 29 | reduceIdents: false, 30 | mergeIdents: false 31 | } 32 | } 33 | }) 34 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | tabWidth: 2, 4 | semi: false, 5 | singleQuote: true, 6 | trailingComma: 'none', 7 | bracketSpacing: true, 8 | arrowParens: 'always', 9 | proseWrap: 'never' 10 | } 11 | -------------------------------------------------------------------------------- /src/js/app.vue: -------------------------------------------------------------------------------- 1 | 14 | 66 | -------------------------------------------------------------------------------- /src/js/components/VuePellEditor.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 150 | 151 | 166 | -------------------------------------------------------------------------------- /src/js/main.ts: -------------------------------------------------------------------------------- 1 | // Main JS File 2 | import '@babel/polyfill' 3 | import Vue from 'vue' 4 | import App from './app' 5 | import VuePellEditor from './vue-pell-editor' 6 | Vue.use(VuePellEditor) 7 | 8 | // Vue App 9 | /* eslint-disable no-new */ 10 | new Vue({ 11 | el: '#app', 12 | render: (h) => h(App) 13 | }) 14 | -------------------------------------------------------------------------------- /src/js/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import Vue, { VNode } from 'vue' 2 | 3 | declare global { 4 | namespace JSX { 5 | // tslint:disable no-empty-interface 6 | interface Element extends VNode {} 7 | // tslint:disable no-empty-interface 8 | interface ElementClass extends Vue {} 9 | interface IntrinsicElements { 10 | [elem: string]: any 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/js/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue' 3 | export default Vue 4 | } 5 | -------------------------------------------------------------------------------- /src/js/vue-pell-editor.ts: -------------------------------------------------------------------------------- 1 | import VuePellEditor from './components/VuePellEditor.vue' 2 | 3 | VuePellEditor.install = (Vue: any, options?: Object) => { 4 | Vue.component('VuePellEditor', VuePellEditor) 5 | } 6 | 7 | const install = (Vue: any) => { 8 | VuePellEditor.install(Vue) 9 | } 10 | 11 | export default install 12 | -------------------------------------------------------------------------------- /src/structure/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vue-pell-editor 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

Hello World

20 |
21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/structure/readme.txt: -------------------------------------------------------------------------------- 1 | Place your uncompiled Template Files here. 2 | -------------------------------------------------------------------------------- /tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | // Import the `mount()` method from the test utils 2 | // and the component you want to test 3 | import { shallow, mount } from '@vue/test-utils' 4 | import App from '../../src/js/app.vue' 5 | 6 | describe('Testing Sidebar', () => { 7 | // Now mount the component and you have the wrapper 8 | const wrapper = mount(App) 9 | 10 | it('App is available', () => { 11 | expect(wrapper.html()) 12 | }) 13 | 14 | it('Data is there', () => { 15 | expect(wrapper.vm.message).toBe('Hello World i am Vue') 16 | }) 17 | 18 | it('render the right markup', () => { 19 | expect(wrapper.html()).toBe('

Hello World i am Vue

') 20 | }) 21 | }) 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "target": "es5", 5 | "module": "esnext", 6 | "strict": true, 7 | "jsx": "preserve", 8 | "importHelpers": true, 9 | "moduleResolution": "node", 10 | "allowSyntheticDefaultImports": true, 11 | "sourceMap": true, 12 | "baseUrl": ".", 13 | "types": ["node", "jest"], 14 | "paths": { 15 | "@/*": ["src/js/*"], 16 | "components/*": ["src/js/components/*"], 17 | "shared/*": ["src/js/shared/*"], 18 | "lang/*": ["src/js/lang/*"] 19 | }, 20 | "lib": ["es7", "dom", "dom.iterable", "scripthost"] 21 | }, 22 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"], 23 | "exclude": ["node_modules"] 24 | } 25 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": [ 4 | "tslint:recommended", 5 | "tslint-config-standard", 6 | "tslint-config-prettier", 7 | "@kurosame/tslint-config-vue" 8 | ], 9 | "linterOptions": { 10 | "exclude": ["node_modules/**"] 11 | }, 12 | "rules": { 13 | "quotemark": [true, "single"], 14 | "indent": [true, "spaces", 2], 15 | "class-name": false, 16 | "interface-name": false, 17 | "ordered-imports": false, 18 | "object-literal-sort-keys": false, 19 | "no-consecutive-blank-lines": false, 20 | "space-before-function-paren": false, 21 | "no-console": false, 22 | "no-submodule-imports": false, 23 | "no-implicit-dependencies": false, 24 | "max-line-length": [true, 100] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /webpack/utils.js: -------------------------------------------------------------------------------- 1 | import { getIfUtils, removeEmpty } from 'webpack-config-utils' 2 | import path from 'path' 3 | import kittnConf from '../config.json' 4 | 5 | exports.getIfUtils = getIfUtils 6 | exports.removeEmpty = removeEmpty 7 | 8 | exports.kittnConf = kittnConf 9 | exports.entryPoints = kittnConf.src.jsEntryPoints 10 | 11 | /* 12 | |-------------------------------------------------------------------------- 13 | | Setting some paths for our Application 14 | |-------------------------------------------------------------------------- 15 | */ 16 | const paths = {} 17 | paths.ROOT_PATH = path.resolve(__dirname, '..') 18 | paths.PUBLIC_PATH = path.join(paths.ROOT_PATH, kittnConf.dist.webpackpublic) 19 | paths.ASSETS_PATH = kittnConf.dist.webpackassets 20 | paths.SRC_ROOT = path.resolve(paths.ROOT_PATH, kittnConf.src.base) 21 | paths.CSS_ROOT = path.resolve(paths.ROOT_PATH, kittnConf.src.style) 22 | paths.LOADER_PATH = path.join(paths.ROOT_PATH, kittnConf.src.js) 23 | exports.paths = paths 24 | 25 | /* 26 | |-------------------------------------------------------------------------- 27 | | Helper Functions 28 | |-------------------------------------------------------------------------- 29 | */ 30 | exports.resolve = function (dir) { 31 | return path.join(__dirname, '..', dir) 32 | } 33 | 34 | exports.assetsPath = function (_path) { 35 | return path.posix.join(paths.ASSETS_PATH, _path); 36 | } 37 | -------------------------------------------------------------------------------- /webpack/webpack.config.base.babel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Webpack Config for Javascript Bundling 3 | * 4 | * @package generator-kittn 5 | * @author Lars Eichler 6 | */ 7 | import path from 'path' 8 | import webpack from 'webpack' 9 | import WebpackBar from 'webpackbar' 10 | import Stylish from 'webpack-stylish' 11 | import HtmlWebpackPlugin from 'html-webpack-plugin' 12 | import ExtractTextPlugin from 'extract-text-webpack-plugin' 13 | import OptimizeCSSPlugin from 'optimize-css-assets-webpack-plugin' 14 | import { VueLoaderPlugin } from 'vue-loader' 15 | 16 | const utils = require('./utils') 17 | const nodeEnv = process.env.NODE_ENV || 'production' 18 | 19 | const { ifProduction, ifDevelopment } = utils.getIfUtils(nodeEnv) 20 | 21 | const CSS_LOADERS = [ 22 | { 23 | loader: 'css-loader', 24 | options: { 25 | autoprefixer: false, 26 | sourceMap: ifProduction(false, true), 27 | url: true 28 | } 29 | }, 30 | { 31 | loader: 'postcss-loader', 32 | options: { 33 | sourceMap: ifProduction(false, true), 34 | config: { 35 | ctx: { 36 | normalize: true 37 | } 38 | } 39 | } 40 | }, 41 | { 42 | loader: 'sass-loader', 43 | options: { 44 | includePaths: [utils.resolve(utils.kittnConf.src.style)], 45 | sourceMap: ifProduction(false, true) 46 | } 47 | } 48 | ] 49 | 50 | /* 51 | |-------------------------------------------------------------------------- 52 | | Let the config begin 53 | |-------------------------------------------------------------------------- 54 | */ 55 | export default { 56 | entry: utils.removeEmpty(utils.entryPoints), 57 | output: { 58 | pathinfo: ifDevelopment(true, false), 59 | path: utils.paths.PUBLIC_PATH 60 | }, 61 | stats: 'none', 62 | resolve: { 63 | extensions: ['.vue', '.js', '.ts', '.tsx'], 64 | modules: [utils.resolve(utils.kittnConf.src.base), utils.resolve('node_modules')], 65 | alias: { 66 | components: path.resolve(utils.paths.LOADER_PATH, 'components/'), 67 | src: utils.resolve(utils.kittnConf.src.base) 68 | } 69 | }, 70 | module: { 71 | rules: [ 72 | { 73 | enforce: 'pre', 74 | test: /\.(js|vue)$/, 75 | loader: 'eslint-loader', 76 | options: { 77 | configFile: './.eslintrc.js', 78 | formatter: require('eslint-friendly-formatter') 79 | }, 80 | exclude: /node_modules/, 81 | include: utils.resolve(utils.kittnConf.src.base) 82 | }, 83 | { 84 | test: /\.js$/, 85 | include: utils.resolve(utils.kittnConf.src.base), 86 | exclude: /node_modules/, 87 | use: { 88 | loader: 'babel-loader', 89 | options: { 90 | cacheDirectory: true 91 | } 92 | } 93 | }, 94 | { 95 | test: /\.vue$/, 96 | loader: 'vue-loader' 97 | }, 98 | { 99 | test: /\.css$/, 100 | use: ['vue-style-loader', 'css-loader'] 101 | }, 102 | { 103 | test: /\.scss$/, 104 | include: [utils.resolve(utils.kittnConf.src.style), utils.resolve(utils.kittnConf.src.js)], 105 | exclude: [utils.resolve('node_modules'), utils.resolve(utils.kittnConf.dist.base)], 106 | use: ['vue-style-loader', ...CSS_LOADERS] 107 | }, 108 | { 109 | test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/, 110 | exclude: [ 111 | path.resolve(utils.paths.SRC_ROOT, 'images/vectors/'), 112 | path.resolve(utils.paths.SRC_ROOT, 'images/vectorsSingle/') 113 | ], 114 | use: [ 115 | { 116 | loader: 'url-loader', 117 | options: { 118 | limit: 8192, 119 | fallback: 'file-loader', 120 | outputPath: utils.assetsPath('img/'), 121 | publicPath: utils.assetsPath('img/'), 122 | name: '[name].[ext]' 123 | } 124 | } 125 | ] 126 | }, 127 | { 128 | test: /\.(eot|ttf|woff|woff2)(\?\S*)?$/, 129 | use: [ 130 | { 131 | loader: 'file-loader', 132 | query: { 133 | outputPath: utils.assetsPath('fonts/'), 134 | publicPath: 'fonts/', 135 | name: '[name].[ext]' 136 | } 137 | } 138 | ] 139 | }, 140 | { 141 | test: /\.svg$/, 142 | include: [ 143 | path.resolve(utils.paths.SRC_ROOT, 'images/vectors/'), 144 | path.resolve(utils.paths.SRC_ROOT, 'images/vectorsSingle/') 145 | ], 146 | use: [ 147 | { 148 | loader: 'svg-sprite-loader' 149 | }, 150 | 'svg-transform-loader', 151 | 'svgo-loader' 152 | ] 153 | }, 154 | { 155 | test: /\.tsx?$/, 156 | exclude: /node_modules/, 157 | use: [ 158 | 'babel-loader', 159 | { 160 | loader: 'ts-loader', 161 | options: { 162 | transpileOnly: true, 163 | experimentalWatchApi: true 164 | } 165 | } 166 | ] 167 | } 168 | ] 169 | }, 170 | plugins: utils.removeEmpty([ 171 | new VueLoaderPlugin(), 172 | new WebpackBar(), 173 | new Stylish(), 174 | new webpack.DefinePlugin({ 175 | 'process.env': { 176 | NODE_ENV: JSON.stringify(nodeEnv) 177 | } 178 | }), 179 | // new ExtractTextPlugin({ 180 | // filename: utils.assetsPath('[name].css'), 181 | // allChunks: true 182 | // }), 183 | // new OptimizeCSSPlugin({ 184 | // cssProcessorOptions: { 185 | // safe: true 186 | // } 187 | // }), 188 | new HtmlWebpackPlugin({ 189 | filename: 'index.html', 190 | template: utils.kittnConf.src.structure + 'index.html', 191 | inject: false, 192 | hash: true, 193 | minify: { 194 | removeComments: true, 195 | collapseWhitespace: true, 196 | removeAttributeQuotes: false 197 | }, 198 | chunksSortMode: 'dependency' 199 | }) 200 | ]) 201 | } 202 | -------------------------------------------------------------------------------- /webpack/webpack.dev.babel.js: -------------------------------------------------------------------------------- 1 | import webpack from 'webpack' 2 | import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin' 3 | // import WriteFilePlugin from 'write-file-webpack-plugin' 4 | import utils from './utils' 5 | 6 | const baseWebpackConfig = require('./webpack.config.base.babel.js') 7 | const merge = require('webpack-merge') 8 | const path = require('path') 9 | const portfinder = require('portfinder') 10 | 11 | /* 12 | |-------------------------------------------------------------------------- 13 | | Defining Entry Points, could be used to manually split Parts of the Application, for example 14 | | Admin Javascript and FrontEnd JavaScript 15 | |-------------------------------------------------------------------------- 16 | */ 17 | let entries = utils.entryPoints 18 | 19 | const HOST = 'localhost' 20 | const PORT = utils.kittnConf.browsersync.port 21 | 22 | const devWebpackConfig = merge(baseWebpackConfig.default, { 23 | devtool: 'eval-source-map', 24 | entry: utils.removeEmpty(entries), 25 | output: { 26 | publicPath: '/', 27 | filename: utils.assetsPath('js/[name].js'), 28 | chunkFilename: utils.assetsPath('js/chunks/[name].js') 29 | }, 30 | 31 | devServer: { 32 | clientLogLevel: 'warning', 33 | historyApiFallback: { 34 | rewrites: [{ from: /.*/, to: path.posix.join(utils.kittnConf.dist.markup, 'index.html') }] 35 | }, 36 | hot: true, 37 | compress: true, 38 | host: HOST, 39 | port: PORT, 40 | proxy: [ 41 | { 42 | path: /\/(?!__webpack_hmr).+/ 43 | } 44 | ], 45 | quiet: true, 46 | stats: { colors: true }, 47 | contentBase: path.join(__dirname, `../${utils.kittnConf.src.base}`), 48 | publicPath: '/', 49 | open: utils.kittnConf.browsersync.openbrowser, 50 | overlay: true 51 | }, 52 | 53 | plugins: [ 54 | new webpack.HotModuleReplacementPlugin(), 55 | new webpack.NoEmitOnErrorsPlugin() 56 | 57 | // only needed if you want to write the files to your harddrive in dev-mode 58 | // new WriteFilePlugin({ 59 | // log: false, 60 | // test: /^(?!.+(?:hot-update.(js|json))).+$/ 61 | // }) 62 | ] 63 | }) 64 | 65 | module.exports = new Promise((resolve, reject) => { 66 | portfinder.basePort = process.env.PORT || utils.kittnConf.browsersync.port 67 | portfinder.getPort((err, port) => { 68 | if (err) { 69 | reject(err) 70 | } else { 71 | // publish the new Port, necessary for e2e tests 72 | process.env.PORT = port 73 | // add port to devServer config 74 | devWebpackConfig.devServer.port = port 75 | 76 | // Add FriendlyErrorsPlugin 77 | devWebpackConfig.plugins.push( 78 | new FriendlyErrorsWebpackPlugin({ 79 | compilationSuccessInfo: { 80 | messages: [ 81 | `Your application is running here: http://${devWebpackConfig.devServer.host}:${port}` 82 | ] 83 | } 84 | }) 85 | ) 86 | 87 | resolve(devWebpackConfig) 88 | } 89 | }) 90 | }) 91 | -------------------------------------------------------------------------------- /webpack/webpack.prod.babel.js: -------------------------------------------------------------------------------- 1 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' 2 | import CleanWebpackPlugin from 'clean-webpack-plugin' 3 | import path from 'path' 4 | const merge = require('webpack-merge') 5 | const utils = require('./utils') 6 | const baseWebpackConfig = require('./webpack.config.base.babel.js') 7 | 8 | /* 9 | |-------------------------------------------------------------------------- 10 | | Merge the configs 11 | |-------------------------------------------------------------------------- 12 | */ 13 | const prodWebpackConfig = merge(baseWebpackConfig.default, { 14 | devtool: '', 15 | output: { 16 | filename: utils.assetsPath('[name].js'), 17 | chunkFilename: utils.assetsPath('chunks/[name].js'), 18 | publicPath: './', 19 | library: 'VuePellEditor', 20 | libraryExport: 'default', 21 | libraryTarget: 'umd' 22 | }, 23 | plugins: [ 24 | new CleanWebpackPlugin([utils.resolve(utils.kittnConf.dist.base)], { 25 | root: path.resolve(utils.paths.PUBLIC_PATH, '..'), 26 | beforeEmit: true 27 | }), 28 | 29 | new BundleAnalyzerPlugin({ 30 | analyzerMode: 'disabled', 31 | generateStatsFile: true, 32 | statsFilename: `${utils.paths.ROOT_PATH}/webpack/stats.json`, 33 | logLevel: 'info' 34 | }) 35 | ] 36 | }) 37 | 38 | module.exports = prodWebpackConfig 39 | --------------------------------------------------------------------------------