├── .babelrc ├── .coveralls.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── .prettierrc.js ├── .travis.yml ├── LICENSE ├── README.md ├── build ├── build.js ├── check-versions.js ├── logo.png ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js ├── webpack.dist.conf.js └── webpack.prod.conf.js ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── docs ├── CNAME ├── index.html └── static │ ├── css │ ├── app.f60de8a36547efcbcfffde85c7c98845.css │ └── app.f60de8a36547efcbcfffde85c7c98845.css.map │ ├── fonts │ └── element-icons.6f0a763.ttf │ └── js │ ├── app.6929d2b6ad0b23e9ecf4.js │ ├── app.6929d2b6ad0b23e9ecf4.js.map │ ├── manifest.2ae2e69a05c33dfc65f8.js │ ├── manifest.2ae2e69a05c33dfc65f8.js.map │ ├── vendor.520118608f94f59d02d1.js │ └── vendor.520118608f94f59d02d1.js.map ├── example ├── App.vue ├── components │ └── Subscription.vue ├── main.js └── schema │ └── newsletter.json ├── index.html ├── lib └── json-editor.min.js ├── package.json ├── screenshot.jpg ├── src ├── JsonEditor.vue ├── parser.js └── utils.js ├── static └── .gitkeep └── test ├── .eslintrc.js ├── __snapshots__ ├── complex.test.js.snap ├── schema.test.js.snap └── simple.test.js.snap ├── complex.test.js ├── component.test.js ├── data ├── complex.json ├── signup.json └── simple.json ├── jest.conf.js ├── schema.test.js └── simple.test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false 5 | }], 6 | "stage-2" 7 | ], 8 | "env": { 9 | "test": { 10 | "presets": [ 11 | ["env", { "targets": { "node": "current" }}] 12 | ] 13 | } 14 | }, 15 | "plugins": ["transform-runtime"] 16 | } 17 | -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: Fybnzn6f3uZVXKohjjSPxsusD5X6eI8Ig 2 | 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /config/ 3 | /dist/ 4 | /*.js 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'guo/vue', 3 | rules: { 4 | 'valid-jsdoc': 'off', 5 | 'array-bracket-spacing': 'off' 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | coverage 3 | node_modules/ 4 | /dist/ 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Editor directories and files 10 | .idea 11 | .vscode 12 | *.suo 13 | *.ntvs* 14 | *.njsproj 15 | *.sln 16 | package-lock.json 17 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "postcss-import": {}, 7 | "autoprefixer": {} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // .prettierrc.js 2 | module.exports = { 3 | printWidth: 120, 4 | singleQuote: true, 5 | trailingComma: "es5", 6 | }; 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | cache: 4 | directories: 5 | - node_modules 6 | 7 | os: 8 | - osx 9 | 10 | node_js: 11 | - 6 12 | - 7 13 | - 8 14 | - 9 15 | - 10 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 郭宇翔 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 | [![NPM version][npm-image]][npm-url] 2 | [![build status][travis-image]][travis-url] 3 | [![Test coverage][coveralls-image]][coveralls-url] 4 | [![David deps][david-image]][david-url] 5 | [![npm download][download-image]][download-url] 6 | [![npm license][license-image]][download-url] 7 | 8 | [npm-image]: https://img.shields.io/npm/v/vue-json-ui-editor.svg?style=flat-square 9 | [npm-url]: https://npmjs.org/package/vue-json-ui-editor 10 | [travis-image]: https://img.shields.io/travis/yourtion/vue-json-ui-editor.svg?style=flat-square 11 | [travis-url]: https://travis-ci.org/yourtion/vue-json-ui-editor 12 | [coveralls-image]: https://img.shields.io/coveralls/yourtion/vue-json-ui-editor.svg?style=flat-square 13 | [coveralls-url]: https://coveralls.io/r/yourtion/vue-json-ui-editor?branch=master 14 | [david-image]: https://img.shields.io/david/yourtion/vue-json-ui-editor.svg?style=flat-square 15 | [david-url]: https://david-dm.org/yourtion/vue-json-ui-editor 16 | [download-image]: https://img.shields.io/npm/dm/vue-json-ui-editor.svg?style=flat-square 17 | [download-url]: https://npmjs.org/package/vue-json-ui-editor 18 | [license-image]: https://img.shields.io/npm/l/vue-json-ui-editor.svg 19 | 20 | # json-editor 21 | 22 | [![Greenkeeper badge](https://badges.greenkeeper.io/yourtion/vue-json-ui-editor.svg)](https://greenkeeper.io/) 23 | [![DeepScan grade](https://deepscan.io/api/teams/2046/projects/2774/branches/19927/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=2046&pid=2774&bid=19927) 24 | 25 | Edit JSON in UI form with JSON Schema and Vue.js `` component. 26 | 27 | ![ScreenShot](screenshot.jpg) 28 | 29 | ## Install 30 | 31 | ```bash 32 | npm install vue-json-ui-editor --save 33 | ``` 34 | 35 | ## Use 36 | 37 | ```Vue 38 | 44 | 45 | 81 | ``` 82 | 83 | More info on: [Example-Subscription](example/components/Subscription.vue) 84 | Schema: [newsletter.json](example/schema/newsletter.json) 85 | 86 | ## props 87 | 88 | - `schema` ***Object*** (*required*) 89 | The JSON Schema object. Use the `v-if` directive to load asynchronous schema. 90 | 91 | - `v-model` ***Object*** (*optional*) `default: [object Object]` 92 | Use this directive to create two-way data bindings with the component. It automatically picks the correct way to update the element based on the input type. 93 | 94 | - `auto-complete` ***String*** (*optional*) 95 | This property indicates whether the value of the control can be automatically completed by the browser. Possible values are: `off` and `on`. 96 | 97 | - `no-validate` ***Boolean*** (*optional*) 98 | This Boolean attribute indicates that the form is not to be validated when submitted. 99 | 100 | - `input-wrapping-class` ***String*** (*optional*) 101 | Define the inputs wrapping class. Leave `undefined` to disable input wrapping. 102 | 103 | ## data 104 | 105 | - `default` 106 | *initial value:* `[object Object]` 107 | 108 | - `fields` 109 | *initial value:* `[object Object]` 110 | 111 | - `error` 112 | *initial value:* `null` 113 | 114 | - `data` 115 | *initial value:* `[object Object]` 116 | 117 | ## events 118 | 119 | - `input` Fired synchronously when the value of an element is changed. 120 | 121 | - `change` Fired when a change to the element's value is committed by the user. 122 | 123 | - `invalid` Fired when a submittable element has been checked and doesn't satisfy its constraints. The validity of submittable elements is checked before submitting their owner form, or after the `checkValidity()` of the element or its owner form is called. 124 | 125 | - `submit` Fired when a form is submitted 126 | 127 | ## methods 128 | 129 | - `input(name)` 130 | Get a form input reference 131 | 132 | - `form()` 133 | Get the form reference 134 | 135 | - `checkValidity()` 136 | Checks whether the form has any constraints and whether it satisfies them. If the form fails its constraints, the browser fires a cancelable `invalid` event at the element, and then returns false. 137 | 138 | - `reset()` 139 | Reset the value of all elements of the parent form. 140 | 141 | - `submit(event)` 142 | Send the content of the form to the server 143 | 144 | - `setErrorMessage(message)` 145 | Set a message error. 146 | 147 | - `clearErrorMessage()` 148 | clear the message error. 149 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | require('./check-versions')() 3 | 4 | process.env.NODE_ENV = 'production' 5 | 6 | const ora = require('ora') 7 | const rm = require('rimraf') 8 | const path = require('path') 9 | const chalk = require('chalk') 10 | const webpack = require('webpack') 11 | const config = require('../config') 12 | const webpackConfig = require('./webpack.prod.conf') 13 | 14 | const spinner = ora('building for production...') 15 | spinner.start() 16 | 17 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 18 | if (err) throw err 19 | webpack(webpackConfig, function (err, stats) { 20 | spinner.stop() 21 | if (err) throw err 22 | process.stdout.write(stats.toString({ 23 | colors: true, 24 | modules: false, 25 | children: false, 26 | chunks: false, 27 | chunkModules: false 28 | }) + '\n\n') 29 | 30 | if (stats.hasErrors()) { 31 | console.log(chalk.red(' Build failed with errors.\n')) 32 | process.exit(1) 33 | } 34 | 35 | console.log(chalk.cyan(' Build complete.\n')) 36 | console.log(chalk.yellow( 37 | ' Tip: built files are meant to be served over an HTTP server.\n' + 38 | ' Opening index.html over file:// won\'t work.\n' 39 | )) 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const chalk = require('chalk') 3 | const semver = require('semver') 4 | const packageConfig = require('../package.json') 5 | const shell = require('shelljs') 6 | function exec (cmd) { 7 | return require('child_process').execSync(cmd).toString().trim() 8 | } 9 | 10 | const versionRequirements = [ 11 | { 12 | name: 'node', 13 | currentVersion: semver.clean(process.version), 14 | versionRequirement: packageConfig.engines.node 15 | } 16 | ] 17 | 18 | if (shell.which('npm')) { 19 | versionRequirements.push({ 20 | name: 'npm', 21 | currentVersion: exec('npm --version'), 22 | versionRequirement: packageConfig.engines.npm 23 | }) 24 | } 25 | 26 | module.exports = function () { 27 | const warnings = [] 28 | for (let i = 0; i < versionRequirements.length; i++) { 29 | const mod = versionRequirements[i] 30 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 31 | warnings.push(mod.name + ': ' + 32 | chalk.red(mod.currentVersion) + ' should be ' + 33 | chalk.green(mod.versionRequirement) 34 | ) 35 | } 36 | } 37 | 38 | if (warnings.length) { 39 | console.log('') 40 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 41 | console.log() 42 | for (let i = 0; i < warnings.length; i++) { 43 | const warning = warnings[i] 44 | console.log(' ' + warning) 45 | } 46 | console.log() 47 | process.exit(1) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /build/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/vue-json-ui-editor/a2f46a3524b1c28bd45cb1bb53413f8a8628d557/build/logo.png -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const config = require('../config') 4 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | const pkg = require('../package.json') 6 | 7 | exports.assetsPath = function (_path) { 8 | const assetsSubDirectory = process.env.NODE_ENV === 'production' 9 | ? config.build.assetsSubDirectory 10 | : config.dev.assetsSubDirectory 11 | return path.posix.join(assetsSubDirectory, _path) 12 | } 13 | 14 | exports.cssLoaders = function (options) { 15 | options = options || {} 16 | 17 | const cssLoader = { 18 | loader: 'css-loader', 19 | options: { 20 | sourceMap: options.sourceMap 21 | } 22 | } 23 | 24 | var postcssLoader = { 25 | loader: 'postcss-loader', 26 | options: { 27 | sourceMap: options.sourceMap 28 | } 29 | } 30 | 31 | // generate loader string to be used with extract text plugin 32 | function generateLoaders (loader, loaderOptions) { 33 | const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] 34 | if (loader) { 35 | loaders.push({ 36 | loader: loader + '-loader', 37 | options: Object.assign({}, loaderOptions, { 38 | sourceMap: options.sourceMap 39 | }) 40 | }) 41 | } 42 | 43 | // Extract CSS when that option is specified 44 | // (which is the case during production build) 45 | if (options.extract) { 46 | return ExtractTextPlugin.extract({ 47 | use: loaders, 48 | fallback: 'vue-style-loader' 49 | }) 50 | } else { 51 | return ['vue-style-loader'].concat(loaders) 52 | } 53 | } 54 | 55 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 56 | return { 57 | css: generateLoaders(), 58 | postcss: generateLoaders(), 59 | less: generateLoaders('less'), 60 | sass: generateLoaders('sass', { indentedSyntax: true }), 61 | scss: generateLoaders('sass'), 62 | stylus: generateLoaders('stylus'), 63 | styl: generateLoaders('stylus') 64 | } 65 | } 66 | 67 | // Generate loaders for standalone style files (outside of .vue) 68 | exports.styleLoaders = function (options) { 69 | const output = [] 70 | const loaders = exports.cssLoaders(options) 71 | for (const extension in loaders) { 72 | const loader = loaders[extension] 73 | output.push({ 74 | test: new RegExp('\\.' + extension + '$'), 75 | use: loader 76 | }) 77 | } 78 | return output 79 | } 80 | 81 | exports.createNotifierCallback = function () { 82 | const notifier = require('node-notifier') 83 | 84 | return (severity, errors) => { 85 | if (severity !== 'error') { 86 | return 87 | } 88 | const error = errors[0] 89 | 90 | const filename = error.file && error.file.split('!').pop() 91 | notifier.notify({ 92 | title: pkg.name, 93 | message: severity + ': ' + error.name, 94 | subtitle: filename || '', 95 | icon: path.join(__dirname, 'logo.png') 96 | }) 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const config = require('../config') 4 | const isProduction = process.env.NODE_ENV === 'production' 5 | const sourceMapEnabled = isProduction 6 | ? config.build.productionSourceMap 7 | : config.dev.cssSourceMap 8 | 9 | 10 | module.exports = { 11 | loaders: utils.cssLoaders({ 12 | sourceMap: sourceMapEnabled, 13 | extract: isProduction 14 | }), 15 | cssSourceMap: sourceMapEnabled, 16 | cacheBusting: config.dev.cacheBusting, 17 | transformToRequire: { 18 | video: 'src', 19 | source: 'src', 20 | img: 'src', 21 | image: 'xlink:href' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const config = require('../config') 5 | const vueLoaderConfig = require('./vue-loader.conf') 6 | 7 | function resolve (dir) { 8 | return path.join(__dirname, '..', dir) 9 | } 10 | 11 | module.exports = { 12 | context: path.resolve(__dirname, '../'), 13 | entry: { 14 | app: './example/main.js' 15 | }, 16 | output: { 17 | path: config.build.assetsRoot, 18 | filename: '[name].js', 19 | publicPath: process.env.NODE_ENV === 'production' 20 | ? config.build.assetsPublicPath 21 | : config.dev.assetsPublicPath 22 | }, 23 | resolve: { 24 | extensions: ['.js', '.vue', '.json'], 25 | alias: { 26 | 'vue$': 'vue/dist/vue.esm.js', 27 | '@': resolve('example'), 28 | } 29 | }, 30 | module: { 31 | rules: [ 32 | ...(config.dev.useEslint? [{ 33 | test: /\.(js|vue)$/, 34 | loader: 'eslint-loader', 35 | enforce: 'pre', 36 | include: [resolve('src'), resolve('test')], 37 | options: { 38 | formatter: require('eslint-friendly-formatter'), 39 | emitWarning: !config.dev.showEslintErrorsInOverlay 40 | } 41 | }] : []), 42 | { 43 | test: /\.vue$/, 44 | loader: 'vue-loader', 45 | options: vueLoaderConfig 46 | }, 47 | { 48 | test: /\.js$/, 49 | loader: 'babel-loader', 50 | include: [resolve('src'), resolve('test')] 51 | }, 52 | { 53 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 54 | loader: 'url-loader', 55 | options: { 56 | limit: 10000, 57 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 58 | } 59 | }, 60 | { 61 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 62 | loader: 'url-loader', 63 | options: { 64 | limit: 10000, 65 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 66 | } 67 | }, 68 | { 69 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 70 | loader: 'url-loader', 71 | options: { 72 | limit: 10000, 73 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 74 | } 75 | } 76 | ] 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const utils = require('./utils') 3 | const webpack = require('webpack') 4 | const config = require('../config') 5 | const merge = require('webpack-merge') 6 | const baseWebpackConfig = require('./webpack.base.conf') 7 | const HtmlWebpackPlugin = require('html-webpack-plugin') 8 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 9 | const portfinder = require('portfinder') 10 | 11 | const devWebpackConfig = merge(baseWebpackConfig, { 12 | module: { 13 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) 14 | }, 15 | // cheap-module-eval-source-map is faster for development 16 | devtool: config.dev.devtool, 17 | 18 | // these devServer options should be customized in /config/index.js 19 | devServer: { 20 | clientLogLevel: 'warning', 21 | historyApiFallback: true, 22 | hot: true, 23 | compress: true, 24 | host: process.env.HOST || config.dev.host, 25 | port: process.env.PORT || config.dev.port, 26 | open: config.dev.autoOpenBrowser, 27 | overlay: config.dev.errorOverlay ? { 28 | warnings: false, 29 | errors: true, 30 | } : false, 31 | publicPath: config.dev.assetsPublicPath, 32 | proxy: config.dev.proxyTable, 33 | quiet: true, // necessary for FriendlyErrorsPlugin 34 | watchOptions: { 35 | poll: config.dev.poll, 36 | } 37 | }, 38 | plugins: [ 39 | new webpack.DefinePlugin({ 40 | 'process.env': require('../config/dev.env') 41 | }), 42 | new webpack.HotModuleReplacementPlugin(), 43 | new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. 44 | new webpack.NoEmitOnErrorsPlugin(), 45 | // https://github.com/ampedandwired/html-webpack-plugin 46 | new HtmlWebpackPlugin({ 47 | filename: 'index.html', 48 | template: 'index.html', 49 | inject: true 50 | }), 51 | ] 52 | }) 53 | 54 | module.exports = new Promise((resolve, reject) => { 55 | portfinder.basePort = process.env.PORT || config.dev.port 56 | portfinder.getPort((err, port) => { 57 | if (err) { 58 | reject(err) 59 | } else { 60 | // publish the new Port, necessary for e2e tests 61 | process.env.PORT = port 62 | // add port to devServer config 63 | devWebpackConfig.devServer.port = port 64 | 65 | // Add FriendlyErrorsPlugin 66 | devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ 67 | compilationSuccessInfo: { 68 | messages: [`Your application is running here: http://${config.dev.host}:${port}`], 69 | }, 70 | onErrors: config.dev.notifyOnErrors 71 | ? utils.createNotifierCallback() 72 | : undefined 73 | })) 74 | 75 | resolve(devWebpackConfig) 76 | } 77 | }) 78 | }) 79 | -------------------------------------------------------------------------------- /build/webpack.dist.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const utils = require('./utils'); 3 | const webpack = require('webpack'); 4 | const vueLoaderConfig = require('./vue-loader.conf') 5 | 6 | process.env.NODE_ENV = 'production'; 7 | 8 | function resolve (dir) { 9 | return path.join(__dirname, '..', dir); 10 | } 11 | 12 | module.exports = { 13 | entry: resolve('src/JsonEditor.vue'), 14 | output: { 15 | path: path.resolve(__dirname, '../lib'), 16 | publicPath: '/lib/', 17 | filename: 'json-editor.min.js', 18 | library: 'json-editor', 19 | libraryTarget: 'umd', 20 | umdNamedDefine: true 21 | }, 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.(js|vue)$/, 26 | loader: 'eslint-loader', 27 | enforce: 'pre', 28 | include: [resolve('src'), resolve('test')], 29 | }, 30 | { 31 | test: /\.js$/, 32 | loader: 'babel-loader', 33 | include: __dirname, 34 | exclude: /node_modules/, 35 | query: { compact: false } 36 | }, 37 | { 38 | test: /\.vue$/, 39 | loader: 'vue-loader' 40 | } 41 | ] 42 | }, 43 | externals: { 44 | vue: { 45 | root: 'Vue', 46 | commonjs: 'vue', 47 | commonjs2: 'vue', 48 | amd: 'vue' 49 | } 50 | }, 51 | resolve: { 52 | extensions: ['.js', '.vue'], 53 | alias: { 54 | 'vue': 'vue/dist/vue.esm.js', 55 | '@': resolve('src') 56 | } 57 | }, 58 | plugins: [ 59 | // @todo 60 | new webpack.DefinePlugin({ 61 | 'process.env.NODE_ENV': '"production"' 62 | }), 63 | // @todo 64 | // new webpack.optimize.UglifyJsPlugin( { 65 | // minimize : true, 66 | // sourceMap : false, 67 | // mangle: true, 68 | // parallel: true, 69 | // compress: { 70 | // warnings: false 71 | // } 72 | // }) 73 | ], 74 | }; -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const utils = require('./utils') 4 | const webpack = require('webpack') 5 | const config = require('../config') 6 | const merge = require('webpack-merge') 7 | const baseWebpackConfig = require('./webpack.base.conf') 8 | const CopyWebpackPlugin = require('copy-webpack-plugin') 9 | const HtmlWebpackPlugin = require('html-webpack-plugin') 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | 13 | const env = require('../config/prod.env') 14 | 15 | const webpackConfig = merge(baseWebpackConfig, { 16 | module: { 17 | rules: utils.styleLoaders({ 18 | sourceMap: config.build.productionSourceMap, 19 | extract: true, 20 | usePostCSS: true 21 | }) 22 | }, 23 | devtool: config.build.productionSourceMap ? config.build.devtool : false, 24 | output: { 25 | path: config.build.assetsRoot, 26 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env 33 | }), 34 | // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify 35 | new webpack.optimize.UglifyJsPlugin({ 36 | compress: { 37 | warnings: false 38 | }, 39 | sourceMap: config.build.productionSourceMap, 40 | parallel: true 41 | }), 42 | // extract css into its own file 43 | new ExtractTextPlugin({ 44 | filename: utils.assetsPath('css/[name].[contenthash].css'), 45 | // set the following option to `true` if you want to extract CSS from 46 | // codesplit chunks into this main css file as well. 47 | // This will result in *all* of your app's CSS being loaded upfront. 48 | allChunks: false, 49 | }), 50 | // Compress extracted CSS. We are using this plugin so that possible 51 | // duplicated CSS from different components can be deduped. 52 | new OptimizeCSSPlugin({ 53 | cssProcessorOptions: config.build.productionSourceMap 54 | ? { safe: true, map: { inline: false } } 55 | : { safe: true } 56 | }), 57 | // generate dist index.html with correct asset hash for caching. 58 | // you can customize output by editing /index.html 59 | // see https://github.com/ampedandwired/html-webpack-plugin 60 | new HtmlWebpackPlugin({ 61 | filename: config.build.index, 62 | template: 'index.html', 63 | inject: true, 64 | minify: { 65 | removeComments: true, 66 | collapseWhitespace: true, 67 | removeAttributeQuotes: true 68 | // more options: 69 | // https://github.com/kangax/html-minifier#options-quick-reference 70 | }, 71 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 72 | chunksSortMode: 'dependency' 73 | }), 74 | // keep module.id stable when vender modules does not change 75 | new webpack.HashedModuleIdsPlugin(), 76 | // enable scope hoisting 77 | new webpack.optimize.ModuleConcatenationPlugin(), 78 | // split vendor js into its own file 79 | new webpack.optimize.CommonsChunkPlugin({ 80 | name: 'vendor', 81 | minChunks: function (module) { 82 | // any required modules inside node_modules are extracted to vendor 83 | return ( 84 | module.resource && 85 | /\.js$/.test(module.resource) && 86 | module.resource.indexOf( 87 | path.join(__dirname, '../node_modules') 88 | ) === 0 89 | ) 90 | } 91 | }), 92 | // extract webpack runtime and module manifest to its own file in order to 93 | // prevent vendor hash from being updated whenever app bundle is updated 94 | new webpack.optimize.CommonsChunkPlugin({ 95 | name: 'manifest', 96 | minChunks: Infinity 97 | }), 98 | // This instance extracts shared chunks from code splitted chunks and bundles them 99 | // in a separate chunk, similar to the vendor chunk 100 | // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk 101 | new webpack.optimize.CommonsChunkPlugin({ 102 | name: 'app', 103 | async: 'vendor-async', 104 | children: true, 105 | minChunks: 3 106 | }), 107 | 108 | // copy custom static assets 109 | new CopyWebpackPlugin([ 110 | { 111 | from: path.resolve(__dirname, '../static'), 112 | to: config.build.assetsSubDirectory, 113 | ignore: ['.*'] 114 | } 115 | ]) 116 | ] 117 | }) 118 | 119 | if (config.build.productionGzip) { 120 | const CompressionWebpackPlugin = require('compression-webpack-plugin') 121 | 122 | webpackConfig.plugins.push( 123 | new CompressionWebpackPlugin({ 124 | asset: '[path].gz[query]', 125 | algorithm: 'gzip', 126 | test: new RegExp( 127 | '\\.(' + 128 | config.build.productionGzipExtensions.join('|') + 129 | ')$' 130 | ), 131 | threshold: 10240, 132 | minRatio: 0.8 133 | }) 134 | ) 135 | } 136 | 137 | if (config.build.bundleAnalyzerReport) { 138 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 139 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 140 | } 141 | 142 | module.exports = webpackConfig 143 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const merge = require('webpack-merge') 3 | const prodEnv = require('./prod.env') 4 | 5 | module.exports = merge(prodEnv, { 6 | NODE_ENV: '"development"' 7 | }) 8 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | // Template version: 1.2.4 3 | // see http://vuejs-templates.github.io/webpack for documentation. 4 | 5 | const path = require('path') 6 | 7 | module.exports = { 8 | dev: { 9 | 10 | // Paths 11 | assetsSubDirectory: 'static', 12 | assetsPublicPath: '/', 13 | proxyTable: {}, 14 | 15 | // Various Dev Server settings 16 | host: 'localhost', // can be overwritten by process.env.HOST 17 | port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined 18 | autoOpenBrowser: false, 19 | errorOverlay: true, 20 | notifyOnErrors: true, 21 | poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- 22 | 23 | // Use Eslint Loader? 24 | // If true, your code will be linted during bundling and 25 | // linting errors and warnings will be shown in the console. 26 | useEslint: true, 27 | // If true, eslint errors and warnings will also be shown in the error overlay 28 | // in the browser. 29 | showEslintErrorsInOverlay: false, 30 | 31 | /** 32 | * Source Maps 33 | */ 34 | 35 | // https://webpack.js.org/configuration/devtool/#development 36 | devtool: 'eval-source-map', 37 | 38 | // If you have problems debugging vue-files in devtools, 39 | // set this to false - it *may* help 40 | // https://vue-loader.vuejs.org/en/options.html#cachebusting 41 | cacheBusting: true, 42 | 43 | // CSS Sourcemaps off by default because relative paths are "buggy" 44 | // with this option, according to the CSS-Loader README 45 | // (https://github.com/webpack/css-loader#sourcemaps) 46 | // In our experience, they generally work as expected, 47 | // just be aware of this issue when enabling this option. 48 | cssSourceMap: false, 49 | }, 50 | 51 | build: { 52 | // Template for index.html 53 | index: path.resolve(__dirname, '../docs/index.html'), 54 | 55 | // Paths 56 | assetsRoot: path.resolve(__dirname, '../docs'), 57 | assetsSubDirectory: 'static', 58 | assetsPublicPath: '/', 59 | 60 | /** 61 | * Source Maps 62 | */ 63 | 64 | productionSourceMap: true, 65 | // https://webpack.js.org/configuration/devtool/#production 66 | devtool: '#source-map', 67 | 68 | // Gzip off by default as many popular static hosts such as 69 | // Surge or Netlify already gzip all static assets for you. 70 | // Before setting to `true`, make sure to: 71 | // npm install --save-dev compression-webpack-plugin 72 | productionGzip: false, 73 | productionGzipExtensions: ['js', 'css'], 74 | 75 | // Run the build command with an extra argument to 76 | // View the bundle analyzer report after build finishes: 77 | // `npm run build --report` 78 | // Set to `true` or `false` to always turn it on or off 79 | bundleAnalyzerReport: process.env.npm_config_report 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | module.exports = { 3 | NODE_ENV: '"production"', 4 | } 5 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | jsonui.js.org -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | vue-json-ui-editor
-------------------------------------------------------------------------------- /docs/static/fonts/element-icons.6f0a763.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/vue-json-ui-editor/a2f46a3524b1c28bd45cb1bb53413f8a8628d557/docs/static/fonts/element-icons.6f0a763.ttf -------------------------------------------------------------------------------- /docs/static/js/app.6929d2b6ad0b23e9ecf4.js: -------------------------------------------------------------------------------- 1 | webpackJsonp([1],{IkKh:function(e,t){},"L/hj":function(e,t,n){"use strict";function o(e){return JSON.parse(c()(e))}function i(e,t,n){var o=e[t];return o&&"object"===(void 0===o?"undefined":p()(o))&&!Array.isArray(o)?o:n&&void 0===o?e[t]={}:void 0}function r(e,t){if(1===t.length)return e[t[0]];var n=e[t[0]];if(void 0===n)return n;for(var o=1,r=t.length-1;o0?a(e,o):e)[t]=n,n}Object.defineProperty(t,"__esModule",{value:!0}),t.deepClone=o,t.getExtendibleLeaf=i,t.getChild=r,t.initChild=a,t.setVal=s;var l=n("pFYg"),p=n.n(l),u=n("mvHQ"),c=n.n(u)},SrUm:function(e,t,n){"use strict";function o(e){n("IkKh")}function i(e){n("sHr2")}Object.defineProperty(t,"__esModule",{value:!0});var r=n("7+uW"),a=n("mvHQ"),s=n.n(a),l=n("fZjL"),p=n.n(l),u=n("bOdI"),c=n.n(u),m=n("Gu7T"),d=n.n(m),h=n("Dd8w"),f=n.n(h),v=n("BO1k"),b=n.n(v),y=n("pFYg"),g=n.n(y),x=n("L/hj"),C=x.initChild,O=x.getChild,w=["anyOf","oneOf","enum"],j=function(e,t,n){t.value=e.hasOwnProperty("default")?e.default:t.hasOwnProperty("value")?t.value:"",t.component=e.component,t.schemaType=e.type,t.label=e.title||"",t.description=e.description||"",t.required=e.required||!1,t.disabled=e.disabled||!1,t.name=n},k=function(e,t){var n=t.name.split("."),o=O(e.value,n);if(e.value&&!o){var i=n.pop(),r=n.length>0?C(e.value,n):e.value;e.$set(r,i,t.value)}},_=function(e,t,n){var o=t.attrs||{};return j(t,o,n),o.type||(o.type="checkbox"),o.checked=t.checked||!1,t.name&&(o.name=n,k(e,o)),o},$=function(e,t,n){var o=t.attrs||{};if(t.format)switch(t.format){case"email":o.type||(o.type="email");break;case"uri":o.type||(o.type="url");break;case"regex":o.type||(o.type="text"),o.pattern=t.pattern}if(!o.type)switch(t.type){case"number":case"integer":o.type="number";break;default:o.type="text"}return j(t,o,n),t.name&&(o.name=n,k(e,o)),t.minLength&&(o.minlength=t.minLength),t.maxLength&&(o.maxlength=t.maxLength),o},E=function(e){return e.map(function(e){return"object"!==(void 0===e?"undefined":g()(e))?{value:e,label:e}:e})},S=function(e,t,n){var o=t.attrs||{};j(t,o,n),o.multiple=t.minItems>1,o.items=[];var i=!0,r=!1,a=void 0;try{for(var s,l=b()(w);!(i=(s=l.next()).done);i=!0){var p=s.value;if(t.hasOwnProperty(p))switch(p){case"enum":o.type||(o.type="select"),o.value=o.value||"",o.items=E(t[p]);break;case"oneOf":o.type="radio",o.value=o.value||"",o.items=E(t[p]);break;case"anyOf":o.type="checkbox",o.value=o.value||[],o.items=E(t[p])}}}catch(e){r=!0,a=e}finally{try{!i&&l.return&&l.return()}finally{if(r)throw a}}return o.type||(o.type=t.type,o.value=o.value||[],o.items=[]),t.name&&(o.name=n,k(e,o)),o},P=function e(t,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t.fields,i=arguments[3];if(n&&!1!==n.visible){var r=i?i.join("."):n.name;switch(n.type){case"object":for(var a in n.properties){if(n.properties[a].name=a,n.required){var s=!0,l=!1,p=void 0;try{for(var u,c=b()(n.required);!(s=(u=c.next()).done);s=!0){var m=u.value;n.properties[m]&&(n.properties[m].required=!0)}}catch(e){l=!0,p=e}finally{try{!s&&c.return&&c.return()}finally{if(l)throw p}}}n.name&&!o[r]&&(o[r]={$sub:!0,$title:n.title,$description:n.description}),e(t,n.properties[a],n.name?o[r]:void 0,i?[].concat(d()(i),[a]):[a])}break;case"boolean":o[r]=_(t,n,r);break;case"array":o[r]=S(t,n,r);break;case"integer":case"number":case"string":var h=!0,f=!1,v=void 0;try{for(var y,g=b()(w);!(h=(y=g.next()).done);h=!0){var x=y.value;if(n.hasOwnProperty(x))return n.items={type:n.type,enum:n[x]},void(o[r]=S(t,n,r))}}catch(e){f=!0,v=e}finally{try{!h&&g.return&&g.return()}finally{if(f)throw v}}o[r]=$(t,n,r);break;default:o[r]=$(t,n,r)}}},L=n("L/hj"),q={native:!0},N={title:{component:"h1",option:q},description:{component:"p",option:q},error:{component:"div",option:q},form:{component:"form",option:q},file:{component:"input",option:q},label:{component:"label",option:q},input:{component:"input",option:q},radio:{component:"input",option:q},select:{component:"select",option:q},option:{component:"option",option:q},button:{component:"button",option:f()({},q,{type:"submit",label:"Submit"})},checkbox:{component:"input",option:q},textarea:{component:"textarea",option:q},radiogroup:{component:"div",option:q},checkboxgroup:{component:"div",option:q}},T={component:"input",option:q},U={component:"div",option:q},V={name:"JsonEditor",props:{schema:{type:Object,required:!0},value:{type:Object,default:function(){return{}}},autoComplete:{type:String},noValidate:{type:Boolean},inputWrappingClass:{type:String}},data:function(){return{default:{},fields:{},error:null,data:{}}},created:function(){P(this,Object(L.deepClone)(this.schema)),this.default=Object(L.deepClone)(this.value),this.data=Object(L.deepClone)(this.value)},render:function(e){function t(n,o){var i=this,r=void 0;r=o?Object(L.setVal)(l,o.pop(),{}):l.root,p()(n).length&&p()(n).forEach(function(a){var s=[];if(0!==a.indexOf("$")){var l=n[a];if(l.$sub)return t.call(i,l,o?[].concat(d()(o),[a]):[a]);var p=l.name,u=Object(L.getChild)(i.value,p.split("."));l.value||(l.value=u);var c=l.component?{component:l.component,option:{}}:void 0,m=l.component?c:l.hasOwnProperty("items")&&"select"!==l.type?N[l.type+"group"]||U:N[l.type]||T,h=i.elementOptions(m,l,l),v=[],b=f()({ref:p,domProps:{value:u},on:{input:function(e){var t=e&&e.target?e.target.value:e,n=p.split("."),o=n.pop(),r=n.length>0?Object(L.initChild)(i.data,n):i.data;i.$set(r,o,t),i.$emit("input",i.data)},change:i.changed}},h);switch(delete l.value,l.type){case"textarea":m.option.native&&(b.domProps.innerHTML=u);break;case"radio":case"checkbox":l.hasOwnProperty("items")&&l.items.forEach(function(t){var n=i.elementOptions(N[l.type],t,t,t);v.push(e(N[l.type].component,n,t.label))});break;case"select":l.required||v.push(e(N.option.component)),l.items.forEach(function(t){var n=i.elementOptions(N.option,{value:t.value},l);v.push(e(N.option.component,f()({domProps:{value:t.value}},n),t.label))})}var y=e(m.component,b,v),g=[];if(l.label&&!q.disableWrappingLabel){var x=i.elementOptions(N.label,l,l),C=[];N.label.option.native&&C.push(e("span",{attrs:{"data-required-field":l.required?"true":"false"}},l.label)),C.push(y),l.description&&(C.push(e("br")),C.push(e("small",l.description))),g.push(e(N.label.component,x,C))}else g.push(y),l.description&&(g.push(e("br")),g.push(e("small",l.description)));i.inputWrappingClass?s.push(e("div",{class:i.inputWrappingClass},g)):g.forEach(function(e){return s.push(e)}),r[a]=s[0]}})}function n(t,o){var i=this,r=[],a=o&&o.pop();return t.$title&&r.push(e("div",{class:"sub-title"},t.$title)),p()(t).forEach(function(s){if(0!==s.indexOf("$")){var p=t[s];if(p.$sub){var u=n.call(i,p,o?[].concat(d()(o),[s]):[s]);r.push(e("div",{class:"sub"},u))}else a?r.push(Object(L.getChild)(l,a.split("."))[s]):r.push(l.root[s])}}),r}var o=this,i=[];if(this.schema.title&&i.push(e(N.title.component,this.schema.title)),this.schema.description&&i.push(e(N.description.component,this.schema.description)),this.error){var r=this.elementOptions(N.error),a=[];N.error.option.native&&a.push(this.error),i.push(e(N.error.component,r,a))}var s=[],l={root:{}};t.call(this,this.fields);var u=n.call(this,this.fields);s.push(u);var c=this.elementOptions(N.label),m=this.$slots.hasOwnProperty("default")?{component:this.$slots.default,option:q}:N.button;if(m.component instanceof Array)s.push(e(N.label.component,c,m.component));else{var h=this.elementOptions(m),v=e(m.component,h,m.option.label);s.push(e(N.label.component,c,[v]))}var b=this.elementOptions(N.form,{autocomplete:this.autocomplete,novalidate:this.novalidate});return i.push(e(N.form.component,f()({ref:"__form",on:{submit:function(e){e.stopPropagation(),o.submit(e)},invalid:this.invalid}},b),s)),e("div",i)},mounted:function(){this.reset()},setComponent:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};N[e]={component:t,option:n}},methods:{optionValue:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return"function"==typeof t?t({vm:this,field:e,item:n}):t},elementOptions:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=e.option.native?"attrs":"props",r="function"==typeof e.option?e.option:f()({},e.option,{native:void 0}),a=this.optionValue(n,r,o);return c()({},i,f()({},t,a))},changed:function(e){this.$emit("change",e)},input:function(e){if(!this.$refs[e])throw new Error("Undefined input reference '"+e+"'");return this.$refs[e][0]},form:function(){return this.$refs.__form},checkValidity:function(){return this.$refs.__form.checkValidity()},invalid:function(e){this.$emit("invalid",e)},reset:function(){for(var e in this.data){var t=e.split("."),n=t.pop(),o=t.length>0?Object(L.initChild)(this.data,t):this.data,i=Object(L.getChild)(this.default,e.split("."));this.$set(o,n,i)}},submit:function(e){this.checkValidity()&&this.$emit("submit",e)},setErrorMessage:function(e){this.error=e},clearErrorMessage:function(){this.error=null}}},A=n("VU/8"),J=A(V,null,!1,null,null,null),M=J.exports,D=n("zL8q"),F=n.n(D);M.setComponent("form","el-form",function(e){function t(e){p()(e).forEach(function(n){if(0!==n.indexOf("$")||"$sub"===n){var o=e[n];if(o.$sub)return t(o);if(o.name){i[o.name]=[];var r="array"===o.schemaType&&"radio"===o.type?"string":o.schemaType,a=o.required,s=o.title,l=["radio","checkbox","select"].includes(o.type)?"change":"blur";if(i[o.name].push({type:r,required:a,message:s,trigger:l}),void 0!==o.minlength||void 0!==o.maxlength){var p=o.maxlength||255,u=o.minlength||0,c="Length must between "+u+" and "+p;i[o.name].push({min:u,max:p,message:c,trigger:l})}}}})}var n=e.vm,o=n.data,i={};return t(n.fields),{labelWidth:"120px",rules:i,model:o}}),M.setComponent("label","el-form-item",function(e){return{prop:e.field.name}}),M.setComponent("email","el-input"),M.setComponent("url","el-input"),M.setComponent("number","el-input-number"),M.setComponent("text","el-input"),M.setComponent("textarea","el-input"),M.setComponent("checkbox","el-checkbox"),M.setComponent("checkboxgroup","el-checkbox-group"),M.setComponent("radio","el-radio"),M.setComponent("select","el-select"),M.setComponent("switch","el-switch"),M.setComponent("color","el-color-picker"),M.setComponent("rate","el-rate"),M.setComponent("option",D.Option),M.setComponent("title","h2"),M.setComponent("description","small"),M.setComponent("error","el-alert",function(e){return{type:"error",title:e.vm.error}});var H={data:function(){return{schema:n("x9Nm"),model:{name:"Yourtion",sub:{sEmail:"yourtion@gmail.com"}}}},computed:{jsonString:function(){return s()(this.model,null,2).trim()}},methods:{submit:function(e){var t=this;this.$refs.JsonEditor.form().validate(function(e){if(!e)return t.$refs.JsonEditor.setErrorMessage("Please fill out the required fields"),!1;console.log("model",s()(t.model)),t.$refs.JsonEditor.clearErrorMessage()})},reset:function(){this.$refs.JsonEditor.reset()}},components:{JsonEditor:M}},R=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("el-row",[n("el-col",{attrs:{span:12}},[n("el-card",{staticClass:"form"},[n("json-editor",{ref:"JsonEditor",attrs:{schema:e.schema},model:{value:e.model,callback:function(t){e.model=t},expression:"model"}},[n("el-button",{attrs:{type:"primary"},on:{click:e.submit}},[e._v("Subscribe")]),e._v(" "),n("el-button",{attrs:{type:"reset"},on:{click:e.reset}},[e._v("Reset")])],1)],1)],1),e._v(" "),n("el-col",{attrs:{span:12}},[n("el-card",{staticClass:"box-card"},[n("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[n("span",[e._v("Model")])]),e._v(" "),n("pre",{staticClass:"json"},[e._v(e._s(e.jsonString))])]),e._v(" "),n("br"),e._v(" "),n("el-card",{staticClass:"box-card"},[n("div",{staticClass:"clearfix",attrs:{slot:"header"},slot:"header"},[n("span",[e._v("How to use")])]),e._v(" "),n("div",{staticClass:"json"},[n("p",[e._v("GitHub: "),n("a",{attrs:{href:"https://github.com/yourtion/vue-json-ui-editor",target:"_blank"}},[e._v("vue-json-ui-editor")])]),e._v(" "),n("p",[e._v("NPM: "),n("a",{attrs:{href:"https://www.npmjs.com/package/vue-json-ui-editor",target:"_blank"}},[e._v("json-editor")])])])])],1)],1)},W=[],Y={render:R,staticRenderFns:W},I=Y,B=n("VU/8"),G=o,K=B(H,I,!1,G,null,null),Q=K.exports,Z={name:"app",components:{Subscription:Q}},z=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{attrs:{id:"app"}},[n("Subscription")],1)},X=[],ee={render:z,staticRenderFns:X},te=ee,ne=n("VU/8"),oe=i,ie=ne(Z,te,!1,oe,null,null),re=ie.exports,ae=(n("tvR6"),n("wUZ8")),se=n.n(ae);r.default.use(F.a,{locale:se.a}),r.default.config.productionTip=!1,new r.default({el:"#app",template:"",components:{App:re}})},sHr2:function(e,t){},tvR6:function(e,t){},x9Nm:function(e,t){e.exports={$schema:"http://json-schema.org/draft-07/schema#",type:"object",title:"Json-Editor-Demo",description:"Demo for vue-json-ui-editor using element-ui ",properties:{name:{type:"string",minLength:8,maxLength:80,title:"String",attrs:{placeholder:"Your Full Name",title:"Please enter your full name"}},sub:{title:"SubTitle",description:"SubDescription",type:"object",properties:{sName:{minLength:8,maxLength:80,title:"SubName",attrs:{placeholder:"Sub Full Name",title:"Please enter your full name"}},sUrl:{title:"SubUrl",format:"uri"},sub2:{type:"object",title:"Sub2Title",description:"Sub2Description",properties:{sName2:{format:"regex",title:"Sub2Name",pattern:"*"},sAge:{type:"integer",title:"Sub2Age"}},required:["sName2"]}},required:["sUrl"]},lists:{type:"string",title:"List",enum:["Daily New","Promotion"],attrs:{placeholder:"Select your list subscription",title:"Please select your list subscription"}},lists2:{type:"array",title:"List2",anyOf:[{value:"daily",label:"Daily New"},{value:"promotion",label:"Promotion"}],attrs:{placeholder:"Select your list subscription",title:"Please select your list subscription"}},lists3:{type:"array",title:"List3",oneOf:[{value:"daily",label:"Daily New"},{value:"promotion",label:"Promotion"}]},source:{type:"string",maxLength:120,title:"Source",description:"Ex. Using the NPM Search Engine",attrs:{type:"textarea",placeholder:"How did you hear about us?"}},rate:{type:"number",title:"Rate",default:2,attrs:{type:"rate","allow-half":!0}},color:{type:"string",title:"Color",default:"#409EFF",attrs:{type:"color"}},agree:{type:"boolean",title:"Agree",description:"You agree to receive occasional updates and special offers for vue-json-schema updates.",default:!1,attrs:{type:"switch"}}},additionalProperties:!1,required:["name","email","lists"]}}},["SrUm"]); 2 | //# sourceMappingURL=app.6929d2b6ad0b23e9ecf4.js.map -------------------------------------------------------------------------------- /docs/static/js/manifest.2ae2e69a05c33dfc65f8.js: -------------------------------------------------------------------------------- 1 | !function(r){function n(e){if(o[e])return o[e].exports;var t=o[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,n),t.l=!0,t.exports}var e=window.webpackJsonp;window.webpackJsonp=function(o,u,c){for(var f,i,p,a=0,l=[];a 2 |
3 | 4 |
5 | 6 | 7 | 17 | 18 | 28 | -------------------------------------------------------------------------------- /example/components/Subscription.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 148 | 149 | 186 | -------------------------------------------------------------------------------- /example/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue'; 4 | import App from './App'; 5 | 6 | import ElementUI from 'element-ui'; 7 | import 'element-ui/lib/theme-chalk/index.css'; 8 | import locale from 'element-ui/lib/locale/lang/en'; 9 | 10 | Vue.use(ElementUI, { locale }); 11 | 12 | Vue.config.productionTip = false; 13 | 14 | /* eslint-disable no-new */ 15 | new Vue({ 16 | el: '#app', 17 | template: '', 18 | components: { App }, 19 | }); 20 | -------------------------------------------------------------------------------- /example/schema/newsletter.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "title": "Json-Editor-Demo", 5 | "description": "Demo for vue-json-ui-editor using element-ui ", 6 | "properties": { 7 | "name": { 8 | "type": "string", 9 | "minLength": 8, 10 | "maxLength": 80, 11 | "title": "String", 12 | "attrs": { 13 | "placeholder": "Your Full Name", 14 | "title": "Please enter your full name" 15 | } 16 | }, 17 | "sub": { 18 | "title": "SubTitle", 19 | "description": "SubDescription", 20 | "type": "object", 21 | "properties": { 22 | "sName": { 23 | "minLength": 8, 24 | "maxLength": 80, 25 | "title": "SubName", 26 | "attrs": { 27 | "placeholder": "Sub Full Name", 28 | "title": "Please enter your full name" 29 | } 30 | }, 31 | "sUrl": { 32 | "title": "SubUrl", 33 | "format": "uri" 34 | }, 35 | "sub2": { 36 | "type": "object", 37 | "title": "Sub2Title", 38 | "description": "Sub2Description", 39 | "properties": { 40 | "sName2": { 41 | "format": "regex", 42 | "title": "Sub2Name", 43 | "pattern": "*" 44 | }, 45 | "sAge": { 46 | "type": "integer", 47 | "title": "Sub2Age" 48 | } 49 | }, 50 | "required": [ "sName2" ] 51 | } 52 | }, 53 | "required": ["sUrl"] 54 | }, 55 | "lists": { 56 | "type": "string", 57 | "title": "List", 58 | "enum": ["Daily New", "Promotion"], 59 | "attrs": { 60 | "placeholder": "Select your list subscription", 61 | "title": "Please select your list subscription" 62 | } 63 | }, 64 | "lists2": { 65 | "type": "array", 66 | "title": "List2", 67 | "anyOf": [ 68 | { "value": "daily", "label": "Daily New" }, 69 | { "value": "promotion", "label": "Promotion" } 70 | ], 71 | "attrs": { 72 | "placeholder": "Select your list subscription", 73 | "title": "Please select your list subscription" 74 | } 75 | }, 76 | "lists3": { 77 | "type": "array", 78 | "title": "List3", 79 | "oneOf": [ 80 | { "value": "daily", "label": "Daily New" }, 81 | { "value": "promotion", "label": "Promotion" } 82 | ] 83 | }, 84 | "source": { 85 | "type": "string", 86 | "maxLength": 120, 87 | "title": "Source", 88 | "description": "Ex. Using the NPM Search Engine", 89 | "attrs": { 90 | "type": "textarea", 91 | "placeholder": "How did you hear about us?" 92 | } 93 | }, 94 | "rate": { 95 | "type": "number", 96 | "title": "Rate", 97 | "default": 2, 98 | "attrs": { 99 | "type": "rate", 100 | "allow-half": true 101 | } 102 | }, 103 | "color": { 104 | "type": "string", 105 | "title": "Color", 106 | "default": "#409EFF", 107 | "attrs": { 108 | "type": "color" 109 | } 110 | }, 111 | "agree": { 112 | "type": "boolean", 113 | "title": "Agree", 114 | "description": "You agree to receive occasional updates and special offers for vue-json-schema updates.", 115 | "default": false, 116 | "attrs": { 117 | "type": "switch" 118 | } 119 | } 120 | }, 121 | "additionalProperties": false, 122 | "required": ["name", "email", "lists"] 123 | } 124 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vue-json-ui-editor 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /lib/json-editor.min.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define("json-editor", [], factory); 6 | else if(typeof exports === 'object') 7 | exports["json-editor"] = factory(); 8 | else 9 | root["json-editor"] = factory(); 10 | })(typeof self !== 'undefined' ? self : this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | /******/ 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | /******/ 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) { 20 | /******/ return installedModules[moduleId].exports; 21 | /******/ } 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ i: moduleId, 25 | /******/ l: false, 26 | /******/ exports: {} 27 | /******/ }; 28 | /******/ 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | /******/ 32 | /******/ // Flag the module as loaded 33 | /******/ module.l = true; 34 | /******/ 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | /******/ 39 | /******/ 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | /******/ 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | /******/ 46 | /******/ // define getter function for harmony exports 47 | /******/ __webpack_require__.d = function(exports, name, getter) { 48 | /******/ if(!__webpack_require__.o(exports, name)) { 49 | /******/ Object.defineProperty(exports, name, { 50 | /******/ configurable: false, 51 | /******/ enumerable: true, 52 | /******/ get: getter 53 | /******/ }); 54 | /******/ } 55 | /******/ }; 56 | /******/ 57 | /******/ // getDefaultExport function for compatibility with non-harmony modules 58 | /******/ __webpack_require__.n = function(module) { 59 | /******/ var getter = module && module.__esModule ? 60 | /******/ function getDefault() { return module['default']; } : 61 | /******/ function getModuleExports() { return module; }; 62 | /******/ __webpack_require__.d(getter, 'a', getter); 63 | /******/ return getter; 64 | /******/ }; 65 | /******/ 66 | /******/ // Object.prototype.hasOwnProperty.call 67 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 68 | /******/ 69 | /******/ // __webpack_public_path__ 70 | /******/ __webpack_require__.p = "/lib/"; 71 | /******/ 72 | /******/ // Load entry module and return exports 73 | /******/ return __webpack_require__(__webpack_require__.s = 31); 74 | /******/ }) 75 | /************************************************************************/ 76 | /******/ ([ 77 | /* 0 */ 78 | /***/ (function(module, exports) { 79 | 80 | var core = module.exports = { version: '2.5.7' }; 81 | if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef 82 | 83 | 84 | /***/ }), 85 | /* 1 */ 86 | /***/ (function(module, exports, __webpack_require__) { 87 | 88 | var store = __webpack_require__(26)('wks'); 89 | var uid = __webpack_require__(27); 90 | var Symbol = __webpack_require__(3).Symbol; 91 | var USE_SYMBOL = typeof Symbol == 'function'; 92 | 93 | var $exports = module.exports = function (name) { 94 | return store[name] || (store[name] = 95 | USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); 96 | }; 97 | 98 | $exports.store = store; 99 | 100 | 101 | /***/ }), 102 | /* 2 */ 103 | /***/ (function(module, exports, __webpack_require__) { 104 | 105 | var global = __webpack_require__(3); 106 | var core = __webpack_require__(0); 107 | var ctx = __webpack_require__(19); 108 | var hide = __webpack_require__(6); 109 | var has = __webpack_require__(9); 110 | var PROTOTYPE = 'prototype'; 111 | 112 | var $export = function (type, name, source) { 113 | var IS_FORCED = type & $export.F; 114 | var IS_GLOBAL = type & $export.G; 115 | var IS_STATIC = type & $export.S; 116 | var IS_PROTO = type & $export.P; 117 | var IS_BIND = type & $export.B; 118 | var IS_WRAP = type & $export.W; 119 | var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); 120 | var expProto = exports[PROTOTYPE]; 121 | var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; 122 | var key, own, out; 123 | if (IS_GLOBAL) source = name; 124 | for (key in source) { 125 | // contains in native 126 | own = !IS_FORCED && target && target[key] !== undefined; 127 | if (own && has(exports, key)) continue; 128 | // export native or passed 129 | out = own ? target[key] : source[key]; 130 | // prevent global pollution for namespaces 131 | exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] 132 | // bind timers to global for call from export context 133 | : IS_BIND && own ? ctx(out, global) 134 | // wrap global constructors for prevent change them in library 135 | : IS_WRAP && target[key] == out ? (function (C) { 136 | var F = function (a, b, c) { 137 | if (this instanceof C) { 138 | switch (arguments.length) { 139 | case 0: return new C(); 140 | case 1: return new C(a); 141 | case 2: return new C(a, b); 142 | } return new C(a, b, c); 143 | } return C.apply(this, arguments); 144 | }; 145 | F[PROTOTYPE] = C[PROTOTYPE]; 146 | return F; 147 | // make static versions for prototype methods 148 | })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; 149 | // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% 150 | if (IS_PROTO) { 151 | (exports.virtual || (exports.virtual = {}))[key] = out; 152 | // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% 153 | if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); 154 | } 155 | } 156 | }; 157 | // type bitmap 158 | $export.F = 1; // forced 159 | $export.G = 2; // global 160 | $export.S = 4; // static 161 | $export.P = 8; // proto 162 | $export.B = 16; // bind 163 | $export.W = 32; // wrap 164 | $export.U = 64; // safe 165 | $export.R = 128; // real proto method for `library` 166 | module.exports = $export; 167 | 168 | 169 | /***/ }), 170 | /* 3 */ 171 | /***/ (function(module, exports) { 172 | 173 | // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 174 | var global = module.exports = typeof window != 'undefined' && window.Math == Math 175 | ? window : typeof self != 'undefined' && self.Math == Math ? self 176 | // eslint-disable-next-line no-new-func 177 | : Function('return this')(); 178 | if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef 179 | 180 | 181 | /***/ }), 182 | /* 4 */ 183 | /***/ (function(module, exports, __webpack_require__) { 184 | 185 | var anObject = __webpack_require__(7); 186 | var IE8_DOM_DEFINE = __webpack_require__(38); 187 | var toPrimitive = __webpack_require__(39); 188 | var dP = Object.defineProperty; 189 | 190 | exports.f = __webpack_require__(5) ? Object.defineProperty : function defineProperty(O, P, Attributes) { 191 | anObject(O); 192 | P = toPrimitive(P, true); 193 | anObject(Attributes); 194 | if (IE8_DOM_DEFINE) try { 195 | return dP(O, P, Attributes); 196 | } catch (e) { /* empty */ } 197 | if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); 198 | if ('value' in Attributes) O[P] = Attributes.value; 199 | return O; 200 | }; 201 | 202 | 203 | /***/ }), 204 | /* 5 */ 205 | /***/ (function(module, exports, __webpack_require__) { 206 | 207 | // Thank's IE8 for his funny defineProperty 208 | module.exports = !__webpack_require__(8)(function () { 209 | return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; 210 | }); 211 | 212 | 213 | /***/ }), 214 | /* 6 */ 215 | /***/ (function(module, exports, __webpack_require__) { 216 | 217 | var dP = __webpack_require__(4); 218 | var createDesc = __webpack_require__(12); 219 | module.exports = __webpack_require__(5) ? function (object, key, value) { 220 | return dP.f(object, key, createDesc(1, value)); 221 | } : function (object, key, value) { 222 | object[key] = value; 223 | return object; 224 | }; 225 | 226 | 227 | /***/ }), 228 | /* 7 */ 229 | /***/ (function(module, exports, __webpack_require__) { 230 | 231 | var isObject = __webpack_require__(11); 232 | module.exports = function (it) { 233 | if (!isObject(it)) throw TypeError(it + ' is not an object!'); 234 | return it; 235 | }; 236 | 237 | 238 | /***/ }), 239 | /* 8 */ 240 | /***/ (function(module, exports) { 241 | 242 | module.exports = function (exec) { 243 | try { 244 | return !!exec(); 245 | } catch (e) { 246 | return true; 247 | } 248 | }; 249 | 250 | 251 | /***/ }), 252 | /* 9 */ 253 | /***/ (function(module, exports) { 254 | 255 | var hasOwnProperty = {}.hasOwnProperty; 256 | module.exports = function (it, key) { 257 | return hasOwnProperty.call(it, key); 258 | }; 259 | 260 | 261 | /***/ }), 262 | /* 10 */ 263 | /***/ (function(module, exports, __webpack_require__) { 264 | 265 | // 7.1.13 ToObject(argument) 266 | var defined = __webpack_require__(14); 267 | module.exports = function (it) { 268 | return Object(defined(it)); 269 | }; 270 | 271 | 272 | /***/ }), 273 | /* 11 */ 274 | /***/ (function(module, exports) { 275 | 276 | module.exports = function (it) { 277 | return typeof it === 'object' ? it !== null : typeof it === 'function'; 278 | }; 279 | 280 | 281 | /***/ }), 282 | /* 12 */ 283 | /***/ (function(module, exports) { 284 | 285 | module.exports = function (bitmap, value) { 286 | return { 287 | enumerable: !(bitmap & 1), 288 | configurable: !(bitmap & 2), 289 | writable: !(bitmap & 4), 290 | value: value 291 | }; 292 | }; 293 | 294 | 295 | /***/ }), 296 | /* 13 */ 297 | /***/ (function(module, exports) { 298 | 299 | // 7.1.4 ToInteger 300 | var ceil = Math.ceil; 301 | var floor = Math.floor; 302 | module.exports = function (it) { 303 | return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); 304 | }; 305 | 306 | 307 | /***/ }), 308 | /* 14 */ 309 | /***/ (function(module, exports) { 310 | 311 | // 7.2.1 RequireObjectCoercible(argument) 312 | module.exports = function (it) { 313 | if (it == undefined) throw TypeError("Can't call method on " + it); 314 | return it; 315 | }; 316 | 317 | 318 | /***/ }), 319 | /* 15 */ 320 | /***/ (function(module, exports) { 321 | 322 | module.exports = {}; 323 | 324 | 325 | /***/ }), 326 | /* 16 */ 327 | /***/ (function(module, exports, __webpack_require__) { 328 | 329 | // 19.1.2.14 / 15.2.3.14 Object.keys(O) 330 | var $keys = __webpack_require__(50); 331 | var enumBugKeys = __webpack_require__(28); 332 | 333 | module.exports = Object.keys || function keys(O) { 334 | return $keys(O, enumBugKeys); 335 | }; 336 | 337 | 338 | /***/ }), 339 | /* 17 */ 340 | /***/ (function(module, exports, __webpack_require__) { 341 | 342 | var shared = __webpack_require__(26)('keys'); 343 | var uid = __webpack_require__(27); 344 | module.exports = function (key) { 345 | return shared[key] || (shared[key] = uid(key)); 346 | }; 347 | 348 | 349 | /***/ }), 350 | /* 18 */ 351 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 352 | 353 | "use strict"; 354 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_defineProperty__ = __webpack_require__(33); 355 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_defineProperty___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_defineProperty__); 356 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_toConsumableArray__ = __webpack_require__(40); 357 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_toConsumableArray___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_toConsumableArray__); 358 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_core_js_object_keys__ = __webpack_require__(62); 359 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_babel_runtime_core_js_object_keys___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_babel_runtime_core_js_object_keys__); 360 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends__ = __webpack_require__(66); 361 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends__); 362 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__parser__ = __webpack_require__(73); 363 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils__ = __webpack_require__(30); 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | var option = { native: true }; 372 | var components = { 373 | title: { component: 'h1', option: option }, 374 | description: { component: 'p', option: option }, 375 | error: { component: 'div', option: option }, 376 | form: { component: 'form', option: option }, 377 | file: { component: 'input', option: option }, 378 | label: { component: 'label', option: option }, 379 | input: { component: 'input', option: option }, 380 | radio: { component: 'input', option: option }, 381 | select: { component: 'select', option: option }, 382 | option: { component: 'option', option: option }, 383 | button: { 384 | component: 'button', 385 | option: __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default()({}, option, { 386 | type: 'submit', 387 | label: 'Submit' 388 | }) 389 | }, 390 | checkbox: { component: 'input', option: option }, 391 | textarea: { component: 'textarea', option: option }, 392 | radiogroup: { component: 'div', option: option }, 393 | checkboxgroup: { component: 'div', option: option } 394 | }; 395 | var defaultInput = { component: 'input', option: option }; 396 | var defaultGroup = { component: 'div', option: option }; 397 | 398 | /** 399 | * Edit JSON in UI form with JSON Schema and Vue.js `` component. 400 | * 401 | * @author Yourtion 402 | * @license MIT 403 | */ 404 | /* harmony default export */ __webpack_exports__["a"] = ({ 405 | name: 'JsonEditor', 406 | props: { 407 | /** 408 | * The JSON Schema object. Use the `v-if` directive to load asynchronous schema. 409 | */ 410 | schema: { type: Object, required: true }, 411 | /** 412 | * Use this directive to create two-way data bindings with the component. It automatically picks the correct way to update the element based on the input type. 413 | * @model 414 | * @default {} 415 | */ 416 | value: { type: Object, default: function _default() { 417 | return {}; 418 | } }, 419 | /** 420 | * This property indicates whether the value of the control can be automatically completed by the browser. Possible values are: `off` and `on`. 421 | */ 422 | autoComplete: { type: String }, 423 | /** 424 | * This Boolean attribute indicates that the form is not to be validated when submitted. 425 | */ 426 | noValidate: { type: Boolean }, 427 | /** 428 | * Define the inputs wrapping class. Leave `undefined` to disable input wrapping. 429 | */ 430 | inputWrappingClass: { type: String } 431 | }, 432 | data: function data() { 433 | return { 434 | default: {}, 435 | fields: {}, 436 | error: null, 437 | data: {} 438 | }; 439 | }, 440 | created: function created() { 441 | Object(__WEBPACK_IMPORTED_MODULE_4__parser__["a" /* loadFields */])(this, Object(__WEBPACK_IMPORTED_MODULE_5__utils__["deepClone"])(this.schema)); 442 | this.default = Object(__WEBPACK_IMPORTED_MODULE_5__utils__["deepClone"])(this.value); 443 | this.data = this.value; 444 | }, 445 | render: function render(createElement) { 446 | var _this3 = this; 447 | 448 | var nodes = []; 449 | if (this.schema.title) { 450 | nodes.push(createElement(components.title.component, this.schema.title)); 451 | } 452 | if (this.schema.description) { 453 | nodes.push(createElement(components.description.component, this.schema.description)); 454 | } 455 | if (this.error) { 456 | var errorOptions = this.elementOptions(components.error); 457 | var errorNodes = []; 458 | if (components.error.option.native) { 459 | errorNodes.push(this.error); 460 | } 461 | nodes.push(createElement(components.error.component, errorOptions, errorNodes)); 462 | } 463 | var allFormNodes = []; 464 | var formNode = { 465 | root: {} 466 | }; 467 | function createForm(fields, sub) { 468 | var _this = this; 469 | 470 | var node = void 0; 471 | if (sub) { 472 | node = Object(__WEBPACK_IMPORTED_MODULE_5__utils__["setVal"])(formNode, sub.pop(), {}); 473 | } else { 474 | node = formNode.root; 475 | } 476 | 477 | if (__WEBPACK_IMPORTED_MODULE_2_babel_runtime_core_js_object_keys___default()(fields).length) { 478 | __WEBPACK_IMPORTED_MODULE_2_babel_runtime_core_js_object_keys___default()(fields).forEach(function (key) { 479 | var formNodes = []; 480 | if (key.indexOf('$') === 0) return; 481 | var field = fields[key]; 482 | if (field.$sub) { 483 | return createForm.call(_this, field, sub ? [].concat(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_toConsumableArray___default()(sub), [key]) : [key]); 484 | } 485 | var fieldName = field.name; 486 | 487 | var fieldValue = Object(__WEBPACK_IMPORTED_MODULE_5__utils__["getChild"])(_this.value, fieldName.split('.')); 488 | if (!field.value) { 489 | field.value = fieldValue; 490 | } 491 | var customComponent = field.component ? { component: field.component, option: {} } : undefined; 492 | // eslint-disable-next-line 493 | var element = field.component ? customComponent : field.hasOwnProperty('items') && field.type !== 'select' ? components[field.type + 'group'] || defaultGroup : components[field.type] || defaultInput; 494 | var fieldOptions = _this.elementOptions(element, field, field); 495 | var children = []; 496 | 497 | var input = __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default()({ 498 | ref: fieldName, 499 | domProps: { 500 | value: fieldValue 501 | }, 502 | on: { 503 | input: function input(event) { 504 | var value = event && event.target ? event.target.value : event; 505 | var ns = fieldName.split('.'); 506 | var n = ns.pop(); 507 | var ret = ns.length > 0 ? Object(__WEBPACK_IMPORTED_MODULE_5__utils__["initChild"])(_this.data, ns) : _this.data; 508 | _this.$set(ret, n, value); 509 | /** 510 | * Fired synchronously when the value of an element is changed. 511 | */ 512 | _this.$emit('input', _this.data); 513 | }, 514 | change: _this.changed 515 | } 516 | }, fieldOptions); 517 | delete field.value; 518 | switch (field.type) { 519 | case 'textarea': 520 | if (element.option.native) { 521 | input.domProps.innerHTML = fieldValue; 522 | } 523 | break; 524 | case 'radio': 525 | case 'checkbox': 526 | if (field.hasOwnProperty('items')) { 527 | field.items.forEach(function (item) { 528 | var itemOptions = _this.elementOptions(components[field.type], item, item, item); 529 | children.push(createElement(components[field.type].component, itemOptions, item.label)); 530 | }); 531 | } 532 | break; 533 | case 'select': 534 | if (!field.required) { 535 | children.push(createElement(components.option.component)); 536 | } 537 | field.items.forEach(function (option) { 538 | var optionOptions = _this.elementOptions(components.option, { 539 | value: option.value 540 | }, field); 541 | children.push(createElement(components.option.component, __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default()({ 542 | domProps: { 543 | value: option.value 544 | } 545 | }, optionOptions), option.label)); 546 | }); 547 | break; 548 | } 549 | var inputElement = createElement(element.component, input, children); 550 | 551 | var formControlsNodes = []; 552 | if (field.label && !option.disableWrappingLabel) { 553 | var _labelOptions = _this.elementOptions(components.label, field, field); 554 | var labelNodes = []; 555 | if (components.label.option.native) { 556 | labelNodes.push(createElement('span', { 557 | attrs: { 558 | 'data-required-field': field.required ? 'true' : 'false' 559 | } 560 | }, field.label)); 561 | } 562 | labelNodes.push(inputElement); 563 | if (field.description) { 564 | labelNodes.push(createElement('br')); 565 | labelNodes.push(createElement('small', field.description)); 566 | } 567 | formControlsNodes.push(createElement(components.label.component, _labelOptions, labelNodes)); 568 | } else { 569 | formControlsNodes.push(inputElement); 570 | if (field.description) { 571 | formControlsNodes.push(createElement('br')); 572 | formControlsNodes.push(createElement('small', field.description)); 573 | } 574 | } 575 | if (_this.inputWrappingClass) { 576 | formNodes.push(createElement('div', { 577 | class: _this.inputWrappingClass 578 | }, formControlsNodes)); 579 | } else { 580 | formControlsNodes.forEach(function (node) { 581 | return formNodes.push(node); 582 | }); 583 | } 584 | node[key] = formNodes[0]; 585 | }); 586 | } 587 | } 588 | createForm.call(this, this.fields); 589 | 590 | function createNode(fields, sub) { 591 | var _this2 = this; 592 | 593 | var nodes = []; 594 | var subName = sub && sub.pop(); 595 | if (fields.$title) { 596 | nodes.push(createElement('div', { 597 | class: 'sub-title' 598 | }, fields.$title)); 599 | } 600 | __WEBPACK_IMPORTED_MODULE_2_babel_runtime_core_js_object_keys___default()(fields).forEach(function (key) { 601 | if (key.indexOf('$') === 0) return; 602 | var field = fields[key]; 603 | if (field.$sub) { 604 | var node = createNode.call(_this2, field, sub ? [].concat(__WEBPACK_IMPORTED_MODULE_1_babel_runtime_helpers_toConsumableArray___default()(sub), [key]) : [key]); 605 | nodes.push(createElement('div', { 606 | class: 'sub' 607 | }, node)); 608 | } else if (subName) { 609 | nodes.push(Object(__WEBPACK_IMPORTED_MODULE_5__utils__["getChild"])(formNode, subName.split('.'))[key]); 610 | } else { 611 | nodes.push(formNode.root[key]); 612 | } 613 | }); 614 | return nodes; 615 | } 616 | var formNodes = createNode.call(this, this.fields); 617 | allFormNodes.push(formNodes); 618 | 619 | var labelOptions = this.elementOptions(components.label); 620 | var button = this.$slots.hasOwnProperty('default') ? { component: this.$slots.default, option: option } : components.button; 621 | if (button.component instanceof Array) { 622 | allFormNodes.push(createElement(components.label.component, labelOptions, button.component)); 623 | } else { 624 | var buttonOptions = this.elementOptions(button); 625 | var buttonElement = createElement(button.component, buttonOptions, button.option.label); 626 | allFormNodes.push(createElement(components.label.component, labelOptions, [buttonElement])); 627 | } 628 | var formOptions = this.elementOptions(components.form, { 629 | autocomplete: this.autocomplete, 630 | novalidate: this.novalidate 631 | }); 632 | nodes.push(createElement(components.form.component, __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default()({ 633 | ref: '__form', 634 | on: { 635 | submit: function submit(event) { 636 | event.stopPropagation(); 637 | _this3.submit(event); 638 | }, 639 | invalid: this.invalid 640 | } 641 | }, formOptions), allFormNodes)); 642 | return createElement('div', nodes); 643 | }, 644 | mounted: function mounted() { 645 | this.reset(); 646 | }, 647 | setComponent: function setComponent(type, component) { 648 | var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 649 | 650 | components[type] = { component: component, option: option }; 651 | }, 652 | 653 | methods: { 654 | /** 655 | * @private 656 | */ 657 | optionValue: function optionValue(field, target) { 658 | var item = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 659 | 660 | return typeof target === 'function' ? target({ vm: this, field: field, item: item }) : target; 661 | }, 662 | 663 | /** 664 | * @private 665 | */ 666 | elementOptions: function elementOptions(element) { 667 | var extendingOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 668 | var field = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 669 | var item = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; 670 | 671 | var attrName = element.option.native ? 'attrs' : 'props'; 672 | var elementProps = typeof element.option === 'function' ? element.option : __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default()({}, element.option, { native: undefined }); 673 | var options = this.optionValue(field, elementProps, item); 674 | return __WEBPACK_IMPORTED_MODULE_0_babel_runtime_helpers_defineProperty___default()({}, attrName, __WEBPACK_IMPORTED_MODULE_3_babel_runtime_helpers_extends___default()({}, extendingOptions, options)); 675 | }, 676 | 677 | /** 678 | * @private 679 | */ 680 | changed: function changed(e) { 681 | /** 682 | * Fired when a change to the element's value is committed by the user. 683 | */ 684 | this.$emit('change', e); 685 | }, 686 | 687 | /** 688 | * Get a form input reference 689 | */ 690 | input: function input(name) { 691 | if (!this.$refs[name]) { 692 | throw new Error('Undefined input reference \'' + name + '\''); 693 | } 694 | return this.$refs[name][0]; 695 | }, 696 | 697 | /** 698 | * Get the form reference 699 | */ 700 | form: function form() { 701 | return this.$refs.__form; 702 | }, 703 | 704 | /** 705 | * Checks whether the form has any constraints and whether it satisfies them. If the form fails its constraints, the browser fires a cancelable `invalid` event at the element, and then returns false. 706 | */ 707 | checkValidity: function checkValidity() { 708 | return this.$refs.__form.checkValidity(); 709 | }, 710 | 711 | /** 712 | * @private 713 | */ 714 | invalid: function invalid(e) { 715 | /** 716 | * Fired when a submittable element has been checked and doesn't satisfy its constraints. The validity of submittable elements is checked before submitting their owner form, or after the `checkValidity()` of the element or its owner form is called. 717 | */ 718 | this.$emit('invalid', e); 719 | }, 720 | 721 | /** 722 | * Reset the value of all elements of the parent form. 723 | */ 724 | reset: function reset() { 725 | for (var key in this.data) { 726 | var ns = key.split('.'); 727 | var n = ns.pop(); 728 | var ret = ns.length > 0 ? Object(__WEBPACK_IMPORTED_MODULE_5__utils__["initChild"])(this.data, ns) : this.data; 729 | var value = Object(__WEBPACK_IMPORTED_MODULE_5__utils__["getChild"])(this.default, key.split('.')); 730 | this.$set(ret, n, value); 731 | } 732 | }, 733 | 734 | /** 735 | * Send the content of the form to the server 736 | */ 737 | submit: function submit(event) { 738 | if (this.checkValidity()) { 739 | /** 740 | * Fired when a form is submitted 741 | */ 742 | this.$emit('submit', event); 743 | } 744 | }, 745 | 746 | /** 747 | * Set a message error. 748 | */ 749 | setErrorMessage: function setErrorMessage(message) { 750 | this.error = message; 751 | }, 752 | 753 | /** 754 | * clear the message error. 755 | */ 756 | clearErrorMessage: function clearErrorMessage() { 757 | this.error = null; 758 | } 759 | } 760 | }); 761 | 762 | /***/ }), 763 | /* 19 */ 764 | /***/ (function(module, exports, __webpack_require__) { 765 | 766 | // optional / simple context binding 767 | var aFunction = __webpack_require__(37); 768 | module.exports = function (fn, that, length) { 769 | aFunction(fn); 770 | if (that === undefined) return fn; 771 | switch (length) { 772 | case 1: return function (a) { 773 | return fn.call(that, a); 774 | }; 775 | case 2: return function (a, b) { 776 | return fn.call(that, a, b); 777 | }; 778 | case 3: return function (a, b, c) { 779 | return fn.call(that, a, b, c); 780 | }; 781 | } 782 | return function (/* ...args */) { 783 | return fn.apply(that, arguments); 784 | }; 785 | }; 786 | 787 | 788 | /***/ }), 789 | /* 20 */ 790 | /***/ (function(module, exports, __webpack_require__) { 791 | 792 | var isObject = __webpack_require__(11); 793 | var document = __webpack_require__(3).document; 794 | // typeof document.createElement is 'object' in old IE 795 | var is = isObject(document) && isObject(document.createElement); 796 | module.exports = function (it) { 797 | return is ? document.createElement(it) : {}; 798 | }; 799 | 800 | 801 | /***/ }), 802 | /* 21 */ 803 | /***/ (function(module, exports) { 804 | 805 | module.exports = true; 806 | 807 | 808 | /***/ }), 809 | /* 22 */ 810 | /***/ (function(module, exports, __webpack_require__) { 811 | 812 | // to indexed object, toObject with fallback for non-array-like ES3 strings 813 | var IObject = __webpack_require__(23); 814 | var defined = __webpack_require__(14); 815 | module.exports = function (it) { 816 | return IObject(defined(it)); 817 | }; 818 | 819 | 820 | /***/ }), 821 | /* 23 */ 822 | /***/ (function(module, exports, __webpack_require__) { 823 | 824 | // fallback for non-array-like ES3 and non-enumerable old V8 strings 825 | var cof = __webpack_require__(24); 826 | // eslint-disable-next-line no-prototype-builtins 827 | module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { 828 | return cof(it) == 'String' ? it.split('') : Object(it); 829 | }; 830 | 831 | 832 | /***/ }), 833 | /* 24 */ 834 | /***/ (function(module, exports) { 835 | 836 | var toString = {}.toString; 837 | 838 | module.exports = function (it) { 839 | return toString.call(it).slice(8, -1); 840 | }; 841 | 842 | 843 | /***/ }), 844 | /* 25 */ 845 | /***/ (function(module, exports, __webpack_require__) { 846 | 847 | // 7.1.15 ToLength 848 | var toInteger = __webpack_require__(13); 849 | var min = Math.min; 850 | module.exports = function (it) { 851 | return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 852 | }; 853 | 854 | 855 | /***/ }), 856 | /* 26 */ 857 | /***/ (function(module, exports, __webpack_require__) { 858 | 859 | var core = __webpack_require__(0); 860 | var global = __webpack_require__(3); 861 | var SHARED = '__core-js_shared__'; 862 | var store = global[SHARED] || (global[SHARED] = {}); 863 | 864 | (module.exports = function (key, value) { 865 | return store[key] || (store[key] = value !== undefined ? value : {}); 866 | })('versions', []).push({ 867 | version: core.version, 868 | mode: __webpack_require__(21) ? 'pure' : 'global', 869 | copyright: '© 2018 Denis Pushkarev (zloirock.ru)' 870 | }); 871 | 872 | 873 | /***/ }), 874 | /* 27 */ 875 | /***/ (function(module, exports) { 876 | 877 | var id = 0; 878 | var px = Math.random(); 879 | module.exports = function (key) { 880 | return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); 881 | }; 882 | 883 | 884 | /***/ }), 885 | /* 28 */ 886 | /***/ (function(module, exports) { 887 | 888 | // IE 8- don't enum bug keys 889 | module.exports = ( 890 | 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' 891 | ).split(','); 892 | 893 | 894 | /***/ }), 895 | /* 29 */ 896 | /***/ (function(module, exports, __webpack_require__) { 897 | 898 | var def = __webpack_require__(4).f; 899 | var has = __webpack_require__(9); 900 | var TAG = __webpack_require__(1)('toStringTag'); 901 | 902 | module.exports = function (it, tag, stat) { 903 | if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); 904 | }; 905 | 906 | 907 | /***/ }), 908 | /* 30 */ 909 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 910 | 911 | "use strict"; 912 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 913 | /* harmony export (immutable) */ __webpack_exports__["deepClone"] = deepClone; 914 | /* harmony export (immutable) */ __webpack_exports__["getExtendibleLeaf"] = getExtendibleLeaf; 915 | /* harmony export (immutable) */ __webpack_exports__["getChild"] = getChild; 916 | /* harmony export (immutable) */ __webpack_exports__["initChild"] = initChild; 917 | /* harmony export (immutable) */ __webpack_exports__["setVal"] = setVal; 918 | function deepClone(obj) { 919 | return JSON.parse(JSON.stringify(obj)); 920 | } 921 | 922 | function getExtendibleLeaf(obj, n, initIt) { 923 | const v = obj[n]; 924 | if (v && typeof v === 'object' && !Array.isArray(v)) { 925 | return v; 926 | } 927 | if (initIt && v === undefined) { 928 | return (obj[n] = {}); 929 | } 930 | } 931 | 932 | function getChild(data, ns) { 933 | if (ns.length === 1) { 934 | return data[ns[0]]; 935 | } 936 | let obj = data[ns[0]]; 937 | if (obj === undefined) return obj; 938 | let i = 1; 939 | const end = ns.length - 1; 940 | for (; i < end; i++) { 941 | obj = getExtendibleLeaf(obj, ns[i], false); 942 | if (obj === undefined) return obj; 943 | } 944 | return obj[ns[i]]; 945 | } 946 | 947 | function initChild(data, ns) { 948 | if (ns.length === 1) { 949 | const ret = getExtendibleLeaf(data, ns[0], true); 950 | if (ret === undefined) { 951 | throw new TypeError('fail to init because namespace ' + ns[0] + ' = ' + data[ns[0]]); 952 | } 953 | return ret; 954 | } 955 | let parent = data; 956 | let obj = data[ns[0]]; 957 | if (obj === undefined) obj = data[ns[0]] = {}; 958 | for (let i = 1; i < ns.length; i++) { 959 | const n = ns[i]; 960 | const ret = getExtendibleLeaf(obj, n, true); 961 | if (ret === undefined) { 962 | throw new TypeError('fail to init because namespace ' + ns.join('.') + ' = ' + obj + '(' + typeof obj + ')'); 963 | } 964 | parent = obj; 965 | obj = ret; 966 | if (parent[n] === undefined) { 967 | throw new TypeError('fail to init because namespace ' + ns.slice(0, i).join('.') + ' = ' + parent); 968 | } 969 | } 970 | return obj; 971 | } 972 | 973 | function setVal(data, n, v) { 974 | const ns = Array.isArray(n) ? n : n.split('.'); 975 | // eslint-disable-next-line 976 | n = ns.pop(); 977 | const ret = ns.length > 0 ? initChild(data, ns) : data; 978 | ret[n] = v; 979 | return v; 980 | } 981 | 982 | 983 | /***/ }), 984 | /* 31 */ 985 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 986 | 987 | "use strict"; 988 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 989 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_JsonEditor_vue__ = __webpack_require__(18); 990 | /* empty harmony namespace reexport */ 991 | var normalizeComponent = __webpack_require__(32) 992 | /* script */ 993 | 994 | 995 | /* template */ 996 | var __vue_template__ = null 997 | /* template functional */ 998 | var __vue_template_functional__ = false 999 | /* styles */ 1000 | var __vue_styles__ = null 1001 | /* scopeId */ 1002 | var __vue_scopeId__ = null 1003 | /* moduleIdentifier (server only) */ 1004 | var __vue_module_identifier__ = null 1005 | var Component = normalizeComponent( 1006 | __WEBPACK_IMPORTED_MODULE_0__babel_loader_node_modules_vue_loader_lib_selector_type_script_index_0_JsonEditor_vue__["a" /* default */], 1007 | __vue_template__, 1008 | __vue_template_functional__, 1009 | __vue_styles__, 1010 | __vue_scopeId__, 1011 | __vue_module_identifier__ 1012 | ) 1013 | 1014 | /* harmony default export */ __webpack_exports__["default"] = (Component.exports); 1015 | 1016 | 1017 | /***/ }), 1018 | /* 32 */ 1019 | /***/ (function(module, exports) { 1020 | 1021 | /* globals __VUE_SSR_CONTEXT__ */ 1022 | 1023 | // IMPORTANT: Do NOT use ES2015 features in this file. 1024 | // This module is a runtime utility for cleaner component module output and will 1025 | // be included in the final webpack user bundle. 1026 | 1027 | module.exports = function normalizeComponent ( 1028 | rawScriptExports, 1029 | compiledTemplate, 1030 | functionalTemplate, 1031 | injectStyles, 1032 | scopeId, 1033 | moduleIdentifier /* server only */ 1034 | ) { 1035 | var esModule 1036 | var scriptExports = rawScriptExports = rawScriptExports || {} 1037 | 1038 | // ES6 modules interop 1039 | var type = typeof rawScriptExports.default 1040 | if (type === 'object' || type === 'function') { 1041 | esModule = rawScriptExports 1042 | scriptExports = rawScriptExports.default 1043 | } 1044 | 1045 | // Vue.extend constructor export interop 1046 | var options = typeof scriptExports === 'function' 1047 | ? scriptExports.options 1048 | : scriptExports 1049 | 1050 | // render functions 1051 | if (compiledTemplate) { 1052 | options.render = compiledTemplate.render 1053 | options.staticRenderFns = compiledTemplate.staticRenderFns 1054 | options._compiled = true 1055 | } 1056 | 1057 | // functional template 1058 | if (functionalTemplate) { 1059 | options.functional = true 1060 | } 1061 | 1062 | // scopedId 1063 | if (scopeId) { 1064 | options._scopeId = scopeId 1065 | } 1066 | 1067 | var hook 1068 | if (moduleIdentifier) { // server build 1069 | hook = function (context) { 1070 | // 2.3 injection 1071 | context = 1072 | context || // cached call 1073 | (this.$vnode && this.$vnode.ssrContext) || // stateful 1074 | (this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext) // functional 1075 | // 2.2 with runInNewContext: true 1076 | if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { 1077 | context = __VUE_SSR_CONTEXT__ 1078 | } 1079 | // inject component styles 1080 | if (injectStyles) { 1081 | injectStyles.call(this, context) 1082 | } 1083 | // register component module identifier for async chunk inferrence 1084 | if (context && context._registeredComponents) { 1085 | context._registeredComponents.add(moduleIdentifier) 1086 | } 1087 | } 1088 | // used by ssr in case component is cached and beforeCreate 1089 | // never gets called 1090 | options._ssrRegister = hook 1091 | } else if (injectStyles) { 1092 | hook = injectStyles 1093 | } 1094 | 1095 | if (hook) { 1096 | var functional = options.functional 1097 | var existing = functional 1098 | ? options.render 1099 | : options.beforeCreate 1100 | 1101 | if (!functional) { 1102 | // inject component registration as beforeCreate hook 1103 | options.beforeCreate = existing 1104 | ? [].concat(existing, hook) 1105 | : [hook] 1106 | } else { 1107 | // for template-only hot-reload because in that case the render fn doesn't 1108 | // go through the normalizer 1109 | options._injectStyles = hook 1110 | // register for functioal component in vue file 1111 | options.render = function renderWithStyleInjection (h, context) { 1112 | hook.call(context) 1113 | return existing(h, context) 1114 | } 1115 | } 1116 | } 1117 | 1118 | return { 1119 | esModule: esModule, 1120 | exports: scriptExports, 1121 | options: options 1122 | } 1123 | } 1124 | 1125 | 1126 | /***/ }), 1127 | /* 33 */ 1128 | /***/ (function(module, exports, __webpack_require__) { 1129 | 1130 | "use strict"; 1131 | 1132 | 1133 | exports.__esModule = true; 1134 | 1135 | var _defineProperty = __webpack_require__(34); 1136 | 1137 | var _defineProperty2 = _interopRequireDefault(_defineProperty); 1138 | 1139 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1140 | 1141 | exports.default = function (obj, key, value) { 1142 | if (key in obj) { 1143 | (0, _defineProperty2.default)(obj, key, { 1144 | value: value, 1145 | enumerable: true, 1146 | configurable: true, 1147 | writable: true 1148 | }); 1149 | } else { 1150 | obj[key] = value; 1151 | } 1152 | 1153 | return obj; 1154 | }; 1155 | 1156 | /***/ }), 1157 | /* 34 */ 1158 | /***/ (function(module, exports, __webpack_require__) { 1159 | 1160 | module.exports = { "default": __webpack_require__(35), __esModule: true }; 1161 | 1162 | /***/ }), 1163 | /* 35 */ 1164 | /***/ (function(module, exports, __webpack_require__) { 1165 | 1166 | __webpack_require__(36); 1167 | var $Object = __webpack_require__(0).Object; 1168 | module.exports = function defineProperty(it, key, desc) { 1169 | return $Object.defineProperty(it, key, desc); 1170 | }; 1171 | 1172 | 1173 | /***/ }), 1174 | /* 36 */ 1175 | /***/ (function(module, exports, __webpack_require__) { 1176 | 1177 | var $export = __webpack_require__(2); 1178 | // 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes) 1179 | $export($export.S + $export.F * !__webpack_require__(5), 'Object', { defineProperty: __webpack_require__(4).f }); 1180 | 1181 | 1182 | /***/ }), 1183 | /* 37 */ 1184 | /***/ (function(module, exports) { 1185 | 1186 | module.exports = function (it) { 1187 | if (typeof it != 'function') throw TypeError(it + ' is not a function!'); 1188 | return it; 1189 | }; 1190 | 1191 | 1192 | /***/ }), 1193 | /* 38 */ 1194 | /***/ (function(module, exports, __webpack_require__) { 1195 | 1196 | module.exports = !__webpack_require__(5) && !__webpack_require__(8)(function () { 1197 | return Object.defineProperty(__webpack_require__(20)('div'), 'a', { get: function () { return 7; } }).a != 7; 1198 | }); 1199 | 1200 | 1201 | /***/ }), 1202 | /* 39 */ 1203 | /***/ (function(module, exports, __webpack_require__) { 1204 | 1205 | // 7.1.1 ToPrimitive(input [, PreferredType]) 1206 | var isObject = __webpack_require__(11); 1207 | // instead of the ES6 spec version, we didn't implement @@toPrimitive case 1208 | // and the second argument - flag - preferred type is a string 1209 | module.exports = function (it, S) { 1210 | if (!isObject(it)) return it; 1211 | var fn, val; 1212 | if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; 1213 | if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; 1214 | if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; 1215 | throw TypeError("Can't convert object to primitive value"); 1216 | }; 1217 | 1218 | 1219 | /***/ }), 1220 | /* 40 */ 1221 | /***/ (function(module, exports, __webpack_require__) { 1222 | 1223 | "use strict"; 1224 | 1225 | 1226 | exports.__esModule = true; 1227 | 1228 | var _from = __webpack_require__(41); 1229 | 1230 | var _from2 = _interopRequireDefault(_from); 1231 | 1232 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1233 | 1234 | exports.default = function (arr) { 1235 | if (Array.isArray(arr)) { 1236 | for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { 1237 | arr2[i] = arr[i]; 1238 | } 1239 | 1240 | return arr2; 1241 | } else { 1242 | return (0, _from2.default)(arr); 1243 | } 1244 | }; 1245 | 1246 | /***/ }), 1247 | /* 41 */ 1248 | /***/ (function(module, exports, __webpack_require__) { 1249 | 1250 | module.exports = { "default": __webpack_require__(42), __esModule: true }; 1251 | 1252 | /***/ }), 1253 | /* 42 */ 1254 | /***/ (function(module, exports, __webpack_require__) { 1255 | 1256 | __webpack_require__(43); 1257 | __webpack_require__(55); 1258 | module.exports = __webpack_require__(0).Array.from; 1259 | 1260 | 1261 | /***/ }), 1262 | /* 43 */ 1263 | /***/ (function(module, exports, __webpack_require__) { 1264 | 1265 | "use strict"; 1266 | 1267 | var $at = __webpack_require__(44)(true); 1268 | 1269 | // 21.1.3.27 String.prototype[@@iterator]() 1270 | __webpack_require__(45)(String, 'String', function (iterated) { 1271 | this._t = String(iterated); // target 1272 | this._i = 0; // next index 1273 | // 21.1.5.2.1 %StringIteratorPrototype%.next() 1274 | }, function () { 1275 | var O = this._t; 1276 | var index = this._i; 1277 | var point; 1278 | if (index >= O.length) return { value: undefined, done: true }; 1279 | point = $at(O, index); 1280 | this._i += point.length; 1281 | return { value: point, done: false }; 1282 | }); 1283 | 1284 | 1285 | /***/ }), 1286 | /* 44 */ 1287 | /***/ (function(module, exports, __webpack_require__) { 1288 | 1289 | var toInteger = __webpack_require__(13); 1290 | var defined = __webpack_require__(14); 1291 | // true -> String#at 1292 | // false -> String#codePointAt 1293 | module.exports = function (TO_STRING) { 1294 | return function (that, pos) { 1295 | var s = String(defined(that)); 1296 | var i = toInteger(pos); 1297 | var l = s.length; 1298 | var a, b; 1299 | if (i < 0 || i >= l) return TO_STRING ? '' : undefined; 1300 | a = s.charCodeAt(i); 1301 | return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff 1302 | ? TO_STRING ? s.charAt(i) : a 1303 | : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; 1304 | }; 1305 | }; 1306 | 1307 | 1308 | /***/ }), 1309 | /* 45 */ 1310 | /***/ (function(module, exports, __webpack_require__) { 1311 | 1312 | "use strict"; 1313 | 1314 | var LIBRARY = __webpack_require__(21); 1315 | var $export = __webpack_require__(2); 1316 | var redefine = __webpack_require__(46); 1317 | var hide = __webpack_require__(6); 1318 | var Iterators = __webpack_require__(15); 1319 | var $iterCreate = __webpack_require__(47); 1320 | var setToStringTag = __webpack_require__(29); 1321 | var getPrototypeOf = __webpack_require__(54); 1322 | var ITERATOR = __webpack_require__(1)('iterator'); 1323 | var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` 1324 | var FF_ITERATOR = '@@iterator'; 1325 | var KEYS = 'keys'; 1326 | var VALUES = 'values'; 1327 | 1328 | var returnThis = function () { return this; }; 1329 | 1330 | module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { 1331 | $iterCreate(Constructor, NAME, next); 1332 | var getMethod = function (kind) { 1333 | if (!BUGGY && kind in proto) return proto[kind]; 1334 | switch (kind) { 1335 | case KEYS: return function keys() { return new Constructor(this, kind); }; 1336 | case VALUES: return function values() { return new Constructor(this, kind); }; 1337 | } return function entries() { return new Constructor(this, kind); }; 1338 | }; 1339 | var TAG = NAME + ' Iterator'; 1340 | var DEF_VALUES = DEFAULT == VALUES; 1341 | var VALUES_BUG = false; 1342 | var proto = Base.prototype; 1343 | var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; 1344 | var $default = $native || getMethod(DEFAULT); 1345 | var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; 1346 | var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; 1347 | var methods, key, IteratorPrototype; 1348 | // Fix native 1349 | if ($anyNative) { 1350 | IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); 1351 | if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { 1352 | // Set @@toStringTag to native iterators 1353 | setToStringTag(IteratorPrototype, TAG, true); 1354 | // fix for some old engines 1355 | if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); 1356 | } 1357 | } 1358 | // fix Array#{values, @@iterator}.name in V8 / FF 1359 | if (DEF_VALUES && $native && $native.name !== VALUES) { 1360 | VALUES_BUG = true; 1361 | $default = function values() { return $native.call(this); }; 1362 | } 1363 | // Define iterator 1364 | if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { 1365 | hide(proto, ITERATOR, $default); 1366 | } 1367 | // Plug for library 1368 | Iterators[NAME] = $default; 1369 | Iterators[TAG] = returnThis; 1370 | if (DEFAULT) { 1371 | methods = { 1372 | values: DEF_VALUES ? $default : getMethod(VALUES), 1373 | keys: IS_SET ? $default : getMethod(KEYS), 1374 | entries: $entries 1375 | }; 1376 | if (FORCED) for (key in methods) { 1377 | if (!(key in proto)) redefine(proto, key, methods[key]); 1378 | } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); 1379 | } 1380 | return methods; 1381 | }; 1382 | 1383 | 1384 | /***/ }), 1385 | /* 46 */ 1386 | /***/ (function(module, exports, __webpack_require__) { 1387 | 1388 | module.exports = __webpack_require__(6); 1389 | 1390 | 1391 | /***/ }), 1392 | /* 47 */ 1393 | /***/ (function(module, exports, __webpack_require__) { 1394 | 1395 | "use strict"; 1396 | 1397 | var create = __webpack_require__(48); 1398 | var descriptor = __webpack_require__(12); 1399 | var setToStringTag = __webpack_require__(29); 1400 | var IteratorPrototype = {}; 1401 | 1402 | // 25.1.2.1.1 %IteratorPrototype%[@@iterator]() 1403 | __webpack_require__(6)(IteratorPrototype, __webpack_require__(1)('iterator'), function () { return this; }); 1404 | 1405 | module.exports = function (Constructor, NAME, next) { 1406 | Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); 1407 | setToStringTag(Constructor, NAME + ' Iterator'); 1408 | }; 1409 | 1410 | 1411 | /***/ }), 1412 | /* 48 */ 1413 | /***/ (function(module, exports, __webpack_require__) { 1414 | 1415 | // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) 1416 | var anObject = __webpack_require__(7); 1417 | var dPs = __webpack_require__(49); 1418 | var enumBugKeys = __webpack_require__(28); 1419 | var IE_PROTO = __webpack_require__(17)('IE_PROTO'); 1420 | var Empty = function () { /* empty */ }; 1421 | var PROTOTYPE = 'prototype'; 1422 | 1423 | // Create object with fake `null` prototype: use iframe Object with cleared prototype 1424 | var createDict = function () { 1425 | // Thrash, waste and sodomy: IE GC bug 1426 | var iframe = __webpack_require__(20)('iframe'); 1427 | var i = enumBugKeys.length; 1428 | var lt = '<'; 1429 | var gt = '>'; 1430 | var iframeDocument; 1431 | iframe.style.display = 'none'; 1432 | __webpack_require__(53).appendChild(iframe); 1433 | iframe.src = 'javascript:'; // eslint-disable-line no-script-url 1434 | // createDict = iframe.contentWindow.Object; 1435 | // html.removeChild(iframe); 1436 | iframeDocument = iframe.contentWindow.document; 1437 | iframeDocument.open(); 1438 | iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); 1439 | iframeDocument.close(); 1440 | createDict = iframeDocument.F; 1441 | while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; 1442 | return createDict(); 1443 | }; 1444 | 1445 | module.exports = Object.create || function create(O, Properties) { 1446 | var result; 1447 | if (O !== null) { 1448 | Empty[PROTOTYPE] = anObject(O); 1449 | result = new Empty(); 1450 | Empty[PROTOTYPE] = null; 1451 | // add "__proto__" for Object.getPrototypeOf polyfill 1452 | result[IE_PROTO] = O; 1453 | } else result = createDict(); 1454 | return Properties === undefined ? result : dPs(result, Properties); 1455 | }; 1456 | 1457 | 1458 | /***/ }), 1459 | /* 49 */ 1460 | /***/ (function(module, exports, __webpack_require__) { 1461 | 1462 | var dP = __webpack_require__(4); 1463 | var anObject = __webpack_require__(7); 1464 | var getKeys = __webpack_require__(16); 1465 | 1466 | module.exports = __webpack_require__(5) ? Object.defineProperties : function defineProperties(O, Properties) { 1467 | anObject(O); 1468 | var keys = getKeys(Properties); 1469 | var length = keys.length; 1470 | var i = 0; 1471 | var P; 1472 | while (length > i) dP.f(O, P = keys[i++], Properties[P]); 1473 | return O; 1474 | }; 1475 | 1476 | 1477 | /***/ }), 1478 | /* 50 */ 1479 | /***/ (function(module, exports, __webpack_require__) { 1480 | 1481 | var has = __webpack_require__(9); 1482 | var toIObject = __webpack_require__(22); 1483 | var arrayIndexOf = __webpack_require__(51)(false); 1484 | var IE_PROTO = __webpack_require__(17)('IE_PROTO'); 1485 | 1486 | module.exports = function (object, names) { 1487 | var O = toIObject(object); 1488 | var i = 0; 1489 | var result = []; 1490 | var key; 1491 | for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); 1492 | // Don't enum bug & hidden keys 1493 | while (names.length > i) if (has(O, key = names[i++])) { 1494 | ~arrayIndexOf(result, key) || result.push(key); 1495 | } 1496 | return result; 1497 | }; 1498 | 1499 | 1500 | /***/ }), 1501 | /* 51 */ 1502 | /***/ (function(module, exports, __webpack_require__) { 1503 | 1504 | // false -> Array#indexOf 1505 | // true -> Array#includes 1506 | var toIObject = __webpack_require__(22); 1507 | var toLength = __webpack_require__(25); 1508 | var toAbsoluteIndex = __webpack_require__(52); 1509 | module.exports = function (IS_INCLUDES) { 1510 | return function ($this, el, fromIndex) { 1511 | var O = toIObject($this); 1512 | var length = toLength(O.length); 1513 | var index = toAbsoluteIndex(fromIndex, length); 1514 | var value; 1515 | // Array#includes uses SameValueZero equality algorithm 1516 | // eslint-disable-next-line no-self-compare 1517 | if (IS_INCLUDES && el != el) while (length > index) { 1518 | value = O[index++]; 1519 | // eslint-disable-next-line no-self-compare 1520 | if (value != value) return true; 1521 | // Array#indexOf ignores holes, Array#includes - not 1522 | } else for (;length > index; index++) if (IS_INCLUDES || index in O) { 1523 | if (O[index] === el) return IS_INCLUDES || index || 0; 1524 | } return !IS_INCLUDES && -1; 1525 | }; 1526 | }; 1527 | 1528 | 1529 | /***/ }), 1530 | /* 52 */ 1531 | /***/ (function(module, exports, __webpack_require__) { 1532 | 1533 | var toInteger = __webpack_require__(13); 1534 | var max = Math.max; 1535 | var min = Math.min; 1536 | module.exports = function (index, length) { 1537 | index = toInteger(index); 1538 | return index < 0 ? max(index + length, 0) : min(index, length); 1539 | }; 1540 | 1541 | 1542 | /***/ }), 1543 | /* 53 */ 1544 | /***/ (function(module, exports, __webpack_require__) { 1545 | 1546 | var document = __webpack_require__(3).document; 1547 | module.exports = document && document.documentElement; 1548 | 1549 | 1550 | /***/ }), 1551 | /* 54 */ 1552 | /***/ (function(module, exports, __webpack_require__) { 1553 | 1554 | // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) 1555 | var has = __webpack_require__(9); 1556 | var toObject = __webpack_require__(10); 1557 | var IE_PROTO = __webpack_require__(17)('IE_PROTO'); 1558 | var ObjectProto = Object.prototype; 1559 | 1560 | module.exports = Object.getPrototypeOf || function (O) { 1561 | O = toObject(O); 1562 | if (has(O, IE_PROTO)) return O[IE_PROTO]; 1563 | if (typeof O.constructor == 'function' && O instanceof O.constructor) { 1564 | return O.constructor.prototype; 1565 | } return O instanceof Object ? ObjectProto : null; 1566 | }; 1567 | 1568 | 1569 | /***/ }), 1570 | /* 55 */ 1571 | /***/ (function(module, exports, __webpack_require__) { 1572 | 1573 | "use strict"; 1574 | 1575 | var ctx = __webpack_require__(19); 1576 | var $export = __webpack_require__(2); 1577 | var toObject = __webpack_require__(10); 1578 | var call = __webpack_require__(56); 1579 | var isArrayIter = __webpack_require__(57); 1580 | var toLength = __webpack_require__(25); 1581 | var createProperty = __webpack_require__(58); 1582 | var getIterFn = __webpack_require__(59); 1583 | 1584 | $export($export.S + $export.F * !__webpack_require__(61)(function (iter) { Array.from(iter); }), 'Array', { 1585 | // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined) 1586 | from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { 1587 | var O = toObject(arrayLike); 1588 | var C = typeof this == 'function' ? this : Array; 1589 | var aLen = arguments.length; 1590 | var mapfn = aLen > 1 ? arguments[1] : undefined; 1591 | var mapping = mapfn !== undefined; 1592 | var index = 0; 1593 | var iterFn = getIterFn(O); 1594 | var length, result, step, iterator; 1595 | if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2); 1596 | // if object isn't iterable or it's array with default iterator - use simple case 1597 | if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) { 1598 | for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) { 1599 | createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value); 1600 | } 1601 | } else { 1602 | length = toLength(O.length); 1603 | for (result = new C(length); length > index; index++) { 1604 | createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]); 1605 | } 1606 | } 1607 | result.length = index; 1608 | return result; 1609 | } 1610 | }); 1611 | 1612 | 1613 | /***/ }), 1614 | /* 56 */ 1615 | /***/ (function(module, exports, __webpack_require__) { 1616 | 1617 | // call something on iterator step with safe closing on error 1618 | var anObject = __webpack_require__(7); 1619 | module.exports = function (iterator, fn, value, entries) { 1620 | try { 1621 | return entries ? fn(anObject(value)[0], value[1]) : fn(value); 1622 | // 7.4.6 IteratorClose(iterator, completion) 1623 | } catch (e) { 1624 | var ret = iterator['return']; 1625 | if (ret !== undefined) anObject(ret.call(iterator)); 1626 | throw e; 1627 | } 1628 | }; 1629 | 1630 | 1631 | /***/ }), 1632 | /* 57 */ 1633 | /***/ (function(module, exports, __webpack_require__) { 1634 | 1635 | // check on default Array iterator 1636 | var Iterators = __webpack_require__(15); 1637 | var ITERATOR = __webpack_require__(1)('iterator'); 1638 | var ArrayProto = Array.prototype; 1639 | 1640 | module.exports = function (it) { 1641 | return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); 1642 | }; 1643 | 1644 | 1645 | /***/ }), 1646 | /* 58 */ 1647 | /***/ (function(module, exports, __webpack_require__) { 1648 | 1649 | "use strict"; 1650 | 1651 | var $defineProperty = __webpack_require__(4); 1652 | var createDesc = __webpack_require__(12); 1653 | 1654 | module.exports = function (object, index, value) { 1655 | if (index in object) $defineProperty.f(object, index, createDesc(0, value)); 1656 | else object[index] = value; 1657 | }; 1658 | 1659 | 1660 | /***/ }), 1661 | /* 59 */ 1662 | /***/ (function(module, exports, __webpack_require__) { 1663 | 1664 | var classof = __webpack_require__(60); 1665 | var ITERATOR = __webpack_require__(1)('iterator'); 1666 | var Iterators = __webpack_require__(15); 1667 | module.exports = __webpack_require__(0).getIteratorMethod = function (it) { 1668 | if (it != undefined) return it[ITERATOR] 1669 | || it['@@iterator'] 1670 | || Iterators[classof(it)]; 1671 | }; 1672 | 1673 | 1674 | /***/ }), 1675 | /* 60 */ 1676 | /***/ (function(module, exports, __webpack_require__) { 1677 | 1678 | // getting tag from 19.1.3.6 Object.prototype.toString() 1679 | var cof = __webpack_require__(24); 1680 | var TAG = __webpack_require__(1)('toStringTag'); 1681 | // ES3 wrong here 1682 | var ARG = cof(function () { return arguments; }()) == 'Arguments'; 1683 | 1684 | // fallback for IE11 Script Access Denied error 1685 | var tryGet = function (it, key) { 1686 | try { 1687 | return it[key]; 1688 | } catch (e) { /* empty */ } 1689 | }; 1690 | 1691 | module.exports = function (it) { 1692 | var O, T, B; 1693 | return it === undefined ? 'Undefined' : it === null ? 'Null' 1694 | // @@toStringTag case 1695 | : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T 1696 | // builtinTag case 1697 | : ARG ? cof(O) 1698 | // ES3 arguments fallback 1699 | : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; 1700 | }; 1701 | 1702 | 1703 | /***/ }), 1704 | /* 61 */ 1705 | /***/ (function(module, exports, __webpack_require__) { 1706 | 1707 | var ITERATOR = __webpack_require__(1)('iterator'); 1708 | var SAFE_CLOSING = false; 1709 | 1710 | try { 1711 | var riter = [7][ITERATOR](); 1712 | riter['return'] = function () { SAFE_CLOSING = true; }; 1713 | // eslint-disable-next-line no-throw-literal 1714 | Array.from(riter, function () { throw 2; }); 1715 | } catch (e) { /* empty */ } 1716 | 1717 | module.exports = function (exec, skipClosing) { 1718 | if (!skipClosing && !SAFE_CLOSING) return false; 1719 | var safe = false; 1720 | try { 1721 | var arr = [7]; 1722 | var iter = arr[ITERATOR](); 1723 | iter.next = function () { return { done: safe = true }; }; 1724 | arr[ITERATOR] = function () { return iter; }; 1725 | exec(arr); 1726 | } catch (e) { /* empty */ } 1727 | return safe; 1728 | }; 1729 | 1730 | 1731 | /***/ }), 1732 | /* 62 */ 1733 | /***/ (function(module, exports, __webpack_require__) { 1734 | 1735 | module.exports = { "default": __webpack_require__(63), __esModule: true }; 1736 | 1737 | /***/ }), 1738 | /* 63 */ 1739 | /***/ (function(module, exports, __webpack_require__) { 1740 | 1741 | __webpack_require__(64); 1742 | module.exports = __webpack_require__(0).Object.keys; 1743 | 1744 | 1745 | /***/ }), 1746 | /* 64 */ 1747 | /***/ (function(module, exports, __webpack_require__) { 1748 | 1749 | // 19.1.2.14 Object.keys(O) 1750 | var toObject = __webpack_require__(10); 1751 | var $keys = __webpack_require__(16); 1752 | 1753 | __webpack_require__(65)('keys', function () { 1754 | return function keys(it) { 1755 | return $keys(toObject(it)); 1756 | }; 1757 | }); 1758 | 1759 | 1760 | /***/ }), 1761 | /* 65 */ 1762 | /***/ (function(module, exports, __webpack_require__) { 1763 | 1764 | // most Object methods by ES6 should accept primitives 1765 | var $export = __webpack_require__(2); 1766 | var core = __webpack_require__(0); 1767 | var fails = __webpack_require__(8); 1768 | module.exports = function (KEY, exec) { 1769 | var fn = (core.Object || {})[KEY] || Object[KEY]; 1770 | var exp = {}; 1771 | exp[KEY] = exec(fn); 1772 | $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp); 1773 | }; 1774 | 1775 | 1776 | /***/ }), 1777 | /* 66 */ 1778 | /***/ (function(module, exports, __webpack_require__) { 1779 | 1780 | "use strict"; 1781 | 1782 | 1783 | exports.__esModule = true; 1784 | 1785 | var _assign = __webpack_require__(67); 1786 | 1787 | var _assign2 = _interopRequireDefault(_assign); 1788 | 1789 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 1790 | 1791 | exports.default = _assign2.default || function (target) { 1792 | for (var i = 1; i < arguments.length; i++) { 1793 | var source = arguments[i]; 1794 | 1795 | for (var key in source) { 1796 | if (Object.prototype.hasOwnProperty.call(source, key)) { 1797 | target[key] = source[key]; 1798 | } 1799 | } 1800 | } 1801 | 1802 | return target; 1803 | }; 1804 | 1805 | /***/ }), 1806 | /* 67 */ 1807 | /***/ (function(module, exports, __webpack_require__) { 1808 | 1809 | module.exports = { "default": __webpack_require__(68), __esModule: true }; 1810 | 1811 | /***/ }), 1812 | /* 68 */ 1813 | /***/ (function(module, exports, __webpack_require__) { 1814 | 1815 | __webpack_require__(69); 1816 | module.exports = __webpack_require__(0).Object.assign; 1817 | 1818 | 1819 | /***/ }), 1820 | /* 69 */ 1821 | /***/ (function(module, exports, __webpack_require__) { 1822 | 1823 | // 19.1.3.1 Object.assign(target, source) 1824 | var $export = __webpack_require__(2); 1825 | 1826 | $export($export.S + $export.F, 'Object', { assign: __webpack_require__(70) }); 1827 | 1828 | 1829 | /***/ }), 1830 | /* 70 */ 1831 | /***/ (function(module, exports, __webpack_require__) { 1832 | 1833 | "use strict"; 1834 | 1835 | // 19.1.2.1 Object.assign(target, source, ...) 1836 | var getKeys = __webpack_require__(16); 1837 | var gOPS = __webpack_require__(71); 1838 | var pIE = __webpack_require__(72); 1839 | var toObject = __webpack_require__(10); 1840 | var IObject = __webpack_require__(23); 1841 | var $assign = Object.assign; 1842 | 1843 | // should work with symbols and should have deterministic property order (V8 bug) 1844 | module.exports = !$assign || __webpack_require__(8)(function () { 1845 | var A = {}; 1846 | var B = {}; 1847 | // eslint-disable-next-line no-undef 1848 | var S = Symbol(); 1849 | var K = 'abcdefghijklmnopqrst'; 1850 | A[S] = 7; 1851 | K.split('').forEach(function (k) { B[k] = k; }); 1852 | return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; 1853 | }) ? function assign(target, source) { // eslint-disable-line no-unused-vars 1854 | var T = toObject(target); 1855 | var aLen = arguments.length; 1856 | var index = 1; 1857 | var getSymbols = gOPS.f; 1858 | var isEnum = pIE.f; 1859 | while (aLen > index) { 1860 | var S = IObject(arguments[index++]); 1861 | var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S); 1862 | var length = keys.length; 1863 | var j = 0; 1864 | var key; 1865 | while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key]; 1866 | } return T; 1867 | } : $assign; 1868 | 1869 | 1870 | /***/ }), 1871 | /* 71 */ 1872 | /***/ (function(module, exports) { 1873 | 1874 | exports.f = Object.getOwnPropertySymbols; 1875 | 1876 | 1877 | /***/ }), 1878 | /* 72 */ 1879 | /***/ (function(module, exports) { 1880 | 1881 | exports.f = {}.propertyIsEnumerable; 1882 | 1883 | 1884 | /***/ }), 1885 | /* 73 */ 1886 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 1887 | 1888 | "use strict"; 1889 | /* unused harmony export parseBoolean */ 1890 | /* unused harmony export parseString */ 1891 | /* unused harmony export parseItems */ 1892 | /* unused harmony export parseArray */ 1893 | /* harmony export (immutable) */ __webpack_exports__["a"] = loadFields; 1894 | 1895 | const { initChild, getChild } = __webpack_require__(30); 1896 | 1897 | const ARRAY_KEYWORDS = ['anyOf', 'oneOf', 'enum']; 1898 | 1899 | function setCommonFields(schema, field, schemaName) { 1900 | // eslint-disable-next-line no-nested-ternary 1901 | field.value = schema.hasOwnProperty('default') ? schema.default : field.hasOwnProperty('value') ? field.value : ''; 1902 | 1903 | field.component = schema.component; 1904 | field.schemaType = schema.type; 1905 | field.label = schema.title || ''; 1906 | field.description = schema.description || ''; 1907 | field.required = schema.required || false; 1908 | field.disabled = schema.disabled || false; 1909 | field.name = schemaName; 1910 | } 1911 | 1912 | function setFormValue(vm, field) { 1913 | const ns = field.name.split('.'); 1914 | const vmValue = getChild(vm.value, ns); 1915 | if (vm.value && !vmValue) { 1916 | const n = ns.pop(); 1917 | const ret = ns.length > 0 ? initChild(vm.value, ns) : vm.value; 1918 | vm.$set(ret, n, field.value); 1919 | } 1920 | } 1921 | 1922 | function parseBoolean(vm, schema, schemaName) { 1923 | const field = schema.attrs || {}; 1924 | 1925 | setCommonFields(schema, field, schemaName); 1926 | 1927 | if (!field.type) { 1928 | field.type = 'checkbox'; 1929 | } 1930 | 1931 | field.checked = schema.checked || false; 1932 | 1933 | if (schema.name) { 1934 | field.name = schemaName; 1935 | 1936 | setFormValue(vm, field); 1937 | } 1938 | 1939 | return field; 1940 | } 1941 | 1942 | function parseString(vm, schema, schemaName) { 1943 | const field = schema.attrs || {}; 1944 | 1945 | if (schema.format) { 1946 | switch (schema.format) { 1947 | case 'email': 1948 | if (!field.type) { 1949 | field.type = 'email'; 1950 | } 1951 | break; 1952 | case 'uri': 1953 | if (!field.type) { 1954 | field.type = 'url'; 1955 | } 1956 | break; 1957 | case 'regex': 1958 | if (!field.type) { 1959 | field.type = 'text'; 1960 | } 1961 | 1962 | field.pattern = schema.pattern; 1963 | break; 1964 | } 1965 | } 1966 | 1967 | if (!field.type) { 1968 | switch (schema.type) { 1969 | case 'number': 1970 | case 'integer': 1971 | field.type = 'number'; 1972 | break; 1973 | default: 1974 | field.type = 'text'; 1975 | } 1976 | } 1977 | 1978 | setCommonFields(schema, field, schemaName); 1979 | 1980 | if (schema.name) { 1981 | field.name = schemaName; 1982 | 1983 | setFormValue(vm, field); 1984 | } 1985 | 1986 | if (schema.minLength) { 1987 | field.minlength = schema.minLength; 1988 | } 1989 | 1990 | if (schema.maxLength) { 1991 | field.maxlength = schema.maxLength; 1992 | } 1993 | 1994 | return field; 1995 | } 1996 | 1997 | function parseItems(items) { 1998 | return items.map(item => { 1999 | if (typeof item !== 'object') { 2000 | return { value: item, label: item }; 2001 | } 2002 | 2003 | return item; 2004 | }); 2005 | } 2006 | 2007 | function parseArray(vm, schema, schemaName) { 2008 | const field = schema.attrs || {}; 2009 | 2010 | setCommonFields(schema, field, schemaName); 2011 | 2012 | field.multiple = schema.minItems > 1; 2013 | field.items = []; 2014 | 2015 | for (const keyword of ARRAY_KEYWORDS) { 2016 | if (schema.hasOwnProperty(keyword)) { 2017 | switch (keyword) { 2018 | case 'enum': 2019 | if (!field.type) { 2020 | field.type = 'select'; 2021 | } 2022 | field.value = field.value || ''; 2023 | field.items = parseItems(schema[keyword]); 2024 | break; 2025 | 2026 | case 'oneOf': 2027 | field.type = 'radio'; 2028 | field.value = field.value || ''; 2029 | field.items = parseItems(schema[keyword]); 2030 | break; 2031 | 2032 | case 'anyOf': 2033 | field.type = 'checkbox'; 2034 | field.value = field.value || []; 2035 | field.items = parseItems(schema[keyword]); 2036 | break; 2037 | } 2038 | } 2039 | } 2040 | if (!field.type) { 2041 | field.type = schema.type; 2042 | field.value = field.value || []; 2043 | field.items = []; 2044 | } 2045 | 2046 | if (schema.name) { 2047 | field.name = schemaName; 2048 | 2049 | setFormValue(vm, field); 2050 | } 2051 | 2052 | return field; 2053 | } 2054 | 2055 | function loadFields(vm, schema, fields = vm.fields, sub) { 2056 | if (!schema || schema.visible === false) return; 2057 | 2058 | const schemaName = sub ? sub.join('.') : schema.name; 2059 | 2060 | switch (schema.type) { 2061 | case 'object': 2062 | for (const key in schema.properties) { 2063 | schema.properties[key].name = key; 2064 | 2065 | if (schema.required) { 2066 | for (const field of schema.required) { 2067 | if (schema.properties[field]) { 2068 | schema.properties[field].required = true; 2069 | } 2070 | } 2071 | } 2072 | if (schema.name && !fields[schemaName]) { 2073 | fields[schemaName] = { 2074 | $sub: true, 2075 | $title: schema.title, 2076 | $description: schema.description, 2077 | }; 2078 | } 2079 | loadFields( 2080 | vm, 2081 | schema.properties[key], 2082 | schema.name ? fields[schemaName] : undefined, 2083 | sub ? [...sub, key] : [key] 2084 | ); 2085 | } 2086 | break; 2087 | 2088 | case 'boolean': 2089 | fields[schemaName] = parseBoolean(vm, schema, schemaName); 2090 | break; 2091 | 2092 | case 'array': 2093 | fields[schemaName] = parseArray(vm, schema, schemaName); 2094 | break; 2095 | 2096 | case 'integer': 2097 | case 'number': 2098 | case 'string': 2099 | for (const keyword of ARRAY_KEYWORDS) { 2100 | if (schema.hasOwnProperty(keyword)) { 2101 | schema.items = { 2102 | type: schema.type, 2103 | enum: schema[keyword], 2104 | }; 2105 | fields[schemaName] = parseArray(vm, schema, schemaName); 2106 | return; 2107 | } 2108 | } 2109 | fields[schemaName] = parseString(vm, schema, schemaName); 2110 | break; 2111 | default: 2112 | fields[schemaName] = parseString(vm, schema, schemaName); 2113 | } 2114 | } 2115 | 2116 | 2117 | /***/ }) 2118 | /******/ ]); 2119 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-json-ui-editor", 3 | "version": "1.0.0", 4 | "description": "Edit JSON in UI form with JSON Schema and Vue.js", 5 | "author": "YourtionGuo ", 6 | "scripts": { 7 | "test": "npm run lint && jest --config test/jest.conf.js --coverage", 8 | "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", 9 | "start": "npm run dev", 10 | "lint": "eslint --ext .js,.vue src test example --fix", 11 | "dist": "npm test && webpack --config build/webpack.dist.conf.js && export TEST_LIB=true && jest --config test/jest.conf.js", 12 | "prepublishOnly": "npm run dist && cat ./coverage/lcov.info | coveralls", 13 | "docs": "vuedoc.md src/JsonEditor.vue", 14 | "build": "node build/build.js" 15 | }, 16 | "main": "lib/json-editor.min.js", 17 | "files": [ 18 | "lib" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/yourtion/vue-json-ui-editor.git" 23 | }, 24 | "keywords": [ 25 | "json", 26 | "schema", 27 | "json-schema", 28 | "vue-editor", 29 | "vue", 30 | "vue-json-schema", 31 | "vue-json-editor", 32 | "json-ui-schema", 33 | "json-editor" 34 | ], 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/yourtion/vue-json-ui-editor/issues" 38 | }, 39 | "homepage": "https://github.com/yourtion/vue-json-ui-editor#readme", 40 | "peerDependencies": { 41 | "vue": "*" 42 | }, 43 | "devDependencies": { 44 | "@vue/server-test-utils": "^1.0.0-beta.26", 45 | "@vue/test-utils": "^1.0.0-beta.18", 46 | "@vuedoc/md": "^1.5.0", 47 | "autoprefixer": "^8.5.2", 48 | "babel-core": "^6.22.1", 49 | "babel-eslint": "^8.2.6", 50 | "babel-helper-vue-jsx-merge-props": "^2.0.3", 51 | "babel-jest": "^23.6.0", 52 | "babel-loader": "^7.1.5", 53 | "babel-plugin-dynamic-import-node": "^1.2.0", 54 | "babel-plugin-syntax-jsx": "^6.18.0", 55 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", 56 | "babel-plugin-transform-runtime": "^6.22.0", 57 | "babel-plugin-transform-vue-jsx": "^3.5.0", 58 | "babel-preset-env": "^1.3.2", 59 | "babel-preset-stage-2": "^6.22.0", 60 | "chalk": "^2.3.2", 61 | "copy-webpack-plugin": "^4.5.2", 62 | "coveralls": "^3.0.2", 63 | "css-loader": "^0.28.0", 64 | "element-ui": "^2.4.11", 65 | "eslint": "^5.9.0", 66 | "eslint-config-guo": "^0.8.0", 67 | "eslint-friendly-formatter": "^4.0.1", 68 | "eslint-loader": "^2.0.0", 69 | "eslint-plugin-html": "^4.0.6", 70 | "eslint-plugin-vue": "^5.0.0", 71 | "extract-text-webpack-plugin": "^3.0.0", 72 | "file-loader": "^3.0.0", 73 | "friendly-errors-webpack-plugin": "^1.6.1", 74 | "html-webpack-plugin": "^3.2.0", 75 | "jest": "^23.6.0", 76 | "jest-serializer-vue": "^2.0.0", 77 | "node-notifier": "^5.1.2", 78 | "optimize-css-assets-webpack-plugin": "^4.0.2", 79 | "ora": "^2.1.0", 80 | "portfinder": "^1.0.13", 81 | "postcss-import": "^11.0.0", 82 | "postcss-loader": "^2.0.8", 83 | "postcss-url": "^7.2.1", 84 | "rimraf": "^2.6.0", 85 | "semver": "^5.3.0", 86 | "shelljs": "^0.7.6", 87 | "uglifyjs-webpack-plugin": "^1.3.0", 88 | "url-loader": "^0.5.8", 89 | "vue": "^2.5.17", 90 | "vue-jest": "^3.0.1", 91 | "vue-loader": "^13.3.0", 92 | "vue-server-renderer": "^2.5.17", 93 | "vue-style-loader": "^3.0.1", 94 | "vue-template-compiler": "^2.5.17", 95 | "webpack": "^4.28.0", 96 | "webpack-bundle-analyzer": "^2.13.1", 97 | "webpack-dev-server": "^2.9.1", 98 | "webpack-merge": "^4.1.4" 99 | }, 100 | "engines": { 101 | "node": ">= 6.0.0", 102 | "npm": ">= 3.0.0" 103 | }, 104 | "browserslist": [ 105 | "> 1%", 106 | "last 2 versions", 107 | "not ie <= 8" 108 | ] 109 | } 110 | -------------------------------------------------------------------------------- /screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/vue-json-ui-editor/a2f46a3524b1c28bd45cb1bb53413f8a8628d557/screenshot.jpg -------------------------------------------------------------------------------- /src/JsonEditor.vue: -------------------------------------------------------------------------------- 1 | 423 | -------------------------------------------------------------------------------- /src/parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const { initChild, getChild } = require('./utils'); 3 | 4 | const ARRAY_KEYWORDS = ['anyOf', 'oneOf', 'enum']; 5 | 6 | function setCommonFields(schema, field, schemaName) { 7 | // eslint-disable-next-line no-nested-ternary 8 | field.value = schema.hasOwnProperty('default') ? schema.default : field.hasOwnProperty('value') ? field.value : ''; 9 | 10 | field.component = schema.component; 11 | field.schemaType = schema.type; 12 | field.label = schema.title || ''; 13 | field.description = schema.description || ''; 14 | field.required = schema.required || false; 15 | field.disabled = schema.disabled || false; 16 | field.name = schemaName; 17 | } 18 | 19 | function setFormValue(vm, field) { 20 | const ns = field.name.split('.'); 21 | const vmValue = getChild(vm.value, ns); 22 | if (vm.value && !vmValue) { 23 | const n = ns.pop(); 24 | const ret = ns.length > 0 ? initChild(vm.value, ns) : vm.value; 25 | vm.$set(ret, n, field.value); 26 | } 27 | } 28 | 29 | export function parseBoolean(vm, schema, schemaName) { 30 | const field = schema.attrs || {}; 31 | 32 | setCommonFields(schema, field, schemaName); 33 | 34 | if (!field.type) { 35 | field.type = 'checkbox'; 36 | } 37 | 38 | field.checked = schema.checked || false; 39 | 40 | if (schema.name) { 41 | field.name = schemaName; 42 | 43 | setFormValue(vm, field); 44 | } 45 | 46 | return field; 47 | } 48 | 49 | export function parseString(vm, schema, schemaName) { 50 | const field = schema.attrs || {}; 51 | 52 | if (schema.format) { 53 | switch (schema.format) { 54 | case 'email': 55 | if (!field.type) { 56 | field.type = 'email'; 57 | } 58 | break; 59 | case 'uri': 60 | if (!field.type) { 61 | field.type = 'url'; 62 | } 63 | break; 64 | case 'regex': 65 | if (!field.type) { 66 | field.type = 'text'; 67 | } 68 | 69 | field.pattern = schema.pattern; 70 | break; 71 | } 72 | } 73 | 74 | if (!field.type) { 75 | switch (schema.type) { 76 | case 'number': 77 | case 'integer': 78 | field.type = 'number'; 79 | break; 80 | default: 81 | field.type = 'text'; 82 | } 83 | } 84 | 85 | setCommonFields(schema, field, schemaName); 86 | 87 | if (schema.name) { 88 | field.name = schemaName; 89 | 90 | setFormValue(vm, field); 91 | } 92 | 93 | if (schema.minLength) { 94 | field.minlength = schema.minLength; 95 | } 96 | 97 | if (schema.maxLength) { 98 | field.maxlength = schema.maxLength; 99 | } 100 | 101 | return field; 102 | } 103 | 104 | export function parseItems(items) { 105 | return items.map(item => { 106 | if (typeof item !== 'object') { 107 | return { value: item, label: item }; 108 | } 109 | 110 | return item; 111 | }); 112 | } 113 | 114 | export function parseArray(vm, schema, schemaName) { 115 | const field = schema.attrs || {}; 116 | 117 | setCommonFields(schema, field, schemaName); 118 | 119 | field.multiple = schema.minItems > 1; 120 | field.items = []; 121 | 122 | for (const keyword of ARRAY_KEYWORDS) { 123 | if (schema.hasOwnProperty(keyword)) { 124 | switch (keyword) { 125 | case 'enum': 126 | if (!field.type) { 127 | field.type = 'select'; 128 | } 129 | field.value = field.value || ''; 130 | field.items = parseItems(schema[keyword]); 131 | break; 132 | 133 | case 'oneOf': 134 | field.type = 'radio'; 135 | field.value = field.value || ''; 136 | field.items = parseItems(schema[keyword]); 137 | break; 138 | 139 | case 'anyOf': 140 | field.type = 'checkbox'; 141 | field.value = field.value || []; 142 | field.items = parseItems(schema[keyword]); 143 | break; 144 | } 145 | } 146 | } 147 | if (!field.type) { 148 | field.type = schema.type; 149 | field.value = field.value || []; 150 | field.items = []; 151 | } 152 | 153 | if (schema.name) { 154 | field.name = schemaName; 155 | 156 | setFormValue(vm, field); 157 | } 158 | 159 | return field; 160 | } 161 | 162 | export function loadFields(vm, schema, fields = vm.fields, sub) { 163 | if (!schema || schema.visible === false) return; 164 | 165 | const schemaName = sub ? sub.join('.') : schema.name; 166 | 167 | switch (schema.type) { 168 | case 'object': 169 | for (const key in schema.properties) { 170 | schema.properties[key].name = key; 171 | 172 | if (schema.required) { 173 | for (const field of schema.required) { 174 | if (schema.properties[field]) { 175 | schema.properties[field].required = true; 176 | } 177 | } 178 | } 179 | if (schema.name && !fields[schemaName]) { 180 | fields[schemaName] = { 181 | $sub: true, 182 | $title: schema.title, 183 | $description: schema.description, 184 | }; 185 | } 186 | loadFields( 187 | vm, 188 | schema.properties[key], 189 | schema.name ? fields[schemaName] : undefined, 190 | sub ? [...sub, key] : [key] 191 | ); 192 | } 193 | break; 194 | 195 | case 'boolean': 196 | fields[schemaName] = parseBoolean(vm, schema, schemaName); 197 | break; 198 | 199 | case 'array': 200 | fields[schemaName] = parseArray(vm, schema, schemaName); 201 | break; 202 | 203 | case 'integer': 204 | case 'number': 205 | case 'string': 206 | for (const keyword of ARRAY_KEYWORDS) { 207 | if (schema.hasOwnProperty(keyword)) { 208 | schema.items = { 209 | type: schema.type, 210 | enum: schema[keyword], 211 | }; 212 | fields[schemaName] = parseArray(vm, schema, schemaName); 213 | return; 214 | } 215 | } 216 | fields[schemaName] = parseString(vm, schema, schemaName); 217 | break; 218 | default: 219 | fields[schemaName] = parseString(vm, schema, schemaName); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | export function deepClone(obj) { 2 | return JSON.parse(JSON.stringify(obj)); 3 | } 4 | 5 | export function getExtendibleLeaf(obj, n, initIt) { 6 | const v = obj[n]; 7 | if (v && typeof v === 'object' && !Array.isArray(v)) { 8 | return v; 9 | } 10 | if (initIt && v === undefined) { 11 | return (obj[n] = {}); 12 | } 13 | } 14 | 15 | export function getChild(data, ns) { 16 | if (ns.length === 1) { 17 | return data[ns[0]]; 18 | } 19 | let obj = data[ns[0]]; 20 | if (obj === undefined) return obj; 21 | let i = 1; 22 | const end = ns.length - 1; 23 | for (; i < end; i++) { 24 | obj = getExtendibleLeaf(obj, ns[i], false); 25 | if (obj === undefined) return obj; 26 | } 27 | return obj[ns[i]]; 28 | } 29 | 30 | export function initChild(data, ns) { 31 | if (ns.length === 1) { 32 | const ret = getExtendibleLeaf(data, ns[0], true); 33 | if (ret === undefined) { 34 | throw new TypeError('fail to init because namespace ' + ns[0] + ' = ' + data[ns[0]]); 35 | } 36 | return ret; 37 | } 38 | let parent = data; 39 | let obj = data[ns[0]]; 40 | if (obj === undefined) obj = data[ns[0]] = {}; 41 | for (let i = 1; i < ns.length; i++) { 42 | const n = ns[i]; 43 | const ret = getExtendibleLeaf(obj, n, true); 44 | if (ret === undefined) { 45 | throw new TypeError('fail to init because namespace ' + ns.join('.') + ' = ' + obj + '(' + typeof obj + ')'); 46 | } 47 | parent = obj; 48 | obj = ret; 49 | if (parent[n] === undefined) { 50 | throw new TypeError('fail to init because namespace ' + ns.slice(0, i).join('.') + ' = ' + parent); 51 | } 52 | } 53 | return obj; 54 | } 55 | 56 | export function setVal(data, n, v) { 57 | const ns = Array.isArray(n) ? n : n.split('.'); 58 | // eslint-disable-next-line 59 | n = ns.pop(); 60 | const ret = ns.length > 0 ? initChild(data, ns) : data; 61 | ret[n] = v; 62 | return v; 63 | } 64 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yourtion/vue-json-ui-editor/a2f46a3524b1c28bd45cb1bb53413f8a8628d557/static/.gitkeep -------------------------------------------------------------------------------- /test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'guo/mocha', 3 | rules: { 4 | 'valid-jsdoc': 'off', 5 | }, 6 | globals: { 7 | expect: false 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /test/__snapshots__/complex.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Component Snapshot 1`] = ` 4 |
5 |

Newsletter Subscription

6 |

Sign up for free newsletters and get more delivered to your inbox

7 |
8 |
9 |
SubTitle
10 |
11 |
Sub2Title
12 |
13 |
20 |
21 |
22 | `; 23 | -------------------------------------------------------------------------------- /test/__snapshots__/schema.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`schema Snapshot 1`] = ` 4 |
5 |
6 |
7 | `; 8 | -------------------------------------------------------------------------------- /test/__snapshots__/simple.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Component Snapshot 1`] = ` 4 |
5 |

Newsletter Subscription

6 |

Sign up for free newsletters and get more delivered to your inbox

7 |
11 |
12 | `; 13 | -------------------------------------------------------------------------------- /test/complex.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { shallowMount } from '@vue/test-utils'; 4 | import { renderToString } from '@vue/server-test-utils'; 5 | 6 | const packPath = process.env.TEST_LIB ? '../lib/json-editor.min.js' : '../src/JsonEditor.vue'; 7 | const pack = require(packPath); 8 | const JsonEditor = pack.default; 9 | 10 | const schema = Object.freeze(require('./data/complex.json')); 11 | 12 | describe('Component', () => { 13 | it('Mount', () => { 14 | const wrapper = shallowMount(JsonEditor, { 15 | propsData: { schema }, 16 | }); 17 | expect(wrapper.isVueInstance()).toBeTruthy(); 18 | }); 19 | 20 | it('Snapshot', () => { 21 | const renderedString = renderToString(JsonEditor, { 22 | propsData: { schema }, 23 | }); 24 | expect(renderedString).toMatchSnapshot(); 25 | }); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /test/component.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const packPath = process.env.TEST_LIB ? '../lib/json-editor.min.js' : '../src/JsonEditor.vue'; 4 | const pack = require(packPath); 5 | const JsonEditor = pack.default; 6 | 7 | describe('JsonEditor', () => { 8 | 9 | describe('hook', () => { 10 | it('should have a created hook', () => { 11 | expect(typeof JsonEditor.created).toBe('function'); 12 | }); 13 | 14 | it('should have a mounted hook', () => { 15 | expect(typeof JsonEditor.mounted).toBe('function'); 16 | }); 17 | }); 18 | 19 | describe('method', () => { 20 | it('should have a changed method', () => { 21 | expect(typeof JsonEditor.methods.changed).toBe('function'); 22 | }); 23 | 24 | it('should have a input method', () => { 25 | expect(typeof JsonEditor.methods.input).toBe('function'); 26 | }); 27 | 28 | it('should have a reset method', () => { 29 | expect(typeof JsonEditor.methods.reset).toBe('function'); 30 | }); 31 | 32 | it('should have a submit method', () => { 33 | expect(typeof JsonEditor.methods.submit).toBe('function'); 34 | }); 35 | 36 | it('should have a setErrorMessage method', () => { 37 | expect(typeof JsonEditor.methods.setErrorMessage).toBe('function'); 38 | }); 39 | 40 | it('should have a clearErrorMessage method', () => { 41 | expect(typeof JsonEditor.methods.clearErrorMessage).toBe('function'); 42 | }); 43 | }); 44 | 45 | describe('data', () => { 46 | // Evaluate the results of functions in 47 | // the raw component options 48 | it('should set the correct default data', () => { 49 | expect(typeof JsonEditor.data).toBe('function'); 50 | const defaultData = JsonEditor.data(); 51 | 52 | expect(Object.keys(defaultData.default).length).toBe(0); 53 | // expect(defaultData.fields.length).toBe(0); 54 | expect(defaultData.error).toBe(null); 55 | }); 56 | }); 57 | 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /test/data/complex.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "type": "object", 4 | "title": "Newsletter Subscription", 5 | "description": "Sign up for free newsletters and get more delivered to your inbox", 6 | "properties": { 7 | "name": { 8 | "type": "string", 9 | "minLength": 8, 10 | "maxLength": 80, 11 | "title": "Full Name", 12 | "attrs": { 13 | "placeholder": "Your Full Name", 14 | "title": "Please enter your full name" 15 | } 16 | }, 17 | "email": { 18 | "maxLength": 120, 19 | "title": "Email", 20 | "format": "email", 21 | "attrs": { 22 | "type": "email", 23 | "placeholder": "Your Email", 24 | "title": "Please enter your email" 25 | } 26 | }, 27 | "sub": { 28 | "title": "SubTitle", 29 | "description": "SubDescription", 30 | "type": "object", 31 | "properties": { 32 | "sName": { 33 | "minLength": 8, 34 | "maxLength": 80, 35 | "title": "SubName", 36 | "attrs": { 37 | "placeholder": "Sub Full Name", 38 | "title": "Please enter your full name" 39 | } 40 | }, 41 | "sUrl": { 42 | "title": "SubUrl", 43 | "format": "uri" 44 | }, 45 | "sub2": { 46 | "type": "object", 47 | "title": "Sub2Title", 48 | "description": "Sub2Description", 49 | "properties": { 50 | "sName2": { 51 | "format": "regex", 52 | "title": "Sub2Name", 53 | "pattern": "*" 54 | }, 55 | "sEmail2": { 56 | "format": "email", 57 | "title": "Sub2Email" 58 | }, 59 | "sAge": { 60 | "type": "integer", 61 | "title": "Sub2Age" 62 | } 63 | }, 64 | "required": [ "sName2" ] 65 | } 66 | }, 67 | "required": ["sEmail"] 68 | }, 69 | "lists": { 70 | "type": "string", 71 | "title": "List", 72 | "enum": ["Daily New", "Promotion"], 73 | "attrs": { 74 | "placeholder": "Select your list subscription", 75 | "title": "Please select your list subscription" 76 | } 77 | }, 78 | "lists2": { 79 | "type": "array", 80 | "title": "List2", 81 | "anyOf": [ 82 | { "value": "daily", "label": "Daily New" }, 83 | { "value": "promotion", "label": "Promotion" } 84 | ], 85 | "attrs": { 86 | "placeholder": "Select your list subscription", 87 | "title": "Please select your list subscription" 88 | } 89 | }, 90 | "lists3": { 91 | "type": "array", 92 | "title": "List3", 93 | "oneOf": [ 94 | { "value": "daily", "label": "Daily New" }, 95 | { "value": "promotion", "label": "Promotion" } 96 | ] 97 | }, 98 | "lists4": { 99 | "type": "array", 100 | "title": "List4" 101 | }, 102 | "source": { 103 | "type": "string", 104 | "maxLength": 120, 105 | "title": "Source", 106 | "description": "Ex. Using the NPM Search Engine", 107 | "attrs": { 108 | "type": "textarea", 109 | "placeholder": "How did you hear about us?" 110 | } 111 | }, 112 | "rate": { 113 | "type": "number", 114 | "title": "Rate", 115 | "default": 2, 116 | "attrs": { 117 | "type": "rate", 118 | "allow-half": true 119 | } 120 | }, 121 | "color": { 122 | "type": "string", 123 | "title": "Color", 124 | "default": "#409EFF", 125 | "attrs": { 126 | "type": "color" 127 | } 128 | }, 129 | "agree": { 130 | "type": "boolean", 131 | "title": "Agree", 132 | "description": "You agree to receive occasional updates and special offers for vue-json-schema updates.", 133 | "default": false, 134 | "attrs": { 135 | "type": "switch" 136 | } 137 | } 138 | }, 139 | "additionalProperties": false, 140 | "required": ["name", "email", "lists"] 141 | } 142 | -------------------------------------------------------------------------------- /test/data/signup.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string", 7 | "minLength": 8, 8 | "maxLength": 80, 9 | "attrs": { 10 | "placeholder": "Your First and Second Name" 11 | } 12 | }, 13 | "email": { 14 | "type": "string", 15 | "minLength": 8, 16 | "maxLength": 120, 17 | "attrs": { 18 | "placeholder": "Enter your email", 19 | "autoComplete": "off" 20 | } 21 | }, 22 | "password": { 23 | "type": "string", 24 | "minLength": 8, 25 | "maxLength": 120, 26 | "attrs": { 27 | "type": "password", 28 | "placeholder": "Enter your password", 29 | "autoComplete": "off" 30 | } 31 | }, 32 | "termsAccepted": { 33 | "type": "boolean", 34 | "title": "I accept the terms of use" 35 | }, 36 | "ip": { "type": "string", "visible": false }, 37 | "date": { "type": "string", "format": "date-time", "default": "now", "visible": false } 38 | }, 39 | "additionalProperties": false, 40 | "required": ["name", "email", "password", "termsAccepted"] 41 | } 42 | -------------------------------------------------------------------------------- /test/data/simple.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "object", 3 | "title": "Newsletter Subscription", 4 | "description": "Sign up for free newsletters and get more delivered to your inbox", 5 | "properties": { 6 | "name": { 7 | "type": "string", 8 | "minLength": 8, 9 | "maxLength": 80, 10 | "title": "Full Name", 11 | "attrs": { 12 | "placeholder": "Your Full Name", 13 | "title": "Please enter your full name" 14 | } 15 | }, 16 | "email": { 17 | "type": "string", 18 | "maxLength": 120, 19 | "title": "Email", 20 | "attrs": { 21 | "type": "email", 22 | "placeholder": "Your Email", 23 | "title": "Please enter your email" 24 | } 25 | }, 26 | "lists": { 27 | "type": "string", 28 | "title": "List", 29 | "enum": ["Daily New", "Promotion"], 30 | "attrs": { 31 | "placeholder": "Select your list subscription", 32 | "title": "Please select your list subscription" 33 | } 34 | } 35 | }, 36 | "required": ["name", "email", "lists"] 37 | } 38 | -------------------------------------------------------------------------------- /test/jest.conf.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | rootDir: path.resolve(__dirname, '../'), 5 | moduleFileExtensions: [ 6 | 'js', 7 | 'json', 8 | 'vue', 9 | ], 10 | moduleNameMapper: { 11 | '^@/(.*)$': '/src/$1', 12 | }, 13 | transform: { 14 | '^.+\\.js$': '/node_modules/babel-jest', 15 | '.*\\.(vue)$': '/node_modules/vue-jest', 16 | }, 17 | snapshotSerializers: [ '/node_modules/jest-serializer-vue' ], 18 | collectCoverageFrom: [ 19 | 'src/**/*.{js,vue}', 20 | '!**/node_modules/**', 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /test/schema.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { shallowMount } from '@vue/test-utils'; 4 | import { renderToString } from '@vue/server-test-utils'; 5 | 6 | const packPath = process.env.TEST_LIB ? '../lib/json-editor.min.js' : '../src/JsonEditor.vue'; 7 | const pack = require(packPath); 8 | const JsonEditor = pack.default; 9 | 10 | const schema = Object.freeze(require('./data/signup.json')); 11 | 12 | describe('schema', () => { 13 | const model = {}; 14 | const wrapper = shallowMount(JsonEditor, { 15 | propsData: { schema, value: model }, 16 | }); 17 | const component = wrapper.vm; 18 | 19 | const form = component.$el.getElementsByTagName('form')[0]; 20 | const inputs = form.elements; 21 | const button = form.getElementsByTagName('button')[0]; 22 | 23 | const attr = (input, name) => input.getAttribute(name); 24 | 25 | describe('input', () => { 26 | for (const fieldName in schema.properties) { 27 | const field = schema.properties[fieldName]; 28 | 29 | if (field.visible === false) { 30 | it(`invisible input.${ fieldName } should be undefined`, () => { 31 | expect(inputs[fieldName]).toBe(undefined); 32 | }); 33 | continue; 34 | } 35 | 36 | const input = inputs[fieldName]; 37 | 38 | if (!field.attrs) { 39 | field.attrs = {}; 40 | } 41 | 42 | field.attrs.name = fieldName; 43 | 44 | if (field.type === 'boolean') { 45 | field.attrs.type = 'checkbox'; 46 | } 47 | 48 | if (field.minLength) { 49 | field.attrs.minlength = field.minLength; 50 | } 51 | 52 | if (field.maxLength) { 53 | field.attrs.maxlength = field.maxLength; 54 | } 55 | 56 | if (field.required) { 57 | field.attrs.required = true; 58 | 59 | if (field.attrs.placeholder) { 60 | field.attrs.placeholder += ' *'; 61 | } 62 | } 63 | 64 | describe(fieldName, () => { 65 | for (const attrName in field.attrs) { 66 | it(`should have attribute '${ attrName }'`, () => { 67 | expect(attr(input, attrName)).toMatch(new RegExp(`${ field.attrs[attrName] }`)); 68 | }); 69 | } 70 | }); 71 | } 72 | }); 73 | 74 | it('should have a submit button', () => { 75 | expect(attr(button, 'type')).toBe('submit'); 76 | }); 77 | 78 | it('should have a button with Submit label', () => { 79 | expect(attr(button, 'label')).toBe('Submit'); 80 | expect(button.innerHTML).toBe('Submit'); 81 | }); 82 | 83 | test('Snapshot', () => { 84 | const renderedString = renderToString(JsonEditor, { 85 | propsData: { schema, value: model }, 86 | }); 87 | expect(renderedString).toMatchSnapshot(); 88 | }); 89 | 90 | }); 91 | -------------------------------------------------------------------------------- /test/simple.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { shallowMount } from '@vue/test-utils'; 4 | import { renderToString } from '@vue/server-test-utils'; 5 | 6 | const packPath = process.env.TEST_LIB ? '../lib/json-editor.min.js' : '../src/JsonEditor.vue'; 7 | const pack = require(packPath); 8 | const JsonEditor = pack.default; 9 | 10 | const schema = Object.freeze(require('./data/simple.json')); 11 | const model = { 12 | name: 'Yourtion', 13 | lists: [ 'Promotion' ], 14 | }; 15 | const model2 = { 16 | name: 'YourtionGuo', 17 | email: 'yourtion@gmail.com', 18 | }; 19 | 20 | describe('Component', () => { 21 | it('Mount', () => { 22 | const wrapper = shallowMount(JsonEditor, { 23 | propsData: { schema }, 24 | }); 25 | expect(wrapper.isVueInstance()).toBeTruthy(); 26 | }); 27 | 28 | it('Snapshot', () => { 29 | const renderedString = renderToString(JsonEditor, { 30 | propsData: { schema }, 31 | }); 32 | expect(renderedString).toMatchSnapshot(); 33 | }); 34 | 35 | describe('Mount with data and set data', () => { 36 | const wrapper = shallowMount(JsonEditor, { 37 | propsData: { schema, value: model }, 38 | }); 39 | const component = wrapper.vm; 40 | expect(wrapper.isVueInstance()).toBeTruthy(); 41 | const form = component.$el.getElementsByTagName('form')[0]; 42 | const { name, lists, email } = form.elements; 43 | 44 | it('get mounted data', () => { 45 | expect(name.getAttribute('value')).toBe(model.name); 46 | expect(lists.getAttribute('value')).toBe(model.lists[0]); 47 | }); 48 | 49 | it('update value by setData', () => { 50 | wrapper.setData({ value: model2 }); 51 | expect(email.getAttribute('value')).toBe(model2.email); 52 | expect(name.getAttribute('value')).toBe(model2.name); 53 | }); 54 | }); 55 | 56 | }); 57 | --------------------------------------------------------------------------------