From 26105034da4fcce7ac883c899d781f016559310d Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 8 Nov 2018 00:38:48 +0800 Subject: switch to vuepress --- node_modules/vue/src/compiler/codegen/events.js | 167 +++++ node_modules/vue/src/compiler/codegen/index.js | 513 ++++++++++++++ node_modules/vue/src/compiler/create-compiler.js | 55 ++ node_modules/vue/src/compiler/directives/bind.js | 11 + node_modules/vue/src/compiler/directives/index.js | 11 + node_modules/vue/src/compiler/directives/model.js | 148 ++++ node_modules/vue/src/compiler/directives/on.js | 10 + node_modules/vue/src/compiler/error-detector.js | 108 +++ node_modules/vue/src/compiler/helpers.js | 164 +++++ node_modules/vue/src/compiler/index.js | 25 + node_modules/vue/src/compiler/optimizer.js | 128 ++++ .../vue/src/compiler/parser/entity-decoder.js | 11 + .../vue/src/compiler/parser/filter-parser.js | 97 +++ .../vue/src/compiler/parser/html-parser.js | 310 ++++++++ node_modules/vue/src/compiler/parser/index.js | 675 ++++++++++++++++++ .../vue/src/compiler/parser/text-parser.js | 53 ++ node_modules/vue/src/compiler/to-function.js | 99 +++ node_modules/vue/src/core/components/index.js | 5 + node_modules/vue/src/core/components/keep-alive.js | 124 ++++ node_modules/vue/src/core/config.js | 121 ++++ node_modules/vue/src/core/global-api/assets.js | 34 + node_modules/vue/src/core/global-api/extend.js | 95 +++ node_modules/vue/src/core/global-api/index.js | 62 ++ node_modules/vue/src/core/global-api/mixin.js | 10 + node_modules/vue/src/core/global-api/use.js | 23 + node_modules/vue/src/core/index.js | 26 + node_modules/vue/src/core/instance/events.js | 142 ++++ node_modules/vue/src/core/instance/index.js | 23 + node_modules/vue/src/core/instance/init.js | 150 ++++ node_modules/vue/src/core/instance/inject.js | 74 ++ node_modules/vue/src/core/instance/lifecycle.js | 336 +++++++++ node_modules/vue/src/core/instance/proxy.js | 79 +++ .../render-helpers/bind-object-listeners.js | 22 + .../instance/render-helpers/bind-object-props.js | 60 ++ .../core/instance/render-helpers/check-keycodes.js | 34 + .../vue/src/core/instance/render-helpers/index.js | 30 + .../core/instance/render-helpers/render-list.js | 39 + .../core/instance/render-helpers/render-slot.js | 50 ++ .../core/instance/render-helpers/render-static.js | 60 ++ .../core/instance/render-helpers/resolve-filter.js | 10 + .../core/instance/render-helpers/resolve-slots.js | 65 ++ node_modules/vue/src/core/instance/render.js | 119 ++++ node_modules/vue/src/core/instance/state.js | 360 ++++++++++ node_modules/vue/src/core/observer/array.js | 45 ++ node_modules/vue/src/core/observer/dep.js | 58 ++ node_modules/vue/src/core/observer/index.js | 273 +++++++ node_modules/vue/src/core/observer/scheduler.js | 148 ++++ node_modules/vue/src/core/observer/traverse.js | 40 ++ node_modules/vue/src/core/observer/watcher.js | 240 +++++++ node_modules/vue/src/core/util/debug.js | 100 +++ node_modules/vue/src/core/util/env.js | 95 +++ node_modules/vue/src/core/util/error.js | 48 ++ node_modules/vue/src/core/util/index.js | 11 + node_modules/vue/src/core/util/lang.js | 39 + node_modules/vue/src/core/util/next-tick.js | 117 +++ node_modules/vue/src/core/util/options.js | 438 ++++++++++++ node_modules/vue/src/core/util/perf.js | 24 + node_modules/vue/src/core/util/props.js | 202 ++++++ node_modules/vue/src/core/vdom/create-component.js | 257 +++++++ node_modules/vue/src/core/vdom/create-element.js | 160 +++++ .../src/core/vdom/create-functional-component.js | 136 ++++ .../vue/src/core/vdom/helpers/extract-props.js | 75 ++ .../core/vdom/helpers/get-first-component-child.js | 15 + node_modules/vue/src/core/vdom/helpers/index.js | 9 + .../src/core/vdom/helpers/is-async-placeholder.js | 5 + .../vue/src/core/vdom/helpers/merge-hook.js | 38 + .../src/core/vdom/helpers/normalize-children.js | 89 +++ .../core/vdom/helpers/resolve-async-component.js | 140 ++++ .../vue/src/core/vdom/helpers/update-listeners.js | 83 +++ .../vue/src/core/vdom/modules/directives.js | 119 ++++ node_modules/vue/src/core/vdom/modules/index.js | 7 + node_modules/vue/src/core/vdom/modules/ref.js | 45 ++ node_modules/vue/src/core/vdom/patch.js | 787 +++++++++++++++++++++ node_modules/vue/src/core/vdom/vnode.js | 108 +++ .../src/platforms/web/compiler/directives/html.js | 9 + .../src/platforms/web/compiler/directives/index.js | 9 + .../src/platforms/web/compiler/directives/model.js | 172 +++++ .../src/platforms/web/compiler/directives/text.js | 9 + .../vue/src/platforms/web/compiler/index.js | 8 + .../src/platforms/web/compiler/modules/class.js | 48 ++ .../src/platforms/web/compiler/modules/index.js | 9 + .../src/platforms/web/compiler/modules/model.js | 94 +++ .../src/platforms/web/compiler/modules/style.js | 51 ++ .../vue/src/platforms/web/compiler/options.js | 26 + .../vue/src/platforms/web/compiler/util.js | 24 + .../vue/src/platforms/web/entry-compiler.js | 5 + .../platforms/web/entry-runtime-with-compiler.js | 100 +++ .../vue/src/platforms/web/entry-runtime.js | 5 + .../platforms/web/entry-server-basic-renderer.js | 13 + .../vue/src/platforms/web/entry-server-renderer.js | 27 + .../vue/src/platforms/web/runtime/class-util.js | 61 ++ .../src/platforms/web/runtime/components/index.js | 7 + .../web/runtime/components/transition-group.js | 180 +++++ .../platforms/web/runtime/components/transition.js | 194 +++++ .../src/platforms/web/runtime/directives/index.js | 7 + .../src/platforms/web/runtime/directives/model.js | 147 ++++ .../src/platforms/web/runtime/directives/show.js | 60 ++ .../vue/src/platforms/web/runtime/index.js | 77 ++ .../vue/src/platforms/web/runtime/modules/attrs.js | 118 +++ .../vue/src/platforms/web/runtime/modules/class.js | 48 ++ .../src/platforms/web/runtime/modules/dom-props.js | 95 +++ .../src/platforms/web/runtime/modules/events.js | 87 +++ .../vue/src/platforms/web/runtime/modules/index.js | 15 + .../vue/src/platforms/web/runtime/modules/style.js | 93 +++ .../platforms/web/runtime/modules/transition.js | 343 +++++++++ .../vue/src/platforms/web/runtime/node-ops.js | 59 ++ .../vue/src/platforms/web/runtime/patch.js | 12 + .../src/platforms/web/runtime/transition-util.js | 185 +++++ .../vue/src/platforms/web/server/compiler.js | 11 + .../src/platforms/web/server/directives/index.js | 7 + .../src/platforms/web/server/directives/model.js | 44 ++ .../src/platforms/web/server/directives/show.js | 12 + .../vue/src/platforms/web/server/modules/attrs.js | 62 ++ .../vue/src/platforms/web/server/modules/class.js | 11 + .../src/platforms/web/server/modules/dom-props.js | 50 ++ .../vue/src/platforms/web/server/modules/index.js | 11 + .../vue/src/platforms/web/server/modules/style.js | 28 + node_modules/vue/src/platforms/web/server/util.js | 56 ++ node_modules/vue/src/platforms/web/util/attrs.js | 43 ++ node_modules/vue/src/platforms/web/util/class.js | 85 +++ node_modules/vue/src/platforms/web/util/compat.js | 16 + node_modules/vue/src/platforms/web/util/element.js | 77 ++ node_modules/vue/src/platforms/web/util/index.js | 25 + node_modules/vue/src/platforms/web/util/style.js | 72 ++ .../platforms/weex/compiler/directives/index.js | 5 + .../platforms/weex/compiler/directives/model.js | 34 + .../vue/src/platforms/weex/compiler/index.js | 52 ++ .../src/platforms/weex/compiler/modules/append.js | 27 + .../src/platforms/weex/compiler/modules/class.js | 73 ++ .../src/platforms/weex/compiler/modules/index.js | 13 + .../src/platforms/weex/compiler/modules/props.js | 32 + .../modules/recycle-list/component-root.js | 16 + .../compiler/modules/recycle-list/component.js | 16 + .../weex/compiler/modules/recycle-list/index.js | 60 ++ .../compiler/modules/recycle-list/recycle-list.js | 50 ++ .../weex/compiler/modules/recycle-list/text.js | 23 + .../weex/compiler/modules/recycle-list/v-bind.js | 21 + .../weex/compiler/modules/recycle-list/v-for.js | 33 + .../weex/compiler/modules/recycle-list/v-if.js | 63 ++ .../weex/compiler/modules/recycle-list/v-on.js | 25 + .../weex/compiler/modules/recycle-list/v-once.js | 19 + .../src/platforms/weex/compiler/modules/style.js | 86 +++ .../vue/src/platforms/weex/entry-compiler.js | 1 + .../vue/src/platforms/weex/entry-framework.js | 187 +++++ .../src/platforms/weex/entry-runtime-factory.js | 6 + .../src/platforms/weex/runtime/components/index.js | 9 + .../platforms/weex/runtime/components/richtext.js | 82 +++ .../weex/runtime/components/transition-group.js | 148 ++++ .../weex/runtime/components/transition.js | 9 + .../src/platforms/weex/runtime/directives/index.js | 2 + .../vue/src/platforms/weex/runtime/index.js | 42 ++ .../src/platforms/weex/runtime/modules/attrs.js | 44 ++ .../src/platforms/weex/runtime/modules/class.js | 75 ++ .../src/platforms/weex/runtime/modules/events.js | 57 ++ .../src/platforms/weex/runtime/modules/index.js | 13 + .../src/platforms/weex/runtime/modules/style.js | 84 +++ .../platforms/weex/runtime/modules/transition.js | 270 +++++++ .../vue/src/platforms/weex/runtime/node-ops.js | 91 +++ .../vue/src/platforms/weex/runtime/patch.js | 16 + .../recycle-list/render-component-template.js | 34 + .../weex/runtime/recycle-list/virtual-component.js | 136 ++++ .../vue/src/platforms/weex/runtime/text-node.js | 9 + .../vue/src/platforms/weex/util/element.js | 52 ++ node_modules/vue/src/platforms/weex/util/index.js | 40 ++ node_modules/vue/src/platforms/weex/util/parser.js | 60 ++ .../bundle-renderer/create-bundle-renderer.js | 151 ++++ .../server/bundle-renderer/create-bundle-runner.js | 150 ++++ .../server/bundle-renderer/source-map-support.js | 45 ++ .../vue/src/server/create-basic-renderer.js | 37 + node_modules/vue/src/server/create-renderer.js | 120 ++++ .../vue/src/server/optimizing-compiler/codegen.js | 260 +++++++ .../vue/src/server/optimizing-compiler/index.js | 20 + .../vue/src/server/optimizing-compiler/modules.js | 126 ++++ .../src/server/optimizing-compiler/optimizer.js | 140 ++++ .../server/optimizing-compiler/runtime-helpers.js | 150 ++++ node_modules/vue/src/server/render-context.js | 130 ++++ node_modules/vue/src/server/render-stream.js | 94 +++ node_modules/vue/src/server/render.js | 396 +++++++++++ .../template-renderer/create-async-file-mapper.js | 53 ++ .../vue/src/server/template-renderer/index.js | 257 +++++++ .../src/server/template-renderer/parse-template.js | 42 ++ .../server/template-renderer/template-stream.js | 82 +++ node_modules/vue/src/server/util.js | 18 + .../vue/src/server/webpack-plugin/client.js | 70 ++ .../vue/src/server/webpack-plugin/server.js | 66 ++ node_modules/vue/src/server/webpack-plugin/util.js | 24 + node_modules/vue/src/server/write.js | 50 ++ node_modules/vue/src/sfc/parser.js | 116 +++ node_modules/vue/src/shared/constants.js | 21 + node_modules/vue/src/shared/util.js | 324 +++++++++ 190 files changed, 16753 insertions(+) create mode 100644 node_modules/vue/src/compiler/codegen/events.js create mode 100644 node_modules/vue/src/compiler/codegen/index.js create mode 100644 node_modules/vue/src/compiler/create-compiler.js create mode 100644 node_modules/vue/src/compiler/directives/bind.js create mode 100644 node_modules/vue/src/compiler/directives/index.js create mode 100644 node_modules/vue/src/compiler/directives/model.js create mode 100644 node_modules/vue/src/compiler/directives/on.js create mode 100644 node_modules/vue/src/compiler/error-detector.js create mode 100644 node_modules/vue/src/compiler/helpers.js create mode 100644 node_modules/vue/src/compiler/index.js create mode 100644 node_modules/vue/src/compiler/optimizer.js create mode 100644 node_modules/vue/src/compiler/parser/entity-decoder.js create mode 100644 node_modules/vue/src/compiler/parser/filter-parser.js create mode 100644 node_modules/vue/src/compiler/parser/html-parser.js create mode 100644 node_modules/vue/src/compiler/parser/index.js create mode 100644 node_modules/vue/src/compiler/parser/text-parser.js create mode 100644 node_modules/vue/src/compiler/to-function.js create mode 100644 node_modules/vue/src/core/components/index.js create mode 100644 node_modules/vue/src/core/components/keep-alive.js create mode 100644 node_modules/vue/src/core/config.js create mode 100644 node_modules/vue/src/core/global-api/assets.js create mode 100644 node_modules/vue/src/core/global-api/extend.js create mode 100644 node_modules/vue/src/core/global-api/index.js create mode 100644 node_modules/vue/src/core/global-api/mixin.js create mode 100644 node_modules/vue/src/core/global-api/use.js create mode 100644 node_modules/vue/src/core/index.js create mode 100644 node_modules/vue/src/core/instance/events.js create mode 100644 node_modules/vue/src/core/instance/index.js create mode 100644 node_modules/vue/src/core/instance/init.js create mode 100644 node_modules/vue/src/core/instance/inject.js create mode 100644 node_modules/vue/src/core/instance/lifecycle.js create mode 100644 node_modules/vue/src/core/instance/proxy.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/bind-object-listeners.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/bind-object-props.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/check-keycodes.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/index.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/render-list.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/render-slot.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/render-static.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/resolve-filter.js create mode 100644 node_modules/vue/src/core/instance/render-helpers/resolve-slots.js create mode 100644 node_modules/vue/src/core/instance/render.js create mode 100644 node_modules/vue/src/core/instance/state.js create mode 100644 node_modules/vue/src/core/observer/array.js create mode 100644 node_modules/vue/src/core/observer/dep.js create mode 100644 node_modules/vue/src/core/observer/index.js create mode 100644 node_modules/vue/src/core/observer/scheduler.js create mode 100644 node_modules/vue/src/core/observer/traverse.js create mode 100644 node_modules/vue/src/core/observer/watcher.js create mode 100644 node_modules/vue/src/core/util/debug.js create mode 100644 node_modules/vue/src/core/util/env.js create mode 100644 node_modules/vue/src/core/util/error.js create mode 100644 node_modules/vue/src/core/util/index.js create mode 100644 node_modules/vue/src/core/util/lang.js create mode 100644 node_modules/vue/src/core/util/next-tick.js create mode 100644 node_modules/vue/src/core/util/options.js create mode 100644 node_modules/vue/src/core/util/perf.js create mode 100644 node_modules/vue/src/core/util/props.js create mode 100644 node_modules/vue/src/core/vdom/create-component.js create mode 100644 node_modules/vue/src/core/vdom/create-element.js create mode 100644 node_modules/vue/src/core/vdom/create-functional-component.js create mode 100644 node_modules/vue/src/core/vdom/helpers/extract-props.js create mode 100644 node_modules/vue/src/core/vdom/helpers/get-first-component-child.js create mode 100644 node_modules/vue/src/core/vdom/helpers/index.js create mode 100644 node_modules/vue/src/core/vdom/helpers/is-async-placeholder.js create mode 100644 node_modules/vue/src/core/vdom/helpers/merge-hook.js create mode 100644 node_modules/vue/src/core/vdom/helpers/normalize-children.js create mode 100644 node_modules/vue/src/core/vdom/helpers/resolve-async-component.js create mode 100644 node_modules/vue/src/core/vdom/helpers/update-listeners.js create mode 100644 node_modules/vue/src/core/vdom/modules/directives.js create mode 100644 node_modules/vue/src/core/vdom/modules/index.js create mode 100644 node_modules/vue/src/core/vdom/modules/ref.js create mode 100644 node_modules/vue/src/core/vdom/patch.js create mode 100644 node_modules/vue/src/core/vdom/vnode.js create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/html.js create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/index.js create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/model.js create mode 100644 node_modules/vue/src/platforms/web/compiler/directives/text.js create mode 100644 node_modules/vue/src/platforms/web/compiler/index.js create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/class.js create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/index.js create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/model.js create mode 100644 node_modules/vue/src/platforms/web/compiler/modules/style.js create mode 100644 node_modules/vue/src/platforms/web/compiler/options.js create mode 100644 node_modules/vue/src/platforms/web/compiler/util.js create mode 100644 node_modules/vue/src/platforms/web/entry-compiler.js create mode 100644 node_modules/vue/src/platforms/web/entry-runtime-with-compiler.js create mode 100644 node_modules/vue/src/platforms/web/entry-runtime.js create mode 100644 node_modules/vue/src/platforms/web/entry-server-basic-renderer.js create mode 100644 node_modules/vue/src/platforms/web/entry-server-renderer.js create mode 100644 node_modules/vue/src/platforms/web/runtime/class-util.js create mode 100644 node_modules/vue/src/platforms/web/runtime/components/index.js create mode 100644 node_modules/vue/src/platforms/web/runtime/components/transition-group.js create mode 100644 node_modules/vue/src/platforms/web/runtime/components/transition.js create mode 100644 node_modules/vue/src/platforms/web/runtime/directives/index.js create mode 100644 node_modules/vue/src/platforms/web/runtime/directives/model.js create mode 100644 node_modules/vue/src/platforms/web/runtime/directives/show.js create mode 100644 node_modules/vue/src/platforms/web/runtime/index.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/attrs.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/class.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/dom-props.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/events.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/index.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/style.js create mode 100644 node_modules/vue/src/platforms/web/runtime/modules/transition.js create mode 100644 node_modules/vue/src/platforms/web/runtime/node-ops.js create mode 100644 node_modules/vue/src/platforms/web/runtime/patch.js create mode 100644 node_modules/vue/src/platforms/web/runtime/transition-util.js create mode 100644 node_modules/vue/src/platforms/web/server/compiler.js create mode 100644 node_modules/vue/src/platforms/web/server/directives/index.js create mode 100644 node_modules/vue/src/platforms/web/server/directives/model.js create mode 100644 node_modules/vue/src/platforms/web/server/directives/show.js create mode 100644 node_modules/vue/src/platforms/web/server/modules/attrs.js create mode 100644 node_modules/vue/src/platforms/web/server/modules/class.js create mode 100644 node_modules/vue/src/platforms/web/server/modules/dom-props.js create mode 100644 node_modules/vue/src/platforms/web/server/modules/index.js create mode 100644 node_modules/vue/src/platforms/web/server/modules/style.js create mode 100644 node_modules/vue/src/platforms/web/server/util.js create mode 100644 node_modules/vue/src/platforms/web/util/attrs.js create mode 100644 node_modules/vue/src/platforms/web/util/class.js create mode 100644 node_modules/vue/src/platforms/web/util/compat.js create mode 100644 node_modules/vue/src/platforms/web/util/element.js create mode 100644 node_modules/vue/src/platforms/web/util/index.js create mode 100644 node_modules/vue/src/platforms/web/util/style.js create mode 100755 node_modules/vue/src/platforms/weex/compiler/directives/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/directives/model.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/append.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/class.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/props.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component-root.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/component.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/index.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/recycle-list.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/text.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-bind.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-for.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-if.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-on.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/recycle-list/v-once.js create mode 100644 node_modules/vue/src/platforms/weex/compiler/modules/style.js create mode 100644 node_modules/vue/src/platforms/weex/entry-compiler.js create mode 100644 node_modules/vue/src/platforms/weex/entry-framework.js create mode 100644 node_modules/vue/src/platforms/weex/entry-runtime-factory.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/index.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/richtext.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/transition-group.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/components/transition.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/directives/index.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/index.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/attrs.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/class.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/events.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/index.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/modules/style.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/modules/transition.js create mode 100755 node_modules/vue/src/platforms/weex/runtime/node-ops.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/patch.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/recycle-list/render-component-template.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/recycle-list/virtual-component.js create mode 100644 node_modules/vue/src/platforms/weex/runtime/text-node.js create mode 100644 node_modules/vue/src/platforms/weex/util/element.js create mode 100755 node_modules/vue/src/platforms/weex/util/index.js create mode 100644 node_modules/vue/src/platforms/weex/util/parser.js create mode 100644 node_modules/vue/src/server/bundle-renderer/create-bundle-renderer.js create mode 100644 node_modules/vue/src/server/bundle-renderer/create-bundle-runner.js create mode 100644 node_modules/vue/src/server/bundle-renderer/source-map-support.js create mode 100644 node_modules/vue/src/server/create-basic-renderer.js create mode 100644 node_modules/vue/src/server/create-renderer.js create mode 100644 node_modules/vue/src/server/optimizing-compiler/codegen.js create mode 100644 node_modules/vue/src/server/optimizing-compiler/index.js create mode 100644 node_modules/vue/src/server/optimizing-compiler/modules.js create mode 100644 node_modules/vue/src/server/optimizing-compiler/optimizer.js create mode 100644 node_modules/vue/src/server/optimizing-compiler/runtime-helpers.js create mode 100644 node_modules/vue/src/server/render-context.js create mode 100644 node_modules/vue/src/server/render-stream.js create mode 100644 node_modules/vue/src/server/render.js create mode 100644 node_modules/vue/src/server/template-renderer/create-async-file-mapper.js create mode 100644 node_modules/vue/src/server/template-renderer/index.js create mode 100644 node_modules/vue/src/server/template-renderer/parse-template.js create mode 100644 node_modules/vue/src/server/template-renderer/template-stream.js create mode 100644 node_modules/vue/src/server/util.js create mode 100644 node_modules/vue/src/server/webpack-plugin/client.js create mode 100644 node_modules/vue/src/server/webpack-plugin/server.js create mode 100644 node_modules/vue/src/server/webpack-plugin/util.js create mode 100644 node_modules/vue/src/server/write.js create mode 100644 node_modules/vue/src/sfc/parser.js create mode 100644 node_modules/vue/src/shared/constants.js create mode 100644 node_modules/vue/src/shared/util.js (limited to 'node_modules/vue/src') diff --git a/node_modules/vue/src/compiler/codegen/events.js b/node_modules/vue/src/compiler/codegen/events.js new file mode 100644 index 00000000..4f922246 --- /dev/null +++ b/node_modules/vue/src/compiler/codegen/events.js @@ -0,0 +1,167 @@ +/* @flow */ + +const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/ +const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/ + +// KeyboardEvent.keyCode aliases +const keyCodes: { [key: string]: number | Array } = { + esc: 27, + tab: 9, + enter: 13, + space: 32, + up: 38, + left: 37, + right: 39, + down: 40, + 'delete': [8, 46] +} + +// KeyboardEvent.key aliases +const keyNames: { [key: string]: string | Array } = { + esc: 'Escape', + tab: 'Tab', + enter: 'Enter', + space: ' ', + // #7806: IE11 uses key names without `Arrow` prefix for arrow keys. + up: ['Up', 'ArrowUp'], + left: ['Left', 'ArrowLeft'], + right: ['Right', 'ArrowRight'], + down: ['Down', 'ArrowDown'], + 'delete': ['Backspace', 'Delete'] +} + +// #4868: modifiers that prevent the execution of the listener +// need to explicitly return null so that we can determine whether to remove +// the listener for .once +const genGuard = condition => `if(${condition})return null;` + +const modifierCode: { [key: string]: string } = { + stop: '$event.stopPropagation();', + prevent: '$event.preventDefault();', + self: genGuard(`$event.target !== $event.currentTarget`), + ctrl: genGuard(`!$event.ctrlKey`), + shift: genGuard(`!$event.shiftKey`), + alt: genGuard(`!$event.altKey`), + meta: genGuard(`!$event.metaKey`), + left: genGuard(`'button' in $event && $event.button !== 0`), + middle: genGuard(`'button' in $event && $event.button !== 1`), + right: genGuard(`'button' in $event && $event.button !== 2`) +} + +export function genHandlers ( + events: ASTElementHandlers, + isNative: boolean, + warn: Function +): string { + let res = isNative ? 'nativeOn:{' : 'on:{' + for (const name in events) { + res += `"${name}":${genHandler(name, events[name])},` + } + return res.slice(0, -1) + '}' +} + +// Generate handler code with binding params on Weex +/* istanbul ignore next */ +function genWeexHandler (params: Array, handlerCode: string) { + let innerHandlerCode = handlerCode + const exps = params.filter(exp => simplePathRE.test(exp) && exp !== '$event') + const bindings = exps.map(exp => ({ '@binding': exp })) + const args = exps.map((exp, i) => { + const key = `$_${i + 1}` + innerHandlerCode = innerHandlerCode.replace(exp, key) + return key + }) + args.push('$event') + return '{\n' + + `handler:function(${args.join(',')}){${innerHandlerCode}},\n` + + `params:${JSON.stringify(bindings)}\n` + + '}' +} + +function genHandler ( + name: string, + handler: ASTElementHandler | Array +): string { + if (!handler) { + return 'function(){}' + } + + if (Array.isArray(handler)) { + return `[${handler.map(handler => genHandler(name, handler)).join(',')}]` + } + + const isMethodPath = simplePathRE.test(handler.value) + const isFunctionExpression = fnExpRE.test(handler.value) + + if (!handler.modifiers) { + if (isMethodPath || isFunctionExpression) { + return handler.value + } + /* istanbul ignore if */ + if (__WEEX__ && handler.params) { + return genWeexHandler(handler.params, handler.value) + } + return `function($event){${handler.value}}` // inline statement + } else { + let code = '' + let genModifierCode = '' + const keys = [] + for (const key in handler.modifiers) { + if (modifierCode[key]) { + genModifierCode += modifierCode[key] + // left/right + if (keyCodes[key]) { + keys.push(key) + } + } else if (key === 'exact') { + const modifiers: ASTModifiers = (handler.modifiers: any) + genModifierCode += genGuard( + ['ctrl', 'shift', 'alt', 'meta'] + .filter(keyModifier => !modifiers[keyModifier]) + .map(keyModifier => `$event.${keyModifier}Key`) + .join('||') + ) + } else { + keys.push(key) + } + } + if (keys.length) { + code += genKeyFilter(keys) + } + // Make sure modifiers like prevent and stop get executed after key filtering + if (genModifierCode) { + code += genModifierCode + } + const handlerCode = isMethodPath + ? `return ${handler.value}($event)` + : isFunctionExpression + ? `return (${handler.value})($event)` + : handler.value + /* istanbul ignore if */ + if (__WEEX__ && handler.params) { + return genWeexHandler(handler.params, code + handlerCode) + } + return `function($event){${code}${handlerCode}}` + } +} + +function genKeyFilter (keys: Array): string { + return `if(!('button' in $event)&&${keys.map(genFilterCode).join('&&')})return null;` +} + +function genFilterCode (key: string): string { + const keyVal = parseInt(key, 10) + if (keyVal) { + return `$event.keyCode!==${keyVal}` + } + const keyCode = keyCodes[key] + const keyName = keyNames[key] + return ( + `_k($event.keyCode,` + + `${JSON.stringify(key)},` + + `${JSON.stringify(keyCode)},` + + `$event.key,` + + `${JSON.stringify(keyName)}` + + `)` + ) +} diff --git a/node_modules/vue/src/compiler/codegen/index.js b/node_modules/vue/src/compiler/codegen/index.js new file mode 100644 index 00000000..1c912c4d --- /dev/null +++ b/node_modules/vue/src/compiler/codegen/index.js @@ -0,0 +1,513 @@ +/* @flow */ + +import { genHandlers } from './events' +import baseDirectives from '../directives/index' +import { camelize, no, extend } from 'shared/util' +import { baseWarn, pluckModuleFunction } from '../helpers' + +type TransformFunction = (el: ASTElement, code: string) => string; +type DataGenFunction = (el: ASTElement) => string; +type DirectiveFunction = (el: ASTElement, dir: ASTDirective, warn: Function) => boolean; + +export class CodegenState { + options: CompilerOptions; + warn: Function; + transforms: Array; + dataGenFns: Array; + directives: { [key: string]: DirectiveFunction }; + maybeComponent: (el: ASTElement) => boolean; + onceId: number; + staticRenderFns: Array; + + constructor (options: CompilerOptions) { + this.options = options + this.warn = options.warn || baseWarn + this.transforms = pluckModuleFunction(options.modules, 'transformCode') + this.dataGenFns = pluckModuleFunction(options.modules, 'genData') + this.directives = extend(extend({}, baseDirectives), options.directives) + const isReservedTag = options.isReservedTag || no + this.maybeComponent = (el: ASTElement) => !isReservedTag(el.tag) + this.onceId = 0 + this.staticRenderFns = [] + } +} + +export type CodegenResult = { + render: string, + staticRenderFns: Array +}; + +export function generate ( + ast: ASTElement | void, + options: CompilerOptions +): CodegenResult { + const state = new CodegenState(options) + const code = ast ? genElement(ast, state) : '_c("div")' + return { + render: `with(this){return ${code}}`, + staticRenderFns: state.staticRenderFns + } +} + +export function genElement (el: ASTElement, state: CodegenState): string { + if (el.staticRoot && !el.staticProcessed) { + return genStatic(el, state) + } else if (el.once && !el.onceProcessed) { + return genOnce(el, state) + } else if (el.for && !el.forProcessed) { + return genFor(el, state) + } else if (el.if && !el.ifProcessed) { + return genIf(el, state) + } else if (el.tag === 'template' && !el.slotTarget) { + return genChildren(el, state) || 'void 0' + } else if (el.tag === 'slot') { + return genSlot(el, state) + } else { + // component or element + let code + if (el.component) { + code = genComponent(el.component, el, state) + } else { + const data = el.plain ? undefined : genData(el, state) + + const children = el.inlineTemplate ? null : genChildren(el, state, true) + code = `_c('${el.tag}'${ + data ? `,${data}` : '' // data + }${ + children ? `,${children}` : '' // children + })` + } + // module transforms + for (let i = 0; i < state.transforms.length; i++) { + code = state.transforms[i](el, code) + } + return code + } +} + +// hoist static sub-trees out +function genStatic (el: ASTElement, state: CodegenState): string { + el.staticProcessed = true + state.staticRenderFns.push(`with(this){return ${genElement(el, state)}}`) + return `_m(${ + state.staticRenderFns.length - 1 + }${ + el.staticInFor ? ',true' : '' + })` +} + +// v-once +function genOnce (el: ASTElement, state: CodegenState): string { + el.onceProcessed = true + if (el.if && !el.ifProcessed) { + return genIf(el, state) + } else if (el.staticInFor) { + let key = '' + let parent = el.parent + while (parent) { + if (parent.for) { + key = parent.key + break + } + parent = parent.parent + } + if (!key) { + process.env.NODE_ENV !== 'production' && state.warn( + `v-once can only be used inside v-for that is keyed. ` + ) + return genElement(el, state) + } + return `_o(${genElement(el, state)},${state.onceId++},${key})` + } else { + return genStatic(el, state) + } +} + +export function genIf ( + el: any, + state: CodegenState, + altGen?: Function, + altEmpty?: string +): string { + el.ifProcessed = true // avoid recursion + return genIfConditions(el.ifConditions.slice(), state, altGen, altEmpty) +} + +function genIfConditions ( + conditions: ASTIfConditions, + state: CodegenState, + altGen?: Function, + altEmpty?: string +): string { + if (!conditions.length) { + return altEmpty || '_e()' + } + + const condition = conditions.shift() + if (condition.exp) { + return `(${condition.exp})?${ + genTernaryExp(condition.block) + }:${ + genIfConditions(conditions, state, altGen, altEmpty) + }` + } else { + return `${genTernaryExp(condition.block)}` + } + + // v-if with v-once should generate code like (a)?_m(0):_m(1) + function genTernaryExp (el) { + return altGen + ? altGen(el, state) + : el.once + ? genOnce(el, state) + : genElement(el, state) + } +} + +export function genFor ( + el: any, + state: CodegenState, + altGen?: Function, + altHelper?: string +): string { + const exp = el.for + const alias = el.alias + const iterator1 = el.iterator1 ? `,${el.iterator1}` : '' + const iterator2 = el.iterator2 ? `,${el.iterator2}` : '' + + if (process.env.NODE_ENV !== 'production' && + state.maybeComponent(el) && + el.tag !== 'slot' && + el.tag !== 'template' && + !el.key + ) { + state.warn( + `<${el.tag} v-for="${alias} in ${exp}">: component lists rendered with ` + + `v-for should have explicit keys. ` + + `See https://vuejs.org/guide/list.html#key for more info.`, + true /* tip */ + ) + } + + el.forProcessed = true // avoid recursion + return `${altHelper || '_l'}((${exp}),` + + `function(${alias}${iterator1}${iterator2}){` + + `return ${(altGen || genElement)(el, state)}` + + '})' +} + +export function genData (el: ASTElement, state: CodegenState): string { + let data = '{' + + // directives first. + // directives may mutate the el's other properties before they are generated. + const dirs = genDirectives(el, state) + if (dirs) data += dirs + ',' + + // key + if (el.key) { + data += `key:${el.key},` + } + // ref + if (el.ref) { + data += `ref:${el.ref},` + } + if (el.refInFor) { + data += `refInFor:true,` + } + // pre + if (el.pre) { + data += `pre:true,` + } + // record original tag name for components using "is" attribute + if (el.component) { + data += `tag:"${el.tag}",` + } + // module data generation functions + for (let i = 0; i < state.dataGenFns.length; i++) { + data += state.dataGenFns[i](el) + } + // attributes + if (el.attrs) { + data += `attrs:{${genProps(el.attrs)}},` + } + // DOM props + if (el.props) { + data += `domProps:{${genProps(el.props)}},` + } + // event handlers + if (el.events) { + data += `${genHandlers(el.events, false, state.warn)},` + } + if (el.nativeEvents) { + data += `${genHandlers(el.nativeEvents, true, state.warn)},` + } + // slot target + // only for non-scoped slots + if (el.slotTarget && !el.slotScope) { + data += `slot:${el.slotTarget},` + } + // scoped slots + if (el.scopedSlots) { + data += `${genScopedSlots(el.scopedSlots, state)},` + } + // component v-model + if (el.model) { + data += `model:{value:${ + el.model.value + },callback:${ + el.model.callback + },expression:${ + el.model.expression + }},` + } + // inline-template + if (el.inlineTemplate) { + const inlineTemplate = genInlineTemplate(el, state) + if (inlineTemplate) { + data += `${inlineTemplate},` + } + } + data = data.replace(/,$/, '') + '}' + // v-bind data wrap + if (el.wrapData) { + data = el.wrapData(data) + } + // v-on data wrap + if (el.wrapListeners) { + data = el.wrapListeners(data) + } + return data +} + +function genDirectives (el: ASTElement, state: CodegenState): string | void { + const dirs = el.directives + if (!dirs) return + let res = 'directives:[' + let hasRuntime = false + let i, l, dir, needRuntime + for (i = 0, l = dirs.length; i < l; i++) { + dir = dirs[i] + needRuntime = true + const gen: DirectiveFunction = state.directives[dir.name] + if (gen) { + // compile-time directive that manipulates AST. + // returns true if it also needs a runtime counterpart. + needRuntime = !!gen(el, dir, state.warn) + } + if (needRuntime) { + hasRuntime = true + res += `{name:"${dir.name}",rawName:"${dir.rawName}"${ + dir.value ? `,value:(${dir.value}),expression:${JSON.stringify(dir.value)}` : '' + }${ + dir.arg ? `,arg:"${dir.arg}"` : '' + }${ + dir.modifiers ? `,modifiers:${JSON.stringify(dir.modifiers)}` : '' + }},` + } + } + if (hasRuntime) { + return res.slice(0, -1) + ']' + } +} + +function genInlineTemplate (el: ASTElement, state: CodegenState): ?string { + const ast = el.children[0] + if (process.env.NODE_ENV !== 'production' && ( + el.children.length !== 1 || ast.type !== 1 + )) { + state.warn('Inline-template components must have exactly one child element.') + } + if (ast.type === 1) { + const inlineRenderFns = generate(ast, state.options) + return `inlineTemplate:{render:function(){${ + inlineRenderFns.render + }},staticRenderFns:[${ + inlineRenderFns.staticRenderFns.map(code => `function(){${code}}`).join(',') + }]}` + } +} + +function genScopedSlots ( + slots: { [key: string]: ASTElement }, + state: CodegenState +): string { + return `scopedSlots:_u([${ + Object.keys(slots).map(key => { + return genScopedSlot(key, slots[key], state) + }).join(',') + }])` +} + +function genScopedSlot ( + key: string, + el: ASTElement, + state: CodegenState +): string { + if (el.for && !el.forProcessed) { + return genForScopedSlot(key, el, state) + } + const fn = `function(${String(el.slotScope)}){` + + `return ${el.tag === 'template' + ? el.if + ? `${el.if}?${genChildren(el, state) || 'undefined'}:undefined` + : genChildren(el, state) || 'undefined' + : genElement(el, state) + }}` + return `{key:${key},fn:${fn}}` +} + +function genForScopedSlot ( + key: string, + el: any, + state: CodegenState +): string { + const exp = el.for + const alias = el.alias + const iterator1 = el.iterator1 ? `,${el.iterator1}` : '' + const iterator2 = el.iterator2 ? `,${el.iterator2}` : '' + el.forProcessed = true // avoid recursion + return `_l((${exp}),` + + `function(${alias}${iterator1}${iterator2}){` + + `return ${genScopedSlot(key, el, state)}` + + '})' +} + +export function genChildren ( + el: ASTElement, + state: CodegenState, + checkSkip?: boolean, + altGenElement?: Function, + altGenNode?: Function +): string | void { + const children = el.children + if (children.length) { + const el: any = children[0] + // optimize single v-for + if (children.length === 1 && + el.for && + el.tag !== 'template' && + el.tag !== 'slot' + ) { + return (altGenElement || genElement)(el, state) + } + const normalizationType = checkSkip + ? getNormalizationType(children, state.maybeComponent) + : 0 + const gen = altGenNode || genNode + return `[${children.map(c => gen(c, state)).join(',')}]${ + normalizationType ? `,${normalizationType}` : '' + }` + } +} + +// determine the normalization needed for the children array. +// 0: no normalization needed +// 1: simple normalization needed (possible 1-level deep nested array) +// 2: full normalization needed +function getNormalizationType ( + children: Array, + maybeComponent: (el: ASTElement) => boolean +): number { + let res = 0 + for (let i = 0; i < children.length; i++) { + const el: ASTNode = children[i] + if (el.type !== 1) { + continue + } + if (needsNormalization(el) || + (el.ifConditions && el.ifConditions.some(c => needsNormalization(c.block)))) { + res = 2 + break + } + if (maybeComponent(el) || + (el.ifConditions && el.ifConditions.some(c => maybeComponent(c.block)))) { + res = 1 + } + } + return res +} + +function needsNormalization (el: ASTElement): boolean { + return el.for !== undefined || el.tag === 'template' || el.tag === 'slot' +} + +function genNode (node: ASTNode, state: CodegenState): string { + if (node.type === 1) { + return genElement(node, state) + } if (node.type === 3 && node.isComment) { + return genComment(node) + } else { + return genText(node) + } +} + +export function genText (text: ASTText | ASTExpression): string { + return `_v(${text.type === 2 + ? text.expression // no need for () because already wrapped in _s() + : transformSpecialNewlines(JSON.stringify(text.text)) + })` +} + +export function genComment (comment: ASTText): string { + return `_e(${JSON.stringify(comment.text)})` +} + +function genSlot (el: ASTElement, state: CodegenState): string { + const slotName = el.slotName || '"default"' + const children = genChildren(el, state) + let res = `_t(${slotName}${children ? `,${children}` : ''}` + const attrs = el.attrs && `{${el.attrs.map(a => `${camelize(a.name)}:${a.value}`).join(',')}}` + const bind = el.attrsMap['v-bind'] + if ((attrs || bind) && !children) { + res += `,null` + } + if (attrs) { + res += `,${attrs}` + } + if (bind) { + res += `${attrs ? '' : ',null'},${bind}` + } + return res + ')' +} + +// componentName is el.component, take it as argument to shun flow's pessimistic refinement +function genComponent ( + componentName: string, + el: ASTElement, + state: CodegenState +): string { + const children = el.inlineTemplate ? null : genChildren(el, state, true) + return `_c(${componentName},${genData(el, state)}${ + children ? `,${children}` : '' + })` +} + +function genProps (props: Array<{ name: string, value: any }>): string { + let res = '' + for (let i = 0; i < props.length; i++) { + const prop = props[i] + /* istanbul ignore if */ + if (__WEEX__) { + res += `"${prop.name}":${generateValue(prop.value)},` + } else { + res += `"${prop.name}":${transformSpecialNewlines(prop.value)},` + } + } + return res.slice(0, -1) +} + +/* istanbul ignore next */ +function generateValue (value) { + if (typeof value === 'string') { + return transformSpecialNewlines(value) + } + return JSON.stringify(value) +} + +// #3895, #4268 +function transformSpecialNewlines (text: string): string { + return text + .replace(/\u2028/g, '\\u2028') + .replace(/\u2029/g, '\\u2029') +} diff --git a/node_modules/vue/src/compiler/create-compiler.js b/node_modules/vue/src/compiler/create-compiler.js new file mode 100644 index 00000000..6671dcfe --- /dev/null +++ b/node_modules/vue/src/compiler/create-compiler.js @@ -0,0 +1,55 @@ +/* @flow */ + +import { extend } from 'shared/util' +import { detectErrors } from './error-detector' +import { createCompileToFunctionFn } from './to-function' + +export function createCompilerCreator (baseCompile: Function): Function { + return function createCompiler (baseOptions: CompilerOptions) { + function compile ( + template: string, + options?: CompilerOptions + ): CompiledResult { + const finalOptions = Object.create(baseOptions) + const errors = [] + const tips = [] + finalOptions.warn = (msg, tip) => { + (tip ? tips : errors).push(msg) + } + + if (options) { + // merge custom modules + if (options.modules) { + finalOptions.modules = + (baseOptions.modules || []).concat(options.modules) + } + // merge custom directives + if (options.directives) { + finalOptions.directives = extend( + Object.create(baseOptions.directives || null), + options.directives + ) + } + // copy other options + for (const key in options) { + if (key !== 'modules' && key !== 'directives') { + finalOptions[key] = options[key] + } + } + } + + const compiled = baseCompile(template, finalOptions) + if (process.env.NODE_ENV !== 'production') { + errors.push.apply(errors, detectErrors(compiled.ast)) + } + compiled.errors = errors + compiled.tips = tips + return compiled + } + + return { + compile, + compileToFunctions: createCompileToFunctionFn(compile) + } + } +} diff --git a/node_modules/vue/src/compiler/directives/bind.js b/node_modules/vue/src/compiler/directives/bind.js new file mode 100644 index 00000000..e1035727 --- /dev/null +++ b/node_modules/vue/src/compiler/directives/bind.js @@ -0,0 +1,11 @@ +/* @flow */ + +export default function bind (el: ASTElement, dir: ASTDirective) { + el.wrapData = (code: string) => { + return `_b(${code},'${el.tag}',${dir.value},${ + dir.modifiers && dir.modifiers.prop ? 'true' : 'false' + }${ + dir.modifiers && dir.modifiers.sync ? ',true' : '' + })` + } +} diff --git a/node_modules/vue/src/compiler/directives/index.js b/node_modules/vue/src/compiler/directives/index.js new file mode 100644 index 00000000..8f4342c0 --- /dev/null +++ b/node_modules/vue/src/compiler/directives/index.js @@ -0,0 +1,11 @@ +/* @flow */ + +import on from './on' +import bind from './bind' +import { noop } from 'shared/util' + +export default { + on, + bind, + cloak: noop +} diff --git a/node_modules/vue/src/compiler/directives/model.js b/node_modules/vue/src/compiler/directives/model.js new file mode 100644 index 00000000..39bdbfda --- /dev/null +++ b/node_modules/vue/src/compiler/directives/model.js @@ -0,0 +1,148 @@ +/* @flow */ + +/** + * Cross-platform code generation for component v-model + */ +export function genComponentModel ( + el: ASTElement, + value: string, + modifiers: ?ASTModifiers +): ?boolean { + const { number, trim } = modifiers || {} + + const baseValueExpression = '$$v' + let valueExpression = baseValueExpression + if (trim) { + valueExpression = + `(typeof ${baseValueExpression} === 'string'` + + `? ${baseValueExpression}.trim()` + + `: ${baseValueExpression})` + } + if (number) { + valueExpression = `_n(${valueExpression})` + } + const assignment = genAssignmentCode(value, valueExpression) + + el.model = { + value: `(${value})`, + expression: `"${value}"`, + callback: `function (${baseValueExpression}) {${assignment}}` + } +} + +/** + * Cross-platform codegen helper for generating v-model value assignment code. + */ +export function genAssignmentCode ( + value: string, + assignment: string +): string { + const res = parseModel(value) + if (res.key === null) { + return `${value}=${assignment}` + } else { + return `$set(${res.exp}, ${res.key}, ${assignment})` + } +} + +/** + * Parse a v-model expression into a base path and a final key segment. + * Handles both dot-path and possible square brackets. + * + * Possible cases: + * + * - test + * - test[key] + * - test[test1[key]] + * - test["a"][key] + * - xxx.test[a[a].test1[key]] + * - test.xxx.a["asa"][test1[key]] + * + */ + +let len, str, chr, index, expressionPos, expressionEndPos + +type ModelParseResult = { + exp: string, + key: string | null +} + +export function parseModel (val: string): ModelParseResult { + // Fix https://github.com/vuejs/vue/pull/7730 + // allow v-model="obj.val " (trailing whitespace) + val = val.trim() + len = val.length + + if (val.indexOf('[') < 0 || val.lastIndexOf(']') < len - 1) { + index = val.lastIndexOf('.') + if (index > -1) { + return { + exp: val.slice(0, index), + key: '"' + val.slice(index + 1) + '"' + } + } else { + return { + exp: val, + key: null + } + } + } + + str = val + index = expressionPos = expressionEndPos = 0 + + while (!eof()) { + chr = next() + /* istanbul ignore if */ + if (isStringStart(chr)) { + parseString(chr) + } else if (chr === 0x5B) { + parseBracket(chr) + } + } + + return { + exp: val.slice(0, expressionPos), + key: val.slice(expressionPos + 1, expressionEndPos) + } +} + +function next (): number { + return str.charCodeAt(++index) +} + +function eof (): boolean { + return index >= len +} + +function isStringStart (chr: number): boolean { + return chr === 0x22 || chr === 0x27 +} + +function parseBracket (chr: number): void { + let inBracket = 1 + expressionPos = index + while (!eof()) { + chr = next() + if (isStringStart(chr)) { + parseString(chr) + continue + } + if (chr === 0x5B) inBracket++ + if (chr === 0x5D) inBracket-- + if (inBracket === 0) { + expressionEndPos = index + break + } + } +} + +function parseString (chr: number): void { + const stringQuote = chr + while (!eof()) { + chr = next() + if (chr === stringQuote) { + break + } + } +} diff --git a/node_modules/vue/src/compiler/directives/on.js b/node_modules/vue/src/compiler/directives/on.js new file mode 100644 index 00000000..893a678e --- /dev/null +++ b/node_modules/vue/src/compiler/directives/on.js @@ -0,0 +1,10 @@ +/* @flow */ + +import { warn } from 'core/util/index' + +export default function on (el: ASTElement, dir: ASTDirective) { + if (process.env.NODE_ENV !== 'production' && dir.modifiers) { + warn(`v-on without argument does not support modifiers.`) + } + el.wrapListeners = (code: string) => `_g(${code},${dir.value})` +} diff --git a/node_modules/vue/src/compiler/error-detector.js b/node_modules/vue/src/compiler/error-detector.js new file mode 100644 index 00000000..e729c499 --- /dev/null +++ b/node_modules/vue/src/compiler/error-detector.js @@ -0,0 +1,108 @@ +/* @flow */ + +import { dirRE, onRE } from './parser/index' + +// these keywords should not appear inside expressions, but operators like +// typeof, instanceof and in are allowed +const prohibitedKeywordRE = new RegExp('\\b' + ( + 'do,if,for,let,new,try,var,case,else,with,await,break,catch,class,const,' + + 'super,throw,while,yield,delete,export,import,return,switch,default,' + + 'extends,finally,continue,debugger,function,arguments' +).split(',').join('\\b|\\b') + '\\b') + +// these unary operators should not be used as property/method names +const unaryOperatorsRE = new RegExp('\\b' + ( + 'delete,typeof,void' +).split(',').join('\\s*\\([^\\)]*\\)|\\b') + '\\s*\\([^\\)]*\\)') + +// strip strings in expressions +const stripStringRE = /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`/g + +// detect problematic expressions in a template +export function detectErrors (ast: ?ASTNode): Array { + const errors: Array = [] + if (ast) { + checkNode(ast, errors) + } + return errors +} + +function checkNode (node: ASTNode, errors: Array) { + if (node.type === 1) { + for (const name in node.attrsMap) { + if (dirRE.test(name)) { + const value = node.attrsMap[name] + if (value) { + if (name === 'v-for') { + checkFor(node, `v-for="${value}"`, errors) + } else if (onRE.test(name)) { + checkEvent(value, `${name}="${value}"`, errors) + } else { + checkExpression(value, `${name}="${value}"`, errors) + } + } + } + } + if (node.children) { + for (let i = 0; i < node.children.length; i++) { + checkNode(node.children[i], errors) + } + } + } else if (node.type === 2) { + checkExpression(node.expression, node.text, errors) + } +} + +function checkEvent (exp: string, text: string, errors: Array) { + const stipped = exp.replace(stripStringRE, '') + const keywordMatch: any = stipped.match(unaryOperatorsRE) + if (keywordMatch && stipped.charAt(keywordMatch.index - 1) !== '$') { + errors.push( + `avoid using JavaScript unary operator as property name: ` + + `"${keywordMatch[0]}" in expression ${text.trim()}` + ) + } + checkExpression(exp, text, errors) +} + +function checkFor (node: ASTElement, text: string, errors: Array) { + checkExpression(node.for || '', text, errors) + checkIdentifier(node.alias, 'v-for alias', text, errors) + checkIdentifier(node.iterator1, 'v-for iterator', text, errors) + checkIdentifier(node.iterator2, 'v-for iterator', text, errors) +} + +function checkIdentifier ( + ident: ?string, + type: string, + text: string, + errors: Array +) { + if (typeof ident === 'string') { + try { + new Function(`var ${ident}=_`) + } catch (e) { + errors.push(`invalid ${type} "${ident}" in expression: ${text.trim()}`) + } + } +} + +function checkExpression (exp: string, text: string, errors: Array) { + try { + new Function(`return ${exp}`) + } catch (e) { + const keywordMatch = exp.replace(stripStringRE, '').match(prohibitedKeywordRE) + if (keywordMatch) { + errors.push( + `avoid using JavaScript keyword as property name: ` + + `"${keywordMatch[0]}"\n Raw expression: ${text.trim()}` + ) + } else { + errors.push( + `invalid expression: ${e.message} in\n\n` + + ` ${exp}\n\n` + + ` Raw expression: ${text.trim()}\n` + ) + } + } +} diff --git a/node_modules/vue/src/compiler/helpers.js b/node_modules/vue/src/compiler/helpers.js new file mode 100644 index 00000000..6a7375a3 --- /dev/null +++ b/node_modules/vue/src/compiler/helpers.js @@ -0,0 +1,164 @@ +/* @flow */ + +import { emptyObject } from 'shared/util' +import { parseFilters } from './parser/filter-parser' + +export function baseWarn (msg: string) { + console.error(`[Vue compiler]: ${msg}`) +} + +export function pluckModuleFunction ( + modules: ?Array, + key: string +): Array { + return modules + ? modules.map(m => m[key]).filter(_ => _) + : [] +} + +export function addProp (el: ASTElement, name: string, value: string) { + (el.props || (el.props = [])).push({ name, value }) + el.plain = false +} + +export function addAttr (el: ASTElement, name: string, value: any) { + (el.attrs || (el.attrs = [])).push({ name, value }) + el.plain = false +} + +// add a raw attr (use this in preTransforms) +export function addRawAttr (el: ASTElement, name: string, value: any) { + el.attrsMap[name] = value + el.attrsList.push({ name, value }) +} + +export function addDirective ( + el: ASTElement, + name: string, + rawName: string, + value: string, + arg: ?string, + modifiers: ?ASTModifiers +) { + (el.directives || (el.directives = [])).push({ name, rawName, value, arg, modifiers }) + el.plain = false +} + +export function addHandler ( + el: ASTElement, + name: string, + value: string, + modifiers: ?ASTModifiers, + important?: boolean, + warn?: Function +) { + modifiers = modifiers || emptyObject + // warn prevent and passive modifier + /* istanbul ignore if */ + if ( + process.env.NODE_ENV !== 'production' && warn && + modifiers.prevent && modifiers.passive + ) { + warn( + 'passive and prevent can\'t be used together. ' + + 'Passive handler can\'t prevent default event.' + ) + } + + // check capture modifier + if (modifiers.capture) { + delete modifiers.capture + name = '!' + name // mark the event as captured + } + if (modifiers.once) { + delete modifiers.once + name = '~' + name // mark the event as once + } + /* istanbul ignore if */ + if (modifiers.passive) { + delete modifiers.passive + name = '&' + name // mark the event as passive + } + + // normalize click.right and click.middle since they don't actually fire + // this is technically browser-specific, but at least for now browsers are + // the only target envs that have right/middle clicks. + if (name === 'click') { + if (modifiers.right) { + name = 'contextmenu' + delete modifiers.right + } else if (modifiers.middle) { + name = 'mouseup' + } + } + + let events + if (modifiers.native) { + delete modifiers.native + events = el.nativeEvents || (el.nativeEvents = {}) + } else { + events = el.events || (el.events = {}) + } + + const newHandler: any = { + value: value.trim() + } + if (modifiers !== emptyObject) { + newHandler.modifiers = modifiers + } + + const handlers = events[name] + /* istanbul ignore if */ + if (Array.isArray(handlers)) { + important ? handlers.unshift(newHandler) : handlers.push(newHandler) + } else if (handlers) { + events[name] = important ? [newHandler, handlers] : [handlers, newHandler] + } else { + events[name] = newHandler + } + + el.plain = false +} + +export function getBindingAttr ( + el: ASTElement, + name: string, + getStatic?: boolean +): ?string { + const dynamicValue = + getAndRemoveAttr(el, ':' + name) || + getAndRemoveAttr(el, 'v-bind:' + name) + if (dynamicValue != null) { + return parseFilters(dynamicValue) + } else if (getStatic !== false) { + const staticValue = getAndRemoveAttr(el, name) + if (staticValue != null) { + return JSON.stringify(staticValue) + } + } +} + +// note: this only removes the attr from the Array (attrsList) so that it +// doesn't get processed by processAttrs. +// By default it does NOT remove it from the map (attrsMap) because the map is +// needed during codegen. +export function getAndRemoveAttr ( + el: ASTElement, + name: string, + removeFromMap?: boolean +): ?string { + let val + if ((val = el.attrsMap[name]) != null) { + const list = el.attrsList + for (let i = 0, l = list.length; i < l; i++) { + if (list[i].name === name) { + list.splice(i, 1) + break + } + } + } + if (removeFromMap) { + delete el.attrsMap[name] + } + return val +} diff --git a/node_modules/vue/src/compiler/index.js b/node_modules/vue/src/compiler/index.js new file mode 100644 index 00000000..56b54fd3 --- /dev/null +++ b/node_modules/vue/src/compiler/index.js @@ -0,0 +1,25 @@ +/* @flow */ + +import { parse } from './parser/index' +import { optimize } from './optimizer' +import { generate } from './codegen/index' +import { createCompilerCreator } from './create-compiler' + +// `createCompilerCreator` allows creating compilers that use alternative +// parser/optimizer/codegen, e.g the SSR optimizing compiler. +// Here we just export a default compiler using the default parts. +export const createCompiler = createCompilerCreator(function baseCompile ( + template: string, + options: CompilerOptions +): CompiledResult { + const ast = parse(template.trim(), options) + if (options.optimize !== false) { + optimize(ast, options) + } + const code = generate(ast, options) + return { + ast, + render: code.render, + staticRenderFns: code.staticRenderFns + } +}) diff --git a/node_modules/vue/src/compiler/optimizer.js b/node_modules/vue/src/compiler/optimizer.js new file mode 100644 index 00000000..ce432035 --- /dev/null +++ b/node_modules/vue/src/compiler/optimizer.js @@ -0,0 +1,128 @@ +/* @flow */ + +import { makeMap, isBuiltInTag, cached, no } from 'shared/util' + +let isStaticKey +let isPlatformReservedTag + +const genStaticKeysCached = cached(genStaticKeys) + +/** + * Goal of the optimizer: walk the generated template AST tree + * and detect sub-trees that are purely static, i.e. parts of + * the DOM that never needs to change. + * + * Once we detect these sub-trees, we can: + * + * 1. Hoist them into constants, so that we no longer need to + * create fresh nodes for them on each re-render; + * 2. Completely skip them in the patching process. + */ +export function optimize (root: ?ASTElement, options: CompilerOptions) { + if (!root) return + isStaticKey = genStaticKeysCached(options.staticKeys || '') + isPlatformReservedTag = options.isReservedTag || no + // first pass: mark all non-static nodes. + markStatic(root) + // second pass: mark static roots. + markStaticRoots(root, false) +} + +function genStaticKeys (keys: string): Function { + return makeMap( + 'type,tag,attrsList,attrsMap,plain,parent,children,attrs' + + (keys ? ',' + keys : '') + ) +} + +function markStatic (node: ASTNode) { + node.static = isStatic(node) + if (node.type === 1) { + // do not make component slot content static. this avoids + // 1. components not able to mutate slot nodes + // 2. static slot content fails for hot-reloading + if ( + !isPlatformReservedTag(node.tag) && + node.tag !== 'slot' && + node.attrsMap['inline-template'] == null + ) { + return + } + for (let i = 0, l = node.children.length; i < l; i++) { + const child = node.children[i] + markStatic(child) + if (!child.static) { + node.static = false + } + } + if (node.ifConditions) { + for (let i = 1, l = node.ifConditions.length; i < l; i++) { + const block = node.ifConditions[i].block + markStatic(block) + if (!block.static) { + node.static = false + } + } + } + } +} + +function markStaticRoots (node: ASTNode, isInFor: boolean) { + if (node.type === 1) { + if (node.static || node.once) { + node.staticInFor = isInFor + } + // For a node to qualify as a static root, it should have children that + // are not just static text. Otherwise the cost of hoisting out will + // outweigh the benefits and it's better off to just always render it fresh. + if (node.static && node.children.length && !( + node.children.length === 1 && + node.children[0].type === 3 + )) { + node.staticRoot = true + return + } else { + node.staticRoot = false + } + if (node.children) { + for (let i = 0, l = node.children.length; i < l; i++) { + markStaticRoots(node.children[i], isInFor || !!node.for) + } + } + if (node.ifConditions) { + for (let i = 1, l = node.ifConditions.length; i < l; i++) { + markStaticRoots(node.ifConditions[i].block, isInFor) + } + } + } +} + +function isStatic (node: ASTNode): boolean { + if (node.type === 2) { // expression + return false + } + if (node.type === 3) { // text + return true + } + return !!(node.pre || ( + !node.hasBindings && // no dynamic bindings + !node.if && !node.for && // not v-if or v-for or v-else + !isBuiltInTag(node.tag) && // not a built-in + isPlatformReservedTag(node.tag) && // not a component + !isDirectChildOfTemplateFor(node) && + Object.keys(node).every(isStaticKey) + )) +} + +function isDirectChildOfTemplateFor (node: ASTElement): boolean { + while (node.parent) { + node = node.parent + if (node.tag !== 'template') { + return false + } + if (node.for) { + return true + } + } + return false +} diff --git a/node_modules/vue/src/compiler/parser/entity-decoder.js b/node_modules/vue/src/compiler/parser/entity-decoder.js new file mode 100644 index 00000000..2836294f --- /dev/null +++ b/node_modules/vue/src/compiler/parser/entity-decoder.js @@ -0,0 +1,11 @@ +/* @flow */ + +let decoder + +export default { + decode (html: string): string { + decoder = decoder || document.createElement('div') + decoder.innerHTML = html + return decoder.textContent + } +} diff --git a/node_modules/vue/src/compiler/parser/filter-parser.js b/node_modules/vue/src/compiler/parser/filter-parser.js new file mode 100644 index 00000000..10939d3f --- /dev/null +++ b/node_modules/vue/src/compiler/parser/filter-parser.js @@ -0,0 +1,97 @@ +/* @flow */ + +const validDivisionCharRE = /[\w).+\-_$\]]/ + +export function parseFilters (exp: string): string { + let inSingle = false + let inDouble = false + let inTemplateString = false + let inRegex = false + let curly = 0 + let square = 0 + let paren = 0 + let lastFilterIndex = 0 + let c, prev, i, expression, filters + + for (i = 0; i < exp.length; i++) { + prev = c + c = exp.charCodeAt(i) + if (inSingle) { + if (c === 0x27 && prev !== 0x5C) inSingle = false + } else if (inDouble) { + if (c === 0x22 && prev !== 0x5C) inDouble = false + } else if (inTemplateString) { + if (c === 0x60 && prev !== 0x5C) inTemplateString = false + } else if (inRegex) { + if (c === 0x2f && prev !== 0x5C) inRegex = false + } else if ( + c === 0x7C && // pipe + exp.charCodeAt(i + 1) !== 0x7C && + exp.charCodeAt(i - 1) !== 0x7C && + !curly && !square && !paren + ) { + if (expression === undefined) { + // first filter, end of expression + lastFilterIndex = i + 1 + expression = exp.slice(0, i).trim() + } else { + pushFilter() + } + } else { + switch (c) { + case 0x22: inDouble = true; break // " + case 0x27: inSingle = true; break // ' + case 0x60: inTemplateString = true; break // ` + case 0x28: paren++; break // ( + case 0x29: paren--; break // ) + case 0x5B: square++; break // [ + case 0x5D: square--; break // ] + case 0x7B: curly++; break // { + case 0x7D: curly--; break // } + } + if (c === 0x2f) { // / + let j = i - 1 + let p + // find first non-whitespace prev char + for (; j >= 0; j--) { + p = exp.charAt(j) + if (p !== ' ') break + } + if (!p || !validDivisionCharRE.test(p)) { + inRegex = true + } + } + } + } + + if (expression === undefined) { + expression = exp.slice(0, i).trim() + } else if (lastFilterIndex !== 0) { + pushFilter() + } + + function pushFilter () { + (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim()) + lastFilterIndex = i + 1 + } + + if (filters) { + for (i = 0; i < filters.length; i++) { + expression = wrapFilter(expression, filters[i]) + } + } + + return expression +} + +function wrapFilter (exp: string, filter: string): string { + const i = filter.indexOf('(') + if (i < 0) { + // _f: resolveFilter + return `_f("${filter}")(${exp})` + } else { + const name = filter.slice(0, i) + const args = filter.slice(i + 1) + return `_f("${name}")(${exp}${args !== ')' ? ',' + args : args}` + } +} diff --git a/node_modules/vue/src/compiler/parser/html-parser.js b/node_modules/vue/src/compiler/parser/html-parser.js new file mode 100644 index 00000000..e2203613 --- /dev/null +++ b/node_modules/vue/src/compiler/parser/html-parser.js @@ -0,0 +1,310 @@ +/** + * Not type-checking this file because it's mostly vendor code. + */ + +/*! + * HTML Parser By John Resig (ejohn.org) + * Modified by Juriy "kangax" Zaytsev + * Original code by Erik Arvidsson, Mozilla Public License + * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js + */ + +import { makeMap, no } from 'shared/util' +import { isNonPhrasingTag } from 'web/compiler/util' + +// Regular Expressions for parsing tags and attributes +const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/ +// could use https://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-QName +// but for Vue templates we can enforce a simple charset +const ncname = '[a-zA-Z_][\\w\\-\\.]*' +const qnameCapture = `((?:${ncname}\\:)?${ncname})` +const startTagOpen = new RegExp(`^<${qnameCapture}`) +const startTagClose = /^\s*(\/?)>/ +const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`) +const doctype = /^]+>/i +// #7298: escape - to avoid being pased as HTML comment when inlined in page +const comment = /^', + '"': '"', + '&': '&', + ' ': '\n', + ' ': '\t' +} +const encodedAttr = /&(?:lt|gt|quot|amp);/g +const encodedAttrWithNewLines = /&(?:lt|gt|quot|amp|#10|#9);/g + +// #5992 +const isIgnoreNewlineTag = makeMap('pre,textarea', true) +const shouldIgnoreFirstNewline = (tag, html) => tag && isIgnoreNewlineTag(tag) && html[0] === '\n' + +function decodeAttr (value, shouldDecodeNewlines) { + const re = shouldDecodeNewlines ? encodedAttrWithNewLines : encodedAttr + return value.replace(re, match => decodingMap[match]) +} + +export function parseHTML (html, options) { + const stack = [] + const expectHTML = options.expectHTML + const isUnaryTag = options.isUnaryTag || no + const canBeLeftOpenTag = options.canBeLeftOpenTag || no + let index = 0 + let last, lastTag + while (html) { + last = html + // Make sure we're not in a plaintext content element like script/style + if (!lastTag || !isPlainTextElement(lastTag)) { + let textEnd = html.indexOf('<') + if (textEnd === 0) { + // Comment: + if (comment.test(html)) { + const commentEnd = html.indexOf('-->') + + if (commentEnd >= 0) { + if (options.shouldKeepComment) { + options.comment(html.substring(4, commentEnd)) + } + advance(commentEnd + 3) + continue + } + } + + // http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment + if (conditionalComment.test(html)) { + const conditionalEnd = html.indexOf(']>') + + if (conditionalEnd >= 0) { + advance(conditionalEnd + 2) + continue + } + } + + // Doctype: + const doctypeMatch = html.match(doctype) + if (doctypeMatch) { + advance(doctypeMatch[0].length) + continue + } + + // End tag: + const endTagMatch = html.match(endTag) + if (endTagMatch) { + const curIndex = index + advance(endTagMatch[0].length) + parseEndTag(endTagMatch[1], curIndex, index) + continue + } + + // Start tag: + const startTagMatch = parseStartTag() + if (startTagMatch) { + handleStartTag(startTagMatch) + if (shouldIgnoreFirstNewline(lastTag, html)) { + advance(1) + } + continue + } + } + + let text, rest, next + if (textEnd >= 0) { + rest = html.slice(textEnd) + while ( + !endTag.test(rest) && + !startTagOpen.test(rest) && + !comment.test(rest) && + !conditionalComment.test(rest) + ) { + // < in plain text, be forgiving and treat it as text + next = rest.indexOf('<', 1) + if (next < 0) break + textEnd += next + rest = html.slice(textEnd) + } + text = html.substring(0, textEnd) + advance(textEnd) + } + + if (textEnd < 0) { + text = html + html = '' + } + + if (options.chars && text) { + options.chars(text) + } + } else { + let endTagLength = 0 + const stackedTag = lastTag.toLowerCase() + const reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(]*>)', 'i')) + const rest = html.replace(reStackedTag, function (all, text, endTag) { + endTagLength = endTag.length + if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') { + text = text + .replace(//g, '$1') // #7298 + .replace(//g, '$1') + } + if (shouldIgnoreFirstNewline(stackedTag, text)) { + text = text.slice(1) + } + if (options.chars) { + options.chars(text) + } + return '' + }) + index += html.length - rest.length + html = rest + parseEndTag(stackedTag, index - endTagLength, index) + } + + if (html === last) { + options.chars && options.chars(html) + if (process.env.NODE_ENV !== 'production' && !stack.length && options.warn) { + options.warn(`Mal-formatted tag at end of template: "${html}"`) + } + break + } + } + + // Clean up any remaining tags + parseEndTag() + + function advance (n) { + index += n + html = html.substring(n) + } + + function parseStartTag () { + const start = html.match(startTagOpen) + if (start) { + const match = { + tagName: start[1], + attrs: [], + start: index + } + advance(start[0].length) + let end, attr + while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) { + advance(attr[0].length) + match.attrs.push(attr) + } + if (end) { + match.unarySlash = end[1] + advance(end[0].length) + match.end = index + return match + } + } + } + + function handleStartTag (match) { + const tagName = match.tagName + const unarySlash = match.unarySlash + + if (expectHTML) { + if (lastTag === 'p' && isNonPhrasingTag(tagName)) { + parseEndTag(lastTag) + } + if (canBeLeftOpenTag(tagName) && lastTag === tagName) { + parseEndTag(tagName) + } + } + + const unary = isUnaryTag(tagName) || !!unarySlash + + const l = match.attrs.length + const attrs = new Array(l) + for (let i = 0; i < l; i++) { + const args = match.attrs[i] + // hackish work around FF bug https://bugzilla.mozilla.org/show_bug.cgi?id=369778 + if (IS_REGEX_CAPTURING_BROKEN && args[0].indexOf('""') === -1) { + if (args[3] === '') { delete args[3] } + if (args[4] === '') { delete args[4] } + if (args[5] === '') { delete args[5] } + } + const value = args[3] || args[4] || args[5] || '' + const shouldDecodeNewlines = tagName === 'a' && args[1] === 'href' + ? options.shouldDecodeNewlinesForHref + : options.shouldDecodeNewlines + attrs[i] = { + name: args[1], + value: decodeAttr(value, shouldDecodeNewlines) + } + } + + if (!unary) { + stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs }) + lastTag = tagName + } + + if (options.start) { + options.start(tagName, attrs, unary, match.start, match.end) + } + } + + function parseEndTag (tagName, start, end) { + let pos, lowerCasedTagName + if (start == null) start = index + if (end == null) end = index + + if (tagName) { + lowerCasedTagName = tagName.toLowerCase() + } + + // Find the closest opened tag of the same type + if (tagName) { + for (pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos].lowerCasedTag === lowerCasedTagName) { + break + } + } + } else { + // If no tag name is provided, clean shop + pos = 0 + } + + if (pos >= 0) { + // Close all the open elements, up the stack + for (let i = stack.length - 1; i >= pos; i--) { + if (process.env.NODE_ENV !== 'production' && + (i > pos || !tagName) && + options.warn + ) { + options.warn( + `tag <${stack[i].tag}> has no matching end tag.` + ) + } + if (options.end) { + options.end(stack[i].tag, start, end) + } + } + + // Remove the open elements from the stack + stack.length = pos + lastTag = pos && stack[pos - 1].tag + } else if (lowerCasedTagName === 'br') { + if (options.start) { + options.start(tagName, [], true, start, end) + } + } else if (lowerCasedTagName === 'p') { + if (options.start) { + options.start(tagName, [], false, start, end) + } + if (options.end) { + options.end(tagName, start, end) + } + } + } +} diff --git a/node_modules/vue/src/compiler/parser/index.js b/node_modules/vue/src/compiler/parser/index.js new file mode 100644 index 00000000..a603b36b --- /dev/null +++ b/node_modules/vue/src/compiler/parser/index.js @@ -0,0 +1,675 @@ +/* @flow */ + +import he from 'he' +import { parseHTML } from './html-parser' +import { parseText } from './text-parser' +import { parseFilters } from './filter-parser' +import { genAssignmentCode } from '../directives/model' +import { extend, cached, no, camelize } from 'shared/util' +import { isIE, isEdge, isServerRendering } from 'core/util/env' + +import { + addProp, + addAttr, + baseWarn, + addHandler, + addDirective, + getBindingAttr, + getAndRemoveAttr, + pluckModuleFunction +} from '../helpers' + +export const onRE = /^@|^v-on:/ +export const dirRE = /^v-|^@|^:/ +export const forAliasRE = /([^]*?)\s+(?:in|of)\s+([^]*)/ +export const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/ +const stripParensRE = /^\(|\)$/g + +const argRE = /:(.*)$/ +export const bindRE = /^:|^v-bind:/ +const modifierRE = /\.[^.]+/g + +const decodeHTMLCached = cached(he.decode) + +// configurable state +export let warn: any +let delimiters +let transforms +let preTransforms +let postTransforms +let platformIsPreTag +let platformMustUseProp +let platformGetTagNamespace + +type Attr = { name: string; value: string }; + +export function createASTElement ( + tag: string, + attrs: Array, + parent: ASTElement | void +): ASTElement { + return { + type: 1, + tag, + attrsList: attrs, + attrsMap: makeAttrsMap(attrs), + parent, + children: [] + } +} + +/** + * Convert HTML string to AST. + */ +export function parse ( + template: string, + options: CompilerOptions +): ASTElement | void { + warn = options.warn || baseWarn + + platformIsPreTag = options.isPreTag || no + platformMustUseProp = options.mustUseProp || no + platformGetTagNamespace = options.getTagNamespace || no + + transforms = pluckModuleFunction(options.modules, 'transformNode') + preTransforms = pluckModuleFunction(options.modules, 'preTransformNode') + postTransforms = pluckModuleFunction(options.modules, 'postTransformNode') + + delimiters = options.delimiters + + const stack = [] + const preserveWhitespace = options.preserveWhitespace !== false + let root + let currentParent + let inVPre = false + let inPre = false + let warned = false + + function warnOnce (msg) { + if (!warned) { + warned = true + warn(msg) + } + } + + function closeElement (element) { + // check pre state + if (element.pre) { + inVPre = false + } + if (platformIsPreTag(element.tag)) { + inPre = false + } + // apply post-transforms + for (let i = 0; i < postTransforms.length; i++) { + postTransforms[i](element, options) + } + } + + parseHTML(template, { + warn, + expectHTML: options.expectHTML, + isUnaryTag: options.isUnaryTag, + canBeLeftOpenTag: options.canBeLeftOpenTag, + shouldDecodeNewlines: options.shouldDecodeNewlines, + shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref, + shouldKeepComment: options.comments, + start (tag, attrs, unary) { + // check namespace. + // inherit parent ns if there is one + const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag) + + // handle IE svg bug + /* istanbul ignore if */ + if (isIE && ns === 'svg') { + attrs = guardIESVGBug(attrs) + } + + let element: ASTElement = createASTElement(tag, attrs, currentParent) + if (ns) { + element.ns = ns + } + + if (isForbiddenTag(element) && !isServerRendering()) { + element.forbidden = true + process.env.NODE_ENV !== 'production' && warn( + 'Templates should only be responsible for mapping the state to the ' + + 'UI. Avoid placing tags with side-effects in your templates, such as ' + + `<${tag}>` + ', as they will not be parsed.' + ) + } + + // apply pre-transforms + for (let i = 0; i < preTransforms.length; i++) { + element = preTransforms[i](element, options) || element + } + + if (!inVPre) { + processPre(element) + if (element.pre) { + inVPre = true + } + } + if (platformIsPreTag(element.tag)) { + inPre = true + } + if (inVPre) { + processRawAttrs(element) + } else if (!element.processed) { + // structural directives + processFor(element) + processIf(element) + processOnce(element) + // element-scope stuff + processElement(element, options) + } + + function checkRootConstraints (el) { + if (process.env.NODE_ENV !== 'production') { + if (el.tag === 'slot' || el.tag === 'template') { + warnOnce( + `Cannot use <${el.tag}> as component root element because it may ` + + 'contain multiple nodes.' + ) + } + if (el.attrsMap.hasOwnProperty('v-for')) { + warnOnce( + 'Cannot use v-for on stateful component root element because ' + + 'it renders multiple elements.' + ) + } + } + } + + // tree management + if (!root) { + root = element + checkRootConstraints(root) + } else if (!stack.length) { + // allow root elements with v-if, v-else-if and v-else + if (root.if && (element.elseif || element.else)) { + checkRootConstraints(element) + addIfCondition(root, { + exp: element.elseif, + block: element + }) + } else if (process.env.NODE_ENV !== 'production') { + warnOnce( + `Component template should contain exactly one root element. ` + + `If you are using v-if on multiple elements, ` + + `use v-else-if to chain them instead.` + ) + } + } + if (currentParent && !element.forbidden) { + if (element.elseif || element.else) { + processIfConditions(element, currentParent) + } else if (element.slotScope) { // scoped slot + currentParent.plain = false + const name = element.slotTarget || '"default"' + ;(currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element + } else { + currentParent.children.push(element) + element.parent = currentParent + } + } + if (!unary) { + currentParent = element + stack.push(element) + } else { + closeElement(element) + } + }, + + end () { + // remove trailing whitespace + const element = stack[stack.length - 1] + const lastNode = element.children[element.children.length - 1] + if (lastNode && lastNode.type === 3 && lastNode.text === ' ' && !inPre) { + element.children.pop() + } + // pop stack + stack.length -= 1 + currentParent = stack[stack.length - 1] + closeElement(element) + }, + + chars (text: string) { + if (!currentParent) { + if (process.env.NODE_ENV !== 'production') { + if (text === template) { + warnOnce( + 'Component template requires a root element, rather than just text.' + ) + } else if ((text = text.trim())) { + warnOnce( + `text "${text}" outside root element will be ignored.` + ) + } + } + return + } + // IE textarea placeholder bug + /* istanbul ignore if */ + if (isIE && + currentParent.tag === 'textarea' && + currentParent.attrsMap.placeholder === text + ) { + return + } + const children = currentParent.children + text = inPre || text.trim() + ? isTextTag(currentParent) ? text : decodeHTMLCached(text) + // only preserve whitespace if its not right after a starting tag + : preserveWhitespace && children.length ? ' ' : '' + if (text) { + let res + if (!inVPre && text !== ' ' && (res = parseText(text, delimiters))) { + children.push({ + type: 2, + expression: res.expression, + tokens: res.tokens, + text + }) + } else if (text !== ' ' || !children.length || children[children.length - 1].text !== ' ') { + children.push({ + type: 3, + text + }) + } + } + }, + comment (text: string) { + currentParent.children.push({ + type: 3, + text, + isComment: true + }) + } + }) + return root +} + +function processPre (el) { + if (getAndRemoveAttr(el, 'v-pre') != null) { + el.pre = true + } +} + +function processRawAttrs (el) { + const l = el.attrsList.length + if (l) { + const attrs = el.attrs = new Array(l) + for (let i = 0; i < l; i++) { + attrs[i] = { + name: el.attrsList[i].name, + value: JSON.stringify(el.attrsList[i].value) + } + } + } else if (!el.pre) { + // non root node in pre blocks with no attributes + el.plain = true + } +} + +export function processElement (element: ASTElement, options: CompilerOptions) { + processKey(element) + + // determine whether this is a plain element after + // removing structural attributes + element.plain = !element.key && !element.attrsList.length + + processRef(element) + processSlot(element) + processComponent(element) + for (let i = 0; i < transforms.length; i++) { + element = transforms[i](element, options) || element + } + processAttrs(element) +} + +function processKey (el) { + const exp = getBindingAttr(el, 'key') + if (exp) { + if (process.env.NODE_ENV !== 'production' && el.tag === 'template') { + warn(`