.'
21 | )
22 | }
23 | }
24 | if (staticClass) {
25 | el.staticClass = JSON.stringify(staticClass)
26 | }
27 | const classBinding = getBindingAttr(el, 'class', false /* getStatic */)
28 | if (classBinding) {
29 | el.classBinding = classBinding
30 | }
31 | }
32 |
33 | function genData (el: ASTElement): string {
34 | let data = ''
35 | if (el.staticClass) {
36 | data += `staticClass:${el.staticClass},`
37 | }
38 | if (el.classBinding) {
39 | data += `class:${el.classBinding},`
40 | }
41 | return data
42 | }
43 |
44 | export default {
45 | staticKeys: ['staticClass'],
46 | transformNode,
47 | genData
48 | }
49 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import model from './model'
4 |
5 | export default [
6 | klass,
7 | style,
8 | model
9 | ]
10 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/compiler/options.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {
4 | isPreTag,
5 | mustUseProp,
6 | isReservedTag,
7 | getTagNamespace
8 | } from '../util/index'
9 |
10 | import modules from './modules/index'
11 | import directives from './directives/index'
12 | import { genStaticKeys } from 'shared/util'
13 | import { isUnaryTag, canBeLeftOpenTag } from './util'
14 |
15 | export const baseOptions: CompilerOptions = {
16 | expectHTML: true,
17 | modules,
18 | directives,
19 | isPreTag,
20 | isUnaryTag,
21 | mustUseProp,
22 | canBeLeftOpenTag,
23 | isReservedTag,
24 | getTagNamespace,
25 | staticKeys: genStaticKeys(modules)
26 | }
27 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/compiler/util.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { makeMap } from 'shared/util'
4 |
5 | export const isUnaryTag = makeMap(
6 | 'area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
7 | 'link,meta,param,source,track,wbr'
8 | )
9 |
10 | // Elements that you can, intentionally, leave open
11 | // (and which close themselves)
12 | export const canBeLeftOpenTag = makeMap(
13 | 'colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source'
14 | )
15 |
16 | // HTML5 tags https://html.spec.whatwg.org/multipage/indices.html#elements-3
17 | // Phrasing Content https://html.spec.whatwg.org/multipage/dom.html#phrasing-content
18 | export const isNonPhrasingTag = makeMap(
19 | 'address,article,aside,base,blockquote,body,caption,col,colgroup,dd,' +
20 | 'details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,' +
21 | 'h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,' +
22 | 'optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,' +
23 | 'title,tr,track'
24 | )
25 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/entry-compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export { parseComponent } from 'sfc/parser'
4 | export { compile, compileToFunctions } from './compiler/index'
5 | export { ssrCompile, ssrCompileToFunctions } from './server/compiler'
6 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/entry-runtime.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import Vue from './runtime/index'
4 |
5 | export default Vue
6 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/entry-server-basic-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import modules from './server/modules/index'
4 | import directives from './server/directives/index'
5 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util'
6 | import { createBasicRenderer } from 'server/create-basic-renderer'
7 |
8 | export default createBasicRenderer({
9 | modules,
10 | directives,
11 | isUnaryTag,
12 | canBeLeftOpenTag
13 | })
14 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/entry-server-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | process.env.VUE_ENV = 'server'
4 |
5 | import { extend } from 'shared/util'
6 | import modules from './server/modules/index'
7 | import baseDirectives from './server/directives/index'
8 | import { isUnaryTag, canBeLeftOpenTag } from './compiler/util'
9 |
10 | import { createRenderer as _createRenderer } from 'server/create-renderer'
11 | import { createBundleRendererCreator } from 'server/bundle-renderer/create-bundle-renderer'
12 |
13 | export function createRenderer (options?: Object = {}): {
14 | renderToString: Function,
15 | renderToStream: Function
16 | } {
17 | return _createRenderer(extend(extend({}, options), {
18 | isUnaryTag,
19 | canBeLeftOpenTag,
20 | modules,
21 | // user can provide server-side implementations for custom directives
22 | // when creating the renderer.
23 | directives: extend(baseDirectives, options.directives)
24 | }))
25 | }
26 |
27 | export const createBundleRenderer = createBundleRendererCreator(createRenderer)
28 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Transition from './transition'
2 | import TransitionGroup from './transition-group'
3 |
4 | export default {
5 | Transition,
6 | TransitionGroup
7 | }
8 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 | import show from './show'
3 |
4 | export default {
5 | model,
6 | show
7 | }
8 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/runtime/modules/class.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import {
4 | isDef,
5 | isUndef
6 | } from 'shared/util'
7 |
8 | import {
9 | concat,
10 | stringifyClass,
11 | genClassForVnode
12 | } from 'web/util/index'
13 |
14 | function updateClass (oldVnode: any, vnode: any) {
15 | const el = vnode.elm
16 | const data: VNodeData = vnode.data
17 | const oldData: VNodeData = oldVnode.data
18 | if (
19 | isUndef(data.staticClass) &&
20 | isUndef(data.class) && (
21 | isUndef(oldData) || (
22 | isUndef(oldData.staticClass) &&
23 | isUndef(oldData.class)
24 | )
25 | )
26 | ) {
27 | return
28 | }
29 |
30 | let cls = genClassForVnode(vnode)
31 |
32 | // handle transition classes
33 | const transitionClass = el._transitionClasses
34 | if (isDef(transitionClass)) {
35 | cls = concat(cls, stringifyClass(transitionClass))
36 | }
37 |
38 | // set the class
39 | if (cls !== el._prevClass) {
40 | el.setAttribute('class', cls)
41 | el._prevClass = cls
42 | }
43 | }
44 |
45 | export default {
46 | create: updateClass,
47 | update: updateClass
48 | }
49 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import domProps from './dom-props'
5 | import style from './style'
6 | import transition from './transition'
7 |
8 | export default [
9 | attrs,
10 | klass,
11 | events,
12 | domProps,
13 | style,
14 | transition
15 | ]
16 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'web/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'web/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({ nodeOps, modules })
13 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/server/compiler.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { baseOptions } from '../compiler/options'
4 | import { createCompiler } from 'server/optimizing-compiler/index'
5 |
6 | const { compile, compileToFunctions } = createCompiler(baseOptions)
7 |
8 | export {
9 | compile as ssrCompile,
10 | compileToFunctions as ssrCompileToFunctions
11 | }
12 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/server/directives/index.js:
--------------------------------------------------------------------------------
1 | import show from './show'
2 | import model from './model'
3 |
4 | export default {
5 | show,
6 | model
7 | }
8 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/server/directives/show.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export default function show (node: VNodeWithData, dir: VNodeDirective) {
4 | if (!dir.value) {
5 | const style: any = node.data.style || (node.data.style = {})
6 | if (Array.isArray(style)) {
7 | style.push({ display: 'none' })
8 | } else {
9 | style.display = 'none'
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/server/modules/class.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { escape } from '../util'
4 | import { genClassForVnode } from 'web/util/index'
5 |
6 | export default function renderClass (node: VNodeWithData): ?string {
7 | const classList = genClassForVnode(node)
8 | if (classList !== '') {
9 | return ` class="${escape(classList)}"`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/server/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import domProps from './dom-props'
3 | import klass from './class'
4 | import style from './style'
5 |
6 | export default [
7 | attrs,
8 | domProps,
9 | klass,
10 | style
11 | ]
12 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/server/modules/style.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { escape } from '../util'
4 | import { hyphenate } from 'shared/util'
5 | import { getStyle } from 'web/util/style'
6 |
7 | export function genStyle (style: Object): string {
8 | let styleText = ''
9 | for (const key in style) {
10 | const value = style[key]
11 | const hyphenatedKey = hyphenate(key)
12 | if (Array.isArray(value)) {
13 | for (let i = 0, len = value.length; i < len; i++) {
14 | styleText += `${hyphenatedKey}:${value[i]};`
15 | }
16 | } else {
17 | styleText += `${hyphenatedKey}:${value};`
18 | }
19 | }
20 | return styleText
21 | }
22 |
23 | export default function renderStyle (vnode: VNodeWithData): ?string {
24 | const styleText = genStyle(getStyle(vnode, false))
25 | if (styleText !== '') {
26 | return ` style=${JSON.stringify(escape(styleText))}`
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/util/compat.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { inBrowser } from 'core/util/index'
4 |
5 | // check whether current browser encodes a char inside attribute values
6 | let div
7 | function getShouldDecode (href: boolean): boolean {
8 | div = div || document.createElement('div')
9 | div.innerHTML = href ? `
` : `
`
10 | return div.innerHTML.indexOf('
') > 0
11 | }
12 |
13 | // #3663: IE encodes newlines inside attribute values while other browsers don't
14 | export const shouldDecodeNewlines = inBrowser ? getShouldDecode(false) : false
15 | // #6828: chrome encodes content in a[href]
16 | export const shouldDecodeNewlinesForHref = inBrowser ? getShouldDecode(true) : false
17 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/web/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/index'
4 |
5 | export * from './attrs'
6 | export * from './class'
7 | export * from './element'
8 |
9 | /**
10 | * Query an element selector if it's not an element already.
11 | */
12 | export function query (el: string | Element): Element {
13 | if (typeof el === 'string') {
14 | const selected = document.querySelector(el)
15 | if (!selected) {
16 | process.env.NODE_ENV !== 'production' && warn(
17 | 'Cannot find element: ' + el
18 | )
19 | return document.createElement('div')
20 | }
21 | return selected
22 | } else {
23 | return el
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/directives/index.js:
--------------------------------------------------------------------------------
1 | import model from './model'
2 |
3 | export default {
4 | model
5 | }
6 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/directives/model.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addHandler, addAttr } from 'compiler/helpers'
4 | import { genComponentModel, genAssignmentCode } from 'compiler/directives/model'
5 |
6 | export default function model (
7 | el: ASTElement,
8 | dir: ASTDirective
9 | ): ?boolean {
10 | if (el.tag === 'input' || el.tag === 'textarea') {
11 | genDefaultModel(el, dir.value, dir.modifiers)
12 | } else {
13 | genComponentModel(el, dir.value, dir.modifiers)
14 | }
15 | }
16 |
17 | function genDefaultModel (
18 | el: ASTElement,
19 | value: string,
20 | modifiers: ?ASTModifiers
21 | ): ?boolean {
22 | const { lazy, trim, number } = modifiers || {}
23 | const event = lazy ? 'change' : 'input'
24 |
25 | let valueExpression = `$event.target.attr.value${trim ? '.trim()' : ''}`
26 | if (number) {
27 | valueExpression = `_n(${valueExpression})`
28 | }
29 |
30 | const code = genAssignmentCode(value, valueExpression)
31 | addAttr(el, 'value', `(${value})`)
32 | addHandler(el, event, code, null, true)
33 | }
34 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { genStaticKeys } from 'shared/util'
4 | import { createCompiler } from 'compiler/index'
5 |
6 | import modules from './modules/index'
7 | import directives from './directives/index'
8 |
9 | import {
10 | isUnaryTag,
11 | mustUseProp,
12 | isReservedTag,
13 | canBeLeftOpenTag,
14 | getTagNamespace
15 | } from '../util/element'
16 |
17 | export const baseOptions: WeexCompilerOptions = {
18 | modules,
19 | directives,
20 | isUnaryTag,
21 | mustUseProp,
22 | canBeLeftOpenTag,
23 | isReservedTag,
24 | getTagNamespace,
25 | preserveWhitespace: false,
26 | recyclable: false,
27 | staticKeys: genStaticKeys(modules)
28 | }
29 |
30 | const compiler = createCompiler(baseOptions)
31 |
32 | export function compile (
33 | template: string,
34 | options?: WeexCompilerOptions
35 | ): WeexCompiledResult {
36 | let generateAltRender = false
37 | if (options && options.recyclable === true) {
38 | generateAltRender = true
39 | options.recyclable = false
40 | }
41 | const result = compiler.compile(template, options)
42 |
43 | // generate @render function for
44 | if (options && generateAltRender) {
45 | options.recyclable = true
46 | // disable static optimizations
47 | options.optimize = false
48 | const { render } = compiler.compile(template, options)
49 | result['@render'] = render
50 | }
51 | return result
52 | }
53 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/append.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { makeMap } from 'shared/util'
4 |
5 | // The "unitary tag" means that the tag node and its children
6 | // must be sent to the native together.
7 | const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
8 |
9 | function preTransformNode (el: ASTElement) {
10 | if (isUnitaryTag(el.tag) && !el.attrsList.some(item => item.name === 'append')) {
11 | el.attrsMap.append = 'tree'
12 | el.attrsList.push({ name: 'append', value: 'tree' })
13 | }
14 | if (el.attrsMap.append === 'tree') {
15 | el.appendAsTree = true
16 | }
17 | }
18 |
19 | function genData (el: ASTElement): string {
20 | return el.appendAsTree ? `appendAsTree:true,` : ''
21 | }
22 |
23 | export default {
24 | staticKeys: ['appendAsTree'],
25 | preTransformNode,
26 | genData
27 | }
28 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/index.js:
--------------------------------------------------------------------------------
1 | import klass from './class'
2 | import style from './style'
3 | import props from './props'
4 | import append from './append'
5 | import recycleList from './recycle-list/index'
6 |
7 | export default [
8 | recycleList,
9 | klass,
10 | style,
11 | props,
12 | append
13 | ]
14 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/props.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { cached, camelize } from 'shared/util'
4 |
5 | const normalize = cached(camelize)
6 |
7 | function normalizeKeyName (str: string): string {
8 | if (str.match(/^v\-/)) {
9 | return str.replace(/(v-[a-z\-]+\:)([a-z\-]+)$/i, ($, directive, prop) => {
10 | return directive + normalize(prop)
11 | })
12 | }
13 | return normalize(str)
14 | }
15 |
16 | function transformNode (el: ASTElement) {
17 | if (Array.isArray(el.attrsList)) {
18 | el.attrsList.forEach(attr => {
19 | if (attr.name && attr.name.match(/\-/)) {
20 | const realName = normalizeKeyName(attr.name)
21 | if (el.attrsMap) {
22 | el.attrsMap[realName] = el.attrsMap[attr.name]
23 | delete el.attrsMap[attr.name]
24 | }
25 | attr.name = realName
26 | }
27 | })
28 | }
29 | }
30 | export default {
31 | transformNode
32 | }
33 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/component-root.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | // mark component root nodes as
6 | export function postTransformComponentRoot (el: ASTElement) {
7 | if (!el.parent) {
8 | // component root
9 | addAttr(el, '@isComponentRoot', 'true')
10 | addAttr(el, '@templateId', '_uid')
11 | addAttr(el, '@componentProps', '$props || {}')
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/component.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 | import { RECYCLE_LIST_MARKER } from 'weex/util/index'
5 |
6 | // mark components as inside recycle-list so that we know we need to invoke
7 | // their special @render function instead of render in create-component.js
8 | export function postTransformComponent (
9 | el: ASTElement,
10 | options: WeexCompilerOptions
11 | ) {
12 | // $flow-disable-line (we know isReservedTag is there)
13 | if (!options.isReservedTag(el.tag) && el.tag !== 'cell-slot') {
14 | addAttr(el, RECYCLE_LIST_MARKER, 'true')
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/text.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { addAttr } from 'compiler/helpers'
4 |
5 | function genText (node: ASTNode) {
6 | const value = node.type === 3
7 | ? node.text
8 | : node.type === 2
9 | ? node.tokens.length === 1
10 | ? node.tokens[0]
11 | : node.tokens
12 | : ''
13 | return JSON.stringify(value)
14 | }
15 |
16 | export function postTransformText (el: ASTElement) {
17 | // weex can only contain text, so the parser
18 | // always generates a single child.
19 | if (el.children.length) {
20 | addAttr(el, 'value', genText(el.children[0]))
21 | el.children = []
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/v-bind.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { camelize } from 'shared/util'
4 | import { generateBinding } from 'weex/util/parser'
5 | import { bindRE } from 'compiler/parser/index'
6 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
7 |
8 | function parseAttrName (name: string): string {
9 | return camelize(name.replace(bindRE, ''))
10 | }
11 |
12 | export function preTransformVBind (el: ASTElement) {
13 | for (const attr in el.attrsMap) {
14 | if (bindRE.test(attr)) {
15 | const name: string = parseAttrName(attr)
16 | const value = generateBinding(getAndRemoveAttr(el, attr))
17 | delete el.attrsMap[attr]
18 | addRawAttr(el, name, value)
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/v-for.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parseFor } from 'compiler/parser/index'
4 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
5 |
6 | export function preTransformVFor (el: ASTElement, options: WeexCompilerOptions) {
7 | const exp = getAndRemoveAttr(el, 'v-for')
8 | if (!exp) {
9 | return
10 | }
11 |
12 | const res = parseFor(exp)
13 | if (!res) {
14 | if (process.env.NODE_ENV !== 'production' && options.warn) {
15 | options.warn(`Invalid v-for expression: ${exp}`)
16 | }
17 | return
18 | }
19 |
20 | const desc: Object = {
21 | '@expression': res.for,
22 | '@alias': res.alias
23 | }
24 | if (res.iterator2) {
25 | desc['@key'] = res.iterator1
26 | desc['@index'] = res.iterator2
27 | } else {
28 | desc['@index'] = res.iterator1
29 | }
30 |
31 | delete el.attrsMap['v-for']
32 | addRawAttr(el, '[[repeat]]', desc)
33 | }
34 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/v-on.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
4 |
5 | function parseHandlerParams (handler: ASTElementHandler) {
6 | const res = inlineStatementRE.exec(handler.value)
7 | if (res && res[2]) {
8 | handler.params = res[2].split(/\s*,\s*/)
9 | }
10 | }
11 |
12 | export function postTransformVOn (el: ASTElement) {
13 | const events: ASTElementHandlers | void = el.events
14 | if (!events) {
15 | return
16 | }
17 | for (const name in events) {
18 | const handler: ASTElementHandler | Array = events[name]
19 | if (Array.isArray(handler)) {
20 | handler.map(fn => parseHandlerParams(fn))
21 | } else {
22 | parseHandlerParams(handler)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/compiler/modules/recycle-list/v-once.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
4 |
5 | function containVOnce (el: ASTElement): boolean {
6 | for (const attr in el.attrsMap) {
7 | if (/^v\-once$/i.test(attr)) {
8 | return true
9 | }
10 | }
11 | return false
12 | }
13 |
14 | export function preTransformVOnce (el: ASTElement) {
15 | if (containVOnce(el)) {
16 | getAndRemoveAttr(el, 'v-once', true)
17 | addRawAttr(el, '[[once]]', true)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/entry-compiler.js:
--------------------------------------------------------------------------------
1 | export { compile } from 'weex/compiler/index'
2 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/entry-runtime-factory.js:
--------------------------------------------------------------------------------
1 | // this entry is built and wrapped with a factory function
2 | // used to generate a fresh copy of Vue for every Weex instance.
3 |
4 | import Vue from './runtime/index'
5 |
6 | exports.Vue = Vue
7 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/components/index.js:
--------------------------------------------------------------------------------
1 | import Richtext from './richtext'
2 | import Transition from './transition'
3 | import TransitionGroup from './transition-group'
4 |
5 | export default {
6 | Richtext,
7 | Transition,
8 | TransitionGroup
9 | }
10 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/components/transition.js:
--------------------------------------------------------------------------------
1 | // reuse same transition component logic from web
2 | export {
3 | transitionProps,
4 | extractTransitionData
5 | } from 'web/runtime/components/transition'
6 |
7 | import Transition from 'web/runtime/components/transition'
8 |
9 | export default Transition
10 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/directives/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | }
3 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import Vue from 'core/index'
4 | import { patch } from 'weex/runtime/patch'
5 | import { mountComponent } from 'core/instance/lifecycle'
6 | import platformDirectives from 'weex/runtime/directives/index'
7 | import platformComponents from 'weex/runtime/components/index'
8 |
9 | import {
10 | query,
11 | mustUseProp,
12 | isReservedTag,
13 | isRuntimeComponent,
14 | isUnknownElement
15 | } from 'weex/util/element'
16 |
17 | // install platform specific utils
18 | Vue.config.mustUseProp = mustUseProp
19 | Vue.config.isReservedTag = isReservedTag
20 | Vue.config.isRuntimeComponent = isRuntimeComponent
21 | Vue.config.isUnknownElement = isUnknownElement
22 |
23 | // install platform runtime directives and components
24 | Vue.options.directives = platformDirectives
25 | Vue.options.components = platformComponents
26 |
27 | // install platform patch function
28 | Vue.prototype.__patch__ = patch
29 |
30 | // wrap mount
31 | Vue.prototype.$mount = function (
32 | el?: any,
33 | hydrating?: boolean
34 | ): Component {
35 | return mountComponent(
36 | this,
37 | el && query(el, this.$document),
38 | hydrating
39 | )
40 | }
41 |
42 | export default Vue
43 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/modules/attrs.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { extend } from 'shared/util'
4 |
5 | function updateAttrs (oldVnode: VNodeWithData, vnode: VNodeWithData) {
6 | if (!oldVnode.data.attrs && !vnode.data.attrs) {
7 | return
8 | }
9 | let key, cur, old
10 | const elm = vnode.elm
11 | const oldAttrs = oldVnode.data.attrs || {}
12 | let attrs = vnode.data.attrs || {}
13 | // clone observed objects, as the user probably wants to mutate it
14 | if (attrs.__ob__) {
15 | attrs = vnode.data.attrs = extend({}, attrs)
16 | }
17 |
18 | const supportBatchUpdate = typeof elm.setAttrs === 'function'
19 | const batchedAttrs = {}
20 | for (key in attrs) {
21 | cur = attrs[key]
22 | old = oldAttrs[key]
23 | if (old !== cur) {
24 | supportBatchUpdate
25 | ? (batchedAttrs[key] = cur)
26 | : elm.setAttr(key, cur)
27 | }
28 | }
29 | for (key in oldAttrs) {
30 | if (attrs[key] == null) {
31 | supportBatchUpdate
32 | ? (batchedAttrs[key] = undefined)
33 | : elm.setAttr(key)
34 | }
35 | }
36 | if (supportBatchUpdate) {
37 | elm.setAttrs(batchedAttrs)
38 | }
39 | }
40 |
41 | export default {
42 | create: updateAttrs,
43 | update: updateAttrs
44 | }
45 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/modules/events.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { updateListeners } from 'core/vdom/helpers/update-listeners'
4 |
5 | let target: any
6 |
7 | function createOnceHandler (event, handler, capture) {
8 | const _target = target // save current target element in closure
9 | return function onceHandler () {
10 | const res = handler.apply(null, arguments)
11 | if (res !== null) {
12 | remove(event, onceHandler, capture, _target)
13 | }
14 | }
15 | }
16 |
17 | function add (
18 | event: string,
19 | handler: Function,
20 | capture: boolean,
21 | passive?: boolean,
22 | params?: Array
23 | ) {
24 | if (capture) {
25 | console.log('Weex do not support event in bubble phase.')
26 | return
27 | }
28 | target.addEvent(event, handler, params)
29 | }
30 |
31 | function remove (
32 | event: string,
33 | handler: any,
34 | capture: any,
35 | _target?: any
36 | ) {
37 | (_target || target).removeEvent(event)
38 | }
39 |
40 | function updateDOMListeners (oldVnode: VNodeWithData, vnode: VNodeWithData) {
41 | if (!oldVnode.data.on && !vnode.data.on) {
42 | return
43 | }
44 | const on = vnode.data.on || {}
45 | const oldOn = oldVnode.data.on || {}
46 | target = vnode.elm
47 | updateListeners(on, oldOn, add, remove, createOnceHandler, vnode.context)
48 | target = undefined
49 | }
50 |
51 | export default {
52 | create: updateDOMListeners,
53 | update: updateDOMListeners
54 | }
55 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/modules/index.js:
--------------------------------------------------------------------------------
1 | import attrs from './attrs'
2 | import klass from './class'
3 | import events from './events'
4 | import style from './style'
5 | import transition from './transition'
6 |
7 | export default [
8 | attrs,
9 | klass,
10 | events,
11 | style,
12 | transition
13 | ]
14 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/patch.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import * as nodeOps from 'weex/runtime/node-ops'
4 | import { createPatchFunction } from 'core/vdom/patch'
5 | import baseModules from 'core/vdom/modules/index'
6 | import platformModules from 'weex/runtime/modules/index'
7 |
8 | // the directive module should be applied last, after all
9 | // built-in modules have been applied.
10 | const modules = platformModules.concat(baseModules)
11 |
12 | export const patch: Function = createPatchFunction({
13 | nodeOps,
14 | modules,
15 | LONG_LIST_THRESHOLD: 10
16 | })
17 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/recycle-list/render-component-template.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { warn } from 'core/util/debug'
4 | import { handleError } from 'core/util/error'
5 | import { RECYCLE_LIST_MARKER } from 'weex/util/index'
6 | import { createComponentInstanceForVnode } from 'core/vdom/create-component'
7 | import { resolveVirtualComponent } from './virtual-component'
8 |
9 | export function isRecyclableComponent (vnode: VNodeWithData): boolean {
10 | return vnode.data.attrs
11 | ? (RECYCLE_LIST_MARKER in vnode.data.attrs)
12 | : false
13 | }
14 |
15 | export function renderRecyclableComponentTemplate (vnode: MountedComponentVNode): VNode {
16 | // $flow-disable-line
17 | delete vnode.data.attrs[RECYCLE_LIST_MARKER]
18 | resolveVirtualComponent(vnode)
19 | const vm = createComponentInstanceForVnode(vnode)
20 | const render = (vm.$options: any)['@render']
21 | if (render) {
22 | try {
23 | return render.call(vm)
24 | } catch (err) {
25 | handleError(err, vm, `@render`)
26 | }
27 | } else {
28 | warn(
29 | `@render function not defined on component used in . ` +
30 | `Make sure to declare \`recyclable="true"\` on the component's template.`,
31 | vm
32 | )
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/runtime/text-node.js:
--------------------------------------------------------------------------------
1 | let latestNodeId = 1
2 |
3 | export default function TextNode (text) {
4 | this.instanceId = ''
5 | this.nodeId = latestNodeId++
6 | this.parentNode = null
7 | this.nodeType = 3
8 | this.text = text
9 | }
10 |
--------------------------------------------------------------------------------
/vue-code/src/platforms/weex/util/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 | declare var document: WeexDocument;
3 |
4 | import { warn } from 'core/util/index'
5 |
6 | export const RECYCLE_LIST_MARKER = '@inRecycleList'
7 |
8 | // Register the component hook to weex native render engine.
9 | // The hook will be triggered by native, not javascript.
10 | export function registerComponentHook (
11 | componentId: string,
12 | type: string, // hook type, could be "lifecycle" or "instance"
13 | hook: string, // hook name
14 | fn: Function
15 | ) {
16 | if (!document || !document.taskCenter) {
17 | warn(`Can't find available "document" or "taskCenter".`)
18 | return
19 | }
20 | if (typeof document.taskCenter.registerHook === 'function') {
21 | return document.taskCenter.registerHook(componentId, type, hook, fn)
22 | }
23 | warn(`Failed to register component hook "${type}@${hook}#${componentId}".`)
24 | }
25 |
26 | // Updates the state of the component to weex native render engine.
27 | export function updateComponentData (
28 | componentId: string,
29 | newData: Object | void,
30 | callback?: Function
31 | ) {
32 | if (!document || !document.taskCenter) {
33 | warn(`Can't find available "document" or "taskCenter".`)
34 | return
35 | }
36 | if (typeof document.taskCenter.updateData === 'function') {
37 | return document.taskCenter.updateData(componentId, newData, callback)
38 | }
39 | warn(`Failed to update component data (${componentId}).`)
40 | }
41 |
--------------------------------------------------------------------------------
/vue-code/src/server/bundle-renderer/source-map-support.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const SourceMapConsumer = require('source-map').SourceMapConsumer
4 |
5 | const filenameRE = /\(([^)]+\.js):(\d+):(\d+)\)$/
6 |
7 | export function createSourceMapConsumers (rawMaps: Object) {
8 | const maps = {}
9 | Object.keys(rawMaps).forEach(file => {
10 | maps[file] = new SourceMapConsumer(rawMaps[file])
11 | })
12 | return maps
13 | }
14 |
15 | export function rewriteErrorTrace (e: any, mapConsumers: {
16 | [key: string]: SourceMapConsumer
17 | }) {
18 | if (e && typeof e.stack === 'string') {
19 | e.stack = e.stack.split('\n').map(line => {
20 | return rewriteTraceLine(line, mapConsumers)
21 | }).join('\n')
22 | }
23 | }
24 |
25 | function rewriteTraceLine (trace: string, mapConsumers: {
26 | [key: string]: SourceMapConsumer
27 | }) {
28 | const m = trace.match(filenameRE)
29 | const map = m && mapConsumers[m[1]]
30 | if (m != null && map) {
31 | const originalPosition = map.originalPositionFor({
32 | line: Number(m[2]),
33 | column: Number(m[3])
34 | })
35 | if (originalPosition.source != null) {
36 | const { source, line, column } = originalPosition
37 | const mappedPosition = `(${source.replace(/^webpack:\/\/\//, '')}:${String(line)}:${String(column)})`
38 | return trace.replace(filenameRE, mappedPosition)
39 | } else {
40 | return trace
41 | }
42 | } else {
43 | return trace
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/vue-code/src/server/create-basic-renderer.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { createWriteFunction } from './write'
4 | import { createRenderFunction } from './render'
5 | import type { RenderOptions } from './create-renderer'
6 |
7 | export function createBasicRenderer ({
8 | modules = [],
9 | directives = {},
10 | isUnaryTag = (() => false),
11 | cache
12 | }: RenderOptions = {}) {
13 | const render = createRenderFunction(modules, directives, isUnaryTag, cache)
14 |
15 | return function renderToString (
16 | component: Component,
17 | context: any,
18 | done: any
19 | ): void {
20 | if (typeof context === 'function') {
21 | done = context
22 | context = {}
23 | }
24 | let result = ''
25 | const write = createWriteFunction(text => {
26 | result += text
27 | return false
28 | }, done)
29 | try {
30 | render(component, write, context, () => {
31 | done(null, result)
32 | })
33 | } catch (e) {
34 | done(e)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/vue-code/src/server/optimizing-compiler/index.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | import { parse } from 'compiler/parser/index'
4 | import { generate } from './codegen'
5 | import { optimize } from './optimizer'
6 | import { createCompilerCreator } from 'compiler/create-compiler'
7 |
8 | export const createCompiler = createCompilerCreator(function baseCompile (
9 | template: string,
10 | options: CompilerOptions
11 | ): CompiledResult {
12 | const ast = parse(template.trim(), options)
13 | optimize(ast, options)
14 | const code = generate(ast, options)
15 | return {
16 | ast,
17 | render: code.render,
18 | staticRenderFns: code.staticRenderFns
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/vue-code/src/server/template-renderer/parse-template.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | const compile = require('lodash.template')
4 | const compileOptions = {
5 | escape: /{{([^{][\s\S]+?[^}])}}/g,
6 | interpolate: /{{{([\s\S]+?)}}}/g
7 | }
8 |
9 | export type ParsedTemplate = {
10 | head: (data: any) => string;
11 | neck: (data: any) => string;
12 | tail: (data: any) => string;
13 | };
14 |
15 | export function parseTemplate (
16 | template: string,
17 | contentPlaceholder?: string = ''
18 | ): ParsedTemplate {
19 | if (typeof template === 'object') {
20 | return template
21 | }
22 |
23 | let i = template.indexOf('')
24 | const j = template.indexOf(contentPlaceholder)
25 |
26 | if (j < 0) {
27 | throw new Error(`Content placeholder not found in template.`)
28 | }
29 |
30 | if (i < 0) {
31 | i = template.indexOf('')
32 | if (i < 0) {
33 | i = j
34 | }
35 | }
36 |
37 | return {
38 | head: compile(template.slice(0, i), compileOptions),
39 | neck: compile(template.slice(i, j), compileOptions),
40 | tail: compile(template.slice(j + contentPlaceholder.length), compileOptions)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/vue-code/src/server/util.js:
--------------------------------------------------------------------------------
1 | /* @flow */
2 |
3 | export const isJS = (file: string): boolean => /\.js(\?[^.]+)?$/.test(file)
4 |
5 | export const isCSS = (file: string): boolean => /\.css(\?[^.]+)?$/.test(file)
6 |
7 | export function createPromiseCallback () {
8 | let resolve, reject
9 | const promise: Promise = new Promise((_resolve, _reject) => {
10 | resolve = _resolve
11 | reject = _reject
12 | })
13 | const cb = (err: Error, res?: string) => {
14 | if (err) return reject(err)
15 | resolve(res || '')
16 | }
17 | return { promise, cb }
18 | }
19 |
--------------------------------------------------------------------------------
/vue-code/src/server/webpack-plugin/util.js:
--------------------------------------------------------------------------------
1 | const { red, yellow } = require('chalk')
2 |
3 | const prefix = `[vue-server-renderer-webpack-plugin]`
4 | const warn = exports.warn = msg => console.error(red(`${prefix} ${msg}\n`))
5 | const tip = exports.tip = msg => console.log(yellow(`${prefix} ${msg}\n`))
6 |
7 | export const validate = compiler => {
8 | if (compiler.options.target !== 'node') {
9 | warn('webpack config `target` should be "node".')
10 | }
11 |
12 | if (compiler.options.output && compiler.options.output.libraryTarget !== 'commonjs2') {
13 | warn('webpack config `output.libraryTarget` should be "commonjs2".')
14 | }
15 |
16 | if (!compiler.options.externals) {
17 | tip(
18 | 'It is recommended to externalize dependencies in the server build for ' +
19 | 'better build performance.'
20 | )
21 | }
22 | }
23 |
24 | export const onEmit = (compiler, name, hook) => {
25 | if (compiler.hooks) {
26 | // Webpack >= 4.0.0
27 | compiler.hooks.emit.tapAsync(name, hook)
28 | } else {
29 | // Webpack < 4.0.0
30 | compiler.plugin('emit', hook)
31 | }
32 | }
33 |
34 | export { isJS, isCSS } from '../util'
35 |
--------------------------------------------------------------------------------
/vue-code/src/shared/constants.js:
--------------------------------------------------------------------------------
1 | export const SSR_ATTR = 'data-server-rendered'
2 |
3 | export const ASSET_TYPES = [
4 | 'component',
5 | 'directive',
6 | 'filter'
7 | ]
8 |
9 | export const LIFECYCLE_HOOKS = [
10 | 'beforeCreate',
11 | 'created',
12 | 'beforeMount',
13 | 'mounted',
14 | 'beforeUpdate',
15 | 'updated',
16 | 'beforeDestroy',
17 | 'destroyed',
18 | 'activated',
19 | 'deactivated',
20 | 'errorCaptured'
21 | ]
22 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "indent": 0
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/runner.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const spawn = require('cross-spawn')
3 | const httpServer = require('http-server')
4 | const server = httpServer.createServer({
5 | root: path.resolve(__dirname, '../../')
6 | })
7 |
8 | server.listen(8080)
9 |
10 | let args = process.argv.slice(2)
11 | if (args.indexOf('--config') === -1) {
12 | args = args.concat(['--config', 'test/e2e/nightwatch.config.js'])
13 | }
14 | if (args.indexOf('--env') === -1) {
15 | args = args.concat(['--env', 'chrome,phantomjs'])
16 | }
17 | const i = args.indexOf('--test')
18 | if (i > -1) {
19 | args[i + 1] = 'test/e2e/specs/' + args[i + 1] + '.js'
20 | }
21 |
22 | const runner = spawn('./node_modules/.bin/nightwatch', args, {
23 | stdio: 'inherit'
24 | })
25 |
26 | runner.on('exit', function (code) {
27 | server.close()
28 | process.exit(code)
29 | })
30 |
31 | runner.on('error', function (err) {
32 | server.close()
33 | throw err
34 | })
35 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/async-edge-cases.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {{ num }}
14 |
15 |
16 |
17 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
35 |
36 | countA: {{countA}}
37 |
38 |
39 | countB: {{countB}}
40 |
41 |
42 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/async-edge-cases.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'async edge cases': function (browser) {
3 | browser
4 | .url('http://localhost:8080/test/e2e/specs/async-edge-cases.html')
5 | // #4510
6 | .assert.containsText('#case-1', '1')
7 | .assert.checked('#case-1 input', false)
8 |
9 | .click('#case-1 input')
10 | .assert.containsText('#case-1', '2')
11 | .assert.checked('#case-1 input', true)
12 |
13 | .click('#case-1 input')
14 | .assert.containsText('#case-1', '3')
15 | .assert.checked('#case-1 input', false)
16 |
17 | // #6566
18 | .assert.containsText('#case-2 button', 'Expand is True')
19 | .assert.containsText('.count-a', 'countA: 0')
20 | .assert.containsText('.count-b', 'countB: 0')
21 |
22 | .click('#case-2 button')
23 | .assert.containsText('#case-2 button', 'Expand is False')
24 | .assert.containsText('.count-a', 'countA: 1')
25 | .assert.containsText('.count-b', 'countB: 0')
26 |
27 | .click('#case-2 button')
28 | .assert.containsText('#case-2 button', 'Expand is True')
29 | .assert.containsText('.count-a', 'countA: 1')
30 | .assert.containsText('.count-b', 'countB: 1')
31 |
32 | .end()
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/basic-ssr.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | wtf
12 |
13 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/basic-ssr.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'basic SSR': function (browser) {
3 | browser
4 | .url('http://localhost:8080/test/e2e/specs/basic-ssr.html')
5 | .assert.containsText('#result', 'foo
')
6 | .end()
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/commits.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'commits': function (browser) {
3 | browser
4 | .url('http://localhost:8080/examples/commits/')
5 | .waitForElementVisible('li', 5000)
6 | .assert.count('input', 2)
7 | .assert.count('label', 2)
8 | .assert.containsText('label[for="master"]', 'master')
9 | .assert.containsText('label[for="dev"]', 'dev')
10 | .assert.checked('#master')
11 | .assert.checked('#dev', false)
12 | .assert.containsText('p', 'vuejs/vue@master')
13 | .assert.count('li', 3)
14 | .assert.count('li .commit', 3)
15 | .assert.count('li .message', 3)
16 | .click('#dev')
17 | .assert.containsText('p', 'vuejs/vue@dev')
18 | .assert.count('li', 3)
19 | .assert.count('li .commit', 3)
20 | .assert.count('li .message', 3)
21 | .end()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/markdown.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'markdown': function (browser) {
3 | browser
4 | .url('http://localhost:8080/examples/markdown/')
5 | .waitForElementVisible('#editor', 1000)
6 | .assert.value('textarea', '# hello')
7 | .assert.hasHTML('#editor div', 'hello
')
8 | .setValue('textarea', '\n## foo\n\n- bar\n- baz')
9 | // assert the output is not updated yet because of debounce
10 | .assert.hasHTML('#editor div', 'hello
')
11 | .waitFor(500)
12 | .assert.hasHTML('#editor div',
13 | 'hello
\n' +
14 | 'foo
\n' +
15 | ''
16 | )
17 | .end()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vue-code/test/e2e/specs/modal.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'modal': function (browser) {
3 | browser
4 | .url('http://localhost:8080/examples/modal/')
5 | .waitForElementVisible('#app', 1000)
6 | .assert.elementNotPresent('.modal-mask')
7 | .click('#show-modal')
8 | .assert.elementPresent('.modal-mask')
9 | .assert.elementPresent('.modal-wrapper')
10 | .assert.elementPresent('.modal-container')
11 | .waitFor(50)
12 | .assert.cssClassPresent('.modal-mask', 'modal-enter-active')
13 | .waitFor(300)
14 | .assert.cssClassNotPresent('.modal-mask', 'modal-enter-active')
15 | .assert.containsText('.modal-header h3', 'custom header')
16 | .assert.containsText('.modal-body', 'default body')
17 | .assert.containsText('.modal-footer', 'default footer')
18 | .click('.modal-default-button')
19 | // should have transition
20 | .assert.elementPresent('.modal-mask')
21 | .waitFor(50)
22 | .assert.cssClassPresent('.modal-mask', 'modal-leave-active')
23 | .waitFor(300)
24 | .assert.elementNotPresent('.modal-mask')
25 | .end()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/vue-code/test/helpers/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jasmine": true
4 | },
5 | "globals": {
6 | "waitForUpdate": true
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/vue-code/test/helpers/classlist.js:
--------------------------------------------------------------------------------
1 | beforeEach(() => {
2 | jasmine.addMatchers({
3 | // since classList may not be supported in all browsers
4 | toHaveClass: () => {
5 | return {
6 | compare: (el, cls) => {
7 | const pass = el.classList
8 | ? el.classList.contains(cls)
9 | : el.getAttribute('class').split(/\s+/g).indexOf(cls) > -1
10 | return {
11 | pass,
12 | message: `Expected element${pass ? ' ' : ' not '}to have class ${cls}`
13 | }
14 | }
15 | }
16 | }
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/vue-code/test/helpers/test-object-option.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | export default function testObjectOption (name) {
4 | it(`Options ${name}: should warn non object value`, () => {
5 | const options = {}
6 | options[name] = () => {}
7 | new Vue(options)
8 | expect(`Invalid value for option "${name}"`).toHaveBeenWarned()
9 | })
10 |
11 | it(`Options ${name}: should not warn valid object value`, () => {
12 | const options = {}
13 | options[name] = {}
14 | new Vue(options)
15 | expect(`Invalid value for option "${name}"`).not.toHaveBeenWarned()
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/vue-code/test/helpers/to-equal.js:
--------------------------------------------------------------------------------
1 | import { isEqual } from 'lodash'
2 |
3 | beforeEach(() => {
4 | jasmine.addMatchers({
5 | // override built-in toEqual because it behaves incorrectly
6 | // on Vue-observed arrays in Safari
7 | toEqual: () => {
8 | return {
9 | compare: (a, b) => {
10 | const pass = isEqual(a, b)
11 | return {
12 | pass,
13 | message: `Expected ${a} to equal ${b}`
14 | }
15 | }
16 | }
17 | }
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/vue-code/test/helpers/trigger-event.js:
--------------------------------------------------------------------------------
1 | window.triggerEvent = function triggerEvent (target, event, process) {
2 | const e = document.createEvent('HTMLEvents')
3 | e.initEvent(event, true, true)
4 | if (process) process(e)
5 | target.dispatchEvent(e)
6 | }
7 |
--------------------------------------------------------------------------------
/vue-code/test/helpers/vdom.js:
--------------------------------------------------------------------------------
1 | import VNode from 'core/vdom/vnode'
2 |
3 | window.createTextVNode = function (text) {
4 | return new VNode(undefined, undefined, undefined, text)
5 | }
6 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jasmine": true
4 | },
5 | "plugins": ["jasmine"],
6 | "rules": {
7 | "jasmine/no-focused-tests": 2
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/async-loader.js:
--------------------------------------------------------------------------------
1 | const hash = require('hash-sum')
2 |
3 | module.exports = function (code) {
4 | const id = hash(this.request) // simulating vue-loader module id injection
5 | return code.replace('__MODULE_ID__', id)
6 | }
7 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/compile-with-webpack.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import webpack from 'webpack'
3 | import MemoryFS from 'memory-fs'
4 |
5 | export function compileWithWebpack (file, extraConfig, cb) {
6 | const config = Object.assign({
7 | mode: 'development',
8 | entry: path.resolve(__dirname, 'fixtures', file),
9 | module: {
10 | rules: [
11 | {
12 | test: /\.js$/,
13 | loader: 'babel-loader'
14 | },
15 | {
16 | test: /async-.*\.js$/,
17 | loader: require.resolve('./async-loader')
18 | },
19 | {
20 | test: /\.(png|woff2|css)$/,
21 | loader: 'file-loader',
22 | options: {
23 | name: '[name].[ext]'
24 | }
25 | }
26 | ]
27 | }
28 | }, extraConfig)
29 |
30 | const compiler = webpack(config)
31 | const fs = new MemoryFS()
32 | compiler.outputFileSystem = fs
33 |
34 | compiler.run((err, stats) => {
35 | expect(err).toBeFalsy()
36 | expect(stats.errors).toBeFalsy()
37 | cb(fs)
38 | })
39 | }
40 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/app.js:
--------------------------------------------------------------------------------
1 | import Vue from '../../../dist/vue.runtime.common.js'
2 |
3 | export default context => {
4 | return new Promise(resolve => {
5 | context.msg = 'hello'
6 | resolve(new Vue({
7 | render (h) {
8 | return h('div', context.url)
9 | }
10 | }))
11 | })
12 | }
13 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/async-bar.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | beforeCreate () {
3 | this.$vnode.ssrContext._registeredComponents.add('__MODULE_ID__')
4 | },
5 | render (h) {
6 | return h('div', 'async bar')
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/async-foo.js:
--------------------------------------------------------------------------------
1 | // import image and font
2 | import './test.css'
3 | import font from './test.woff2'
4 | import image from './test.png'
5 |
6 | export default {
7 | beforeCreate () {
8 | this.$vnode.ssrContext._registeredComponents.add('__MODULE_ID__')
9 | },
10 | render (h) {
11 | return h('div', `async ${font} ${image}`)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/cache.js:
--------------------------------------------------------------------------------
1 | import Vue from '../../../dist/vue.runtime.common.js'
2 |
3 | const app = {
4 | name: 'app',
5 | props: ['id'],
6 | serverCacheKey: props => props.id,
7 | render (h) {
8 | return h('div', '/test')
9 | }
10 | }
11 |
12 | export default () => {
13 | return Promise.resolve(new Vue({
14 | render: h => h(app, { props: { id: 1 }})
15 | }))
16 | }
17 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/error.js:
--------------------------------------------------------------------------------
1 | throw new Error('foo')
2 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/nested-cache.js:
--------------------------------------------------------------------------------
1 | import Vue from '../../../dist/vue.runtime.common.js'
2 |
3 | function createRegisterFn (id) {
4 | return function (context) {
5 | context = context || this.$vnode.ssrContext
6 | context.registered.push(id)
7 | }
8 | }
9 |
10 | function addHooks (comp) {
11 | const hook = createRegisterFn(comp.name)
12 | return Object.assign(comp, {
13 | _ssrRegister: hook,
14 | beforeCreate: hook
15 | })
16 | }
17 |
18 | const grandchild = addHooks({
19 | name: 'grandchild',
20 | props: ['id'],
21 | serverCacheKey: props => props.id,
22 | render (h) {
23 | return h('div', '/test')
24 | }
25 | })
26 |
27 | const child = addHooks({
28 | name: 'child',
29 | props: ['id'],
30 | serverCacheKey: props => props.id,
31 | render (h) {
32 | return h(grandchild, { props: { id: this.id }})
33 | }
34 | })
35 |
36 | const app = addHooks({
37 | name: 'app',
38 | props: ['id'],
39 | serverCacheKey: props => props.id,
40 | render (h) {
41 | return h(child, { props: { id: this.id }})
42 | }
43 | })
44 |
45 | export default () => {
46 | return Promise.resolve(new Vue({
47 | render: h => h(app, { props: { id: 1 }})
48 | }))
49 | }
50 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/promise-rejection.js:
--------------------------------------------------------------------------------
1 | export default () => {
2 | return Promise.reject(new Error('foo'))
3 | }
4 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/split.js:
--------------------------------------------------------------------------------
1 | import Vue from '../../../dist/vue.runtime.common.js'
2 |
3 | // async component!
4 | const Foo = () => import('./async-foo')
5 | const Bar = () => import('./async-bar') // eslint-disable-line
6 |
7 | export default context => {
8 | return new Promise(resolve => {
9 | context.msg = 'hello'
10 | const vm = new Vue({
11 | render (h) {
12 | return h('div', [
13 | context.url,
14 | h(Foo)
15 | ])
16 | }
17 | })
18 |
19 | // simulate router.onReady
20 | Foo().then(comp => {
21 | // resolve now to make the render sync
22 | Foo.resolved = Vue.extend(comp.default)
23 | resolve(vm)
24 | })
25 | })
26 | }
27 |
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/test.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaoyiming0803/into-vue/089052fa4b569f309b89337762d2c3df9625dd10/vue-code/test/ssr/fixtures/test.css
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaoyiming0803/into-vue/089052fa4b569f309b89337762d2c3df9625dd10/vue-code/test/ssr/fixtures/test.png
--------------------------------------------------------------------------------
/vue-code/test/ssr/fixtures/test.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaoyiming0803/into-vue/089052fa4b569f309b89337762d2c3df9625dd10/vue-code/test/ssr/fixtures/test.woff2
--------------------------------------------------------------------------------
/vue-code/test/ssr/jasmine.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | spec_dir: 'test/ssr',
3 | spec_files: [
4 | '*.spec.js'
5 | ],
6 | helpers: [
7 | require.resolve('@babel/register')
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/vue-code/test/unit/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jasmine": true
4 | },
5 | "globals": {
6 | "waitForUpdate": true,
7 | "triggerEvent": true,
8 | "createTextVNode": true
9 | },
10 | "plugins": ["jasmine"],
11 | "rules": {
12 | "jasmine/no-focused-tests": 2,
13 | "no-unused-vars": 0
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/directives/cloak.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Directive v-cloak', () => {
4 | it('should be removed after compile', () => {
5 | const el = document.createElement('div')
6 | el.setAttribute('v-cloak', '')
7 | const vm = new Vue({ el })
8 | expect(vm.$el.hasAttribute('v-cloak')).toBe(false)
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/directives/model-file.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Directive v-model file', () => {
4 | it('warn to use @change instead', () => {
5 | new Vue({
6 | data: {
7 | file: ''
8 | },
9 | template: ''
10 | }).$mount()
11 | expect('Use a v-on:change listener instead').toHaveBeenWarned()
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/directives/model-parse.spec.js:
--------------------------------------------------------------------------------
1 | import { parseModel } from 'compiler/directives/model'
2 |
3 | describe('model expression parser', () => {
4 | it('parse single path', () => {
5 | const res = parseModel('foo')
6 | expect(res.exp).toBe('foo')
7 | expect(res.key).toBe(null)
8 | })
9 |
10 | it('parse object dot notation', () => {
11 | const res = parseModel('a.b.c')
12 | expect(res.exp).toBe('a.b')
13 | expect(res.key).toBe('"c"')
14 | })
15 |
16 | it('parse string in brackets', () => {
17 | const res = parseModel('a["b"][c]')
18 | expect(res.exp).toBe('a["b"]')
19 | expect(res.key).toBe('c')
20 | })
21 |
22 | it('parse brackets with object dot notation', () => {
23 | const res = parseModel('a["b"][c].xxx')
24 | expect(res.exp).toBe('a["b"][c]')
25 | expect(res.key).toBe('"xxx"')
26 | })
27 |
28 | it('parse nested brackets', () => {
29 | const res = parseModel('a[i[c]]')
30 | expect(res.exp).toBe('a')
31 | expect(res.key).toBe('i[c]')
32 | })
33 |
34 | it('combined', () => {
35 | const res = parseModel('test.xxx.a["asa"][test1[key]]')
36 | expect(res.exp).toBe('test.xxx.a["asa"]')
37 | expect(res.key).toBe('test1[key]')
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/directives/pre.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Directive v-pre', function () {
4 | it('should not compile inner content', function () {
5 | const vm = new Vue({
6 | template: `
7 |
{{ a }}
8 |
{{ a }}
9 |
10 |
11 |
12 |
`,
13 | data: {
14 | a: 123
15 | }
16 | })
17 | vm.$mount()
18 | expect(vm.$el.firstChild.textContent).toBe('{{ a }}')
19 | expect(vm.$el.children[1].textContent).toBe('123')
20 | expect(vm.$el.lastChild.innerHTML).toBe('')
21 | })
22 |
23 | it('should not compile on root node', function () {
24 | const vm = new Vue({
25 | template: '{{ a }}
',
26 | replace: true,
27 | data: {
28 | a: 123
29 | }
30 | })
31 | vm.$mount()
32 | expect(vm.$el.firstChild.textContent).toBe('{{ a }}')
33 | })
34 |
35 | // #8286
36 | it('should not compile custom component tags', function () {
37 | Vue.component('vtest', { template: ` Hello World
` })
38 | const vm = new Vue({
39 | template: '
',
40 | replace: true
41 | })
42 | vm.$mount()
43 | expect(vm.$el.firstChild.tagName).toBe('VTEST')
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/global-api/compile.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Global API: compile', () => {
4 | it('should compile render functions', () => {
5 | const res = Vue.compile('{{ msg }}
')
6 | const vm = new Vue({
7 | data: {
8 | msg: 'hello'
9 | },
10 | render: res.render,
11 | staticRenderFns: res.staticRenderFns
12 | }).$mount()
13 | expect(vm.$el.innerHTML).toContain('hello')
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/instance/init.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Initialization', () => {
4 | it('without new', () => {
5 | try { Vue() } catch (e) {}
6 | expect('Vue is a constructor and should be called with the `new` keyword').toHaveBeenWarned()
7 | })
8 |
9 | it('with new', () => {
10 | expect(new Vue() instanceof Vue).toBe(true)
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/comments.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Comments', () => {
4 | it('comments should be kept', () => {
5 | const vm = new Vue({
6 | comments: true,
7 | data () {
8 | return {
9 | foo: 1
10 | }
11 | },
12 | template: 'node1{{foo}}
'
13 | }).$mount()
14 | expect(vm.$el.innerHTML).toEqual('node11')
15 | })
16 | })
17 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/inheritAttrs.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Options inheritAttrs', () => {
4 | it('should work', done => {
5 | const vm = new Vue({
6 | template: ``,
7 | data: { foo: 'foo' },
8 | components: {
9 | foo: {
10 | inheritAttrs: false,
11 | template: `foo
`
12 | }
13 | }
14 | }).$mount()
15 | expect(vm.$el.id).toBe('')
16 | vm.foo = 'bar'
17 | waitForUpdate(() => {
18 | expect(vm.$el.id).toBe('')
19 | }).then(done)
20 | })
21 |
22 | it('with inner v-bind', done => {
23 | const vm = new Vue({
24 | template: ``,
25 | data: { foo: 'foo' },
26 | components: {
27 | foo: {
28 | inheritAttrs: false,
29 | template: ``
30 | }
31 | }
32 | }).$mount()
33 | expect(vm.$el.children[0].id).toBe('foo')
34 | vm.foo = 'bar'
35 | waitForUpdate(() => {
36 | expect(vm.$el.children[0].id).toBe('bar')
37 | }).then(done)
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/methods.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import testObjectOption from '../../../helpers/test-object-option'
3 |
4 | describe('Options methods', () => {
5 | testObjectOption('methods')
6 |
7 | it('should have correct context', () => {
8 | const vm = new Vue({
9 | data: {
10 | a: 1
11 | },
12 | methods: {
13 | plus () {
14 | this.a++
15 | }
16 | }
17 | })
18 | vm.plus()
19 | expect(vm.a).toBe(2)
20 | })
21 |
22 | it('should warn methods of not function type', () => {
23 | new Vue({
24 | methods: {
25 | hello: {}
26 | }
27 | })
28 | expect('Method "hello" has type "object" in the component definition').toHaveBeenWarned()
29 | })
30 |
31 | it('should warn methods conflicting with data', () => {
32 | new Vue({
33 | data: {
34 | foo: 1
35 | },
36 | methods: {
37 | foo () {}
38 | }
39 | })
40 | expect(`Method "foo" has already been defined as a data property`).toHaveBeenWarned()
41 | })
42 |
43 | it('should warn methods conflicting with internal methods', () => {
44 | new Vue({
45 | methods: {
46 | _update () {}
47 | }
48 | })
49 | expect(`Method "_update" conflicts with an existing Vue instance method`).toHaveBeenWarned()
50 | })
51 | })
52 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/name.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Options name', () => {
4 | it('should contain itself in self components', () => {
5 | const vm = Vue.extend({
6 | name: 'SuperVue'
7 | })
8 |
9 | expect(vm.options.components['SuperVue']).toEqual(vm)
10 | })
11 |
12 | it('should warn when incorrect name given', () => {
13 | Vue.extend({
14 | name: 'Hyper*Vue'
15 | })
16 |
17 | /* eslint-disable */
18 | expect(`Invalid component name: "Hyper*Vue". Component names can only contain alphanumeric characters and the hyphen, and must start with a letter.`)
19 | .toHaveBeenWarned()
20 | /* eslint-enable */
21 |
22 | Vue.extend({
23 | name: '2Cool2BValid'
24 | })
25 |
26 | /* eslint-disable */
27 | expect(`Invalid component name: "2Cool2BValid". Component names can only contain alphanumeric characters and the hyphen, and must start with a letter.`)
28 | .toHaveBeenWarned()
29 | /* eslint-enable */
30 | })
31 |
32 | it('id should not override given name when using Vue.component', () => {
33 | const SuperComponent = Vue.component('super-component', {
34 | name: 'SuperVue'
35 | })
36 |
37 | expect(SuperComponent.options.components['SuperVue']).toEqual(SuperComponent)
38 | expect(SuperComponent.options.components['super-component']).toEqual(SuperComponent)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/parent.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Options parent', () => {
4 | it('should work', () => {
5 | const parent = new Vue({
6 | render () {}
7 | }).$mount()
8 |
9 | const child = new Vue({
10 | parent: parent,
11 | render () {}
12 | }).$mount()
13 |
14 | // this option is straight-forward
15 | // it should register 'parent' as a $parent for 'child'
16 | // and push 'child' to $children array on 'parent'
17 | expect(child.$options.parent).toBeDefined()
18 | expect(child.$options.parent).toEqual(parent)
19 | expect(child.$parent).toBeDefined()
20 | expect(child.$parent).toEqual(parent)
21 | expect(parent.$children).toContain(child)
22 |
23 | // destroy 'child' and check if it was removed from 'parent' $children
24 | child.$destroy()
25 | expect(parent.$children.length).toEqual(0)
26 | parent.$destroy()
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/propsData.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Options propsData', () => {
4 | it('should work', done => {
5 | const A = Vue.extend({
6 | props: ['a'],
7 | template: '{{ a }}
'
8 | })
9 | const vm = new A({
10 | propsData: {
11 | a: 123
12 | }
13 | }).$mount()
14 | expect(vm.a).toBe(123)
15 | expect(vm.$el.textContent).toBe('123')
16 | vm.a = 234
17 | waitForUpdate(() => {
18 | expect(vm.$el.textContent).toBe('234')
19 | }).then(done)
20 | })
21 |
22 | it('warn non instantiation usage', () => {
23 | Vue.extend({
24 | propsData: {
25 | a: 123
26 | }
27 | })
28 | expect('option "propsData" can only be used during instance creation').toHaveBeenWarned()
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/render.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Options render', () => {
4 | it('basic usage', () => {
5 | const vm = new Vue({
6 | render (h) {
7 | const children = []
8 | for (let i = 0; i < this.items.length; i++) {
9 | children.push(h('li', { staticClass: 'task' }, [this.items[i].name]))
10 | }
11 | return h('ul', { staticClass: 'tasks' }, children)
12 | },
13 | data: {
14 | items: [{ id: 1, name: 'task1' }, { id: 2, name: 'task2' }]
15 | }
16 | }).$mount()
17 | expect(vm.$el.tagName).toBe('UL')
18 | for (let i = 0; i < vm.$el.children.length; i++) {
19 | const li = vm.$el.children[i]
20 | expect(li.tagName).toBe('LI')
21 | expect(li.textContent).toBe(vm.items[i].name)
22 | }
23 | })
24 |
25 | it('allow null data', () => {
26 | const vm = new Vue({
27 | render (h) {
28 | return h('div', null, 'hello' /* string as children*/)
29 | }
30 | }).$mount()
31 | expect(vm.$el.tagName).toBe('DIV')
32 | expect(vm.$el.textContent).toBe('hello')
33 | })
34 |
35 | it('should warn non `render` option and non `template` option', () => {
36 | new Vue().$mount()
37 | expect('Failed to mount component: template or render function not defined.').toHaveBeenWarned()
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/vue-code/test/unit/features/options/renderError.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | describe('Options renderError', () => {
4 | it('should be used on render errors', done => {
5 | Vue.config.errorHandler = () => {}
6 | const vm = new Vue({
7 | data: {
8 | ok: true
9 | },
10 | render (h) {
11 | if (this.ok) {
12 | return h('div', 'ok')
13 | } else {
14 | throw new Error('no')
15 | }
16 | },
17 | renderError (h, err) {
18 | return h('div', err.toString())
19 | }
20 | }).$mount()
21 | expect(vm.$el.textContent).toBe('ok')
22 | vm.ok = false
23 | waitForUpdate(() => {
24 | expect(vm.$el.textContent).toBe('Error: no')
25 | Vue.config.errorHandler = null
26 | }).then(done)
27 | })
28 |
29 | it('should pass on errors in renderError to global handler', () => {
30 | const spy = Vue.config.errorHandler = jasmine.createSpy()
31 | const err = new Error('renderError')
32 | const vm = new Vue({
33 | render () {
34 | throw new Error('render')
35 | },
36 | renderError () {
37 | throw err
38 | }
39 | }).$mount()
40 | expect(spy).toHaveBeenCalledWith(err, vm, 'renderError')
41 | })
42 | })
43 |
--------------------------------------------------------------------------------
/vue-code/test/unit/index.js:
--------------------------------------------------------------------------------
1 | require('es6-promise/auto')
2 |
3 | // import all helpers
4 | const helpersContext = require.context('../helpers', true)
5 | helpersContext.keys().forEach(helpersContext)
6 |
7 | // require all test files
8 | const testsContext = require.context('./', true, /\.spec$/)
9 | testsContext.keys().forEach(testsContext)
10 |
--------------------------------------------------------------------------------
/vue-code/test/unit/karma.base.config.js:
--------------------------------------------------------------------------------
1 | const alias = require('../../scripts/alias')
2 | const webpack = require('webpack')
3 |
4 | const webpackConfig = {
5 | mode: 'development',
6 | resolve: {
7 | alias: alias
8 | },
9 | module: {
10 | rules: [
11 | {
12 | test: /\.js$/,
13 | loader: 'babel-loader',
14 | exclude: /node_modules/
15 | }
16 | ]
17 | },
18 | plugins: [
19 | new webpack.DefinePlugin({
20 | __WEEX__: false,
21 | 'process.env': {
22 | TRANSITION_DURATION: process.env.CI ? 100 : 50,
23 | TRANSITION_BUFFER: 10
24 | }
25 | })
26 | ],
27 | devtool: '#inline-source-map'
28 | }
29 |
30 | // shared config for all unit tests
31 | module.exports = {
32 | frameworks: ['jasmine'],
33 | files: [
34 | './index.js'
35 | ],
36 | preprocessors: {
37 | './index.js': ['webpack', 'sourcemap']
38 | },
39 | webpack: webpackConfig,
40 | webpackMiddleware: {
41 | noInfo: true
42 | },
43 | plugins: [
44 | 'karma-jasmine',
45 | 'karma-mocha-reporter',
46 | 'karma-sourcemap-loader',
47 | 'karma-webpack'
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/vue-code/test/unit/karma.cover.config.js:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.config.js')
2 |
3 | module.exports = function (config) {
4 | const options = Object.assign(base, {
5 | browsers: ['PhantomJS'],
6 | reporters: ['mocha', 'coverage'],
7 | coverageReporter: {
8 | reporters: [
9 | { type: 'lcov', dir: '../../coverage', subdir: '.' },
10 | { type: 'text-summary', dir: '../../coverage', subdir: '.' }
11 | ]
12 | },
13 | singleRun: true,
14 | plugins: base.plugins.concat([
15 | 'karma-coverage',
16 | 'karma-phantomjs-launcher'
17 | ])
18 | })
19 |
20 | // add babel-plugin-istanbul for code instrumentation
21 | options.webpack.module.rules[0].options = {
22 | plugins: [['istanbul', {
23 | exclude: [
24 | 'test/',
25 | 'src/compiler/parser/html-parser.js',
26 | 'src/core/instance/proxy.js',
27 | 'src/sfc/deindent.js',
28 | 'src/platforms/weex/'
29 | ]
30 | }]]
31 | }
32 |
33 | config.set(options)
34 | }
35 |
--------------------------------------------------------------------------------
/vue-code/test/unit/karma.dev.config.js:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.config.js')
2 |
3 | module.exports = function (config) {
4 | config.set(Object.assign(base, {
5 | browsers: ['PhantomJS'],
6 | reporters: ['progress'],
7 | plugins: base.plugins.concat([
8 | 'karma-phantomjs-launcher'
9 | ])
10 | }))
11 | }
12 |
--------------------------------------------------------------------------------
/vue-code/test/unit/karma.unit.config.js:
--------------------------------------------------------------------------------
1 | const base = require('./karma.base.config.js')
2 |
3 | module.exports = function (config) {
4 | config.set(Object.assign(base, {
5 | browsers: ['Chrome', 'Firefox', 'Safari'],
6 | reporters: ['progress'],
7 | singleRun: true,
8 | plugins: base.plugins.concat([
9 | 'karma-chrome-launcher',
10 | 'karma-firefox-launcher',
11 | 'karma-safari-launcher'
12 | ])
13 | }))
14 | }
15 |
--------------------------------------------------------------------------------
/vue-code/test/unit/modules/server-compiler/optimizer.spec.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhaoyiming0803/into-vue/089052fa4b569f309b89337762d2c3df9625dd10/vue-code/test/unit/modules/server-compiler/optimizer.spec.js
--------------------------------------------------------------------------------
/vue-code/test/unit/modules/util/next-tick.spec.js:
--------------------------------------------------------------------------------
1 | import { nextTick } from 'core/util/next-tick'
2 |
3 | describe('nextTick', () => {
4 | it('accepts a callback', done => {
5 | nextTick(done)
6 | })
7 |
8 | it('returns undefined when passed a callback', () => {
9 | expect(nextTick(() => {})).toBeUndefined()
10 | })
11 |
12 | if (typeof Promise !== 'undefined') {
13 | it('returns a Promise when provided no callback', done => {
14 | nextTick().then(done)
15 | })
16 |
17 | it('returns a Promise with a context argument when provided a falsy callback and an object', done => {
18 | const obj = {}
19 | nextTick(undefined, obj).then(ctx => {
20 | expect(ctx).toBe(obj)
21 | done()
22 | })
23 | })
24 |
25 | it('returned Promise should resolve correctly vs callback', done => {
26 | const spy = jasmine.createSpy()
27 | nextTick(spy)
28 | nextTick().then(() => {
29 | expect(spy).toHaveBeenCalled()
30 | done()
31 | })
32 | })
33 | }
34 | })
35 |
--------------------------------------------------------------------------------
/vue-code/test/unit/modules/vdom/modules/directive.spec.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import { patch } from 'web/runtime/patch'
3 | import VNode from 'core/vdom/vnode'
4 |
5 | describe('vdom directive module', () => {
6 | it('should work', () => {
7 | const directive1 = {
8 | bind: jasmine.createSpy('bind'),
9 | update: jasmine.createSpy('update'),
10 | unbind: jasmine.createSpy('unbind')
11 | }
12 | const vm = new Vue({ directives: { directive1 }})
13 | // create
14 | const vnode1 = new VNode('div', {}, [
15 | new VNode('p', {
16 | directives: [{
17 | name: 'directive1', value: 'hello', arg: 'arg1', modifiers: { modifier1: true }
18 | }]
19 | }, undefined, 'hello world', undefined, vm)
20 | ])
21 | patch(null, vnode1)
22 | expect(directive1.bind).toHaveBeenCalled()
23 | // update
24 | const vnode2 = new VNode('div', {}, [
25 | new VNode('p', {
26 | directives: [{
27 | name: 'directive1', value: 'world', arg: 'arg1', modifiers: { modifier1: true }
28 | }]
29 | }, undefined, 'hello world', undefined, vm)
30 | ])
31 | patch(vnode1, vnode2)
32 | expect(directive1.update).toHaveBeenCalled()
33 | // destroy
34 | const vnode3 = new VNode('div')
35 | patch(vnode2, vnode3)
36 | expect(directive1.unbind).toHaveBeenCalled()
37 | })
38 | })
39 |
--------------------------------------------------------------------------------
/vue-code/test/unit/modules/vdom/modules/style.spec.js:
--------------------------------------------------------------------------------
1 | import { patch } from 'web/runtime/patch'
2 | import VNode from 'core/vdom/vnode'
3 |
4 | describe('vdom style module', () => {
5 | it('should create an element with style', () => {
6 | const vnode = new VNode('p', { style: { fontSize: '12px' }})
7 | const elm = patch(null, vnode)
8 | expect(elm.style.fontSize).toBe('12px')
9 | })
10 |
11 | it('should create an element with array style', () => {
12 | const vnode = new VNode('p', { style: [{ fontSize: '12px' }, { color: 'red' }] })
13 | const elm = patch(null, vnode)
14 | expect(elm.style.fontSize).toBe('12px')
15 | expect(elm.style.color).toBe('red')
16 | })
17 |
18 | it('should change elements style', () => {
19 | const vnode1 = new VNode('p', { style: { fontSize: '12px' }})
20 | const vnode2 = new VNode('p', { style: { fontSize: '10px', display: 'block' }})
21 | patch(null, vnode1)
22 | const elm = patch(vnode1, vnode2)
23 | expect(elm.style.fontSize).toBe('10px')
24 | expect(elm.style.display).toBe('block')
25 | })
26 |
27 | it('should remove elements attrs', () => {
28 | const vnode1 = new VNode('p', { style: { fontSize: '12px' }})
29 | const vnode2 = new VNode('p', { style: { display: 'block' }})
30 | patch(null, vnode1)
31 | const elm = patch(vnode1, vnode2)
32 | expect(elm.style.fontSize).toBe('')
33 | expect(elm.style.display).toBe('block')
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/vue-code/test/weex/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jasmine": true
4 | },
5 | "plugins": ["jasmine"],
6 | "rules": {
7 | "jasmine/no-focused-tests": 2
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/event/click.after.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'div',
3 | event: ['click'],
4 | children: [{
5 | type: 'text',
6 | attr: {
7 | value: '43'
8 | }
9 | }]
10 | })
11 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/event/click.before.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'div',
3 | event: ['click'],
4 | children: [{
5 | type: 'text',
6 | attr: {
7 | value: '42'
8 | }
9 | }]
10 | })
11 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/event/click.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{count}}
4 |
5 |
6 |
7 |
21 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/attrs.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A', count: 1, source: 'http://whatever.com/x.png' },
7 | { type: 'A', count: 2, source: 'http://whatever.com/y.png' },
8 | { type: 'A', count: 3, source: 'http://whatever.com/z.png' }
9 | ],
10 | switch: 'type',
11 | alias: 'item'
12 | },
13 | children: [{
14 | type: 'cell-slot',
15 | attr: { append: 'tree', case: 'A' },
16 | children: [{
17 | type: 'image',
18 | attr: {
19 | resize: 'cover',
20 | src: {
21 | '@binding': 'item.source'
22 | }
23 | }
24 | }, {
25 | type: 'text',
26 | attr: {
27 | lines: '3',
28 | count: {
29 | '@binding': 'item.count'
30 | }
31 | }
32 | }]
33 | }]
34 | })
35 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/attrs.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/classname.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A', color: 'red' },
7 | { type: 'A', color: 'blue' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | style: {
16 | backgroundColor: '#FF6600'
17 | },
18 | children: [{
19 | type: 'text',
20 | attr: {
21 | // not supported yet
22 | // classList: ['text', { '@binding': 'item.color' }],
23 | value: 'content'
24 | }
25 | }]
26 | }]
27 | })
28 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/classname.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | content
5 |
6 |
7 |
8 |
9 |
24 |
25 |
37 |
38 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/banner.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | BANNER
4 |
5 |
6 |
7 |
20 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/counter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{count}}
4 | +
5 |
6 |
7 |
8 |
23 |
24 |
37 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{output}}
4 |
5 |
6 |
7 |
8 |
18 |
19 |
32 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
19 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/lifecycle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{number}}
4 |
5 |
6 |
7 |
40 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/poster.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{title}}
5 |
6 |
7 |
8 |
22 |
23 |
34 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateful-lifecycle.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'X' },
7 | { type: 'X' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'X' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '@isComponentRoot': true,
19 | '@componentProps': {}
20 | },
21 | children: [{
22 | type: 'text',
23 | attr: {
24 | value: { '@binding': 'number' }
25 | }
26 | }]
27 | }]
28 | }]
29 | })
30 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateful-lifecycle.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateful-v-model.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '@isComponentRoot': true,
19 | '@componentProps': {
20 | message: 'No binding'
21 | }
22 | },
23 | children: [{
24 | type: 'text',
25 | classList: ['output'],
26 | attr: {
27 | value: { '@binding': 'output' }
28 | }
29 | }, {
30 | type: 'input',
31 | event: ['input'],
32 | classList: ['input'],
33 | attr: {
34 | type: 'text',
35 | value: 'No binding'
36 | }
37 | }]
38 | }]
39 | }]
40 | })
41 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateful-v-model.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateful.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A', number: 24 },
7 | { type: 'A', number: 42 }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '@isComponentRoot': true,
19 | '@componentProps': {
20 | start: { '@binding': 'item.number' }
21 | }
22 | },
23 | children: [{
24 | type: 'text',
25 | classList: ['output'],
26 | attr: {
27 | value: { '@binding': 'count' } // need confirm
28 | }
29 | }, {
30 | type: 'text',
31 | event: ['click'],
32 | classList: ['button'],
33 | attr: { value: '+' }
34 | }]
35 | }, {
36 | type: 'text',
37 | attr: { value: 'other' }
38 | }]
39 | }]
40 | })
41 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateful.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | other
6 |
7 |
8 |
9 |
10 |
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateless-multi-components.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ----
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
31 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateless-with-props.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A', poster: 'xx', title: 'x' },
7 | { type: 'A', poster: 'yy', title: 'y' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '@isComponentRoot': true,
19 | '@componentProps': {
20 | imageUrl: { '@binding': 'item.poster' },
21 | title: { '@binding': 'item.title' }
22 | }
23 | },
24 | children: [{
25 | type: 'image',
26 | classList: ['image'],
27 | attr: {
28 | src: { '@binding': 'imageUrl' }
29 | }
30 | }, {
31 | type: 'text',
32 | classList: ['title'],
33 | attr: {
34 | value: { '@binding': 'title' }
35 | }
36 | }]
37 | }, {
38 | type: 'text',
39 | attr: {
40 | value: 'content'
41 | }
42 | }]
43 | }]
44 | })
45 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateless-with-props.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | content
6 |
7 |
8 |
9 |
10 |
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateless.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '@isComponentRoot': true,
19 | '@componentProps': {}
20 | },
21 | classList: ['banner'],
22 | children: [{
23 | type: 'text',
24 | classList: ['title'],
25 | attr: {
26 | value: 'BANNER'
27 | }
28 | }]
29 | }, {
30 | type: 'text',
31 | attr: {
32 | value: 'content'
33 | }
34 | }]
35 | }]
36 | })
37 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/components/stateless.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | content
6 |
7 |
8 |
9 |
10 |
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/inline-style.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A', color: '#606060' },
7 | { type: 'A', color: '#E5E5E5' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | style: {
16 | backgroundColor: '#FF6600'
17 | },
18 | children: [{
19 | type: 'text',
20 | style: {
21 | fontSize: '100px',
22 | color: { '@binding': 'item.color' }
23 | },
24 | attr: {
25 | value: 'content'
26 | }
27 | }]
28 | }]
29 | })
30 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/inline-style.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | content
5 |
6 |
7 |
8 |
9 |
21 |
22 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/text-node.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A', dynamic: 'decimal', two: '2', four: '4' },
7 | { type: 'A', dynamic: 'binary', two: '10', four: '100' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'text',
17 | attr: {
18 | value: 'static'
19 | }
20 | }, {
21 | type: 'text',
22 | attr: {
23 | value: { '@binding': 'item.dynamic' }
24 | }
25 | }, {
26 | type: 'text',
27 | attr: {
28 | value: [
29 | 'one ',
30 | { '@binding': 'item.two' },
31 | ' three ',
32 | { '@binding': 'item.four' },
33 | ' five'
34 | ]
35 | }
36 | }]
37 | }]
38 | })
39 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/text-node.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | static
5 | {{item.dynamic}}
6 | one {{item.two}} three {{ item.four }} five
7 |
8 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-else-if.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'image',
17 | attr: {
18 | '[[match]]': 'item.sourceA',
19 | src: { '@binding': 'item.sourceA' }
20 | }
21 | }, {
22 | type: 'image',
23 | attr: {
24 | '[[match]]': '!(item.sourceA) && (item.sourceB)',
25 | src: { '@binding': 'item.sourceB' }
26 | }
27 | }, {
28 | type: 'image',
29 | attr: {
30 | '[[match]]': '!(item.sourceA || item.sourceB)',
31 | src: { '@binding': 'item.placeholder' }
32 | }
33 | }]
34 | }]
35 | })
36 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-else-if.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-else.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'image',
17 | attr: {
18 | '[[match]]': 'item.source',
19 | src: { '@binding': 'item.source' }
20 | }
21 | }, {
22 | type: 'image',
23 | attr: {
24 | '[[match]]': '!(item.source)',
25 | src: { '@binding': 'item.placeholder' }
26 | }
27 | }]
28 | }]
29 | })
30 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-else.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
22 |
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-for-iterator.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '[[repeat]]': {
19 | '@expression': 'item.list',
20 | '@index': 'index',
21 | '@alias': 'object'
22 | }
23 | },
24 | children: [{
25 | type: 'text',
26 | attr: {
27 | value: {
28 | '@binding': 'object.name'
29 | }
30 | }
31 | }, {
32 | type: 'text',
33 | attr: {
34 | '[[repeat]]': {
35 | '@expression': 'object',
36 | '@alias': 'v',
37 | '@key': 'k',
38 | '@index': 'i'
39 | },
40 | value: {
41 | '@binding': 'v'
42 | }
43 | }
44 | }]
45 | }]
46 | }]
47 | })
48 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-for-iterator.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{object.name}}
6 | {{v}}
7 |
8 |
9 |
10 |
11 |
12 |
24 |
25 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-for.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'div',
17 | attr: {
18 | '[[repeat]]': {
19 | '@expression': 'item.list',
20 | '@alias': 'panel'
21 | }
22 | },
23 | children: [{
24 | type: 'text',
25 | attr: {
26 | value: {
27 | '@binding': 'panel.label'
28 | }
29 | }
30 | }]
31 | }]
32 | }]
33 | })
34 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-for.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{panel.label}}
6 |
7 |
8 |
9 |
10 |
11 |
23 |
24 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-if.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'image',
17 | attr: {
18 | '[[match]]': 'item.source',
19 | src: { '@binding': 'item.source' }
20 | }
21 | }, {
22 | type: 'text',
23 | attr: {
24 | '[[match]]': '!item.source',
25 | value: 'Title'
26 | }
27 | }]
28 | }]
29 | })
30 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-if.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 |
22 |
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-on-inline.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'text',
17 | event: ['click', {
18 | type: 'longpress',
19 | params: [{ '@binding': 'item.key' }]
20 | }]
21 | }, {
22 | type: 'text',
23 | event: [{
24 | type: 'appear',
25 | params: [
26 | { '@binding': 'item.index' },
27 | { '@binding': 'item.type' }
28 | ]
29 | }],
30 | attr: { value: 'Button' }
31 | }, {
32 | type: 'text',
33 | event: [{ type: 'disappear' }],
34 | attr: { value: 'Tips' }
35 | }]
36 | }]
37 | })
38 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-on-inline.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Button
6 | Tips
7 |
8 |
9 |
10 |
11 |
28 |
29 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-on.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | switch: 'type',
10 | alias: 'item'
11 | },
12 | children: [{
13 | type: 'cell-slot',
14 | attr: { append: 'tree', case: 'A' },
15 | children: [{
16 | type: 'text',
17 | event: ['click', 'longpress'],
18 | attr: { value: 'A' }
19 | }, {
20 | type: 'text',
21 | event: ['touchend'],
22 | attr: { value: 'B' }
23 | }]
24 | }]
25 | })
26 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-on.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | A
5 | B
6 |
7 |
8 |
9 |
10 |
26 |
27 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-once.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'recycle-list',
3 | attr: {
4 | append: 'tree',
5 | listData: [
6 | { type: 'A' },
7 | { type: 'A' }
8 | ],
9 | alias: 'item'
10 | },
11 | children: [{
12 | type: 'cell-slot',
13 | attr: { append: 'tree' },
14 | children: [{
15 | type: 'text',
16 | attr: {
17 | '[[once]]': true,
18 | value: { '@binding': 'item.type' }
19 | }
20 | }]
21 | }]
22 | })
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/recycle-list/v-once.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{item.type}}
5 |
6 |
7 |
8 |
9 |
21 |
22 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/render/class.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'div',
3 | children: [{
4 | type: 'div',
5 | classList: ['box', 'box1']
6 | }, {
7 | type: 'div',
8 | classList: ['box', 'box2']
9 | }, {
10 | type: 'div',
11 | classList: ['box', 'box3']
12 | }, {
13 | type: 'div',
14 | classList: ['box', 'box4']
15 | }, {
16 | type: 'div',
17 | classList: ['box', 'box5']
18 | }]
19 | })
20 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/render/class.vue:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
37 |
38 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/render/sample.vdom.js:
--------------------------------------------------------------------------------
1 | ({
2 | type: 'div',
3 | style: {
4 | justifyContent: 'center'
5 | },
6 | children: [{
7 | type: 'text',
8 | attr: {
9 | value: 'Yo'
10 | },
11 | classList: ['freestyle']
12 | }]
13 | })
14 |
--------------------------------------------------------------------------------
/vue-code/test/weex/cases/render/sample.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{string}}
4 |
5 |
6 |
7 |
14 |
15 |
24 |
--------------------------------------------------------------------------------
/vue-code/test/weex/compiler/props.spec.js:
--------------------------------------------------------------------------------
1 | import { compile } from '../../../packages/weex-template-compiler'
2 | import { strToRegExp } from '../helpers/index'
3 |
4 | describe('compile props', () => {
5 | it('custom props', () => {
6 | const { render, staticRenderFns, errors } = compile(``)
7 | expect(render).not.toBeUndefined()
8 | expect(staticRenderFns).not.toBeUndefined()
9 | expect(staticRenderFns.length).toEqual(0)
10 | expect(render).toMatch(strToRegExp(`attrs:{"custom":"whatever"}`))
11 | expect(errors).toEqual([])
12 | })
13 |
14 | it('camelize props', () => {
15 | const { render, staticRenderFns, errors } = compile(``)
16 | expect(render).not.toBeUndefined()
17 | expect(staticRenderFns).not.toBeUndefined()
18 | expect(staticRenderFns.length).toEqual(0)
19 | expect(render).toMatch(strToRegExp(`attrs:{"kebabCase":"whatever"}`))
20 | expect(errors).toEqual([])
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/vue-code/test/weex/jasmine.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | spec_dir: 'test/weex',
3 | spec_files: [
4 | '**/*[sS]pec.js'
5 | ],
6 | helpers: [
7 | require.resolve('@babel/register')
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/vue-code/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue } from "./vue";
2 |
3 | export default Vue;
4 |
5 | export as namespace Vue;
6 |
7 | export {
8 | CreateElement,
9 | VueConstructor
10 | } from "./vue";
11 |
12 | export {
13 | Component,
14 | AsyncComponent,
15 | ComponentOptions,
16 | FunctionalComponentOptions,
17 | RenderContext,
18 | PropOptions,
19 | ComputedOptions,
20 | WatchHandler,
21 | WatchOptions,
22 | WatchOptionsWithHandler,
23 | DirectiveFunction,
24 | DirectiveOptions
25 | } from "./options";
26 |
27 | export {
28 | PluginFunction,
29 | PluginObject
30 | } from "./plugin";
31 |
32 | export {
33 | VNodeChildren,
34 | VNodeChildrenArrayContents,
35 | VNode,
36 | VNodeComponentOptions,
37 | VNodeData,
38 | VNodeDirective
39 | } from "./vnode";
40 |
--------------------------------------------------------------------------------
/vue-code/types/plugin.d.ts:
--------------------------------------------------------------------------------
1 | import { Vue as _Vue } from "./vue";
2 |
3 | export type PluginFunction = (Vue: typeof _Vue, options?: T) => void;
4 |
5 | export interface PluginObject {
6 | install: PluginFunction;
7 | [key: string]: any;
8 | }
9 |
--------------------------------------------------------------------------------
/vue-code/types/test/augmentation-test.ts:
--------------------------------------------------------------------------------
1 | import Vue from "../index";
2 |
3 | declare module "../vue" {
4 | // add instance property and method
5 | interface Vue {
6 | $instanceProperty: string;
7 | $instanceMethod(): void;
8 | }
9 |
10 | // add static property and method
11 | interface VueConstructor {
12 | staticProperty: string;
13 | staticMethod(): void;
14 | }
15 | }
16 |
17 | // augment ComponentOptions
18 | declare module "../options" {
19 | interface ComponentOptions {
20 | foo?: string;
21 | }
22 | }
23 |
24 | const vm = new Vue({
25 | props: ["bar"],
26 | data: {
27 | a: true
28 | },
29 | foo: "foo",
30 | methods: {
31 | foo() {
32 | this.a = false;
33 | }
34 | },
35 | computed: {
36 | BAR(): string {
37 | return this.bar.toUpperCase();
38 | }
39 | }
40 | });
41 |
42 | vm.$instanceProperty;
43 | vm.$instanceMethod();
44 |
45 | Vue.staticProperty;
46 | Vue.staticMethod();
47 |
--------------------------------------------------------------------------------
/vue-code/types/test/es-module.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | data() {
3 | return {}
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/vue-code/types/test/plugin-test.ts:
--------------------------------------------------------------------------------
1 | import Vue from "../index";
2 | import { PluginFunction, PluginObject } from "../index";
3 |
4 | class Option {
5 | prefix: string = "";
6 | suffix: string = "";
7 | }
8 |
9 | const plugin: PluginObject