You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ha...@apache.org on 2018/01/03 07:13:32 UTC
[01/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Repository: incubator-weex
Updated Branches:
refs/heads/master d724832ff -> c0b2cfd50
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/legacy-framework.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/legacy-framework.js b/test/js-framework/unit/runtime/legacy-framework.js
new file mode 100644
index 0000000..c9e37d0
--- /dev/null
+++ b/test/js-framework/unit/runtime/legacy-framework.js
@@ -0,0 +1,348 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const {
+ expect
+} = chai
+chai.use(sinonChai)
+
+import runtime from '../../../../runtime/api'
+import frameworks from '../../../../runtime/frameworks'
+import defaultConfig from '../../../../runtime/frameworks/legacy/config'
+import { init as resetTaskHandler } from '../../../../runtime/bridge/TaskCenter'
+
+const { init, config } = runtime
+config.frameworks = frameworks
+runtime.setNativeConsole()
+
+import Vm from '../../../../runtime/frameworks/legacy/vm'
+import { clearModules, getModule } from '../../../../runtime/frameworks/legacy/app/register'
+
+const framework = init(config)
+
+function clearRefs (json) {
+ delete json.ref
+ if (json.children) {
+ json.children.forEach(clearRefs)
+ }
+}
+
+describe('framework entry', () => {
+ const oriCallNative = global.callNative
+ const oriCallAddElement = global.callAddElement
+ const oriDocumentHandler = config.Document.handler
+ const callNativeSpy = sinon.spy()
+ const callAddElementSpy = sinon.spy()
+ const documentHandlerSpy = sinon.spy()
+ const instanceId = Date.now() + ''
+
+ before(() => {
+ global.callNative = (id, tasks, callbackId) => {
+ callNativeSpy(id, tasks, callbackId)
+ /* istanbul ignore if */
+ if (callbackId !== '-1') {
+ framework.callJS(id, [{
+ method: 'callback',
+ args: [callbackId, null, true]
+ }])
+ }
+ }
+ global.callAddElement = (name, id, ref, json, index, callbackId) => {
+ callAddElementSpy(name, ref, json, index, callbackId)
+ /* istanbul ignore if */
+ if (callbackId !== '-1') {
+ framework.callJS(id, [{
+ method: 'callback',
+ args: [callbackId, null, true]
+ }])
+ }
+ }
+ config.Document.handler = oriDocumentHandler
+ resetTaskHandler()
+ })
+
+ afterEach(() => {
+ callNativeSpy.reset()
+ callAddElementSpy.reset()
+ documentHandlerSpy.reset()
+ })
+
+ after(() => {
+ config.Document.handler = oriDocumentHandler
+ global.callNative = oriCallNative
+ global.callAddElement = oriCallAddElement
+ })
+
+ describe('createInstance', () => {
+ it('a simple bundle', () => {
+ const code = `
+ define('@weex-component/main',
+ function(require, exports, module) {
+ module.exports = {
+ data: function() {
+ return {
+ text: 'Hello World',
+ showText: true
+ };
+ }
+ }
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ 'type': 'container',
+ 'children': [{
+ 'type': 'text',
+ 'shown': function() {
+ return this.showText
+ },
+ 'attr': {
+ 'value': function() {
+ return this.text
+ }
+ }
+ }]
+ }
+ }
+ )
+
+ bootstrap('@weex-component/main')
+ `
+ framework.createInstance(instanceId, code)
+ expect(callNativeSpy.callCount).to.be.equal(2)
+ expect(callAddElementSpy.callCount).to.be.equal(1)
+
+ expect(callNativeSpy.firstCall.args[0]).to.be.equal(instanceId)
+ expect(callNativeSpy.firstCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'createBody',
+ args: [{
+ ref: '_root',
+ type: 'container',
+ attr: {},
+ style: {}
+ }]
+ }])
+ // expect(callNativeSpy.firstCall.args[2]).to.not.equal('-1')
+
+ expect(callAddElementSpy.firstCall.args[0]).to.be.equal(instanceId)
+ delete callAddElementSpy.firstCall.args[1].ref
+ expect(callAddElementSpy.firstCall.args[1]).to.deep.equal({
+ type: 'text',
+ attr: { value: 'Hello World' },
+ style: {}
+ })
+
+ // expect(callNativeSpy.secondCall.args[2]).to.not.equal('-1')
+
+ expect(callNativeSpy.secondCall.args[0]).to.be.equal(instanceId)
+ expect(callNativeSpy.secondCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'createFinish',
+ args: []
+ }])
+ // expect(callNativeSpy.thirdCall.args[2]).to.not.equal('-1')
+ })
+
+ it('with a exist instanceId', () => {
+ const code = ''
+ const result = framework.createInstance(instanceId, code)
+ expect(result).to.be.an.instanceof(Error)
+ })
+ })
+
+ describe('getRoot', () => {
+ it('with a exist instanceId', () => {
+ const json = framework.getRoot(instanceId)
+ expect(json.ref).eql('_root')
+ clearRefs(json)
+ const expectJSON = {
+ type: 'container',
+ attr: {},
+ style: {},
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ },
+ style: {}
+ }]
+ }
+ expect(json).to.be.deep.equal(expectJSON)
+ })
+ })
+
+ describe('callJS', () => {
+ it('fireEvent with no params', () => {
+ framework.callJS()
+ })
+
+ it('fireEvent with a exist instanceId', () => {
+ framework.callJS(instanceId, [{
+ method: 'fireEvent',
+ args: []
+ }])
+ })
+
+ it('callback with a exist instanceId', () => {
+ framework.callJS(instanceId, [{
+ method: 'callback',
+ args: []
+ }])
+ })
+
+ it('with a non-exist instanceId', () => {
+ const result = framework.callJS('123', [{
+ method: 'fireEvent',
+ args: []
+ }])
+ expect(result).to.be.an.instanceof(Error)
+ })
+
+ it('with a non-array tasks', () => {
+ const result = framework.callJS(instanceId, {
+ method: 'fireEvent',
+ args: []
+ })
+ expect(result).to.be.an.instanceof(Error)
+ })
+ })
+
+ describe('refreshInstance', () => {
+ it('modify showText to false', () => {
+ const json = framework.getRoot(instanceId)
+ const textRef = json.children[0].ref
+ framework.refreshInstance(instanceId, { showText: false })
+ expect(callNativeSpy.callCount).to.be.equal(2)
+ expect(callNativeSpy.firstCall.args[0]).to.be.equal(instanceId)
+ expect(callNativeSpy.firstCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'removeElement',
+ args: [textRef]
+ }])
+ // expect(callNativeSpy.firstCall.args[2]).to.be.equal('-1')
+
+ expect(callNativeSpy.secondCall.args[0]).to.be.equal(instanceId)
+ expect(callNativeSpy.secondCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'refreshFinish',
+ args: []
+ }])
+ // expect(callNativeSpy.secondCall.args[2]).to.be.equal('-1')
+ })
+
+ it('with a non-exist instanceId', () => {
+ const result = framework.refreshInstance('123', {})
+ expect(result).to.be.an.instanceof(Error)
+ })
+ })
+
+ describe('destroyInstance', () => {
+ it('with no params', () => {
+ framework.destroyInstance()
+ })
+
+ it('with a exist instanceId', () => {
+ const result = framework.destroyInstance(instanceId)
+ expect(result[instanceId]).to.be.undefined
+ })
+
+ it('with a non-exist instanceId', () => {
+ const result = framework.destroyInstance('123')
+ expect(result).to.be.an.instanceof(Error)
+ })
+ })
+
+ describe('registerComponents', () => {
+ it('with old format', () => {
+ framework.registerComponents(['a', 'b', 'c'])
+ expect(defaultConfig.nativeComponentMap).to.contain.keys('a', 'b', 'c')
+ })
+
+ it('with new format', () => {
+ framework.registerComponents([{
+ type: 'd',
+ append: 'tree'
+ }])
+ expect(defaultConfig.nativeComponentMap).to.contain.keys('d')
+ expect(defaultConfig.nativeComponentMap['d']).to.be.deep.equal({
+ type: 'd',
+ append: 'tree'
+ })
+ })
+
+ it('with non-array', () => {
+ framework.registerComponents({
+ type: 'e'
+ })
+ expect(defaultConfig.nativeComponentMap).not.contain.keys('e')
+ })
+
+ it('with methods', () => {
+ const components = [{
+ type: 'x',
+ methods: ['foo', 'bar']
+ }, {
+ type: 'y',
+ methods: []
+ }, {
+ type: 'z',
+ methods: null
+ }]
+ framework.registerComponents(components)
+ expect(defaultConfig.nativeComponentMap).to.contain.keys('x', 'y', 'z')
+ })
+ })
+
+ describe('register modules', () => {
+ it('with object of modules', () => {
+ clearModules()
+ const modules = {
+ a: [{
+ name: 'b',
+ args: ['string']
+ }]
+ }
+
+ framework.registerModules(modules)
+ expect(getModule('b')).an.object
+ clearModules()
+ })
+ })
+
+ describe('register methods', () => {
+ it('with object of methods', () => {
+ const methods = {
+ a: sinon.spy()
+ }
+
+ framework.registerMethods(methods)
+ expect(Vm.prototype.a).a.function
+ delete Vm.prototype.a
+ })
+ })
+})
+
+describe('config', () => {
+ it('config is an object', () => {
+ init({})
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/runner/helper.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/runner/helper.js b/test/js-framework/unit/runtime/runner/helper.js
new file mode 100644
index 0000000..79714fc
--- /dev/null
+++ b/test/js-framework/unit/runtime/runner/helper.js
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import runtime from '../../../../../runtime/api'
+import frameworks from '../../../../../runtime/frameworks'
+import services from '../../../../../runtime/services'
+
+const defaultModules = {
+ animation: ['transition'],
+ clipboard: ['getString', 'setString'],
+ dom: ['scrollToElement', 'getComponentRect', 'addRule'],
+ modal: ['alert', 'confirm', 'prompt', 'toast'],
+ navigator: ['push', 'pop'],
+ picker: ['pick', 'pickDate', 'pickTime'],
+ storage: ['setItem', 'getItem', 'removeItem', 'length', 'getAllKeys'],
+ stream: ['fetch'],
+ timer: ['setTimeout', 'setInterval'],
+ WebSocket: ['send', 'close', 'onopen', 'onmessage', 'onclose', 'onerror'],
+ webview: ['goBack', 'goForward', 'reload']
+}
+
+const defaultComponents = [
+ 'div', 'text', 'image', 'input', 'a', 'switch', 'scroller', 'list', 'cell',
+ 'slider', 'indicator', 'loading', 'refresh', 'textarea', 'web', 'video',
+ 'embed', 'richtext'
+]
+
+export function createContext () {
+ const currentConfig = Object.assign({}, runtime.config)
+ currentConfig.frameworks = frameworks
+
+ for (const serviceName in services) {
+ runtime.service.register(serviceName, services[serviceName])
+ }
+
+ const context = runtime.init(currentConfig)
+
+ context.registerModules(defaultModules)
+ context.registerComponents(defaultComponents)
+
+ return context
+}
+
+// execute code and return the generated vdom tree
+export function execute (type, code) {
+ const context = createContext()
+ return new Promise(resolve => {
+ const id = String(Date.now() + Math.random())
+ context.createInstance(id, `
+ // { "framework": "${type}" }
+ ${code}
+ `)
+ setTimeout(() => {
+ resolve(context.getRoot(id))
+ }, 10)
+ })
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/runner/vanilla.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/runner/vanilla.js b/test/js-framework/unit/runtime/runner/vanilla.js
new file mode 100644
index 0000000..2bb6226
--- /dev/null
+++ b/test/js-framework/unit/runtime/runner/vanilla.js
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { expect } from 'chai'
+import { execute } from './helper'
+
+describe('Vanilla Examples', () => {
+ it('execute vanilla code', (done) => {
+ execute('Vanilla', `
+ const body = document.createElement('div')
+ document.documentElement.appendChild(body)
+ `).then($root => {
+ expect($root.type).to.be.equal('div')
+ }).then(done)
+ })
+
+ it('instert child nodes', (done) => {
+ execute('Vanilla', `
+ const body = document.createElement('div')
+ body.appendChild(document.createElement('text'))
+ body.appendChild(document.createElement('image'))
+ document.documentElement.appendChild(body)
+ `).then($root => {
+ expect($root.type).to.be.equal('div')
+ expect($root.children[0].type).to.be.equal('text')
+ expect($root.children[1].type).to.be.equal('image')
+ }).then(done)
+ })
+
+ it('add text nodes', (done) => {
+ execute('Vanilla', `
+ const body = document.createElement('div')
+ const text = document.createElement('text')
+ text.setAttr('value', 'whatever')
+ body.appendChild(text)
+ document.documentElement.appendChild(body)
+ `).then($root => {
+ expect($root.type).to.be.equal('div')
+ expect($root.children[0].type).to.be.equal('text')
+ expect($root.children[0].attr.value).to.be.equal('whatever')
+ }).then(done)
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/runner/vue.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/runner/vue.js b/test/js-framework/unit/runtime/runner/vue.js
new file mode 100644
index 0000000..bdb0006
--- /dev/null
+++ b/test/js-framework/unit/runtime/runner/vue.js
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { expect } from 'chai'
+import { execute } from './helper'
+import { compile } from 'weex-template-compiler'
+
+function toFunction (content) {
+ return `function () { ${content} }`
+}
+
+function compileAndExecute (template, additional) {
+ const { render, staticRenderFns } = compile(template)
+ return execute('Vue', `
+ new Vue({
+ el: '#root',
+ render: ${toFunction(render)},
+ staticRenderFns: [${staticRenderFns.map(toFunction).join(',')}],
+ ${additional}
+ })
+ `)
+}
+
+describe('Vue Examples', () => {
+ it('execute Vue code', (done) => {
+ execute('Vue', `
+ new Vue({
+ el: 'body',
+ render (h) {
+ return h('div', {}, [h('text', {}, 'Hello World')])
+ }
+ })
+ `).then($root => {
+ expect($root.type).to.be.equal('div')
+ expect($root.children[0].type).to.be.equal('text')
+ expect($root.children[0].attr.value).to.be.equal('Hello World')
+ }).then(done)
+ })
+
+ it('compile and execute', (done) => {
+ compileAndExecute(`
+ <div>
+ <text>Hello World</text>
+ </div>
+ `).then($root => {
+ expect($root.type).to.be.equal('div')
+ expect($root.children[0].type).to.be.equal('text')
+ expect($root.children[0].attr.value).to.be.equal('Hello World')
+ }).then(done)
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/utils.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/utils.js b/test/js-framework/unit/runtime/utils.js
new file mode 100644
index 0000000..3b1e3b8
--- /dev/null
+++ b/test/js-framework/unit/runtime/utils.js
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { expect } from 'chai'
+import * as utils from '../../../../runtime/shared/utils'
+
+describe('utils', () => {
+ it('isEmpty', () => {
+ expect(utils.isEmpty()).to.be.true
+ expect(utils.isEmpty(0)).to.be.true
+ expect(utils.isEmpty(null)).to.be.true
+ expect(utils.isEmpty(undefined)).to.be.true
+ expect(utils.isEmpty(false)).to.be.true
+ expect(utils.isEmpty(true)).to.be.true
+ expect(utils.isEmpty(NaN)).to.be.true
+ expect(utils.isEmpty([])).to.be.true
+ expect(utils.isEmpty({})).to.be.true
+ expect(utils.isEmpty(Object.create(null))).to.be.true
+ expect(utils.isEmpty(Object.create({}))).to.be.true
+ expect(utils.isEmpty(Object.create({ x: '' }))).to.be.true
+
+ expect(utils.isEmpty({ abc: '' })).to.be.false
+ expect(utils.isEmpty([0])).to.be.false
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/vdom/index.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/vdom/index.js b/test/js-framework/unit/runtime/vdom/index.js
new file mode 100644
index 0000000..763b202
--- /dev/null
+++ b/test/js-framework/unit/runtime/vdom/index.js
@@ -0,0 +1,639 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import {
+ Document,
+ Element,
+ Comment,
+ isWeexElement,
+ registerElement,
+ clearWeexElements
+} from '../../../../../runtime/vdom'
+
+describe('document constructor', () => {
+ it('create & destroy document', () => {
+ const doc = new Document('foo', 'http://path/to/url')
+ expect(doc).is.an.object
+ expect(doc.id).eql('foo')
+ expect(doc.URL).eql('http://path/to/url')
+ expect(doc.documentElement).is.an.object
+ expect(doc.documentElement.role).equal('documentElement')
+ doc.destroy()
+ })
+})
+
+describe('component methods management', () => {
+ before(() => {
+ registerElement('x', ['foo', 'bar'])
+ registerElement('y', [])
+ registerElement('z')
+ })
+
+ after(() => {
+ clearWeexElements()
+ })
+
+ it('has registered element types', () => {
+ expect(isWeexElement('x')).to.be.true
+ })
+
+ it('will call component method', () => {
+ const spy = sinon.spy()
+ const doc = new Document('test', '', spy)
+ const x = new Element('x')
+ const y = new Element('y')
+ const z = new Element('z')
+ const n = new Element('n')
+ expect(x.foo).is.function
+ expect(x.bar).is.function
+ expect(x.baz).is.undefined
+ expect(y.foo).is.undefined
+ expect(z.foo).is.undefined
+ expect(n.foo).is.undefined
+
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(x)
+ doc.body.appendChild(y)
+ doc.body.appendChild(z)
+ doc.body.appendChild(n)
+ expect(spy.args.length).eql(5)
+
+ x.foo(1, 2, 3)
+ expect(spy.args.length).eql(6)
+ expect(spy.args[5]).eql([[{ component: 'x', method: 'foo', ref: x.ref, args: [1, 2, 3] }]])
+ })
+})
+
+describe('document methods', () => {
+ let doc
+
+ beforeEach(() => {
+ doc = new Document('foo', null, function () {})
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ })
+
+ it('open & close with a listener', () => {
+ expect(doc.listener.batched).is.false
+ doc.close()
+ expect(doc.listener.batched).is.true
+ doc.open()
+ expect(doc.listener.batched).is.false
+ })
+
+ it('create body', () => {
+ const ele = doc.createBody('container',
+ { attr: { id: 'a' }, style: { fontSize: 16 }})
+ expect(ele.role).equal('body')
+ expect(ele.attr).to.have.a.property('id', 'a')
+ expect(ele.style).to.have.a.property('fontSize', 16)
+ expect(ele).have.a.property('ref')
+ expect(ele).have.a.property('children')
+ expect(ele).have.a.property('pureChildren')
+ expect(ele).have.a.property('insertBefore')
+ expect(ele).have.a.property('setStyle')
+
+ const ref = ele.ref
+ expect(doc.nodeMap[ref]).equal(ele)
+ })
+
+ it('create element', () => {
+ const ele = doc.createElement('container',
+ { attr: { id: 'a' }, style: { fontSize: 16 }})
+ expect(ele.attr).to.have.a.property('id', 'a')
+ expect(ele.style).to.have.a.property('fontSize', 16)
+ expect(ele).have.a.property('ref')
+ expect(ele).have.a.property('children')
+ expect(ele).have.a.property('pureChildren')
+ expect(ele).have.a.property('insertBefore')
+ expect(ele).have.a.property('setStyle')
+
+ expect(doc.nodeMap[ele.ref]).is.undefined
+ doc.documentElement.appendChild(ele)
+ expect(doc.nodeMap[ele.ref]).equal(ele)
+ })
+
+ it('create comment', () => {
+ const comment = doc.createComment('start')
+ expect(comment).have.a.property('ref')
+ expect(comment).not.have.a.property('appendChild')
+ expect(comment).have.a.property('value', 'start')
+ expect(comment.toString()).eql('<!-- start -->')
+
+ const ref = comment.ref
+ expect(doc.nodeMap[ref]).is.undefined
+ doc.documentElement.appendChild(comment)
+ expect(doc.nodeMap[ref]).equal(comment)
+ })
+})
+
+describe('Element in document methods', () => {
+ let doc, el, el2, el3
+
+ beforeEach(() => {
+ doc = new Document('foo', null, function () {})
+ el = new Element('bar', {
+ attr: { a: 11, b: 12 },
+ style: { c: 13, d: 14 },
+ classStyle: { a: 211, c: 213 }
+ })
+ el2 = new Element('baz', {
+ attr: { a: 21, b: 22 },
+ style: { c: 23, d: 24 },
+ classStyle: { a: 221, c: 223 }
+ })
+ el3 = new Element('qux', {
+ attr: { a: 31, b: 32 },
+ style: { c: 33, d: 34 },
+ classStyle: { a: 231, c: 233 }
+ })
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ })
+
+ it('init correctly', () => {
+ expect(el).is.an.object
+ expect(el.type).eql('bar')
+ expect(el.attr).eql({ a: 11, b: 12 })
+ expect(el.style).eql({ c: 13, d: 14 })
+ expect(el.event).eql({})
+ expect(el.children).eql([])
+ expect(el.pureChildren).eql([])
+ expect(doc.nodeMap).is.an.object
+ expect(doc.documentElement).is.an.object
+ expect(Object.keys(doc.nodeMap)).eql([doc.documentElement.ref])
+ doc.documentElement.appendChild(el)
+ doc.documentElement.appendChild(el2)
+ el2.appendChild(el3)
+ expect(Object.keys(doc.nodeMap)).eql([
+ doc.documentElement.ref,
+ el.ref
+ ])
+ })
+
+ it('has correct exports', () => {
+ const ref = el.ref
+ const finalStyle = el.toStyle()
+ expect(finalStyle).eql({ a: 211, c: 13, d: 14 })
+ expect(el.toJSON()).eql({
+ ref: ref, type: 'bar',
+ attr: el.attr, style: finalStyle
+ })
+ expect(el.toString()).eql(
+ '<bar attr={"a":11,"b":12} style={"a":211,"c":13,"d":14}></bar>')
+ })
+
+ it('createBody', () => {
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ expect(doc.body).is.an.object
+ expect(doc.body.role).eql('body')
+ expect(doc.body.type).eql('r')
+ expect(doc.body.docId).eql('foo')
+ })
+
+ it('appendChild', () => {
+ el.appendChild(el2)
+ expect(el.children.length).eql(1)
+ expect(el.children[0]).equal(el2)
+ expect(el2.parentNode.ref).eql(el.ref)
+
+ expect(el.docId).is.not.ok
+ expect(el2.docId).is.not.ok
+
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(el)
+ expect(doc.body.children.length).eql(1)
+ expect(el.parentNode.ref).eql(doc.body.ref)
+ expect(el.docId).is.ok
+ expect(el2.docId).is.ok
+
+ expect(el3.docId).is.not.ok
+ el.appendChild(el3)
+ expect(el.children.length).eql(2)
+ expect(el.children[0]).equal(el2)
+ expect(el.children[1]).equal(el3)
+ expect(el3.parentNode.ref).eql(el.ref)
+ expect(el3.docId).is.ok
+
+ expect(el2.previousSibling).is.not.ok
+ expect(el2.nextSibling).eql(el3)
+ expect(el3.previousSibling).eql(el2)
+ expect(el3.nextSibling).is.not.ok
+ })
+
+ it('insertBefore', () => {
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(el)
+ expect(el.parentNode.ref).eql(doc.body.ref)
+
+ el.appendChild(el2)
+ expect(el2.parentNode.ref).eql(el.ref)
+ expect(el.children.length).eql(1)
+ expect(el.children[0]).equal(el2)
+
+ el.insertBefore(el3, el2)
+ expect(el.children.length).eql(2)
+ expect(el.children[0]).equal(el3)
+ expect(el.children[1]).equal(el2)
+ expect(el3.parentNode.ref).eql(el.ref)
+
+ expect(el.docId).eql('foo')
+ expect(el2.docId).eql('foo')
+ expect(el3.docId).eql('foo')
+
+ expect(el3.previousSibling).is.not.ok
+ expect(el3.nextSibling).eql(el2)
+ expect(el2.previousSibling).eql(el3)
+ expect(el2.nextSibling).is.not.ok
+
+ el.insertBefore(el2, el3)
+ expect(el.children.length).eql(2)
+ expect(el.children[0]).equal(el2)
+ expect(el.children[1]).equal(el3)
+
+ expect(el.docId).eql('foo')
+ expect(el2.docId).eql('foo')
+ expect(el3.docId).eql('foo')
+
+ expect(el2.previousSibling).is.not.ok
+ expect(el2.nextSibling).eql(el3)
+ expect(el3.previousSibling).eql(el2)
+ expect(el3.nextSibling).is.not.ok
+ })
+
+ it('insertAfter', () => {
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(el)
+ expect(el.parentNode.ref).eql(doc.body.ref)
+
+ el.appendChild(el2)
+ el.insertAfter(el3, el2)
+ expect(el.children.length).eql(2)
+ expect(el.children[0]).equal(el2)
+ expect(el.children[1]).equal(el3)
+ expect(el2.parentNode.ref).eql(el.ref)
+ expect(el3.parentNode.ref).eql(el.ref)
+
+ expect(el.docId).eql('foo')
+ expect(el2.docId).eql('foo')
+ expect(el3.docId).eql('foo')
+
+ expect(el2.previousSibling).is.not.ok
+ expect(el2.nextSibling).eql(el3)
+ expect(el3.previousSibling).eql(el2)
+ expect(el3.nextSibling).is.not.ok
+
+ el.insertAfter(el2, el3, true)
+ expect(el.children.length).eql(2)
+ expect(el.children[0]).equal(el3)
+ expect(el.children[1]).equal(el2)
+
+ expect(el3.previousSibling).is.not.ok
+ expect(el3.nextSibling).eql(el2)
+ expect(el2.previousSibling).eql(el3)
+ expect(el2.nextSibling).is.not.ok
+ })
+
+ it('removeChild', () => {
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(el)
+ doc.body.appendChild(el2)
+ el2.appendChild(el3)
+
+ expect(el.docId).eql('foo')
+ expect(el2.docId).eql('foo')
+ expect(el3.docId).eql('foo')
+ doc.body.removeChild(el)
+ expect(doc.body.children.length).equal(1)
+ expect(doc.body.children[0]).equal(el2)
+ expect(el.docId).is.not.ok
+ expect(el2.docId).eql('foo')
+ expect(el3.docId).eql('foo')
+ doc.body.removeChild(el2)
+ expect(doc.body.children.length).equal(0)
+ expect(el.docId).is.not.ok
+ expect(el2.docId).is.not.ok
+ expect(el3.docId).is.not.ok
+ })
+
+ it('clear', () => {
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(el)
+ doc.body.appendChild(el2)
+ doc.body.appendChild(el3)
+
+ expect(el.docId).eql('foo')
+ expect(el2.docId).eql('foo')
+ expect(el3.docId).eql('foo')
+
+ doc.body.clear()
+ expect(doc.body.children.length).equal(0)
+ expect(el.docId).is.not.ok
+ expect(el2.docId).is.not.ok
+ expect(el3.docId).is.not.ok
+ })
+
+ it('modify attr, style, event', () => {
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.body.appendChild(el)
+
+ el.setAttr('a', 21)
+ expect(el.toJSON().attr).eql({ a: 21, b: 12 })
+ el.setAttr('a', 22, true)
+ expect(el.toJSON().attr).eql({ a: 22, b: 12 })
+ el.setAttr('a', 23, false)
+ expect(el.toJSON().attr).eql({ a: 23, b: 12 })
+
+ el.setStyle('c', 21)
+ expect(el.toJSON().style).eql({ a: 211, c: 21, d: 14 })
+ el.setStyle('c', 22, true)
+ expect(el.toJSON().style).eql({ a: 211, c: 22, d: 14 })
+ el.setStyle('c', 23, false)
+ expect(el.toJSON().style).eql({ a: 211, c: 23, d: 14 })
+
+ el.setClassStyle({ a: 311, c: 313 })
+ expect(el.toJSON().style).eql({ a: 311, c: 23, d: 14 })
+
+ const handler = function () {}
+ el.addEvent('click', handler)
+ expect(el.toJSON().event).eql(['click'])
+ expect(el.event.click.handler).equal(handler)
+ el.removeEvent('click')
+ expect(el.event.click).is.undefined
+ })
+})
+
+describe('Node', () => {
+ let doc, el, el2, el3, c, c2, c3, spy
+
+ beforeEach(() => {
+ spy = sinon.spy()
+ doc = new Document('foo', '', spy)
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ el = new Element('bar')
+ el2 = new Element('baz')
+ el3 = new Element('qux')
+ c = new Comment('aaa')
+ c2 = new Comment('bbb')
+ c3 = new Comment('ccc')
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ })
+
+ it('prev and next', () => {
+ expect(el.previousSibling).is.not.ok
+ expect(el.nextSibling).is.not.ok
+
+ doc.body.appendChild(el)
+ doc.body.appendChild(el2)
+ doc.body.appendChild(c)
+ doc.body.appendChild(el3)
+ doc.body.appendChild(c2)
+ doc.body.appendChild(c3)
+
+ expect(el.previousSibling).is.not.ok
+ expect(el2.previousSibling).equal(el)
+ expect(c.previousSibling).equal(el2)
+ expect(el3.previousSibling).equal(c)
+ expect(c2.previousSibling).equal(el3)
+ expect(c3.previousSibling).equal(c2)
+
+ expect(el.nextSibling).equal(el2)
+ expect(el2.nextSibling).equal(c)
+ expect(c.nextSibling).equal(el3)
+ expect(el3.nextSibling).equal(c2)
+ expect(c2.nextSibling).equal(c3)
+ expect(c3.nextSibling).is.not.ok
+ })
+
+ it('tree operations with renderer', () => {
+ doc.body.appendChild(el)
+ el.appendChild(el2)
+ el.appendChild(el3)
+
+ expect(spy.args.length).eql(4)
+ el.insertBefore(el3, el2) // [el3, el2]
+ expect(spy.args.length).eql(5)
+ expect(spy.args[4][0]).eql([{
+ module: 'dom', method: 'moveElement',
+ args: [el3.ref, el.ref, 0]
+ }])
+ el.insertAfter(el3, el2) // [el2, el3]
+ expect(spy.args.length).eql(6)
+ expect(spy.args[5][0]).eql([{
+ module: 'dom', method: 'moveElement',
+ args: [el3.ref, el.ref, 2]
+ }])
+ el.removeChild(el2) // [el3]
+ expect(spy.args.length).eql(7)
+ expect(spy.args[6][0]).eql([{
+ module: 'dom', method: 'removeElement',
+ args: [el2.ref]
+ }])
+ el.clear() // []
+ expect(spy.args.length).eql(8)
+ expect(spy.args[7][0]).eql([{
+ module: 'dom', method: 'removeElement',
+ args: [el3.ref]
+ }])
+ })
+})
+
+describe('complicated situations', () => {
+ let doc, el, el2, el3, c, c2, c3, spy
+
+ beforeEach(() => {
+ spy = sinon.spy()
+ doc = new Document('foo', '', spy)
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ el = new Element('bar')
+ el2 = new Element('baz')
+ el3 = new Element('qux')
+ c = new Comment('aaa')
+ c2 = new Comment('bbb')
+ c3 = new Comment('ccc')
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ })
+
+ it('move a node to its original position', () => {
+ doc.body.appendChild(el)
+ doc.body.appendChild(el2)
+ doc.body.appendChild(el3)
+
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, el3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertAfter(el2, el)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, el3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertAfter(el3, el2, true)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, el3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertBefore(el, el2)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, el3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertBefore(el2, el3, true)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, el3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertAfter(c, el)
+ doc.body.insertAfter(c2, el2)
+ doc.body.insertAfter(c3, el3)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, c, el2, c2, el3, c3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertBefore(el, c)
+ doc.body.insertBefore(el, c, true)
+ doc.body.insertBefore(c, el2)
+ doc.body.insertBefore(c, el2, true)
+ doc.body.insertAfter(c, el)
+ doc.body.insertAfter(c, el, true)
+ doc.body.insertAfter(el2, c)
+ doc.body.insertAfter(el2, c, true)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, c, el2, c2, el3, c3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ // move to another place that not change the pureChildren
+ doc.body.insertBefore(el, el2)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([c, el, el2, c2, el3, c3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertBefore(el, c)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, c, el2, c2, el3, c3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertAfter(c, el2)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, c, c2, el3, c3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+
+ doc.body.insertBefore(c2, c)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, c2, c, el3, c3])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+ })
+
+ it('insert before a comment', () => {
+ doc.body.appendChild(el)
+ doc.body.appendChild(c)
+ doc.body.appendChild(c2)
+ doc.body.appendChild(el2)
+ expect(spy.args.length).eql(3)
+ expect(doc.body.children).eql([el, c, c2, el2])
+ expect(doc.body.pureChildren).eql([el, el2])
+
+ doc.body.insertBefore(el3, c)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el3, c, c2, el2])
+ expect(doc.body.pureChildren).eql([el, el3, el2])
+ expect(spy.args[3][0]).eql([{
+ module: 'dom', method: 'addElement',
+ args: [doc.body.ref, el3.toJSON(), 1] }])
+ })
+
+ it('insert before a comment which has no more element after', () => {
+ doc.body.appendChild(el)
+ doc.body.appendChild(el2)
+ doc.body.appendChild(c)
+ doc.body.appendChild(c2)
+ expect(spy.args.length).eql(3)
+ expect(doc.body.children).eql([el, el2, c, c2])
+ expect(doc.body.pureChildren).eql([el, el2])
+
+ doc.body.insertBefore(el3, c)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, el2, el3, c, c2])
+ expect(doc.body.pureChildren).eql([el, el2, el3])
+ expect(spy.args[3][0]).eql([{
+ module: 'dom', method: 'addElement',
+ args: [doc.body.ref, el3.toJSON(), 2] }])
+ })
+
+ it('insert after a comment', () => {
+ doc.body.appendChild(el)
+ doc.body.appendChild(c)
+ doc.body.appendChild(c2)
+ doc.body.appendChild(el2)
+ expect(spy.args.length).eql(3)
+ expect(doc.body.children).eql([el, c, c2, el2])
+ expect(doc.body.pureChildren).eql([el, el2])
+
+ doc.body.insertAfter(el3, c2)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([el, c, c2, el3, el2])
+ expect(doc.body.pureChildren).eql([el, el3, el2])
+ expect(spy.args[3][0]).eql([{
+ module: 'dom', method: 'addElement',
+ args: [doc.body.ref, el3.toJSON(), 1] }])
+ })
+
+ it('insert after a comment which has no more element before', () => {
+ doc.body.appendChild(c)
+ doc.body.appendChild(c2)
+ doc.body.appendChild(el)
+ doc.body.appendChild(el2)
+ expect(spy.args.length).eql(3)
+ expect(doc.body.children).eql([c, c2, el, el2])
+ expect(doc.body.pureChildren).eql([el, el2])
+
+ doc.body.insertAfter(el3, c2)
+ expect(spy.args.length).eql(4)
+ expect(doc.body.children).eql([c, c2, el3, el, el2])
+ expect(doc.body.pureChildren).eql([el3, el, el2])
+ expect(spy.args[3][0]).eql([{
+ module: 'dom', method: 'addElement',
+ args: [doc.body.ref, el3.toJSON(), 0] }])
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/vdom/listener.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/vdom/listener.js b/test/js-framework/unit/runtime/vdom/listener.js
new file mode 100644
index 0000000..dab4b7e
--- /dev/null
+++ b/test/js-framework/unit/runtime/vdom/listener.js
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import { Document } from '../../../../../runtime/vdom'
+import Listener from '../../../../../runtime/bridge/Listener'
+
+describe('dom listener basic', () => {
+ it('works with no id', () => {
+ const doc = new Document(null, null, null)
+ doc.destroy()
+ })
+
+ it('works with no handler', () => {
+ const oriCallNative = global.callNative
+ const oriCallAddElement = global.callAddElement
+ const oriDocumentHandler = Document.handler
+
+ Document.handler = null
+ global.callNative = function () { return -1 }
+ global.callAddElement = function () { return -1 }
+
+ const doc = new Document('foo1', null, null)
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ const el = doc.createElement('a')
+ doc.body.appendChild(el)
+ doc.destroy()
+
+ global.callNative = oriCallNative
+ global.callAddElement = oriCallAddElement
+ Document.handler = oriDocumentHandler
+ })
+
+ it('works with an handler', () => {
+ const doc = new Document('foo2', null, function () {})
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.destroy()
+ })
+
+ it('works with an handler', () => {
+ const doc = new Document('foo2', null, function () {})
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+ doc.destroy()
+ })
+})
+
+describe('dom listener details', () => {
+ let doc, spy
+
+ beforeEach(() => {
+ spy = sinon.spy()
+ doc = new Document('foo', '', spy, Listener)
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ })
+
+ it('create document again', (done) => {
+ const documentElement = doc.createDocumentElement()
+
+ expect(documentElement).eql(doc.documentElement)
+ done()
+ })
+
+ it('create body', (done) => {
+ const body = doc.createBody('r', {
+ attr: { a: 1 }, style: { b: 2 }
+ })
+
+ doc.documentElement.appendChild(body)
+
+ expect(spy.args.length).eql(1)
+ expect(spy.args[0]).eql([[{
+ module: 'dom', method: 'createBody',
+ args: [{ type: 'r', ref: '_root', attr: { a: 1 }, style: { b: 2 }}]
+ }], '-1'])
+ done()
+ })
+
+ it('document appendChild', (done) => {
+ const el = doc.createElement('father')
+ const el2 = doc.createElement('child1')
+ const el3 = doc.createElement('child2')
+
+ el.appendChild(el2)
+ el.appendChild(el3)
+
+ doc.documentElement.appendChild(el)
+
+ expect(doc.documentElement.children.length).eql(1)
+ expect(doc.documentElement.children[0]).eql(el)
+
+ done()
+ })
+
+ it('document insertBefore', (done) => {
+ const body = doc.createBody('r', {
+ attr: { a: 1 }, style: { b: 2 }
+ })
+
+ doc.documentElement.insertBefore(body)
+
+ expect(spy.args.length).eql(1)
+ expect(spy.args[0]).eql([[{
+ module: 'dom', method: 'createBody',
+ args: [{ type: 'r', ref: '_root', attr: { a: 1 }, style: { b: 2 }}]
+ }], '-1'])
+ done()
+ })
+
+ it('document insertBefore with comment', (done) => {
+ const body = doc.createBody('r', {
+ attr: { a: 1 }, style: { b: 2 }
+ })
+ const el = doc.createComment('asd')
+
+ doc.documentElement.appendChild(el)
+ doc.documentElement.insertBefore(body, el)
+
+ expect(doc.documentElement.children.length).eql(2)
+ expect(doc.documentElement.children[0]).eql(body)
+ done()
+ })
+
+ it('document fireEvent with no element', (done) => {
+ doc.fireEvent(null)
+ done()
+ })
+
+ it('document fireEvent with domChanges', (done) => {
+ const el = doc.createElement('el', {
+ attr: { a: 1 }, style: { b: 2 }
+ })
+
+ doc.documentElement.appendChild(el)
+
+ doc.fireEvent(el, null, null, {})
+
+ expect(el.attr).eql({ a: 1 })
+ expect(el.style).eql({ b: 2 })
+
+ doc.fireEvent(el, null, null, {
+ attrs: { a: 1 }, style: { b: 2 }
+ })
+
+ expect(el.attr).eql({ a: 1 })
+ expect(el.style).eql({ b: 2 })
+
+ doc.fireEvent(el, null, null, {
+ attrs: { a: 2 }, style: { b: 3 }
+ })
+
+ expect(el.attr).eql({ a: 2 })
+ expect(el.style).eql({ b: 3 })
+ done()
+ })
+
+ it('toString has pureChildren', (done) => {
+ const el = doc.createElement('el')
+ const el1 = doc.createElement('el1')
+ el.appendChild(el1)
+ expect(el.toString()).eql('<el attr={} style={}><el1 attr={} style={}></el1></el>')
+
+ done()
+ })
+
+ it('removeChild', (done) => {
+ const el = doc.createElement('el')
+ const el1 = doc.createElement('el1')
+
+ el.removeChild(el1)
+ el.removeChild(el1, true)
+
+ done()
+ })
+
+ it('removeEvent', (done) => {
+ const el = doc.createElement('el')
+ el.removeEvent(null)
+ done()
+ })
+
+ it('add element', (done) => {
+ const body = doc.createBody('r')
+
+ doc.documentElement.appendChild(body)
+
+ expect(spy.args[0]).eql([[{
+ module: 'dom', method: 'createBody',
+ args: [body.toJSON()]
+ }], '-1'])
+
+ const el = doc.createElement('a')
+ el.setAttr('x', 1)
+ el.addEvent('click', () => {})
+ doc.body.appendChild(el)
+
+ expect(spy.args[1]).eql([[{
+ module: 'dom', method: 'addElement',
+ args: ['_root', el.toJSON(), -1]
+ }], '-1'])
+
+ const el2 = doc.createElement('b')
+ doc.body.insertBefore(el2, el) // [el2, el]
+
+ const el3 = doc.createElement('c')
+ doc.body.insertAfter(el3, el) // [el2, el, el3]
+
+ expect(spy.args.length).eql(4)
+ expect(spy.args[2]).eql([[{
+ module: 'dom', method: 'addElement',
+ args: ['_root', el2.toJSON(), 0]
+ }], '-1'])
+ expect(spy.args[3]).eql([[{
+ module: 'dom', method: 'addElement',
+ args: ['_root', el3.toJSON(), 2]
+ }], '-1'])
+
+ done()
+ })
+
+ it('bind listener for element props', () => {
+ const el = doc.createElement('bar')
+ doc.createBody('r')
+ doc.documentElement.appendChild(doc.body)
+
+ expect(spy.args.length).eql(1)
+ expect(spy.args[0][0]).eql([{
+ module: 'dom', method: 'createBody',
+ args: [doc.body.toJSON()]
+ }])
+
+ el.setAttr('a', 1)
+ el.setStyle('a', 2)
+ el.setClassStyle({ a: 3, b: 4 })
+ el.addEvent('click', () => {})
+ el.addEvent('appear', () => {})
+ el.removeEvent('appear')
+ doc.body.appendChild(el)
+
+ expect(spy.args.length).eql(2)
+ expect(spy.args[1][0]).eql([{
+ module: 'dom', method: 'addElement',
+ args: ['_root', el.toJSON(), -1]
+ }])
+
+ el.setAttr('a', 11, true)
+ expect(spy.args.length).eql(2)
+ el.setAttr('a', 12)
+ expect(spy.args.length).eql(3)
+ expect(spy.args[2][0]).eql([{
+ module: 'dom', method: 'updateAttrs',
+ args: [el.ref, { a: 12 }]
+ }])
+ el.setAttr('a', 12, false)
+ expect(spy.args.length).eql(4)
+ expect(spy.args[3][0]).eql([{
+ module: 'dom', method: 'updateAttrs',
+ args: [el.ref, { a: 12 }]
+ }])
+
+ el.setStyle('a', 13, true)
+ expect(spy.args.length).eql(4)
+ el.setStyle('a', 14)
+ expect(spy.args.length).eql(5)
+ expect(spy.args[4][0]).eql([{
+ module: 'dom', method: 'updateStyle',
+ args: [el.ref, { a: 14 }]
+ }])
+ el.setStyle('a', 14, false)
+ expect(spy.args.length).eql(6)
+ expect(spy.args[5][0]).eql([{
+ module: 'dom', method: 'updateStyle',
+ args: [el.ref, { a: 14 }]
+ }])
+
+ el.setClassStyle({ a: 13, b: 14 })
+ expect(spy.args[6][0]).eql([{
+ module: 'dom', method: 'updateStyle',
+ args: [el.ref, { a: 14, b: 14 }]
+ }])
+ expect(spy.args.length).eql(7)
+ el.addEvent('click', () => {})
+ expect(spy.args.length).eql(7)
+ el.addEvent('appear', () => {})
+ expect(spy.args.length).eql(8)
+ expect(spy.args[7][0]).eql([{
+ module: 'dom', method: 'addEvent',
+ args: [el.ref, 'appear']
+ }])
+
+ el.removeEvent('click')
+ expect(spy.args.length).eql(9)
+ expect(spy.args[8][0]).eql([{
+ module: 'dom', method: 'removeEvent',
+ args: [el.ref, 'click']
+ }])
+ el.removeEvent('appear')
+ expect(spy.args.length).eql(10)
+ expect(spy.args[9][0]).eql([{
+ module: 'dom', method: 'removeEvent',
+ args: [el.ref, 'appear']
+ }])
+
+ el.setAttr('a', 1)
+ el.setStyle('a', 2)
+ el.setClassStyle({ a: 3, b: 4 })
+ el.addEvent('click', () => {})
+ el.addEvent('appear', () => {})
+ el.removeEvent('appear')
+ expect(spy.args.length).eql(16)
+ expect(spy.args.slice(10).map(c => c[0][0])).eql([
+ { module: 'dom', method: 'updateAttrs', args: [el.ref, { a: 1 }] },
+ { module: 'dom', method: 'updateStyle', args: [el.ref, { a: 2 }] },
+ { module: 'dom', method: 'updateStyle', args: [el.ref, { a: 2, b: 4 }] },
+ { module: 'dom', method: 'addEvent', args: [el.ref, 'click'] },
+ { module: 'dom', method: 'addEvent', args: [el.ref, 'appear'] },
+ { module: 'dom', method: 'removeEvent', args: [el.ref, 'appear'] }
+ ])
+ })
+})
+
+describe('listener', () => {
+ let spy, listener
+
+ beforeEach(() => {
+ spy = sinon.spy()
+ listener = new Listener('1', spy)
+ })
+
+ it('removeElement many', () => {
+ listener.removeElement(['1', '2', '3', '4'])
+
+ expect(spy.args[0][0]).eql([
+ { module: 'dom', method: 'removeElement', args: ['1'] },
+ { module: 'dom', method: 'removeElement', args: ['2'] },
+ { module: 'dom', method: 'removeElement', args: ['3'] },
+ { module: 'dom', method: 'removeElement', args: ['4'] }
+ ])
+
+ listener = null
+ })
+
+ it('no-handler', () => {
+ listener = new Listener('1')
+ listener.handler(
+ { module: 'dom', method: 'removeElement', args: ['1'] },
+ spy
+ )
+ expect(spy).callCount(1)
+ })
+
+ afterEach(() => {
+ spy = null
+ listener = null
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/runtime/vdom/node.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/runtime/vdom/node.js b/test/js-framework/unit/runtime/vdom/node.js
new file mode 100644
index 0000000..172718f
--- /dev/null
+++ b/test/js-framework/unit/runtime/vdom/node.js
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import {
+ Node
+} from '../../../../../runtime/vdom'
+
+describe('Node', () => {
+ it('create node', () => {
+ const node = new Node()
+ expect(node).is.an.object
+ expect(node.nodeId).to.be.a('string')
+ expect(node.ref).eql(node.nodeId)
+ expect(node.children).eql([])
+ expect(node.pureChildren).eql([])
+ expect(node.parentNode).to.be.null
+ expect(node.nextSibling).to.be.null
+ expect(node.previousSibling).to.be.null
+ node.destroy()
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/shared/BroadcastChannel.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/shared/BroadcastChannel.js b/test/js-framework/unit/shared/BroadcastChannel.js
new file mode 100644
index 0000000..608b65c
--- /dev/null
+++ b/test/js-framework/unit/shared/BroadcastChannel.js
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { expect } from 'chai'
+import sinon from 'sinon'
+
+import service from '../../../../runtime/services/broadcast-channel/index'
+import { MessageEvent } from '../../../../runtime/services/broadcast-channel/message-event'
+const { BroadcastChannel } = service.create('foo').instance
+
+describe('BroadcastChannel', () => {
+ it('is a function', () => {
+ expect(BroadcastChannel).is.an('function')
+ })
+
+ it('has standard APIs', () => {
+ const JamesBond = new BroadcastChannel('007')
+ expect(JamesBond.name).is.an('string')
+ expect(JamesBond.onmessage).is.an('null')
+ expect(JamesBond.postMessage).is.an('function')
+ expect(JamesBond.close).is.an('function')
+
+ expect(JamesBond).to.have.ownProperty('name')
+ expect(JamesBond).to.have.ownProperty('onmessage')
+ expect(JamesBond).not.to.have.ownProperty('postMessage')
+ expect(JamesBond).not.to.have.ownProperty('close')
+ JamesBond.close()
+ })
+
+ it('name attribute is readonly', () => {
+ const Wolverine = new BroadcastChannel('Logan')
+ expect(Wolverine.name).to.equal('Logan')
+ Wolverine.name = 'Wolverine'
+ expect(Wolverine.name).to.equal('Logan')
+ Wolverine.close()
+ })
+
+ describe('basci usage', () => {
+ const Hulk = new BroadcastChannel('Avengers')
+ const Stack = new BroadcastChannel('Avengers')
+ const Steven = new BroadcastChannel('Avengers')
+ const Logan = new BroadcastChannel('Mutants')
+ const Erik = new BroadcastChannel('Mutants')
+
+ beforeEach(() => {
+ Hulk.onmessage = sinon.spy()
+ Stack.onmessage = sinon.spy()
+ Steven.onmessage = sinon.spy()
+ Logan.onmessage = sinon.spy()
+ })
+
+ afterEach(() => {
+ Hulk.onmessage = null
+ Stack.onmessage = null
+ Steven.onmessage = null
+ Logan.onmessage = null
+ Erik.onmessage = null
+ })
+
+ it('trigger onmessage', () => {
+ Hulk.postMessage('Hulk Smash !!!')
+ expect(Hulk.onmessage.callCount).to.be.equal(0)
+ expect(Logan.onmessage.callCount).to.be.equal(0)
+ expect(Stack.onmessage.callCount).to.be.equal(1)
+ expect(Steven.onmessage.callCount).to.be.equal(1)
+ })
+
+ it('don\'t trigger onmessage itself', () => {
+ Logan.postMessage('Any one here ?')
+ expect(Hulk.onmessage.callCount).to.be.equal(0)
+ expect(Logan.onmessage.callCount).to.be.equal(0)
+ expect(Stack.onmessage.callCount).to.be.equal(0)
+ expect(Steven.onmessage.callCount).to.be.equal(0)
+ })
+
+ it('send multi messages', () => {
+ Hulk.postMessage('Hulk Smash !!!')
+ Logan.postMessage('I will fight you !')
+ Stack.postMessage('whatever')
+ Hulk.postMessage('whatever')
+ Stack.postMessage('whatever')
+ Steven.postMessage('whatever')
+ Stack.postMessage('whatever')
+
+ expect(Hulk.onmessage.callCount).to.be.equal(4)
+ expect(Logan.onmessage.callCount).to.be.equal(0)
+ expect(Stack.onmessage.callCount).to.be.equal(3)
+ expect(Steven.onmessage.callCount).to.be.equal(5)
+ })
+
+ it('send string message', () => {
+ Stack.postMessage('I am Iron-Man.')
+
+ expect(Hulk.onmessage.callCount).to.be.equal(1)
+ expect(Steven.onmessage.callCount).to.be.equal(1)
+
+ const event = Hulk.onmessage.firstCall.args[0]
+ expect(event).is.an('object')
+ expect(event.data).is.a('string')
+ expect(event.data).to.be.equal('I am Iron-Man.')
+ })
+
+ it('send object message', () => {
+ const message = {
+ type: 'SOKOVIA ACCORDS',
+ approvedCountry: 117,
+ content: 'The Avengers shall no longer be a private organization.'
+ }
+
+ Stack.postMessage(message)
+
+ const event = Steven.onmessage.firstCall.args[0]
+ expect(event).is.an('object')
+ expect(event.data).is.a('object')
+ expect(event.data).to.deep.equal(message)
+ })
+
+ it('close channel', () => {
+ Hulk.close()
+
+ Steven.postMessage('come to fight !')
+ expect(Hulk.onmessage.callCount).to.be.equal(0)
+ expect(Stack.onmessage.callCount).to.be.equal(1)
+ expect(Steven.onmessage.callCount).to.be.equal(0)
+ })
+
+ it('send message after close', () => {
+ Hulk.close()
+
+ expect(() => { Hulk.postMessage('I am leaving.') }).to.throw(Error)
+
+ expect(Hulk.onmessage.callCount).to.be.equal(0)
+ expect(Logan.onmessage.callCount).to.be.equal(0)
+ expect(Stack.onmessage.callCount).to.be.equal(0)
+ expect(Steven.onmessage.callCount).to.be.equal(0)
+ })
+
+ it('MessageEvent dafault parameters', () => {
+ const event = new MessageEvent()
+
+ expect(event).is.an('object')
+ expect(event.data).to.be.null
+ expect(event.type).to.be.equal('message')
+ expect(event.origin).to.be.equal('')
+ expect(event.target).to.be.null
+ expect(event.source).to.be.null
+ expect(event.timeStamp).to.be.a('number')
+ expect(event.ports).to.be.an('array')
+ })
+
+ it('MessageEvent constructor', () => {
+ const source = { type: 'empty' }
+ const event = new MessageEvent('custom', {
+ source,
+ data: 'Nothing',
+ origin: 'http://127.0.0.1',
+ ports: ['8080']
+ })
+
+ expect(event).is.an('object')
+ expect(event.data).to.be.equal('Nothing')
+ expect(event.type).to.be.equal('custom')
+ expect(event.origin).to.be.equal('http://127.0.0.1')
+ expect(event.target).to.be.null
+ expect(event.source).to.deep.equal(source)
+ expect(event.timeStamp).to.be.a('number')
+ expect(event.ports).to.deep.equal(['8080'])
+ })
+
+ it('use MessageEvent', () => {
+ Steven.postMessage('Be Together.')
+
+ const event = Stack.onmessage.firstCall.args[0]
+ expect(event).is.an('object')
+ expect(event.data).to.be.equal('Be Together.')
+ expect(event.type).to.be.equal('message')
+ expect(event.origin).to.be.equal('')
+ expect(event.target).to.be.null
+ expect(event.timeStamp).to.be.a('number')
+ })
+
+ it('invalid usage', () => {
+ const stranger = {
+ name: 'stranger',
+ close: Erik.close,
+ postMessage: Erik.postMessage
+ }
+
+ stranger.postMessage('hello world.')
+
+ expect(Hulk.onmessage.callCount).to.be.equal(0)
+ expect(Logan.onmessage.callCount).to.be.equal(0)
+ expect(Stack.onmessage.callCount).to.be.equal(0)
+ expect(Steven.onmessage.callCount).to.be.equal(0)
+
+ stranger.close()
+ })
+
+ it('close all', () => {
+ Hulk.close()
+ Stack.close()
+ Steven.close()
+ Logan.close()
+ Erik.close()
+
+ // close again
+ expect(() => {
+ Hulk.close()
+ Stack.close()
+ Steven.close()
+ Logan.close()
+ Erik.close()
+ }).to.not.throw
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/shared/arrayFrom.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/shared/arrayFrom.js b/test/js-framework/unit/shared/arrayFrom.js
new file mode 100644
index 0000000..c75ea5f
--- /dev/null
+++ b/test/js-framework/unit/shared/arrayFrom.js
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+// remove original Array.from
+// Array.from = null
+
+import '../../../../runtime/shared/polyfill/arrayFrom'
+
+/* eslint-disable */
+describe('Array.from', () => {
+ it('is a function', () => {
+ expect(Array.from).is.an('function')
+ })
+
+ it('requires an array-like object', () => {
+ expect(() => Array.from()).to.throw(TypeError)
+ expect(() => Array.from(null)).to.throw(TypeError)
+ })
+
+ it('throws with invalid lengths', () => {
+ expect(() => Array.from({ 'length': Infinity })).to.throw(RangeError)
+ expect(() => Array.from({ 'length': Math.pow(2, 32) })).to.throw(RangeError)
+ })
+
+ it('swallows negative lengths', () => {
+ expect(Array.from({ length: -1 }).length).to.equal(0)
+ expect(Array.from({ length: -0 }).length).to.equal(0)
+ expect(Array.from({ length: -Infinity }).length).to.equal(0)
+ })
+
+ it('works with primitives', () => {
+ expect(Array.from(false)).to.deep.equal([])
+ expect(Array.from(true)).to.deep.equal([])
+ expect(Array.from(0)).to.deep.equal([])
+ expect(Array.from(-0)).to.deep.equal([])
+ expect(Array.from(1)).to.deep.equal([])
+ expect(Array.from(-1)).to.deep.equal([])
+ expect(Array.from(Infinity)).to.deep.equal([])
+ expect(Array.from(-Infinity)).to.deep.equal([])
+ })
+
+ it('works with primitive strings', () => {
+ expect(Array.from('')).to.deep.equal([])
+ expect(Array.from('abc')).to.deep.equal(['a', 'b', 'c'])
+ expect(Array.from('a\u5F20\u7FF0')).to.deep.equal(['a', '\u5F20', '\u7FF0'])
+ expect(Array.from('x\uD834\uDF06Y')).to.deep.equal(['x', '\uD834\uDF06', 'Y'])
+ })
+
+ it('works with objects', () => {
+ expect(Array.from({})).to.deep.equal([])
+ expect(Array.from({ name: 'abc' })).to.deep.equal([])
+ })
+
+ it('works with arrays', () => {
+ expect(Array.from([])).to.deep.equal([])
+ expect(Array.from(['a', 2, false, {}])).to.deep.equal(['a', 2, false, {}])
+ })
+
+ it('throws with an invalid mapping function', () => {
+ expect(() => Array.from([], null)).to.throw(TypeError)
+ expect(() => Array.from([], false)).to.throw(TypeError)
+ expect(() => Array.from([], 'true')).to.throw(TypeError)
+ expect(() => Array.from([], 42)).to.throw(TypeError)
+ expect(() => Array.from([], {})).to.throw(TypeError)
+ expect(() => Array.from([], [])).to.throw(TypeError)
+ })
+
+ it('works with mapping function', () => {
+ expect(Array.from([1, 2, 3], n => n * n)).to.deep.equal([1, 4, 9])
+ expect(Array.from('abc', x => x.toUpperCase())).to.deep.equal(['A', 'B', 'C'])
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/shared/console.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/shared/console.js b/test/js-framework/unit/shared/console.js
new file mode 100644
index 0000000..dcf0b4e
--- /dev/null
+++ b/test/js-framework/unit/shared/console.js
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import {
+ setNativeConsole,
+ resetNativeConsole
+} from '../../../../runtime/shared/env/console'
+
+const oriEnv = global.WXEnvironment
+const oriConsole = global.console
+
+describe.skip('polyfill for console', () => {
+ const scope = {}
+ const nativeLogSpy = sinon.spy()
+
+ before(() => {
+ delete global.console
+ global.nativeLog = function (...args) {
+ nativeLogSpy(...args)
+ }
+ global.WXEnvironment = {
+ platform: 'iOS',
+ logLevel: 'log'
+ }
+ setNativeConsole()
+ scope.console = global.console
+ // global.console = oriConsole // no output for these test case
+ })
+
+ after(() => {
+ global.WXEnvironment = oriEnv
+ resetNativeConsole()
+ expect(global.console).eql(oriConsole)
+ })
+
+ beforeEach(() => {
+ nativeLogSpy.reset()
+ })
+
+ it('export apis', () => {
+ expect(setNativeConsole).is.a('function')
+ expect(resetNativeConsole).is.a('function')
+ })
+
+ it('nativeLog', () => {
+ expect(global.nativeLog).is.a('function')
+ global.nativeLog('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ })
+
+ it('console apis', () => {
+ expect(scope.console).is.a('object')
+ expect(scope.console.debug).is.a('function')
+ expect(scope.console.log).is.a('function')
+ expect(scope.console.info).is.a('function')
+ expect(scope.console.warn).is.a('function')
+ expect(scope.console.error).is.a('function')
+ })
+
+ it('no debug message', () => {
+ scope.console.debug('a debug message')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ })
+
+ it('a log message', () => {
+ scope.console.log('a log message')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ expect(nativeLogSpy.firstCall.args).to.deep.equal(
+ ['a log message', '__LOG']
+ )
+ })
+
+ it('multi log message', () => {
+ scope.console.log('A', 'B', 'C')
+ scope.console.log('D', 'E')
+ expect(nativeLogSpy.callCount).to.be.equal(2)
+ expect(nativeLogSpy.firstCall.args).to.deep.equal(
+ ['A', 'B', 'C', '__LOG']
+ )
+ expect(nativeLogSpy.lastCall.args).to.deep.equal(
+ ['D', 'E', '__LOG']
+ )
+ })
+
+ it('an info message', () => {
+ scope.console.info('a info message')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ expect(nativeLogSpy.firstCall.args).to.deep.equal(
+ ['a info message', '__INFO']
+ )
+ })
+
+ it('a warn message', () => {
+ scope.console.warn('a warn message')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ expect(nativeLogSpy.firstCall.args).eql(
+ ['a warn message', '__WARN']
+ )
+ })
+
+ it('a error message', () => {
+ scope.console.error('a error message')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ expect(nativeLogSpy.firstCall.args).eql(
+ ['a error message', '__ERROR']
+ )
+ })
+
+ it('debug logLevel', () => {
+ global.WXEnvironment.logLevel = 'debug'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(2)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(3)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(4)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(5)
+ })
+
+ it('log logLevel', () => {
+ global.WXEnvironment.logLevel = 'log'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(2)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(3)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(4)
+ })
+
+ it('info logLevel', () => {
+ global.WXEnvironment.logLevel = 'info'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(2)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(3)
+ })
+
+ it('warn logLevel', () => {
+ global.WXEnvironment.logLevel = 'warn'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(2)
+ })
+
+ it('error logLevel', () => {
+ global.WXEnvironment.logLevel = 'error'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ })
+
+ it('off logLevel', () => {
+ global.WXEnvironment.logLevel = 'off'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ })
+
+ it('unknown logLevel', () => {
+ global.WXEnvironment.logLevel = 'log'
+ scope.console.debug('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(0)
+ scope.console.log('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(1)
+ scope.console.info('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(2)
+ scope.console.warn('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(3)
+ scope.console.error('whatever')
+ expect(nativeLogSpy.callCount).to.be.equal(4)
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/shared/index.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/shared/index.js b/test/js-framework/unit/shared/index.js
new file mode 100644
index 0000000..1a6f815
--- /dev/null
+++ b/test/js-framework/unit/shared/index.js
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import * as shared from '../../../../runtime/shared/'
+
+describe('a polyfill of', () => {
+ it('Promise', () => {
+ expect(typeof Promise).to.be.equal('function')
+ expect(() => {
+ new Promise(sinon.spy()).then(sinon.spy())
+ Promise.all()
+ Promise.race()
+ Promise.resolve()
+ Promise.reject()
+ }).to.not.throw
+ })
+
+ it('Object.assign', () => {
+ expect(typeof Object.assign).to.be.equal('function')
+ })
+
+ it('setTimeout', () => {
+ expect(typeof setTimeout).to.be.equal('function')
+ })
+
+ it('console.log', () => {
+ expect(typeof console.log).to.be.equal('function')
+ })
+})
+
+describe('freeze the prototype of build-in objects', function () {
+ before(() => {
+ shared.freezePrototype()
+ })
+
+ it('Object & Object.prototype', () => {
+ expect(Object).to.be.frozen
+ // expect(Object.prototype).to.be.frozen
+ })
+ it('Array & Array.prototype', () => {
+ expect(Array).to.be.frozen
+ expect(Array.prototype).to.be.frozen
+ })
+
+ it('String.prototype', () => { expect(String.prototype).to.be.frozen })
+ it('Number.prototype', () => { expect(Number.prototype).to.be.frozen })
+ it('Boolean.prototype', () => { expect(Boolean.prototype).to.be.frozen })
+ it('Error.prototype', () => { expect(Error.prototype).to.be.frozen })
+ it('Date.prototype', () => { expect(Date.prototype).to.be.frozen })
+ it('Math.prototype', () => { expect(Math.prototype).to.be.frozen })
+ it('RegExp.prototype', () => { expect(RegExp.prototype).to.be.frozen })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/shared/objectAssign.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/shared/objectAssign.js b/test/js-framework/unit/shared/objectAssign.js
new file mode 100644
index 0000000..b20329f
--- /dev/null
+++ b/test/js-framework/unit/shared/objectAssign.js
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import '../../../../runtime/shared/polyfill/objectAssign'
+
+describe('object.assign', () => {
+ it('is a function', () => {
+ expect(Object.assign).is.an('function')
+ })
+
+ it('source to taget', () => {
+ const target = {
+ a: 'a',
+ b: 'b'
+ }
+ const src1 = {
+ b: 'bb',
+ c: 'c'
+ }
+ const src2 = {
+ d: 'd',
+ a: 'aa'
+ }
+ Object.assign(target, src1, src2)
+ expect(target).to.deep.equal({
+ a: 'aa',
+ b: 'bb',
+ c: 'c',
+ d: 'd'
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/shared/objectSetPrototypeOf.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/shared/objectSetPrototypeOf.js b/test/js-framework/unit/shared/objectSetPrototypeOf.js
new file mode 100644
index 0000000..b6fe66e
--- /dev/null
+++ b/test/js-framework/unit/shared/objectSetPrototypeOf.js
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import '../../../../runtime/shared/polyfill/objectSetPrototypeOf'
+
+/* eslint-disable */
+describe('Object.setPrototypeOf', () => {
+ it('is a function', () => {
+ expect(Object.setPrototypeOf).is.an('function')
+ })
+
+ it('be able to set prototype', () => {
+ const JonSnow = { name: 'Jon Snow' }
+ Object.setPrototypeOf(JonSnow, {
+ know: function() { return 'nothing' }
+ })
+
+ expect(Object.hasOwnProperty.call(JonSnow, 'name')).to.be.true
+ expect(Object.hasOwnProperty.call(JonSnow, 'know')).to.be.false
+
+ expect(JonSnow.know()).to.equal('nothing')
+
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/vanilla/index.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/vanilla/index.js b/test/js-framework/unit/vanilla/index.js
new file mode 100644
index 0000000..49ea29a
--- /dev/null
+++ b/test/js-framework/unit/vanilla/index.js
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { expect } from 'chai'
+
+import vanilla from '../../../../runtime/frameworks/vanilla'
+import runtime from '../../../../runtime/api'
+
+// clear ref property in vdom
+function clearRefs (json) {
+ delete json.ref
+ if (json.children) {
+ json.children.forEach(clearRefs)
+ }
+}
+
+describe('vanilla test', () => {
+ it('standard APIs', () => {
+ expect(vanilla.init).to.be.a('function')
+ expect(vanilla.createInstance).to.be.a('function')
+ expect(vanilla.destroyInstance).to.be.a('function')
+ expect(vanilla.getRoot).to.be.a('function')
+ expect(vanilla.receiveTasks).to.be.a('function')
+ })
+
+ it('create & destroy instance', () => {
+ const id = 'basic-demo'
+ vanilla.init(runtime.config)
+ vanilla.createInstance(id, `
+ var body = document.createBody()
+ var div = document.createElement('div')
+ body.appendChild(div)
+ `, {})
+ vanilla.destroyInstance(id)
+ })
+
+ it('getRoot', () => {
+ const id = 'sample-demo'
+ const code = `
+ var body = document.createBody()
+ var div = document.createElement('div')
+ div.setStyle('color', 'red')
+ var span = document.createElement('span')
+ span.setAttr('value', 'text node')
+ div.appendChild(span)
+ body.appendChild(div)
+ `
+ vanilla.init(runtime.config)
+ vanilla.createInstance(id, code, {})
+
+ const vdom = vanilla.getRoot(id)
+ clearRefs(vdom)
+ expect(vdom).to.deep.equal({
+ // ref: '_root',
+ type: 'div',
+ attr: {},
+ style: {},
+ children: [
+ {
+ // ref: '8',
+ type: 'div',
+ attr: {},
+ style: {
+ color: 'red'
+ },
+ children: [
+ {
+ // ref: '9',
+ type: 'span',
+ attr: {
+ value: 'text node'
+ },
+ style: {}
+ }
+ ]
+ }
+ ]
+ })
+
+ vanilla.destroyInstance(id)
+ })
+
+ describe('receiveTasks', () => {
+ const id = 'task-demo'
+
+ before(() => {
+ vanilla.init(runtime.config)
+ vanilla.createInstance(id, `
+ var body = document.createBody()
+ body.addEvent('click', function() {
+ this.setStyle('width', '200')
+ })
+ document.addCallback(function(message) {
+ body.setAttr('from', message)
+ })
+ `, {})
+ })
+
+ after(() => {
+ vanilla.destroyInstance(id)
+ })
+
+ it('initial state', () => {
+ // initial style and attr in empty
+ expect(vanilla.getRoot(id).style).to.deep.equal({})
+ expect(vanilla.getRoot(id).attr).to.deep.equal({})
+
+ // empty task
+ vanilla.receiveTasks(id, [])
+ })
+
+ it('invalid tasks', () => {
+ vanilla.receiveTasks('invalid id', [])
+ vanilla.receiveTasks(id, {})
+ vanilla.receiveTasks(id, [{
+ method: 'whatever',
+ args: []
+ }])
+ })
+
+ it('fireEvent', () => {
+ vanilla.receiveTasks(id, [{
+ method: 'fireEvent',
+ args: ['_root', 'click']
+ }])
+ expect(vanilla.getRoot(id).style).to.deep.equal({ width: '200' })
+ })
+
+ it('callback', () => {
+ vanilla.receiveTasks(id, [{
+ method: 'callback',
+ args: ['1', 'callback']
+ }])
+ expect(vanilla.getRoot(id).attr).to.deep.equal({ from: 'callback' })
+
+ // last callback
+ vanilla.receiveTasks(id, [{
+ method: 'callback',
+ args: ['1', 'last message', true]
+ }])
+ expect(vanilla.getRoot(id).attr).to.deep.equal({ from: 'last message' })
+ })
+ })
+})
[11/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/legacy-framework.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/legacy-framework.js b/html5/test/unit/runtime/legacy-framework.js
deleted file mode 100644
index a82d23b..0000000
--- a/html5/test/unit/runtime/legacy-framework.js
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const {
- expect
-} = chai
-chai.use(sinonChai)
-
-import runtime from '../../../runtime'
-import frameworks from '../../../frameworks'
-import defaultConfig from '../../../frameworks/legacy/config'
-import { init as resetTaskHandler } from '../../../runtime/bridge/TaskCenter'
-
-const { init, config } = runtime
-config.frameworks = frameworks
-runtime.setNativeConsole()
-
-import Vm from '../../../frameworks/legacy/vm'
-import { clearModules, getModule } from '../../../frameworks/legacy/app/register'
-
-const framework = init(config)
-
-function clearRefs (json) {
- delete json.ref
- if (json.children) {
- json.children.forEach(clearRefs)
- }
-}
-
-describe('framework entry', () => {
- const oriCallNative = global.callNative
- const oriCallAddElement = global.callAddElement
- const oriDocumentHandler = config.Document.handler
- const callNativeSpy = sinon.spy()
- const callAddElementSpy = sinon.spy()
- const documentHandlerSpy = sinon.spy()
- const instanceId = Date.now() + ''
-
- before(() => {
- global.callNative = (id, tasks, callbackId) => {
- callNativeSpy(id, tasks, callbackId)
- /* istanbul ignore if */
- if (callbackId !== '-1') {
- framework.callJS(id, [{
- method: 'callback',
- args: [callbackId, null, true]
- }])
- }
- }
- global.callAddElement = (name, id, ref, json, index, callbackId) => {
- callAddElementSpy(name, ref, json, index, callbackId)
- /* istanbul ignore if */
- if (callbackId !== '-1') {
- framework.callJS(id, [{
- method: 'callback',
- args: [callbackId, null, true]
- }])
- }
- }
- config.Document.handler = oriDocumentHandler
- resetTaskHandler()
- })
-
- afterEach(() => {
- callNativeSpy.reset()
- callAddElementSpy.reset()
- documentHandlerSpy.reset()
- })
-
- after(() => {
- config.Document.handler = oriDocumentHandler
- global.callNative = oriCallNative
- global.callAddElement = oriCallAddElement
- })
-
- describe('createInstance', () => {
- it('a simple bundle', () => {
- const code = `
- define('@weex-component/main',
- function(require, exports, module) {
- module.exports = {
- data: function() {
- return {
- text: 'Hello World',
- showText: true
- };
- }
- }
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- 'type': 'container',
- 'children': [{
- 'type': 'text',
- 'shown': function() {
- return this.showText
- },
- 'attr': {
- 'value': function() {
- return this.text
- }
- }
- }]
- }
- }
- )
-
- bootstrap('@weex-component/main')
- `
- framework.createInstance(instanceId, code)
- expect(callNativeSpy.callCount).to.be.equal(2)
- expect(callAddElementSpy.callCount).to.be.equal(1)
-
- expect(callNativeSpy.firstCall.args[0]).to.be.equal(instanceId)
- expect(callNativeSpy.firstCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'createBody',
- args: [{
- ref: '_root',
- type: 'container',
- attr: {},
- style: {}
- }]
- }])
- // expect(callNativeSpy.firstCall.args[2]).to.not.equal('-1')
-
- expect(callAddElementSpy.firstCall.args[0]).to.be.equal(instanceId)
- delete callAddElementSpy.firstCall.args[1].ref
- expect(callAddElementSpy.firstCall.args[1]).to.deep.equal({
- type: 'text',
- attr: { value: 'Hello World' },
- style: {}
- })
-
- // expect(callNativeSpy.secondCall.args[2]).to.not.equal('-1')
-
- expect(callNativeSpy.secondCall.args[0]).to.be.equal(instanceId)
- expect(callNativeSpy.secondCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'createFinish',
- args: []
- }])
- // expect(callNativeSpy.thirdCall.args[2]).to.not.equal('-1')
- })
-
- it('with a exist instanceId', () => {
- const code = ''
- const result = framework.createInstance(instanceId, code)
- expect(result).to.be.an.instanceof(Error)
- })
- })
-
- describe('getRoot', () => {
- it('with a exist instanceId', () => {
- const json = framework.getRoot(instanceId)
- expect(json.ref).eql('_root')
- clearRefs(json)
- const expectJSON = {
- type: 'container',
- attr: {},
- style: {},
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- },
- style: {}
- }]
- }
- expect(json).to.be.deep.equal(expectJSON)
- })
- })
-
- describe('callJS', () => {
- it('fireEvent with no params', () => {
- framework.callJS()
- })
-
- it('fireEvent with a exist instanceId', () => {
- framework.callJS(instanceId, [{
- method: 'fireEvent',
- args: []
- }])
- })
-
- it('callback with a exist instanceId', () => {
- framework.callJS(instanceId, [{
- method: 'callback',
- args: []
- }])
- })
-
- it('with a non-exist instanceId', () => {
- const result = framework.callJS('123', [{
- method: 'fireEvent',
- args: []
- }])
- expect(result).to.be.an.instanceof(Error)
- })
-
- it('with a non-array tasks', () => {
- const result = framework.callJS(instanceId, {
- method: 'fireEvent',
- args: []
- })
- expect(result).to.be.an.instanceof(Error)
- })
- })
-
- describe('refreshInstance', () => {
- it('modify showText to false', () => {
- const json = framework.getRoot(instanceId)
- const textRef = json.children[0].ref
- framework.refreshInstance(instanceId, { showText: false })
- expect(callNativeSpy.callCount).to.be.equal(2)
- expect(callNativeSpy.firstCall.args[0]).to.be.equal(instanceId)
- expect(callNativeSpy.firstCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'removeElement',
- args: [textRef]
- }])
- // expect(callNativeSpy.firstCall.args[2]).to.be.equal('-1')
-
- expect(callNativeSpy.secondCall.args[0]).to.be.equal(instanceId)
- expect(callNativeSpy.secondCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'refreshFinish',
- args: []
- }])
- // expect(callNativeSpy.secondCall.args[2]).to.be.equal('-1')
- })
-
- it('with a non-exist instanceId', () => {
- const result = framework.refreshInstance('123', {})
- expect(result).to.be.an.instanceof(Error)
- })
- })
-
- describe('destroyInstance', () => {
- it('with no params', () => {
- framework.destroyInstance()
- })
-
- it('with a exist instanceId', () => {
- const result = framework.destroyInstance(instanceId)
- expect(result[instanceId]).to.be.undefined
- })
-
- it('with a non-exist instanceId', () => {
- const result = framework.destroyInstance('123')
- expect(result).to.be.an.instanceof(Error)
- })
- })
-
- describe('registerComponents', () => {
- it('with old format', () => {
- framework.registerComponents(['a', 'b', 'c'])
- expect(defaultConfig.nativeComponentMap).to.contain.keys('a', 'b', 'c')
- })
-
- it('with new format', () => {
- framework.registerComponents([{
- type: 'd',
- append: 'tree'
- }])
- expect(defaultConfig.nativeComponentMap).to.contain.keys('d')
- expect(defaultConfig.nativeComponentMap['d']).to.be.deep.equal({
- type: 'd',
- append: 'tree'
- })
- })
-
- it('with non-array', () => {
- framework.registerComponents({
- type: 'e'
- })
- expect(defaultConfig.nativeComponentMap).not.contain.keys('e')
- })
-
- it('with methods', () => {
- const components = [{
- type: 'x',
- methods: ['foo', 'bar']
- }, {
- type: 'y',
- methods: []
- }, {
- type: 'z',
- methods: null
- }]
- framework.registerComponents(components)
- expect(defaultConfig.nativeComponentMap).to.contain.keys('x', 'y', 'z')
- })
- })
-
- describe('register modules', () => {
- it('with object of modules', () => {
- clearModules()
- const modules = {
- a: [{
- name: 'b',
- args: ['string']
- }]
- }
-
- framework.registerModules(modules)
- expect(getModule('b')).an.object
- clearModules()
- })
- })
-
- describe('register methods', () => {
- it('with object of methods', () => {
- const methods = {
- a: sinon.spy()
- }
-
- framework.registerMethods(methods)
- expect(Vm.prototype.a).a.function
- delete Vm.prototype.a
- })
- })
-})
-
-describe('config', () => {
- it('config is an object', () => {
- init({})
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/runner/helper.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/runner/helper.js b/html5/test/unit/runtime/runner/helper.js
deleted file mode 100644
index dce81c7..0000000
--- a/html5/test/unit/runtime/runner/helper.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import runtime from '../../../../runtime'
-import frameworks from '../../../../frameworks'
-import services from '../../../../services'
-
-const defaultModules = {
- animation: ['transition'],
- clipboard: ['getString', 'setString'],
- dom: ['scrollToElement', 'getComponentRect', 'addRule'],
- modal: ['alert', 'confirm', 'prompt', 'toast'],
- navigator: ['push', 'pop'],
- picker: ['pick', 'pickDate', 'pickTime'],
- storage: ['setItem', 'getItem', 'removeItem', 'length', 'getAllKeys'],
- stream: ['fetch'],
- timer: ['setTimeout', 'setInterval'],
- WebSocket: ['send', 'close', 'onopen', 'onmessage', 'onclose', 'onerror'],
- webview: ['goBack', 'goForward', 'reload']
-}
-
-const defaultComponents = [
- 'div', 'text', 'image', 'input', 'a', 'switch', 'scroller', 'list', 'cell',
- 'slider', 'indicator', 'loading', 'refresh', 'textarea', 'web', 'video',
- 'embed', 'richtext'
-]
-
-export function createContext () {
- const currentConfig = Object.assign({}, runtime.config)
- currentConfig.frameworks = frameworks
-
- for (const serviceName in services) {
- runtime.service.register(serviceName, services[serviceName])
- }
-
- const context = runtime.init(currentConfig)
-
- context.registerModules(defaultModules)
- context.registerComponents(defaultComponents)
-
- return context
-}
-
-// execute code and return the generated vdom tree
-export function execute (type, code) {
- const context = createContext()
- return new Promise(resolve => {
- const id = String(Date.now() + Math.random())
- context.createInstance(id, `
- // { "framework": "${type}" }
- ${code}
- `)
- setTimeout(() => {
- resolve(context.getRoot(id))
- }, 10)
- })
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/runner/vanilla.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/runner/vanilla.js b/html5/test/unit/runtime/runner/vanilla.js
deleted file mode 100644
index 2bb6226..0000000
--- a/html5/test/unit/runtime/runner/vanilla.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { expect } from 'chai'
-import { execute } from './helper'
-
-describe('Vanilla Examples', () => {
- it('execute vanilla code', (done) => {
- execute('Vanilla', `
- const body = document.createElement('div')
- document.documentElement.appendChild(body)
- `).then($root => {
- expect($root.type).to.be.equal('div')
- }).then(done)
- })
-
- it('instert child nodes', (done) => {
- execute('Vanilla', `
- const body = document.createElement('div')
- body.appendChild(document.createElement('text'))
- body.appendChild(document.createElement('image'))
- document.documentElement.appendChild(body)
- `).then($root => {
- expect($root.type).to.be.equal('div')
- expect($root.children[0].type).to.be.equal('text')
- expect($root.children[1].type).to.be.equal('image')
- }).then(done)
- })
-
- it('add text nodes', (done) => {
- execute('Vanilla', `
- const body = document.createElement('div')
- const text = document.createElement('text')
- text.setAttr('value', 'whatever')
- body.appendChild(text)
- document.documentElement.appendChild(body)
- `).then($root => {
- expect($root.type).to.be.equal('div')
- expect($root.children[0].type).to.be.equal('text')
- expect($root.children[0].attr.value).to.be.equal('whatever')
- }).then(done)
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/runner/vue.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/runner/vue.js b/html5/test/unit/runtime/runner/vue.js
deleted file mode 100644
index bdb0006..0000000
--- a/html5/test/unit/runtime/runner/vue.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { expect } from 'chai'
-import { execute } from './helper'
-import { compile } from 'weex-template-compiler'
-
-function toFunction (content) {
- return `function () { ${content} }`
-}
-
-function compileAndExecute (template, additional) {
- const { render, staticRenderFns } = compile(template)
- return execute('Vue', `
- new Vue({
- el: '#root',
- render: ${toFunction(render)},
- staticRenderFns: [${staticRenderFns.map(toFunction).join(',')}],
- ${additional}
- })
- `)
-}
-
-describe('Vue Examples', () => {
- it('execute Vue code', (done) => {
- execute('Vue', `
- new Vue({
- el: 'body',
- render (h) {
- return h('div', {}, [h('text', {}, 'Hello World')])
- }
- })
- `).then($root => {
- expect($root.type).to.be.equal('div')
- expect($root.children[0].type).to.be.equal('text')
- expect($root.children[0].attr.value).to.be.equal('Hello World')
- }).then(done)
- })
-
- it('compile and execute', (done) => {
- compileAndExecute(`
- <div>
- <text>Hello World</text>
- </div>
- `).then($root => {
- expect($root.type).to.be.equal('div')
- expect($root.children[0].type).to.be.equal('text')
- expect($root.children[0].attr.value).to.be.equal('Hello World')
- }).then(done)
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/utils.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/utils.js b/html5/test/unit/runtime/utils.js
deleted file mode 100644
index 6480705..0000000
--- a/html5/test/unit/runtime/utils.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { expect } from 'chai'
-import * as utils from '../../../runtime/utils'
-
-describe('utils', () => {
- it('isEmpty', () => {
- expect(utils.isEmpty()).to.be.true
- expect(utils.isEmpty(0)).to.be.true
- expect(utils.isEmpty(null)).to.be.true
- expect(utils.isEmpty(undefined)).to.be.true
- expect(utils.isEmpty(false)).to.be.true
- expect(utils.isEmpty(true)).to.be.true
- expect(utils.isEmpty(NaN)).to.be.true
- expect(utils.isEmpty([])).to.be.true
- expect(utils.isEmpty({})).to.be.true
- expect(utils.isEmpty(Object.create(null))).to.be.true
- expect(utils.isEmpty(Object.create({}))).to.be.true
- expect(utils.isEmpty(Object.create({ x: '' }))).to.be.true
-
- expect(utils.isEmpty({ abc: '' })).to.be.false
- expect(utils.isEmpty([0])).to.be.false
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/vdom/index.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/vdom/index.js b/html5/test/unit/runtime/vdom/index.js
deleted file mode 100644
index 5270014..0000000
--- a/html5/test/unit/runtime/vdom/index.js
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import {
- Document,
- Element,
- Comment,
- isWeexElement,
- registerElement,
- clearWeexElements
-} from '../../../../runtime/vdom'
-
-describe('document constructor', () => {
- it('create & destroy document', () => {
- const doc = new Document('foo', 'http://path/to/url')
- expect(doc).is.an.object
- expect(doc.id).eql('foo')
- expect(doc.URL).eql('http://path/to/url')
- expect(doc.documentElement).is.an.object
- expect(doc.documentElement.role).equal('documentElement')
- doc.destroy()
- })
-})
-
-describe('component methods management', () => {
- before(() => {
- registerElement('x', ['foo', 'bar'])
- registerElement('y', [])
- registerElement('z')
- })
-
- after(() => {
- clearWeexElements()
- })
-
- it('has registered element types', () => {
- expect(isWeexElement('x')).to.be.true
- })
-
- it('will call component method', () => {
- const spy = sinon.spy()
- const doc = new Document('test', '', spy)
- const x = new Element('x')
- const y = new Element('y')
- const z = new Element('z')
- const n = new Element('n')
- expect(x.foo).is.function
- expect(x.bar).is.function
- expect(x.baz).is.undefined
- expect(y.foo).is.undefined
- expect(z.foo).is.undefined
- expect(n.foo).is.undefined
-
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(x)
- doc.body.appendChild(y)
- doc.body.appendChild(z)
- doc.body.appendChild(n)
- expect(spy.args.length).eql(5)
-
- x.foo(1, 2, 3)
- expect(spy.args.length).eql(6)
- expect(spy.args[5]).eql([[{ component: 'x', method: 'foo', ref: x.ref, args: [1, 2, 3] }]])
- })
-})
-
-describe('document methods', () => {
- let doc
-
- beforeEach(() => {
- doc = new Document('foo', null, function () {})
- })
-
- afterEach(() => {
- doc.destroy()
- })
-
- it('open & close with a listener', () => {
- expect(doc.listener.batched).is.false
- doc.close()
- expect(doc.listener.batched).is.true
- doc.open()
- expect(doc.listener.batched).is.false
- })
-
- it('create body', () => {
- const ele = doc.createBody('container',
- { attr: { id: 'a' }, style: { fontSize: 16 }})
- expect(ele.role).equal('body')
- expect(ele.attr).to.have.a.property('id', 'a')
- expect(ele.style).to.have.a.property('fontSize', 16)
- expect(ele).have.a.property('ref')
- expect(ele).have.a.property('children')
- expect(ele).have.a.property('pureChildren')
- expect(ele).have.a.property('insertBefore')
- expect(ele).have.a.property('setStyle')
-
- const ref = ele.ref
- expect(doc.nodeMap[ref]).equal(ele)
- })
-
- it('create element', () => {
- const ele = doc.createElement('container',
- { attr: { id: 'a' }, style: { fontSize: 16 }})
- expect(ele.attr).to.have.a.property('id', 'a')
- expect(ele.style).to.have.a.property('fontSize', 16)
- expect(ele).have.a.property('ref')
- expect(ele).have.a.property('children')
- expect(ele).have.a.property('pureChildren')
- expect(ele).have.a.property('insertBefore')
- expect(ele).have.a.property('setStyle')
-
- expect(doc.nodeMap[ele.ref]).is.undefined
- doc.documentElement.appendChild(ele)
- expect(doc.nodeMap[ele.ref]).equal(ele)
- })
-
- it('create comment', () => {
- const comment = doc.createComment('start')
- expect(comment).have.a.property('ref')
- expect(comment).not.have.a.property('appendChild')
- expect(comment).have.a.property('value', 'start')
- expect(comment.toString()).eql('<!-- start -->')
-
- const ref = comment.ref
- expect(doc.nodeMap[ref]).is.undefined
- doc.documentElement.appendChild(comment)
- expect(doc.nodeMap[ref]).equal(comment)
- })
-})
-
-describe('Element in document methods', () => {
- let doc, el, el2, el3
-
- beforeEach(() => {
- doc = new Document('foo', null, function () {})
- el = new Element('bar', {
- attr: { a: 11, b: 12 },
- style: { c: 13, d: 14 },
- classStyle: { a: 211, c: 213 }
- })
- el2 = new Element('baz', {
- attr: { a: 21, b: 22 },
- style: { c: 23, d: 24 },
- classStyle: { a: 221, c: 223 }
- })
- el3 = new Element('qux', {
- attr: { a: 31, b: 32 },
- style: { c: 33, d: 34 },
- classStyle: { a: 231, c: 233 }
- })
- })
-
- afterEach(() => {
- doc.destroy()
- })
-
- it('init correctly', () => {
- expect(el).is.an.object
- expect(el.type).eql('bar')
- expect(el.attr).eql({ a: 11, b: 12 })
- expect(el.style).eql({ c: 13, d: 14 })
- expect(el.event).eql({})
- expect(el.children).eql([])
- expect(el.pureChildren).eql([])
- expect(doc.nodeMap).is.an.object
- expect(doc.documentElement).is.an.object
- expect(Object.keys(doc.nodeMap)).eql([doc.documentElement.ref])
- doc.documentElement.appendChild(el)
- doc.documentElement.appendChild(el2)
- el2.appendChild(el3)
- expect(Object.keys(doc.nodeMap)).eql([
- doc.documentElement.ref,
- el.ref
- ])
- })
-
- it('has correct exports', () => {
- const ref = el.ref
- const finalStyle = el.toStyle()
- expect(finalStyle).eql({ a: 211, c: 13, d: 14 })
- expect(el.toJSON()).eql({
- ref: ref, type: 'bar',
- attr: el.attr, style: finalStyle
- })
- expect(el.toString()).eql(
- '<bar attr={"a":11,"b":12} style={"a":211,"c":13,"d":14}></bar>')
- })
-
- it('createBody', () => {
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- expect(doc.body).is.an.object
- expect(doc.body.role).eql('body')
- expect(doc.body.type).eql('r')
- expect(doc.body.docId).eql('foo')
- })
-
- it('appendChild', () => {
- el.appendChild(el2)
- expect(el.children.length).eql(1)
- expect(el.children[0]).equal(el2)
- expect(el2.parentNode.ref).eql(el.ref)
-
- expect(el.docId).is.not.ok
- expect(el2.docId).is.not.ok
-
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(el)
- expect(doc.body.children.length).eql(1)
- expect(el.parentNode.ref).eql(doc.body.ref)
- expect(el.docId).is.ok
- expect(el2.docId).is.ok
-
- expect(el3.docId).is.not.ok
- el.appendChild(el3)
- expect(el.children.length).eql(2)
- expect(el.children[0]).equal(el2)
- expect(el.children[1]).equal(el3)
- expect(el3.parentNode.ref).eql(el.ref)
- expect(el3.docId).is.ok
-
- expect(el2.previousSibling).is.not.ok
- expect(el2.nextSibling).eql(el3)
- expect(el3.previousSibling).eql(el2)
- expect(el3.nextSibling).is.not.ok
- })
-
- it('insertBefore', () => {
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(el)
- expect(el.parentNode.ref).eql(doc.body.ref)
-
- el.appendChild(el2)
- expect(el2.parentNode.ref).eql(el.ref)
- expect(el.children.length).eql(1)
- expect(el.children[0]).equal(el2)
-
- el.insertBefore(el3, el2)
- expect(el.children.length).eql(2)
- expect(el.children[0]).equal(el3)
- expect(el.children[1]).equal(el2)
- expect(el3.parentNode.ref).eql(el.ref)
-
- expect(el.docId).eql('foo')
- expect(el2.docId).eql('foo')
- expect(el3.docId).eql('foo')
-
- expect(el3.previousSibling).is.not.ok
- expect(el3.nextSibling).eql(el2)
- expect(el2.previousSibling).eql(el3)
- expect(el2.nextSibling).is.not.ok
-
- el.insertBefore(el2, el3)
- expect(el.children.length).eql(2)
- expect(el.children[0]).equal(el2)
- expect(el.children[1]).equal(el3)
-
- expect(el.docId).eql('foo')
- expect(el2.docId).eql('foo')
- expect(el3.docId).eql('foo')
-
- expect(el2.previousSibling).is.not.ok
- expect(el2.nextSibling).eql(el3)
- expect(el3.previousSibling).eql(el2)
- expect(el3.nextSibling).is.not.ok
- })
-
- it('insertAfter', () => {
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(el)
- expect(el.parentNode.ref).eql(doc.body.ref)
-
- el.appendChild(el2)
- el.insertAfter(el3, el2)
- expect(el.children.length).eql(2)
- expect(el.children[0]).equal(el2)
- expect(el.children[1]).equal(el3)
- expect(el2.parentNode.ref).eql(el.ref)
- expect(el3.parentNode.ref).eql(el.ref)
-
- expect(el.docId).eql('foo')
- expect(el2.docId).eql('foo')
- expect(el3.docId).eql('foo')
-
- expect(el2.previousSibling).is.not.ok
- expect(el2.nextSibling).eql(el3)
- expect(el3.previousSibling).eql(el2)
- expect(el3.nextSibling).is.not.ok
-
- el.insertAfter(el2, el3, true)
- expect(el.children.length).eql(2)
- expect(el.children[0]).equal(el3)
- expect(el.children[1]).equal(el2)
-
- expect(el3.previousSibling).is.not.ok
- expect(el3.nextSibling).eql(el2)
- expect(el2.previousSibling).eql(el3)
- expect(el2.nextSibling).is.not.ok
- })
-
- it('removeChild', () => {
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(el)
- doc.body.appendChild(el2)
- el2.appendChild(el3)
-
- expect(el.docId).eql('foo')
- expect(el2.docId).eql('foo')
- expect(el3.docId).eql('foo')
- doc.body.removeChild(el)
- expect(doc.body.children.length).equal(1)
- expect(doc.body.children[0]).equal(el2)
- expect(el.docId).is.not.ok
- expect(el2.docId).eql('foo')
- expect(el3.docId).eql('foo')
- doc.body.removeChild(el2)
- expect(doc.body.children.length).equal(0)
- expect(el.docId).is.not.ok
- expect(el2.docId).is.not.ok
- expect(el3.docId).is.not.ok
- })
-
- it('clear', () => {
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(el)
- doc.body.appendChild(el2)
- doc.body.appendChild(el3)
-
- expect(el.docId).eql('foo')
- expect(el2.docId).eql('foo')
- expect(el3.docId).eql('foo')
-
- doc.body.clear()
- expect(doc.body.children.length).equal(0)
- expect(el.docId).is.not.ok
- expect(el2.docId).is.not.ok
- expect(el3.docId).is.not.ok
- })
-
- it('modify attr, style, event', () => {
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.body.appendChild(el)
-
- el.setAttr('a', 21)
- expect(el.toJSON().attr).eql({ a: 21, b: 12 })
- el.setAttr('a', 22, true)
- expect(el.toJSON().attr).eql({ a: 22, b: 12 })
- el.setAttr('a', 23, false)
- expect(el.toJSON().attr).eql({ a: 23, b: 12 })
-
- el.setStyle('c', 21)
- expect(el.toJSON().style).eql({ a: 211, c: 21, d: 14 })
- el.setStyle('c', 22, true)
- expect(el.toJSON().style).eql({ a: 211, c: 22, d: 14 })
- el.setStyle('c', 23, false)
- expect(el.toJSON().style).eql({ a: 211, c: 23, d: 14 })
-
- el.setClassStyle({ a: 311, c: 313 })
- expect(el.toJSON().style).eql({ a: 311, c: 23, d: 14 })
-
- const handler = function () {}
- el.addEvent('click', handler)
- expect(el.toJSON().event).eql(['click'])
- expect(el.event.click.handler).equal(handler)
- el.removeEvent('click')
- expect(el.event.click).is.undefined
- })
-})
-
-describe('Node', () => {
- let doc, el, el2, el3, c, c2, c3, spy
-
- beforeEach(() => {
- spy = sinon.spy()
- doc = new Document('foo', '', spy)
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- el = new Element('bar')
- el2 = new Element('baz')
- el3 = new Element('qux')
- c = new Comment('aaa')
- c2 = new Comment('bbb')
- c3 = new Comment('ccc')
- })
-
- afterEach(() => {
- doc.destroy()
- })
-
- it('prev and next', () => {
- expect(el.previousSibling).is.not.ok
- expect(el.nextSibling).is.not.ok
-
- doc.body.appendChild(el)
- doc.body.appendChild(el2)
- doc.body.appendChild(c)
- doc.body.appendChild(el3)
- doc.body.appendChild(c2)
- doc.body.appendChild(c3)
-
- expect(el.previousSibling).is.not.ok
- expect(el2.previousSibling).equal(el)
- expect(c.previousSibling).equal(el2)
- expect(el3.previousSibling).equal(c)
- expect(c2.previousSibling).equal(el3)
- expect(c3.previousSibling).equal(c2)
-
- expect(el.nextSibling).equal(el2)
- expect(el2.nextSibling).equal(c)
- expect(c.nextSibling).equal(el3)
- expect(el3.nextSibling).equal(c2)
- expect(c2.nextSibling).equal(c3)
- expect(c3.nextSibling).is.not.ok
- })
-
- it('tree operations with renderer', () => {
- doc.body.appendChild(el)
- el.appendChild(el2)
- el.appendChild(el3)
-
- expect(spy.args.length).eql(4)
- el.insertBefore(el3, el2) // [el3, el2]
- expect(spy.args.length).eql(5)
- expect(spy.args[4][0]).eql([{
- module: 'dom', method: 'moveElement',
- args: [el3.ref, el.ref, 0]
- }])
- el.insertAfter(el3, el2) // [el2, el3]
- expect(spy.args.length).eql(6)
- expect(spy.args[5][0]).eql([{
- module: 'dom', method: 'moveElement',
- args: [el3.ref, el.ref, 2]
- }])
- el.removeChild(el2) // [el3]
- expect(spy.args.length).eql(7)
- expect(spy.args[6][0]).eql([{
- module: 'dom', method: 'removeElement',
- args: [el2.ref]
- }])
- el.clear() // []
- expect(spy.args.length).eql(8)
- expect(spy.args[7][0]).eql([{
- module: 'dom', method: 'removeElement',
- args: [el3.ref]
- }])
- })
-})
-
-describe('complicated situations', () => {
- let doc, el, el2, el3, c, c2, c3, spy
-
- beforeEach(() => {
- spy = sinon.spy()
- doc = new Document('foo', '', spy)
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- el = new Element('bar')
- el2 = new Element('baz')
- el3 = new Element('qux')
- c = new Comment('aaa')
- c2 = new Comment('bbb')
- c3 = new Comment('ccc')
- })
-
- afterEach(() => {
- doc.destroy()
- })
-
- it('move a node to its original position', () => {
- doc.body.appendChild(el)
- doc.body.appendChild(el2)
- doc.body.appendChild(el3)
-
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, el3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertAfter(el2, el)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, el3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertAfter(el3, el2, true)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, el3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertBefore(el, el2)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, el3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertBefore(el2, el3, true)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, el3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertAfter(c, el)
- doc.body.insertAfter(c2, el2)
- doc.body.insertAfter(c3, el3)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, c, el2, c2, el3, c3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertBefore(el, c)
- doc.body.insertBefore(el, c, true)
- doc.body.insertBefore(c, el2)
- doc.body.insertBefore(c, el2, true)
- doc.body.insertAfter(c, el)
- doc.body.insertAfter(c, el, true)
- doc.body.insertAfter(el2, c)
- doc.body.insertAfter(el2, c, true)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, c, el2, c2, el3, c3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- // move to another place that not change the pureChildren
- doc.body.insertBefore(el, el2)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([c, el, el2, c2, el3, c3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertBefore(el, c)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, c, el2, c2, el3, c3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertAfter(c, el2)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, c, c2, el3, c3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
-
- doc.body.insertBefore(c2, c)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, c2, c, el3, c3])
- expect(doc.body.pureChildren).eql([el, el2, el3])
- })
-
- it('insert before a comment', () => {
- doc.body.appendChild(el)
- doc.body.appendChild(c)
- doc.body.appendChild(c2)
- doc.body.appendChild(el2)
- expect(spy.args.length).eql(3)
- expect(doc.body.children).eql([el, c, c2, el2])
- expect(doc.body.pureChildren).eql([el, el2])
-
- doc.body.insertBefore(el3, c)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el3, c, c2, el2])
- expect(doc.body.pureChildren).eql([el, el3, el2])
- expect(spy.args[3][0]).eql([{
- module: 'dom', method: 'addElement',
- args: [doc.body.ref, el3.toJSON(), 1] }])
- })
-
- it('insert before a comment which has no more element after', () => {
- doc.body.appendChild(el)
- doc.body.appendChild(el2)
- doc.body.appendChild(c)
- doc.body.appendChild(c2)
- expect(spy.args.length).eql(3)
- expect(doc.body.children).eql([el, el2, c, c2])
- expect(doc.body.pureChildren).eql([el, el2])
-
- doc.body.insertBefore(el3, c)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, el2, el3, c, c2])
- expect(doc.body.pureChildren).eql([el, el2, el3])
- expect(spy.args[3][0]).eql([{
- module: 'dom', method: 'addElement',
- args: [doc.body.ref, el3.toJSON(), 2] }])
- })
-
- it('insert after a comment', () => {
- doc.body.appendChild(el)
- doc.body.appendChild(c)
- doc.body.appendChild(c2)
- doc.body.appendChild(el2)
- expect(spy.args.length).eql(3)
- expect(doc.body.children).eql([el, c, c2, el2])
- expect(doc.body.pureChildren).eql([el, el2])
-
- doc.body.insertAfter(el3, c2)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([el, c, c2, el3, el2])
- expect(doc.body.pureChildren).eql([el, el3, el2])
- expect(spy.args[3][0]).eql([{
- module: 'dom', method: 'addElement',
- args: [doc.body.ref, el3.toJSON(), 1] }])
- })
-
- it('insert after a comment which has no more element before', () => {
- doc.body.appendChild(c)
- doc.body.appendChild(c2)
- doc.body.appendChild(el)
- doc.body.appendChild(el2)
- expect(spy.args.length).eql(3)
- expect(doc.body.children).eql([c, c2, el, el2])
- expect(doc.body.pureChildren).eql([el, el2])
-
- doc.body.insertAfter(el3, c2)
- expect(spy.args.length).eql(4)
- expect(doc.body.children).eql([c, c2, el3, el, el2])
- expect(doc.body.pureChildren).eql([el3, el, el2])
- expect(spy.args[3][0]).eql([{
- module: 'dom', method: 'addElement',
- args: [doc.body.ref, el3.toJSON(), 0] }])
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/vdom/listener.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/vdom/listener.js b/html5/test/unit/runtime/vdom/listener.js
deleted file mode 100644
index 1eab8d5..0000000
--- a/html5/test/unit/runtime/vdom/listener.js
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import { Document } from '../../../../runtime/vdom'
-import Listener from '../../../../runtime/bridge/Listener'
-
-describe('dom listener basic', () => {
- it('works with no id', () => {
- const doc = new Document(null, null, null)
- doc.destroy()
- })
-
- it('works with no handler', () => {
- const oriCallNative = global.callNative
- const oriCallAddElement = global.callAddElement
- const oriDocumentHandler = Document.handler
-
- Document.handler = null
- global.callNative = function () { return -1 }
- global.callAddElement = function () { return -1 }
-
- const doc = new Document('foo1', null, null)
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- const el = doc.createElement('a')
- doc.body.appendChild(el)
- doc.destroy()
-
- global.callNative = oriCallNative
- global.callAddElement = oriCallAddElement
- Document.handler = oriDocumentHandler
- })
-
- it('works with an handler', () => {
- const doc = new Document('foo2', null, function () {})
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.destroy()
- })
-
- it('works with an handler', () => {
- const doc = new Document('foo2', null, function () {})
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
- doc.destroy()
- })
-})
-
-describe('dom listener details', () => {
- let doc, spy
-
- beforeEach(() => {
- spy = sinon.spy()
- doc = new Document('foo', '', spy, Listener)
- })
-
- afterEach(() => {
- doc.destroy()
- })
-
- it('create document again', (done) => {
- const documentElement = doc.createDocumentElement()
-
- expect(documentElement).eql(doc.documentElement)
- done()
- })
-
- it('create body', (done) => {
- const body = doc.createBody('r', {
- attr: { a: 1 }, style: { b: 2 }
- })
-
- doc.documentElement.appendChild(body)
-
- expect(spy.args.length).eql(1)
- expect(spy.args[0]).eql([[{
- module: 'dom', method: 'createBody',
- args: [{ type: 'r', ref: '_root', attr: { a: 1 }, style: { b: 2 }}]
- }], '-1'])
- done()
- })
-
- it('document appendChild', (done) => {
- const el = doc.createElement('father')
- const el2 = doc.createElement('child1')
- const el3 = doc.createElement('child2')
-
- el.appendChild(el2)
- el.appendChild(el3)
-
- doc.documentElement.appendChild(el)
-
- expect(doc.documentElement.children.length).eql(1)
- expect(doc.documentElement.children[0]).eql(el)
-
- done()
- })
-
- it('document insertBefore', (done) => {
- const body = doc.createBody('r', {
- attr: { a: 1 }, style: { b: 2 }
- })
-
- doc.documentElement.insertBefore(body)
-
- expect(spy.args.length).eql(1)
- expect(spy.args[0]).eql([[{
- module: 'dom', method: 'createBody',
- args: [{ type: 'r', ref: '_root', attr: { a: 1 }, style: { b: 2 }}]
- }], '-1'])
- done()
- })
-
- it('document insertBefore with comment', (done) => {
- const body = doc.createBody('r', {
- attr: { a: 1 }, style: { b: 2 }
- })
- const el = doc.createComment('asd')
-
- doc.documentElement.appendChild(el)
- doc.documentElement.insertBefore(body, el)
-
- expect(doc.documentElement.children.length).eql(2)
- expect(doc.documentElement.children[0]).eql(body)
- done()
- })
-
- it('document fireEvent with no element', (done) => {
- doc.fireEvent(null)
- done()
- })
-
- it('document fireEvent with domChanges', (done) => {
- const el = doc.createElement('el', {
- attr: { a: 1 }, style: { b: 2 }
- })
-
- doc.documentElement.appendChild(el)
-
- doc.fireEvent(el, null, null, {})
-
- expect(el.attr).eql({ a: 1 })
- expect(el.style).eql({ b: 2 })
-
- doc.fireEvent(el, null, null, {
- attrs: { a: 1 }, style: { b: 2 }
- })
-
- expect(el.attr).eql({ a: 1 })
- expect(el.style).eql({ b: 2 })
-
- doc.fireEvent(el, null, null, {
- attrs: { a: 2 }, style: { b: 3 }
- })
-
- expect(el.attr).eql({ a: 2 })
- expect(el.style).eql({ b: 3 })
- done()
- })
-
- it('toString has pureChildren', (done) => {
- const el = doc.createElement('el')
- const el1 = doc.createElement('el1')
- el.appendChild(el1)
- expect(el.toString()).eql('<el attr={} style={}><el1 attr={} style={}></el1></el>')
-
- done()
- })
-
- it('removeChild', (done) => {
- const el = doc.createElement('el')
- const el1 = doc.createElement('el1')
-
- el.removeChild(el1)
- el.removeChild(el1, true)
-
- done()
- })
-
- it('removeEvent', (done) => {
- const el = doc.createElement('el')
- el.removeEvent(null)
- done()
- })
-
- it('add element', (done) => {
- const body = doc.createBody('r')
-
- doc.documentElement.appendChild(body)
-
- expect(spy.args[0]).eql([[{
- module: 'dom', method: 'createBody',
- args: [body.toJSON()]
- }], '-1'])
-
- const el = doc.createElement('a')
- el.setAttr('x', 1)
- el.addEvent('click', () => {})
- doc.body.appendChild(el)
-
- expect(spy.args[1]).eql([[{
- module: 'dom', method: 'addElement',
- args: ['_root', el.toJSON(), -1]
- }], '-1'])
-
- const el2 = doc.createElement('b')
- doc.body.insertBefore(el2, el) // [el2, el]
-
- const el3 = doc.createElement('c')
- doc.body.insertAfter(el3, el) // [el2, el, el3]
-
- expect(spy.args.length).eql(4)
- expect(spy.args[2]).eql([[{
- module: 'dom', method: 'addElement',
- args: ['_root', el2.toJSON(), 0]
- }], '-1'])
- expect(spy.args[3]).eql([[{
- module: 'dom', method: 'addElement',
- args: ['_root', el3.toJSON(), 2]
- }], '-1'])
-
- done()
- })
-
- it('bind listener for element props', () => {
- const el = doc.createElement('bar')
- doc.createBody('r')
- doc.documentElement.appendChild(doc.body)
-
- expect(spy.args.length).eql(1)
- expect(spy.args[0][0]).eql([{
- module: 'dom', method: 'createBody',
- args: [doc.body.toJSON()]
- }])
-
- el.setAttr('a', 1)
- el.setStyle('a', 2)
- el.setClassStyle({ a: 3, b: 4 })
- el.addEvent('click', () => {})
- el.addEvent('appear', () => {})
- el.removeEvent('appear')
- doc.body.appendChild(el)
-
- expect(spy.args.length).eql(2)
- expect(spy.args[1][0]).eql([{
- module: 'dom', method: 'addElement',
- args: ['_root', el.toJSON(), -1]
- }])
-
- el.setAttr('a', 11, true)
- expect(spy.args.length).eql(2)
- el.setAttr('a', 12)
- expect(spy.args.length).eql(3)
- expect(spy.args[2][0]).eql([{
- module: 'dom', method: 'updateAttrs',
- args: [el.ref, { a: 12 }]
- }])
- el.setAttr('a', 12, false)
- expect(spy.args.length).eql(4)
- expect(spy.args[3][0]).eql([{
- module: 'dom', method: 'updateAttrs',
- args: [el.ref, { a: 12 }]
- }])
-
- el.setStyle('a', 13, true)
- expect(spy.args.length).eql(4)
- el.setStyle('a', 14)
- expect(spy.args.length).eql(5)
- expect(spy.args[4][0]).eql([{
- module: 'dom', method: 'updateStyle',
- args: [el.ref, { a: 14 }]
- }])
- el.setStyle('a', 14, false)
- expect(spy.args.length).eql(6)
- expect(spy.args[5][0]).eql([{
- module: 'dom', method: 'updateStyle',
- args: [el.ref, { a: 14 }]
- }])
-
- el.setClassStyle({ a: 13, b: 14 })
- expect(spy.args[6][0]).eql([{
- module: 'dom', method: 'updateStyle',
- args: [el.ref, { a: 14, b: 14 }]
- }])
- expect(spy.args.length).eql(7)
- el.addEvent('click', () => {})
- expect(spy.args.length).eql(7)
- el.addEvent('appear', () => {})
- expect(spy.args.length).eql(8)
- expect(spy.args[7][0]).eql([{
- module: 'dom', method: 'addEvent',
- args: [el.ref, 'appear']
- }])
-
- el.removeEvent('click')
- expect(spy.args.length).eql(9)
- expect(spy.args[8][0]).eql([{
- module: 'dom', method: 'removeEvent',
- args: [el.ref, 'click']
- }])
- el.removeEvent('appear')
- expect(spy.args.length).eql(10)
- expect(spy.args[9][0]).eql([{
- module: 'dom', method: 'removeEvent',
- args: [el.ref, 'appear']
- }])
-
- el.setAttr('a', 1)
- el.setStyle('a', 2)
- el.setClassStyle({ a: 3, b: 4 })
- el.addEvent('click', () => {})
- el.addEvent('appear', () => {})
- el.removeEvent('appear')
- expect(spy.args.length).eql(16)
- expect(spy.args.slice(10).map(c => c[0][0])).eql([
- { module: 'dom', method: 'updateAttrs', args: [el.ref, { a: 1 }] },
- { module: 'dom', method: 'updateStyle', args: [el.ref, { a: 2 }] },
- { module: 'dom', method: 'updateStyle', args: [el.ref, { a: 2, b: 4 }] },
- { module: 'dom', method: 'addEvent', args: [el.ref, 'click'] },
- { module: 'dom', method: 'addEvent', args: [el.ref, 'appear'] },
- { module: 'dom', method: 'removeEvent', args: [el.ref, 'appear'] }
- ])
- })
-})
-
-describe('listener', () => {
- let spy, listener
-
- beforeEach(() => {
- spy = sinon.spy()
- listener = new Listener('1', spy)
- })
-
- it('removeElement many', () => {
- listener.removeElement(['1', '2', '3', '4'])
-
- expect(spy.args[0][0]).eql([
- { module: 'dom', method: 'removeElement', args: ['1'] },
- { module: 'dom', method: 'removeElement', args: ['2'] },
- { module: 'dom', method: 'removeElement', args: ['3'] },
- { module: 'dom', method: 'removeElement', args: ['4'] }
- ])
-
- listener = null
- })
-
- it('no-handler', () => {
- listener = new Listener('1')
- listener.handler(
- { module: 'dom', method: 'removeElement', args: ['1'] },
- spy
- )
- expect(spy).callCount(1)
- })
-
- afterEach(() => {
- spy = null
- listener = null
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/runtime/vdom/node.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/runtime/vdom/node.js b/html5/test/unit/runtime/vdom/node.js
deleted file mode 100644
index b05d277..0000000
--- a/html5/test/unit/runtime/vdom/node.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import {
- Node
-} from '../../../../runtime/vdom'
-
-describe('Node', () => {
- it('create node', () => {
- const node = new Node()
- expect(node).is.an.object
- expect(node.nodeId).to.be.a('string')
- expect(node.ref).eql(node.nodeId)
- expect(node.children).eql([])
- expect(node.pureChildren).eql([])
- expect(node.parentNode).to.be.null
- expect(node.nextSibling).to.be.null
- expect(node.previousSibling).to.be.null
- node.destroy()
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/shared/BroadcastChannel.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/shared/BroadcastChannel.js b/html5/test/unit/shared/BroadcastChannel.js
deleted file mode 100644
index 880ed6b..0000000
--- a/html5/test/unit/shared/BroadcastChannel.js
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { expect } from 'chai'
-import sinon from 'sinon'
-
-import service from '../../../services/broadcast-channel/index'
-import { MessageEvent } from '../../../services/broadcast-channel/message-event'
-const { BroadcastChannel } = service.create('foo').instance
-
-describe('BroadcastChannel', () => {
- it('is a function', () => {
- expect(BroadcastChannel).is.an('function')
- })
-
- it('has standard APIs', () => {
- const JamesBond = new BroadcastChannel('007')
- expect(JamesBond.name).is.an('string')
- expect(JamesBond.onmessage).is.an('null')
- expect(JamesBond.postMessage).is.an('function')
- expect(JamesBond.close).is.an('function')
-
- expect(JamesBond).to.have.ownProperty('name')
- expect(JamesBond).to.have.ownProperty('onmessage')
- expect(JamesBond).not.to.have.ownProperty('postMessage')
- expect(JamesBond).not.to.have.ownProperty('close')
- JamesBond.close()
- })
-
- it('name attribute is readonly', () => {
- const Wolverine = new BroadcastChannel('Logan')
- expect(Wolverine.name).to.equal('Logan')
- Wolverine.name = 'Wolverine'
- expect(Wolverine.name).to.equal('Logan')
- Wolverine.close()
- })
-
- describe('basci usage', () => {
- const Hulk = new BroadcastChannel('Avengers')
- const Stack = new BroadcastChannel('Avengers')
- const Steven = new BroadcastChannel('Avengers')
- const Logan = new BroadcastChannel('Mutants')
- const Erik = new BroadcastChannel('Mutants')
-
- beforeEach(() => {
- Hulk.onmessage = sinon.spy()
- Stack.onmessage = sinon.spy()
- Steven.onmessage = sinon.spy()
- Logan.onmessage = sinon.spy()
- })
-
- afterEach(() => {
- Hulk.onmessage = null
- Stack.onmessage = null
- Steven.onmessage = null
- Logan.onmessage = null
- Erik.onmessage = null
- })
-
- it('trigger onmessage', () => {
- Hulk.postMessage('Hulk Smash !!!')
- expect(Hulk.onmessage.callCount).to.be.equal(0)
- expect(Logan.onmessage.callCount).to.be.equal(0)
- expect(Stack.onmessage.callCount).to.be.equal(1)
- expect(Steven.onmessage.callCount).to.be.equal(1)
- })
-
- it('don\'t trigger onmessage itself', () => {
- Logan.postMessage('Any one here ?')
- expect(Hulk.onmessage.callCount).to.be.equal(0)
- expect(Logan.onmessage.callCount).to.be.equal(0)
- expect(Stack.onmessage.callCount).to.be.equal(0)
- expect(Steven.onmessage.callCount).to.be.equal(0)
- })
-
- it('send multi messages', () => {
- Hulk.postMessage('Hulk Smash !!!')
- Logan.postMessage('I will fight you !')
- Stack.postMessage('whatever')
- Hulk.postMessage('whatever')
- Stack.postMessage('whatever')
- Steven.postMessage('whatever')
- Stack.postMessage('whatever')
-
- expect(Hulk.onmessage.callCount).to.be.equal(4)
- expect(Logan.onmessage.callCount).to.be.equal(0)
- expect(Stack.onmessage.callCount).to.be.equal(3)
- expect(Steven.onmessage.callCount).to.be.equal(5)
- })
-
- it('send string message', () => {
- Stack.postMessage('I am Iron-Man.')
-
- expect(Hulk.onmessage.callCount).to.be.equal(1)
- expect(Steven.onmessage.callCount).to.be.equal(1)
-
- const event = Hulk.onmessage.firstCall.args[0]
- expect(event).is.an('object')
- expect(event.data).is.a('string')
- expect(event.data).to.be.equal('I am Iron-Man.')
- })
-
- it('send object message', () => {
- const message = {
- type: 'SOKOVIA ACCORDS',
- approvedCountry: 117,
- content: 'The Avengers shall no longer be a private organization.'
- }
-
- Stack.postMessage(message)
-
- const event = Steven.onmessage.firstCall.args[0]
- expect(event).is.an('object')
- expect(event.data).is.a('object')
- expect(event.data).to.deep.equal(message)
- })
-
- it('close channel', () => {
- Hulk.close()
-
- Steven.postMessage('come to fight !')
- expect(Hulk.onmessage.callCount).to.be.equal(0)
- expect(Stack.onmessage.callCount).to.be.equal(1)
- expect(Steven.onmessage.callCount).to.be.equal(0)
- })
-
- it('send message after close', () => {
- Hulk.close()
-
- expect(() => { Hulk.postMessage('I am leaving.') }).to.throw(Error)
-
- expect(Hulk.onmessage.callCount).to.be.equal(0)
- expect(Logan.onmessage.callCount).to.be.equal(0)
- expect(Stack.onmessage.callCount).to.be.equal(0)
- expect(Steven.onmessage.callCount).to.be.equal(0)
- })
-
- it('MessageEvent dafault parameters', () => {
- const event = new MessageEvent()
-
- expect(event).is.an('object')
- expect(event.data).to.be.null
- expect(event.type).to.be.equal('message')
- expect(event.origin).to.be.equal('')
- expect(event.target).to.be.null
- expect(event.source).to.be.null
- expect(event.timeStamp).to.be.a('number')
- expect(event.ports).to.be.an('array')
- })
-
- it('MessageEvent constructor', () => {
- const source = { type: 'empty' }
- const event = new MessageEvent('custom', {
- source,
- data: 'Nothing',
- origin: 'http://127.0.0.1',
- ports: ['8080']
- })
-
- expect(event).is.an('object')
- expect(event.data).to.be.equal('Nothing')
- expect(event.type).to.be.equal('custom')
- expect(event.origin).to.be.equal('http://127.0.0.1')
- expect(event.target).to.be.null
- expect(event.source).to.deep.equal(source)
- expect(event.timeStamp).to.be.a('number')
- expect(event.ports).to.deep.equal(['8080'])
- })
-
- it('use MessageEvent', () => {
- Steven.postMessage('Be Together.')
-
- const event = Stack.onmessage.firstCall.args[0]
- expect(event).is.an('object')
- expect(event.data).to.be.equal('Be Together.')
- expect(event.type).to.be.equal('message')
- expect(event.origin).to.be.equal('')
- expect(event.target).to.be.null
- expect(event.timeStamp).to.be.a('number')
- })
-
- it('invalid usage', () => {
- const stranger = {
- name: 'stranger',
- close: Erik.close,
- postMessage: Erik.postMessage
- }
-
- stranger.postMessage('hello world.')
-
- expect(Hulk.onmessage.callCount).to.be.equal(0)
- expect(Logan.onmessage.callCount).to.be.equal(0)
- expect(Stack.onmessage.callCount).to.be.equal(0)
- expect(Steven.onmessage.callCount).to.be.equal(0)
-
- stranger.close()
- })
-
- it('close all', () => {
- Hulk.close()
- Stack.close()
- Steven.close()
- Logan.close()
- Erik.close()
-
- // close again
- expect(() => {
- Hulk.close()
- Stack.close()
- Steven.close()
- Logan.close()
- Erik.close()
- }).to.not.throw
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/shared/arrayFrom.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/shared/arrayFrom.js b/html5/test/unit/shared/arrayFrom.js
deleted file mode 100644
index 99e9495..0000000
--- a/html5/test/unit/shared/arrayFrom.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-// remove original Array.from
-// Array.from = null
-
-import '../../../shared/arrayFrom'
-
-/* eslint-disable */
-describe('Array.from', () => {
- it('is a function', () => {
- expect(Array.from).is.an('function')
- })
-
- it('requires an array-like object', () => {
- expect(() => Array.from()).to.throw(TypeError)
- expect(() => Array.from(null)).to.throw(TypeError)
- })
-
- it('throws with invalid lengths', () => {
- expect(() => Array.from({ 'length': Infinity })).to.throw(RangeError)
- expect(() => Array.from({ 'length': Math.pow(2, 32) })).to.throw(RangeError)
- })
-
- it('swallows negative lengths', () => {
- expect(Array.from({ length: -1 }).length).to.equal(0)
- expect(Array.from({ length: -0 }).length).to.equal(0)
- expect(Array.from({ length: -Infinity }).length).to.equal(0)
- })
-
- it('works with primitives', () => {
- expect(Array.from(false)).to.deep.equal([])
- expect(Array.from(true)).to.deep.equal([])
- expect(Array.from(0)).to.deep.equal([])
- expect(Array.from(-0)).to.deep.equal([])
- expect(Array.from(1)).to.deep.equal([])
- expect(Array.from(-1)).to.deep.equal([])
- expect(Array.from(Infinity)).to.deep.equal([])
- expect(Array.from(-Infinity)).to.deep.equal([])
- })
-
- it('works with primitive strings', () => {
- expect(Array.from('')).to.deep.equal([])
- expect(Array.from('abc')).to.deep.equal(['a', 'b', 'c'])
- expect(Array.from('a\u5F20\u7FF0')).to.deep.equal(['a', '\u5F20', '\u7FF0'])
- expect(Array.from('x\uD834\uDF06Y')).to.deep.equal(['x', '\uD834\uDF06', 'Y'])
- })
-
- it('works with objects', () => {
- expect(Array.from({})).to.deep.equal([])
- expect(Array.from({ name: 'abc' })).to.deep.equal([])
- })
-
- it('works with arrays', () => {
- expect(Array.from([])).to.deep.equal([])
- expect(Array.from(['a', 2, false, {}])).to.deep.equal(['a', 2, false, {}])
- })
-
- it('throws with an invalid mapping function', () => {
- expect(() => Array.from([], null)).to.throw(TypeError)
- expect(() => Array.from([], false)).to.throw(TypeError)
- expect(() => Array.from([], 'true')).to.throw(TypeError)
- expect(() => Array.from([], 42)).to.throw(TypeError)
- expect(() => Array.from([], {})).to.throw(TypeError)
- expect(() => Array.from([], [])).to.throw(TypeError)
- })
-
- it('works with mapping function', () => {
- expect(Array.from([1, 2, 3], n => n * n)).to.deep.equal([1, 4, 9])
- expect(Array.from('abc', x => x.toUpperCase())).to.deep.equal(['A', 'B', 'C'])
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/shared/console.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/shared/console.js b/html5/test/unit/shared/console.js
deleted file mode 100644
index 60eb281..0000000
--- a/html5/test/unit/shared/console.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import { setNativeConsole, resetNativeConsole } from '../../../shared/console'
-
-const oriEnv = global.WXEnvironment
-const oriConsole = global.console
-
-describe.skip('polyfill for console', () => {
- const scope = {}
- const nativeLogSpy = sinon.spy()
-
- before(() => {
- delete global.console
- global.nativeLog = function (...args) {
- nativeLogSpy(...args)
- }
- global.WXEnvironment = {
- platform: 'iOS',
- logLevel: 'log'
- }
- setNativeConsole()
- scope.console = global.console
- // global.console = oriConsole // no output for these test case
- })
-
- after(() => {
- global.WXEnvironment = oriEnv
- resetNativeConsole()
- expect(global.console).eql(oriConsole)
- })
-
- beforeEach(() => {
- nativeLogSpy.reset()
- })
-
- it('export apis', () => {
- expect(setNativeConsole).is.a('function')
- expect(resetNativeConsole).is.a('function')
- })
-
- it('nativeLog', () => {
- expect(global.nativeLog).is.a('function')
- global.nativeLog('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- })
-
- it('console apis', () => {
- expect(scope.console).is.a('object')
- expect(scope.console.debug).is.a('function')
- expect(scope.console.log).is.a('function')
- expect(scope.console.info).is.a('function')
- expect(scope.console.warn).is.a('function')
- expect(scope.console.error).is.a('function')
- })
-
- it('no debug message', () => {
- scope.console.debug('a debug message')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- })
-
- it('a log message', () => {
- scope.console.log('a log message')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- expect(nativeLogSpy.firstCall.args).to.deep.equal(
- ['a log message', '__LOG']
- )
- })
-
- it('multi log message', () => {
- scope.console.log('A', 'B', 'C')
- scope.console.log('D', 'E')
- expect(nativeLogSpy.callCount).to.be.equal(2)
- expect(nativeLogSpy.firstCall.args).to.deep.equal(
- ['A', 'B', 'C', '__LOG']
- )
- expect(nativeLogSpy.lastCall.args).to.deep.equal(
- ['D', 'E', '__LOG']
- )
- })
-
- it('an info message', () => {
- scope.console.info('a info message')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- expect(nativeLogSpy.firstCall.args).to.deep.equal(
- ['a info message', '__INFO']
- )
- })
-
- it('a warn message', () => {
- scope.console.warn('a warn message')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- expect(nativeLogSpy.firstCall.args).eql(
- ['a warn message', '__WARN']
- )
- })
-
- it('a error message', () => {
- scope.console.error('a error message')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- expect(nativeLogSpy.firstCall.args).eql(
- ['a error message', '__ERROR']
- )
- })
-
- it('debug logLevel', () => {
- global.WXEnvironment.logLevel = 'debug'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(2)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(3)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(4)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(5)
- })
-
- it('log logLevel', () => {
- global.WXEnvironment.logLevel = 'log'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(2)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(3)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(4)
- })
-
- it('info logLevel', () => {
- global.WXEnvironment.logLevel = 'info'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(2)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(3)
- })
-
- it('warn logLevel', () => {
- global.WXEnvironment.logLevel = 'warn'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(2)
- })
-
- it('error logLevel', () => {
- global.WXEnvironment.logLevel = 'error'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- })
-
- it('off logLevel', () => {
- global.WXEnvironment.logLevel = 'off'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- })
-
- it('unknown logLevel', () => {
- global.WXEnvironment.logLevel = 'log'
- scope.console.debug('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(0)
- scope.console.log('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(1)
- scope.console.info('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(2)
- scope.console.warn('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(3)
- scope.console.error('whatever')
- expect(nativeLogSpy.callCount).to.be.equal(4)
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/shared/index.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/shared/index.js b/html5/test/unit/shared/index.js
deleted file mode 100644
index 337bdf1..0000000
--- a/html5/test/unit/shared/index.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as shared from '../../../shared'
-
-describe('a polyfill of', () => {
- it('Promise', () => {
- expect(typeof Promise).to.be.equal('function')
- expect(() => {
- new Promise(sinon.spy()).then(sinon.spy())
- Promise.all()
- Promise.race()
- Promise.resolve()
- Promise.reject()
- }).to.not.throw
- })
-
- it('Object.assign', () => {
- expect(typeof Object.assign).to.be.equal('function')
- })
-
- it('setTimeout', () => {
- expect(typeof setTimeout).to.be.equal('function')
- })
-
- it('console.log', () => {
- expect(typeof console.log).to.be.equal('function')
- })
-})
-
-describe('freeze the prototype of build-in objects', function () {
- before(() => {
- shared.freezePrototype()
- })
-
- it('Object & Object.prototype', () => {
- expect(Object).to.be.frozen
- // expect(Object.prototype).to.be.frozen
- })
- it('Array & Array.prototype', () => {
- expect(Array).to.be.frozen
- expect(Array.prototype).to.be.frozen
- })
-
- it('String.prototype', () => { expect(String.prototype).to.be.frozen })
- it('Number.prototype', () => { expect(Number.prototype).to.be.frozen })
- it('Boolean.prototype', () => { expect(Boolean.prototype).to.be.frozen })
- it('Error.prototype', () => { expect(Error.prototype).to.be.frozen })
- it('Date.prototype', () => { expect(Date.prototype).to.be.frozen })
- it('Math.prototype', () => { expect(Math.prototype).to.be.frozen })
- it('RegExp.prototype', () => { expect(RegExp.prototype).to.be.frozen })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/shared/objectAssign.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/shared/objectAssign.js b/html5/test/unit/shared/objectAssign.js
deleted file mode 100644
index 7c76a4a..0000000
--- a/html5/test/unit/shared/objectAssign.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import '../../../shared/objectAssign'
-
-describe('object.assign', () => {
- it('is a function', () => {
- expect(Object.assign).is.an('function')
- })
-
- it('source to taget', () => {
- const target = {
- a: 'a',
- b: 'b'
- }
- const src1 = {
- b: 'bb',
- c: 'c'
- }
- const src2 = {
- d: 'd',
- a: 'aa'
- }
- Object.assign(target, src1, src2)
- expect(target).to.deep.equal({
- a: 'aa',
- b: 'bb',
- c: 'c',
- d: 'd'
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/shared/objectSetPrototypeOf.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/shared/objectSetPrototypeOf.js b/html5/test/unit/shared/objectSetPrototypeOf.js
deleted file mode 100644
index 58056bc..0000000
--- a/html5/test/unit/shared/objectSetPrototypeOf.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import '../../../shared/objectSetPrototypeOf'
-
-/* eslint-disable */
-describe('Object.setPrototypeOf', () => {
- it('is a function', () => {
- expect(Object.setPrototypeOf).is.an('function')
- })
-
- it('be able to set prototype', () => {
- const JonSnow = { name: 'Jon Snow' }
- Object.setPrototypeOf(JonSnow, {
- know: function() { return 'nothing' }
- })
-
- expect(Object.hasOwnProperty.call(JonSnow, 'name')).to.be.true
- expect(Object.hasOwnProperty.call(JonSnow, 'know')).to.be.false
-
- expect(JonSnow.know()).to.equal('nothing')
-
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/vanilla/index.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/vanilla/index.js b/html5/test/unit/vanilla/index.js
deleted file mode 100644
index 6389c4c..0000000
--- a/html5/test/unit/vanilla/index.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { expect } from 'chai'
-
-import vanilla from '../../../frameworks/vanilla'
-import runtime from '../../../runtime'
-
-// clear ref property in vdom
-function clearRefs (json) {
- delete json.ref
- if (json.children) {
- json.children.forEach(clearRefs)
- }
-}
-
-describe('vanilla test', () => {
- it('standard APIs', () => {
- expect(vanilla.init).to.be.a('function')
- expect(vanilla.createInstance).to.be.a('function')
- expect(vanilla.destroyInstance).to.be.a('function')
- expect(vanilla.getRoot).to.be.a('function')
- expect(vanilla.receiveTasks).to.be.a('function')
- })
-
- it('create & destroy instance', () => {
- const id = 'basic-demo'
- vanilla.init(runtime.config)
- vanilla.createInstance(id, `
- var body = document.createBody()
- var div = document.createElement('div')
- body.appendChild(div)
- `, {})
- vanilla.destroyInstance(id)
- })
-
- it('getRoot', () => {
- const id = 'sample-demo'
- const code = `
- var body = document.createBody()
- var div = document.createElement('div')
- div.setStyle('color', 'red')
- var span = document.createElement('span')
- span.setAttr('value', 'text node')
- div.appendChild(span)
- body.appendChild(div)
- `
- vanilla.init(runtime.config)
- vanilla.createInstance(id, code, {})
-
- const vdom = vanilla.getRoot(id)
- clearRefs(vdom)
- expect(vdom).to.deep.equal({
- // ref: '_root',
- type: 'div',
- attr: {},
- style: {},
- children: [
- {
- // ref: '8',
- type: 'div',
- attr: {},
- style: {
- color: 'red'
- },
- children: [
- {
- // ref: '9',
- type: 'span',
- attr: {
- value: 'text node'
- },
- style: {}
- }
- ]
- }
- ]
- })
-
- vanilla.destroyInstance(id)
- })
-
- describe('receiveTasks', () => {
- const id = 'task-demo'
-
- before(() => {
- vanilla.init(runtime.config)
- vanilla.createInstance(id, `
- var body = document.createBody()
- body.addEvent('click', function() {
- this.setStyle('width', '200')
- })
- document.addCallback(function(message) {
- body.setAttr('from', message)
- })
- `, {})
- })
-
- after(() => {
- vanilla.destroyInstance(id)
- })
-
- it('initial state', () => {
- // initial style and attr in empty
- expect(vanilla.getRoot(id).style).to.deep.equal({})
- expect(vanilla.getRoot(id).attr).to.deep.equal({})
-
- // empty task
- vanilla.receiveTasks(id, [])
- })
-
- it('invalid tasks', () => {
- vanilla.receiveTasks('invalid id', [])
- vanilla.receiveTasks(id, {})
- vanilla.receiveTasks(id, [{
- method: 'whatever',
- args: []
- }])
- })
-
- it('fireEvent', () => {
- vanilla.receiveTasks(id, [{
- method: 'fireEvent',
- args: ['_root', 'click']
- }])
- expect(vanilla.getRoot(id).style).to.deep.equal({ width: '200' })
- })
-
- it('callback', () => {
- vanilla.receiveTasks(id, [{
- method: 'callback',
- args: ['1', 'callback']
- }])
- expect(vanilla.getRoot(id).attr).to.deep.equal({ from: 'callback' })
-
- // last callback
- vanilla.receiveTasks(id, [{
- method: 'callback',
- args: ['1', 'last message', true]
- }])
- expect(vanilla.getRoot(id).attr).to.deep.equal({ from: 'last message' })
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/WeexInstance.js
----------------------------------------------------------------------
diff --git a/runtime/api/WeexInstance.js b/runtime/api/WeexInstance.js
new file mode 100644
index 0000000..3bc25e6
--- /dev/null
+++ b/runtime/api/WeexInstance.js
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import Document from '../vdom/Document'
+import { isRegisteredModule, getModuleDescription } from './module'
+import { isRegisteredComponent } from './component'
+import { getTaskCenter } from '../vdom/operation'
+
+const moduleProxies = {}
+
+function setId (weex, id) {
+ Object.defineProperty(weex, '[[CurrentInstanceId]]', { value: id })
+}
+
+function getId (weex) {
+ return weex['[[CurrentInstanceId]]']
+}
+
+function moduleGetter (id, module, method) {
+ const taskCenter = getTaskCenter(id)
+ if (!taskCenter || typeof taskCenter.send !== 'function') {
+ console.error(`[JS Framework] Failed to find taskCenter (${id}).`)
+ return null
+ }
+ return (...args) => taskCenter.send('module', { module, method }, args)
+}
+
+function moduleSetter (id, module, method, fn) {
+ const taskCenter = getTaskCenter(id)
+ if (!taskCenter || typeof taskCenter.send !== 'function') {
+ console.error(`[JS Framework] Failed to find taskCenter (${id}).`)
+ return null
+ }
+ if (typeof fn !== 'function') {
+ console.error(`[JS Framework] ${module}.${method} must be assigned as a function.`)
+ return null
+ }
+ return fn => taskCenter.send('module', { module, method }, [fn])
+}
+
+export default class WeexInstance {
+ constructor (id, config) {
+ setId(this, String(id))
+ this.config = config || {}
+ this.document = new Document(id, this.config.bundleUrl)
+ this.requireModule = this.requireModule.bind(this)
+ this.isRegisteredModule = isRegisteredModule
+ this.isRegisteredComponent = isRegisteredComponent
+ }
+
+ requireModule (moduleName) {
+ const id = getId(this)
+ if (!(id && this.document && this.document.taskCenter)) {
+ console.error(`[JS Framework] Failed to requireModule("${moduleName}"), `
+ + `instance (${id}) doesn't exist anymore.`)
+ return
+ }
+
+ // warn for unknown module
+ if (!isRegisteredModule(moduleName)) {
+ console.warn(`[JS Framework] using unregistered weex module "${moduleName}"`)
+ return
+ }
+
+ // create new module proxy
+ const proxyName = `${moduleName}#${id}`
+ if (!moduleProxies[proxyName]) {
+ // create registered module apis
+ const moduleDefine = getModuleDescription(moduleName)
+ const moduleApis = {}
+ for (const methodName in moduleDefine) {
+ Object.defineProperty(moduleApis, methodName, {
+ enumerable: true,
+ configurable: true,
+ get: () => moduleGetter(id, moduleName, methodName),
+ set: fn => moduleSetter(id, moduleName, methodName, fn)
+ })
+ }
+
+ // create module Proxy
+ if (typeof Proxy === 'function') {
+ moduleProxies[proxyName] = new Proxy(moduleApis, {
+ get (target, methodName) {
+ if (methodName in target) {
+ return target[methodName]
+ }
+ console.warn(`[JS Framework] using unregistered method "${moduleName}.${methodName}"`)
+ return moduleGetter(id, moduleName, methodName)
+ }
+ })
+ }
+ else {
+ moduleProxies[proxyName] = moduleApis
+ }
+ }
+
+ return moduleProxies[proxyName]
+ }
+
+ supports (condition) {
+ if (typeof condition !== 'string') return null
+
+ const res = condition.match(/^@(\w+)\/(\w+)(\.(\w+))?$/i)
+ if (res) {
+ const type = res[1]
+ const name = res[2]
+ const method = res[4]
+ switch (type) {
+ case 'module': return isRegisteredModule(name, method)
+ case 'component': return isRegisteredComponent(name)
+ }
+ }
+
+ return null
+ }
+
+ // registerStyleSheet (styles) {
+ // if (this.document) {
+ // this.document.registerStyleSheet(styles)
+ // }
+ // }
+}
[20/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
* [jsfm] Adjust the file structure of js framework
1. Rename `html5/` to `runtime/` and move api, bridge, vdom out:
rename: html5/frameworks -> runtime/frameworks
rename: html5/runtime/api -> runtime/api
rename: html5/runtime/bridge -> runtime/bridge
rename: html5/runtime/vdom -> runtime/vdom
rename: html5/runtime/utils.js -> runtime/shared/utils.js
rename: html5/services -> runtime/services
rename: html5/shared -> runtime/shared
2. Delete `html5/render/`, move it to `entries`:
delete: html5/render/
rename: html5/runtime/index.js -> runtime/entries/runtime.js
rename: html5/render/native/index.js -> runtime/entries/index.js
rename: html5/render/native/setup.js -> runtime/entries/setup.js
3. Move `html5/test` into `test/` folder:
rename: html5/test -> test/js-framework
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/51dd277e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/51dd277e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/51dd277e
Branch: refs/heads/master
Commit: 51dd277e5cd579c7fda524a0a0972e2972d04ab8
Parents: dc42844
Author: Hanks <zh...@gmail.com>
Authored: Fri Dec 29 20:37:26 2017 +0800
Committer: Hanks <zh...@gmail.com>
Committed: Fri Dec 29 20:58:12 2017 +0800
----------------------------------------------------------------------
html5/frameworks/index.js | 29 -
html5/frameworks/legacy/api/methods.js | 194 --
html5/frameworks/legacy/api/modules.js | 96 -
html5/frameworks/legacy/app/bundle/bootstrap.js | 90 -
html5/frameworks/legacy/app/bundle/define.js | 115 -
html5/frameworks/legacy/app/bundle/index.js | 34 -
html5/frameworks/legacy/app/ctrl/index.js | 40 -
html5/frameworks/legacy/app/ctrl/init.js | 215 --
html5/frameworks/legacy/app/ctrl/misc.js | 206 --
html5/frameworks/legacy/app/differ.js | 91 -
html5/frameworks/legacy/app/downgrade.js | 172 --
html5/frameworks/legacy/app/index.js | 55 -
html5/frameworks/legacy/app/instance.js | 47 -
html5/frameworks/legacy/app/register.js | 131 --
html5/frameworks/legacy/app/viewport.js | 56 -
html5/frameworks/legacy/config.js | 35 -
html5/frameworks/legacy/core/LICENSE | 21 -
html5/frameworks/legacy/core/array.js | 100 -
html5/frameworks/legacy/core/dep.js | 80 -
html5/frameworks/legacy/core/object.js | 91 -
html5/frameworks/legacy/core/observer.js | 323 ---
html5/frameworks/legacy/core/state.js | 92 -
html5/frameworks/legacy/core/watcher.js | 254 ---
html5/frameworks/legacy/index.js | 40 -
html5/frameworks/legacy/static/bridge.js | 56 -
html5/frameworks/legacy/static/create.js | 51 -
html5/frameworks/legacy/static/life.js | 91 -
html5/frameworks/legacy/static/map.js | 19 -
html5/frameworks/legacy/static/misc.js | 40 -
html5/frameworks/legacy/static/register.js | 75 -
html5/frameworks/legacy/util/LICENSE | 21 -
html5/frameworks/legacy/util/index.js | 156 --
html5/frameworks/legacy/util/shared.js | 162 --
html5/frameworks/legacy/vm/compiler.js | 636 ------
html5/frameworks/legacy/vm/directive.js | 377 ----
html5/frameworks/legacy/vm/dom-helper.js | 258 ---
html5/frameworks/legacy/vm/events.js | 179 --
html5/frameworks/legacy/vm/index.js | 131 --
html5/frameworks/vanilla/index.js | 110 -
html5/render/native/index.js | 22 -
html5/render/native/setup.js | 58 -
html5/render/vue/README.md | 3 -
html5/runtime/api/WeexInstance.js | 138 --
html5/runtime/api/component.js | 51 -
html5/runtime/api/config.js | 37 -
html5/runtime/api/init.js | 304 ---
html5/runtime/api/module.js | 56 -
html5/runtime/api/service.js | 77 -
html5/runtime/bridge/CallbackManager.js | 89 -
html5/runtime/bridge/Handler.js | 91 -
html5/runtime/bridge/Listener.js | 220 --
html5/runtime/bridge/TaskCenter.js | 145 --
html5/runtime/bridge/debug.js | 65 -
html5/runtime/bridge/normalize.js | 91 -
html5/runtime/bridge/receiver.js | 71 -
html5/runtime/index.js | 55 -
html5/runtime/utils.js | 71 -
html5/runtime/vdom/Comment.js | 43 -
html5/runtime/vdom/Document.js | 189 --
html5/runtime/vdom/Element.js | 524 -----
html5/runtime/vdom/Node.js | 47 -
html5/runtime/vdom/WeexElement.js | 84 -
html5/runtime/vdom/index.js | 37 -
html5/runtime/vdom/operation.js | 272 ---
html5/services/amd/index.js | 105 -
html5/services/broadcast-channel/index.js | 125 --
.../services/broadcast-channel/message-event.js | 40 -
html5/services/index.js | 23 -
html5/shared/arrayFrom.js | 105 -
html5/shared/console.js | 137 --
html5/shared/freeze.js | 90 -
html5/shared/index.js | 32 -
html5/shared/objectAssign.js | 19 -
html5/shared/objectSetPrototypeOf.js | 74 -
html5/shared/promise.js | 28 -
html5/shared/setTimeout.js | 63 -
html5/test/case/.eslintrc | 9 -
html5/test/case/basic/append-root.output.js | 36 -
html5/test/case/basic/append-root.source.js | 75 -
html5/test/case/basic/append.output.js | 79 -
html5/test/case/basic/append.source.js | 123 --
html5/test/case/basic/backward1.output.js | 57 -
html5/test/case/basic/backward1.source.js | 113 -
html5/test/case/basic/backward2.output.js | 57 -
html5/test/case/basic/backward2.source.js | 113 -
html5/test/case/basic/components.output.js | 20 -
html5/test/case/basic/components.source.js | 101 -
.../case/basic/computed-in-repeat.output.js | 19 -
.../case/basic/computed-in-repeat.source.js | 82 -
html5/test/case/basic/created.output.js | 11 -
html5/test/case/basic/created.source.js | 56 -
html5/test/case/basic/dynamic-id.output.js | 44 -
html5/test/case/basic/dynamic-id.source.js | 94 -
.../test/case/basic/dynamic-property.output.js | 24 -
.../test/case/basic/dynamic-property.source.js | 79 -
html5/test/case/basic/dynamic-type.output.js | 10 -
html5/test/case/basic/dynamic-type.source.js | 45 -
html5/test/case/basic/foo.output.js | 3 -
html5/test/case/basic/foo.source.js | 44 -
html5/test/case/basic/foo2.output.js | 10 -
html5/test/case/basic/foo2.source.js | 52 -
html5/test/case/basic/foo3.output.js | 9 -
html5/test/case/basic/foo3.source.js | 41 -
html5/test/case/basic/foo4.output.js | 12 -
html5/test/case/basic/foo4.source.js | 44 -
html5/test/case/basic/foo5.output.js | 14 -
html5/test/case/basic/foo5.source.js | 50 -
html5/test/case/basic/foo6.output.js | 28 -
html5/test/case/basic/foo6.source.js | 71 -
html5/test/case/basic/foo7.output.js | 26 -
html5/test/case/basic/foo7.source.js | 76 -
html5/test/case/basic/foo8.output.js | 60 -
html5/test/case/basic/foo8.source.js | 91 -
html5/test/case/basic/foo9.output.js | 57 -
html5/test/case/basic/foo9.source.js | 113 -
.../case/basic/global-weex-object.output.js | 6 -
.../case/basic/global-weex-object.source.js | 37 -
html5/test/case/basic/id.output.js | 32 -
html5/test/case/basic/id.source.js | 80 -
html5/test/case/basic/if-repeat.output.js | 13 -
html5/test/case/basic/if-repeat.source.js | 60 -
html5/test/case/basic/if-root.output.js | 1 -
html5/test/case/basic/if-root.source.js | 44 -
html5/test/case/basic/if.output.js | 13 -
html5/test/case/basic/if.source.js | 57 -
html5/test/case/basic/promise.output.js | 3 -
html5/test/case/basic/promise.source.js | 47 -
html5/test/case/basic/ready.output.js | 11 -
html5/test/case/basic/ready.source.js | 56 -
html5/test/case/basic/repeat-array-kv.output.js | 22 -
html5/test/case/basic/repeat-array-kv.source.js | 63 -
.../case/basic/repeat-array-no-kv.output.js | 22 -
.../case/basic/repeat-array-no-kv.source.js | 61 -
.../case/basic/repeat-array-non-obj.output.js | 22 -
.../case/basic/repeat-array-non-obj.source.js | 62 -
html5/test/case/basic/repeat-array-v.output.js | 22 -
html5/test/case/basic/repeat-array-v.source.js | 62 -
html5/test/case/basic/repeat-index.output.js | 22 -
html5/test/case/basic/repeat-index.source.js | 59 -
html5/test/case/basic/repeat-root.output.js | 1 -
html5/test/case/basic/repeat-root.source.js | 47 -
html5/test/case/basic/repeat-watch.output.js | 46 -
html5/test/case/basic/repeat-watch.source.js | 75 -
html5/test/case/basic/require.output.js | 9 -
html5/test/case/basic/require.source.js | 52 -
html5/test/case/basic/reset-style.output.js | 15 -
html5/test/case/basic/reset-style.source.js | 58 -
html5/test/case/basic/static1.output.js | 12 -
html5/test/case/basic/static1.source.js | 51 -
html5/test/case/basic/static2.output.js | 30 -
html5/test/case/basic/static2.source.js | 62 -
html5/test/case/basic/static3.output.js | 33 -
html5/test/case/basic/static3.source.js | 62 -
html5/test/case/basic/static4.output.js | 35 -
html5/test/case/basic/static4.source.js | 93 -
html5/test/case/basic/subvm.output.js | 20 -
html5/test/case/basic/subvm.source.js | 98 -
html5/test/case/basic/transformer1.output.js | 3 -
html5/test/case/basic/transformer1.source.js | 46 -
.../case/complex/append-root-event.output.js | 13 -
.../case/complex/append-root-event.source.js | 63 -
html5/test/case/complex/click.output.js | 26 -
html5/test/case/complex/click.source.js | 76 -
.../complex/component-append-tree.output.js | 22 -
.../complex/component-append-tree.source.js | 87 -
html5/test/case/complex/computed.output.js | 15 -
html5/test/case/complex/computed.source.js | 72 -
html5/test/case/complex/if-refresh.output.js | 3 -
html5/test/case/complex/if-refresh.source.js | 57 -
.../case/complex/if-repeat-refresh.output.js | 22 -
.../case/complex/if-repeat-refresh.source.js | 60 -
html5/test/case/complex/inline-click.output.js | 14 -
html5/test/case/complex/inline-click.source.js | 54 -
html5/test/case/complex/input-binding.output.js | 12 -
html5/test/case/complex/input-binding.source.js | 78 -
html5/test/case/complex/refresh2.output.js | 20 -
html5/test/case/complex/refresh2.source.js | 133 --
.../test/case/complex/repeat-track-by.output.js | 24 -
.../test/case/complex/repeat-track-by.source.js | 64 -
html5/test/case/complex/transformer2.output.js | 3 -
html5/test/case/complex/transformer2.source.js | 46 -
html5/test/case/complex/transformer3.output.js | 3 -
html5/test/case/complex/transformer3.source.js | 46 -
.../case/multi/clear-dep-target-error.source.js | 45 -
.../case/multi/clear-dep-target-fine.output.js | 11 -
.../case/multi/clear-dep-target-fine.source.js | 48 -
html5/test/case/multi/clear-moduleA.output.js | 12 -
html5/test/case/multi/clear-moduleA.source.js | 61 -
html5/test/case/multi/clear-moduleB.output.js | 11 -
html5/test/case/multi/clear-moduleB.source.js | 50 -
html5/test/case/prepare.js | 83 -
html5/test/case/signals/modal.output.js | 9 -
html5/test/case/signals/modal.source.js | 60 -
html5/test/case/signals/signals-long.source.js | 1223 -----------
html5/test/case/signals/signals.source.js | 84 -
html5/test/case/signals/timer.output.js | 9 -
html5/test/case/signals/timer.source.js | 54 -
html5/test/case/tester.js | 528 -----
.../test/case/throws/global-variable1.source.js | 35 -
.../test/case/throws/global-variable2.source.js | 33 -
.../test/case/throws/global-variable3.source.js | 40 -
html5/test/unit/default/api/methods.js | 190 --
html5/test/unit/default/api/modules.js | 43 -
html5/test/unit/default/app/bundle.js | 409 ----
html5/test/unit/default/app/ctrl.js | 230 --
html5/test/unit/default/app/downgrade.js | 265 ---
html5/test/unit/default/app/index.js | 147 --
html5/test/unit/default/app/register.js | 200 --
html5/test/unit/default/app/viewport.js | 79 -
html5/test/unit/default/util/index.js | 185 --
html5/test/unit/default/util/shared.js | 143 --
html5/test/unit/default/vm/directive.js | 228 --
html5/test/unit/default/vm/dom-helper.js | 405 ----
html5/test/unit/default/vm/events.js | 416 ----
html5/test/unit/default/vm/vm.js | 1975 ------------------
html5/test/unit/runtime/legacy-framework.js | 348 ---
html5/test/unit/runtime/runner/helper.js | 73 -
html5/test/unit/runtime/runner/vanilla.js | 59 -
html5/test/unit/runtime/runner/vue.js | 67 -
html5/test/unit/runtime/utils.js | 41 -
html5/test/unit/runtime/vdom/index.js | 639 ------
html5/test/unit/runtime/vdom/listener.js | 381 ----
html5/test/unit/runtime/vdom/node.js | 39 -
html5/test/unit/shared/BroadcastChannel.js | 231 --
html5/test/unit/shared/arrayFrom.js | 90 -
html5/test/unit/shared/console.js | 224 --
html5/test/unit/shared/index.js | 73 -
html5/test/unit/shared/objectAssign.js | 50 -
html5/test/unit/shared/objectSetPrototypeOf.js | 42 -
html5/test/unit/vanilla/index.js | 159 --
runtime/api/WeexInstance.js | 138 ++
runtime/api/component.js | 51 +
runtime/api/config.js | 37 +
runtime/api/index.js | 40 +
runtime/api/init.js | 304 +++
runtime/api/module.js | 56 +
runtime/api/service.js | 77 +
runtime/bridge/CallbackManager.js | 89 +
runtime/bridge/Handler.js | 91 +
runtime/bridge/Listener.js | 220 ++
runtime/bridge/TaskCenter.js | 145 ++
runtime/bridge/debug.js | 65 +
runtime/bridge/normalize.js | 91 +
runtime/bridge/receiver.js | 71 +
runtime/entries/index.js | 23 +
runtime/entries/rax.js | 23 +
runtime/entries/setup.js | 60 +
runtime/entries/vue.js | 23 +
runtime/frameworks/index.js | 29 +
runtime/frameworks/legacy/api/methods.js | 194 ++
runtime/frameworks/legacy/api/modules.js | 96 +
.../frameworks/legacy/app/bundle/bootstrap.js | 90 +
runtime/frameworks/legacy/app/bundle/define.js | 115 +
runtime/frameworks/legacy/app/bundle/index.js | 34 +
runtime/frameworks/legacy/app/ctrl/index.js | 40 +
runtime/frameworks/legacy/app/ctrl/init.js | 215 ++
runtime/frameworks/legacy/app/ctrl/misc.js | 206 ++
runtime/frameworks/legacy/app/differ.js | 91 +
runtime/frameworks/legacy/app/downgrade.js | 172 ++
runtime/frameworks/legacy/app/index.js | 55 +
runtime/frameworks/legacy/app/instance.js | 47 +
runtime/frameworks/legacy/app/register.js | 131 ++
runtime/frameworks/legacy/app/viewport.js | 56 +
runtime/frameworks/legacy/config.js | 35 +
runtime/frameworks/legacy/core/LICENSE | 21 +
runtime/frameworks/legacy/core/array.js | 100 +
runtime/frameworks/legacy/core/dep.js | 80 +
runtime/frameworks/legacy/core/object.js | 91 +
runtime/frameworks/legacy/core/observer.js | 323 +++
runtime/frameworks/legacy/core/state.js | 92 +
runtime/frameworks/legacy/core/watcher.js | 254 +++
runtime/frameworks/legacy/index.js | 40 +
runtime/frameworks/legacy/static/bridge.js | 56 +
runtime/frameworks/legacy/static/create.js | 51 +
runtime/frameworks/legacy/static/life.js | 91 +
runtime/frameworks/legacy/static/map.js | 19 +
runtime/frameworks/legacy/static/misc.js | 40 +
runtime/frameworks/legacy/static/register.js | 75 +
runtime/frameworks/legacy/util/LICENSE | 21 +
runtime/frameworks/legacy/util/index.js | 156 ++
runtime/frameworks/legacy/util/shared.js | 162 ++
runtime/frameworks/legacy/vm/compiler.js | 636 ++++++
runtime/frameworks/legacy/vm/directive.js | 377 ++++
runtime/frameworks/legacy/vm/dom-helper.js | 258 +++
runtime/frameworks/legacy/vm/events.js | 179 ++
runtime/frameworks/legacy/vm/index.js | 131 ++
runtime/frameworks/vanilla/index.js | 110 +
runtime/services/amd/index.js | 105 +
runtime/services/broadcast-channel/index.js | 125 ++
.../services/broadcast-channel/message-event.js | 40 +
runtime/services/index.js | 23 +
runtime/shared/env/console.js | 137 ++
runtime/shared/env/freeze.js | 90 +
runtime/shared/env/setTimeout.js | 63 +
runtime/shared/index.js | 33 +
runtime/shared/polyfill/arrayFrom.js | 105 +
runtime/shared/polyfill/objectAssign.js | 19 +
runtime/shared/polyfill/objectSetPrototypeOf.js | 74 +
runtime/shared/polyfill/promise.js | 28 +
runtime/shared/utils.js | 71 +
runtime/vdom/Comment.js | 43 +
runtime/vdom/Document.js | 189 ++
runtime/vdom/Element.js | 524 +++++
runtime/vdom/Node.js | 47 +
runtime/vdom/WeexElement.js | 84 +
runtime/vdom/index.js | 37 +
runtime/vdom/operation.js | 272 +++
test/js-framework/case/.eslintrc | 9 +
.../case/basic/append-root.output.js | 36 +
.../case/basic/append-root.source.js | 75 +
test/js-framework/case/basic/append.output.js | 79 +
test/js-framework/case/basic/append.source.js | 123 ++
.../js-framework/case/basic/backward1.output.js | 57 +
.../js-framework/case/basic/backward1.source.js | 113 +
.../js-framework/case/basic/backward2.output.js | 57 +
.../js-framework/case/basic/backward2.source.js | 113 +
.../case/basic/components.output.js | 20 +
.../case/basic/components.source.js | 101 +
.../case/basic/computed-in-repeat.output.js | 19 +
.../case/basic/computed-in-repeat.source.js | 82 +
test/js-framework/case/basic/created.output.js | 11 +
test/js-framework/case/basic/created.source.js | 56 +
.../case/basic/dynamic-id.output.js | 44 +
.../case/basic/dynamic-id.source.js | 94 +
.../case/basic/dynamic-property.output.js | 24 +
.../case/basic/dynamic-property.source.js | 79 +
.../case/basic/dynamic-type.output.js | 10 +
.../case/basic/dynamic-type.source.js | 45 +
test/js-framework/case/basic/foo.output.js | 3 +
test/js-framework/case/basic/foo.source.js | 44 +
test/js-framework/case/basic/foo2.output.js | 10 +
test/js-framework/case/basic/foo2.source.js | 52 +
test/js-framework/case/basic/foo3.output.js | 9 +
test/js-framework/case/basic/foo3.source.js | 41 +
test/js-framework/case/basic/foo4.output.js | 12 +
test/js-framework/case/basic/foo4.source.js | 44 +
test/js-framework/case/basic/foo5.output.js | 14 +
test/js-framework/case/basic/foo5.source.js | 50 +
test/js-framework/case/basic/foo6.output.js | 28 +
test/js-framework/case/basic/foo6.source.js | 71 +
test/js-framework/case/basic/foo7.output.js | 26 +
test/js-framework/case/basic/foo7.source.js | 76 +
test/js-framework/case/basic/foo8.output.js | 60 +
test/js-framework/case/basic/foo8.source.js | 91 +
test/js-framework/case/basic/foo9.output.js | 57 +
test/js-framework/case/basic/foo9.source.js | 113 +
.../case/basic/global-weex-object.output.js | 6 +
.../case/basic/global-weex-object.source.js | 37 +
test/js-framework/case/basic/id.output.js | 32 +
test/js-framework/case/basic/id.source.js | 80 +
.../js-framework/case/basic/if-repeat.output.js | 13 +
.../js-framework/case/basic/if-repeat.source.js | 60 +
test/js-framework/case/basic/if-root.output.js | 1 +
test/js-framework/case/basic/if-root.source.js | 44 +
test/js-framework/case/basic/if.output.js | 13 +
test/js-framework/case/basic/if.source.js | 57 +
test/js-framework/case/basic/promise.output.js | 3 +
test/js-framework/case/basic/promise.source.js | 47 +
test/js-framework/case/basic/ready.output.js | 11 +
test/js-framework/case/basic/ready.source.js | 56 +
.../case/basic/repeat-array-kv.output.js | 22 +
.../case/basic/repeat-array-kv.source.js | 63 +
.../case/basic/repeat-array-no-kv.output.js | 22 +
.../case/basic/repeat-array-no-kv.source.js | 61 +
.../case/basic/repeat-array-non-obj.output.js | 22 +
.../case/basic/repeat-array-non-obj.source.js | 62 +
.../case/basic/repeat-array-v.output.js | 22 +
.../case/basic/repeat-array-v.source.js | 62 +
.../case/basic/repeat-index.output.js | 22 +
.../case/basic/repeat-index.source.js | 59 +
.../case/basic/repeat-root.output.js | 1 +
.../case/basic/repeat-root.source.js | 47 +
.../case/basic/repeat-watch.output.js | 46 +
.../case/basic/repeat-watch.source.js | 75 +
test/js-framework/case/basic/require.output.js | 9 +
test/js-framework/case/basic/require.source.js | 52 +
.../case/basic/reset-style.output.js | 15 +
.../case/basic/reset-style.source.js | 58 +
test/js-framework/case/basic/static1.output.js | 12 +
test/js-framework/case/basic/static1.source.js | 51 +
test/js-framework/case/basic/static2.output.js | 30 +
test/js-framework/case/basic/static2.source.js | 62 +
test/js-framework/case/basic/static3.output.js | 33 +
test/js-framework/case/basic/static3.source.js | 62 +
test/js-framework/case/basic/static4.output.js | 35 +
test/js-framework/case/basic/static4.source.js | 93 +
test/js-framework/case/basic/subvm.output.js | 20 +
test/js-framework/case/basic/subvm.source.js | 98 +
.../case/basic/transformer1.output.js | 3 +
.../case/basic/transformer1.source.js | 46 +
.../case/complex/append-root-event.output.js | 13 +
.../case/complex/append-root-event.source.js | 63 +
test/js-framework/case/complex/click.output.js | 26 +
test/js-framework/case/complex/click.source.js | 76 +
.../complex/component-append-tree.output.js | 22 +
.../complex/component-append-tree.source.js | 87 +
.../case/complex/computed.output.js | 15 +
.../case/complex/computed.source.js | 72 +
.../case/complex/if-refresh.output.js | 3 +
.../case/complex/if-refresh.source.js | 57 +
.../case/complex/if-repeat-refresh.output.js | 22 +
.../case/complex/if-repeat-refresh.source.js | 60 +
.../case/complex/inline-click.output.js | 14 +
.../case/complex/inline-click.source.js | 54 +
.../case/complex/input-binding.output.js | 12 +
.../case/complex/input-binding.source.js | 78 +
.../case/complex/refresh2.output.js | 20 +
.../case/complex/refresh2.source.js | 133 ++
.../case/complex/repeat-track-by.output.js | 24 +
.../case/complex/repeat-track-by.source.js | 64 +
.../case/complex/transformer2.output.js | 3 +
.../case/complex/transformer2.source.js | 46 +
.../case/complex/transformer3.output.js | 3 +
.../case/complex/transformer3.source.js | 46 +
.../case/multi/clear-dep-target-error.source.js | 45 +
.../case/multi/clear-dep-target-fine.output.js | 11 +
.../case/multi/clear-dep-target-fine.source.js | 48 +
.../case/multi/clear-moduleA.output.js | 12 +
.../case/multi/clear-moduleA.source.js | 61 +
.../case/multi/clear-moduleB.output.js | 11 +
.../case/multi/clear-moduleB.source.js | 50 +
test/js-framework/case/prepare.js | 83 +
test/js-framework/case/signals/modal.output.js | 9 +
test/js-framework/case/signals/modal.source.js | 60 +
.../case/signals/signals-long.source.js | 1223 +++++++++++
.../js-framework/case/signals/signals.source.js | 84 +
test/js-framework/case/signals/timer.output.js | 9 +
test/js-framework/case/signals/timer.source.js | 54 +
test/js-framework/case/tester.js | 528 +++++
.../case/throws/global-variable1.source.js | 35 +
.../case/throws/global-variable2.source.js | 33 +
.../case/throws/global-variable3.source.js | 40 +
test/js-framework/unit/default/api/methods.js | 190 ++
test/js-framework/unit/default/api/modules.js | 43 +
test/js-framework/unit/default/app/bundle.js | 409 ++++
test/js-framework/unit/default/app/ctrl.js | 230 ++
test/js-framework/unit/default/app/downgrade.js | 265 +++
test/js-framework/unit/default/app/index.js | 147 ++
test/js-framework/unit/default/app/register.js | 200 ++
test/js-framework/unit/default/app/viewport.js | 79 +
test/js-framework/unit/default/util/index.js | 185 ++
test/js-framework/unit/default/util/shared.js | 143 ++
test/js-framework/unit/default/vm/directive.js | 228 ++
test/js-framework/unit/default/vm/dom-helper.js | 405 ++++
test/js-framework/unit/default/vm/events.js | 416 ++++
test/js-framework/unit/default/vm/vm.js | 1975 ++++++++++++++++++
.../unit/runtime/legacy-framework.js | 348 +++
test/js-framework/unit/runtime/runner/helper.js | 73 +
.../js-framework/unit/runtime/runner/vanilla.js | 59 +
test/js-framework/unit/runtime/runner/vue.js | 67 +
test/js-framework/unit/runtime/utils.js | 41 +
test/js-framework/unit/runtime/vdom/index.js | 639 ++++++
test/js-framework/unit/runtime/vdom/listener.js | 381 ++++
test/js-framework/unit/runtime/vdom/node.js | 39 +
.../unit/shared/BroadcastChannel.js | 231 ++
test/js-framework/unit/shared/arrayFrom.js | 90 +
test/js-framework/unit/shared/console.js | 227 ++
test/js-framework/unit/shared/index.js | 73 +
test/js-framework/unit/shared/objectAssign.js | 50 +
.../unit/shared/objectSetPrototypeOf.js | 42 +
test/js-framework/unit/vanilla/index.js | 159 ++
461 files changed, 23298 insertions(+), 23263 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/index.js b/html5/frameworks/index.js
deleted file mode 100644
index 8880f75..0000000
--- a/html5/frameworks/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import * as Vanilla from './vanilla/index'
-import * as Vue from 'weex-vue-framework'
-import * as Weex from './legacy/index'
-import Rax from 'weex-rax-framework'
-
-export default {
- Vanilla,
- Vue,
- Rax,
- Weex
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/api/methods.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/api/methods.js b/html5/frameworks/legacy/api/methods.js
deleted file mode 100644
index 19f1cdc..0000000
--- a/html5/frameworks/legacy/api/methods.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview The api for invoking with "$" prefix
- */
-
-/**
- * @deprecated use $vm instead
- * find the vm by id
- * Note: there is only one id in whole component
- * @param {string} id
- * @return {Vm}
- */
-export function $ (id) {
- console.warn('[JS Framework] Vm#$ is deprecated, please use Vm#$vm instead')
- const info = this._ids[id]
- if (info) {
- return info.vm
- }
-}
-
-/**
- * find the element by id
- * Note: there is only one id in whole component
- * @param {string} id
- * @return {Element}
- */
-export function $el (id) {
- const info = this._ids[id]
- if (info) {
- return info.el
- }
-}
-
-/**
- * find the vm of the custom component by id
- * Note: there is only one id in whole component
- * @param {string} id
- * @return {Vm}
- */
-export function $vm (id) {
- const info = this._ids[id]
- if (info) {
- return info.vm
- }
-}
-
-/**
- * Fire when differ rendering finished
- *
- * @param {Function} fn
- */
-export function $renderThen (fn) {
- const app = this._app
- const differ = app.differ
- return differ.then(() => {
- fn()
- })
-}
-
-/**
- * scroll an element specified by id into view,
- * moreover specify a number of offset optionally
- * @param {string} id
- * @param {number} offset
- */
-export function $scrollTo (id, offset) {
- console.warn('[JS Framework] Vm#$scrollTo is deprecated, ' +
- 'please use "require(\'@weex-module/dom\')' +
- '.scrollTo(el, options)" instead')
- const el = this.$el(id)
- if (el) {
- const dom = this._app.requireModule('dom')
- dom.scrollToElement(el.ref, { offset: offset })
- }
-}
-
-/**
- * perform transition animation on an element specified by id
- * @param {string} id
- * @param {object} options
- * @param {object} options.styles
- * @param {object} options.duration(ms)
- * @param {object} [options.timingFunction]
- * @param {object} [options.delay=0(ms)]
- * @param {Function} callback
- */
-export function $transition (id, options, callback) {
- const el = this.$el(id)
- if (el && options && options.styles) {
- const animation = this._app.requireModule('animation')
- animation.transition(el.ref, options, (...args) => {
- this._setStyle(el, options.styles)
- callback && callback(...args)
- })
- }
-}
-
-/**
- * get some config
- * @return {object} some config for app instance
- * @property {string} bundleUrl
- * @property {boolean} debug
- * @property {object} env
- * @property {string} env.weexVersion(ex. 1.0.0)
- * @property {string} env.appName(ex. TB/TM)
- * @property {string} env.appVersion(ex. 5.0.0)
- * @property {string} env.platform(ex. iOS/Android)
- * @property {string} env.osVersion(ex. 7.0.0)
- * @property {string} env.deviceModel **native only**
- * @property {number} env.[deviceWidth=750]
- * @property {number} env.deviceHeight
- */
-export function $getConfig (callback) {
- const config = this._app.options
- if (typeof callback === 'function') {
- console.warn('[JS Framework] the callback of Vm#$getConfig(callback) is deprecated, ' +
- 'this api now can directly RETURN config info.')
- callback(config)
- }
- return config
-}
-
-/**
- * @deprecated
- * request network via http protocol
- * @param {object} params
- * @param {Function} callback
- */
-export function $sendHttp (params, callback) {
- console.warn('[JS Framework] Vm#$sendHttp is deprecated, ' +
- 'please use "require(\'@weex-module/stream\')' +
- '.sendHttp(params, callback)" instead')
- const stream = this._app.requireModule('stream')
- stream.sendHttp(params, callback)
-}
-
-/**
- * @deprecated
- * open a url
- * @param {string} url
- */
-export function $openURL (url) {
- console.warn('[JS Framework] Vm#$openURL is deprecated, ' +
- 'please use "require(\'@weex-module/event\')' +
- '.openURL(url)" instead')
- const event = this._app.requireModule('event')
- event.openURL(url)
-}
-
-/**
- * @deprecated
- * set a title for page
- * @param {string} title
- */
-export function $setTitle (title) {
- console.warn('[JS Framework] Vm#$setTitle is deprecated, ' +
- 'please use "require(\'@weex-module/pageInfo\')' +
- '.setTitle(title)" instead')
- const pageInfo = this._app.requireModule('pageInfo')
- pageInfo.setTitle(title)
-}
-
-/**
- * @deprecated use "require('@weex-module/moduleName') instead"
- * invoke a native method by specifing the name of module and method
- * @param {string} moduleName
- * @param {string} methodName
- * @param {...*} the rest arguments
- */
-export function $call (moduleName, methodName, ...args) {
- console.warn('[JS Framework] Vm#$call is deprecated, ' +
- 'please use "require(\'@weex-module/moduleName\')" instead')
- const module = this._app.requireModule(moduleName)
- if (module && module[methodName]) {
- module[methodName](...args)
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/api/modules.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/api/modules.js b/html5/frameworks/legacy/api/modules.js
deleted file mode 100644
index 60123b0..0000000
--- a/html5/frameworks/legacy/api/modules.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @deprecated after native register these modules
- */
-
-/**
- * @module dom
- * @type {Array}
- */
-export const dom = [
- /**
- * @method scrollToElement
- * @param {string} ref
- * @param {object} options
- * @param {number} options.offset
- */
- {
- name: 'scrollToElement',
- args: ['string', 'object']
- }
-]
-
-/**
- * @module stream
- */
-export const stream = [
- /**
- * @method sendHttp
- * @param {object} params
- * @param {string} params.url
- * @param {string} [params.method]
- * @param {object} [params.header]
- * @param {object} params.body
- * @param {function} callback
- */
- {
- name: 'sendHttp',
- args: ['object', 'function']
- }
-]
-
-/**
- * @module event
- */
-export const event = [
- /**
- * @method openURL
- * @param {string} url
- */
- {
- name: 'openURL',
- args: ['string']
- }
-]
-
-/**
- * @module pageInfo
- */
-export const pageInfo = [
- /**
- * @method setTitle
- * @param {string} text
- */
- {
- name: 'setTitle',
- args: ['string']
- }
-]
-
-/**
- * @module animation
- */
-export const animation = [
-
- {
- name: 'transition',
- args: ['string', 'object', 'function']
- }
-]
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/bundle/bootstrap.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/bundle/bootstrap.js b/html5/frameworks/legacy/app/bundle/bootstrap.js
deleted file mode 100644
index 8821873..0000000
--- a/html5/frameworks/legacy/app/bundle/bootstrap.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import semver from 'semver'
-import Vm from '../../vm/index'
-import * as downgrade from '../downgrade'
-import { setViewport } from '../viewport'
-import {
- requireCustomComponent
-} from '../register'
-import {
- isPlainObject,
- isWeexComponent,
- isNpmModule,
- removeWeexPrefix,
- removeJSSurfix
-} from '../../util/index'
-
-/**
- * bootstrap app from a certain custom component with config & data
- */
-export function bootstrap (app, name, config, data) {
- console.debug(`[JS Framework] bootstrap for ${name}`)
-
- // 1. validate custom component name first
- let cleanName
- if (isWeexComponent(name)) {
- cleanName = removeWeexPrefix(name)
- }
- else if (isNpmModule(name)) {
- cleanName = removeJSSurfix(name)
- // check if define by old 'define' method
- /* istanbul ignore if */
- if (!requireCustomComponent(app, cleanName)) {
- return new Error(`It's not a component: ${name}`)
- }
- }
- else {
- return new Error(`Wrong component name: ${name}`)
- }
-
- // 2. validate configuration
- config = isPlainObject(config) ? config : {}
- // 2.1 transformer version check
- if (typeof config.transformerVersion === 'string' &&
- typeof global.transformerVersion === 'string' &&
- !semver.satisfies(config.transformerVersion,
- global.transformerVersion)) {
- return new Error(`JS Bundle version: ${config.transformerVersion} ` +
- `not compatible with ${global.transformerVersion}`)
- }
- // 2.2 downgrade version check
- const downgradeResult = downgrade.check(config.downgrade)
- /* istanbul ignore if */
- if (downgradeResult.isDowngrade) {
- app.callTasks([{
- module: 'instanceWrap',
- method: 'error',
- args: [
- downgradeResult.errorType,
- downgradeResult.code,
- downgradeResult.errorMessage
- ]
- }])
- return new Error(`Downgrade[${downgradeResult.code}]: ${downgradeResult.errorMessage}`)
- }
-
- // set viewport
- if (config.viewport) {
- setViewport(app, config.viewport)
- }
-
- // 3. create a new Vm with custom component name and data
- app.vm = new Vm(cleanName, null, { _app: app }, null, data)
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/bundle/define.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/bundle/define.js b/html5/frameworks/legacy/app/bundle/define.js
deleted file mode 100644
index aec30f7..0000000
--- a/html5/frameworks/legacy/app/bundle/define.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import {
- isWeexComponent,
- isWeexModule,
- isNormalModule,
- isNpmModule,
- removeWeexPrefix,
- removeJSSurfix
-} from '../../util/index'
-import {
- registerCustomComponent,
- requireCustomComponent,
- initModules
-} from '../register'
-
-/**
- * define(name, factory) for primary usage
- * or
- * define(name, deps, factory) for compatibility
- * Notice: DO NOT use function define() {},
- * it will cause error after builded by webpack
- */
-export const defineFn = function (app, name, ...args) {
- console.debug(`[JS Framework] define a component ${name}`)
-
- // adapt args:
- // 1. name, deps[], factory()
- // 2. name, factory()
- // 3. name, definition{}
- let factory, definition
- if (args.length > 1) {
- definition = args[1]
- }
- else {
- definition = args[0]
- }
- if (typeof definition === 'function') {
- factory = definition
- definition = null
- }
-
- // resolve definition from factory
- if (factory) {
- const r = (name) => {
- if (isWeexComponent(name)) {
- const cleanName = removeWeexPrefix(name)
- return requireCustomComponent(app, cleanName)
- }
- if (isWeexModule(name)) {
- const cleanName = removeWeexPrefix(name)
- return app.requireModule(cleanName)
- }
- if (isNormalModule(name) || isNpmModule(name)) {
- const cleanName = removeJSSurfix(name)
- return app.commonModules[cleanName]
- }
- }
- const m = { exports: {}}
- factory(r, m.exports, m)
- definition = m.exports
- }
-
- // apply definition
- if (isWeexComponent(name)) {
- const cleanName = removeWeexPrefix(name)
- registerCustomComponent(app, cleanName, definition)
- }
- else if (isWeexModule(name)) {
- const cleanName = removeWeexPrefix(name)
- initModules({ [cleanName]: definition })
- }
- else if (isNormalModule(name)) {
- const cleanName = removeJSSurfix(name)
- app.commonModules[cleanName] = definition
- }
- else if (isNpmModule(name)) {
- const cleanName = removeJSSurfix(name)
- if (definition.template ||
- definition.style ||
- definition.methods) {
- // downgrade to old define method (define('componentName', factory))
- // the exports contain one key of template, style or methods
- // but it has risk!!!
- registerCustomComponent(app, cleanName, definition)
- }
- else {
- app.commonModules[cleanName] = definition
- }
- }
-}
-
-/**
- * @deprecated
- */
-export function register (app, type, options) {
- console.warn('[JS Framework] Register is deprecated, please install lastest transformer.')
- registerCustomComponent(app, type, options)
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/bundle/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/bundle/index.js b/html5/frameworks/legacy/app/bundle/index.js
deleted file mode 100644
index 40126cf..0000000
--- a/html5/frameworks/legacy/app/bundle/index.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * api that invoked by js bundle code
- *
- * - define(name, factory): define a new composed component type
- * - bootstrap(type, config, data): require a certain type &
- * render with (optional) data
- *
- * deprecated:
- * - register(type, options): register a new composed component type
- * - render(type, data): render by a certain type with (optional) data
- * - require(type)(data): require a type then render with data
- */
-
-export { bootstrap } from './bootstrap'
-export { defineFn, register } from './define'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/ctrl/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/ctrl/index.js b/html5/frameworks/legacy/app/ctrl/index.js
deleted file mode 100644
index 99fb3a7..0000000
--- a/html5/frameworks/legacy/app/ctrl/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * instance controls from native
- *
- * - init bundle
- * - fire event
- * - callback
- * - destroy
- *
- * corresponded with the API of instance manager (framework.js)
- */
-export { init } from './init'
-
-export {
- refresh,
- destroy,
- getRootElement,
- fireEvent,
- callback,
- updateActions,
- callTasks
-} from './misc'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/ctrl/init.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/ctrl/init.js b/html5/frameworks/legacy/app/ctrl/init.js
deleted file mode 100644
index 401d614..0000000
--- a/html5/frameworks/legacy/app/ctrl/init.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * instance controls from native
- *
- * - init bundle
- *
- * corresponded with the API of instance manager (framework.js)
- */
-
-import Vm from '../../vm/index'
-import { removeWeexPrefix } from '../../util/index'
-import {
- defineFn,
- bootstrap,
- register
-} from '../bundle/index'
-import { updateActions } from './misc'
-
-/**
- * Init an app by run code witgh data
- * @param {object} app
- * @param {string} code
- * @param {object} data
- */
-export function init (app, code, data, services) {
- console.debug('[JS Framework] Intialize an instance with:\n', data)
- let result
-
- // prepare app env methods
- const bundleDefine = (...args) => defineFn(app, ...args)
- const bundleBootstrap = (name, config, _data) => {
- result = bootstrap(app, name, config, _data || data)
- updateActions(app)
- app.doc.listener.createFinish()
- console.debug(`[JS Framework] After intialized an instance(${app.id})`)
- }
- const bundleVm = Vm
- /* istanbul ignore next */
- const bundleRegister = (...args) => register(app, ...args)
- /* istanbul ignore next */
- const bundleRender = (name, _data) => {
- result = bootstrap(app, name, {}, _data)
- }
- /* istanbul ignore next */
- const bundleRequire = name => _data => {
- result = bootstrap(app, name, {}, _data)
- }
- const bundleDocument = app.doc
- /* istanbul ignore next */
- const bundleRequireModule = name => app.requireModule(removeWeexPrefix(name))
-
- const weexGlobalObject = {
- config: app.options,
- define: bundleDefine,
- bootstrap: bundleBootstrap,
- requireModule: bundleRequireModule,
- document: bundleDocument,
- Vm: bundleVm
- }
-
- Object.freeze(weexGlobalObject)
-
- // prepare code
- let functionBody
- /* istanbul ignore if */
- if (typeof code === 'function') {
- // `function () {...}` -> `{...}`
- // not very strict
- functionBody = code.toString().substr(12)
- }
- /* istanbul ignore next */
- else if (code) {
- functionBody = code.toString()
- }
- // wrap IFFE and use strict mode
- functionBody = `(function(global){\n\n"use strict";\n\n ${functionBody} \n\n})(Object.create(this))`
-
- // run code and get result
- const { WXEnvironment } = global
- const timerAPIs = {}
-
- /* istanbul ignore if */
- if (WXEnvironment && WXEnvironment.platform !== 'Web') {
- // timer APIs polyfill in native
- const timer = app.requireModule('timer')
- Object.assign(timerAPIs, {
- setTimeout: (...args) => {
- const handler = function () {
- args[0](...args.slice(2))
- }
- timer.setTimeout(handler, args[1])
- return app.doc.taskCenter.callbackManager.lastCallbackId.toString()
- },
- setInterval: (...args) => {
- const handler = function () {
- args[0](...args.slice(2))
- }
- timer.setInterval(handler, args[1])
- return app.doc.taskCenter.callbackManager.lastCallbackId.toString()
- },
- clearTimeout: (n) => {
- timer.clearTimeout(n)
- },
- clearInterval: (n) => {
- timer.clearInterval(n)
- }
- })
- }
- // run code and get result
- const globalObjects = Object.assign({
- define: bundleDefine,
- require: bundleRequire,
- bootstrap: bundleBootstrap,
- register: bundleRegister,
- render: bundleRender,
- __weex_define__: bundleDefine, // alias for define
- __weex_bootstrap__: bundleBootstrap, // alias for bootstrap
- __weex_document__: bundleDocument,
- __weex_require__: bundleRequireModule,
- __weex_viewmodel__: bundleVm,
- weex: weexGlobalObject
- }, timerAPIs, services)
- if (!callFunctionNative(globalObjects, functionBody)) {
- // If failed to compile functionBody on native side,
- // fallback to callFunction.
- callFunction(globalObjects, functionBody)
- }
-
- return result
-}
-
-/**
- * Call a new function body with some global objects.
- * @param {object} globalObjects
- * @param {string} code
- * @return {any}
- */
-function callFunction (globalObjects, body) {
- const globalKeys = []
- const globalValues = []
- for (const key in globalObjects) {
- globalKeys.push(key)
- globalValues.push(globalObjects[key])
- }
- globalKeys.push(body)
-
- const result = new Function(...globalKeys)
- return result(...globalValues)
-}
-
-/**
- * Call a new function generated on the V8 native side.
- * @param {object} globalObjects
- * @param {string} body
- * @return {boolean} return true if no error occurred.
- */
-function callFunctionNative (globalObjects, body) {
- if (typeof compileAndRunBundle !== 'function') {
- return false
- }
-
- let fn = void 0
- let isNativeCompileOk = false
- let script = '(function ('
- const globalKeys = []
- const globalValues = []
- for (const key in globalObjects) {
- globalKeys.push(key)
- globalValues.push(globalObjects[key])
- }
- for (let i = 0; i < globalKeys.length - 1; ++i) {
- script += globalKeys[i]
- script += ','
- }
- script += globalKeys[globalKeys.length - 1]
- script += ') {'
- script += body
- script += '} )'
-
- try {
- const weex = globalObjects.weex || {}
- const config = weex.config || {}
- fn = compileAndRunBundle(script,
- config.bundleUrl,
- config.bundleDigest,
- config.codeCachePath)
- if (fn && typeof fn === 'function') {
- fn(...globalValues)
- isNativeCompileOk = true
- }
- }
- catch (e) {
- console.error(e)
- }
-
- return isNativeCompileOk
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/ctrl/misc.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/ctrl/misc.js b/html5/frameworks/legacy/app/ctrl/misc.js
deleted file mode 100644
index 13ab09e..0000000
--- a/html5/frameworks/legacy/app/ctrl/misc.js
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * instance controls from native
- *
- * - fire event
- * - callback
- * - refresh
- * - destroy
- *
- * corresponded with the API of instance manager (framework.js)
- */
-import { extend, typof } from '../../util/index'
-
-/**
- * Refresh an app with data to its root component options.
- * @param {object} app
- * @param {any} data
- */
-export function refresh (app, data) {
- console.debug(`[JS Framework] Refresh with`, data,
- `in instance[${app.id}]`)
- const vm = app.vm
- if (vm && data) {
- if (typeof vm.refreshData === 'function') {
- vm.refreshData(data)
- }
- else {
- extend(vm, data)
- }
- app.differ.flush()
- app.doc.taskCenter.send('dom', { action: 'refreshFinish' }, [])
- return
- }
- return new Error(`invalid data "${data}"`)
-}
-
-/**
- * Destroy an app.
- * @param {object} app
- */
-export function destroy (app) {
- console.debug(`[JS Framework] Destory an instance(${app.id})`)
-
- if (app.vm) {
- destroyVm(app.vm)
- }
-
- app.id = ''
- app.options = null
- app.blocks = null
- app.vm = null
- app.doc.taskCenter.destroyCallback()
- app.doc.destroy()
- app.doc = null
- app.customComponentMap = null
- app.commonModules = null
-}
-
-/**
- * Destroy an Vm.
- * @param {object} vm
- */
-export function destroyVm (vm) {
- delete vm._app
- delete vm._computed
- delete vm._css
- delete vm._data
- delete vm._ids
- delete vm._methods
- delete vm._options
- delete vm._parent
- delete vm._parentEl
- delete vm._rootEl
-
- // remove all watchers
- if (vm._watchers) {
- let watcherCount = vm._watchers.length
- while (watcherCount--) {
- vm._watchers[watcherCount].teardown()
- }
- delete vm._watchers
- }
-
- // destroy child vms recursively
- if (vm._childrenVms) {
- let vmCount = vm._childrenVms.length
- while (vmCount--) {
- destroyVm(vm._childrenVms[vmCount])
- }
- delete vm._childrenVms
- }
-
- console.debug(`[JS Framework] "destroyed" lifecycle in Vm(${vm._type})`)
- vm.$emit('hook:destroyed')
-
- delete vm._type
- delete vm._vmEvents
-}
-
-/**
- * Get a JSON object to describe the document body.
- * @param {object} app
- * @return {object}
- */
-export function getRootElement (app) {
- const doc = app.doc || {}
- const body = doc.body || {}
- return body.toJSON ? body.toJSON() : {}
-}
-
-/**
- * Fire an event from renderer. The event has type, an event object and an
- * element ref. If the event comes with some virtual-DOM changes, it should
- * have one more parameter to describe the changes.
- * @param {object} app
- * @param {string} ref
- * @param {type} type
- * @param {object} e
- * @param {object} domChanges
- */
-export function fireEvent (app, ref, type, e, domChanges) {
- console.debug(`[JS Framework] Fire a "${type}" event on an element(${ref}) in instance(${app.id})`)
- if (Array.isArray(ref)) {
- ref.some((ref) => {
- return fireEvent(app, ref, type, e) !== false
- })
- return
- }
- const el = app.doc.getRef(ref)
- if (el) {
- const result = app.doc.fireEvent(el, type, e, domChanges)
- app.differ.flush()
- app.doc.taskCenter.send('dom', { action: 'updateFinish' }, [])
- return result
- }
- return new Error(`invalid element reference "${ref}"`)
-}
-
-/**
- * Make a callback for a certain app.
- * @param {object} app
- * @param {number} callbackId
- * @param {any} data
- * @param {boolean} ifKeepAlive
- */
-export function callback (app, callbackId, data, ifKeepAlive) {
- console.debug(`[JS Framework] Invoke a callback(${callbackId}) with`, data,
- `in instance(${app.id})`)
- const result = app.doc.taskCenter.callback(callbackId, data, ifKeepAlive)
- updateActions(app)
- app.doc.taskCenter.send('dom', { action: 'updateFinish' }, [])
- return result
-}
-
-/**
- * Collect all virtual-DOM mutations together and send them to renderer.
- * @param {object} app
- */
-export function updateActions (app) {
- app.differ.flush()
-}
-
-/**
- * Call all tasks from an app to renderer (native).
- * @param {object} app
- * @param {array} tasks
- */
-export function callTasks (app, tasks) {
- let result
-
- /* istanbul ignore next */
- if (typof(tasks) !== 'array') {
- tasks = [tasks]
- }
-
- tasks.forEach(task => {
- result = app.doc.taskCenter.send(
- 'module',
- {
- module: task.module,
- method: task.method
- },
- task.args
- )
- })
-
- return result
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/differ.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/differ.js b/html5/frameworks/legacy/app/differ.js
deleted file mode 100644
index 61e25ef..0000000
--- a/html5/frameworks/legacy/app/differ.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-export default class Differ {
- constructor (id) {
- this.id = id
- this.map = []
- this.hooks = []
- }
- isEmpty () {
- return this.map.length === 0
- }
- append (type, depth = 0, ref, handler) {
- if (!this.hasTimer) {
- this.hasTimer = true
- setTimeout(() => {
- this.hasTimer = false
- this.flush(true)
- }, 0)
- }
- const map = this.map
- if (!map[depth]) {
- map[depth] = {}
- }
- const group = map[depth]
- if (!group[type]) {
- group[type] = {}
- }
- if (type === 'element') {
- if (!group[type][ref]) {
- group[type][ref] = []
- }
- group[type][ref].push(handler)
- }
- else {
- group[type][ref] = handler
- }
- }
- flush (isTimeout) {
- const map = this.map.slice()
- this.map.length = 0
- map.forEach((group) => {
- callTypeMap(group, 'repeat')
- callTypeMap(group, 'shown')
- callTypeList(group, 'element')
- })
-
- const hooks = this.hooks.slice()
- this.hooks.length = 0
- hooks.forEach((fn) => {
- fn()
- })
-
- if (!this.isEmpty()) {
- this.flush()
- }
- }
- then (fn) {
- this.hooks.push(fn)
- }
-}
-
-function callTypeMap (group, type) {
- const map = group[type]
- for (const ref in map) {
- map[ref]()
- }
-}
-
-function callTypeList (group, type) {
- const map = group[type]
- for (const ref in map) {
- const list = map[ref]
- list.forEach((handler) => { handler() })
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/downgrade.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/downgrade.js b/html5/frameworks/legacy/app/downgrade.js
deleted file mode 100644
index 327d70a..0000000
--- a/html5/frameworks/legacy/app/downgrade.js
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import semver from 'semver'
-import { isPlainObject, typof } from '../util/index'
-
-/**
- * Normalize a version string.
- * @param {String} Version. ie: 1, 1.0, 1.0.0
- * @return {String} Version
- */
-export function normalizeVersion (v) {
- const isValid = semver.valid(v)
- if (isValid) {
- return v
- }
-
- v = typeof (v) === 'string' ? v : ''
- const split = v.split('.')
- let i = 0
- const result = []
-
- while (i < 3) {
- const s = typeof (split[i]) === 'string' && split[i] ? split[i] : '0'
- result.push(s)
- i++
- }
-
- return result.join('.')
-}
-
-/**
- * Get informations from different error key. Like:
- * - code
- * - errorMessage
- * - errorType
- * - isDowngrade
- * @param {string} key
- * @param {string} val
- * @param {string} criteria
- * @return {object}
- */
-export function getError (key, val, criteria) {
- const result = {
- isDowngrade: true,
- errorType: 1,
- code: 1000
- }
- const getMsg = function (key, val, criteria) {
- return 'Downgrade[' + key + '] :: deviceInfo '
- + val + ' matched criteria ' + criteria
- }
- const _key = key.toLowerCase()
-
- result.errorMessage = getMsg(key, val, criteria)
-
- if (_key.indexOf('osversion') >= 0) {
- result.code = 1001
- }
- else if (_key.indexOf('appversion') >= 0) {
- result.code = 1002
- }
- else if (_key.indexOf('weexversion') >= 0) {
- result.code = 1003
- }
- else if (_key.indexOf('devicemodel') >= 0) {
- result.code = 1004
- }
-
- return result
-}
-
-/**
- * WEEX framework input(deviceInfo)
- * {
- * platform: 'iOS' or 'android'
- * osVersion: '1.0.0' or '1.0' or '1'
- * appVersion: '1.0.0' or '1.0' or '1'
- * weexVersion: '1.0.0' or '1.0' or '1'
- * dDeviceModel: 'MODEL_NAME'
- * }
- *
- * downgrade config(config)
- * {
- * ios: {
- * osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- * appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- * weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- * deviceModel: ['modelA', 'modelB', ...]
- * },
- * android: {
- * osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- * appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- * weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
- * deviceModel: ['modelA', 'modelB', ...]
- * }
- * }
- *
- *
- * @param {object} deviceInfo Weex SDK framework input
- * @param {object} config user input
- * @return {Object} { isDowngrade: true/false, errorMessage... }
- */
-export function check (config, deviceInfo) {
- deviceInfo = deviceInfo || global.WXEnvironment
- deviceInfo = isPlainObject(deviceInfo) ? deviceInfo : {}
-
- let result = {
- isDowngrade: false // defautl is pass
- }
-
- if (typof(config) === 'function') {
- let customDowngrade = config.call(this, deviceInfo, {
- semver: semver,
- normalizeVersion
- })
-
- customDowngrade = !!customDowngrade
-
- result = customDowngrade ? getError('custom', '', 'custom params') : result
- }
- else {
- config = isPlainObject(config) ? config : {}
-
- const platform = deviceInfo.platform || 'unknow'
- const dPlatform = platform.toLowerCase()
- const cObj = config[dPlatform] || {}
-
- for (const i in deviceInfo) {
- const key = i
- const keyLower = key.toLowerCase()
- const val = deviceInfo[i]
- const isVersion = keyLower.indexOf('version') >= 0
- const isDeviceModel = keyLower.indexOf('devicemodel') >= 0
- const criteria = cObj[i]
-
- if (criteria && isVersion) {
- const c = normalizeVersion(criteria)
- const d = normalizeVersion(deviceInfo[i])
-
- if (semver.satisfies(d, c)) {
- result = getError(key, val, criteria)
- break
- }
- }
- else if (isDeviceModel) {
- const _criteria = typof(criteria) === 'array' ? criteria : [criteria]
- if (_criteria.indexOf(val) >= 0) {
- result = getError(key, val, criteria)
- break
- }
- }
- }
- }
-
- return result
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/index.js b/html5/frameworks/legacy/app/index.js
deleted file mode 100644
index 5ae389d..0000000
--- a/html5/frameworks/legacy/app/index.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * Weex instance constructor & definition
- */
-
-import { requireModule } from './register'
-import { updateActions, callTasks } from './ctrl/index'
-import App from './instance'
-
-/**
- * @deprecated
- */
-App.prototype.requireModule = function (name) {
- return requireModule(this, name)
-}
-
-/**
- * @deprecated
- */
-App.prototype.updateActions = function () {
- return updateActions(this)
-}
-
-/**
- * @deprecated
- */
-App.prototype.callTasks = function (tasks) {
- return callTasks(this, tasks)
-}
-
-/**
- * Prevent modification of App and App.prototype
- */
-Object.freeze(App)
-Object.freeze(App.prototype)
-
-export default App
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/instance.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/instance.js b/html5/frameworks/legacy/app/instance.js
deleted file mode 100644
index 55bb4c5..0000000
--- a/html5/frameworks/legacy/app/instance.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * Weex App constructor & definition
- */
-
-import Differ from './differ'
-import renderer from '../config'
-
-/**
- * App constructor for Weex framework.
- * @param {string} id
- * @param {object} options
- */
-export default function App (id, options) {
- this.id = id
- this.options = options || {}
- this.vm = null
- this.customComponentMap = {}
- this.commonModules = {}
-
- // document
- this.doc = new renderer.Document(
- id,
- this.options.bundleUrl,
- null,
- renderer.Listener
- )
- this.differ = new Differ(id)
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/register.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/register.js b/html5/frameworks/legacy/app/register.js
deleted file mode 100644
index bd0302e..0000000
--- a/html5/frameworks/legacy/app/register.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-let nativeModules = {}
-
-// for testing
-
-/**
- * for testing
- */
-export function getModule (moduleName) {
- return nativeModules[moduleName]
-}
-
-/**
- * for testing
- */
-export function clearModules () {
- nativeModules = {}
-}
-
-// for framework
-
-/**
- * init modules for an app instance
- * the second param determines whether to replace an existed method
- */
-export function initModules (modules, ifReplace) {
- for (const moduleName in modules) {
- // init `modules[moduleName][]`
- let methods = nativeModules[moduleName]
- if (!methods) {
- methods = {}
- nativeModules[moduleName] = methods
- }
-
- // push each non-existed new method
- modules[moduleName].forEach(function (method) {
- if (typeof method === 'string') {
- method = {
- name: method
- }
- }
-
- if (!methods[method.name] || ifReplace) {
- methods[method.name] = method
- }
- })
- }
-}
-
-/**
- * init app methods
- */
-export function initMethods (Vm, apis) {
- const p = Vm.prototype
-
- for (const apiName in apis) {
- if (!p.hasOwnProperty(apiName)) {
- p[apiName] = apis[apiName]
- }
- }
-}
-
-/**
- * get a module of methods for an app instance
- */
-export function requireModule (app, name) {
- const methods = nativeModules[name]
- const target = {}
- for (const methodName in methods) {
- Object.defineProperty(target, methodName, {
- configurable: true,
- enumerable: true,
- get: function moduleGetter () {
- return (...args) => app.callTasks({
- module: name,
- method: methodName,
- args: args
- })
- },
- set: function moduleSetter (value) {
- if (typeof value === 'function') {
- return app.callTasks({
- module: name,
- method: methodName,
- args: [value]
- })
- }
- }
- })
- }
- return target
-}
-
-/**
- * get a custom component options
- */
-export function requireCustomComponent (app, name) {
- const { customComponentMap } = app
- return customComponentMap[name]
-}
-
-/**
- * register a custom component options
- */
-export function registerCustomComponent (app, name, def) {
- const { customComponentMap } = app
-
- if (customComponentMap[name]) {
- console.error(`[JS Framework] define a component(${name}) that already exists`)
- return
- }
-
- customComponentMap[name] = def
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/app/viewport.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/app/viewport.js b/html5/frameworks/legacy/app/viewport.js
deleted file mode 100644
index 60f8eff..0000000
--- a/html5/frameworks/legacy/app/viewport.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-export function setViewport (app, configs = {}) {
- /* istanbul ignore if */
- if (process.env.NODE_ENV === 'development') {
- console.debug(`[JS Framework] Set viewport (width: ${configs.width}) for app#${app.id}.`)
- validateViewport(configs)
- }
-
- // Send viewport configs to native
- if (app && app.callTasks) {
- return app.callTasks([{
- module: 'meta',
- method: 'setViewport',
- args: [configs]
- }])
- }
-
- /* istanbul ignore next */
- else if (process.env.NODE_ENV === 'development') {
- console.warn(`[JS Framework] Can't find "callTasks" method on current app.`)
- }
-}
-
-/**
- * Validate the viewport config.
- * @param {Object} configs
- */
-export function validateViewport (configs = {}) {
- const { width } = configs
- if (width) {
- if (typeof width !== 'number' && width !== 'device-width') {
- console.warn(`[JS Framework] Not support to use ${width} as viewport width.`)
- return false
- }
- return true
- }
- console.warn('[JS Framework] the viewport config should contain the "width" property.')
- return false
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/config.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/config.js b/html5/frameworks/legacy/config.js
deleted file mode 100644
index ebf64d2..0000000
--- a/html5/frameworks/legacy/config.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-// @todo: It should be registered by native from `registerComponents()`.
-
-export default {
- nativeComponentMap: {
- text: true,
- image: true,
- container: true,
- slider: {
- type: 'slider',
- append: 'tree'
- },
- cell: {
- type: 'cell',
- append: 'tree'
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/LICENSE
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/LICENSE b/html5/frameworks/legacy/core/LICENSE
deleted file mode 100644
index 4645bc4..0000000
--- a/html5/frameworks/legacy/core/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013-2015 Yuxi Evan You
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/array.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/array.js b/html5/frameworks/legacy/core/array.js
deleted file mode 100644
index 856792f..0000000
--- a/html5/frameworks/legacy/core/array.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/* eslint-disable */
-
-
-import { def } from '../util/index'
-
-const arrayProto = Array.prototype
-export const arrayMethods = Object.create(arrayProto)
-
-/**
- * Intercept mutating methods and emit events
- */
-
-;[
- 'push',
- 'pop',
- 'shift',
- 'unshift',
- 'splice',
- 'sort',
- 'reverse'
-]
-.forEach(function (method) {
- // cache original method
- const original = arrayProto[method]
- def(arrayMethods, method, function mutator () {
- // avoid leaking arguments:
- // http://jsperf.com/closure-with-arguments
- let i = arguments.length
- const args = new Array(i)
- while (i--) {
- args[i] = arguments[i]
- }
- const result = original.apply(this, args)
- const ob = this.__ob__
- let inserted
- switch (method) {
- case 'push':
- inserted = args
- break
- case 'unshift':
- inserted = args
- break
- case 'splice':
- inserted = args.slice(2)
- break
- }
- if (inserted) ob.observeArray(inserted)
- // notify change
- ob.dep.notify()
- return result
- })
-})
-
-/**
- * Swap the element at the given index with a new value
- * and emits corresponding event.
- *
- * @param {Number} index
- * @param {*} val
- * @return {*} - replaced element
- */
-
-def(
- arrayProto,
- '$set',
- function $set (index, val) {
- console.warn(`[JS Framework] "Array.prototype.$set" is not a standard API,`
- + ` it will be removed in the next version.`)
- if (index >= this.length) {
- this.length = index + 1
- }
- return this.splice(index, 1, val)[0]
- }
-)
-
-/**
- * Convenience method to remove the element at given index.
- *
- * @param {Number} index
- * @param {*} val
- */
-
-def(
- arrayProto,
- '$remove',
- function $remove (index) {
- console.warn(`[JS Framework] "Array.prototype.$remove" is not a standard API,`
- + ` it will be removed in the next version.`)
- /* istanbul ignore if */
- if (!this.length) return
- /* istanbul ignore else */
- if (typeof index !== 'number') {
- index = this.indexOf(index)
- }
- /* istanbul ignore else */
- if (index > -1) {
- this.splice(index, 1)
- }
- }
-)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/dep.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/dep.js b/html5/frameworks/legacy/core/dep.js
deleted file mode 100644
index 6c29bf6..0000000
--- a/html5/frameworks/legacy/core/dep.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* eslint-disable */
-
-
-import { remove } from '../util/index'
-
-let uid = 0
-
-/**
- * A dep is an observable that can have multiple
- * directives subscribing to it.
- *
- * @constructor
- */
-
-export default function Dep () {
- this.id = uid++
- this.subs = []
-}
-
-// the current target watcher being evaluated.
-// this is globally unique because there could be only one
-// watcher being evaluated at any time.
-Dep.target = null
-let targetStack = []
-
-export function pushTarget (_target) {
- if (Dep.target) targetStack.push(Dep.target)
- Dep.target = _target
-}
-
-export function popTarget () {
- Dep.target = targetStack.pop()
-}
-
-export function resetTarget () {
- Dep.target = null
- targetStack = []
-}
-
-/**
- * Add a directive subscriber.
- *
- * @param {Directive} sub
- */
-
-Dep.prototype.addSub = function (sub) {
- this.subs.push(sub)
-}
-
-/**
- * Remove a directive subscriber.
- *
- * @param {Directive} sub
- */
-
-Dep.prototype.removeSub = function (sub) {
- remove(this.subs, sub)
-}
-
-/**
- * Add self as a dependency to the target watcher.
- */
-
-Dep.prototype.depend = function () {
- if (Dep.target) {
- Dep.target.addDep(this)
- }
-}
-
-/**
- * Notify all subscribers of a new value.
- */
-
-Dep.prototype.notify = function () {
- // stablize the subscriber list first
- const subs = this.subs.slice()
- for (let i = 0, l = subs.length; i < l; i++) {
- subs[i].update()
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/object.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/object.js b/html5/frameworks/legacy/core/object.js
deleted file mode 100644
index 86f83e3..0000000
--- a/html5/frameworks/legacy/core/object.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/* eslint-disable */
-
-
-import * as _ from '../util/index'
-var objProto = Object.prototype
-
-/**
- * Add a new property to an observed object
- * and emits corresponding event
- *
- * @param {String} key
- * @param {*} val
- * @public
- */
-
-_.define(
- objProto,
- '$add',
- function $add (key, val) {
- console.warn(`[JS Framework] "Object.prototype.$add" is not a standard API,`
- + ` it will be removed in the next version.`)
- if (this.hasOwnProperty(key)) return
- var ob = this.__ob__
- if (!ob || _.isReserved(key)) {
- this[key] = val
- return
- }
- ob.convert(key, val)
- ob.notify()
- if (ob.vms) {
- var i = ob.vms.length
- while (i--) {
- var vm = ob.vms[i]
- vm._proxy(key)
- // vm._digest() // todo
- }
- }
- }
-)
-
-/**
- * Set a property on an observed object, calling add to
- * ensure the property is observed.
- *
- * @param {String} key
- * @param {*} val
- * @public
- */
-
-_.define(
- objProto,
- '$set',
- function $set (key, val) {
- console.warn(`[JS Framework] "Object.prototype.$set" is not a standard API,`
- + ` it will be removed in the next version.`)
- this.$add(key, val)
- this[key] = val
- }
-)
-
-/**
- * Deletes a property from an observed object
- * and emits corresponding event
- *
- * @param {String} key
- * @public
- */
-
-_.define(
- objProto,
- '$delete',
- function $delete (key) {
- console.warn(`[JS Framework] "Object.prototype.$delete" is not a standard API,`
- + ` it will be removed in the next version.`)
- if (!this.hasOwnProperty(key)) return
- delete this[key]
- var ob = this.__ob__
- if (!ob || _.isReserved(key)) {
- return
- }
- ob.notify()
- if (ob.vms) {
- var i = ob.vms.length
- while (i--) {
- var vm = ob.vms[i]
- vm._unproxy(key)
- // vm._digest() // todo
- }
- }
- }
-)
[04/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/signals/signals-long.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/signals/signals-long.source.js b/test/js-framework/case/signals/signals-long.source.js
new file mode 100644
index 0000000..06b541f
--- /dev/null
+++ b/test/js-framework/case/signals/signals-long.source.js
@@ -0,0 +1,1223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+new Promise(function () {})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+;define('systemConfig', function (require, exports, module) {
+ module.exports = {"isAliIntranet":false,"serverTime":"2016-07-04 17:00:00"};
+ module.exports.serverTime = new Date(module.exports.serverTime).getTime();
+ module.exports.clientTime = new Date().getTime();
+});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+;define('zebraConfig', function (require, exports, module) {
+ module.exports = {"spma":"0","spmb":"0","name":"zebra-act-item-240x240","title":"zebra-act-item-240x240","pageStatus":"online","modules":[{"name":"zebra-act-item-240x240","rmcId":"zebra-act-item-240x240","zebraId":"zebra-act-item-240x240","moduleId":"zebra-act-item-240x240","meta":{"size":"10px"}}],"closeCustom":true};
+});
+
+;define('zebraDoms', function (require, exports, module) {
+ var els = [
+ {"isZebraModule":true,"zebraId":"zebra-act-item-240x240","name":"zebra-act-item-240x240","data":{"$config":{"$dynamic":true,"mobileNoLogo":false},"item":[{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemIm
g":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png",
"itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/",
"itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpX
XQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":
567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","
brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.ali
cdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.al
icdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXX
XJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.
com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com
/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子
短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短
裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","bra
ndLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"item
MPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicd
n.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXX
XGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg"
:"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","i
temDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","i
temTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQ
U6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":56
7,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","br
andLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicd
n.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alic
dn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJ
XFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.co
m/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/t
ps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子�
�裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短�
�连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brand
Logo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMP
rice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.
com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXG
XFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"
http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","ite
mDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","ite
mTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6
CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,
"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","bran
dLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.
com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn
.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXF
XXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/
tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps
/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短�
��连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙�
��衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLo
go":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPri
ce":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.co
m/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXF
XXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"ht
tp://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemD
esc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemT
itle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CG
XXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"i
temActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandL
ogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.co
m/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.c
om/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXX
mqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tp
s/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i
1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙
连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连
衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo
":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice
":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/
tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXX
G9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http
://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDes
c":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTit
le":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXX
X-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"ite
mActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLog
o":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/
tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com
/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmq
jTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/
i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/
TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙�
�衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连�
�裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":
"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":
12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tp
s/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9
gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http:/
/gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc"
:"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle
":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-
348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemA
ctPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo"
:"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tp
s/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/t
ps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.p
<TRUNCATED>
[18/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/render/native/setup.js
----------------------------------------------------------------------
diff --git a/html5/render/native/setup.js b/html5/render/native/setup.js
deleted file mode 100644
index d7404cb..0000000
--- a/html5/render/native/setup.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { subversion } from '../../../package.json'
-import runtime from '../../runtime'
-import services from '../../services/index'
-
-/**
- * Setup frameworks with runtime.
- * You can package more frameworks by
- * passing them as arguments.
- */
-export default function (frameworks) {
- const { init, config } = runtime
- config.frameworks = frameworks
- const { native, transformer } = subversion
-
- for (const serviceName in services) {
- runtime.service.register(serviceName, services[serviceName])
- }
-
- runtime.freezePrototype()
- runtime.setNativeConsole()
-
- // register framework meta info
- global.frameworkVersion = native
- global.transformerVersion = transformer
-
- // init frameworks
- const globalMethods = init(config)
-
- // set global methods
- for (const methodName in globalMethods) {
- global[methodName] = (...args) => {
- const ret = globalMethods[methodName](...args)
- if (ret instanceof Error) {
- console.error(ret.toString())
- }
- return ret
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/render/vue/README.md
----------------------------------------------------------------------
diff --git a/html5/render/vue/README.md b/html5/render/vue/README.md
deleted file mode 100644
index a8bf32e..0000000
--- a/html5/render/vue/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# weex-vue-render
-
-This project has been moved to [weexteam group](https://github.com/weexteam/weex-vue-render)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/api/WeexInstance.js
----------------------------------------------------------------------
diff --git a/html5/runtime/api/WeexInstance.js b/html5/runtime/api/WeexInstance.js
deleted file mode 100644
index 3bc25e6..0000000
--- a/html5/runtime/api/WeexInstance.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import Document from '../vdom/Document'
-import { isRegisteredModule, getModuleDescription } from './module'
-import { isRegisteredComponent } from './component'
-import { getTaskCenter } from '../vdom/operation'
-
-const moduleProxies = {}
-
-function setId (weex, id) {
- Object.defineProperty(weex, '[[CurrentInstanceId]]', { value: id })
-}
-
-function getId (weex) {
- return weex['[[CurrentInstanceId]]']
-}
-
-function moduleGetter (id, module, method) {
- const taskCenter = getTaskCenter(id)
- if (!taskCenter || typeof taskCenter.send !== 'function') {
- console.error(`[JS Framework] Failed to find taskCenter (${id}).`)
- return null
- }
- return (...args) => taskCenter.send('module', { module, method }, args)
-}
-
-function moduleSetter (id, module, method, fn) {
- const taskCenter = getTaskCenter(id)
- if (!taskCenter || typeof taskCenter.send !== 'function') {
- console.error(`[JS Framework] Failed to find taskCenter (${id}).`)
- return null
- }
- if (typeof fn !== 'function') {
- console.error(`[JS Framework] ${module}.${method} must be assigned as a function.`)
- return null
- }
- return fn => taskCenter.send('module', { module, method }, [fn])
-}
-
-export default class WeexInstance {
- constructor (id, config) {
- setId(this, String(id))
- this.config = config || {}
- this.document = new Document(id, this.config.bundleUrl)
- this.requireModule = this.requireModule.bind(this)
- this.isRegisteredModule = isRegisteredModule
- this.isRegisteredComponent = isRegisteredComponent
- }
-
- requireModule (moduleName) {
- const id = getId(this)
- if (!(id && this.document && this.document.taskCenter)) {
- console.error(`[JS Framework] Failed to requireModule("${moduleName}"), `
- + `instance (${id}) doesn't exist anymore.`)
- return
- }
-
- // warn for unknown module
- if (!isRegisteredModule(moduleName)) {
- console.warn(`[JS Framework] using unregistered weex module "${moduleName}"`)
- return
- }
-
- // create new module proxy
- const proxyName = `${moduleName}#${id}`
- if (!moduleProxies[proxyName]) {
- // create registered module apis
- const moduleDefine = getModuleDescription(moduleName)
- const moduleApis = {}
- for (const methodName in moduleDefine) {
- Object.defineProperty(moduleApis, methodName, {
- enumerable: true,
- configurable: true,
- get: () => moduleGetter(id, moduleName, methodName),
- set: fn => moduleSetter(id, moduleName, methodName, fn)
- })
- }
-
- // create module Proxy
- if (typeof Proxy === 'function') {
- moduleProxies[proxyName] = new Proxy(moduleApis, {
- get (target, methodName) {
- if (methodName in target) {
- return target[methodName]
- }
- console.warn(`[JS Framework] using unregistered method "${moduleName}.${methodName}"`)
- return moduleGetter(id, moduleName, methodName)
- }
- })
- }
- else {
- moduleProxies[proxyName] = moduleApis
- }
- }
-
- return moduleProxies[proxyName]
- }
-
- supports (condition) {
- if (typeof condition !== 'string') return null
-
- const res = condition.match(/^@(\w+)\/(\w+)(\.(\w+))?$/i)
- if (res) {
- const type = res[1]
- const name = res[2]
- const method = res[4]
- switch (type) {
- case 'module': return isRegisteredModule(name, method)
- case 'component': return isRegisteredComponent(name)
- }
- }
-
- return null
- }
-
- // registerStyleSheet (styles) {
- // if (this.document) {
- // this.document.registerStyleSheet(styles)
- // }
- // }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/api/component.js
----------------------------------------------------------------------
diff --git a/html5/runtime/api/component.js b/html5/runtime/api/component.js
deleted file mode 100644
index 8a56961..0000000
--- a/html5/runtime/api/component.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { registerElement } from '../vdom/WeexElement'
-
-const weexComponents = {}
-
-/**
- * Register native components information.
- * @param {array} newComponents
- */
-export function registerComponents (newComponents) {
- if (Array.isArray(newComponents)) {
- newComponents.forEach(component => {
- if (!component) {
- return
- }
- if (typeof component === 'string') {
- weexComponents[component] = true
- }
- else if (typeof component === 'object' && typeof component.type === 'string') {
- weexComponents[component.type] = component
- registerElement(component.type, component.methods)
- }
- })
- }
-}
-
-/**
- * Check whether the component has been registered.
- * @param {String} component name
- */
-export function isRegisteredComponent (name) {
- return !!weexComponents[name]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/api/config.js
----------------------------------------------------------------------
diff --git a/html5/runtime/api/config.js b/html5/runtime/api/config.js
deleted file mode 100644
index d212f3d..0000000
--- a/html5/runtime/api/config.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Document, Element, Comment } from '../vdom'
-import Listener from '../bridge/Listener'
-import { TaskCenter } from '../bridge/TaskCenter'
-
-const config = {
- Document, Element, Comment, Listener,
- TaskCenter,
- sendTasks (...args) {
- if (typeof callNative === 'function') {
- return callNative(...args)
- }
- return (global.callNative || (() => {}))(...args)
- }
-}
-
-Document.handler = config.sendTasks
-
-export default config
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/api/init.js
----------------------------------------------------------------------
diff --git a/html5/runtime/api/init.js b/html5/runtime/api/init.js
deleted file mode 100644
index 187504a..0000000
--- a/html5/runtime/api/init.js
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { init as initTaskHandler } from '../bridge/TaskCenter'
-import { receiveTasks } from '../bridge/receiver'
-import { registerModules } from './module'
-import { registerComponents } from './component'
-import { services, register, unregister } from './service'
-import { track } from '../bridge/debug'
-import WeexInstance from './WeexInstance'
-import { getDoc } from '../vdom/operation'
-
-let frameworks
-let runtimeConfig
-
-const versionRegExp = /^\s*\/\/ *(\{[^}]*\}) *\r?\n/
-
-/**
- * Detect a JS Bundle code and make sure which framework it's based to. Each JS
- * Bundle should make sure that it starts with a line of JSON comment and is
- * more that one line.
- * @param {string} code
- * @return {object}
- */
-function getBundleType (code) {
- const result = versionRegExp.exec(code)
- if (result) {
- try {
- const info = JSON.parse(result[1])
- return info.framework
- }
- catch (e) {}
- }
-
- // default bundle type
- return 'Weex'
-}
-
-function createServices (id, env, config) {
- // Init JavaScript services for this instance.
- const serviceMap = Object.create(null)
- serviceMap.service = Object.create(null)
- services.forEach(({ name, options }) => {
- if (process.env.NODE_ENV === 'development') {
- console.debug(`[JS Runtime] create service ${name}.`)
- }
- const create = options.create
- if (create) {
- const result = create(id, env, config)
- Object.assign(serviceMap.service, result)
- Object.assign(serviceMap, result.instance)
- }
- })
- delete serviceMap.service.instance
- Object.freeze(serviceMap.service)
- return serviceMap
-}
-
-const instanceTypeMap = {}
-function getFrameworkType (id) {
- return instanceTypeMap[id]
-}
-
-function createInstanceContext (id, options = {}, data) {
- const weex = new WeexInstance(id, options)
- Object.freeze(weex)
-
- const bundleType = options.bundleType || 'Vue'
- instanceTypeMap[id] = bundleType
- const framework = runtimeConfig.frameworks[bundleType]
- if (!framework) {
- return new Error(`[JS Framework] Invalid bundle type "${bundleType}".`)
- }
- track(id, 'bundleType', bundleType)
-
- // prepare js service
- const services = createServices(id, { weex, bundleType }, runtimeConfig)
- Object.freeze(services)
-
- // prepare runtime context
- const runtimeContext = Object.create(null)
- Object.assign(runtimeContext, services, {
- weex,
- services // Temporary compatible with some legacy APIs in Rax
- })
- Object.freeze(runtimeContext)
-
- // prepare instance context
- const instanceContext = Object.create(runtimeContext)
- if (typeof framework.createInstanceContext === 'function') {
- Object.assign(instanceContext, framework.createInstanceContext(id, runtimeContext, data))
- }
- Object.freeze(instanceContext)
- return instanceContext
-}
-
-/**
- * Check which framework a certain JS Bundle code based to. And create instance
- * by this framework.
- * @param {string} id
- * @param {string} code
- * @param {object} config
- * @param {object} data
- */
-function createInstance (id, code, config, data) {
- if (instanceTypeMap[id]) {
- return new Error(`The instance id "${id}" has already been used!`)
- }
-
- // Init instance info.
- const bundleType = getBundleType(code)
- instanceTypeMap[id] = bundleType
-
- // Init instance config.
- config = JSON.parse(JSON.stringify(config || {}))
- config.env = JSON.parse(JSON.stringify(global.WXEnvironment || {}))
- config.bundleType = bundleType
-
- const framework = runtimeConfig.frameworks[bundleType]
- if (!framework) {
- return new Error(`[JS Framework] Invalid bundle type "${bundleType}".`)
- }
- if (bundleType === 'Weex') {
- console.error(`[JS Framework] COMPATIBILITY WARNING: `
- + `Weex DSL 1.0 (.we) framework is no longer supported! `
- + `It will be removed in the next version of WeexSDK, `
- + `your page would be crash if you still using the ".we" framework. `
- + `Please upgrade it to Vue.js or Rax.`)
- }
-
- const instanceContext = createInstanceContext(id, config, data)
- if (typeof framework.createInstance === 'function') {
- // Temporary compatible with some legacy APIs in Rax,
- // some Rax page is using the legacy ".we" framework.
- if (bundleType === 'Rax' || bundleType === 'Weex') {
- const raxInstanceContext = Object.assign({
- config,
- created: Date.now(),
- framework: bundleType
- }, instanceContext)
- return framework.createInstance(id, code, config, data, raxInstanceContext)
- }
- return framework.createInstance(id, code, config, data, instanceContext)
- }
- // console.error(`[JS Framework] Can't find available "createInstance" method in ${bundleType}!`)
- runInContext(code, instanceContext)
-}
-
-/**
- * Run js code in a specific context.
- * @param {string} code
- * @param {object} context
- */
-function runInContext (code, context) {
- const keys = []
- const args = []
- for (const key in context) {
- keys.push(key)
- args.push(context[key])
- }
-
- const bundle = `
- (function (global) {
- ${code}
- })(Object.create(this))
- `
-
- return (new Function(...keys, bundle))(...args)
-}
-
-/**
- * Get the JSON object of the root element.
- * @param {string} instanceId
- */
-function getRoot (instanceId) {
- const document = getDoc(instanceId)
- try {
- if (document && document.body) {
- return document.body.toJSON()
- }
- }
- catch (e) {
- console.error(`[JS Framework] Failed to get the virtual dom tree.`)
- return
- }
-}
-
-const methods = {
- createInstance,
- createInstanceContext,
- getRoot,
- getDocument: getDoc,
- registerService: register,
- unregisterService: unregister,
- callJS (id, tasks) {
- const framework = frameworks[getFrameworkType(id)]
- if (framework && typeof framework.receiveTasks === 'function') {
- return framework.receiveTasks(id, tasks)
- }
- return receiveTasks(id, tasks)
- }
-}
-
-/**
- * Register methods which will be called for each instance.
- * @param {string} methodName
- */
-function genInstance (methodName) {
- methods[methodName] = function (...args) {
- const id = args[0]
- const type = getFrameworkType(id)
- if (type && frameworks[type]) {
- const result = frameworks[type][methodName](...args)
- const info = { framework: type }
-
- // Lifecycle methods
- if (methodName === 'refreshInstance') {
- services.forEach(service => {
- const refresh = service.options.refresh
- if (refresh) {
- refresh(id, { info, runtime: runtimeConfig })
- }
- })
- }
- else if (methodName === 'destroyInstance') {
- services.forEach(service => {
- const destroy = service.options.destroy
- if (destroy) {
- destroy(id, { info, runtime: runtimeConfig })
- }
- })
- delete instanceTypeMap[id]
- }
-
- return result
- }
- return new Error(`[JS Framework] Using invalid instance id `
- + `"${id}" when calling ${methodName}.`)
- }
-}
-
-/**
- * Register methods which init each frameworks.
- * @param {string} methodName
- * @param {function} sharedMethod
- */
-function adaptMethod (methodName, sharedMethod) {
- methods[methodName] = function (...args) {
- if (typeof sharedMethod === 'function') {
- sharedMethod(...args)
- }
-
- // TODO: deprecated
- for (const name in runtimeConfig.frameworks) {
- const framework = runtimeConfig.frameworks[name]
- if (framework && framework[methodName]) {
- framework[methodName](...args)
- }
- }
- }
-}
-
-export default function init (config) {
- runtimeConfig = config || {}
- frameworks = runtimeConfig.frameworks || {}
- initTaskHandler()
-
- // Init each framework by `init` method and `config` which contains three
- // virtual-DOM Class: `Document`, `Element` & `Comment`, and a JS bridge method:
- // `sendTasks(...args)`.
- for (const name in frameworks) {
- const framework = frameworks[name]
- if (typeof framework.init === 'function') {
- try {
- framework.init(config)
- }
- catch (e) {}
- }
- }
-
- adaptMethod('registerComponents', registerComponents)
- adaptMethod('registerModules', registerModules)
- adaptMethod('registerMethods')
-
- ; ['destroyInstance', 'refreshInstance'].forEach(genInstance)
-
- return methods
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/api/module.js
----------------------------------------------------------------------
diff --git a/html5/runtime/api/module.js b/html5/runtime/api/module.js
deleted file mode 100644
index df26b92..0000000
--- a/html5/runtime/api/module.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-const weexModules = {}
-
-/**
- * Register native modules information.
- * @param {object} newModules
- */
-export function registerModules (newModules) {
- for (const name in newModules) {
- if (!weexModules[name]) {
- weexModules[name] = {}
- }
- newModules[name].forEach(method => {
- if (typeof method === 'string') {
- weexModules[name][method] = true
- }
- else {
- weexModules[name][method.name] = method.args
- }
- })
- }
-}
-
-/**
- * Check whether the module or the method has been registered.
- * @param {String} module name
- * @param {String} method name (optional)
- */
-export function isRegisteredModule (name, method) {
- if (typeof method === 'string') {
- return !!(weexModules[name] && weexModules[name][method])
- }
- return !!weexModules[name]
-}
-
-export function getModuleDescription (name) {
- return weexModules[name]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/api/service.js
----------------------------------------------------------------------
diff --git a/html5/runtime/api/service.js b/html5/runtime/api/service.js
deleted file mode 100644
index 6f2e72e..0000000
--- a/html5/runtime/api/service.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// JS Services
-
-export const services = []
-
-/**
- * Register a JavaScript service.
- * A JavaScript service options could have a set of lifecycle methods
- * for each Weex instance. For example: create, refresh, destroy.
- * For the JS framework maintainer if you want to supply some features
- * which need to work well in different Weex instances, even in different
- * frameworks separately. You can make a JavaScript service to init
- * its variables or classes for each Weex instance when it's created
- * and recycle them when it's destroyed.
- * @param {object} options Could have { create, refresh, destroy }
- * lifecycle methods. In create method it should
- * return an object of what variables or classes
- * would be injected into the Weex instance.
- */
-export function register (name, options) {
- if (has(name)) {
- console.warn(`Service "${name}" has been registered already!`)
- }
- else {
- options = Object.assign({}, options)
- services.push({ name, options })
- }
-}
-
-/**
- * Unregister a JavaScript service by name
- * @param {string} name
- */
-export function unregister (name) {
- services.some((service, index) => {
- if (service.name === name) {
- services.splice(index, 1)
- return true
- }
- })
-}
-
-/**
- * Check if a JavaScript service with a certain name existed.
- * @param {string} name
- * @return {Boolean}
- */
-export function has (name) {
- return indexOf(name) >= 0
-}
-
-/**
- * Find the index of a JavaScript service by name
- * @param {string} name
- * @return {number}
- */
-function indexOf (name) {
- return services.map(service => service.name).indexOf(name)
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/CallbackManager.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/CallbackManager.js b/html5/runtime/bridge/CallbackManager.js
deleted file mode 100644
index 70bd729..0000000
--- a/html5/runtime/bridge/CallbackManager.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { decodePrimitive } from './normalize'
-
-function getHookKey (componentId, type, hookName) {
- return `${type}@${hookName}#${componentId}`
-}
-
-/**
- * For general callback management of a certain Weex instance.
- * Because function can not passed into native, so we create callback
- * callback id for each function and pass the callback id into native
- * in fact. And when a callback called from native, we can find the real
- * callback through the callback id we have passed before.
- */
-export default class CallbackManager {
- constructor (instanceId) {
- this.instanceId = String(instanceId)
- this.lastCallbackId = 0
- this.callbacks = {}
- this.hooks = {}
- }
- add (callback) {
- this.lastCallbackId++
- this.callbacks[this.lastCallbackId] = callback
- return this.lastCallbackId
- }
- remove (callbackId) {
- const callback = this.callbacks[callbackId]
- delete this.callbacks[callbackId]
- return callback
- }
- registerHook (componentId, type, hookName, hookFunction) {
- // TODO: validate arguments
- const key = getHookKey(componentId, type, hookName)
- if (this.hooks[key]) {
- console.warn(`[JS Framework] Override an existing component hook "${key}".`)
- }
- this.hooks[key] = hookFunction
- }
- triggerHook (componentId, type, hookName, options = {}) {
- // TODO: validate arguments
- const key = getHookKey(componentId, type, hookName)
- const hookFunction = this.hooks[key]
- if (typeof hookFunction !== 'function') {
- console.error(`[JS Framework] Invalid hook function type (${typeof hookFunction}) on "${key}".`)
- return null
- }
- let result = null
- try {
- result = hookFunction.apply(null, options.args || [])
- }
- catch (e) {
- console.error(`[JS Framework] Failed to execute the hook function on "${key}".`)
- }
- return result
- }
- consume (callbackId, data, ifKeepAlive) {
- const callback = this.callbacks[callbackId]
- if (typeof ifKeepAlive === 'undefined' || ifKeepAlive === false) {
- delete this.callbacks[callbackId]
- }
- if (typeof callback === 'function') {
- return callback(decodePrimitive(data))
- }
- return new Error(`invalid callback id "${callbackId}"`)
- }
- close () {
- this.callbacks = {}
- this.hooks = {}
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/Handler.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/Handler.js b/html5/runtime/bridge/Handler.js
deleted file mode 100644
index 71bf4c5..0000000
--- a/html5/runtime/bridge/Handler.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @fileOverview
- * Task handler for communication between javascript and native.
- */
-
-const handlerMap = {
- createBody: 'callCreateBody',
- addElement: 'callAddElement',
- removeElement: 'callRemoveElement',
- moveElement: 'callMoveElement',
- updateAttrs: 'callUpdateAttrs',
- updateStyle: 'callUpdateStyle',
- addEvent: 'callAddEvent',
- removeEvent: 'callRemoveEvent'
-}
-
-/**
- * Create a task handler.
- * @param {string} id
- * @param {function} handler
- * @return {function} taskHandler
- */
-export function createHandler (id, handler) {
- const defaultHandler = handler || global.callNative
-
- /* istanbul ignore if */
- if (typeof defaultHandler !== 'function') {
- console.error('[JS Runtime] no default handler')
- }
-
- return function taskHandler (tasks) {
- /* istanbul ignore if */
- if (!Array.isArray(tasks)) {
- tasks = [tasks]
- }
- for (let i = 0; i < tasks.length; i++) {
- const returnValue = dispatchTask(id, tasks[i], defaultHandler)
- if (returnValue === -1) {
- return returnValue
- }
- }
- }
-}
-
-/**
- * Check if there is a corresponding available handler in the environment.
- * @param {string} module
- * @param {string} method
- * @return {boolean}
- */
-function hasAvailableHandler (module, method) {
- return module === 'dom'
- && handlerMap[method]
- && typeof global[handlerMap[method]] === 'function'
-}
-
-/**
- * Dispatch the task to the specified handler.
- * @param {string} id
- * @param {object} task
- * @param {function} defaultHandler
- * @return {number} signal returned from native
- */
-function dispatchTask (id, task, defaultHandler) {
- const { module, method, args } = task
-
- if (hasAvailableHandler(module, method)) {
- return global[handlerMap[method]](id, ...args, '-1')
- }
-
- return defaultHandler(id, [task], '-1')
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/Listener.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/Listener.js b/html5/runtime/bridge/Listener.js
deleted file mode 100644
index 2bf3893..0000000
--- a/html5/runtime/bridge/Listener.js
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
-* Create the action object.
-* @param {string} name
-* @param {array} arguments
-* @return {object} action
-*/
-function createAction (name, args = []) {
- return { module: 'dom', method: name, args: args }
-}
-
-export default class Listener {
- constructor (id, handler) {
- this.id = id
- this.batched = false
- this.updates = []
- if (typeof handler === 'function') {
- Object.defineProperty(this, 'handler', {
- configurable: true,
- enumerable: true,
- writable: true,
- value: handler
- })
- }
- else {
- console.error('[JS Runtime] invalid parameter, handler must be a function')
- }
- }
-
- /**
- * Send the "createFinish" signal.
- * @param {function} callback
- * @return {undefined | number} the signal sent by native
- */
- createFinish (callback) {
- const handler = this.handler
- return handler([createAction('createFinish')], callback)
- }
-
- /**
- * Send the "updateFinish" signal.
- * @param {function} callback
- * @return {undefined | number} the signal sent by native
- */
- updateFinish (callback) {
- const handler = this.handler
- return handler([createAction('updateFinish')], callback)
- }
-
- /**
- * Send the "refreshFinish" signal.
- * @param {function} callback
- * @return {undefined | number} the signal sent by native
- */
- refreshFinish (callback) {
- const handler = this.handler
- return handler([createAction('refreshFinish')], callback)
- }
-
- /**
- * Send the "createBody" signal.
- * @param {object} element
- * @return {undefined | number} the signal sent by native
- */
- createBody (element) {
- const body = element.toJSON()
- const children = body.children
- delete body.children
- const actions = [createAction('createBody', [body])]
- if (children) {
- actions.push.apply(actions, children.map(child => {
- return createAction('addElement', [body.ref, child, -1])
- }))
- }
- return this.addActions(actions)
- }
-
- /**
- * Send the "addElement" signal.
- * @param {object} element
- * @param {stirng} reference id
- * @param {number} index
- * @return {undefined | number} the signal sent by native
- */
- addElement (element, ref, index) {
- if (!(index >= 0)) {
- index = -1
- }
- return this.addActions(createAction('addElement', [ref, element.toJSON(), index]))
- }
-
- /**
- * Send the "removeElement" signal.
- * @param {stirng} reference id
- * @return {undefined | number} the signal sent by native
- */
- removeElement (ref) {
- if (Array.isArray(ref)) {
- const actions = ref.map((r) => createAction('removeElement', [r]))
- return this.addActions(actions)
- }
- return this.addActions(createAction('removeElement', [ref]))
- }
-
- /**
- * Send the "moveElement" signal.
- * @param {stirng} target reference id
- * @param {stirng} parent reference id
- * @param {number} index
- * @return {undefined | number} the signal sent by native
- */
- moveElement (targetRef, parentRef, index) {
- return this.addActions(createAction('moveElement', [targetRef, parentRef, index]))
- }
-
- /**
- * Send the "updateAttrs" signal.
- * @param {stirng} reference id
- * @param {stirng} key
- * @param {stirng} value
- * @return {undefined | number} the signal sent by native
- */
- setAttr (ref, key, value) {
- const result = {}
- result[key] = value
- return this.addActions(createAction('updateAttrs', [ref, result]))
- }
-
- /**
- * Send the "updateStyle" signal, update a sole style.
- * @param {stirng} reference id
- * @param {stirng} key
- * @param {stirng} value
- * @return {undefined | number} the signal sent by native
- */
- setStyle (ref, key, value) {
- const result = {}
- result[key] = value
- return this.addActions(createAction('updateStyle', [ref, result]))
- }
-
- /**
- * Send the "updateStyle" signal.
- * @param {stirng} reference id
- * @param {object} style
- * @return {undefined | number} the signal sent by native
- */
- setStyles (ref, style) {
- return this.addActions(createAction('updateStyle', [ref, style]))
- }
-
- /**
- * Send the "addEvent" signal.
- * @param {stirng} reference id
- * @param {string} event type
- * @return {undefined | number} the signal sent by native
- */
- addEvent (ref, type) {
- return this.addActions(createAction('addEvent', [ref, type]))
- }
-
- /**
- * Send the "removeEvent" signal.
- * @param {stirng} reference id
- * @param {string} event type
- * @return {undefined | number} the signal sent by native
- */
- removeEvent (ref, type) {
- return this.addActions(createAction('removeEvent', [ref, type]))
- }
-
- /**
- * Default handler.
- * @param {object | array} actions
- * @param {function} callback
- * @return {} anything returned by callback function
- */
- handler (actions, cb) {
- return cb && cb()
- }
-
- /**
- * Add actions into updates.
- * @param {object | array} actions
- * @return {undefined | number} the signal sent by native
- */
- addActions (actions) {
- const updates = this.updates
- const handler = this.handler
-
- if (!Array.isArray(actions)) {
- actions = [actions]
- }
-
- if (this.batched) {
- updates.push.apply(updates, actions)
- }
- else {
- return handler(actions)
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/TaskCenter.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/TaskCenter.js b/html5/runtime/bridge/TaskCenter.js
deleted file mode 100644
index defee6f..0000000
--- a/html5/runtime/bridge/TaskCenter.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import CallbackManager from './CallbackManager'
-import Element from '../vdom/Element'
-import { typof } from '../utils'
-import { normalizePrimitive } from './normalize'
-
-let fallback = function () {}
-
-// The API of TaskCenter would be re-design.
-export class TaskCenter {
- constructor (id, sendTasks) {
- Object.defineProperty(this, 'instanceId', {
- enumerable: true,
- value: String(id)
- })
- Object.defineProperty(this, 'callbackManager', {
- enumerable: true,
- value: new CallbackManager(id)
- })
- fallback = sendTasks || function () {}
- }
-
- callback (callbackId, data, ifKeepAlive) {
- return this.callbackManager.consume(callbackId, data, ifKeepAlive)
- }
-
- registerHook (...args) {
- return this.callbackManager.registerHook(...args)
- }
-
- triggerHook (...args) {
- return this.callbackManager.triggerHook(...args)
- }
-
- updateData (componentId, newData, callback) {
- this.send('module', {
- module: 'dom',
- method: 'updateComponentData'
- }, [componentId, newData, callback])
- }
-
- destroyCallback () {
- return this.callbackManager.close()
- }
-
- /**
- * Normalize a value. Specially, if the value is a function, then generate a function id
- * and save it to `CallbackManager`, at last return the function id.
- * @param {any} v
- * @return {primitive}
- */
- normalize (v) {
- const type = typof(v)
- if (v && v instanceof Element) {
- return v.ref
- }
- if (v && v._isVue && v.$el instanceof Element) {
- return v.$el.ref
- }
- if (type === 'Function') {
- return this.callbackManager.add(v).toString()
- }
- return normalizePrimitive(v)
- }
-
- send (type, params, args, options) {
- const { action, component, ref, module, method } = params
-
- args = args.map(arg => this.normalize(arg))
-
- switch (type) {
- case 'dom':
- return this[action](this.instanceId, args)
- case 'component':
- return this.componentHandler(this.instanceId, ref, method, args, Object.assign({ component }, options))
- default:
- return this.moduleHandler(this.instanceId, module, method, args, options)
- }
- }
-
- callDOM (action, args) {
- return this[action](this.instanceId, args)
- }
-
- callComponent (ref, method, args, options) {
- return this.componentHandler(this.instanceId, ref, method, args, options)
- }
-
- callModule (module, method, args, options) {
- return this.moduleHandler(this.instanceId, module, method, args, options)
- }
-}
-
-export function init () {
- const DOM_METHODS = {
- createFinish: global.callCreateFinish,
- updateFinish: global.callUpdateFinish,
- refreshFinish: global.callRefreshFinish,
-
- createBody: global.callCreateBody,
-
- addElement: global.callAddElement,
- removeElement: global.callRemoveElement,
- moveElement: global.callMoveElement,
- updateAttrs: global.callUpdateAttrs,
- updateStyle: global.callUpdateStyle,
-
- addEvent: global.callAddEvent,
- removeEvent: global.callRemoveEvent
- }
- const proto = TaskCenter.prototype
-
- for (const name in DOM_METHODS) {
- const method = DOM_METHODS[name]
- proto[name] = method ?
- (id, args) => method(id, ...args) :
- (id, args) => fallback(id, [{ module: 'dom', method: name, args }], '-1')
- }
-
- proto.componentHandler = global.callNativeComponent ||
- ((id, ref, method, args, options) =>
- fallback(id, [{ component: options.component, ref, method, args }]))
-
- proto.moduleHandler = global.callNativeModule ||
- ((id, module, method, args) =>
- fallback(id, [{ module, method, args }]))
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/debug.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/debug.js b/html5/runtime/bridge/debug.js
deleted file mode 100644
index 6e24c6a..0000000
--- a/html5/runtime/bridge/debug.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { getTaskCenter } from '../vdom/operation'
-import { isRegisteredModule } from '../api/module'
-
-export function track (id, type, value) {
- const taskCenter = getTaskCenter(id)
- if (!taskCenter || typeof taskCenter.send !== 'function') {
- console.error(`[JS Framework] Failed to create tracker!`)
- return
- }
- if (!type || !value) {
- console.warn(`[JS Framework] Invalid track type (${type}) or value (${value})`)
- return
- }
- const label = `jsfm.${type}.${value}`
- try {
- if (isRegisteredModule('userTrack', 'addPerfPoint')) {
- const message = Object.create(null)
- message[label] = '4'
- taskCenter.send('module', {
- module: 'userTrack',
- method: 'addPerfPoint'
- }, [message])
- }
- }
- catch (err) {
- console.error(`[JS Framework] Failed to trace "${label}"!`)
- }
-}
-
-export function error (...messages) {
- if (typeof console.error === 'function') {
- console.error(`[JS Framework] `, ...messages)
- }
-}
-
-export function handleException (err) {
- if (typeof console.error === 'function') {
- try {
- console.error(err.toString())
- }
- catch (e) {}
- }
- if (process.env.NODE_ENV !== 'production') {
- throw err
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/normalize.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/normalize.js b/html5/runtime/bridge/normalize.js
deleted file mode 100644
index d7f2450..0000000
--- a/html5/runtime/bridge/normalize.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { typof, bufferToBase64, base64ToBuffer } from '../utils'
-
-/**
- * Normalize a primitive value.
- * @param {any} v
- * @return {primitive}
- */
-export function normalizePrimitive (v) {
- const type = typof(v)
-
- switch (type) {
- case 'Undefined':
- case 'Null':
- return ''
-
- case 'RegExp':
- return v.toString()
- case 'Date':
- return v.toISOString()
-
- case 'Number':
- case 'String':
- case 'Boolean':
- case 'Array':
- case 'Object':
- return v
-
- case 'ArrayBuffer':
- return {
- '@type': 'binary',
- dataType: type,
- base64: bufferToBase64(v)
- }
-
- case 'Int8Array':
- case 'Uint8Array':
- case 'Uint8ClampedArray':
- case 'Int16Array':
- case 'Uint16Array':
- case 'Int32Array':
- case 'Uint32Array':
- case 'Float32Array':
- case 'Float64Array':
- return {
- '@type': 'binary',
- dataType: type,
- base64: bufferToBase64(v.buffer)
- }
-
- default:
- return JSON.stringify(v)
- }
-}
-
-export function decodePrimitive (data) {
- if (typof(data) === 'Object') {
- // decode base64 into binary
- if (data['@type'] && data['@type'] === 'binary') {
- return base64ToBuffer(data.base64 || '')
- }
-
- const realData = {}
- for (const key in data) {
- realData[key] = decodePrimitive(data[key])
- }
- return realData
- }
- if (typof(data) === 'Array') {
- return data.map(decodePrimitive)
- }
- return data
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/bridge/receiver.js
----------------------------------------------------------------------
diff --git a/html5/runtime/bridge/receiver.js b/html5/runtime/bridge/receiver.js
deleted file mode 100644
index e6dea06..0000000
--- a/html5/runtime/bridge/receiver.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { getDoc } from '../vdom/operation'
-
-function fireEvent (document, nodeId, type, event, domChanges, params) {
- const el = document.getRef(nodeId)
- if (el) {
- return document.fireEvent(el, type, event, domChanges, params)
- }
- return new Error(`invalid element reference "${nodeId}"`)
-}
-
-function callback (document, callbackId, data, ifKeepAlive) {
- return document.taskCenter.callback(callbackId, data, ifKeepAlive)
-}
-
-function componentHook (document, componentId, type, hook, options) {
- if (!document || !document.taskCenter) {
- console.error(`[JS Framework] Can't find "document" or "taskCenter".`)
- return null
- }
- let result = null
- try {
- result = document.taskCenter.triggerHook(componentId, type, hook, options)
- }
- catch (e) {
- console.error(`[JS Framework] Failed to trigger the "${type}@${hook}" hook on ${componentId}.`)
- }
- return result
-}
-
-/**
- * Accept calls from native (event or callback).
- *
- * @param {string} id
- * @param {array} tasks list with `method` and `args`
- */
-export function receiveTasks (id, tasks) {
- const document = getDoc(id)
- if (!document) {
- return new Error(`[JS Framework] Failed to receiveTasks, `
- + `instance (${id}) is not available.`)
- }
- if (Array.isArray(tasks)) {
- return tasks.map(task => {
- switch (task.method) {
- case 'callback': return callback(document, ...task.args)
- case 'fireEventSync':
- case 'fireEvent': return fireEvent(document, ...task.args)
- case 'componentHook': return componentHook(document, ...task.args)
- }
- })
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/index.js
----------------------------------------------------------------------
diff --git a/html5/runtime/index.js b/html5/runtime/index.js
deleted file mode 100644
index 90c425e..0000000
--- a/html5/runtime/index.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @fileOverview
- * Register framework(s) in JS runtime. Weex supply two layers for 3rd-party
- * framework(s): one is the instance management layer, another is the
- * virtual-DOM layer.
- */
-
-import * as shared from '../shared'
-
-import init from './api/init'
-import config from './api/config'
-import { register, unregister, has } from './api/service'
-
-/* istanbul ignore next */
-function freezePrototype () {
- shared.freezePrototype()
-
- // Object.freeze(config.Element)
- Object.freeze(config.Comment)
- Object.freeze(config.Listener)
- Object.freeze(config.Document.prototype)
- // Object.freeze(config.Element.prototype)
- Object.freeze(config.Comment.prototype)
- Object.freeze(config.Listener.prototype)
-}
-
-export default {
- setNativeConsole: shared.setNativeConsole,
- resetNativeConsole: shared.resetNativeConsole,
- setNativeTimer: shared.setNativeTimer,
- resetNativeTimer: shared.resetNativeTimer,
- service: { register, unregister, has },
- freezePrototype,
- init,
- config
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/utils.js
----------------------------------------------------------------------
diff --git a/html5/runtime/utils.js b/html5/runtime/utils.js
deleted file mode 100644
index c2ab10f..0000000
--- a/html5/runtime/utils.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Get a unique id.
- */
-let nextNodeRef = 1
-export function uniqueId () {
- return (nextNodeRef++).toString()
-}
-
-export function typof (v) {
- const s = Object.prototype.toString.call(v)
- return s.substring(8, s.length - 1)
-}
-
-export function bufferToBase64 (buffer) {
- if (typeof btoa !== 'function') {
- return ''
- }
- const string = Array.prototype.map.call(
- new Uint8Array(buffer),
- code => String.fromCharCode(code)
- ).join('')
- return btoa(string) // eslint-disable-line no-undef
-}
-
-export function base64ToBuffer (base64) {
- if (typeof atob !== 'function') {
- return new ArrayBuffer(0)
- }
- const string = atob(base64) // eslint-disable-line no-undef
- const array = new Uint8Array(string.length)
- Array.prototype.forEach.call(string, (ch, i) => {
- array[i] = ch.charCodeAt(0)
- })
- return array.buffer
-}
-
-/**
- * Detect if the param is falsy or empty
- * @param {any} any
- */
-export function isEmpty (any) {
- if (!any || typeof any !== 'object') {
- return true
- }
-
- for (const key in any) {
- if (Object.prototype.hasOwnProperty.call(any, key)) {
- return false
- }
- }
- return true
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/Comment.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/Comment.js b/html5/runtime/vdom/Comment.js
deleted file mode 100644
index d7ab115..0000000
--- a/html5/runtime/vdom/Comment.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import Node from './Node'
-import { uniqueId } from '../utils'
-
-export default class Comment extends Node {
- constructor (value) {
- super()
-
- this.nodeType = 8
- this.nodeId = uniqueId()
- this.ref = this.nodeId
- this.type = 'comment'
- this.value = value
- this.children = []
- this.pureChildren = []
- }
-
- /**
- * Convert to HTML comment string.
- * @return {stirng} html
- */
- toString () {
- return '<!-- ' + this.value + ' -->'
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/Document.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/Document.js b/html5/runtime/vdom/Document.js
deleted file mode 100644
index c64fba5..0000000
--- a/html5/runtime/vdom/Document.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import Comment from './Comment'
-import Element from './Element'
-import Listener from '../bridge/Listener'
-import { TaskCenter } from '../bridge/TaskCenter'
-import { createHandler } from '../bridge/Handler'
-import { addDoc, removeDoc, appendBody, setBody } from './operation'
-
-/**
- * Update all changes for an element.
- * @param {object} element
- * @param {object} changes
- */
-function updateElement (el, changes) {
- const attrs = changes.attrs || {}
- for (const name in attrs) {
- el.setAttr(name, attrs[name], true)
- }
- const style = changes.style || {}
- for (const name in style) {
- el.setStyle(name, style[name], true)
- }
-}
-
-export default class Document {
- constructor (id, url, handler) {
- id = id ? id.toString() : ''
- this.id = id
- this.URL = url
-
- addDoc(id, this)
- this.nodeMap = {}
- const L = Document.Listener || Listener
- this.listener = new L(id, handler || createHandler(id, Document.handler)) // deprecated
- this.taskCenter = new TaskCenter(id, handler ? (id, ...args) => handler(...args) : Document.handler)
- this.createDocumentElement()
- }
-
- /**
- * Get the node from nodeMap.
- * @param {string} reference id
- * @return {object} node
- */
- getRef (ref) {
- return this.nodeMap[ref]
- }
-
- /**
- * Turn on batched updates.
- */
- open () {
- this.listener.batched = false
- }
-
- /**
- * Turn off batched updates.
- */
- close () {
- this.listener.batched = true
- }
-
- /**
- * Create the document element.
- * @return {object} documentElement
- */
- createDocumentElement () {
- if (!this.documentElement) {
- const el = new Element('document')
- el.docId = this.id
- el.ownerDocument = this
- el.role = 'documentElement'
- el.depth = 0
- el.ref = '_documentElement'
- this.nodeMap._documentElement = el
- this.documentElement = el
-
- Object.defineProperty(el, 'appendChild', {
- configurable: true,
- enumerable: true,
- writable: true,
- value: (node) => {
- appendBody(this, node)
- }
- })
-
- Object.defineProperty(el, 'insertBefore', {
- configurable: true,
- enumerable: true,
- writable: true,
- value: (node, before) => {
- appendBody(this, node, before)
- }
- })
- }
-
- return this.documentElement
- }
-
- /**
- * Create the body element.
- * @param {string} type
- * @param {objct} props
- * @return {object} body element
- */
- createBody (type, props) {
- if (!this.body) {
- const el = new Element(type, props)
- setBody(this, el)
- }
-
- return this.body
- }
-
- /**
- * Create an element.
- * @param {string} tagName
- * @param {objct} props
- * @return {object} element
- */
- createElement (tagName, props) {
- return new Element(tagName, props)
- }
-
- /**
- * Create an comment.
- * @param {string} text
- * @return {object} comment
- */
- createComment (text) {
- return new Comment(text)
- }
-
- /**
- * Fire an event on specified element manually.
- * @param {object} element
- * @param {string} event type
- * @param {object} event object
- * @param {object} dom changes
- * @param {object} options
- * @return {} anything returned by handler function
- */
- fireEvent (el, type, event, domChanges, options) {
- if (!el) {
- return
- }
- event = event || {}
- event.type = event.type || type
- event.target = el
- event.currentTarget = el
- event.timestamp = Date.now()
- if (domChanges) {
- updateElement(el, domChanges)
- }
- const isBubble = this.getRef('_root').attr['bubble'] === 'true'
- return el.fireEvent(type, event, isBubble, options)
- }
-
- /**
- * Destroy current document, and remove itself form docMap.
- */
- destroy () {
- this.taskCenter.destroyCallback()
- delete this.listener
- delete this.nodeMap
- delete this.taskCenter
- removeDoc(this.id)
- }
-}
-
-// default task handler
-Document.handler = null
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/Element.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/Element.js b/html5/runtime/vdom/Element.js
deleted file mode 100644
index 5ba05ba..0000000
--- a/html5/runtime/vdom/Element.js
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import Node from './Node'
-import {
- getDoc,
- getTaskCenter,
- linkParent,
- nextElement,
- previousElement,
- insertIndex,
- moveIndex,
- removeIndex
-} from './operation'
-import { uniqueId, isEmpty } from '../utils'
-import { getWeexElement, setElement } from './WeexElement'
-
-const DEFAULT_TAG_NAME = 'div'
-const BUBBLE_EVENTS = [
- 'click', 'longpress', 'touchstart', 'touchmove', 'touchend',
- 'panstart', 'panmove', 'panend', 'horizontalpan', 'verticalpan', 'swipe'
-]
-
-function registerNode (docId, node) {
- const doc = getDoc(docId)
- doc.nodeMap[node.nodeId] = node
-}
-
-export default class Element extends Node {
- constructor (type = DEFAULT_TAG_NAME, props, isExtended) {
- super()
-
- const WeexElement = getWeexElement(type)
- if (WeexElement && !isExtended) {
- return new WeexElement(type, props, true)
- }
-
- props = props || {}
- this.nodeType = 1
- this.nodeId = uniqueId()
- this.ref = this.nodeId
- this.type = type
- this.attr = props.attr || {}
- this.style = props.style || {}
- this.classStyle = props.classStyle || {}
- this.event = {}
- this.children = []
- this.pureChildren = []
- }
-
- /**
- * Append a child node.
- * @param {object} node
- * @return {undefined | number} the signal sent by native
- */
- appendChild (node) {
- if (node.parentNode && node.parentNode !== this) {
- return
- }
- /* istanbul ignore else */
- if (!node.parentNode) {
- linkParent(node, this)
- insertIndex(node, this.children, this.children.length, true)
- if (this.docId) {
- registerNode(this.docId, node)
- }
- if (node.nodeType === 1) {
- insertIndex(node, this.pureChildren, this.pureChildren.length)
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- return taskCenter.send(
- 'dom',
- { action: 'addElement' },
- [this.ref, node.toJSON(), -1]
- )
- }
- }
- }
- else {
- moveIndex(node, this.children, this.children.length, true)
- if (node.nodeType === 1) {
- const index = moveIndex(node, this.pureChildren, this.pureChildren.length)
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter && index >= 0) {
- return taskCenter.send(
- 'dom',
- { action: 'moveElement' },
- [node.ref, this.ref, index]
- )
- }
- }
- }
- }
-
- /**
- * Insert a node before specified node.
- * @param {object} node
- * @param {object} before
- * @return {undefined | number} the signal sent by native
- */
- insertBefore (node, before) {
- if (node.parentNode && node.parentNode !== this) {
- return
- }
- if (node === before || (node.nextSibling && node.nextSibling === before)) {
- return
- }
- if (!node.parentNode) {
- linkParent(node, this)
- insertIndex(node, this.children, this.children.indexOf(before), true)
- if (this.docId) {
- registerNode(this.docId, node)
- }
- if (node.nodeType === 1) {
- const pureBefore = nextElement(before)
- const index = insertIndex(
- node,
- this.pureChildren,
- pureBefore
- ? this.pureChildren.indexOf(pureBefore)
- : this.pureChildren.length
- )
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- return taskCenter.send(
- 'dom',
- { action: 'addElement' },
- [this.ref, node.toJSON(), index]
- )
- }
- }
- }
- else {
- moveIndex(node, this.children, this.children.indexOf(before), true)
- if (node.nodeType === 1) {
- const pureBefore = nextElement(before)
- /* istanbul ignore next */
- const index = moveIndex(
- node,
- this.pureChildren,
- pureBefore
- ? this.pureChildren.indexOf(pureBefore)
- : this.pureChildren.length
- )
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter && index >= 0) {
- return taskCenter.send(
- 'dom',
- { action: 'moveElement' },
- [node.ref, this.ref, index]
- )
- }
- }
- }
- }
-
- /**
- * Insert a node after specified node.
- * @param {object} node
- * @param {object} after
- * @return {undefined | number} the signal sent by native
- */
- insertAfter (node, after) {
- if (node.parentNode && node.parentNode !== this) {
- return
- }
- if (node === after || (node.previousSibling && node.previousSibling === after)) {
- return
- }
- if (!node.parentNode) {
- linkParent(node, this)
- insertIndex(node, this.children, this.children.indexOf(after) + 1, true)
- /* istanbul ignore else */
- if (this.docId) {
- registerNode(this.docId, node)
- }
- if (node.nodeType === 1) {
- const index = insertIndex(
- node,
- this.pureChildren,
- this.pureChildren.indexOf(previousElement(after)) + 1
- )
- const taskCenter = getTaskCenter(this.docId)
- /* istanbul ignore else */
- if (taskCenter) {
- return taskCenter.send(
- 'dom',
- { action: 'addElement' },
- [this.ref, node.toJSON(), index]
- )
- }
- }
- }
- else {
- moveIndex(node, this.children, this.children.indexOf(after) + 1, true)
- if (node.nodeType === 1) {
- const index = moveIndex(
- node,
- this.pureChildren,
- this.pureChildren.indexOf(previousElement(after)) + 1
- )
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter && index >= 0) {
- return taskCenter.send(
- 'dom',
- { action: 'moveElement' },
- [node.ref, this.ref, index]
- )
- }
- }
- }
- }
-
- /**
- * Remove a child node, and decide whether it should be destroyed.
- * @param {object} node
- * @param {boolean} preserved
- */
- removeChild (node, preserved) {
- if (node.parentNode) {
- removeIndex(node, this.children, true)
- if (node.nodeType === 1) {
- removeIndex(node, this.pureChildren)
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- taskCenter.send(
- 'dom',
- { action: 'removeElement' },
- [node.ref]
- )
- }
- }
- }
- if (!preserved) {
- node.destroy()
- }
- }
-
- /**
- * Clear all child nodes.
- */
- clear () {
- const taskCenter = getTaskCenter(this.docId)
- /* istanbul ignore else */
- if (taskCenter) {
- this.pureChildren.forEach(node => {
- taskCenter.send(
- 'dom',
- { action: 'removeElement' },
- [node.ref]
- )
- })
- }
- this.children.forEach(node => {
- node.destroy()
- })
- this.children.length = 0
- this.pureChildren.length = 0
- }
-
- /**
- * Set an attribute, and decide whether the task should be send to native.
- * @param {string} key
- * @param {string | number} value
- * @param {boolean} silent
- */
- setAttr (key, value, silent) {
- if (this.attr[key] === value && silent !== false) {
- return
- }
- this.attr[key] = value
- const taskCenter = getTaskCenter(this.docId)
- if (!silent && taskCenter) {
- const result = {}
- result[key] = value
- taskCenter.send(
- 'dom',
- { action: 'updateAttrs' },
- [this.ref, result]
- )
- }
- }
-
- /**
- * Set batched attributes.
- * @param {object} batchedAttrs
- * @param {boolean} silent
- */
- setAttrs (batchedAttrs, silent) {
- if (isEmpty(batchedAttrs)) return
- const mutations = {}
- for (const key in batchedAttrs) {
- if (this.attr[key] !== batchedAttrs[key]) {
- this.attr[key] = batchedAttrs[key]
- mutations[key] = batchedAttrs[key]
- }
- }
- if (!isEmpty(mutations)) {
- const taskCenter = getTaskCenter(this.docId)
- if (!silent && taskCenter) {
- taskCenter.send(
- 'dom',
- { action: 'updateAttrs' },
- [this.ref, mutations]
- )
- }
- }
- }
-
- /**
- * Set a style property, and decide whether the task should be send to native.
- * @param {string} key
- * @param {string | number} value
- * @param {boolean} silent
- */
- setStyle (key, value, silent) {
- if (this.style[key] === value && silent !== false) {
- return
- }
- this.style[key] = value
- const taskCenter = getTaskCenter(this.docId)
- if (!silent && taskCenter) {
- const result = {}
- result[key] = value
- taskCenter.send(
- 'dom',
- { action: 'updateStyle' },
- [this.ref, result]
- )
- }
- }
-
- /**
- * Set batched style properties.
- * @param {object} batchedStyles
- * @param {boolean} silent
- */
- setStyles (batchedStyles, silent) {
- if (isEmpty(batchedStyles)) return
- const mutations = {}
- for (const key in batchedStyles) {
- if (this.style[key] !== batchedStyles[key]) {
- this.style[key] = batchedStyles[key]
- mutations[key] = batchedStyles[key]
- }
- }
- if (!isEmpty(mutations)) {
- const taskCenter = getTaskCenter(this.docId)
- if (!silent && taskCenter) {
- taskCenter.send(
- 'dom',
- { action: 'updateStyle' },
- [this.ref, mutations]
- )
- }
- }
- }
-
- /**
- * Set style properties from class.
- * @param {object} classStyle
- */
- setClassStyle (classStyle) {
- // reset previous class style to empty string
- for (const key in this.classStyle) {
- this.classStyle[key] = ''
- }
-
- Object.assign(this.classStyle, classStyle)
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- taskCenter.send(
- 'dom',
- { action: 'updateStyle' },
- [this.ref, this.toStyle()]
- )
- }
- }
-
- /**
- * Add an event handler.
- * @param {string} event type
- * @param {function} event handler
- */
- addEvent (type, handler, params) {
- if (!this.event) {
- this.event = {}
- }
- if (!this.event[type]) {
- this.event[type] = { handler, params }
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- taskCenter.send(
- 'dom',
- { action: 'addEvent' },
- [this.ref, type]
- )
- }
- }
- }
-
- /**
- * Remove an event handler.
- * @param {string} event type
- */
- removeEvent (type) {
- if (this.event && this.event[type]) {
- delete this.event[type]
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- taskCenter.send(
- 'dom',
- { action: 'removeEvent' },
- [this.ref, type]
- )
- }
- }
- }
-
- /**
- * Fire an event manually.
- * @param {string} type type
- * @param {function} event handler
- * @param {boolean} isBubble whether or not event bubble
- * @param {boolean} options
- * @return {} anything returned by handler function
- */
- fireEvent (type, event, isBubble, options) {
- let result = null
- let isStopPropagation = false
- const eventDesc = this.event[type]
- if (eventDesc && event) {
- const handler = eventDesc.handler
- event.stopPropagation = () => {
- isStopPropagation = true
- }
- if (options && options.params) {
- result = handler.call(this, ...options.params, event)
- }
- else {
- result = handler.call(this, event)
- }
- }
-
- if (!isStopPropagation
- && isBubble
- && (BUBBLE_EVENTS.indexOf(type) !== -1)
- && this.parentNode
- && this.parentNode.fireEvent) {
- event.currentTarget = this.parentNode
- this.parentNode.fireEvent(type, event, isBubble) // no options
- }
-
- return result
- }
-
- /**
- * Get all styles of current element.
- * @return {object} style
- */
- toStyle () {
- return Object.assign({}, this.classStyle, this.style)
- }
-
- /**
- * Convert current element to JSON like object.
- * @return {object} element
- */
- toJSON () {
- const result = {
- ref: this.ref.toString(),
- type: this.type,
- attr: this.attr,
- style: this.toStyle()
- }
- const event = []
- for (const type in this.event) {
- const { params } = this.event[type]
- if (!params) {
- event.push(type)
- }
- else {
- event.push({ type, params })
- }
- }
- if (event.length) {
- result.event = event
- }
- if (this.pureChildren.length) {
- result.children = this.pureChildren.map((child) => child.toJSON())
- }
- return result
- }
-
- /**
- * Convert to HTML element tag string.
- * @return {stirng} html
- */
- toString () {
- return '<' + this.type +
- ' attr=' + JSON.stringify(this.attr) +
- ' style=' + JSON.stringify(this.toStyle()) + '>' +
- this.pureChildren.map((child) => child.toString()).join('') +
- '</' + this.type + '>'
- }
-}
-
-setElement(Element)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/Node.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/Node.js b/html5/runtime/vdom/Node.js
deleted file mode 100644
index 645f7df..0000000
--- a/html5/runtime/vdom/Node.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uniqueId } from '../utils'
-import { getDoc } from './operation'
-
-export default class Node {
- constructor () {
- this.nodeId = uniqueId()
- this.ref = this.nodeId
- this.children = []
- this.pureChildren = []
- this.parentNode = null
- this.nextSibling = null
- this.previousSibling = null
- }
-
- /**
- * Destroy current node, and remove itself form nodeMap.
- */
- destroy () {
- const doc = getDoc(this.docId)
- if (doc) {
- delete this.docId
- delete doc.nodeMap[this.nodeId]
- }
- this.children.forEach(child => {
- child.destroy()
- })
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/WeexElement.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/WeexElement.js b/html5/runtime/vdom/WeexElement.js
deleted file mode 100644
index 455e69e..0000000
--- a/html5/runtime/vdom/WeexElement.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { getTaskCenter } from './operation'
-
-let Element
-
-export function setElement (El) {
- Element = El
-}
-
-/**
- * A map which stores all type of elements.
- * @type {Object}
- */
-const registeredElements = {}
-
-/**
- * Register an extended element type with component methods.
- * @param {string} type component type
- * @param {array} methods a list of method names
- */
-export function registerElement (type, methods) {
- // Skip when no special component methods.
- if (!methods || !methods.length) {
- return
- }
-
- // Init constructor.
- class WeexElement extends Element {}
-
- // Add methods to prototype.
- methods.forEach(methodName => {
- WeexElement.prototype[methodName] = function (...args) {
- const taskCenter = getTaskCenter(this.docId)
- if (taskCenter) {
- return taskCenter.send('component', {
- ref: this.ref,
- component: type,
- method: methodName
- }, args)
- }
- }
- })
-
- // Add to element type map.
- registeredElements[type] = WeexElement
-}
-
-export function unregisterElement (type) {
- delete registeredElements[type]
-}
-
-export function getWeexElement (type) {
- return registeredElements[type]
-}
-
-export function isWeexElement (type) {
- return !!registeredElements[type]
-}
-
-/**
- * Clear all element types. Only for testing.
- */
-export function clearWeexElements () {
- for (const type in registeredElements) {
- unregisterElement(type)
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/index.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/index.js b/html5/runtime/vdom/index.js
deleted file mode 100644
index 2947f5e..0000000
--- a/html5/runtime/vdom/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import Node from './Node'
-import Element from './Element'
-import Comment from './Comment'
-import Document from './Document'
-
-export {
- registerElement,
- unregisterElement,
- isWeexElement,
- clearWeexElements
-} from './WeexElement'
-
-export {
- Document,
- Node,
- Element,
- Comment
-}
[02/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/vm/directive.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/vm/directive.js b/test/js-framework/unit/default/vm/directive.js
new file mode 100644
index 0000000..451b310
--- /dev/null
+++ b/test/js-framework/unit/default/vm/directive.js
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import {
+ applyNaitveComponentOptions,
+ bindSubVm,
+ bindSubVmAfterInitialized
+} from '../../../../../runtime/frameworks/legacy/vm/directive'
+
+import {
+ initState
+} from '../../../../../runtime/frameworks/legacy/core/state'
+import config from '../../../../../runtime/frameworks/legacy/config'
+
+const { nativeComponentMap } = config
+const directive = {}
+
+function extendVm (vm, methodNames) {
+ methodNames.forEach((name) => {
+ vm[name] = directive[name]
+ })
+ initState(vm)
+}
+
+function initElement (el) {
+ el.setAttr = function (k, v) { this.attr[k] = v }
+ el.setStyle = function (k, v) { this.style[k] = v }
+ el.setClassStyle = function (style) { this.classStyle = style }
+ el.addEvent = function (t, h) {
+ this.event[t] = h
+ }
+}
+
+describe('apply component options', () => {
+ it('apply top prop', () => {
+ nativeComponentMap['test-apply'] = {
+ type: 'test-apply1',
+ append: 'tree'
+ }
+ const template = {
+ type: 'test-apply'
+ }
+ applyNaitveComponentOptions(template)
+ expect(template.type).to.be.equal('test-apply')
+ expect(template.append).to.be.equal('tree')
+
+ delete nativeComponentMap['test-apply']
+ })
+
+ it('apply a object', () => {
+ nativeComponentMap['test-apply'] = {
+ classList: ['c'],
+ attr: {
+ a: 'a',
+ b: 'b'
+ }
+ }
+ const spy = sinon.spy()
+ const template = {
+ type: 'test-apply',
+ classList: spy,
+ attr: {
+ b: '2'
+ }
+ }
+ applyNaitveComponentOptions(template)
+
+ expect(template).to.deep.equal({
+ type: 'test-apply',
+ classList: spy,
+ attr: {
+ a: 'a',
+ b: '2'
+ }
+ })
+
+ delete nativeComponentMap['test-apply']
+ })
+})
+
+// exports._bindSubVm(subVm, template)
+describe('bind external infomations to sub vm', () => {
+ let vm, subVm
+ // const methodNames = [
+ // '_watch', '_bindKey', '_bindDir',
+ // '_setId', '_setAttr', '_setClass', '_setStyle',
+ // '_setEvent', '_bindEvents', '_bindElement',
+ // '_bindSubVm', '_bindSubVmAfterInitialized']
+ beforeEach(() => {
+ vm = {
+ _data: { a: 1, b: 2, c: 'class-style1' },
+ _watchers: [],
+ _app: { eventManager: { add: () => {} }},
+ _options: {
+ style: {
+ 'class-style1': {
+ aaa: 1,
+ bbb: 2
+ },
+ 'class-style2': {
+ aaa: 2,
+ ccc: 3
+ }
+ }
+ },
+ foo: function () {}
+ }
+ extendVm(vm, [])
+ subVm = {
+ _options: {
+ props: {
+ a: String,
+ b: String
+ }
+ }
+ }
+ })
+
+ it('bind to no-root-element sub vm', () => {
+ bindSubVm(vm, subVm, {
+ attr: { a: 3, c: 4 },
+ style: { a: 2 },
+ events: { click: 'foo' }
+ })
+ expect(subVm.a).eql(3)
+ expect(subVm.c).is.undefined
+ expect(subVm._rootEl).is.undefined
+ })
+
+ it('bind props with external data', () => {
+ bindSubVm(vm, subVm, {
+ attr: { a: function () { return this.b } }
+ })
+ expect(subVm.a).eql(2)
+ })
+
+ it('bind styles to a sub vm with root element', () => {
+ subVm._rootEl = {
+ attr: {},
+ style: {},
+ event: []
+ }
+ const template = {
+ style: { aaa: 2, bbb: function () { return this.a } }
+ }
+ initElement(subVm._rootEl)
+ bindSubVm(vm, subVm, template)
+ bindSubVmAfterInitialized(vm, subVm, template)
+ expect(subVm._rootEl.style.aaa).eql(2)
+ expect(subVm._rootEl.style.bbb).eql(1)
+ vm.a = 3
+ expect(subVm._rootEl.style.bbb).eql(3)
+ })
+
+ it('bind simply classlist to a sub vm with root element', () => {
+ subVm._rootEl = {
+ attr: {},
+ style: {},
+ event: []
+ }
+ const template = {
+ classList: ['class-style1']
+ }
+ initElement(subVm._rootEl)
+ bindSubVm(vm, subVm, template)
+ bindSubVmAfterInitialized(vm, subVm, template)
+ expect(subVm._rootEl.classStyle.aaa).eql(1)
+ expect(subVm._rootEl.classStyle.bbb).eql(2)
+ })
+
+ it('bind classlist to a sub vm with root element', () => {
+ subVm._rootEl = {
+ attr: {},
+ style: {},
+ event: []
+ }
+ const template = {
+ classList: function () {
+ return [this.c]
+ }
+ }
+ initElement(subVm._rootEl)
+ bindSubVm(vm, subVm, template)
+ bindSubVmAfterInitialized(vm, subVm, template)
+ expect(subVm._rootEl.classStyle.aaa).eql(1)
+ expect(subVm._rootEl.classStyle.bbb).eql(2)
+ vm.c = 'class-style2'
+ expect(subVm._rootEl.classStyle.aaa).eql(2)
+ expect(subVm._rootEl.classStyle.bbb).to.be.undefined
+ expect(subVm._rootEl.classStyle.ccc).eql(3)
+ })
+
+ it('bind events to a sub vm with root element', () => {
+ subVm._rootEl = {
+ attr: {},
+ style: {},
+ event: {}
+ }
+ const template = {
+ events: { click: 'foo' }
+ }
+ initElement(subVm._rootEl)
+ bindSubVm(vm, subVm, template)
+ bindSubVmAfterInitialized(vm, subVm, template)
+ // expect(subVm._rootEl.event.click).a('function')
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/vm/dom-helper.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/vm/dom-helper.js b/test/js-framework/unit/default/vm/dom-helper.js
new file mode 100644
index 0000000..d0e5a54
--- /dev/null
+++ b/test/js-framework/unit/default/vm/dom-helper.js
@@ -0,0 +1,405 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import {
+ createElement,
+ createBlock,
+ createBody,
+ attachTarget,
+ moveTarget,
+ removeTarget
+} from '../../../../../runtime/frameworks/legacy/vm/dom-helper'
+import { Document } from '../../../../../runtime/vdom'
+import Listener from '../../../../../runtime/bridge/Listener'
+
+describe('help create body', () => {
+ let vm
+
+ beforeEach(() => {
+ vm = {
+ _app: { doc: new Document('foo', null, null, Listener) }
+ }
+ })
+
+ afterEach(() => {
+ vm._app.doc.destroy()
+ vm = null
+ })
+
+ it('create body with type', () => {
+ const result = createBody(vm, 'bar')
+ expect(result).is.an.object
+ expect(result.type).eql('bar')
+ expect(result.ref).eql('_root')
+ expect(result.docId).is.not.ok
+ })
+})
+
+describe('help create element', () => {
+ let vm
+
+ beforeEach(() => {
+ vm = {
+ _app: { doc: new Document('foo', null, null, Listener) }
+ }
+ })
+
+ afterEach(() => {
+ vm._app.doc.destroy()
+ vm = null
+ })
+
+ it('create element with type', () => {
+ const result = createElement(vm, 'bar')
+ expect(result).is.an.object
+ expect(result.type).eql('bar')
+ expect(result.docId).is.not.ok
+ })
+})
+
+describe('help create block', () => {
+ let vm
+
+ beforeEach(() => {
+ vm = {
+ _app: { doc: new Document('foo', null, null, Listener) }
+ }
+ })
+
+ afterEach(() => {
+ vm._app.doc.destroy()
+ vm = null
+ })
+
+ it('create block with element', () => {
+ const element = vm._app.doc.createElement('bar')
+ const result = createBlock(vm, element)
+ expect(result).is.an.object
+ expect(result.start).is.an.object
+ expect(result.end).is.an.object
+ expect(result.start.type).eql('comment')
+ expect(result.end.type).eql('comment')
+ expect(result.start.value).eql('start')
+ expect(result.end.value).eql('end')
+ expect(result.element).equal(element)
+ expect(result.element.children).eql([result.start, result.end])
+ })
+})
+
+describe('help attach target', () => {
+ let vm
+
+ beforeEach(() => {
+ vm = {
+ _app: { doc: new Document('foo', null, null, Listener) }
+ }
+ })
+
+ afterEach(() => {
+ vm._app.doc.destroy()
+ vm = null
+ })
+
+ it('attach body to documentElement', () => {
+ const oriCallnative = global.callNative
+ global.callNative = function () {}
+ const target = createBody(vm, 'bar')
+ const dest = vm._app.doc.documentElement
+ attachTarget(vm, target, dest)
+ expect(dest.children).eql([target])
+ global.callNative = oriCallnative
+ })
+
+ it('attach element to body', () => {
+ const target = createElement(vm, 'bar')
+ const dest = createBody(vm, 'baz')
+ attachTarget(vm, target, dest)
+ expect(dest.children).eql([target])
+ })
+
+ it('attach element to element', () => {
+ const target = createElement(vm, 'bar')
+ const dest = createElement(vm, 'baz')
+ attachTarget(vm, target, dest)
+ expect(dest.children).eql([target])
+ })
+
+ it('attach block to element', () => {
+ const parent = createElement(vm, 'bar')
+ const target = createBlock(vm, parent)
+ const dest = createElement(vm, 'baz')
+ attachTarget(vm, target, dest)
+ // block can't attach to another element
+ expect(dest.children).eql([])
+ expect(parent.children).eql([target.start, target.end])
+ })
+
+ it('attach element to block', () => {
+ const target = createElement(vm, 'bar')
+ const parent = createElement(vm, 'baz')
+ const dest = createBlock(vm, parent)
+ attachTarget(vm, target, dest)
+ expect(parent.children).eql([dest.start, target, dest.end])
+ })
+
+ it('attach block to block', () => {
+ const element = createElement(vm, 'bar')
+ const target = createBlock(vm, element)
+ const parent = createElement(vm, 'baz')
+ const dest = createBlock(vm, parent)
+ attachTarget(vm, target, dest)
+ // block can't attach to another element
+ expect(parent.children).eql([dest.start, dest.end])
+ expect(element.children).eql([target.start, target.end])
+ })
+
+ it('attach element to block with an update mark', () => {
+ const target = createElement(vm, 'bar')
+ const parent = createElement(vm, 'baz')
+ const dest = createBlock(vm, parent)
+ const mark = createElement(vm, 'qux')
+
+ attachTarget(vm, target, dest)
+ attachTarget(vm, mark, dest)
+ expect(parent.children).eql([dest.start, target, mark, dest.end])
+
+ dest.updateMark = mark
+ attachTarget(vm, target, dest)
+ expect(parent.children).eql([dest.start, mark, target, dest.end])
+ expect(dest.updateMark).eql(target)
+ })
+
+ it('attach block to block with an update mark', () => {
+ const element = createElement(vm, 'bar')
+ const target = createBlock(vm, element)
+ const parent = createElement(vm, 'baz')
+ const dest = createBlock(vm, parent)
+ const mark = createElement(vm, 'qux')
+
+ attachTarget(vm, target, dest)
+ attachTarget(vm, mark, dest)
+ // block can't attach to another element
+ expect(parent.children).eql([dest.start, mark, dest.end])
+ expect(element.children).eql([target.start, target.end])
+
+ dest.updateMark = mark
+ attachTarget(vm, target, dest)
+ // block can't attach to another element
+ expect(parent.children).eql([dest.start, mark, dest.end])
+ expect(element.children).eql([target.start, target.end])
+ })
+})
+
+describe('help move target', () => {
+ let vm, parent, dest, target1, block1, target2, block2, target3, block3
+
+ beforeEach(() => {
+ vm = {
+ _app: { doc: new Document('foo', null, null, Listener) }
+ }
+ parent = createElement(vm, 'r')
+ dest = createBlock(vm, parent)
+ target1 = createElement(vm, 't1')
+ attachTarget(vm, target1, dest)
+ block1 = createBlock(vm, dest)
+ target2 = createElement(vm, 't2')
+ attachTarget(vm, target2, dest)
+ block2 = createBlock(vm, dest)
+ target3 = createElement(vm, 't3')
+ attachTarget(vm, target3, block2)
+ block3 = createBlock(vm, block2)
+ })
+
+ afterEach(() => {
+ vm._app.doc.destroy()
+ vm = null
+ })
+
+ it('move an element to an element mark', () => {
+ /* eslint-disable indent */
+ expect(parent.children).eql([
+ dest.start,
+ target1, block1.start, block1.end,
+ target2, block2.start,
+ target3, block3.start, block3.end,
+ block2.end,
+ dest.end])
+ /* eslint-enable indent */
+
+ const mark = target2
+ dest.updateMark = mark
+
+ moveTarget(vm, target1, mark)
+
+ /* eslint-disable indent */
+ expect(parent.children).eql([
+ dest.start,
+ block1.start, block1.end,
+ target2, target1, block2.start,
+ target3, block3.start, block3.end,
+ block2.end,
+ dest.end])
+ /* eslint-enable indent */
+ })
+
+ it('move an element to a block mark', () => {
+ const mark = block2.end
+ dest.updateMark = mark
+
+ moveTarget(vm, target1, mark)
+
+ /* eslint-disable indent */
+ expect(parent.children).eql([
+ dest.start,
+ block1.start, block1.end,
+ target2, block2.start,
+ target3, block3.start, block3.end,
+ block2.end, target1,
+ dest.end])
+ /* eslint-enable indent */
+ })
+
+ it('move a block to an element mark', () => {
+ const mark = target2
+ dest.updateMark = mark
+
+ moveTarget(vm, block1, mark)
+
+ /* eslint-disable indent */
+ expect(parent.children).eql([
+ dest.start,
+ target1,
+ target2, block1.start, block1.end,
+ block2.start,
+ target3, block3.start, block3.end,
+ block2.end,
+ dest.end])
+ /* eslint-enable indent */
+ })
+
+ it('move a block to a block mark', () => {
+ const mark = block2.end
+ dest.updateMark = mark
+
+ moveTarget(vm, block1, mark)
+
+ /* eslint-disable indent */
+ expect(parent.children).eql([
+ dest.start,
+ target1,
+ target2,
+ block2.start,
+ target3, block3.start, block3.end,
+ block2.end, block1.start, block1.end,
+ dest.end])
+ /* eslint-enable indent */
+ })
+
+ it('move a whole block to a block mark', () => {
+ const mark = block1.end
+ dest.updateMark = mark
+
+ moveTarget(vm, block2, mark)
+
+ /* eslint-disable indent */
+ expect(parent.children).eql([
+ dest.start,
+ target1, block1.start, block1.end,
+ block2.start,
+ target3, block3.start, block3.end,
+ block2.end,
+ target2,
+ dest.end])
+ /* eslint-enable indent */
+ })
+})
+
+describe('help remove target', () => {
+ let vm
+
+ beforeEach(() => {
+ vm = {
+ _app: { doc: new Document('foo', null, null, Listener) }
+ }
+ })
+
+ afterEach(() => {
+ vm._app.doc.destroy()
+ vm = null
+ })
+
+ it('remove body', () => {
+ const oriCallnative = global.callNative
+ global.callNative = function () {}
+ const parent = vm._app.doc.documentElement
+ const element = createBody(vm, 'baz')
+ parent.appendChild(element)
+ expect(parent.children).eql([element])
+ removeTarget(vm, element)
+ expect(parent.children).eql([])
+ global.callNative = oriCallnative
+ })
+
+ it('remove element', () => {
+ const parent = createElement(vm, 'bar')
+ const element = createElement(vm, 'baz')
+ parent.appendChild(element)
+ expect(parent.children).eql([element])
+ removeTarget(vm, element)
+ expect(parent.children).eql([])
+ })
+
+ it('remove block', () => {
+ const element = createElement(vm, 'baz')
+ const prevElement = createElement(vm, 'prev')
+ const nextElement = createElement(vm, 'next')
+ const parent = createElement(vm, 'bar')
+ attachTarget(vm, prevElement, parent)
+ const block = createBlock(vm, parent)
+ attachTarget(vm, element, block)
+ attachTarget(vm, nextElement, parent)
+
+ expect(parent.children).eql([
+ prevElement, block.start, element, block.end, nextElement])
+
+ removeTarget(vm, block)
+ expect(parent.children).eql([
+ prevElement, nextElement])
+ })
+
+ it('remove block but preserved itself', () => {
+ const element = createElement(vm, 'baz')
+ const prevElement = createElement(vm, 'prev')
+ const nextElement = createElement(vm, 'next')
+ const parent = createElement(vm, 'bar')
+ attachTarget(vm, prevElement, parent)
+ const block = createBlock(vm, parent)
+ attachTarget(vm, element, block)
+ attachTarget(vm, nextElement, parent)
+
+ expect(parent.children).eql([
+ prevElement, block.start, element, block.end, nextElement])
+
+ removeTarget(vm, block, true)
+ expect(parent.children).eql([
+ prevElement, block.start, block.end, nextElement])
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/vm/events.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/vm/events.js b/test/js-framework/unit/default/vm/events.js
new file mode 100644
index 0000000..b43b016
--- /dev/null
+++ b/test/js-framework/unit/default/vm/events.js
@@ -0,0 +1,416 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import Vm from '../../../../../runtime/frameworks/legacy/vm'
+import { Document } from '../../../../../runtime/vdom'
+
+describe('bind and fire events', () => {
+ let doc, customComponentMap, spy
+
+ function checkReady (vm, handler) {
+ /* istanbul ignore else */
+ if (vm._ready) {
+ handler()
+ }
+ else {
+ vm.$on('hook:ready', handler)
+ }
+ }
+
+ beforeEach(() => {
+ spy = sinon.spy()
+ doc = new Document('test', '', spy)
+ customComponentMap = {}
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ })
+
+ it('bind event and fire in a single dom', (done) => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ a: function () { return this.x }
+ },
+ events: { click: 'handleClick' }
+ },
+ data: function () {
+ return { x: 1 }
+ },
+ methods: {
+ handleClick: function () {
+ this.x = 2
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ checkReady(vm, function () {
+ expect(doc.body.event.click.handler).a('function')
+
+ const el = doc.body
+ expect(el.attr.a).eql(1)
+ expect(spy.args.length).eql(1)
+ expect(doc.listener.updates.length).eql(0)
+
+ el.event.click.handler({ xxx: 1 })
+ expect(el.attr.a).eql(2)
+ expect(spy.args.length).eql(2)
+ expect(spy.args[1][0]).eql([
+ { module: 'dom', method: 'updateAttrs', args: [el.ref, { a: 2 }] }
+ ])
+
+ done()
+ })
+ })
+
+ it('emit, broadcast and dispatch vm events', (done) => {
+ customComponentMap.foo = {
+ template: {
+ type: 'aaa',
+ children: [{ type: 'bar', component: true }]
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'bbb'
+ }
+ }
+
+ const app = { doc, customComponentMap }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ checkReady(vm, function () {
+ doc.close()
+
+ expect(vm._childrenVms.length).eql(1)
+
+ const subVm = vm._childrenVms[0]
+ expect(vm._type).eql('foo')
+ expect(subVm._type).eql('bar')
+
+ const spyA = sinon.spy()
+ const spyB = sinon.spy()
+
+ vm.$on('customTypeA', spyA)
+ subVm.$on('customTypeA', spyB)
+
+ let detail = { aaa: 111 }
+ vm.$emit('customTypeA', detail)
+ expect(spyA.args.length).eql(1)
+ expect(spyB.args.length).eql(0)
+
+ detail = { aaa: 111 }
+ subVm.$emit('customTypeA', detail)
+ expect(spyA.args.length).eql(1)
+ expect(spyB.args.length).eql(1)
+
+ detail = { aaa: 111 }
+ vm.$broadcast('customTypeA', detail)
+ expect(spyA.args.length).eql(2)
+ expect(spyB.args.length).eql(2)
+
+ detail = { aaa: 111 }
+ subVm.$broadcast('customTypeA', detail)
+ expect(spyA.args.length).eql(2)
+ expect(spyB.args.length).eql(3)
+
+ detail = { aaa: 111 }
+ vm.$dispatch('customTypeA', detail)
+ expect(spyA.args.length).eql(3)
+ expect(spyB.args.length).eql(3)
+
+ detail = { aaa: 111 }
+ subVm.$dispatch('customTypeA', detail)
+ expect(spyA.args.length).eql(4)
+ expect(spyB.args.length).eql(4)
+
+ vm.$off('customTypeA', spyA)
+ subVm.$off('customTypeA')
+
+ detail = { aaa: 111 }
+ vm.$emit('customTypeA', detail)
+ detail = { aaa: 111 }
+ subVm.$emit('customTypeA', detail)
+ detail = { aaa: 111 }
+ vm.$broadcast('customTypeA', detail)
+ detail = { aaa: 111 }
+ subVm.$broadcast('customTypeA', detail)
+ detail = { aaa: 111 }
+ vm.$dispatch('customTypeA', detail)
+ detail = { aaa: 111 }
+ subVm.$dispatch('customTypeA', detail)
+
+ expect(spyA.args.length).eql(4)
+ expect(spyB.args.length).eql(4)
+
+ const spyAA = function (e) {
+ e.stop()
+ spyA()
+ }
+ const spyBB = function (e) {
+ e.stop()
+ spyB()
+ }
+
+ vm.$on('customTypeA', spyAA)
+ subVm.$on('customTypeA', spyBB)
+ vm.$off()
+ vm.$off('unknownTypeA', spyA)
+
+ detail = { aaa: 111 }
+ vm.$emit('customTypeA', detail)
+ expect(spyA.args.length).eql(5)
+ expect(spyB.args.length).eql(4)
+ detail = { aaa: 111 }
+ subVm.$emit('customTypeA', detail)
+ expect(spyA.args.length).eql(5)
+ expect(spyB.args.length).eql(5)
+ detail = { aaa: 111 }
+ vm.$broadcast('customTypeA', detail)
+ expect(spyA.args.length).eql(6)
+ expect(spyB.args.length).eql(5)
+ detail = { aaa: 111 }
+ subVm.$broadcast('customTypeA', detail)
+ expect(spyA.args.length).eql(6)
+ expect(spyB.args.length).eql(6)
+ detail = { aaa: 111 }
+ vm.$dispatch('customTypeA', detail)
+ expect(spyA.args.length).eql(7)
+ expect(spyB.args.length).eql(6)
+ detail = { aaa: 111 }
+ subVm.$dispatch('customTypeA', detail)
+ expect(spyA.args.length).eql(7)
+ expect(spyB.args.length).eql(7)
+
+ done()
+ })
+ })
+
+ it('broadcast for repeat vms', (done) => {
+ const vmSpy = sinon.spy()
+ const subVmSpy = sinon.spy()
+
+ customComponentMap.foo = {
+ data: function () {
+ return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] }
+ },
+ template: {
+ type: 'container',
+ children: [{
+ type: 'bar', component: true,
+ repeat: function () { return this.list }
+ }]
+ },
+ events: {
+ customTypeA: function (e) {
+ vmSpy(this, e)
+ }
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'aaa'
+ },
+ events: {
+ customTypeA: function (e) {
+ subVmSpy(this, e)
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ checkReady(vm, function () {
+ doc.close()
+ expect(vm._childrenVms.length).eql(3)
+
+ let detail = { aaa: 111 }
+ vm.$emit('customTypeA', detail)
+ expect(vmSpy.args.length).eql(1)
+ expect(subVmSpy.args.length).eql(0)
+ expect(vmSpy.args[0][0]).equal(vm)
+ expect(vmSpy.args[0][1]).is.an.object
+ expect(vmSpy.args[0][1].detail).equal(detail)
+
+ detail = { aaa: 111 }
+ vm.$broadcast('customTypeA', detail)
+ expect(vmSpy.args.length).eql(2)
+ expect(subVmSpy.args.length).eql(3)
+ expect(vmSpy.args[1][0]).equal(vm)
+ expect(vmSpy.args[1][1]).is.an.object
+ expect(vmSpy.args[1][1].detail).equal(detail)
+ expect(subVmSpy.args[1][0]).equal(vm._childrenVms[1])
+ expect(subVmSpy.args[1][1]).is.an.object
+ expect(subVmSpy.args[1][1].detail).equal(detail)
+
+ done()
+ })
+ })
+
+ it('dispatch from repeat vms', (done) => {
+ const vmSpy = sinon.spy()
+ const subVmSpy = sinon.spy()
+
+ customComponentMap.foo = {
+ data: function () {
+ return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] }
+ },
+ template: {
+ type: 'container',
+ children: [{
+ type: 'bar', component: true,
+ repeat: function () { return this.list }
+ }]
+ },
+ events: {
+ customTypeA: function (e) {
+ vmSpy(this, e)
+ }
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'aaa'
+ },
+ events: {
+ customTypeA: function (e) {
+ subVmSpy(this, e)
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ checkReady(vm, function () {
+ doc.close()
+ expect(vm._childrenVms.length).eql(3)
+
+ let detail = { aaa: 111 }
+ const subVm = vm._childrenVms[1]
+ subVm.$emit('customTypeA', detail)
+ expect(vmSpy.args.length).eql(0)
+ expect(subVmSpy.args.length).eql(1)
+ expect(subVmSpy.args[0][0]).equal(subVm)
+ expect(subVmSpy.args[0][1]).is.an.object
+ expect(subVmSpy.args[0][1].detail).equal(detail)
+
+ detail = { aaa: 111 }
+ subVm.$dispatch('customTypeA', detail)
+ expect(vmSpy.args.length).eql(1)
+ expect(subVmSpy.args.length).eql(2)
+ expect(vmSpy.args[0][0]).equal(vm)
+ expect(vmSpy.args[0][1]).is.an.object
+ expect(vmSpy.args[0][1].detail).equal(detail)
+ expect(subVmSpy.args[1][0]).equal(subVm)
+ expect(subVmSpy.args[1][1]).is.an.object
+ expect(subVmSpy.args[1][1].detail).equal(detail)
+
+ done()
+ })
+ })
+
+ it('lifecycel events', (done) => {
+ const vmSpy = sinon.spy()
+
+ customComponentMap.foo = {
+ template: {
+ type: 'aaa',
+ children: [{ type: 'bar', component: true }]
+ },
+ data: function () {
+ return {
+ x: 1
+ }
+ },
+ init: function (e) {
+ vmSpy(this, e)
+ expect(this._data).is.not.ok
+ expect(this.x).is.not.ok
+ expect(this._parentEl).is.not.ok
+ },
+ created: function (e) {
+ vmSpy(this, e)
+ expect(this._data).is.ok
+ expect(this.x).is.ok
+ expect(this._parentEl).is.not.ok
+ },
+ ready: function (e) {
+ vmSpy(this, e)
+ expect(this._data).is.ok
+ expect(this.x).is.ok
+ expect(this._parentEl).is.ok
+ expect(this._parentEl.children.length).eql(1)
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'bbb'
+ },
+ created: function (e) {
+ vmSpy(this, e)
+ }
+ }
+
+ const app = { doc, customComponentMap }
+ const evSpy = sinon.spy()
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, null,
+ {
+ 'hook:init': () => evSpy('hook:init'),
+ 'hook:created': () => evSpy('hook:created'),
+ 'hook:ready': () => evSpy('hook:ready')
+ }
+ )
+
+ checkReady(vm, function () {
+ doc.close()
+
+ expect(vmSpy.args.length).eql(4)
+
+ const subVm = vm._childrenVms[0]
+ const calls = vmSpy.args.map(args => [args[0], args[1].type])
+ expect(calls).eql([
+ [vm, 'hook:init'],
+ [vm, 'hook:created'],
+ [subVm, 'hook:created'],
+ [vm, 'hook:ready']
+ ])
+
+ expect(evSpy.callCount).to.be.equal(3)
+ expect(evSpy.args).to.deep.equal([
+ ['hook:init'],
+ ['hook:created'],
+ ['hook:ready']
+ ])
+
+ done()
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/vm/vm.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/vm/vm.js b/test/js-framework/unit/default/vm/vm.js
new file mode 100644
index 0000000..761c913
--- /dev/null
+++ b/test/js-framework/unit/default/vm/vm.js
@@ -0,0 +1,1975 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import Vm from '../../../../../runtime/frameworks/legacy/vm'
+import { Document } from '../../../../../runtime/vdom'
+import { init as resetTaskHandler } from '../../../../../runtime/bridge/TaskCenter'
+import Differ from '../../../../../runtime/frameworks/legacy/app/differ'
+
+const oriCallNative = global.callNative
+
+describe('generate virtual dom for a single vm', () => {
+ const spy = sinon.spy()
+ const spy1 = sinon.spy()
+ let doc
+ let customComponentMap
+ let differ
+
+ beforeEach(() => {
+ differ = new Differ('test')
+ doc = new Document('test', '', function (actions) {
+ actions.forEach((action) => {
+ spy.apply(null, ['test', action.method].concat(action.args))
+ })
+ })
+ customComponentMap = {}
+ })
+
+ afterEach(() => {
+ spy.reset()
+ spy1.reset()
+ doc.destroy()
+ })
+
+ it('$watch', () => {
+ const data = {
+ a: {
+ b: 1
+ }
+ }
+
+ customComponentMap.foo = {
+ template: {
+ type: 'container'
+ },
+ data: data
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(doc.body).is.an.object
+
+ vm.$watch(function () {
+ return this.a.b
+ }, (value) => {
+ expect(value).eql(2)
+ })
+
+ data.a.b = 2
+ })
+
+ it('vm.data is not a object', () => {
+ const data = 'hello'
+
+ customComponentMap.foo = {
+ template: {
+ type: 'container'
+ },
+ data: data
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(doc.body).is.an.object
+ })
+
+ it('no param parentVm', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container'
+ }
+ }
+
+ const vm = new Vm('foo', customComponentMap.foo, null)
+
+ expect(vm._app).is.an.object
+ expect(doc.body).is.an.object
+ })
+
+ it('no param options', () => {
+ const app = {}
+ const vm = new Vm('foo', null, { _app: app })
+
+ expect(vm._app).is.an.object
+ expect(doc.body).is.an.object
+ })
+
+ it('old method.ready', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container'
+ },
+ methods: {
+ ready: spy1
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(doc.body).is.an.object
+ expect(doc.body.type).eql('container')
+ expect(spy1).callCount(1)
+ })
+
+ it('generate an static element ', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ a: 1,
+ b: 2,
+ static: ''
+ },
+ style: {
+ c: 3,
+ d: 4
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm._static).eql(true)
+ expect(doc.body).is.an.object
+ expect(doc.body.type).eql('container')
+ expect(doc.body.attr).eql({ a: 1, b: 2, static: '' })
+ expect(doc.body.style).eql({ c: 3, d: 4 })
+ expect(doc.body.children).is.an.array
+ expect(doc.body.children.length).eql(0)
+ })
+
+ it('generate an single element', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ a: 1,
+ b: 2
+ },
+ style: {
+ c: 3,
+ d: 4
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(doc.body).is.an.object
+ expect(doc.body.type).eql('container')
+ expect(doc.body.attr).eql({ a: 1, b: 2 })
+ expect(doc.body.style).eql({ c: 3, d: 4 })
+ expect(doc.body.children).is.an.array
+ expect(doc.body.children.length).eql(0)
+ })
+
+ it('generate an element tree', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
+ children: [
+ { type: 'image', attr: { src: '<some image url>' }},
+ { type: 'text', attr: { value: '<some text content>' }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.attr).eql({ a: 1, b: 2 })
+ expect(el.style).eql({ c: 3, d: 4 })
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(2)
+
+ const image = el.children[0]
+ const text = el.children[1]
+ expect(image.type).eql('image')
+ expect(image.attr).eql({ src: '<some image url>' })
+ expect(text.type).eql('text')
+ expect(text.attr).eql({ value: '<some text content>' })
+ })
+
+ it('generate an element tree with component options', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'cell',
+ children: [
+ { type: 'text', attr: { value: '<some text content>' }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(spy.firstCall.args[0]).to.be.equal('test')
+ expect(spy.firstCall.args[1]).to.be.equal('createBody')
+ expect(spy.firstCall.args[2]).to.deep.equal({
+ ref: '_root',
+ type: 'cell',
+ attr: {
+ append: 'tree'
+ },
+ children: [{
+ ref: spy.firstCall.args[2].children[0].ref,
+ type: 'text',
+ attr: {
+ value: '<some text content>'
+ },
+ style: {}
+ }],
+ style: {}
+ })
+
+ expect(vm._app).equal(app)
+ const el = doc.body
+ expect(el.type).eql('cell')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const text = el.children[0]
+ expect(text.type).eql('text')
+ expect(text.attr).eql({ value: '<some text content>' })
+ })
+
+ it('generate an element tree with data binding', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
+ children: [
+ { type: 'image', attr: { src: function () { return this.x } }},
+ { type: 'text', attr: { value: function () { return this.n } }},
+ { type: 'text', attr: { value: function () { return this.m } }}
+ ]
+ },
+ data: {
+ x: '<some image url>', y: '<some text content>'
+ },
+ computed: {
+ n: function () {
+ return this.y.toUpperCase()
+ },
+ m: {
+ get: function () {
+ return this.y.toUpperCase()
+ },
+ set: function (v) {
+ this.y = v
+ }
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.x).eql('<some image url>')
+ expect(vm.y).eql('<some text content>')
+ expect(vm.n).eql('<SOME TEXT CONTENT>')
+ expect(vm.m).eql('<SOME TEXT CONTENT>')
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.attr).eql({ a: 1, b: 2 })
+ expect(el.style).eql({ c: 3, d: 4 })
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(3)
+
+ const image = el.children[0]
+ const text = el.children[1]
+ const text2 = el.children[2]
+ expect(image.type).eql('image')
+ expect(image.attr).eql({ src: '<some image url>' })
+ expect(text.type).eql('text')
+ expect(text.attr).eql({ value: '<SOME TEXT CONTENT>' })
+ expect(text2.type).eql('text')
+ expect(text2.attr).eql({ value: '<SOME TEXT CONTENT>' })
+
+ vm.x = '<some image url>'
+ differ.flush()
+ expect(el).equal(doc.body)
+ expect(image).equal(el.children[0])
+ expect(text).equal(el.children[1])
+ expect(text2).equal(el.children[2])
+
+ vm.x = 'other string value'
+ differ.flush()
+ expect(el).equal(doc.body)
+ expect(image).equal(el.children[0])
+ expect(image.attr).eql({ src: 'other string value' })
+
+ vm.y = 'other string value'
+ differ.flush()
+ expect(el).equal(doc.body)
+ expect(text).equal(el.children[1])
+ expect(text.attr).eql({ value: 'OTHER STRING VALUE' })
+ expect(text2).equal(el.children[2])
+ expect(text2.attr).eql({ value: 'OTHER STRING VALUE' })
+
+ vm.m = 'third string value'
+ differ.flush()
+ expect(vm.x).eql('other string value')
+ expect(vm.y).eql('third string value')
+ expect(vm.n).eql('THIRD STRING VALUE')
+ expect(vm.m).eql('THIRD STRING VALUE')
+ expect(el).equal(doc.body)
+ expect(text).equal(el.children[1])
+ expect(text.attr).eql({ value: 'THIRD STRING VALUE' })
+ expect(text2).equal(el.children[2])
+ expect(text2.attr).eql({ value: 'THIRD STRING VALUE' })
+ })
+
+ it('generate an element tree with shown', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'prev' },
+ {
+ shown: function () { return this.y },
+ type: 'image', attr: { src: function () { return this.x } }
+ },
+ { type: 'next' }
+ ]
+ },
+ data: {
+ x: '<some image url>', y: true
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.x).eql('<some image url>')
+ expect(vm.y).eql(true)
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(5)
+
+ const prev = el.children[0]
+ const starter = el.children[1]
+ const image = el.children[2]
+ const ender = el.children[3]
+ const next = el.children[4]
+ expect(prev.type).eql('prev')
+ expect(starter.type).eql('comment')
+ expect(ender.type).eql('comment')
+ expect(next.type).eql('next')
+ expect(image.type).eql('image')
+ expect(image.attr).eql({ src: '<some image url>' })
+
+ vm.y = false
+ differ.flush()
+
+ expect(el).equal(doc.body)
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(4)
+ expect(prev).equal(el.children[0])
+ expect(starter).equal(el.children[1])
+ expect(ender).equal(el.children[2])
+ expect(next).equal(el.children[3])
+
+ vm.y = true
+ differ.flush()
+
+ expect(el).equal(doc.body)
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(5)
+ expect(prev).equal(el.children[0])
+ expect(starter).equal(el.children[1])
+
+ const image2 = el.children[2]
+ expect(image2.type).eql('image')
+ expect(image2.attr).eql({ src: '<some image url>' })
+ expect(ender).equal(el.children[3])
+ expect(next).equal(el.children[4])
+ })
+
+ it('generate an element tree with repeat', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'prev' },
+ {
+ repeat: function () { return this.list },
+ type: 'image', attr: { src: function () { return this.x } }
+ },
+ { type: 'next' }
+ ]
+ },
+ data: {
+ x: '<some image url>',
+ list: [
+ { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.x).eql('<some image url>')
+ expect(vm.list).eql([
+ { uid: 1, x: 1, $index: 0 },
+ { uid: 2, x: 2, $index: 1 },
+ { uid: 3, $index: 2 }])
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(7)
+
+ const prev = el.children[0]
+ const starter = el.children[1]
+ const ender = el.children[5]
+ const next = el.children[6]
+ expect(prev.type).eql('prev')
+ expect(starter.type).eql('comment')
+ expect(ender.type).eql('comment')
+ expect(next.type).eql('next')
+
+ expect(el.children[2].type).eql('image')
+ expect(el.children[2].attr).eql({ src: 1 })
+ expect(el.children[3].type).eql('image')
+ expect(el.children[3].attr).eql({ src: 2 })
+ expect(el.children[4].type).eql('image')
+ expect(el.children[4].attr).eql({ src: '<some image url>' })
+
+ vm.list[1].x = 3
+ differ.flush()
+ expect(el.children.length).eql(7)
+ expect(el.children[2].attr).eql({ src: 1 })
+ expect(el.children[3].attr).eql({ src: 3 })
+ expect(el.children[4].attr).eql({ src: '<some image url>' })
+
+ vm.x = 'other string value'
+ differ.flush()
+ expect(el.children.length).eql(7)
+ expect(el.children[2].attr).eql({ src: 1 })
+ expect(el.children[3].attr).eql({ src: 3 })
+ expect(el.children[4].attr).eql({ src: 'other string value' })
+
+ vm.list.push({ uid: 4, x: 4 })
+ vm.list.push({ uid: 5 }, { uid: 6, x: 6 })
+
+ differ.flush()
+
+ expect(el.children.length).eql(10)
+ expect(el.children[2].attr).eql({ src: 1 })
+ expect(el.children[3].attr).eql({ src: 3 })
+ expect(el.children[4].attr).eql({ src: 'other string value' })
+ expect(el.children[5].attr).eql({ src: 4 })
+ expect(el.children[6].attr).eql({ src: 'other string value' })
+ expect(el.children[7].attr).eql({ src: 6 })
+
+ vm.list.splice(1, 2, { uid: 7, x: 7 })
+ differ.flush()
+
+ expect(el.children.length).eql(9)
+ expect(el.children[2].attr).eql({ src: 1 })
+ expect(el.children[3].attr).eql({ src: 7 })
+ expect(el.children[4].attr).eql({ src: 4 })
+ expect(el.children[5].attr).eql({ src: 'other string value' })
+ expect(el.children[6].attr).eql({ src: 6 })
+
+ vm.list.$set(0, { uid: 321, x: 32 })
+ vm.list.$set(10, { uid: 8889, x: 8888 })
+ differ.flush()
+
+ expect(el.children.length).eql(10)
+ expect(el.children[2].attr).eql({ src: 32 })
+ expect(el.children[7].attr).eql({ src: 8888 })
+
+ vm.list.unshift({ uid: 12345, x: 123456 })
+ differ.flush()
+
+ expect(el.children.length).eql(11)
+ expect(el.children[2].attr).eql({ src: 123456 })
+ })
+
+ it('generate an static element tree with shown and repeat', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ static: ''
+ },
+ children: [
+ { type: 'prev' },
+ {
+ shown: function () { return this.x % 2 === 0 },
+ repeat: function () { return this.list },
+ type: 'image', attr: { src: function () { return this.x } }
+ },
+ { type: 'next' }
+ ]
+ },
+ data: {
+ x: '<some image url>',
+ list: [
+ { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm._static).equal(true)
+ expect(vm.x).eql('<some image url>')
+ expect(vm.list).eql([
+ { uid: 1, x: 1, $index: 0 },
+ { uid: 2, x: 2, $index: 1 },
+ { uid: 3, $index: 2 }])
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(11)
+
+ const prev = el.children[0]
+ const next = el.children[10]
+ expect(prev.type).eql('prev')
+ expect(el.children[1].type).eql('comment')
+ expect(el.children[1].value).eql('start')
+ expect(el.children[9].type).eql('comment')
+ expect(el.children[9].value).eql('end')
+
+ expect(el.children[2].type).eql('comment')
+ expect(el.children[2].value).eql('start')
+ expect(el.children[3].type).eql('comment')
+ expect(el.children[3].value).eql('end')
+
+ expect(el.children[4].type).eql('comment')
+ expect(el.children[4].value).eql('start')
+ expect(el.children[5].type).eql('image')
+ expect(el.children[5].attr).eql({ src: 2 })
+ expect(el.children[6].type).eql('comment')
+ expect(el.children[6].value).eql('end')
+
+ expect(el.children[7].type).eql('comment')
+ expect(el.children[7].value).eql('start')
+ expect(el.children[8].type).eql('comment')
+ expect(el.children[8].value).eql('end')
+ expect(next.type).eql('next')
+
+ vm.list[0].x = 4
+ differ.flush()
+
+ expect(el.children.length).eql(11)
+ expect(el.children[5].type).eql('image')
+ expect(el.children[5].attr).eql({ src: 2 })
+ })
+
+ it('generate an element tree which root element with shown', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ shown: function () { return this.x % 2 === 0 }
+ },
+ data: {
+ x: 2
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.x).eql(2)
+ })
+
+ it('append tree', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ append: 'tree'
+ },
+ children: [
+ { type: 'a' },
+ { repeat: {}}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ })
+
+ it('repeat is not a function', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'a' },
+ { repeat: {}}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ })
+
+ it('repeat oldStyle with item which not a object', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'a' },
+ { repeat: function () { return [1, 2, 3] } }
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ })
+
+ it('classList length is zero', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ classList: []
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ })
+
+ it('classList is a function', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ classList: function () { return [] }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ })
+
+ it('generate an element tree which root element with repeat', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ repeat: function () { return this.list }
+ },
+ data: {
+ list: [
+ { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.list).eql([
+ { uid: 1, x: 1 },
+ { uid: 2, x: 2 },
+ { uid: 3 }
+ ])
+ })
+
+ it('generate an element tree with shown and repeat', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'prev' },
+ {
+ shown: function () { return this.x % 2 === 0 },
+ repeat: function () { return this.list },
+ type: 'image', attr: { src: function () { return this.x } }
+ },
+ { type: 'next' }
+ ]
+ },
+ data: {
+ x: '<some image url>',
+ list: [
+ { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.x).eql('<some image url>')
+ expect(vm.list).eql([
+ { uid: 1, x: 1, $index: 0 },
+ { uid: 2, x: 2, $index: 1 },
+ { uid: 3, $index: 2 }])
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(11)
+
+ const prev = el.children[0]
+ const next = el.children[10]
+ expect(prev.type).eql('prev')
+ expect(el.children[1].type).eql('comment')
+ expect(el.children[1].value).eql('start')
+ expect(el.children[9].type).eql('comment')
+ expect(el.children[9].value).eql('end')
+
+ expect(el.children[2].type).eql('comment')
+ expect(el.children[2].value).eql('start')
+ expect(el.children[3].type).eql('comment')
+ expect(el.children[3].value).eql('end')
+
+ expect(el.children[4].type).eql('comment')
+ expect(el.children[4].value).eql('start')
+ expect(el.children[5].type).eql('image')
+ expect(el.children[5].attr).eql({ src: 2 })
+ expect(el.children[6].type).eql('comment')
+ expect(el.children[6].value).eql('end')
+
+ expect(el.children[7].type).eql('comment')
+ expect(el.children[7].value).eql('start')
+ expect(el.children[8].type).eql('comment')
+ expect(el.children[8].value).eql('end')
+ expect(next.type).eql('next')
+
+ vm.list[0].x = 4
+ differ.flush()
+
+ expect(el.children.length).eql(12)
+ expect(el.children[3].type).eql('image')
+ expect(el.children[3].attr).eql({ src: 4 })
+ expect(el.children[6].type).eql('image')
+ expect(el.children[6].attr).eql({ src: 2 })
+ })
+
+ it('generate more than one group of elements with the same repeat data', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'begin' },
+ {
+ repeat: {
+ expression: function () { return this.list },
+ value: 'v1'
+ },
+ type: 'image', attr: { src: function () { return this.v1.x } }
+ },
+ { type: 'middle' },
+ {
+ repeat: {
+ expression: function () { return this.list },
+ value: 'v2'
+ },
+ type: 'text', attr: { value: function () { return this.v2.x } }
+ },
+ { type: 'end' }
+ ]
+ },
+ data: {
+ list: [
+ { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm.list).eql([
+ { uid: 1, x: 1 },
+ { uid: 2, x: 2 },
+ { uid: 3 }])
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+
+ // [begin, comment, image x 3, comment, middle, comment, text x 3, comment, end]
+ expect(el.children.length).eql(13)
+
+ expect(el.children[0].type).eql('begin')
+ expect(el.children[1].type).eql('comment')
+ expect(el.children[1].value).eql('start')
+ expect(el.children[2].type).eql('image')
+ expect(el.children[2].attr).eql({ src: 1 })
+ expect(el.children[3].type).eql('image')
+ expect(el.children[3].attr).eql({ src: 2 })
+ expect(el.children[4].type).eql('image')
+ expect(el.children[4].attr).eql({})
+ expect(el.children[5].type).eql('comment')
+ expect(el.children[5].value).eql('end')
+ expect(el.children[6].type).eql('middle')
+ expect(el.children[7].type).eql('comment')
+ expect(el.children[7].value).eql('start')
+ expect(el.children[8].type).eql('text')
+ expect(el.children[8].attr).eql({ value: 1 })
+ expect(el.children[9].type).eql('text')
+ expect(el.children[9].attr).eql({ value: 2 })
+ expect(el.children[10].type).eql('text')
+ expect(el.children[10].attr).eql({})
+ expect(el.children[11].type).eql('comment')
+ expect(el.children[11].value).eql('end')
+ expect(el.children[12].type).eql('end')
+
+ vm.list[0].x = 4
+ differ.flush()
+
+ expect(el.children.length).eql(13)
+ expect(el.children[2].attr).eql({ src: 4 })
+ expect(el.children[8].attr).eql({ value: 4 })
+
+ // [begin, comment, image x 4, comment, middle, comment, text x 4, comment, end]
+ vm.list.push({ uid: 10, x: 10 })
+ differ.flush()
+
+ expect(el.children.length).eql(15)
+ expect(el.children[5].attr).eql({ src: 10 })
+ expect(el.children[12].attr).eql({ value: 10 })
+
+ // [begin, comment, image x 2, comment, middle, comment, text x 2, comment, end]
+ vm.list = [
+ { uid: 100, x: 100 }, { uid: 1, x: 1 }
+ ]
+ differ.flush()
+
+ expect(el.children.length).eql(11)
+ expect(el.children[2].attr).eql({ src: 100 })
+ expect(el.children[3].attr).eql({ src: 1 })
+ expect(el.children[7].attr).eql({ value: 100 })
+ expect(el.children[8].attr).eql({ value: 1 })
+
+ vm.list[0].x = 4
+ differ.flush()
+
+ expect(el.children.length).eql(11)
+ expect(el.children[2].attr).eql({ src: 4 })
+ expect(el.children[3].attr).eql({ src: 1 })
+ expect(el.children[7].attr).eql({ value: 4 })
+ expect(el.children[8].attr).eql({ value: 1 })
+
+ vm.list[1].x = 5
+ differ.flush()
+
+ expect(el.children.length).eql(11)
+ expect(el.children[2].attr).eql({ src: 4 })
+ expect(el.children[3].attr).eql({ src: 5 })
+ expect(el.children[7].attr).eql({ value: 4 })
+ expect(el.children[8].attr).eql({ value: 5 })
+ })
+
+ it('generate an element with external data', () => {
+ customComponentMap.foo = {
+ data: () => {
+ return { a: 10, b: 20 }
+ },
+ template: {
+ type: 'container',
+ attr: {
+ x: function () { return this.a },
+ y: function () { return this.b }
+ }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, { a: 1000 })
+
+ expect(vm._app).equal(app)
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.attr).eql({ x: 1000, y: 20 })
+
+ vm.a = 100
+ vm.b = 200
+ differ.flush()
+
+ expect(el).equal(doc.body)
+ expect(el.attr).eql({ x: 100, y: 200 })
+ })
+})
+
+describe('generate virtual dom for sub vm', () => {
+ let doc
+ let customComponentMap
+ let differ
+
+ beforeEach(() => {
+ global.callNative = function () {}
+ resetTaskHandler()
+ doc = new Document('test', null, null)
+ customComponentMap = {}
+ differ = new Differ('test')
+ })
+
+ afterEach(() => {
+ doc.destroy()
+ global.callNative = oriCallNative
+ })
+
+ it('generate sub elements', () => {
+ customComponentMap.foo = {
+ data: function () {
+ return {
+ showbar1: false,
+ showbar2: false,
+ bar2list: [{
+ id: 'bar2-1'
+ }, {
+ id: 'bar2-2'
+ }]
+ }
+ },
+ template: {
+ type: 'div',
+ children: [
+ { type: 'bar', id: 'bar', component: true,
+ events: { click: 'handleClick' }
+ },
+ { type: 'bar1',
+ shown: function () { return this.showbar1 },
+ id: 'bar1', component: true
+ },
+ { type: 'bar2',
+ shown: function () { return this.showbar2 },
+ repeat: function () { return this.bar2list },
+ id: function () { return this.id },
+ component: true
+ }
+ ]
+ },
+ methods: {
+ handleClick: sinon.spy()
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'container',
+ children: [{ type: 'aaa' }, { type: 'bbb' }]
+ }
+ }
+ customComponentMap.bar1 = {
+ template: {
+ type: 'container',
+ children: [{ type: 'aaaa' }, { type: 'bbbb' }]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm._rootEl).to.deep.equal(vm._parentEl.children[0])
+
+ expect(vm._childrenVms.length).to.be.equal(1)
+ expect(vm._childrenVms[0]).to.deep.equal(vm._ids['bar'].vm)
+ expect(vm._childrenVms[0]._rootEl).to.deep.equal(vm._ids['bar'].el)
+
+ const el = doc.body
+ expect(el.type).eql('div')
+ expect(el.pureChildren).is.an.array
+ expect(el.pureChildren.length).eql(1)
+
+ const sub = el.children[0]
+ expect(sub.type).eql('container')
+ expect(sub.children).is.an.array
+ expect(sub.children.length).eql(2)
+ expect(sub.children[0].type).eql('aaa')
+ expect(sub.children[1].type).eql('bbb')
+ expect(sub.event.click).is.a.function
+
+ const spy = customComponentMap.foo.methods.handleClick
+ sub.event.click.handler(1, 2, 3)
+ expect(spy.args.length).eql(1)
+ expect(spy.args[0]).eql([1, 2, 3])
+
+ vm.showbar1 = true
+ differ.flush()
+
+ expect(vm._childrenVms.length).to.be.equal(2)
+ expect(vm._childrenVms[1]).to.deep.equal(vm._ids['bar1'].vm)
+ expect(vm._childrenVms[1]._rootEl).to.deep.equal(vm._ids['bar1'].el)
+
+ vm.showbar2 = true
+ differ.flush()
+
+ expect(vm._ids['bar2-1'].vm).to.be.not.undefined
+ expect(vm._ids['bar2-1'].el).to.be.not.undefined
+ expect(vm._ids['bar2-2'].vm).to.be.not.undefined
+ expect(vm._ids['bar2-2'].el).to.be.not.undefined
+ })
+
+ it('generate sub element with static', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ static: ''
+ },
+ children: [{ type: 'bar', component: true }]
+ }
+ }
+ customComponentMap.bar = {
+ replace: true,
+ template: {
+ type: 'container',
+ children: [{ type: 'aaa' }]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ expect(vm._static).eql(true)
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const aaa = el.children[0]
+ expect(aaa.type).eql('aaa')
+ expect(vm._childrenVms.length).to.be.equal(1)
+ expect(vm._childrenVms[0]._static).eql(true)
+ })
+
+ it('generate replaced sub element', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true }]
+ }
+ }
+ customComponentMap.bar = {
+ replace: true,
+ template: {
+ type: 'container',
+ children: [{ type: 'aaa' }]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const aaa = el.children[0]
+ expect(aaa.type).eql('aaa')
+ })
+
+ it('generate replaced sub elements', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true }]
+ }
+ }
+ customComponentMap.bar = {
+ replace: true,
+ template: {
+ type: 'container',
+ children: [{ type: 'aaa' }, { type: 'bbb' }]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(4)
+
+ expect(el.children[0].type).eql('comment')
+ const aaa = el.children[1]
+ expect(aaa.type).eql('aaa')
+ const bbb = el.children[2]
+ expect(bbb.type).eql('bbb')
+ expect(el.children[3].type).eql('comment')
+ })
+
+ it('generate sub elements with no props', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
+ }
+ }
+ customComponentMap.bar = {
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const sub = el.children[0]
+ const aaa = sub.children[0]
+ expect(aaa.type).eql('aaa')
+ expect(aaa.attr).eql({ a: 10 })
+ const bbb = sub.children[1]
+ expect(bbb.type).eql('bbb')
+ expect(bbb.attr).eql({ b: 20 })
+ })
+
+ it('generate sub elements with array props', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
+ }
+ }
+ customComponentMap.bar = {
+ props: ['x'],
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const sub = el.children[0]
+ const aaa = sub.children[0]
+ expect(aaa.type).eql('aaa')
+ expect(aaa.attr).eql({ a: 10 })
+ const bbb = sub.children[1]
+ expect(bbb.type).eql('bbb')
+ expect(bbb.attr).eql({ b: 2 })
+ })
+
+ it('generate sub elements with props', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
+ }
+ }
+ customComponentMap.bar = {
+ props: { x: Number },
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const sub = el.children[0]
+ const aaa = sub.children[0]
+ expect(aaa.type).eql('aaa')
+ expect(aaa.attr).eql({ a: 10 })
+ const bbb = sub.children[1]
+ expect(bbb.type).eql('bbb')
+ expect(bbb.attr).eql({ b: 2 })
+ })
+
+ it('generate sub elements with data', () => {
+ customComponentMap.foo = {
+ data: () => {
+ return { a: 10, b: 20 }
+ },
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: {
+ x: function () { return this.a },
+ y: function () { return this.b }
+ }}]
+ }
+ }
+ customComponentMap.bar = {
+ props: { x: Number },
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(1)
+
+ const sub = el.children[0]
+ const aaa = sub.children[0]
+ expect(aaa.type).eql('aaa')
+ expect(aaa.attr).eql({ a: 10 })
+ const bbb = sub.children[1]
+ expect(bbb.type).eql('bbb')
+ expect(bbb.attr).eql({ b: 2 })
+
+ vm.a = 100
+ vm.b = 200
+ differ.flush()
+
+ expect(el).equal(doc.body)
+ expect(sub).equal(el.children[0])
+ expect(aaa).equal(sub.children[0])
+ expect(aaa.attr).eql({ a: 100 })
+ expect(bbb).equal(sub.children[1])
+ expect(bbb.attr).eql({ b: 2 })
+ })
+
+ it('generate sub elements with shown data', () => {
+ customComponentMap.foo = {
+ data: () => {
+ return { a: 10, b: 20 }
+ },
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: {
+ x: function () { return this.a },
+ y: function () { return this.b }
+ }, shown: function () { return this.a < 15 } }]
+ }
+ }
+ customComponentMap.bar = {
+ props: { x: Number },
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(3)
+
+ const sub = el.children[1]
+ const aaa = sub.children[0]
+ expect(aaa.type).eql('aaa')
+ expect(aaa.attr).eql({ a: 10 })
+ const bbb = sub.children[1]
+ expect(bbb.type).eql('bbb')
+ expect(bbb.attr).eql({ b: 2 })
+
+ vm.a = 20
+ differ.flush()
+
+ expect(el).equal(doc.body)
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(2)
+ })
+
+ it('generate sub elements with repeat data', () => {
+ customComponentMap.foo = {
+ data: () => {
+ return { list: [{ uid: 1, a: 1 }, { uid: 2, a: 2 }, { uid: 3, a: 3 }] }
+ },
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: {
+ x: function () { return this.a },
+ y: function () { return this.b }
+ }, repeat: function () { return this.list } }]
+ }
+ }
+ customComponentMap.bar = {
+ props: { x: Number },
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(vm._app).equal(app)
+
+ const el = doc.body
+ expect(el.type).eql('container')
+ expect(el.children).is.an.array
+ expect(el.children.length).eql(5)
+
+ const sub1 = el.children[1]
+ const aaa1 = sub1.children[0]
+ expect(aaa1.type).eql('aaa')
+ expect(aaa1.attr).eql({ a: 1 })
+ const bbb1 = sub1.children[1]
+ expect(bbb1.type).eql('bbb')
+ expect(bbb1.attr).eql({ b: 2 })
+
+ const sub2 = el.children[2]
+ const aaa2 = sub2.children[0]
+ expect(aaa2.type).eql('aaa')
+ expect(aaa2.attr).eql({ a: 2 })
+ const bbb2 = sub2.children[1]
+ expect(bbb2.type).eql('bbb')
+ expect(bbb2.attr).eql({ b: 2 })
+
+ const sub3 = el.children[3]
+ const aaa3 = sub3.children[0]
+ expect(aaa3.type).eql('aaa')
+ expect(aaa3.attr).eql({ a: 3 })
+ const bbb3 = sub3.children[1]
+ expect(bbb3.type).eql('bbb')
+ expect(bbb3.attr).eql({ b: 2 })
+ })
+
+ it('generate sub elements with content', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, children: [
+ { type: 'a' }, { type: 'b', attr: { bbb: function () { return this.x } }}
+ ] }]
+ },
+ data: () => {
+ return {
+ x: 1, y: 2
+ }
+ }
+ }
+ customComponentMap.bar = {
+ replace: true,
+ template: {
+ type: 'container',
+ children: [{ type: 'aaa' }, { type: 'content' }, { type: 'bbb' }]
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ const el = doc.body
+
+ expect(el.type).eql('container')
+ // [comment, aaa, comment, a, b, comment, bbb, comment]
+ expect(el.children.length).eql(8)
+ expect(el.children[0].type).eql('comment')
+ expect(el.children[2].type).eql('comment')
+ expect(el.children[5].type).eql('comment')
+ expect(el.children[7].type).eql('comment')
+
+ expect(el.pureChildren.length).eql(4)
+ expect(el.pureChildren[0].type).eql('aaa')
+ expect(el.pureChildren[1].type).eql('a')
+ expect(el.pureChildren[2].type).eql('b')
+ expect(el.pureChildren[2].attr).eql({ bbb: 1 })
+ expect(el.pureChildren[3].type).eql('bbb')
+
+ vm.x = 10
+ differ.flush()
+ expect(el.pureChildren[2].attr).eql({ bbb: 10 })
+ })
+
+ it('generate sub elements with dynamic types', (done) => {
+ customComponentMap.foo = {
+ data: {
+ x: 'bar',
+ y: 'hello'
+ },
+ template: {
+ type: 'div',
+ children: [{
+ type: function () { return this.x },
+ attr: { value: function () { return this.y } }
+ }]
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'text',
+ attr: { value: 'bar' }
+ }
+ }
+ customComponentMap.baz = {
+ data: function () {
+ return {
+ value: ''
+ }
+ },
+ template: {
+ type: 'text',
+ attr: { value: function () { return this.value + ' baz' } }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(doc.body.pureChildren[0].type).eql('text')
+ expect(doc.body.pureChildren[0].attr).eql({ value: 'bar' })
+
+ vm.x = 'baz'
+ expect(doc.body.pureChildren[0].type).eql('text')
+ expect(doc.body.pureChildren[0].attr).eql({ value: 'hello baz' })
+
+ vm.y = 'bye'
+ setTimeout(() => {
+ expect(doc.body.pureChildren[0].type).eql('text')
+ expect(doc.body.pureChildren[0].attr).eql({ value: 'bye baz' })
+
+ vm.x = 'text'
+ expect(doc.body.pureChildren[0].type).eql('text')
+ expect(doc.body.pureChildren[0].attr).eql({ value: 'bye' })
+
+ done()
+ })
+ })
+
+ it('generate sub elements with repeat dynamic types', (done) => {
+ customComponentMap.foo = {
+ data: {
+ list: [
+ { uid: 1, type: 'bar' },
+ { uid: 2, type: 'baz' },
+ { uid: 3, type: 'bar' },
+ { uid: 4, type: 'baz' }
+ ]
+ },
+ template: {
+ type: 'div',
+ children: [{
+ type: function () { return this.v.type },
+ repeat: {
+ expression: function () { return this.list },
+ trackBy: 'uid',
+ value: 'v'
+ }
+ }]
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'text',
+ attr: { value: 'bar' }
+ }
+ }
+ customComponentMap.baz = {
+ template: {
+ type: 'text',
+ attr: { value: 'baz' }
+ }
+ }
+
+ const app = { doc, customComponentMap, differ }
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(doc.body.pureChildren.length).eql(4)
+ expect(doc.body.pureChildren.map(el => el.attr.value)).eql(['bar', 'baz', 'bar', 'baz'])
+
+ vm.list.splice(2, 0, { uid: 5, type: 'baz' })
+ setTimeout(() => {
+ expect(doc.body.pureChildren.length).eql(5)
+ expect(doc.body.pureChildren.map(el => el.attr.value)).eql(['bar', 'baz', 'baz', 'bar', 'baz'])
+
+ done()
+ })
+ })
+})
+
+describe('generate dom actions', () => {
+ let doc, app, spy, customComponentMap, differ
+
+ beforeEach(() => {
+ spy = sinon.spy()
+ doc = new Document('foo', '', function (actions) {
+ actions.forEach((action) => {
+ spy.apply(null, ['bar', action.method].concat(action.args))
+ })
+ })
+ differ = new Differ('foo')
+ customComponentMap = {}
+ app = { doc, customComponentMap, differ }
+ })
+
+ afterEach(() => {
+ customComponentMap = {}
+ doc.destroy()
+ app = doc = spy = null
+ })
+
+ it('received create body and add element actions', () => {
+ const handler = sinon.spy()
+
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ attr: {
+ a: 1,
+ b: 2
+ },
+ style: {
+ c: 3,
+ d: 4
+ },
+ classList: ['classA'],
+ events: { click: 'handleClick' }
+ },
+ style: {
+ classA: { d: 5, e: 6 }
+ },
+ methods: {
+ handleClick: handler
+ }
+ }
+
+ new Vm('foo', customComponentMap.foo, { _app: app })
+ const el = {
+ ref: '_root',
+ type: 'container',
+ attr: { a: 1, b: 2 }, style: { c: 3, d: 4, e: 6 },
+ event: ['click']
+ }
+
+ expect(spy.args.length).eql(1)
+ expect(spy.args[0]).eql(['bar', 'createBody', el])
+ expect(doc.body.event.click).is.a.function
+ expect(handler.args.length).eql(0)
+ doc.body.fireEvent('click')
+ expect(handler.args.length).eql(0)
+ })
+
+ it('received actions for a template with if & repeat', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [
+ { type: 'prev' },
+ {
+ shown: function () { return this.x % 2 === 0 },
+ repeat: function () { return this.list },
+ trackBy: 'uid',
+ type: 'image', attr: { src: function () { return this.x } }
+ },
+ { type: 'next' }
+ ]
+ },
+ data: {
+ x: '<some image url>',
+ list: [
+ { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
+ ]
+ }
+ }
+
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ const pureChildren = doc.body.pureChildren
+ const el = { ref: '_root', type: 'container', attr: {}, style: {}}
+ const prev = {
+ ref: pureChildren[0].ref,
+ type: 'prev', attr: {}, style: {}
+ }
+ const img = {
+ ref: pureChildren[1].ref,
+ type: 'image', attr: { src: 2 }, style: {}
+ }
+ const next = {
+ ref: pureChildren[2].ref,
+ type: 'next', attr: {}, style: {}
+ }
+
+ expect(spy.args.length).eql(4)
+ expect(spy.args[0]).eql(['bar', 'createBody', el])
+ expect(spy.args[1]).eql(['bar', 'addElement', '_root', prev, -1])
+ expect(spy.args[2]).eql(['bar', 'addElement', '_root', img, 1])
+ expect(spy.args[3]).eql(['bar', 'addElement', '_root', next, -1])
+
+ vm.list[1].x = 3
+ differ.flush()
+
+ // [1, 3, undefined]
+ expect(spy.args.length).eql(5)
+ expect(spy.args[4]).eql(['bar', 'removeElement', img.ref])
+
+ vm.list[1].x = 12
+ differ.flush()
+
+ // [1, !12, undefined]
+ expect(spy.args.length).eql(6)
+ img.ref = pureChildren[1].ref
+ img.attr.src = 12
+ expect(spy.args[5]).eql(['bar', 'addElement', '_root', img, 1])
+
+ vm.x = 'other string value'
+ differ.flush()
+
+ expect(spy.args.length).eql(6)
+
+ vm.list.push({ uid: 4, x: 4 })
+ vm.list.push({ uid: 5 }, { uid: 6, x: 6 })
+ differ.flush()
+
+ // [1, !12, undefined, !4, undefined, !6]
+ const img2 = {
+ ref: pureChildren[2].ref,
+ type: 'image', attr: { src: 4 }, style: {}
+ }
+ const img3 = {
+ ref: pureChildren[3].ref,
+ type: 'image', attr: { src: 6 }, style: {}
+ }
+ expect(spy.args.length).eql(8)
+ expect(spy.args[6]).eql(['bar', 'addElement', '_root', img2, 2])
+ expect(spy.args[7]).eql(['bar', 'addElement', '_root', img3, 3])
+
+ const temp1 = vm.list[1] // 12
+ const temp2 = vm.list[5] // 6
+ // vm.list.splice(0, 6, temp2, {uid: 7, x: 7}, temp1)
+ vm.list = []
+ vm.list.push(temp2, { uid: 7, x: 7 }, temp1)
+ differ.flush()
+
+ // [!6, 7, !12]
+ expect(spy.args.length).eql(10)
+ expect(spy.args[8]).eql(['bar', 'removeElement', img2.ref])
+ expect(spy.args[9]).eql(['bar', 'moveElement', img3.ref, '_root', 1])
+ })
+
+ it('received actions for element updates', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
+ children: [
+ { type: 'image', attr: { src: function () { return this.x } }},
+ { type: 'text', attr: { value: function () { return this.y } }}
+ ]
+ },
+ data: {
+ x: '<some image url>', y: '<some text content>'
+ }
+ }
+
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+ const pureChildren = doc.body.pureChildren
+ const length = spy.args.length
+
+ vm.x = '<some image url>'
+ differ.flush()
+ expect(spy.args.length - length).eql(0)
+
+ vm.x = 'other string value'
+ differ.flush()
+ const change = [
+ 'bar', 'updateAttrs',
+ pureChildren[0].ref,
+ { src: 'other string value' }
+ ]
+ expect(spy.args.length - length).eql(1)
+ expect(spy.args[length]).eql(change)
+ })
+
+ it('received no action when no virtual dom different', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container', children: [
+ {
+ type: 'text',
+ shown: function () { return this.name.length > 3 },
+ attr: {
+ value: function () { return this.name.toUpperCase() }
+ }
+ }
+ ]
+ },
+ data: {
+ name: 'Mike'
+ }
+ }
+
+ const vm = new Vm('foo', customComponentMap.foo, { _app: app })
+
+ expect(doc.body.pureChildren.length).eql(1)
+ const text = doc.body.pureChildren[0]
+ expect(text.attr.value).eql('MIKE')
+
+ const initCalls = spy.args.length
+
+ vm.name = 'MiKe'
+ differ.flush()
+
+ expect(spy.args.length).eql(initCalls)
+
+ text.setAttr('value', 'MIKE')
+ differ.flush()
+
+ expect(spy.args.length).eql(initCalls)
+
+ text.setAttr('value', 'STEVE')
+ differ.flush()
+
+ expect(spy.args.length).eql(initCalls + 1)
+ expect(spy.args[initCalls]).eql([
+ 'bar', 'updateAttrs', text.ref, { value: 'STEVE' }])
+
+ vm.name = 'Steve'
+ differ.flush()
+
+ expect(spy.args.length).eql(initCalls + 1)
+ })
+
+ it('received actions for components', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true }]
+ }
+ }
+ customComponentMap.bar = {
+ template: {
+ type: 'container',
+ children: [{ type: 'aaa' }, { type: 'bbb' }]
+ }
+ }
+
+ new Vm('foo', customComponentMap.foo, { _app: app })
+ const pureChildren = doc.body.pureChildren
+ const first = pureChildren[0]
+ const second = first.pureChildren[0]
+ const third = first.pureChildren[1]
+ expect(spy.args.length).eql(4)
+ let el = { ref: '_root', type: 'container', attr: {}, style: {}}
+ expect(spy.args[0]).eql(['bar', 'createBody', el])
+ el = { ref: first.ref, type: 'container', attr: {}, style: {}}
+ expect(spy.args[1]).eql(['bar', 'addElement', '_root', el, -1])
+ el = { ref: second.ref, type: 'aaa', attr: {}, style: {}}
+ expect(spy.args[2]).eql(['bar', 'addElement', first.ref, el, -1])
+ el = { ref: third.ref, type: 'bbb', attr: {}, style: {}}
+ expect(spy.args[3]).eql(['bar', 'addElement', first.ref, el, -1])
+ })
+
+ it('received actions for complicated components', () => {
+ customComponentMap.foo = {
+ data: () => {
+ return { list: [{ uid: 1, a: 1 }, { uid: 2, a: 2 }, { uid: 3, a: 3 }] }
+ },
+ template: {
+ type: 'container',
+ children: [{ type: 'bar', component: true, attr: {
+ x: function () { return this.a },
+ y: function () { return this.b }
+ }, repeat: function () { return this.list } }]
+ }
+ }
+ customComponentMap.bar = {
+ props: { x: Number },
+ data: () => {
+ return { x: 1, y: 2 }
+ },
+ template: {
+ type: 'container',
+ children: [
+ { type: 'aaa', attr: { a: function () { return this.x } }},
+ { type: 'bbb', attr: { b: function () { return this.y } }}
+ ]
+ }
+ }
+
+ new Vm('foo', customComponentMap.foo, { _app: app })
+ const pureChildren = doc.body.pureChildren
+ const first = pureChildren[0]
+ const second = pureChildren[1]
+ const third = pureChildren[2]
+
+ /* eslint-disable indent */
+ // expect(spy.args[0]).eql([ 'bar', 'createBody', 'container' ])
+ expect(spy.args[0]).eql(['bar', 'createBody', { ref: '_root', type: 'container', attr: {}, style: {}}])
+ expect(spy.args[1]).eql(['bar', 'addElement', '_root', { ref: first.ref, type: 'container', attr: {}, style: {}}, 0])
+ expect(spy.args[2]).eql(['bar', 'addElement', first.ref, { ref: first.pureChildren[0].ref, type: 'aaa', attr: { a: 1 }, style: {}}, -1])
+ expect(spy.args[3]).eql(['bar', 'addElement', first.ref, { ref: first.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
+ expect(spy.args[4]).eql(['bar', 'addElement', '_root', { ref: second.ref, type: 'container', attr: {}, style: {}}, 1])
+ expect(spy.args[5]).eql(['bar', 'addElement', second.ref, { ref: second.pureChildren[0].ref, type: 'aaa', attr: { a: 2 }, style: {}}, -1])
+ expect(spy.args[6]).eql(['bar', 'addElement', second.ref, { ref: second.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
+ expect(spy.args[7]).eql(['bar', 'addElement', '_root', { ref: third.ref, type: 'container', attr: {}, style: {}}, 2])
+ expect(spy.args[8]).eql(['bar', 'addElement', third.ref, { ref: third.pureChildren[0].ref, type: 'aaa', attr: { a: 3 }, style: {}}, -1])
+ expect(spy.args[9]).eql(['bar', 'addElement', third.ref, { ref: third.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
+ /* eslint-enable indent */
+ })
+
+ it('received actions for add a tree element', () => {
+ customComponentMap.foo = {
+ template: {
+ type: 'r',
+ children: [
+ { type: 'a' }, { type: 'b', children: [
+ { type: 'd' }, { type: 'e', append: 'tree', children: [
+ { type: 'g' }, { type: 'h' }, { type: 'i' }
+ ] }, { type: 'f' }
+ ] }, { type: 'c' }
+ ]
+ }
+ }
+
+ new Vm('foo', customComponentMap.foo, { _app: app })
+ const pureChildren = doc.body.pureChildren
+
+ expect(spy.args.length).eql(7)
+ // body, r, r.a, r.b, r.b.d, r.b.e(tree), r.b.f, r.c
+
+ expect(spy.args[0][2].ref).eql('_root')
+ expect(spy.args[0][2].type).eql('r')
+
+ expect(spy.args[1][3].ref).eql(pureChildren[0].ref)
+ expect(spy.args[1][3].type).eql('a')
+ expect(spy.args[1][2]).eql('_root')
+ expect(spy.args[1][4]).eql(-1)
+
+ expect(spy.args[2][3].ref).eql(pureChildren[1].ref)
+ expect(spy.args[2][3].type).eql('b')
+ expect(spy.args[2][2]).eql('_root')
+ expect(spy.args[2][4]).eql(-1)
+
+ expect(spy.args[3][3].ref).eql(pureChildren[1].pureChildren[0].ref)
+ expect(spy.args[3][3].type).eql('d')
+ expect(spy.args[3][2]).eql(pureChildren[1].ref)
+ expect(spy.args[3][4]).eql(-1)
+
+ const tree = pureChildren[1].pureChildren[1]
+ expect(spy.args[4][3].ref).eql(tree.ref)
+ expect(spy.args[4][3].type).eql('e')
+ expect(spy.args[4][2]).eql(pureChildren[1].ref)
+ expect(spy.args[4][4]).eql(-1)
+ expect(spy.args[4][3].children).eql([
+ { ref: tree.pureChildren[0].ref, type: 'g', attr: {}, style: {}},
+ { ref: tree.pureChildren[1].ref, type: 'h', attr: {}, style: {}},
+ { ref: tree.pureChildren[2].ref, type: 'i', attr: {}, style: {}}])
+
+ expect(spy.args[5][3].ref).eql(pureChildren[1].pureChildren[2].ref)
+ expect(spy.args[5][3].type).eql('f')
+ expect(spy.args[5][2]).eql(pureChildren[1].ref)
+ expect(spy.args[5][4]).eql(-1)
+
+ expect(spy.args[6][3].ref).eql(pureChildren[2].ref)
+ expect(spy.args[6][3].type).eql('c')
+ expect(spy.args[6][2]).eql('_root')
+ expect(spy.args[6][4]).eql(-1)
+ })
+})
[08/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/vm/directive.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/vm/directive.js b/runtime/frameworks/legacy/vm/directive.js
new file mode 100644
index 0000000..77ccd9a
--- /dev/null
+++ b/runtime/frameworks/legacy/vm/directive.js
@@ -0,0 +1,377 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * Directive Parser
+ */
+
+import { bind, typof } from '../util/index'
+import Watcher from '../core/watcher'
+import config from '../config'
+
+const { nativeComponentMap } = config
+
+const SETTERS = {
+ attr: 'setAttr',
+ style: 'setStyle',
+ event: 'addEvent'
+}
+
+/**
+ * apply the native component's options(specified by template.type)
+ * to the template
+ */
+export function applyNaitveComponentOptions (template) {
+ const { type } = template
+ const options = nativeComponentMap[type]
+
+ if (typeof options === 'object') {
+ for (const key in options) {
+ if (template[key] == null) {
+ template[key] = options[key]
+ }
+ else if (typof(template[key]) === 'object' &&
+ typof(options[key]) === 'object') {
+ for (const subkey in options[key]) {
+ if (template[key][subkey] == null) {
+ template[key][subkey] = options[key][subkey]
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * bind all id, attr, classnames, style, events to an element
+ */
+export function bindElement (vm, el, template) {
+ setId(vm, el, template.id, vm)
+ setAttr(vm, el, template.attr)
+ setClass(vm, el, template.classList)
+ setStyle(vm, el, template.style)
+ bindEvents(vm, el, template.events)
+}
+
+/**
+ * bind all props to sub vm and bind all style, events to the root element
+ * of the sub vm if it doesn't have a replaced multi-node fragment
+ */
+export function bindSubVm (vm, subVm, template, repeatItem) {
+ subVm = subVm || {}
+ template = template || {}
+
+ const options = subVm._options || {}
+
+ // bind props
+ let props = options.props
+
+ if (Array.isArray(props)) {
+ props = props.reduce((result, value) => {
+ result[value] = true
+ return result
+ }, {})
+ }
+
+ mergeProps(repeatItem, props, vm, subVm)
+ mergeProps(template.attr, props, vm, subVm)
+}
+
+/**
+ * merge class and styles from vm to sub vm.
+ */
+export function bindSubVmAfterInitialized (vm, subVm, template, target = {}) {
+ mergeClassStyle(template.classList, vm, subVm)
+ mergeStyle(template.style, vm, subVm)
+
+ // bind subVm to the target element
+ if (target.children) {
+ target.children[target.children.length - 1]._vm = subVm
+ }
+ else {
+ target._vm = subVm
+ }
+}
+
+/**
+ * Bind props from vm to sub vm and watch their updates.
+ */
+function mergeProps (target, props, vm, subVm) {
+ if (!target) {
+ return
+ }
+ for (const key in target) {
+ if (!props || props[key]) {
+ const value = target[key]
+ if (typeof value === 'function') {
+ const returnValue = watch(vm, value, function (v) {
+ subVm[key] = v
+ })
+ subVm[key] = returnValue
+ }
+ else {
+ subVm[key] = value
+ }
+ }
+ }
+}
+
+/**
+ * Bind style from vm to sub vm and watch their updates.
+ */
+function mergeStyle (target, vm, subVm) {
+ for (const key in target) {
+ const value = target[key]
+ if (typeof value === 'function') {
+ const returnValue = watch(vm, value, function (v) {
+ if (subVm._rootEl) {
+ subVm._rootEl.setStyle(key, v)
+ }
+ })
+ subVm._rootEl.setStyle(key, returnValue)
+ }
+ else {
+ if (subVm._rootEl) {
+ subVm._rootEl.setStyle(key, value)
+ }
+ }
+ }
+}
+
+/**
+ * Bind class & style from vm to sub vm and watch their updates.
+ */
+function mergeClassStyle (target, vm, subVm) {
+ const css = vm._options && vm._options.style || {}
+
+ /* istanbul ignore if */
+ if (!subVm._rootEl) {
+ return
+ }
+
+ const className = '@originalRootEl'
+ css[className] = subVm._rootEl.classStyle
+
+ function addClassName (list, name) {
+ if (typof(list) === 'array') {
+ list.unshift(name)
+ }
+ }
+
+ if (typeof target === 'function') {
+ const value = watch(vm, target, v => {
+ addClassName(v, className)
+ setClassStyle(subVm._rootEl, css, v)
+ })
+ addClassName(value, className)
+ setClassStyle(subVm._rootEl, css, value)
+ }
+ else if (target != null) {
+ addClassName(target, className)
+ setClassStyle(subVm._rootEl, css, target)
+ }
+}
+
+/**
+ * bind id to an element
+ * each id is unique in a whole vm
+ */
+export function setId (vm, el, id, target) {
+ const map = Object.create(null)
+
+ Object.defineProperties(map, {
+ vm: {
+ value: target,
+ writable: false,
+ configurable: false
+ },
+ el: {
+ get: () => el || target._rootEl,
+ configurable: false
+ }
+ })
+
+ if (typeof id === 'function') {
+ const handler = id
+ id = handler.call(vm)
+ if (id || id === 0) {
+ vm._ids[id] = map
+ }
+ watch(vm, handler, (newId) => {
+ if (newId) {
+ vm._ids[newId] = map
+ }
+ })
+ }
+ else if (id && typeof id === 'string') {
+ vm._ids[id] = map
+ }
+}
+
+/**
+ * bind attr to an element
+ */
+function setAttr (vm, el, attr) {
+ bindDir(vm, el, 'attr', attr)
+}
+
+function setClassStyle (el, css, classList) {
+ if (typeof classList === 'string') {
+ classList = classList.split(/\s+/)
+ }
+ classList.forEach((name, i) => {
+ classList.splice(i, 1, ...name.split(/\s+/))
+ })
+ const classStyle = {}
+ const length = classList.length
+
+ for (let i = 0; i < length; i++) {
+ const style = css[classList[i]]
+ if (style) {
+ Object.keys(style).forEach((key) => {
+ classStyle[key] = style[key]
+ })
+ }
+ }
+ el.setClassStyle(classStyle)
+}
+
+/**
+ * bind classnames to an element
+ */
+function setClass (vm, el, classList) {
+ if (typeof classList !== 'function' && !Array.isArray(classList)) {
+ return
+ }
+ if (Array.isArray(classList) && !classList.length) {
+ el.setClassStyle({})
+ return
+ }
+
+ const style = vm._options && vm._options.style || {}
+ if (typeof classList === 'function') {
+ const value = watch(vm, classList, v => {
+ setClassStyle(el, style, v)
+ })
+ setClassStyle(el, style, value)
+ }
+ else {
+ setClassStyle(el, style, classList)
+ }
+}
+
+/**
+ * bind style to an element
+ */
+function setStyle (vm, el, style) {
+ bindDir(vm, el, 'style', style)
+}
+
+/**
+ * add an event type and handler to an element and generate a dom update
+ */
+function setEvent (vm, el, type, handler) {
+ el.addEvent(type, bind(handler, vm))
+}
+
+/**
+ * add all events of an element
+ */
+function bindEvents (vm, el, events) {
+ if (!events) {
+ return
+ }
+ const keys = Object.keys(events)
+ let i = keys.length
+ while (i--) {
+ const key = keys[i]
+ let handler = events[key]
+ if (typeof handler === 'string') {
+ handler = vm[handler]
+ /* istanbul ignore if */
+ if (!handler) {
+ console.warn(`[JS Framework] The event handler "${handler}" is not defined.`)
+ }
+ }
+ setEvent(vm, el, key, handler)
+ }
+}
+
+/**
+ * set a series of members as a kind of an element
+ * for example: style, attr, ...
+ * if the value is a function then bind the data changes
+ */
+function bindDir (vm, el, name, data) {
+ if (!data) {
+ return
+ }
+ const keys = Object.keys(data)
+ let i = keys.length
+ while (i--) {
+ const key = keys[i]
+ const value = data[key]
+ if (typeof value === 'function') {
+ bindKey(vm, el, name, key, value)
+ }
+ else {
+ el[SETTERS[name]](key, value)
+ }
+ }
+}
+
+/**
+ * bind data changes to a certain key to a name series in an element
+ */
+function bindKey (vm, el, name, key, calc) {
+ const methodName = SETTERS[name]
+ // watch the calc, and returns a value by calc.call()
+ const value = watch(vm, calc, (value) => {
+ function handler () {
+ el[methodName](key, value)
+ }
+ const differ = vm && vm._app && vm._app.differ
+ if (differ) {
+ differ.append('element', el.depth || 0, el.ref, handler)
+ }
+ else {
+ handler()
+ }
+ })
+
+ el[methodName](key, value)
+}
+
+/**
+ * watch a calc function and callback if the calc value changes
+ */
+export function watch (vm, calc, callback) {
+ if (vm._static) {
+ return calc.call(vm, vm)
+ }
+ const watcher = new Watcher(vm, calc, function (value, oldValue) {
+ /* istanbul ignore if */
+ if (typeof value !== 'object' && value === oldValue) {
+ return
+ }
+ callback(value)
+ })
+
+ return watcher.value
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/vm/dom-helper.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/vm/dom-helper.js b/runtime/frameworks/legacy/vm/dom-helper.js
new file mode 100644
index 0000000..6e5a800
--- /dev/null
+++ b/runtime/frameworks/legacy/vm/dom-helper.js
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview Document & Element Helpers.
+ *
+ * required:
+ * Document#: createElement, createComment, getRef
+ * Element#: appendChild, insertBefore, removeChild, nextSibling
+ */
+
+/**
+ * Create a body by type
+ * Using this._app.doc
+ *
+ * @param {string} type
+ */
+export function createBody (vm, type) {
+ const doc = vm._app.doc
+ return doc.createBody(type)
+}
+
+/**
+ * Create an element by type
+ * Using this._app.doc
+ *
+ * @param {string} type
+ */
+export function createElement (vm, type) {
+ const doc = vm._app.doc
+ return doc.createElement(type)
+}
+
+/**
+ * Create and return a frag block for an element.
+ * The frag block has a starter, ender and the element itself.
+ *
+ * @param {object} element
+ */
+export function createBlock (vm, element) {
+ const start = createBlockStart(vm)
+ const end = createBlockEnd(vm)
+ const blockId = lastestBlockId++
+ if (element.element) {
+ let updateMark = element.updateMark
+ if (updateMark) {
+ if (updateMark.element) {
+ updateMark = updateMark.end
+ }
+ element.element.insertAfter(end, updateMark)
+ element.element.insertAfter(start, updateMark)
+ element.updateMark = end
+ }
+ else {
+ element.element.insertBefore(start, element.end)
+ element.element.insertBefore(end, element.end)
+ }
+ element = element.element
+ }
+ else {
+ element.appendChild(start)
+ element.appendChild(end)
+ }
+ return { start, end, element, blockId }
+}
+
+let lastestBlockId = 1
+
+/**
+ * Create and return a block starter.
+ * Using this._app.doc
+ */
+function createBlockStart (vm) {
+ const doc = vm._app.doc
+ const anchor = doc.createComment('start')
+ return anchor
+}
+
+/**
+ * Create and return a block ender.
+ * Using this._app.doc
+ */
+function createBlockEnd (vm) {
+ const doc = vm._app.doc
+ const anchor = doc.createComment('end')
+ return anchor
+}
+
+/**
+ * Attach target to a certain dest using appendChild by default.
+ * If the dest is a frag block then insert before the ender.
+ * If the target is a frag block then attach the starter and ender in order.
+ *
+ * @param {object} target
+ * @param {object} dest
+ */
+export function attachTarget (vm, target, dest) {
+ if (dest.element) {
+ const before = dest.end
+ const after = dest.updateMark
+ // push new target for watch list update later
+ if (dest.children) {
+ dest.children.push(target)
+ }
+ // for check repeat case
+ if (after) {
+ const signal = moveTarget(vm, target, after)
+ dest.updateMark = target.element ? target.end : target
+ return signal
+ }
+ else if (target.element) {
+ dest.element.insertBefore(target.start, before)
+ dest.element.insertBefore(target.end, before)
+ }
+ else {
+ return dest.element.insertBefore(target, before)
+ }
+ }
+ else {
+ if (target.element) {
+ dest.appendChild(target.start)
+ dest.appendChild(target.end)
+ }
+ else {
+ return dest.appendChild(target)
+ }
+ }
+}
+
+/**
+ * Move target before a certain element. The target maybe block or element.
+ *
+ * @param {object} target
+ * @param {object} before
+ */
+export function moveTarget (vm, target, after) {
+ if (target.element) {
+ return moveBlock(target, after)
+ }
+ return moveElement(target, after)
+}
+
+/**
+ * Move element before a certain element.
+ *
+ * @param {object} element
+ * @param {object} before
+ */
+function moveElement (element, after) {
+ const parent = after.parentNode
+ if (parent) {
+ return parent.insertAfter(element, after)
+ }
+}
+
+/**
+ * Move all elements of the block before a certain element.
+ *
+ * @param {object} fragBlock
+ * @param {object} before
+ */
+function moveBlock (fragBlock, after) {
+ const parent = after.parentNode
+
+ if (parent) {
+ let el = fragBlock.start
+ let signal
+ const group = [el]
+
+ while (el && el !== fragBlock.end) {
+ el = el.nextSibling
+ group.push(el)
+ }
+
+ let temp = after
+ group.every((el) => {
+ signal = parent.insertAfter(el, temp)
+ temp = el
+ return signal !== -1
+ })
+
+ return signal
+ }
+}
+
+/**
+ * Remove target from DOM tree.
+ * If the target is a frag block then call _removeBlock
+ *
+ * @param {object} target
+ */
+export function removeTarget (vm, target, preserveBlock = false) {
+ if (target.element) {
+ removeBlock(target, preserveBlock)
+ }
+ else {
+ removeElement(target)
+ }
+ if (target._vm) {
+ target._vm.$emit('hook:destroyed')
+ }
+}
+
+/**
+ * Remove a certain element.
+ * Using this._app.doc
+ *
+ * @param {object} target
+ */
+function removeElement (target) {
+ const parent = target.parentNode
+
+ if (parent) {
+ parent.removeChild(target)
+ }
+}
+
+/**
+ * Remove a frag block.
+ * The second param decides whether the block self should be removed too.
+ *
+ * @param {object} fragBlock
+ * @param {Boolean} preserveBlock=false
+ */
+function removeBlock (fragBlock, preserveBlock = false) {
+ const result = []
+ let el = fragBlock.start.nextSibling
+
+ while (el && el !== fragBlock.end) {
+ result.push(el)
+ el = el.nextSibling
+ }
+
+ if (!preserveBlock) {
+ removeElement(fragBlock.start)
+ }
+ result.forEach((el) => {
+ removeElement(el)
+ })
+ if (!preserveBlock) {
+ removeElement(fragBlock.end)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/vm/events.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/vm/events.js b/runtime/frameworks/legacy/vm/events.js
new file mode 100644
index 0000000..5691472
--- /dev/null
+++ b/runtime/frameworks/legacy/vm/events.js
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * Everything about component event which includes event object, event listener,
+ * event emitter and lifecycle hooks.
+ */
+
+/**
+ * Event object definition. An event object has `type`, `timestamp` and
+ * `detail` from which a component emit. The event object could be dispatched to
+ * parents or broadcasted to children except `this.stop()` is called.
+ * @param {string} type
+ * @param {any} detail
+ */
+function Evt (type, detail) {
+ if (detail instanceof Evt) {
+ return detail
+ }
+
+ this.timestamp = Date.now()
+ this.detail = detail
+ this.type = type
+
+ let shouldStop = false
+
+ /**
+ * stop dispatch and broadcast
+ */
+ this.stop = function () {
+ shouldStop = true
+ }
+
+ /**
+ * check if it can't be dispatched or broadcasted
+ */
+ this.hasStopped = function () {
+ return shouldStop
+ }
+}
+
+/**
+ * Emit an event but not broadcast down or dispatch up.
+ * @param {string} type
+ * @param {any} detail
+ */
+export function $emit (type, detail) {
+ const events = this._vmEvents
+ const handlerList = events[type]
+ if (handlerList) {
+ const evt = new Evt(type, detail)
+ handlerList.forEach((handler) => {
+ handler.call(this, evt)
+ })
+ }
+}
+
+/**
+ * Emit an event and dispatch it up.
+ * @param {string} type
+ * @param {any} detail
+ */
+export function $dispatch (type, detail) {
+ const evt = new Evt(type, detail)
+ this.$emit(type, evt)
+
+ if (!evt.hasStopped() && this._parent && this._parent.$dispatch) {
+ this._parent.$dispatch(type, evt)
+ }
+}
+
+/**
+ * Emit an event and broadcast it down.
+ * @param {string} type
+ * @param {any} detail
+ */
+export function $broadcast (type, detail) {
+ const evt = new Evt(type, detail)
+ this.$emit(type, evt)
+
+ if (!evt.hasStopped() && this._childrenVms) {
+ this._childrenVms.forEach((subVm) => {
+ subVm.$broadcast(type, evt)
+ })
+ }
+}
+
+/**
+ * Add event listener.
+ * @param {string} type
+ * @param {function} handler
+ */
+export function $on (type, handler) {
+ if (!type || typeof handler !== 'function') {
+ return
+ }
+ const events = this._vmEvents
+ const handlerList = events[type] || []
+ handlerList.push(handler)
+ events[type] = handlerList
+
+ // fixed old version lifecycle design
+ /* istanbul ignore if */
+ if (type === 'hook:ready' && this._ready) {
+ this.$emit('hook:ready')
+ }
+}
+
+/**
+ * Remove event listener.
+ * @param {string} type
+ * @param {function} handler
+ */
+export function $off (type, handler) {
+ if (!type) {
+ return
+ }
+ const events = this._vmEvents
+ if (!handler) {
+ delete events[type]
+ return
+ }
+ const handlerList = events[type]
+ if (!handlerList) {
+ return
+ }
+ handlerList.$remove(handler)
+}
+
+const LIFE_CYCLE_TYPES = ['init', 'created', 'ready', 'destroyed']
+
+/**
+ * Init events:
+ * 1. listen `events` in component options & `externalEvents`.
+ * 2. bind lifecycle hooks.
+ * @param {Vm} vm
+ * @param {object} externalEvents
+ */
+export function initEvents (vm, externalEvents) {
+ const options = vm._options || {}
+ const events = options.events || {}
+ for (const type1 in events) {
+ vm.$on(type1, events[type1])
+ }
+ for (const type2 in externalEvents) {
+ vm.$on(type2, externalEvents[type2])
+ }
+ LIFE_CYCLE_TYPES.forEach((type) => {
+ vm.$on(`hook:${type}`, options[type])
+ })
+}
+
+/**
+ * Bind event related methods to ViewModel instance.
+ * @param {Vm} vm
+ */
+export function mixinEvents (vm) {
+ vm.$emit = $emit
+ vm.$dispatch = $dispatch
+ vm.$broadcast = $broadcast
+ vm.$on = $on
+ vm.$off = $off
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/vm/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/vm/index.js b/runtime/frameworks/legacy/vm/index.js
new file mode 100644
index 0000000..45a33af
--- /dev/null
+++ b/runtime/frameworks/legacy/vm/index.js
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * ViewModel Constructor & definition
+ */
+
+import { extend } from '../util/index'
+import {
+ initState
+} from '../core/state'
+import {
+ build
+} from './compiler'
+import {
+ set,
+ del
+} from '../core/observer'
+import {
+ watch
+} from './directive'
+import {
+ initEvents,
+ mixinEvents
+} from './events'
+
+/**
+ * ViewModel constructor
+ *
+ * @param {string} type
+ * @param {object} options component options
+ * @param {object} parentVm which contains _app
+ * @param {object} parentEl root element or frag block
+ * @param {object} mergedData external data
+ * @param {object} externalEvents external events
+ */
+export default function Vm (
+ type,
+ options,
+ parentVm,
+ parentEl,
+ mergedData,
+ externalEvents
+) {
+ parentVm = parentVm || {}
+ this._parent = parentVm._realParent ? parentVm._realParent : parentVm
+ this._app = parentVm._app || {}
+ parentVm._childrenVms && parentVm._childrenVms.push(this)
+
+ if (!options && this._app.customComponentMap) {
+ options = this._app.customComponentMap[type]
+ }
+ options = options || {}
+
+ const data = options.data || {}
+
+ this._options = options
+ this._methods = options.methods || {}
+ this._computed = options.computed || {}
+ this._css = options.style || {}
+ this._ids = {}
+ this._vmEvents = {}
+ this._childrenVms = []
+ this._type = type
+
+ // bind events and lifecycles
+ initEvents(this, externalEvents)
+
+ console.debug(`[JS Framework] "init" lifecycle in Vm(${this._type})`)
+ this.$emit('hook:init')
+ this._inited = true
+
+ // proxy data and methods
+ // observe data and add this to vms
+ this._data = typeof data === 'function' ? data() : data
+ if (mergedData) {
+ extend(this._data, mergedData)
+ }
+ initState(this)
+
+ console.debug(`[JS Framework] "created" lifecycle in Vm(${this._type})`)
+ this.$emit('hook:created')
+ this._created = true
+
+ // backward old ready entry
+ if (options.methods && options.methods.ready) {
+ console.warn('"exports.methods.ready" is deprecated, ' +
+ 'please use "exports.created" instead')
+ options.methods.ready.call(this)
+ }
+
+ if (!this._app.doc) {
+ return
+ }
+
+ // if no parentElement then specify the documentElement
+ this._parentEl = parentEl || this._app.doc.documentElement
+ build(this)
+}
+
+mixinEvents(Vm.prototype)
+
+/**
+ * Watch an function and bind all the data appeared in it. When the related
+ * data changes, the callback will be called with new value as 1st param.
+ *
+ * @param {Function} fn
+ * @param {Function} callback
+ */
+Vm.prototype.$watch = function (fn, callback) {
+ watch(this, fn, callback)
+}
+
+Vm.set = set
+Vm.delete = del
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/vanilla/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/vanilla/index.js b/runtime/frameworks/vanilla/index.js
new file mode 100644
index 0000000..f3b4bc2
--- /dev/null
+++ b/runtime/frameworks/vanilla/index.js
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+const config = {}
+
+const instanceMap = {}
+
+export function init (cfg) {
+ config.Document = cfg.Document
+ config.Element = cfg.Element
+ config.Comment = cfg.Comment
+ config.sendTasks = cfg.sendTasks
+}
+
+export function createInstance (id, code, options = {}, data = {}, serviceObjects = {}) {
+ const document = new config.Document(id, options.bundleUrl)
+ const callbacks = {}
+ const instance = { id, data, document, callbacks }
+
+ let lastCallbackId = 0
+ document.addCallback = func => {
+ lastCallbackId++
+ callbacks[lastCallbackId] = func
+ return lastCallbackId
+ }
+ document.handleCallback = (funcId, data, ifLast) => {
+ const callback = callbacks[funcId]
+ if (ifLast) {
+ delete callbacks[funcId]
+ }
+ return callback(data)
+ }
+ instanceMap[id] = instance
+
+ const globalObjects = Object.assign({
+ Document: config.Document,
+ Element: config.Element,
+ Comment: config.Comment,
+ sendTasks: tasks => config.sendTasks(id, tasks, -1),
+ options,
+ document
+ }, serviceObjects)
+
+ const globalKeys = []
+ const globalValues = []
+ for (const key in globalObjects) {
+ globalKeys.push(key)
+ globalValues.push(globalObjects[key])
+ }
+ globalKeys.push(code)
+
+ const result = new Function(...globalKeys)
+ result(...globalValues)
+
+ config.sendTasks(id, [{ module: 'dom', method: 'createFinish', args: [] }], -1)
+
+ return instance
+}
+
+export function destroyInstance (id) {
+ delete instanceMap[id]
+}
+
+export function getRoot (id) {
+ return instanceMap[id].document.body.toJSON()
+}
+
+export function receiveTasks (id, tasks) {
+ const jsHandlers = {
+ fireEvent: (id, ref, type, data, domChanges) => {
+ const { document } = instanceMap[id]
+ const el = document.getRef(ref)
+ return document.fireEvent(el, type, data, domChanges)
+ },
+
+ callback: (id, funcId, data, ifLast) => {
+ const { document } = instanceMap[id]
+ return document.handleCallback(funcId, data, ifLast)
+ }
+ }
+
+ const { document } = instanceMap[id] || {}
+ if (document && Array.isArray(tasks)) {
+ const results = []
+ tasks.forEach((task) => {
+ const handler = jsHandlers[task.method]
+ const args = [...task.args]
+ if (typeof handler === 'function') {
+ args.unshift(id)
+ results.push(handler(...args))
+ }
+ })
+ return results
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/services/amd/index.js
----------------------------------------------------------------------
diff --git a/runtime/services/amd/index.js b/runtime/services/amd/index.js
new file mode 100644
index 0000000..3a7a491
--- /dev/null
+++ b/runtime/services/amd/index.js
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileOverview
+ * A simple implementation of AMD for weex.
+ */
+
+/**
+ * amd modules (<id, module> pair)
+ * - id : instance id.
+ * - module: {
+ * name: module name
+ * , factory: module's factory function
+ * , cached: cached module,
+ * , deps: module's dependencies, always be [] under most circumstances.
+ * }
+ */
+const modules = {}
+
+const amdService = {
+
+ // create a amd service.
+ create: (id, env, config) => {
+ if (!env.framework.match(/Vue/i)) {
+ return
+ }
+
+ const mod = {}
+ modules[id] = mod
+ const amdObject = {
+
+ /**
+ * define a module.
+ * @param {String} name: module name.
+ * @param {Array} deps: dependencies. Always be empty array.
+ * @param {function} factory: factory function.
+ */
+ define (name, deps, factory) {
+ if (mod[name]) {
+ console.warn(`[amdService] already defined module: '${name}'`)
+ }
+ if (typeof deps === 'function') {
+ factory = deps
+ deps = []
+ }
+ mod[name] = { name, factory, cached: false, deps }
+ },
+
+ /**
+ * require a module.
+ * @param {string} name - module name.
+ */
+ require (name) {
+ const servMod = mod[name]
+ if (!servMod) {
+ return console.warn(`[amdService] module '${name}' is not defined.`)
+ }
+ if (servMod.cached) {
+ return servMod.cached
+ }
+ const exports = {}
+ const module = { exports }
+ const { deps } = servMod
+ let ret
+ if (deps && deps.length >= 1) {
+ /**
+ * to support:
+ * define(name, ['foo', 'bar'], function (foo, bar) { ... })
+ */
+ const args = deps.map(depName => require(depName))
+ ret = servMod.factory(...args)
+ }
+ else {
+ ret = servMod.factory(amdObject.require, exports, module)
+ }
+ servMod.cached = ret || module.exports
+ return servMod.cached
+ }
+ }
+ return { instance: amdObject }
+ },
+
+ destroy: (id, env) => {
+ delete modules[id]
+ }
+}
+
+export default amdService
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/services/broadcast-channel/index.js
----------------------------------------------------------------------
diff --git a/runtime/services/broadcast-channel/index.js b/runtime/services/broadcast-channel/index.js
new file mode 100644
index 0000000..cc7524e
--- /dev/null
+++ b/runtime/services/broadcast-channel/index.js
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileOverview
+ * The polyfill of BroadcastChannel API.
+ * This api can be used to achieve inter-instance communications.
+ *
+ * https://html.spec.whatwg.org/multipage/comms.html#broadcasting-to-other-browsing-contexts
+ */
+
+import { MessageEvent } from './message-event'
+
+const channels = {}
+const instances = {}
+
+/**
+ * An empty constructor for BroadcastChannel polyfill.
+ * The real constructor will be defined when a Weex instance created because
+ * we need to track the channel by Weex instance id.
+ */
+function BroadcastChannel () {}
+
+/**
+ * Sends the given message to other BroadcastChannel objects set up for this channel.
+ * @param {any} message
+ */
+BroadcastChannel.prototype.postMessage = function (message) {
+ if (this._closed) {
+ throw new Error(`BroadcastChannel "${this.name}" is closed.`)
+ }
+
+ const subscribers = channels[this.name]
+ if (subscribers && subscribers.length) {
+ for (let i = 0; i < subscribers.length; ++i) {
+ const member = subscribers[i]
+
+ if (member._closed || member === this) continue
+
+ if (typeof member.onmessage === 'function') {
+ member.onmessage(new MessageEvent('message', { data: message }))
+ }
+ }
+ }
+}
+
+/**
+ * Closes the BroadcastChannel object, opening it up to garbage collection.
+ */
+BroadcastChannel.prototype.close = function () {
+ if (this._closed) {
+ return
+ }
+
+ this._closed = true
+
+ // remove itself from channels.
+ if (channels[this.name]) {
+ const subscribers = channels[this.name].filter(x => x !== this)
+ if (subscribers.length) {
+ channels[this.name] = subscribers
+ }
+ else {
+ delete channels[this.name]
+ }
+ }
+}
+
+export default {
+ create: (id, env, config) => {
+ instances[id] = []
+ if (typeof global.BroadcastChannel === 'function') {
+ return {}
+ }
+ const serviceObject = {
+ /**
+ * Returns a new BroadcastChannel object via which messages for the given
+ * channel name can be sent and received.
+ * @param {string} name
+ */
+ BroadcastChannel: function (name) {
+ // the name property is readonly
+ Object.defineProperty(this, 'name', {
+ configurable: false,
+ enumerable: true,
+ writable: false,
+ value: String(name)
+ })
+
+ this._closed = false
+ this.onmessage = null
+
+ if (!channels[this.name]) {
+ channels[this.name] = []
+ }
+ channels[this.name].push(this)
+ instances[id].push(this)
+ }
+ }
+ serviceObject.BroadcastChannel.prototype = BroadcastChannel.prototype
+ return {
+ instance: serviceObject
+ }
+ },
+ destroy: (id, env) => {
+ instances[id].forEach(channel => channel.close())
+ delete instances[id]
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/services/broadcast-channel/message-event.js
----------------------------------------------------------------------
diff --git a/runtime/services/broadcast-channel/message-event.js b/runtime/services/broadcast-channel/message-event.js
new file mode 100644
index 0000000..00fa36a
--- /dev/null
+++ b/runtime/services/broadcast-channel/message-event.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Mock MessageEvent type
+ * @param {string} type
+ * @param {object} dict { data, origin, source, ports }
+ *
+ * This type has been simplified.
+ * https://html.spec.whatwg.org/multipage/comms.html#messageevent
+ * https://dom.spec.whatwg.org/#interface-event
+ */
+export function MessageEvent (type, dict = {}) {
+ this.type = type || 'message'
+
+ this.data = dict.data || null
+ this.origin = dict.origin || ''
+ this.source = dict.source || null
+ this.ports = dict.ports || []
+
+ // inherit properties
+ this.target = null
+ this.timeStamp = Date.now()
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/services/index.js
----------------------------------------------------------------------
diff --git a/runtime/services/index.js b/runtime/services/index.js
new file mode 100644
index 0000000..52cd97d
--- /dev/null
+++ b/runtime/services/index.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import BroadcastChannel from './broadcast-channel/index'
+
+export default {
+ BroadcastChannel
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/env/console.js
----------------------------------------------------------------------
diff --git a/runtime/shared/env/console.js b/runtime/shared/env/console.js
new file mode 100644
index 0000000..eb54815
--- /dev/null
+++ b/runtime/shared/env/console.js
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileOverview
+ * This file will hack `console` methods by `WXEnvironment.logLevel`.
+ * So we can control how many and which messages will be sent by change the log level.
+ * Additionally in native platform the message content must be primitive values and
+ * using `nativeLog(...args, logLevelMark)` so we create a new `console` object in
+ * global add a format process for its methods.
+ */
+
+const LEVELS = ['off', 'error', 'warn', 'info', 'log', 'debug']
+let levelMap = {}
+
+const originalConsole = global.console
+
+/**
+ * Hack console for native environment.
+ */
+export function setNativeConsole () {
+ generateLevelMap()
+
+ /* istanbul ignore next */
+ // mock console in native environment
+ if (global.WXEnvironment && global.WXEnvironment.platform !== 'Web') {
+ global.console = {
+ debug: (...args) => {
+ if (checkLevel('debug')) { global.nativeLog(...format(args), '__DEBUG') }
+ },
+ log: (...args) => {
+ if (checkLevel('log')) { global.nativeLog(...format(args), '__LOG') }
+ },
+ info: (...args) => {
+ if (checkLevel('info')) { global.nativeLog(...format(args), '__INFO') }
+ },
+ warn: (...args) => {
+ if (checkLevel('warn')) { global.nativeLog(...format(args), '__WARN') }
+ },
+ error: (...args) => {
+ if (checkLevel('error')) { global.nativeLog(...format(args), '__ERROR') }
+ }
+ }
+ }
+
+ // Web or Node
+ else {
+ const { debug, log, info, warn, error } = console
+ console.__ori__ = { debug, log, info, warn, error }
+ console.debug = (...args) => {
+ if (checkLevel('debug')) { console.__ori__.debug.apply(console, args) }
+ }
+ console.log = (...args) => {
+ if (checkLevel('log')) { console.__ori__.log.apply(console, args) }
+ }
+ console.info = (...args) => {
+ if (checkLevel('info')) { console.__ori__.info.apply(console, args) }
+ }
+ console.warn = (...args) => {
+ if (checkLevel('warn')) { console.__ori__.warn.apply(console, args) }
+ }
+ console.error = (...args) => {
+ if (checkLevel('error')) { console.__ori__.error.apply(console, args) }
+ }
+ }
+}
+
+/**
+ * Reset hacked console to original.
+ */
+/* istanbul ignore next */
+export function resetNativeConsole () {
+ levelMap = {}
+ global.console = originalConsole
+}
+
+/**
+ * Generate map for which types of message will be sent in a certain message level
+ * as the order of LEVELS.
+ */
+function generateLevelMap () {
+ LEVELS.forEach(level => {
+ const levelIndex = LEVELS.indexOf(level)
+ levelMap[level] = {}
+ LEVELS.forEach(type => {
+ const typeIndex = LEVELS.indexOf(type)
+ if (typeIndex <= levelIndex) {
+ levelMap[level][type] = true
+ }
+ })
+ })
+}
+
+/**
+ * Check if a certain type of message will be sent in current log level of env.
+ * @param {string} type
+ * @return {boolean}
+ */
+function checkLevel (type) {
+ const logLevel = (global.WXEnvironment && global.WXEnvironment.logLevel) || 'log'
+ return levelMap[logLevel] && levelMap[logLevel][type]
+}
+
+/**
+ * Convert all log arguments into primitive values.
+ * @param {array} args
+ * @return {array}
+ */
+/* istanbul ignore next */
+function format (args) {
+ return args.map((v) => {
+ const type = Object.prototype.toString.call(v)
+ if (type.toLowerCase() === '[object object]') {
+ v = JSON.stringify(v)
+ }
+ else {
+ v = String(v)
+ }
+ return v
+ })
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/env/freeze.js
----------------------------------------------------------------------
diff --git a/runtime/shared/env/freeze.js b/runtime/shared/env/freeze.js
new file mode 100644
index 0000000..f997a5f
--- /dev/null
+++ b/runtime/shared/env/freeze.js
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * Freeze the prototype of javascript build-in objects.
+ */
+/* istanbul ignore next */
+export function freezePrototype () {
+ Object.freeze(Object)
+ Object.freeze(Array)
+
+ // Object.freeze(Object.prototype)
+ freezeObjectProto()
+ Object.freeze(Array.prototype)
+ Object.freeze(String.prototype)
+ Object.freeze(Number.prototype)
+ Object.freeze(Boolean.prototype)
+
+ // Object.freeze(Error.prototype)
+ freezeErrorProto()
+ Object.freeze(Date.prototype)
+ Object.freeze(RegExp.prototype)
+}
+
+function freezeObjectProto () {
+ const proto = Object.prototype
+ const protoName = 'Object.prototype'
+ freezeProtoProperty(proto, '__defineGetter__', protoName)
+ freezeProtoProperty(proto, '__defineSetter__', protoName)
+ freezeProtoProperty(proto, '__lookupGetter__', protoName)
+ freezeProtoProperty(proto, '__lookupSetter__', protoName)
+ freezeProtoProperty(proto, 'constructor', protoName)
+ freezeProtoProperty(proto, 'hasOwnProperty', protoName)
+ freezeProtoProperty(proto, 'isPrototypeOf', protoName)
+ freezeProtoProperty(proto, 'propertyIsEnumerable', protoName)
+ freezeProtoProperty(proto, 'toLocaleString', protoName)
+ freezeProtoProperty(proto, 'toString', protoName)
+ freezeProtoProperty(proto, 'valueOf', protoName)
+ Object.seal(proto)
+}
+
+function freezeErrorProto () {
+ const proto = Error.prototype
+ const protoName = 'Error.prototype'
+ freezeProtoProperty(proto, 'name', protoName)
+ freezeProtoProperty(proto, 'message', protoName)
+ freezeProtoProperty(proto, 'toString', protoName)
+ freezeProtoProperty(proto, 'constructor', protoName)
+ Object.seal(proto)
+}
+
+function freezeProtoProperty (proto, propertyName, protoName) {
+ if (!proto.hasOwnProperty(propertyName)) {
+ return
+ }
+
+ const origin = proto[propertyName]
+ Object.defineProperty(proto, propertyName, {
+ get: function () {
+ return origin
+ },
+ set: function (value) {
+ if (this === proto) {
+ throw Error(`Cannot assign to read only property ${propertyName} of ${protoName}`)
+ }
+
+ Object.defineProperty(this, propertyName, {
+ value: value,
+ writable: true
+ })
+
+ return value
+ }
+ })
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/env/setTimeout.js
----------------------------------------------------------------------
diff --git a/runtime/shared/env/setTimeout.js b/runtime/shared/env/setTimeout.js
new file mode 100644
index 0000000..d545d6d
--- /dev/null
+++ b/runtime/shared/env/setTimeout.js
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileOverview
+ * Polyfill `setTimeout` on Android V8 using native method
+ * `setTimeoutNative(callbackId, time)` and JS method
+ * `setTimeoutCallback(callbackId)`.
+ * This polyfill is only used in virtual-DOM diff & flush agorithm. Not
+ * accessed by JS Bundle code (The timer APIs polyfill for JS Bundle is in
+ * `html5/default/app/ctrl.js`).
+ */
+
+const originalSetTimeout = global.setTimeout
+const setTimeoutNative = global.setTimeoutNative
+
+/**
+ * Set up native timer
+ */
+/* istanbul ignore next */
+export function setNativeTimer () {
+ if (typeof setTimeout === 'undefined' &&
+ typeof setTimeoutNative === 'function') {
+ const timeoutMap = {}
+ let timeoutId = 0
+
+ global.setTimeout = (cb, time) => {
+ timeoutMap[++timeoutId] = cb
+ setTimeoutNative(timeoutId.toString(), time)
+ }
+
+ global.setTimeoutCallback = (id) => {
+ if (typeof timeoutMap[id] === 'function') {
+ timeoutMap[id]()
+ delete timeoutMap[id]
+ }
+ }
+ }
+}
+
+/* istanbul ignore next */
+export function resetNativeTimer () {
+ global.setTimeout = originalSetTimeout
+ global.setTimeoutCallback = null
+}
+
+setNativeTimer()
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/index.js
----------------------------------------------------------------------
diff --git a/runtime/shared/index.js b/runtime/shared/index.js
new file mode 100644
index 0000000..a478b86
--- /dev/null
+++ b/runtime/shared/index.js
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import './polyfill/arrayFrom'
+import './polyfill/objectAssign'
+import './polyfill/objectSetPrototypeOf'
+
+// import promise hack and polyfills
+import './polyfill/promise'
+import 'core-js/modules/es6.object.to-string'
+import 'core-js/modules/es6.string.iterator'
+import 'core-js/modules/web.dom.iterable'
+import 'core-js/modules/es6.promise'
+
+export * from './env/console'
+export * from './env/setTimeout'
+export * from './env/freeze'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/polyfill/arrayFrom.js
----------------------------------------------------------------------
diff --git a/runtime/shared/polyfill/arrayFrom.js b/runtime/shared/polyfill/arrayFrom.js
new file mode 100644
index 0000000..af5e78c
--- /dev/null
+++ b/runtime/shared/polyfill/arrayFrom.js
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* eslint-disable */
+
+// Production steps of ECMA-262, Edition 6, 22.1.2.1
+// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
+
+/* istanbul ignore if */
+if (!Array.from) {
+ Array.from = (function() {
+ var toStr = Object.prototype.toString;
+ var isCallable = function(fn) {
+ return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
+ };
+ var toInteger = function(value) {
+ var number = Number(value);
+ if (isNaN(number)) {
+ return 0;
+ }
+ if (number === 0 || !isFinite(number)) {
+ return number;
+ }
+ return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
+ };
+ var maxSafeInteger = Math.pow(2, 53) - 1;
+ var toLength = function(value) {
+ var len = toInteger(value);
+ return Math.min(Math.max(len, 0), maxSafeInteger);
+ };
+
+ // The length property of the from method is 1.
+ return function from(arrayLike/*, mapFn, thisArg */) {
+ // 1. Let C be the this value.
+ var C = this;
+
+ // 2. Let items be ToObject(arrayLike).
+ var items = Object(arrayLike);
+
+ // 3. ReturnIfAbrupt(items).
+ if (arrayLike == null) {
+ throw new TypeError('Array.from requires an array-like object - not null or undefined');
+ }
+
+ // 4. If mapfn is undefined, then let mapping be false.
+ var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
+ var T;
+ if (typeof mapFn !== 'undefined') {
+ // 5. else
+ // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
+ if (!isCallable(mapFn)) {
+ throw new TypeError('Array.from: when provided, the second argument must be a function');
+ }
+
+ // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
+ if (arguments.length > 2) {
+ T = arguments[2];
+ }
+ }
+
+ // 10. Let lenValue be Get(items, "length").
+ // 11. Let len be ToLength(lenValue).
+ var len = toLength(items.length);
+
+ // 13. If IsConstructor(C) is true, then
+ // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
+ // 14. a. Else, Let A be ArrayCreate(len).
+ var A = isCallable(C) ? Object(new C(len)) : new Array(len);
+
+ // 16. Let k be 0.
+ var k = 0;
+ // 17. Repeat, while k < len… (also steps a - h)
+ var kValue;
+ while (k < len) {
+ kValue = items[k];
+ if (mapFn) {
+ A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
+ } else {
+ A[k] = kValue;
+ }
+ k += 1;
+ }
+ // 18. Let putStatus be Put(A, "length", len, true).
+ A.length = len;
+ // 20. Return A.
+ return A;
+ };
+ }());
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/polyfill/objectAssign.js
----------------------------------------------------------------------
diff --git a/runtime/shared/polyfill/objectAssign.js b/runtime/shared/polyfill/objectAssign.js
new file mode 100644
index 0000000..7aa5993
--- /dev/null
+++ b/runtime/shared/polyfill/objectAssign.js
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import 'core-js/fn/object/assign'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/polyfill/objectSetPrototypeOf.js
----------------------------------------------------------------------
diff --git a/runtime/shared/polyfill/objectSetPrototypeOf.js b/runtime/shared/polyfill/objectSetPrototypeOf.js
new file mode 100644
index 0000000..6364ce4
--- /dev/null
+++ b/runtime/shared/polyfill/objectSetPrototypeOf.js
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* eslint-disable */
+
+// https://gist.github.com/WebReflection/5593554
+
+/* istanbul ignore if */
+if (!Object.setPrototypeOf) {
+ Object.setPrototypeOf = (function(Object, magic) {
+ var set;
+ function setPrototypeOf(O, proto) {
+ set.call(O, proto);
+ return O;
+ }
+ try {
+ // this works already in Firefox and Safari
+ set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set;
+ set.call({}, null);
+ } catch (e) {
+ if (
+ // IE < 11 cannot be shimmed
+ Object.prototype !== {}[magic] ||
+ // neither can any browser that actually
+ // implemented __proto__ correctly
+ // (all but old V8 will return here)
+ {__proto__: null}.__proto__ === void 0
+ // this case means null objects cannot be passed
+ // through setPrototypeOf in a reliable way
+ // which means here a **Sham** is needed instead
+ ) {
+ return;
+ }
+ // nodejs 0.8 and 0.10 are (buggy and..) fine here
+ // probably Chrome or some old Mobile stock browser
+ set = function(proto) {
+ this[magic] = proto;
+ };
+ // please note that this will **not** work
+ // in those browsers that do not inherit
+ // __proto__ by mistake from Object.prototype
+ // in these cases we should probably throw an error
+ // or at least be informed about the issue
+ setPrototypeOf.polyfill = setPrototypeOf(
+ setPrototypeOf({}, null),
+ Object.prototype
+ ) instanceof Object;
+ // setPrototypeOf.polyfill === true means it works as meant
+ // setPrototypeOf.polyfill === false means it's not 100% reliable
+ // setPrototypeOf.polyfill === undefined
+ // or
+ // setPrototypeOf.polyfill == null means it's not a polyfill
+ // which means it works as expected
+ // we can even delete Object.prototype.__proto__;
+ }
+ return setPrototypeOf;
+ }(Object, '__proto__'));
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/polyfill/promise.js
----------------------------------------------------------------------
diff --git a/runtime/shared/polyfill/promise.js b/runtime/shared/polyfill/promise.js
new file mode 100644
index 0000000..39fe816
--- /dev/null
+++ b/runtime/shared/polyfill/promise.js
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// fix Promise Problem on JSContext of iOS7~8
+// @see https://bugs.webkit.org/show_bug.cgi?id=135866
+
+const { WXEnvironment } = global
+
+/* istanbul ignore next */
+if (WXEnvironment && WXEnvironment.platform === 'iOS') {
+ global.Promise = undefined
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/shared/utils.js
----------------------------------------------------------------------
diff --git a/runtime/shared/utils.js b/runtime/shared/utils.js
new file mode 100644
index 0000000..c2ab10f
--- /dev/null
+++ b/runtime/shared/utils.js
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Get a unique id.
+ */
+let nextNodeRef = 1
+export function uniqueId () {
+ return (nextNodeRef++).toString()
+}
+
+export function typof (v) {
+ const s = Object.prototype.toString.call(v)
+ return s.substring(8, s.length - 1)
+}
+
+export function bufferToBase64 (buffer) {
+ if (typeof btoa !== 'function') {
+ return ''
+ }
+ const string = Array.prototype.map.call(
+ new Uint8Array(buffer),
+ code => String.fromCharCode(code)
+ ).join('')
+ return btoa(string) // eslint-disable-line no-undef
+}
+
+export function base64ToBuffer (base64) {
+ if (typeof atob !== 'function') {
+ return new ArrayBuffer(0)
+ }
+ const string = atob(base64) // eslint-disable-line no-undef
+ const array = new Uint8Array(string.length)
+ Array.prototype.forEach.call(string, (ch, i) => {
+ array[i] = ch.charCodeAt(0)
+ })
+ return array.buffer
+}
+
+/**
+ * Detect if the param is falsy or empty
+ * @param {any} any
+ */
+export function isEmpty (any) {
+ if (!any || typeof any !== 'object') {
+ return true
+ }
+
+ for (const key in any) {
+ if (Object.prototype.hasOwnProperty.call(any, key)) {
+ return false
+ }
+ }
+ return true
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/Comment.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/Comment.js b/runtime/vdom/Comment.js
new file mode 100644
index 0000000..79f9e15
--- /dev/null
+++ b/runtime/vdom/Comment.js
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import Node from './Node'
+import { uniqueId } from '../shared/utils'
+
+export default class Comment extends Node {
+ constructor (value) {
+ super()
+
+ this.nodeType = 8
+ this.nodeId = uniqueId()
+ this.ref = this.nodeId
+ this.type = 'comment'
+ this.value = value
+ this.children = []
+ this.pureChildren = []
+ }
+
+ /**
+ * Convert to HTML comment string.
+ * @return {stirng} html
+ */
+ toString () {
+ return '<!-- ' + this.value + ' -->'
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/Document.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/Document.js b/runtime/vdom/Document.js
new file mode 100644
index 0000000..c64fba5
--- /dev/null
+++ b/runtime/vdom/Document.js
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import Comment from './Comment'
+import Element from './Element'
+import Listener from '../bridge/Listener'
+import { TaskCenter } from '../bridge/TaskCenter'
+import { createHandler } from '../bridge/Handler'
+import { addDoc, removeDoc, appendBody, setBody } from './operation'
+
+/**
+ * Update all changes for an element.
+ * @param {object} element
+ * @param {object} changes
+ */
+function updateElement (el, changes) {
+ const attrs = changes.attrs || {}
+ for (const name in attrs) {
+ el.setAttr(name, attrs[name], true)
+ }
+ const style = changes.style || {}
+ for (const name in style) {
+ el.setStyle(name, style[name], true)
+ }
+}
+
+export default class Document {
+ constructor (id, url, handler) {
+ id = id ? id.toString() : ''
+ this.id = id
+ this.URL = url
+
+ addDoc(id, this)
+ this.nodeMap = {}
+ const L = Document.Listener || Listener
+ this.listener = new L(id, handler || createHandler(id, Document.handler)) // deprecated
+ this.taskCenter = new TaskCenter(id, handler ? (id, ...args) => handler(...args) : Document.handler)
+ this.createDocumentElement()
+ }
+
+ /**
+ * Get the node from nodeMap.
+ * @param {string} reference id
+ * @return {object} node
+ */
+ getRef (ref) {
+ return this.nodeMap[ref]
+ }
+
+ /**
+ * Turn on batched updates.
+ */
+ open () {
+ this.listener.batched = false
+ }
+
+ /**
+ * Turn off batched updates.
+ */
+ close () {
+ this.listener.batched = true
+ }
+
+ /**
+ * Create the document element.
+ * @return {object} documentElement
+ */
+ createDocumentElement () {
+ if (!this.documentElement) {
+ const el = new Element('document')
+ el.docId = this.id
+ el.ownerDocument = this
+ el.role = 'documentElement'
+ el.depth = 0
+ el.ref = '_documentElement'
+ this.nodeMap._documentElement = el
+ this.documentElement = el
+
+ Object.defineProperty(el, 'appendChild', {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: (node) => {
+ appendBody(this, node)
+ }
+ })
+
+ Object.defineProperty(el, 'insertBefore', {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: (node, before) => {
+ appendBody(this, node, before)
+ }
+ })
+ }
+
+ return this.documentElement
+ }
+
+ /**
+ * Create the body element.
+ * @param {string} type
+ * @param {objct} props
+ * @return {object} body element
+ */
+ createBody (type, props) {
+ if (!this.body) {
+ const el = new Element(type, props)
+ setBody(this, el)
+ }
+
+ return this.body
+ }
+
+ /**
+ * Create an element.
+ * @param {string} tagName
+ * @param {objct} props
+ * @return {object} element
+ */
+ createElement (tagName, props) {
+ return new Element(tagName, props)
+ }
+
+ /**
+ * Create an comment.
+ * @param {string} text
+ * @return {object} comment
+ */
+ createComment (text) {
+ return new Comment(text)
+ }
+
+ /**
+ * Fire an event on specified element manually.
+ * @param {object} element
+ * @param {string} event type
+ * @param {object} event object
+ * @param {object} dom changes
+ * @param {object} options
+ * @return {} anything returned by handler function
+ */
+ fireEvent (el, type, event, domChanges, options) {
+ if (!el) {
+ return
+ }
+ event = event || {}
+ event.type = event.type || type
+ event.target = el
+ event.currentTarget = el
+ event.timestamp = Date.now()
+ if (domChanges) {
+ updateElement(el, domChanges)
+ }
+ const isBubble = this.getRef('_root').attr['bubble'] === 'true'
+ return el.fireEvent(type, event, isBubble, options)
+ }
+
+ /**
+ * Destroy current document, and remove itself form docMap.
+ */
+ destroy () {
+ this.taskCenter.destroyCallback()
+ delete this.listener
+ delete this.nodeMap
+ delete this.taskCenter
+ removeDoc(this.id)
+ }
+}
+
+// default task handler
+Document.handler = null
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/Element.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/Element.js b/runtime/vdom/Element.js
new file mode 100644
index 0000000..3160b6d
--- /dev/null
+++ b/runtime/vdom/Element.js
@@ -0,0 +1,524 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import Node from './Node'
+import {
+ getDoc,
+ getTaskCenter,
+ linkParent,
+ nextElement,
+ previousElement,
+ insertIndex,
+ moveIndex,
+ removeIndex
+} from './operation'
+import { uniqueId, isEmpty } from '../shared/utils'
+import { getWeexElement, setElement } from './WeexElement'
+
+const DEFAULT_TAG_NAME = 'div'
+const BUBBLE_EVENTS = [
+ 'click', 'longpress', 'touchstart', 'touchmove', 'touchend',
+ 'panstart', 'panmove', 'panend', 'horizontalpan', 'verticalpan', 'swipe'
+]
+
+function registerNode (docId, node) {
+ const doc = getDoc(docId)
+ doc.nodeMap[node.nodeId] = node
+}
+
+export default class Element extends Node {
+ constructor (type = DEFAULT_TAG_NAME, props, isExtended) {
+ super()
+
+ const WeexElement = getWeexElement(type)
+ if (WeexElement && !isExtended) {
+ return new WeexElement(type, props, true)
+ }
+
+ props = props || {}
+ this.nodeType = 1
+ this.nodeId = uniqueId()
+ this.ref = this.nodeId
+ this.type = type
+ this.attr = props.attr || {}
+ this.style = props.style || {}
+ this.classStyle = props.classStyle || {}
+ this.event = {}
+ this.children = []
+ this.pureChildren = []
+ }
+
+ /**
+ * Append a child node.
+ * @param {object} node
+ * @return {undefined | number} the signal sent by native
+ */
+ appendChild (node) {
+ if (node.parentNode && node.parentNode !== this) {
+ return
+ }
+ /* istanbul ignore else */
+ if (!node.parentNode) {
+ linkParent(node, this)
+ insertIndex(node, this.children, this.children.length, true)
+ if (this.docId) {
+ registerNode(this.docId, node)
+ }
+ if (node.nodeType === 1) {
+ insertIndex(node, this.pureChildren, this.pureChildren.length)
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ return taskCenter.send(
+ 'dom',
+ { action: 'addElement' },
+ [this.ref, node.toJSON(), -1]
+ )
+ }
+ }
+ }
+ else {
+ moveIndex(node, this.children, this.children.length, true)
+ if (node.nodeType === 1) {
+ const index = moveIndex(node, this.pureChildren, this.pureChildren.length)
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter && index >= 0) {
+ return taskCenter.send(
+ 'dom',
+ { action: 'moveElement' },
+ [node.ref, this.ref, index]
+ )
+ }
+ }
+ }
+ }
+
+ /**
+ * Insert a node before specified node.
+ * @param {object} node
+ * @param {object} before
+ * @return {undefined | number} the signal sent by native
+ */
+ insertBefore (node, before) {
+ if (node.parentNode && node.parentNode !== this) {
+ return
+ }
+ if (node === before || (node.nextSibling && node.nextSibling === before)) {
+ return
+ }
+ if (!node.parentNode) {
+ linkParent(node, this)
+ insertIndex(node, this.children, this.children.indexOf(before), true)
+ if (this.docId) {
+ registerNode(this.docId, node)
+ }
+ if (node.nodeType === 1) {
+ const pureBefore = nextElement(before)
+ const index = insertIndex(
+ node,
+ this.pureChildren,
+ pureBefore
+ ? this.pureChildren.indexOf(pureBefore)
+ : this.pureChildren.length
+ )
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ return taskCenter.send(
+ 'dom',
+ { action: 'addElement' },
+ [this.ref, node.toJSON(), index]
+ )
+ }
+ }
+ }
+ else {
+ moveIndex(node, this.children, this.children.indexOf(before), true)
+ if (node.nodeType === 1) {
+ const pureBefore = nextElement(before)
+ /* istanbul ignore next */
+ const index = moveIndex(
+ node,
+ this.pureChildren,
+ pureBefore
+ ? this.pureChildren.indexOf(pureBefore)
+ : this.pureChildren.length
+ )
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter && index >= 0) {
+ return taskCenter.send(
+ 'dom',
+ { action: 'moveElement' },
+ [node.ref, this.ref, index]
+ )
+ }
+ }
+ }
+ }
+
+ /**
+ * Insert a node after specified node.
+ * @param {object} node
+ * @param {object} after
+ * @return {undefined | number} the signal sent by native
+ */
+ insertAfter (node, after) {
+ if (node.parentNode && node.parentNode !== this) {
+ return
+ }
+ if (node === after || (node.previousSibling && node.previousSibling === after)) {
+ return
+ }
+ if (!node.parentNode) {
+ linkParent(node, this)
+ insertIndex(node, this.children, this.children.indexOf(after) + 1, true)
+ /* istanbul ignore else */
+ if (this.docId) {
+ registerNode(this.docId, node)
+ }
+ if (node.nodeType === 1) {
+ const index = insertIndex(
+ node,
+ this.pureChildren,
+ this.pureChildren.indexOf(previousElement(after)) + 1
+ )
+ const taskCenter = getTaskCenter(this.docId)
+ /* istanbul ignore else */
+ if (taskCenter) {
+ return taskCenter.send(
+ 'dom',
+ { action: 'addElement' },
+ [this.ref, node.toJSON(), index]
+ )
+ }
+ }
+ }
+ else {
+ moveIndex(node, this.children, this.children.indexOf(after) + 1, true)
+ if (node.nodeType === 1) {
+ const index = moveIndex(
+ node,
+ this.pureChildren,
+ this.pureChildren.indexOf(previousElement(after)) + 1
+ )
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter && index >= 0) {
+ return taskCenter.send(
+ 'dom',
+ { action: 'moveElement' },
+ [node.ref, this.ref, index]
+ )
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove a child node, and decide whether it should be destroyed.
+ * @param {object} node
+ * @param {boolean} preserved
+ */
+ removeChild (node, preserved) {
+ if (node.parentNode) {
+ removeIndex(node, this.children, true)
+ if (node.nodeType === 1) {
+ removeIndex(node, this.pureChildren)
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ taskCenter.send(
+ 'dom',
+ { action: 'removeElement' },
+ [node.ref]
+ )
+ }
+ }
+ }
+ if (!preserved) {
+ node.destroy()
+ }
+ }
+
+ /**
+ * Clear all child nodes.
+ */
+ clear () {
+ const taskCenter = getTaskCenter(this.docId)
+ /* istanbul ignore else */
+ if (taskCenter) {
+ this.pureChildren.forEach(node => {
+ taskCenter.send(
+ 'dom',
+ { action: 'removeElement' },
+ [node.ref]
+ )
+ })
+ }
+ this.children.forEach(node => {
+ node.destroy()
+ })
+ this.children.length = 0
+ this.pureChildren.length = 0
+ }
+
+ /**
+ * Set an attribute, and decide whether the task should be send to native.
+ * @param {string} key
+ * @param {string | number} value
+ * @param {boolean} silent
+ */
+ setAttr (key, value, silent) {
+ if (this.attr[key] === value && silent !== false) {
+ return
+ }
+ this.attr[key] = value
+ const taskCenter = getTaskCenter(this.docId)
+ if (!silent && taskCenter) {
+ const result = {}
+ result[key] = value
+ taskCenter.send(
+ 'dom',
+ { action: 'updateAttrs' },
+ [this.ref, result]
+ )
+ }
+ }
+
+ /**
+ * Set batched attributes.
+ * @param {object} batchedAttrs
+ * @param {boolean} silent
+ */
+ setAttrs (batchedAttrs, silent) {
+ if (isEmpty(batchedAttrs)) return
+ const mutations = {}
+ for (const key in batchedAttrs) {
+ if (this.attr[key] !== batchedAttrs[key]) {
+ this.attr[key] = batchedAttrs[key]
+ mutations[key] = batchedAttrs[key]
+ }
+ }
+ if (!isEmpty(mutations)) {
+ const taskCenter = getTaskCenter(this.docId)
+ if (!silent && taskCenter) {
+ taskCenter.send(
+ 'dom',
+ { action: 'updateAttrs' },
+ [this.ref, mutations]
+ )
+ }
+ }
+ }
+
+ /**
+ * Set a style property, and decide whether the task should be send to native.
+ * @param {string} key
+ * @param {string | number} value
+ * @param {boolean} silent
+ */
+ setStyle (key, value, silent) {
+ if (this.style[key] === value && silent !== false) {
+ return
+ }
+ this.style[key] = value
+ const taskCenter = getTaskCenter(this.docId)
+ if (!silent && taskCenter) {
+ const result = {}
+ result[key] = value
+ taskCenter.send(
+ 'dom',
+ { action: 'updateStyle' },
+ [this.ref, result]
+ )
+ }
+ }
+
+ /**
+ * Set batched style properties.
+ * @param {object} batchedStyles
+ * @param {boolean} silent
+ */
+ setStyles (batchedStyles, silent) {
+ if (isEmpty(batchedStyles)) return
+ const mutations = {}
+ for (const key in batchedStyles) {
+ if (this.style[key] !== batchedStyles[key]) {
+ this.style[key] = batchedStyles[key]
+ mutations[key] = batchedStyles[key]
+ }
+ }
+ if (!isEmpty(mutations)) {
+ const taskCenter = getTaskCenter(this.docId)
+ if (!silent && taskCenter) {
+ taskCenter.send(
+ 'dom',
+ { action: 'updateStyle' },
+ [this.ref, mutations]
+ )
+ }
+ }
+ }
+
+ /**
+ * Set style properties from class.
+ * @param {object} classStyle
+ */
+ setClassStyle (classStyle) {
+ // reset previous class style to empty string
+ for (const key in this.classStyle) {
+ this.classStyle[key] = ''
+ }
+
+ Object.assign(this.classStyle, classStyle)
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ taskCenter.send(
+ 'dom',
+ { action: 'updateStyle' },
+ [this.ref, this.toStyle()]
+ )
+ }
+ }
+
+ /**
+ * Add an event handler.
+ * @param {string} event type
+ * @param {function} event handler
+ */
+ addEvent (type, handler, params) {
+ if (!this.event) {
+ this.event = {}
+ }
+ if (!this.event[type]) {
+ this.event[type] = { handler, params }
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ taskCenter.send(
+ 'dom',
+ { action: 'addEvent' },
+ [this.ref, type]
+ )
+ }
+ }
+ }
+
+ /**
+ * Remove an event handler.
+ * @param {string} event type
+ */
+ removeEvent (type) {
+ if (this.event && this.event[type]) {
+ delete this.event[type]
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ taskCenter.send(
+ 'dom',
+ { action: 'removeEvent' },
+ [this.ref, type]
+ )
+ }
+ }
+ }
+
+ /**
+ * Fire an event manually.
+ * @param {string} type type
+ * @param {function} event handler
+ * @param {boolean} isBubble whether or not event bubble
+ * @param {boolean} options
+ * @return {} anything returned by handler function
+ */
+ fireEvent (type, event, isBubble, options) {
+ let result = null
+ let isStopPropagation = false
+ const eventDesc = this.event[type]
+ if (eventDesc && event) {
+ const handler = eventDesc.handler
+ event.stopPropagation = () => {
+ isStopPropagation = true
+ }
+ if (options && options.params) {
+ result = handler.call(this, ...options.params, event)
+ }
+ else {
+ result = handler.call(this, event)
+ }
+ }
+
+ if (!isStopPropagation
+ && isBubble
+ && (BUBBLE_EVENTS.indexOf(type) !== -1)
+ && this.parentNode
+ && this.parentNode.fireEvent) {
+ event.currentTarget = this.parentNode
+ this.parentNode.fireEvent(type, event, isBubble) // no options
+ }
+
+ return result
+ }
+
+ /**
+ * Get all styles of current element.
+ * @return {object} style
+ */
+ toStyle () {
+ return Object.assign({}, this.classStyle, this.style)
+ }
+
+ /**
+ * Convert current element to JSON like object.
+ * @return {object} element
+ */
+ toJSON () {
+ const result = {
+ ref: this.ref.toString(),
+ type: this.type,
+ attr: this.attr,
+ style: this.toStyle()
+ }
+ const event = []
+ for (const type in this.event) {
+ const { params } = this.event[type]
+ if (!params) {
+ event.push(type)
+ }
+ else {
+ event.push({ type, params })
+ }
+ }
+ if (event.length) {
+ result.event = event
+ }
+ if (this.pureChildren.length) {
+ result.children = this.pureChildren.map((child) => child.toJSON())
+ }
+ return result
+ }
+
+ /**
+ * Convert to HTML element tag string.
+ * @return {stirng} html
+ */
+ toString () {
+ return '<' + this.type +
+ ' attr=' + JSON.stringify(this.attr) +
+ ' style=' + JSON.stringify(this.toStyle()) + '>' +
+ this.pureChildren.map((child) => child.toString()).join('') +
+ '</' + this.type + '>'
+ }
+}
+
+setElement(Element)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/Node.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/Node.js b/runtime/vdom/Node.js
new file mode 100644
index 0000000..4f13edb
--- /dev/null
+++ b/runtime/vdom/Node.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { uniqueId } from '../shared/utils'
+import { getDoc } from './operation'
+
+export default class Node {
+ constructor () {
+ this.nodeId = uniqueId()
+ this.ref = this.nodeId
+ this.children = []
+ this.pureChildren = []
+ this.parentNode = null
+ this.nextSibling = null
+ this.previousSibling = null
+ }
+
+ /**
+ * Destroy current node, and remove itself form nodeMap.
+ */
+ destroy () {
+ const doc = getDoc(this.docId)
+ if (doc) {
+ delete this.docId
+ delete doc.nodeMap[this.nodeId]
+ }
+ this.children.forEach(child => {
+ child.destroy()
+ })
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/WeexElement.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/WeexElement.js b/runtime/vdom/WeexElement.js
new file mode 100644
index 0000000..455e69e
--- /dev/null
+++ b/runtime/vdom/WeexElement.js
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { getTaskCenter } from './operation'
+
+let Element
+
+export function setElement (El) {
+ Element = El
+}
+
+/**
+ * A map which stores all type of elements.
+ * @type {Object}
+ */
+const registeredElements = {}
+
+/**
+ * Register an extended element type with component methods.
+ * @param {string} type component type
+ * @param {array} methods a list of method names
+ */
+export function registerElement (type, methods) {
+ // Skip when no special component methods.
+ if (!methods || !methods.length) {
+ return
+ }
+
+ // Init constructor.
+ class WeexElement extends Element {}
+
+ // Add methods to prototype.
+ methods.forEach(methodName => {
+ WeexElement.prototype[methodName] = function (...args) {
+ const taskCenter = getTaskCenter(this.docId)
+ if (taskCenter) {
+ return taskCenter.send('component', {
+ ref: this.ref,
+ component: type,
+ method: methodName
+ }, args)
+ }
+ }
+ })
+
+ // Add to element type map.
+ registeredElements[type] = WeexElement
+}
+
+export function unregisterElement (type) {
+ delete registeredElements[type]
+}
+
+export function getWeexElement (type) {
+ return registeredElements[type]
+}
+
+export function isWeexElement (type) {
+ return !!registeredElements[type]
+}
+
+/**
+ * Clear all element types. Only for testing.
+ */
+export function clearWeexElements () {
+ for (const type in registeredElements) {
+ unregisterElement(type)
+ }
+}
[21/22] incubator-weex git commit: * [build] update build scripts of
js framework
Posted by ha...@apache.org.
* [build] update build scripts of js framework
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/9dd6cba1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/9dd6cba1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/9dd6cba1
Branch: refs/heads/master
Commit: 9dd6cba1eb14fd3e629678635f7662670d472db7
Parents: 51dd277
Author: Hanks <zh...@gmail.com>
Authored: Fri Dec 29 20:58:43 2017 +0800
Committer: Hanks <zh...@gmail.com>
Committed: Tue Jan 2 14:39:07 2018 +0800
----------------------------------------------------------------------
.flowconfig | 17 -----
build/build.js | 118 +++++++++++------------------------
build/config.js | 143 ++++++++++++++++++++++++-------------------
dangerfile.js | 15 ++---
package.json | 31 +++++-----
runtime/vdom/Element.js | 8 +--
6 files changed, 147 insertions(+), 185 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9dd6cba1/.flowconfig
----------------------------------------------------------------------
diff --git a/.flowconfig b/.flowconfig
deleted file mode 100644
index d92b990..0000000
--- a/.flowconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-[ignore]
-.*/node_modules/.*
-.*/test/.*
-.*/build/.*
-.*/examples/.*
-.*/doc/.*
-.*/android/.*
-.*/ios/.*
-.*/bin/.*
-.*/scripts/.*
-.*/dist/.*
-.*/flow-typed/.*
-
-[include]
-
-[options]
-experimental.strict_type_args=false
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9dd6cba1/build/build.js
----------------------------------------------------------------------
diff --git a/build/build.js b/build/build.js
index fb05e4b..d845816 100644
--- a/build/build.js
+++ b/build/build.js
@@ -16,23 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-"use strict"
const fs = require('fs')
const path = require('path')
-const gzip = require('zlib').createGzip()
-const pkg = require('../package.json')
const rollup = require('rollup')
const watch = require('rollup-watch')
-const webpack = require('webpack')
-
const getConfig = require('./config')
-// create dist folder
-if (!fs.existsSync('dist')) {
- fs.mkdirSync('dist')
-}
-
let isWatch = false
if (process.argv[3]) {
isWatch = process.argv[3] === '--watch' || process.argv[3] === '-w'
@@ -46,100 +36,66 @@ else {
console.log('\nPlease specify the package you want to build. [native, runtime, browser, vue]')
}
-function extend(to, ...froms) {
- froms.forEach(function (from) {
- for (const key in from) {
- if (from.hasOwnProperty(key)) {
- to[key] = from[key]
- }
- }
- })
- return to
-}
-
-function runRollupOnWatch(config) {
+function runRollupOnWatch (config) {
const watcher = watch(rollup, config)
watcher.on('event', event => {
- switch ( event.code ) {
- case 'STARTING':
- console.log('checking rollup-watch version...')
- break
-
- case 'BUILD_START':
- console.log('bundling...')
- break
-
- case 'BUILD_END':
+ switch (event.code) {
+ case 'STARTING': console.log('checking rollup-watch version...'); break
+ case 'BUILD_START': console.log('bundling...'); break
+ case 'BUILD_END': {
console.log('bundled in ' + path.relative(process.cwd(), config.dest)
+ ' (' + event.duration + 'ms)')
- console.log('Watching for changes...' )
- break
-
- case 'ERROR':
- console.error('ERROR: ', event.error)
- break
-
- default:
- console.error('unknown event', event)
+ console.log('Watching for changes...')
+ } break
+ case 'ERROR': console.error('ERROR: ', event.error); break
+ default: console.error('unknown event', event)
}
})
}
-function runRollup (config) {
- return new Promise((resolve, reject) => {
- rollup.rollup(config).then(bundle => {
- bundle.write(config).then(() => {
- report(config.dest)
- resolve()
- })
- })
- })
+async function runRollup (config) {
+ const bundle = await rollup.rollup(config)
+ const outputOptions = config.output
+ if (Array.isArray(outputOptions)) {
+ for (let i = 0; i < outputOptions.length; ++i) {
+ await bundle.write(outputOptions[i])
+ report(outputOptions[i].output.file)
+ }
+ }
+ else {
+ await bundle.write(outputOptions)
+ report(outputOptions.file)
+ }
}
-function build (name) {
+async function build (name) {
let pkgName = 'weex-js-framework'
switch (name) {
- case 'native': pkgName = 'weex-js-framework'; break;
- case 'runtime': pkgName = 'weex-js-runtime'; break;
- case 'legacy': pkgName = 'weex-legacy-framework'; break;
- case 'vanilla': pkgName = 'weex-vanilla-framework'; break;
+ case 'native': pkgName = 'weex-js-framework'; break
+ case 'vue': pkgName = 'weex-vue'; break
+ case 'rax': pkgName = 'weex-rax'; break
+ case 'runtime': pkgName = 'weex-js-runtime'; break
+ case 'legacy': pkgName = 'weex-legacy-framework'; break
+ case 'vanilla': pkgName = 'weex-vanilla-framework'; break
}
const config = getConfig(pkgName)
const minifyConfig = getConfig(pkgName, true)
+ const ES6Config = getConfig(pkgName, false, true)
+ const ES6MinifyConfig = getConfig(pkgName, true, true)
if (isWatch) {
- return runRollupOnWatch(config)
+ return await runRollupOnWatch(config)
}
else {
- console.log(`\n => start to build ${name} (${pkgName})\n`)
- return new Promise((resolve, reject) => {
- return runRollup(config).then(() => {
- let p = Promise.resolve()
- return p.then(function () {
- return runRollup(minifyConfig).then(() => {
- zip(minifyConfig.dest, resolve)
- })
- })
- })
- })
+ console.log(`\n => start to build ${pkgName}\n`)
+ await runRollup(config)
+ await runRollup(minifyConfig)
+ await runRollup(ES6Config)
+ await runRollup(ES6MinifyConfig)
}
}
-function zip (filePath, callback) {
- const read = fs.createReadStream(filePath)
- const write = fs.createWriteStream(filePath + '.gz')
- read.pipe(gzip).pipe(write).on('close', () => {
- report(filePath + '.gz')
- callback && callback()
- })
-}
-
-function now () {
- const time = Date.now() - (new Date()).getTimezoneOffset() * 60000
- return (new Date(time)).toISOString().replace('T', ' ').substring(0, 16)
-}
-
function report (filePath) {
const size = (fs.statSync(filePath).size / 1024).toFixed(2) + 'KB'
const file = path.relative(process.cwd(), filePath)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9dd6cba1/build/config.js
----------------------------------------------------------------------
diff --git a/build/config.js b/build/config.js
index 5a75a74..6c3873b 100644
--- a/build/config.js
+++ b/build/config.js
@@ -1,4 +1,3 @@
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -17,106 +16,126 @@
* specific language governing permissions and limitations
* under the License.
*/
+
const path = require('path')
const json = require('rollup-plugin-json')
const eslint = require('rollup-plugin-eslint')
const replace = require('rollup-plugin-replace')
const nodeResolve = require('rollup-plugin-node-resolve')
const uglify = require('rollup-plugin-uglify')
+const uglifyES = require('uglify-es')
const commonjs = require('rollup-plugin-commonjs')
const buble = require('rollup-plugin-buble')
-const subversion = require('../package.json').subversion
+const packageJSON = require('../package.json')
+const deps = packageJSON.dependencies
+const subversion = packageJSON.subversion
const frameworkBanner = `;(this.getJSFMVersion = function()`
+ `{return "${subversion.framework}"});\n`
- + `var global = this, process = { env: {} };var setTimeout = global.setTimeout;\n`
+ + `var global = this; var process = {env:{}}; var setTimeout = global.setTimeout;\n`
const configs = {
'weex-js-framework': {
- moduleName: 'Weex',
- entry: absolute('html5/render/native/index.js'),
- dest: absolute('packages/weex-js-framework/index.js'),
- banner: `(this.nativeLog || function(s) {console.log(s)})`
- + `('START JS FRAMEWORK ${subversion.framework}, Build ${now()}.');\n`
- + frameworkBanner,
- format: 'umd',
- plugins: [
- nodeResolve({
- jsnext: true,
- main: true
- }),
- ]
+ input: absolute('runtime/entries/index.js'),
+ output: {
+ name: 'Weex',
+ file: absolute('pre-build/weex-js-framework'),
+ banner: `(this.nativeLog || function(s) {console.log(s)})`
+ + `('START JS FRAMEWORK ${subversion.framework}, Build ${now()}. `
+ + `(Vue: ${deps['weex-vue-framework']}, Rax: ${deps['weex-rax-framework']})');\n`
+ + frameworkBanner
+ }
+ },
+ 'weex-vue': {
+ input: absolute('runtime/entries/vue.js'),
+ output: {
+ name: 'WeexVue',
+ file: absolute('pre-build/weex-vue'),
+ banner: `(this.nativeLog || function(s) {console.log(s)})`
+ + `('Weex JS Framework ${subversion.framework}, Build ${now()}. `
+ + `(Vue: ${deps['weex-vue-framework']})');\n`
+ + frameworkBanner
+ }
+ },
+ 'weex-rax': {
+ input: absolute('runtime/entries/rax.js'),
+ output: {
+ name: 'WeexRax',
+ file: absolute('pre-build/weex-rax'),
+ banner: `(this.nativeLog || function(s) {console.log(s)})`
+ + `('Weex JS Framework ${subversion.framework}, Build ${now()}. `
+ + `(Rax: ${deps['weex-rax-framework']})');\n`
+ + frameworkBanner
+ }
},
'weex-js-runtime': {
- moduleName: 'WeexRuntime',
- entry: absolute('html5/runtime/index.js'),
- dest: absolute('packages/weex-js-runtime/index.js'),
- banner: `/* WEEX JS RUNTIME ${subversion.framework}, Build ${now()}. */\n\n`,
- format: 'umd',
- plugins: [
- nodeResolve({
- jsnext: true,
- main: true
- }),
- ]
+ input: absolute('runtime/api/index.js'),
+ output: {
+ name: 'WeexJSRuntime',
+ file: absolute('packages/weex-js-runtime/index'),
+ banner: `/* Weex JS Runtime ${subversion.framework}, Build ${now()}. */\n\n`
+ }
},
'weex-legacy-framework': {
- moduleName: 'WeexLegacyFramework',
- entry: absolute('html5/frameworks/legacy/index.js'),
- dest: absolute('packages/weex-legacy-framework/index.js'),
- banner: `/* Weex Legacy Framework ${subversion.framework}, Build ${now()}. */\n`,
- format: 'umd',
- plugins: [
- nodeResolve({
- jsnext: true,
- main: true
- }),
- ]
+ input: absolute('runtime/frameworks/legacy/index.js'),
+ output: {
+ name: 'WeexLegacyFramework',
+ file: absolute('packages/weex-legacy-framework/index'),
+ banner: `/* Weex Legacy Framework ${subversion.framework}, Build ${now()}. */\n`
+ }
},
'weex-vanilla-framework': {
- moduleName: 'WeexVanillaFramework',
- entry: absolute('html5/frameworks/vanilla/index.js'),
- dest: absolute('packages/weex-vanilla-framework/index.js'),
- banner: `/* Weex Vanilla Framework ${subversion.framework}, Build ${now()}. */\n`,
- format: 'umd',
- plugins: [
- nodeResolve({
- jsnext: true,
- main: true
- }),
- ]
+ input: absolute('runtime/frameworks/vanilla/index.js'),
+ output: {
+ name: 'WeexVanillaFramework',
+ file: absolute('packages/weex-vanilla-framework/index'),
+ banner: `/* Weex Vanilla Framework ${subversion.framework}, Build ${now()}. */\n`
+ }
}
}
-function getConfig (name, minify) {
+function getConfig (name, minify, es6) {
const opt = configs[name]
+ if (!opt.plugins) {
+ opt.plugins = []
+ }
+ const output = opt.output
+ const suffix = `${es6 ? '.es6' : ''}${minify ? '.min' : ''}.js`
const config = {
- moduleName: opt.moduleName,
- entry: opt.entry,
- dest: minify ? opt.dest && opt.dest.replace(/\.js$/, '.min.js') : opt.dest,
- format: opt.format,
- banner: opt.banner,
+ input: opt.input,
+ output: {
+ name: output.name,
+ file: output.file + suffix,
+ format: output.format || 'umd',
+ banner: output.banner
+ },
plugins: opt.plugins.concat([
+ nodeResolve({ jsnext: true, main: true }),
json(),
replace({
- 'process.env.VIEWPORT_WIDTH': 750,
+ '__WEEX_VERSION__': JSON.stringify(subversion.framework),
'process.env.NODE_ENV': JSON.stringify(minify ? 'production' : 'development'),
'process.env.VUE_ENV': JSON.stringify('WEEX'),
+ 'process.env.SUPPORT_ES2015': !!es6,
'process.env.NODE_DEBUG': false
}),
- commonjs(),
- buble()
+ commonjs()
])
}
-
+ if (!es6) {
+ config.plugins.push(buble())
+ }
if (minify) {
- config.plugins.push(uglify())
+ config.output.sourcemap = true
+ config.plugins.push(es6
+ ? uglify({ safari10: true, toplevel: true }, uglifyES.minify)
+ : uglify()
+ )
}
else {
- config.sourceMap = 'inline'
+ config.output.sourcemap = 'inline'
config.plugins.unshift(eslint({ exclude: ['**/*.json', '**/*.css'] }))
}
-
return config
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9dd6cba1/dangerfile.js
----------------------------------------------------------------------
diff --git a/dangerfile.js b/dangerfile.js
index 40cbadb..660c4af 100644
--- a/dangerfile.js
+++ b/dangerfile.js
@@ -72,12 +72,12 @@ if (unFlowedFiles.length > 0) {
// Error or Warn when delete public interface
var isNotDanger = false;
console.log('pr.title:'+danger.github.pr.title)
-if(!isNotDanger && danger.github.pr.title
+if(!isNotDanger && danger.github.pr.title
&& danger.github.pr.title.match(/@notdanger/i)){
isNotDanger = true;
}
console.log('pr.body:'+danger.github.pr.body)
-if(!isNotDanger && danger.github.pr.body
+if(!isNotDanger && danger.github.pr.body
&& danger.github.pr.body.match(/@notdanger/i)){
isNotDanger = true;
}
@@ -146,10 +146,10 @@ const getFileType = file => {
} else if (file.match(/android\/sdk\/src\/main\/java\/.+\.java/)) {
return type_android_sdk;
} else if (
- file.match(/html5\/(shared|frameworks|render|runtime|services)\/.+\.js/)
+ file.match(/runtime\/.+\.js/)
) {
return type_jsfm;
- } else if (file.match(/html5\/test\/.+\.js/)) {
+ } else if (file.match(/test\/js-framework\/.+\.js/)) {
return type_jsfm_test;
} else if (file.match(/doc\/\.+\.md/)) {
return type_doc;
@@ -250,7 +250,8 @@ const ignoreCopyrightVerifyPath = [
'test',
'packages',
'pre-build',
- 'html5/test/case',
+ 'runtime/frameworks/legacy/core',
+ 'test/js\-framework/case',
'android/playground/app/src/main/assets',
'android/sdk/assets',
'ios/playground/bundlejs',
@@ -275,7 +276,7 @@ filesToVerifySrcHeader.forEach(filepath => {
}
// check cn for source code
- var reg = /[\u4e00-\u9FA5]+/;
+ var reg = /[\u4e00-\u9FA5]+/;
var res = reg.test(content);
if(res){
console.error("Code file "+ filepath +" has cn source code.");
@@ -356,7 +357,7 @@ function getContent(url) {
console.log('response:', response.statusCode)
if (response.statusCode < 200 || response.statusCode > 299) {
if (response.statusCode === 404 || response.statusCode === 502) {
- // ignore this, probably a renamed file,or .so that can't blame
+ // ignore this, probably a renamed file,or .so that can't blame
return resolve('')
}
reject(new Error('Failed to load page, status code: ' + response.statusCode + ', '
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9dd6cba1/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 0282224..636a1f0 100644
--- a/package.json
+++ b/package.json
@@ -32,11 +32,13 @@
"yunos"
],
"engines": {
- "node": ">=4"
+ "node": ">=8"
},
"scripts": {
"postinstall": "bash ./scripts/install-hooks.sh",
"build:native": "node build/build.js native",
+ "build:vue": "node build/build.js vue",
+ "build:rax": "node build/build.js rax",
"build:runtime": "node build/build.js runtime",
"build:legacy": "node build/build.js legacy",
"build:vanilla": "node build/build.js vanilla",
@@ -58,8 +60,8 @@
"dev:examples:web": "webpack --watch --config build/webpack.examples.web.config.js",
"dev:test": "webpack --watch --config build/webpack.test.config.js",
"lint": "eslint html5",
- "test:case": "mocha --require reify html5/test/case/tester.js",
- "test:unit": "mocha --require reify html5/test/unit/**/*",
+ "test:case": "mocha --require reify test/js-framework/case/tester.js",
+ "test:unit": "mocha --require reify test/js-framework/unit/**/*",
"test": "npm run lint && npm run test:unit && npm run test:case",
"test:cover-html": "babel-istanbul cover --report html node_modules/mocha/bin/_mocha -- --require reify --reporter dot html5/test/unit/ && open coverage/index.html",
"test:cover": "babel-istanbul cover --report text node_modules/mocha/bin/_mocha -- --require reify --reporter dot html5/test/unit/",
@@ -100,6 +102,7 @@
"danger": "^0.18.0",
"dateformat": "^2.0.0",
"eslint": "^2.11.1",
+ "eslint-plugin-flowtype": "^2.40.1",
"fs-extra": "^2.0.0",
"github": "^9.2.0",
"http-server": "^0.9.0",
@@ -110,20 +113,21 @@
"parse-diff": "^0.4.0",
"phantomjs-prebuilt": "^2.1.7",
"reify": "^0.3.8",
- "rollup": "^0.36.0",
- "rollup-plugin-buble": "^0.14.0",
- "rollup-plugin-commonjs": "^5.0.4",
- "rollup-plugin-eslint": "^3.0.0",
- "rollup-plugin-json": "^2.0.2",
- "rollup-plugin-node-resolve": "^2.0.0",
- "rollup-plugin-postcss": "^0.2.0",
- "rollup-plugin-replace": "^1.1.1",
+ "rollup": "^0.53.2",
+ "rollup-plugin-buble": "^0.18.0",
+ "rollup-plugin-commonjs": "^8.2.6",
+ "rollup-plugin-eslint": "^4.0.0",
+ "rollup-plugin-json": "^2.3.0",
+ "rollup-plugin-node-resolve": "^3.0.0",
+ "rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^2.0.1",
- "rollup-watch": "^2.5.0",
+ "rollup-watch": "^4.3.1",
"selenium-server": "2.53.1",
"serve": "^1.4.0",
+ "shelljs": "^0.7.8",
"sinon": "^2.1.0",
"sinon-chai": "^2.8.0",
+ "uglify-es": "^3.3.4",
"uglify-js": "^2.8.29",
"vue": "2.4.3",
"vue-loader": "^12.2.1",
@@ -134,7 +138,6 @@
"weex-loader": "^0.5.3",
"weex-vdom-tester": "^0.2.0",
"weex-wd": "^1.0.23",
- "xmldom": "^0.1.27",
- "shelljs": "^0.7.8"
+ "xmldom": "^0.1.27"
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/9dd6cba1/runtime/vdom/Element.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/Element.js b/runtime/vdom/Element.js
index 3160b6d..8e7b572 100644
--- a/runtime/vdom/Element.js
+++ b/runtime/vdom/Element.js
@@ -133,8 +133,8 @@ export default class Element extends Node {
node,
this.pureChildren,
pureBefore
- ? this.pureChildren.indexOf(pureBefore)
- : this.pureChildren.length
+ ? this.pureChildren.indexOf(pureBefore)
+ : this.pureChildren.length
)
const taskCenter = getTaskCenter(this.docId)
if (taskCenter) {
@@ -155,8 +155,8 @@ export default class Element extends Node {
node,
this.pureChildren,
pureBefore
- ? this.pureChildren.indexOf(pureBefore)
- : this.pureChildren.length
+ ? this.pureChildren.indexOf(pureBefore)
+ : this.pureChildren.length
)
const taskCenter = getTaskCenter(this.docId)
if (taskCenter && index >= 0) {
[05/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-moduleB.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-moduleB.source.js b/test/js-framework/case/multi/clear-moduleB.source.js
new file mode 100644
index 0000000..c6338fd
--- /dev/null
+++ b/test/js-framework/case/multi/clear-moduleB.source.js
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/moduleB', function(require, exports, module) {
+
+ ;module.exports = {
+ data: {
+ text: ''
+ },
+ created: function() {
+ var smp = require('sample')
+ this.text = smp ? smp.name : 'nothing'
+ }
+ }
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function() { return this.text }
+ }
+ }
+ ]
+ }
+
+})
+
+// require module
+bootstrap('@weex-component/moduleB', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/prepare.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/prepare.js b/test/js-framework/case/prepare.js
new file mode 100644
index 0000000..03d21be
--- /dev/null
+++ b/test/js-framework/case/prepare.js
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import fs from 'fs'
+import path from 'path'
+
+// load test driver
+import {
+ Runtime,
+ Instance
+} from 'weex-vdom-tester'
+
+// load env
+import shared from '../../../runtime/shared'
+import { Document, Element, Comment } from '../../../runtime/vdom'
+import Listener from '../../../runtime/bridge/Listener'
+import { TaskCenter, init } from '../../../runtime/bridge/TaskCenter'
+
+// load framework
+import * as defaultFramework from '../../../runtime/frameworks/legacy'
+import { subversion } from '../../../package.json'
+
+shared.setNativeConsole()
+
+// mock config & global APIs
+global.callNativeHandler = function () {}
+
+// init special API called `callAddElement()`
+// which is supported temporarily in native render
+global.callAddElement = function (id, ref, json, index) {
+ return callNativeHandler(id, [{ module: 'dom', method: 'addElement', args: [ref, json, index] }])
+}
+
+init()
+
+// create test driver runtime
+export function createRuntime () {
+ const config = {
+ Document, Element, Comment, Listener,
+ TaskCenter,
+ sendTasks (...args) {
+ return callNativeHandler(...args)
+ }
+ }
+
+ Document.Listener = Listener
+ Document.handler = config.sendTasks
+
+ defaultFramework.init(config)
+
+ Object.assign(global, {
+ frameworkVersion: subversion.native,
+ transformerVersion: subversion.transformer
+ })
+
+ return new Runtime(defaultFramework)
+}
+
+// create framework instance
+export function createApp (runtime) {
+ return new Instance(runtime)
+}
+
+// read source code from file
+export function getCode (filePath) {
+ const absolutPath = path.join(__dirname, filePath)
+ return fs.readFileSync(absolutPath, 'utf8')
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/signals/modal.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/signals/modal.output.js b/test/js-framework/case/signals/modal.output.js
new file mode 100644
index 0000000..f645aa2
--- /dev/null
+++ b/test/js-framework/case/signals/modal.output.js
@@ -0,0 +1,9 @@
+{
+ type: 'div',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'foo'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/signals/modal.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/signals/modal.source.js b/test/js-framework/case/signals/modal.source.js
new file mode 100644
index 0000000..bdef1b8
--- /dev/null
+++ b/test/js-framework/case/signals/modal.source.js
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/modal', function (require, exports, module) {
+
+;
+ var modal = require('@weex-module/modal')
+ module.exports = {
+ data: function () {
+ return {
+ x: 'foo'
+ }
+ },
+ created: function () {
+ var message = 'Here is a message for you!'
+ var okTitle = 'OK'
+ modal.alert({
+ message: message,
+ okTitle: okTitle
+ }, function() {
+ this.x = 'bar'
+ }.bind(this))
+ }
+ }
+
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {
+ return this.x
+ }
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/modal')
[09/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/downgrade.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/downgrade.js b/runtime/frameworks/legacy/app/downgrade.js
new file mode 100644
index 0000000..327d70a
--- /dev/null
+++ b/runtime/frameworks/legacy/app/downgrade.js
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import semver from 'semver'
+import { isPlainObject, typof } from '../util/index'
+
+/**
+ * Normalize a version string.
+ * @param {String} Version. ie: 1, 1.0, 1.0.0
+ * @return {String} Version
+ */
+export function normalizeVersion (v) {
+ const isValid = semver.valid(v)
+ if (isValid) {
+ return v
+ }
+
+ v = typeof (v) === 'string' ? v : ''
+ const split = v.split('.')
+ let i = 0
+ const result = []
+
+ while (i < 3) {
+ const s = typeof (split[i]) === 'string' && split[i] ? split[i] : '0'
+ result.push(s)
+ i++
+ }
+
+ return result.join('.')
+}
+
+/**
+ * Get informations from different error key. Like:
+ * - code
+ * - errorMessage
+ * - errorType
+ * - isDowngrade
+ * @param {string} key
+ * @param {string} val
+ * @param {string} criteria
+ * @return {object}
+ */
+export function getError (key, val, criteria) {
+ const result = {
+ isDowngrade: true,
+ errorType: 1,
+ code: 1000
+ }
+ const getMsg = function (key, val, criteria) {
+ return 'Downgrade[' + key + '] :: deviceInfo '
+ + val + ' matched criteria ' + criteria
+ }
+ const _key = key.toLowerCase()
+
+ result.errorMessage = getMsg(key, val, criteria)
+
+ if (_key.indexOf('osversion') >= 0) {
+ result.code = 1001
+ }
+ else if (_key.indexOf('appversion') >= 0) {
+ result.code = 1002
+ }
+ else if (_key.indexOf('weexversion') >= 0) {
+ result.code = 1003
+ }
+ else if (_key.indexOf('devicemodel') >= 0) {
+ result.code = 1004
+ }
+
+ return result
+}
+
+/**
+ * WEEX framework input(deviceInfo)
+ * {
+ * platform: 'iOS' or 'android'
+ * osVersion: '1.0.0' or '1.0' or '1'
+ * appVersion: '1.0.0' or '1.0' or '1'
+ * weexVersion: '1.0.0' or '1.0' or '1'
+ * dDeviceModel: 'MODEL_NAME'
+ * }
+ *
+ * downgrade config(config)
+ * {
+ * ios: {
+ * osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+ * appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+ * weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+ * deviceModel: ['modelA', 'modelB', ...]
+ * },
+ * android: {
+ * osVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+ * appVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+ * weexVersion: '>1.0.0' or '>=1.0.0' or '<1.0.0' or '<=1.0.0' or '1.0.0'
+ * deviceModel: ['modelA', 'modelB', ...]
+ * }
+ * }
+ *
+ *
+ * @param {object} deviceInfo Weex SDK framework input
+ * @param {object} config user input
+ * @return {Object} { isDowngrade: true/false, errorMessage... }
+ */
+export function check (config, deviceInfo) {
+ deviceInfo = deviceInfo || global.WXEnvironment
+ deviceInfo = isPlainObject(deviceInfo) ? deviceInfo : {}
+
+ let result = {
+ isDowngrade: false // defautl is pass
+ }
+
+ if (typof(config) === 'function') {
+ let customDowngrade = config.call(this, deviceInfo, {
+ semver: semver,
+ normalizeVersion
+ })
+
+ customDowngrade = !!customDowngrade
+
+ result = customDowngrade ? getError('custom', '', 'custom params') : result
+ }
+ else {
+ config = isPlainObject(config) ? config : {}
+
+ const platform = deviceInfo.platform || 'unknow'
+ const dPlatform = platform.toLowerCase()
+ const cObj = config[dPlatform] || {}
+
+ for (const i in deviceInfo) {
+ const key = i
+ const keyLower = key.toLowerCase()
+ const val = deviceInfo[i]
+ const isVersion = keyLower.indexOf('version') >= 0
+ const isDeviceModel = keyLower.indexOf('devicemodel') >= 0
+ const criteria = cObj[i]
+
+ if (criteria && isVersion) {
+ const c = normalizeVersion(criteria)
+ const d = normalizeVersion(deviceInfo[i])
+
+ if (semver.satisfies(d, c)) {
+ result = getError(key, val, criteria)
+ break
+ }
+ }
+ else if (isDeviceModel) {
+ const _criteria = typof(criteria) === 'array' ? criteria : [criteria]
+ if (_criteria.indexOf(val) >= 0) {
+ result = getError(key, val, criteria)
+ break
+ }
+ }
+ }
+ }
+
+ return result
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/index.js b/runtime/frameworks/legacy/app/index.js
new file mode 100644
index 0000000..5ae389d
--- /dev/null
+++ b/runtime/frameworks/legacy/app/index.js
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * Weex instance constructor & definition
+ */
+
+import { requireModule } from './register'
+import { updateActions, callTasks } from './ctrl/index'
+import App from './instance'
+
+/**
+ * @deprecated
+ */
+App.prototype.requireModule = function (name) {
+ return requireModule(this, name)
+}
+
+/**
+ * @deprecated
+ */
+App.prototype.updateActions = function () {
+ return updateActions(this)
+}
+
+/**
+ * @deprecated
+ */
+App.prototype.callTasks = function (tasks) {
+ return callTasks(this, tasks)
+}
+
+/**
+ * Prevent modification of App and App.prototype
+ */
+Object.freeze(App)
+Object.freeze(App.prototype)
+
+export default App
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/instance.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/instance.js b/runtime/frameworks/legacy/app/instance.js
new file mode 100644
index 0000000..55bb4c5
--- /dev/null
+++ b/runtime/frameworks/legacy/app/instance.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * Weex App constructor & definition
+ */
+
+import Differ from './differ'
+import renderer from '../config'
+
+/**
+ * App constructor for Weex framework.
+ * @param {string} id
+ * @param {object} options
+ */
+export default function App (id, options) {
+ this.id = id
+ this.options = options || {}
+ this.vm = null
+ this.customComponentMap = {}
+ this.commonModules = {}
+
+ // document
+ this.doc = new renderer.Document(
+ id,
+ this.options.bundleUrl,
+ null,
+ renderer.Listener
+ )
+ this.differ = new Differ(id)
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/register.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/register.js b/runtime/frameworks/legacy/app/register.js
new file mode 100644
index 0000000..bd0302e
--- /dev/null
+++ b/runtime/frameworks/legacy/app/register.js
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+let nativeModules = {}
+
+// for testing
+
+/**
+ * for testing
+ */
+export function getModule (moduleName) {
+ return nativeModules[moduleName]
+}
+
+/**
+ * for testing
+ */
+export function clearModules () {
+ nativeModules = {}
+}
+
+// for framework
+
+/**
+ * init modules for an app instance
+ * the second param determines whether to replace an existed method
+ */
+export function initModules (modules, ifReplace) {
+ for (const moduleName in modules) {
+ // init `modules[moduleName][]`
+ let methods = nativeModules[moduleName]
+ if (!methods) {
+ methods = {}
+ nativeModules[moduleName] = methods
+ }
+
+ // push each non-existed new method
+ modules[moduleName].forEach(function (method) {
+ if (typeof method === 'string') {
+ method = {
+ name: method
+ }
+ }
+
+ if (!methods[method.name] || ifReplace) {
+ methods[method.name] = method
+ }
+ })
+ }
+}
+
+/**
+ * init app methods
+ */
+export function initMethods (Vm, apis) {
+ const p = Vm.prototype
+
+ for (const apiName in apis) {
+ if (!p.hasOwnProperty(apiName)) {
+ p[apiName] = apis[apiName]
+ }
+ }
+}
+
+/**
+ * get a module of methods for an app instance
+ */
+export function requireModule (app, name) {
+ const methods = nativeModules[name]
+ const target = {}
+ for (const methodName in methods) {
+ Object.defineProperty(target, methodName, {
+ configurable: true,
+ enumerable: true,
+ get: function moduleGetter () {
+ return (...args) => app.callTasks({
+ module: name,
+ method: methodName,
+ args: args
+ })
+ },
+ set: function moduleSetter (value) {
+ if (typeof value === 'function') {
+ return app.callTasks({
+ module: name,
+ method: methodName,
+ args: [value]
+ })
+ }
+ }
+ })
+ }
+ return target
+}
+
+/**
+ * get a custom component options
+ */
+export function requireCustomComponent (app, name) {
+ const { customComponentMap } = app
+ return customComponentMap[name]
+}
+
+/**
+ * register a custom component options
+ */
+export function registerCustomComponent (app, name, def) {
+ const { customComponentMap } = app
+
+ if (customComponentMap[name]) {
+ console.error(`[JS Framework] define a component(${name}) that already exists`)
+ return
+ }
+
+ customComponentMap[name] = def
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/viewport.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/viewport.js b/runtime/frameworks/legacy/app/viewport.js
new file mode 100644
index 0000000..60f8eff
--- /dev/null
+++ b/runtime/frameworks/legacy/app/viewport.js
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export function setViewport (app, configs = {}) {
+ /* istanbul ignore if */
+ if (process.env.NODE_ENV === 'development') {
+ console.debug(`[JS Framework] Set viewport (width: ${configs.width}) for app#${app.id}.`)
+ validateViewport(configs)
+ }
+
+ // Send viewport configs to native
+ if (app && app.callTasks) {
+ return app.callTasks([{
+ module: 'meta',
+ method: 'setViewport',
+ args: [configs]
+ }])
+ }
+
+ /* istanbul ignore next */
+ else if (process.env.NODE_ENV === 'development') {
+ console.warn(`[JS Framework] Can't find "callTasks" method on current app.`)
+ }
+}
+
+/**
+ * Validate the viewport config.
+ * @param {Object} configs
+ */
+export function validateViewport (configs = {}) {
+ const { width } = configs
+ if (width) {
+ if (typeof width !== 'number' && width !== 'device-width') {
+ console.warn(`[JS Framework] Not support to use ${width} as viewport width.`)
+ return false
+ }
+ return true
+ }
+ console.warn('[JS Framework] the viewport config should contain the "width" property.')
+ return false
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/config.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/config.js b/runtime/frameworks/legacy/config.js
new file mode 100644
index 0000000..ebf64d2
--- /dev/null
+++ b/runtime/frameworks/legacy/config.js
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+// @todo: It should be registered by native from `registerComponents()`.
+
+export default {
+ nativeComponentMap: {
+ text: true,
+ image: true,
+ container: true,
+ slider: {
+ type: 'slider',
+ append: 'tree'
+ },
+ cell: {
+ type: 'cell',
+ append: 'tree'
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/LICENSE
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/LICENSE b/runtime/frameworks/legacy/core/LICENSE
new file mode 100644
index 0000000..4645bc4
--- /dev/null
+++ b/runtime/frameworks/legacy/core/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2015 Yuxi Evan You
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/array.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/array.js b/runtime/frameworks/legacy/core/array.js
new file mode 100644
index 0000000..856792f
--- /dev/null
+++ b/runtime/frameworks/legacy/core/array.js
@@ -0,0 +1,100 @@
+/* eslint-disable */
+
+
+import { def } from '../util/index'
+
+const arrayProto = Array.prototype
+export const arrayMethods = Object.create(arrayProto)
+
+/**
+ * Intercept mutating methods and emit events
+ */
+
+;[
+ 'push',
+ 'pop',
+ 'shift',
+ 'unshift',
+ 'splice',
+ 'sort',
+ 'reverse'
+]
+.forEach(function (method) {
+ // cache original method
+ const original = arrayProto[method]
+ def(arrayMethods, method, function mutator () {
+ // avoid leaking arguments:
+ // http://jsperf.com/closure-with-arguments
+ let i = arguments.length
+ const args = new Array(i)
+ while (i--) {
+ args[i] = arguments[i]
+ }
+ const result = original.apply(this, args)
+ const ob = this.__ob__
+ let inserted
+ switch (method) {
+ case 'push':
+ inserted = args
+ break
+ case 'unshift':
+ inserted = args
+ break
+ case 'splice':
+ inserted = args.slice(2)
+ break
+ }
+ if (inserted) ob.observeArray(inserted)
+ // notify change
+ ob.dep.notify()
+ return result
+ })
+})
+
+/**
+ * Swap the element at the given index with a new value
+ * and emits corresponding event.
+ *
+ * @param {Number} index
+ * @param {*} val
+ * @return {*} - replaced element
+ */
+
+def(
+ arrayProto,
+ '$set',
+ function $set (index, val) {
+ console.warn(`[JS Framework] "Array.prototype.$set" is not a standard API,`
+ + ` it will be removed in the next version.`)
+ if (index >= this.length) {
+ this.length = index + 1
+ }
+ return this.splice(index, 1, val)[0]
+ }
+)
+
+/**
+ * Convenience method to remove the element at given index.
+ *
+ * @param {Number} index
+ * @param {*} val
+ */
+
+def(
+ arrayProto,
+ '$remove',
+ function $remove (index) {
+ console.warn(`[JS Framework] "Array.prototype.$remove" is not a standard API,`
+ + ` it will be removed in the next version.`)
+ /* istanbul ignore if */
+ if (!this.length) return
+ /* istanbul ignore else */
+ if (typeof index !== 'number') {
+ index = this.indexOf(index)
+ }
+ /* istanbul ignore else */
+ if (index > -1) {
+ this.splice(index, 1)
+ }
+ }
+)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/dep.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/dep.js b/runtime/frameworks/legacy/core/dep.js
new file mode 100644
index 0000000..6c29bf6
--- /dev/null
+++ b/runtime/frameworks/legacy/core/dep.js
@@ -0,0 +1,80 @@
+/* eslint-disable */
+
+
+import { remove } from '../util/index'
+
+let uid = 0
+
+/**
+ * A dep is an observable that can have multiple
+ * directives subscribing to it.
+ *
+ * @constructor
+ */
+
+export default function Dep () {
+ this.id = uid++
+ this.subs = []
+}
+
+// the current target watcher being evaluated.
+// this is globally unique because there could be only one
+// watcher being evaluated at any time.
+Dep.target = null
+let targetStack = []
+
+export function pushTarget (_target) {
+ if (Dep.target) targetStack.push(Dep.target)
+ Dep.target = _target
+}
+
+export function popTarget () {
+ Dep.target = targetStack.pop()
+}
+
+export function resetTarget () {
+ Dep.target = null
+ targetStack = []
+}
+
+/**
+ * Add a directive subscriber.
+ *
+ * @param {Directive} sub
+ */
+
+Dep.prototype.addSub = function (sub) {
+ this.subs.push(sub)
+}
+
+/**
+ * Remove a directive subscriber.
+ *
+ * @param {Directive} sub
+ */
+
+Dep.prototype.removeSub = function (sub) {
+ remove(this.subs, sub)
+}
+
+/**
+ * Add self as a dependency to the target watcher.
+ */
+
+Dep.prototype.depend = function () {
+ if (Dep.target) {
+ Dep.target.addDep(this)
+ }
+}
+
+/**
+ * Notify all subscribers of a new value.
+ */
+
+Dep.prototype.notify = function () {
+ // stablize the subscriber list first
+ const subs = this.subs.slice()
+ for (let i = 0, l = subs.length; i < l; i++) {
+ subs[i].update()
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/object.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/object.js b/runtime/frameworks/legacy/core/object.js
new file mode 100644
index 0000000..86f83e3
--- /dev/null
+++ b/runtime/frameworks/legacy/core/object.js
@@ -0,0 +1,91 @@
+/* eslint-disable */
+
+
+import * as _ from '../util/index'
+var objProto = Object.prototype
+
+/**
+ * Add a new property to an observed object
+ * and emits corresponding event
+ *
+ * @param {String} key
+ * @param {*} val
+ * @public
+ */
+
+_.define(
+ objProto,
+ '$add',
+ function $add (key, val) {
+ console.warn(`[JS Framework] "Object.prototype.$add" is not a standard API,`
+ + ` it will be removed in the next version.`)
+ if (this.hasOwnProperty(key)) return
+ var ob = this.__ob__
+ if (!ob || _.isReserved(key)) {
+ this[key] = val
+ return
+ }
+ ob.convert(key, val)
+ ob.notify()
+ if (ob.vms) {
+ var i = ob.vms.length
+ while (i--) {
+ var vm = ob.vms[i]
+ vm._proxy(key)
+ // vm._digest() // todo
+ }
+ }
+ }
+)
+
+/**
+ * Set a property on an observed object, calling add to
+ * ensure the property is observed.
+ *
+ * @param {String} key
+ * @param {*} val
+ * @public
+ */
+
+_.define(
+ objProto,
+ '$set',
+ function $set (key, val) {
+ console.warn(`[JS Framework] "Object.prototype.$set" is not a standard API,`
+ + ` it will be removed in the next version.`)
+ this.$add(key, val)
+ this[key] = val
+ }
+)
+
+/**
+ * Deletes a property from an observed object
+ * and emits corresponding event
+ *
+ * @param {String} key
+ * @public
+ */
+
+_.define(
+ objProto,
+ '$delete',
+ function $delete (key) {
+ console.warn(`[JS Framework] "Object.prototype.$delete" is not a standard API,`
+ + ` it will be removed in the next version.`)
+ if (!this.hasOwnProperty(key)) return
+ delete this[key]
+ var ob = this.__ob__
+ if (!ob || _.isReserved(key)) {
+ return
+ }
+ ob.notify()
+ if (ob.vms) {
+ var i = ob.vms.length
+ while (i--) {
+ var vm = ob.vms[i]
+ vm._unproxy(key)
+ // vm._digest() // todo
+ }
+ }
+ }
+)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/observer.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/observer.js b/runtime/frameworks/legacy/core/observer.js
new file mode 100644
index 0000000..103dd0d
--- /dev/null
+++ b/runtime/frameworks/legacy/core/observer.js
@@ -0,0 +1,323 @@
+/* eslint-disable */
+
+
+import Dep from './dep'
+import { arrayMethods } from './array'
+import {
+ def,
+ remove,
+ isObject,
+ isPlainObject,
+ hasProto,
+ hasOwn,
+ isReserved
+} from '../util/index'
+
+const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
+
+/**
+ * Observer class that are attached to each observed
+ * object. Once attached, the observer converts target
+ * object's property keys into getter/setters that
+ * collect dependencies and dispatches updates.
+ *
+ * @param {Array|Object} value
+ * @constructor
+ */
+
+export function Observer (value) {
+ this.value = value
+ this.dep = new Dep()
+ def(value, '__ob__', this)
+ if (Array.isArray(value)) {
+ const augment = hasProto
+ ? protoAugment
+ : copyAugment
+ augment(value, arrayMethods, arrayKeys)
+ this.observeArray(value)
+ } else {
+ this.walk(value)
+ }
+}
+
+// Instance methods
+
+/**
+ * Walk through each property and convert them into
+ * getter/setters. This method should only be called when
+ * value type is Object.
+ *
+ * @param {Object} obj
+ */
+
+Observer.prototype.walk = function (obj) {
+ for (let key in obj) {
+ this.convert(key, obj[key])
+ }
+}
+
+/**
+ * Observe a list of Array items.
+ *
+ * @param {Array} items
+ */
+
+Observer.prototype.observeArray = function (items) {
+ for (let i = 0, l = items.length; i < l; i++) {
+ observe(items[i])
+ }
+}
+
+/**
+ * Convert a property into getter/setter so we can emit
+ * the events when the property is accessed/changed.
+ *
+ * @param {String} key
+ * @param {*} val
+ */
+
+Observer.prototype.convert = function (key, val) {
+ defineReactive(this.value, key, val)
+}
+
+/**
+ * Add an owner vm, so that when $set/$delete mutations
+ * happen we can notify owner vms to proxy the keys and
+ * digest the watchers. This is only called when the object
+ * is observed as an instance's root $data.
+ *
+ * @param {Vue} vm
+ */
+
+Observer.prototype.addVm = function (vm) {
+ (this.vms || (this.vms = [])).push(vm)
+}
+
+/**
+ * Remove an owner vm. This is called when the object is
+ * swapped out as an instance's $data object.
+ *
+ * @param {Vue} vm
+ */
+
+/* istanbul ignore next */
+Observer.prototype.removeVm = function (vm) {
+ remove(this.vms, vm)
+}
+
+// helpers
+
+/**
+ * Augment an target Object or Array by intercepting
+ * the prototype chain using __proto__
+ *
+ * @param {Object|Array} target
+ * @param {Object} src
+ */
+
+function protoAugment (target, src) {
+ /* eslint-disable no-proto */
+ target.__proto__ = src
+ /* eslint-enable no-proto */
+}
+
+/**
+ * Augment an target Object or Array by defining
+ * hidden properties.
+ *
+ * @param {Object|Array} target
+ * @param {Object} proto
+ */
+
+/* istanbul ignore next */
+function copyAugment (target, src, keys) {
+ for (let i = 0, l = keys.length; i < l; i++) {
+ const key = keys[i]
+ def(target, key, src[key])
+ }
+}
+
+/**
+ * Attempt to create an observer instance for a value,
+ * returns the new observer if successfully observed,
+ * or the existing observer if the value already has one.
+ *
+ * @param {*} value
+ * @param {Vue} [vm]
+ * @return {Observer|undefined}
+ * @static
+ */
+
+export function observe (value, vm) {
+ if (!isObject(value)) {
+ return
+ }
+ let ob
+ if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
+ ob = value.__ob__
+ } else if (
+ (Array.isArray(value) || isPlainObject(value)) &&
+ Object.isExtensible(value) &&
+ !value._isVue
+ ) {
+ ob = new Observer(value)
+ }
+ if (ob && vm) {
+ ob.addVm(vm)
+ }
+ return ob
+}
+
+/**
+ * Define a reactive property on an Object.
+ *
+ * @param {Object} obj
+ * @param {String} key
+ * @param {*} val
+ */
+
+export function defineReactive (obj, key, val) {
+ const dep = new Dep()
+
+ const property = Object.getOwnPropertyDescriptor(obj, key)
+ if (property && property.configurable === false) {
+ return
+ }
+
+ // cater for pre-defined getter/setters
+ const getter = property && property.get
+ const setter = property && property.set
+
+ let childOb = observe(val)
+ Object.defineProperty(obj, key, {
+ enumerable: true,
+ configurable: true,
+ get: function reactiveGetter () {
+ const value = getter ? getter.call(obj) : val
+ if (Dep.target) {
+ dep.depend()
+ if (childOb) {
+ childOb.dep.depend()
+ }
+ if (Array.isArray(value)) {
+ for (let e, i = 0, l = value.length; i < l; i++) {
+ e = value[i]
+ e && e.__ob__ && e.__ob__.dep.depend()
+ }
+ }
+ }
+ return value
+ },
+ set: function reactiveSetter (newVal) {
+ const value = getter ? getter.call(obj) : val
+ if (newVal === value) {
+ return
+ }
+ if (setter) {
+ setter.call(obj, newVal)
+ } else {
+ val = newVal
+ }
+ childOb = observe(newVal)
+ dep.notify()
+ }
+ })
+}
+
+/**
+ * Set a property on an object. Adds the new property and
+ * triggers change notification if the property doesn't
+ * already exist.
+ *
+ * @param {Object} obj
+ * @param {String} key
+ * @param {*} val
+ * @public
+ */
+
+/* istanbul ignore next */
+export function set (obj, key, val) {
+ if (Array.isArray(obj)) {
+ return obj.splice(key, 1, val)
+ }
+ if (hasOwn(obj, key)) {
+ obj[key] = val
+ return
+ }
+ if (obj._isVue) {
+ set(obj._data, key, val)
+ return
+ }
+ const ob = obj.__ob__
+ if (!ob) {
+ obj[key] = val
+ return
+ }
+ ob.convert(key, val)
+ ob.dep.notify()
+ if (ob.vms) {
+ let i = ob.vms.length
+ while (i--) {
+ const vm = ob.vms[i]
+ proxy(vm, key)
+ // vm.$forceUpdate()
+ }
+ }
+ return val
+}
+
+/**
+ * Delete a property and trigger change if necessary.
+ *
+ * @param {Object} obj
+ * @param {String} key
+ */
+
+/* istanbul ignore next */
+export function del (obj, key) {
+ if (!hasOwn(obj, key)) {
+ return
+ }
+ delete obj[key]
+ const ob = obj.__ob__
+
+ if (!ob) {
+ if (obj._isVue) {
+ delete obj._data[key]
+ // obj.$forceUpdate()
+ }
+ return
+ }
+ ob.dep.notify()
+ if (ob.vms) {
+ let i = ob.vms.length
+ while (i--) {
+ const vm = ob.vms[i]
+ unproxy(vm, key)
+ // vm.$forceUpdate()
+ }
+ }
+}
+
+const KEY_WORDS = ['$index', '$value', '$event']
+export function proxy (vm, key) {
+ if (KEY_WORDS.indexOf(key) > -1 || !isReserved(key)) {
+ Object.defineProperty(vm, key, {
+ configurable: true,
+ enumerable: true,
+ get: function proxyGetter () {
+ return vm._data[key]
+ },
+ set: function proxySetter (val) {
+ vm._data[key] = val
+ }
+ })
+ }
+}
+
+/* istanbul ignore next */
+export function unproxy (vm, key) {
+ if (!isReserved(key)) {
+ delete vm[key]
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/state.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/state.js b/runtime/frameworks/legacy/core/state.js
new file mode 100644
index 0000000..5300dbf
--- /dev/null
+++ b/runtime/frameworks/legacy/core/state.js
@@ -0,0 +1,92 @@
+/* eslint-disable */
+
+
+import Watcher from './watcher'
+import Dep from './dep'
+import {
+ observe,
+ proxy,
+ unproxy
+} from './observer'
+import {
+ isPlainObject,
+ bind
+} from '../util/index'
+
+export function initState (vm) {
+ vm._watchers = []
+ initData(vm)
+ initComputed(vm)
+ initMethods(vm)
+}
+
+export function initData (vm) {
+ let data = vm._data
+
+ if (!isPlainObject(data)) {
+ data = {}
+ }
+ // proxy data on instance
+ const keys = Object.keys(data)
+ let i = keys.length
+ while (i--) {
+ proxy(vm, keys[i])
+ }
+ // observe data
+ observe(data, vm)
+}
+
+/* istanbul ignore next */
+function noop () {
+}
+
+export function initComputed (vm) {
+ const computed = vm._computed
+ if (computed) {
+ for (let key in computed) {
+ const userDef = computed[key]
+ const def = {
+ enumerable: true,
+ configurable: true
+ }
+ if (typeof userDef === 'function') {
+ def.get = makeComputedGetter(userDef, vm)
+ def.set = noop
+ } else {
+ def.get = userDef.get
+ ? userDef.cache !== false
+ ? makeComputedGetter(userDef.get, vm)
+ : bind(userDef.get, vm)
+ : noop
+ def.set = userDef.set
+ ? bind(userDef.set, vm)
+ : noop
+ }
+ Object.defineProperty(vm, key, def)
+ }
+ }
+}
+
+function makeComputedGetter (getter, owner) {
+ const watcher = new Watcher(owner, getter, null, {
+ lazy: true
+ })
+ return function computedGetter () {
+ if (watcher.dirty) {
+ watcher.evaluate()
+ }
+ if (Dep.target) {
+ watcher.depend()
+ }
+ return watcher.value
+ }
+}
+
+export function initMethods (vm) {
+ const methods = vm._methods
+ if (methods) {
+ for (let key in methods) {
+ vm[key] = methods[key]
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/core/watcher.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/core/watcher.js b/runtime/frameworks/legacy/core/watcher.js
new file mode 100644
index 0000000..cfd6370
--- /dev/null
+++ b/runtime/frameworks/legacy/core/watcher.js
@@ -0,0 +1,254 @@
+/* eslint-disable */
+
+
+import Dep, { pushTarget, popTarget } from './dep'
+// import { pushWatcher } from './batcher'
+import {
+ remove,
+ extend,
+ isObject,
+ createNewSet
+ // _Set as Set
+} from '../util/index'
+
+let uid = 0
+
+/**
+ * A watcher parses an expression, collects dependencies,
+ * and fires callback when the expression value changes.
+ * This is used for both the $watch() api and directives.
+ *
+ * @param {Vue} vm
+ * @param {String|Function} expOrFn
+ * @param {Function} cb
+ * @param {Object} options
+ * - {Array} filters
+ * - {Boolean} twoWay
+ * - {Boolean} deep
+ * - {Boolean} user
+ * - {Boolean} sync
+ * - {Boolean} lazy
+ * - {Function} [preProcess]
+ * - {Function} [postProcess]
+ * @constructor
+ */
+
+export default function Watcher (vm, expOrFn, cb, options) {
+ // mix in options
+ if (options) {
+ extend(this, options)
+ }
+ const isFn = typeof expOrFn === 'function'
+ this.vm = vm
+ vm._watchers.push(this)
+ this.expression = expOrFn
+ this.cb = cb
+ this.id = ++uid // uid for batching
+ this.active = true
+ this.dirty = this.lazy // for lazy watchers
+ this.deps = []
+ this.newDeps = []
+ this.depIds = createNewSet() // new Set()
+ this.newDepIds = createNewSet() // new Set()
+ // parse expression for getter
+ if (isFn) {
+ this.getter = expOrFn
+ }
+ this.value = this.lazy
+ ? undefined
+ : this.get()
+ // state for avoiding false triggers for deep and Array
+ // watchers during vm._digest()
+ this.queued = this.shallow = false
+}
+
+/**
+ * Evaluate the getter, and re-collect dependencies.
+ */
+
+Watcher.prototype.get = function () {
+ pushTarget(this)
+ const value = this.getter.call(this.vm, this.vm)
+ // "touch" every property so they are all tracked as
+ // dependencies for deep watching
+ if (this.deep) {
+ traverse(value)
+ }
+ popTarget()
+ this.cleanupDeps()
+ return value
+}
+
+/**
+ * Add a dependency to this directive.
+ *
+ * @param {Dep} dep
+ */
+
+Watcher.prototype.addDep = function (dep) {
+ const id = dep.id
+ if (!this.newDepIds.has(id)) {
+ this.newDepIds.add(id)
+ this.newDeps.push(dep)
+ if (!this.depIds.has(id)) {
+ dep.addSub(this)
+ }
+ }
+}
+
+/**
+ * Clean up for dependency collection.
+ */
+
+Watcher.prototype.cleanupDeps = function () {
+ let i = this.deps.length
+ while (i--) {
+ const dep = this.deps[i]
+ if (!this.newDepIds.has(dep.id)) {
+ dep.removeSub(this)
+ }
+ }
+ let tmp = this.depIds
+ this.depIds = this.newDepIds
+ this.newDepIds = tmp
+ this.newDepIds.clear()
+ tmp = this.deps
+ this.deps = this.newDeps
+ this.newDeps = tmp
+ this.newDeps.length = 0
+}
+
+/**
+ * Subscriber interface.
+ * Will be called when a dependency changes.
+ *
+ * @param {Boolean} shallow
+ */
+
+Watcher.prototype.update = function (shallow) {
+ if (this.lazy) {
+ this.dirty = true
+ } else {
+ this.run()
+ }
+ // } else if (this.sync) {
+ // this.run()
+ // } else {
+ // // if queued, only overwrite shallow with non-shallow,
+ // // but not the other way around.
+ // this.shallow = this.queued
+ // ? shallow
+ // ? this.shallow
+ // : false
+ // : !!shallow
+ // this.queued = true
+ // pushWatcher(this)
+ // }
+}
+
+/**
+ * Batcher job interface.
+ * Will be called by the batcher.
+ */
+
+Watcher.prototype.run = function () {
+ if (this.active) {
+ const value = this.get()
+ if (
+ value !== this.value ||
+ // Deep watchers and watchers on Object/Arrays should fire even
+ // when the value is the same, because the value may
+ // have mutated; but only do so if this is a
+ // non-shallow update (caused by a vm digest).
+ ((isObject(value) || this.deep) && !this.shallow)
+ ) {
+ // set new value
+ const oldValue = this.value
+ this.value = value
+ this.cb.call(this.vm, value, oldValue)
+ }
+ this.queued = this.shallow = false
+ }
+}
+
+/**
+ * Evaluate the value of the watcher.
+ * This only gets called for lazy watchers.
+ */
+
+Watcher.prototype.evaluate = function () {
+ this.value = this.get()
+ this.dirty = false
+}
+
+/**
+ * Depend on all deps collected by this watcher.
+ */
+
+Watcher.prototype.depend = function () {
+ let i = this.deps.length
+ while (i--) {
+ this.deps[i].depend()
+ }
+}
+
+/**
+ * Remove self from all dependencies' subcriber list.
+ */
+
+Watcher.prototype.teardown = function () {
+ if (this.active) {
+ // remove self from vm's watcher list
+ // this is a somewhat expensive operation so we skip it
+ // if the vm is being destroyed or is performing a v-for
+ // re-render (the watcher list is then filtered by v-for).
+ if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
+ remove(this.vm._watchers, this)
+ }
+ let i = this.deps.length
+ while (i--) {
+ this.deps[i].removeSub(this)
+ }
+ this.active = false
+ this.vm = this.cb = this.value = null
+ }
+}
+
+/**
+ * Recrusively traverse an object to evoke all converted
+ * getters, so that every nested property inside the object
+ * is collected as a "deep" dependency.
+ *
+ * @param {*} val
+ * @param {Set} seen
+ */
+
+const seenObjects = createNewSet() // new Set()
+/* istanbul ignore next */
+function traverse (val, seen) {
+ let i, keys, isA, isO
+ if (!seen) {
+ seen = seenObjects
+ seen.clear()
+ }
+ isA = Array.isArray(val)
+ isO = isObject(val)
+ if (isA || isO) {
+ if (val.__ob__) {
+ const depId = val.__ob__.dep.id
+ if (seen.has(depId)) {
+ return
+ } else {
+ seen.add(depId)
+ }
+ }
+ if (isA) {
+ i = val.length
+ while (i--) traverse(val[i], seen)
+ } else if (isO) {
+ keys = Object.keys(val)
+ i = keys.length
+ while (i--) traverse(val[keys[i]], seen)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/index.js b/runtime/frameworks/legacy/index.js
new file mode 100644
index 0000000..366ecb3
--- /dev/null
+++ b/runtime/frameworks/legacy/index.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview Weex framework entry.
+ */
+
+import * as methods from './api/methods'
+
+import Vm from './vm'
+export { createInstance } from './static/create'
+export { init, refreshInstance, destroyInstance } from './static/life'
+import { registerComponents, registerModules, registerMethods } from './static/register'
+export { receiveTasks } from './static/bridge'
+export { getRoot } from './static/misc'
+
+// register special methods for Weex framework
+registerMethods(methods)
+
+/**
+ * Prevent modification of Vm and Vm.prototype
+ */
+Object.freeze(Vm)
+
+export { registerComponents, registerModules, registerMethods }
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/static/bridge.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/static/bridge.js b/runtime/frameworks/legacy/static/bridge.js
new file mode 100644
index 0000000..665b1ad
--- /dev/null
+++ b/runtime/frameworks/legacy/static/bridge.js
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { instanceMap } from './map'
+import {
+ fireEvent,
+ callback
+} from '../app/ctrl/index'
+
+const jsHandlers = {
+ fireEvent: (id, ...args) => {
+ return fireEvent(instanceMap[id], ...args)
+ },
+ callback: (id, ...args) => {
+ return callback(instanceMap[id], ...args)
+ }
+}
+
+/**
+ * Accept calls from native (event or callback).
+ *
+ * @param {string} id
+ * @param {array} tasks list with `method` and `args`
+ */
+export function receiveTasks (id, tasks) {
+ const instance = instanceMap[id]
+ if (instance && Array.isArray(tasks)) {
+ const results = []
+ tasks.forEach((task) => {
+ const handler = jsHandlers[task.method]
+ const args = [...task.args]
+ /* istanbul ignore else */
+ if (typeof handler === 'function') {
+ args.unshift(id)
+ results.push(handler(...args))
+ }
+ })
+ return results
+ }
+ return new Error(`invalid instance id "${id}" or tasks`)
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/static/create.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/static/create.js b/runtime/frameworks/legacy/static/create.js
new file mode 100644
index 0000000..1c963b3
--- /dev/null
+++ b/runtime/frameworks/legacy/static/create.js
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import App from '../app/index'
+import { instanceMap } from './map'
+import { init as initApp } from '../app/ctrl/index'
+import { resetTarget } from '../core/dep'
+
+/**
+ * Create a Weex instance.
+ *
+ * @param {string} id
+ * @param {string} code
+ * @param {object} options
+ * option `HAS_LOG` enable print log
+ * @param {object} data
+ * @param {object} info { created, ... services }
+ */
+export function createInstance (id, code, options, data, info) {
+ const { services } = info || {}
+ resetTarget()
+ let instance = instanceMap[id]
+ /* istanbul ignore else */
+ options = options || {}
+ let result
+ /* istanbul ignore else */
+ if (!instance) {
+ instance = new App(id, options)
+ instanceMap[id] = instance
+ result = initApp(instance, code, data, services)
+ }
+ else {
+ result = new Error(`invalid instance id "${id}"`)
+ }
+ return (result instanceof Error) ? result : instance
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/static/life.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/static/life.js b/runtime/frameworks/legacy/static/life.js
new file mode 100644
index 0000000..9cb8abc
--- /dev/null
+++ b/runtime/frameworks/legacy/static/life.js
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import config from '../config'
+import {
+ refresh,
+ destroy
+} from '../app/ctrl/index'
+import { instanceMap } from './map'
+import { resetTarget } from '../core/dep'
+
+/**
+ * Init config informations for Weex framework
+ * @param {object} cfg
+ */
+export function init (cfg) {
+ config.Document = cfg.Document
+ config.Element = cfg.Element
+ config.Comment = cfg.Comment
+ config.sendTasks = cfg.sendTasks
+ config.Listener = cfg.Listener
+}
+
+/**
+ * Refresh a Weex instance with data.
+ *
+ * @param {string} id
+ * @param {object} data
+ */
+export function refreshInstance (id, data) {
+ const instance = instanceMap[id]
+ let result
+ /* istanbul ignore else */
+ if (instance) {
+ result = refresh(instance, data)
+ }
+ else {
+ result = new Error(`invalid instance id "${id}"`)
+ }
+ return result
+}
+
+/**
+ * Destroy a Weex instance.
+ * @param {string} id
+ */
+export function destroyInstance (id) {
+ // Markup some global state in native side
+ if (typeof markupState === 'function') {
+ markupState()
+ }
+
+ resetTarget()
+ const instance = instanceMap[id]
+ /* istanbul ignore else */
+ if (!instance) {
+ return new Error(`invalid instance id "${id}"`)
+ }
+ destroy(instance)
+ delete instanceMap[id]
+ // notifyContextDisposed is used to tell v8 to do a full GC,
+ // but this would have a negative performance impact on weex,
+ // because all the inline cache in v8 would get cleared
+ // during a full GC.
+ // To take care of both memory and performance, just tell v8
+ // to do a full GC every eighteen times.
+ const idNum = Math.round(id)
+ const round = 18
+ if (idNum > 0) {
+ const remainder = idNum % round
+ if (!remainder && typeof notifyTrimMemory === 'function') {
+ notifyTrimMemory()
+ }
+ }
+ return instanceMap
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/static/map.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/static/map.js b/runtime/frameworks/legacy/static/map.js
new file mode 100644
index 0000000..8c94ef4
--- /dev/null
+++ b/runtime/frameworks/legacy/static/map.js
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export const instanceMap = {}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/static/misc.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/static/misc.js b/runtime/frameworks/legacy/static/misc.js
new file mode 100644
index 0000000..afbc5e3
--- /dev/null
+++ b/runtime/frameworks/legacy/static/misc.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { instanceMap } from './map'
+import {
+ getRootElement
+} from '../app/ctrl/index'
+
+/**
+ * Get a whole element tree of an instance for debugging.
+ * @param {string} id
+ * @return {object} a virtual dom tree
+ */
+export function getRoot (id) {
+ const instance = instanceMap[id]
+ let result
+ /* istanbul ignore else */
+ if (instance) {
+ result = getRootElement(instance)
+ }
+ else {
+ result = new Error(`invalid instance id "${id}"`)
+ }
+ return result
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/static/register.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/static/register.js b/runtime/frameworks/legacy/static/register.js
new file mode 100644
index 0000000..f21df89
--- /dev/null
+++ b/runtime/frameworks/legacy/static/register.js
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import Vm from '../vm/index'
+import config from '../config'
+import {
+ initModules,
+ initMethods
+} from '../app/register'
+
+const {
+ nativeComponentMap
+} = config
+
+/**
+ * Register the name of each native component.
+ * @param {array} components array of name
+ */
+export function registerComponents (components) {
+ if (Array.isArray(components)) {
+ components.forEach(function register (name) {
+ /* istanbul ignore if */
+ if (!name) {
+ return
+ }
+ if (typeof name === 'string') {
+ nativeComponentMap[name] = true
+ }
+ /* istanbul ignore else */
+ else if (typeof name === 'object' && typeof name.type === 'string') {
+ nativeComponentMap[name.type] = name
+ }
+ })
+ }
+}
+
+/**
+ * Register the name and methods of each module.
+ * @param {object} modules a object of modules
+ */
+export function registerModules (modules) {
+ /* istanbul ignore else */
+ if (typeof modules === 'object') {
+ initModules(modules)
+ }
+}
+
+/**
+ * Register the name and methods of each api.
+ * @param {object} apis a object of apis
+ */
+export function registerMethods (methods) {
+ /* istanbul ignore else */
+ if (typeof methods === 'object') {
+ initMethods(Vm, methods)
+ }
+}
+
+// @todo: Hack for this framework only. Will be re-designed or removed later.
+global.registerMethods = registerMethods
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/util/LICENSE
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/util/LICENSE b/runtime/frameworks/legacy/util/LICENSE
new file mode 100644
index 0000000..4645bc4
--- /dev/null
+++ b/runtime/frameworks/legacy/util/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2013-2015 Yuxi Evan You
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/util/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/util/index.js b/runtime/frameworks/legacy/util/index.js
new file mode 100644
index 0000000..0d716f4
--- /dev/null
+++ b/runtime/frameworks/legacy/util/index.js
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export {
+ extend,
+ def,
+ remove,
+ hasOwn,
+ bind,
+ toArray,
+ isObject,
+ isPlainObject
+} from './shared'
+
+/**
+ * Check if a string starts with $ or _
+ *
+ * @param {String} str
+ * @return {Boolean}
+ */
+
+export function isReserved (str) {
+ const c = (str + '').charCodeAt(0)
+ return c === 0x24 || c === 0x5F
+}
+
+// can we use __proto__?
+export const hasProto = '__proto__' in {}
+
+let _Set
+/* istanbul ignore next */
+if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
+ // use native Set when available.
+ _Set = Set
+}
+else {
+ // a non-standard Set polyfill that only works with primitive keys.
+ _Set = function () {
+ this.set = Object.create(null)
+ }
+ _Set.prototype.has = function (key) {
+ return this.set[key] !== undefined
+ }
+ _Set.prototype.add = function (key) {
+ if (key == null || this.set[key]) {
+ return
+ }
+ this.set[key] = 1
+ }
+ _Set.prototype.clear = function () {
+ this.set = Object.create(null)
+ }
+}
+
+export { _Set }
+
+/**
+ * Polyfill in iOS7 by native because the JavaScript polyfill has memory problem.
+ * @return {object}
+ */
+
+export function createNewSet () {
+ /* istanbul ignore next */
+ /* eslint-disable */
+ if (typeof nativeSet === 'object') {
+ return nativeSet.create()
+ }
+ /* eslint-enable */
+ return new _Set()
+}
+
+/**
+ * Create a cached version of a pure function.
+ *
+ * @param {Function} fn
+ * @return {Function}
+ */
+
+export function cached (fn) {
+ const cache = Object.create(null)
+ return function cachedFn (str) {
+ const hit = cache[str]
+ return hit || (cache[str] = fn(str))
+ }
+}
+
+/**
+ * Camelize a hyphen-delmited string.
+ *
+ * @param {String} str
+ * @return {String}
+ */
+
+const camelizeRE = /-(\w)/g
+export const camelize = cached(str => {
+ return str.replace(camelizeRE, toUpper)
+})
+
+function toUpper (_, c) {
+ return c ? c.toUpperCase() : ''
+}
+
+/**
+ * Hyphenate a camelCase string.
+ *
+ * @param {String} str
+ * @return {String}
+ */
+
+const hyphenateRE = /([a-z\d])([A-Z])/g
+export const hyphenate = cached(str => {
+ return str
+ .replace(hyphenateRE, '$1-$2')
+ .toLowerCase()
+})
+
+export function typof (v) {
+ const s = Object.prototype.toString.call(v)
+ return s.substring(8, s.length - 1).toLowerCase()
+}
+
+// weex name rules
+
+const WEEX_COMPONENT_REG = /^@weex-component\//
+const WEEX_MODULE_REG = /^@weex-module\//
+const NORMAL_MODULE_REG = /^\.{1,2}\//
+const JS_SURFIX_REG = /\.js$/
+
+export const isWeexComponent = name => !!name.match(WEEX_COMPONENT_REG)
+export const isWeexModule = name => !!name.match(WEEX_MODULE_REG)
+export const isNormalModule = name => !!name.match(NORMAL_MODULE_REG)
+export const isNpmModule = name => !isWeexComponent(name) && !isWeexModule(name) && !isNormalModule(name)
+
+export function removeWeexPrefix (str) {
+ const result = str.replace(WEEX_COMPONENT_REG, '').replace(WEEX_MODULE_REG, '')
+ return result
+}
+
+export function removeJSSurfix (str) {
+ return str.replace(JS_SURFIX_REG, '')
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/util/shared.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/util/shared.js b/runtime/frameworks/legacy/util/shared.js
new file mode 100644
index 0000000..faf76e1
--- /dev/null
+++ b/runtime/frameworks/legacy/util/shared.js
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * Mix properties into target object.
+ *
+ * @param {Object} to
+ * @param {Object} from
+ */
+
+function extend (target, ...src) {
+ /* istanbul ignore else */
+ if (typeof Object.assign === 'function') {
+ Object.assign(target, ...src)
+ }
+ else {
+ const first = src.shift()
+ for (const key in first) {
+ target[key] = first[key]
+ }
+ if (src.length) {
+ extend(target, ...src)
+ }
+ }
+ return target
+}
+
+/**
+ * Define a property.
+ *
+ * @param {Object} obj
+ * @param {String} key
+ * @param {*} val
+ * @param {Boolean} [enumerable]
+ */
+
+function def (obj, key, val, enumerable) {
+ Object.defineProperty(obj, key, {
+ value: val,
+ enumerable: !!enumerable,
+ writable: true,
+ configurable: true
+ })
+}
+
+/**
+ * Remove an item from an array
+ *
+ * @param {Array} arr
+ * @param {*} item
+ */
+
+function remove (arr, item) {
+ if (arr.length) {
+ const index = arr.indexOf(item)
+ if (index > -1) {
+ return arr.splice(index, 1)
+ }
+ }
+}
+
+/**
+ * Check whether the object has the property.
+ *
+ * @param {Object} obj
+ * @param {String} key
+ * @return {Boolean}
+ */
+const hasOwnProperty = Object.prototype.hasOwnProperty
+function hasOwn (obj, key) {
+ return hasOwnProperty.call(obj, key)
+}
+
+/**
+ * Simple bind, faster than native
+ *
+ * @param {Function} fn
+ * @param {Object} ctx
+ * @return {Function}
+ */
+
+function bind (fn, ctx) {
+ return function (a) {
+ const l = arguments.length
+ return l
+ ? l > 1
+ ? fn.apply(ctx, arguments)
+ : fn.call(ctx, a)
+ : fn.call(ctx)
+ }
+}
+
+/**
+ * Convert an Array-like object to a real Array.
+ *
+ * @param {Array-like} list
+ * @param {Number} [start] - start index
+ * @return {Array}
+ */
+
+function toArray (list, start) {
+ start = start || 0
+ let i = list.length - start
+ const ret = new Array(i)
+ while (i--) {
+ ret[i] = list[i + start]
+ }
+ return ret
+}
+
+/**
+ * Quick object check - this is primarily used to tell
+ * Objects from primitive values when we know the value
+ * is a JSON-compliant type.
+ *
+ * @param {*} obj
+ * @return {Boolean}
+ */
+
+function isObject (obj) {
+ return obj !== null && typeof obj === 'object'
+}
+
+/**
+ * Strict object type check. Only returns true
+ * for plain JavaScript objects.
+ *
+ * @param {*} obj
+ * @return {Boolean}
+ */
+
+const toString = Object.prototype.toString
+const OBJECT_STRING = '[object Object]'
+function isPlainObject (obj) {
+ return toString.call(obj) === OBJECT_STRING
+}
+
+export {
+ extend,
+ def,
+ remove,
+ hasOwn,
+ bind,
+ toArray,
+ isObject,
+ isPlainObject
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/vm/compiler.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/vm/compiler.js b/runtime/frameworks/legacy/vm/compiler.js
new file mode 100644
index 0000000..ffca01f
--- /dev/null
+++ b/runtime/frameworks/legacy/vm/compiler.js
@@ -0,0 +1,636 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * ViewModel template parser & data-binding process
+ */
+
+import {
+ extend,
+ isObject,
+ bind
+} from '../util/index'
+import {
+ initData,
+ initComputed
+} from '../core/state'
+import {
+ bindElement,
+ setId,
+ bindSubVm,
+ bindSubVmAfterInitialized,
+ applyNaitveComponentOptions,
+ watch
+} from './directive'
+import {
+ createBlock,
+ createBody,
+ createElement,
+ attachTarget,
+ moveTarget,
+ removeTarget
+} from './dom-helper'
+
+/**
+ * build()
+ * compile(template, parentNode)
+ * if (type is content) create contentNode
+ * else if (dirs have v-for) foreach -> create context
+ * -> compile(templateWithoutFor, parentNode): diff(list) onchange
+ * else if (dirs have v-if) assert
+ * -> compile(templateWithoutIf, parentNode): toggle(shown) onchange
+ * else if (type is dynamic)
+ * -> compile(templateWithoutDynamicType, parentNode): watch(type) onchange
+ * else if (type is custom)
+ * addChildVm(vm, parentVm)
+ * build(externalDirs)
+ * foreach childNodes -> compile(childNode, template)
+ * else if (type is native)
+ * set(dirs): update(id/attr/style/class) onchange
+ * append(template, parentNode)
+ * foreach childNodes -> compile(childNode, template)
+ */
+export function build (vm) {
+ const opt = vm._options || {}
+ const template = opt.template || {}
+
+ if (opt.replace) {
+ if (template.children && template.children.length === 1) {
+ compile(vm, template.children[0], vm._parentEl)
+ }
+ else {
+ compile(vm, template.children, vm._parentEl)
+ }
+ }
+ else {
+ compile(vm, template, vm._parentEl)
+ }
+
+ console.debug(`[JS Framework] "ready" lifecycle in Vm(${vm._type})`)
+ vm.$emit('hook:ready')
+ vm._ready = true
+}
+
+/**
+ * Generate elements by child or children and append to parent elements.
+ * Root element info would be merged if has. The first argument may be an array
+ * if the root element with options.replace has not only one child.
+ *
+ * @param {object|array} target
+ * @param {object} dest
+ * @param {object} meta
+ */
+function compile (vm, target, dest, meta) {
+ const app = vm._app || {}
+
+ if (app.lastSignal === -1) {
+ return
+ }
+
+ if (target.attr && target.attr.hasOwnProperty('static')) {
+ vm._static = true
+ }
+
+ if (targetIsFragment(target)) {
+ compileFragment(vm, target, dest, meta)
+ return
+ }
+ meta = meta || {}
+ if (targetIsContent(target)) {
+ console.debug('[JS Framework] compile "content" block by', target)
+ vm._content = createBlock(vm, dest)
+ return
+ }
+
+ if (targetNeedCheckRepeat(target, meta)) {
+ console.debug('[JS Framework] compile "repeat" logic by', target)
+ if (dest.type === 'document') {
+ console.warn('[JS Framework] The root element does\'t support `repeat` directive!')
+ }
+ else {
+ compileRepeat(vm, target, dest)
+ }
+ return
+ }
+ if (targetNeedCheckShown(target, meta)) {
+ console.debug('[JS Framework] compile "if" logic by', target)
+ if (dest.type === 'document') {
+ console.warn('[JS Framework] The root element does\'t support `if` directive!')
+ }
+ else {
+ compileShown(vm, target, dest, meta)
+ }
+ return
+ }
+ const typeGetter = meta.type || target.type
+ if (targetNeedCheckType(typeGetter, meta)) {
+ compileType(vm, target, dest, typeGetter, meta)
+ return
+ }
+ const type = typeGetter
+ const component = targetIsComposed(vm, target, type)
+ if (component) {
+ console.debug('[JS Framework] compile composed component by', target)
+ compileCustomComponent(vm, component, target, dest, type, meta)
+ return
+ }
+ console.debug('[JS Framework] compile native component by', target)
+ compileNativeComponent(vm, target, dest, type)
+}
+
+/**
+ * Check if target is a fragment (an array).
+ *
+ * @param {object} target
+ * @return {boolean}
+ */
+function targetIsFragment (target) {
+ return Array.isArray(target)
+}
+
+/**
+ * Check if target type is content/slot.
+ *
+ * @param {object} target
+ * @return {boolean}
+ */
+function targetIsContent (target) {
+ return target.type === 'content' || target.type === 'slot'
+}
+
+/**
+ * Check if target need to compile by a list.
+ *
+ * @param {object} target
+ * @param {object} meta
+ * @return {boolean}
+ */
+function targetNeedCheckRepeat (target, meta) {
+ return !meta.hasOwnProperty('repeat') && target.repeat
+}
+
+/**
+ * Check if target need to compile by a boolean value.
+ *
+ * @param {object} target
+ * @param {object} meta
+ * @return {boolean}
+ */
+function targetNeedCheckShown (target, meta) {
+ return !meta.hasOwnProperty('shown') && target.shown
+}
+
+/**
+ * Check if target need to compile by a dynamic type.
+ *
+ * @param {string|function} typeGetter
+ * @param {object} meta
+ * @return {boolean}
+ */
+function targetNeedCheckType (typeGetter, meta) {
+ return (typeof typeGetter === 'function') && !meta.hasOwnProperty('type')
+}
+
+/**
+ * Check if this kind of component is composed.
+ *
+ * @param {string} type
+ * @return {boolean}
+ */
+function targetIsComposed (vm, target, type) {
+ let component
+ if (vm._app && vm._app.customComponentMap) {
+ component = vm._app.customComponentMap[type]
+ }
+ if (vm._options && vm._options.components) {
+ component = vm._options.components[type]
+ }
+ if (target.component) {
+ component = component || {}
+ }
+ return component
+}
+
+/**
+ * Compile a list of targets.
+ *
+ * @param {object} target
+ * @param {object} dest
+ * @param {object} meta
+ */
+function compileFragment (vm, target, dest, meta) {
+ const fragBlock = createBlock(vm, dest)
+ target.forEach((child) => {
+ compile(vm, child, fragBlock, meta)
+ })
+}
+
+/**
+ * Compile a target with repeat directive.
+ *
+ * @param {object} target
+ * @param {object} dest
+ */
+function compileRepeat (vm, target, dest) {
+ const repeat = target.repeat
+ const oldStyle = typeof repeat === 'function'
+ let getter = repeat.getter || repeat.expression || repeat
+ if (typeof getter !== 'function') {
+ getter = function () { return [] }
+ }
+ const key = repeat.key || '$index'
+ const value = repeat.value || '$value'
+ const trackBy = repeat.trackBy || target.trackBy ||
+ (target.attr && target.attr.trackBy)
+
+ const fragBlock = createBlock(vm, dest)
+ fragBlock.children = []
+ fragBlock.data = []
+ fragBlock.vms = []
+
+ bindRepeat(vm, target, fragBlock, { getter, key, value, trackBy, oldStyle })
+}
+
+/**
+ * Compile a target with if directive.
+ *
+ * @param {object} target
+ * @param {object} dest
+ * @param {object} meta
+ */
+function compileShown (vm, target, dest, meta) {
+ const newMeta = { shown: true }
+ const fragBlock = createBlock(vm, dest)
+
+ if (dest.element && dest.children) {
+ dest.children.push(fragBlock)
+ }
+
+ if (meta.repeat) {
+ newMeta.repeat = meta.repeat
+ }
+
+ bindShown(vm, target, fragBlock, newMeta)
+}
+
+/**
+ * Compile a target with dynamic component type.
+ *
+ * @param {object} target
+ * @param {object} dest
+ * @param {function} typeGetter
+ */
+function compileType (vm, target, dest, typeGetter, meta) {
+ const type = typeGetter.call(vm)
+ const newMeta = extend({ type }, meta)
+ const fragBlock = createBlock(vm, dest)
+
+ if (dest.element && dest.children) {
+ dest.children.push(fragBlock)
+ }
+
+ watch(vm, typeGetter, (value) => {
+ const newMeta = extend({ type: value }, meta)
+ removeTarget(vm, fragBlock, true)
+ compile(vm, target, fragBlock, newMeta)
+ })
+
+ compile(vm, target, fragBlock, newMeta)
+}
+
+/**
+ * Compile a composed component.
+ *
+ * @param {object} target
+ * @param {object} dest
+ * @param {string} type
+ */
+function compileCustomComponent (vm, component, target, dest, type, meta) {
+ const Ctor = vm.constructor
+ const subVm = new Ctor(type, component, vm, dest, undefined, {
+ 'hook:init': function () {
+ if (vm._static) {
+ this._static = vm._static
+ }
+ setId(vm, null, target.id, this)
+ // bind template earlier because of lifecycle issues
+ this._externalBinding = {
+ parent: vm,
+ template: target
+ }
+ },
+ 'hook:created': function () {
+ bindSubVm(vm, this, target, meta.repeat)
+ },
+ 'hook:ready': function () {
+ if (this._content) {
+ compileChildren(vm, target, this._content)
+ }
+ }
+ })
+ bindSubVmAfterInitialized(vm, subVm, target, dest)
+}
+
+/**
+ * Generate element from template and attach to the dest if needed.
+ * The time to attach depends on whether the mode status is node or tree.
+ *
+ * @param {object} template
+ * @param {object} dest
+ * @param {string} type
+ */
+function compileNativeComponent (vm, template, dest, type) {
+ applyNaitveComponentOptions(template)
+
+ let element
+ if (dest.ref === '_documentElement') {
+ // if its parent is documentElement then it's a body
+ console.debug(`[JS Framework] compile to create body for ${type}`)
+ element = createBody(vm, type)
+ }
+ else {
+ console.debug(`[JS Framework] compile to create element for ${type}`)
+ element = createElement(vm, type)
+ }
+
+ if (!vm._rootEl) {
+ vm._rootEl = element
+ // bind event earlier because of lifecycle issues
+ const binding = vm._externalBinding || {}
+ const target = binding.template
+ const parentVm = binding.parent
+ if (target && target.events && parentVm && element) {
+ for (const type in target.events) {
+ const handler = parentVm[target.events[type]]
+ if (handler) {
+ element.addEvent(type, bind(handler, parentVm))
+ }
+ }
+ }
+ }
+
+ bindElement(vm, element, template)
+
+ if (template.attr && template.attr.append) { // backward, append prop in attr
+ template.append = template.attr.append
+ }
+
+ if (template.append) { // give the append attribute for ios adaptation
+ element.attr = element.attr || {}
+ element.attr.append = template.append
+ }
+
+ const treeMode = template.append === 'tree'
+ const app = vm._app || {}
+ if (app.lastSignal !== -1 && !treeMode) {
+ console.debug('[JS Framework] compile to append single node for', element)
+ app.lastSignal = attachTarget(vm, element, dest)
+ }
+ if (app.lastSignal !== -1) {
+ compileChildren(vm, template, element)
+ }
+ if (app.lastSignal !== -1 && treeMode) {
+ console.debug('[JS Framework] compile to append whole tree for', element)
+ app.lastSignal = attachTarget(vm, element, dest)
+ }
+}
+
+/**
+ * Set all children to a certain parent element.
+ *
+ * @param {object} template
+ * @param {object} dest
+ */
+function compileChildren (vm, template, dest) {
+ const app = vm._app || {}
+ const children = template.children
+ if (children && children.length) {
+ children.every((child) => {
+ compile(vm, child, dest)
+ return app.lastSignal !== -1
+ })
+ }
+}
+
+/**
+ * Watch the list update and refresh the changes.
+ *
+ * @param {object} target
+ * @param {object} fragBlock {vms, data, children}
+ * @param {object} info {getter, key, value, trackBy, oldStyle}
+ */
+function bindRepeat (vm, target, fragBlock, info) {
+ const vms = fragBlock.vms
+ const children = fragBlock.children
+ const { getter, trackBy, oldStyle } = info
+ const keyName = info.key
+ const valueName = info.value
+
+ function compileItem (item, index, context) {
+ let mergedData
+ if (oldStyle) {
+ mergedData = item
+ if (isObject(item)) {
+ mergedData[keyName] = index
+ if (!mergedData.hasOwnProperty('INDEX')) {
+ Object.defineProperty(mergedData, 'INDEX', {
+ value: () => {
+ console.warn('[JS Framework] "INDEX" in repeat is deprecated, ' +
+ 'please use "$index" instead')
+ }
+ })
+ }
+ }
+ else {
+ console.warn('[JS Framework] Each list item must be an object in old-style repeat, '
+ + 'please use `repeat={{v in list}}` instead.')
+ mergedData = {}
+ mergedData[keyName] = index
+ mergedData[valueName] = item
+ }
+ }
+ else {
+ mergedData = {}
+ mergedData[keyName] = index
+ mergedData[valueName] = item
+ }
+ const newContext = mergeContext(context, mergedData)
+ vms.push(newContext)
+ compile(newContext, target, fragBlock, { repeat: item })
+ }
+
+ const list = watchBlock(vm, fragBlock, getter, 'repeat',
+ (data) => {
+ console.debug('[JS Framework] the "repeat" item has changed', data)
+ if (!fragBlock || !data) {
+ return
+ }
+
+ const oldChildren = children.slice()
+ const oldVms = vms.slice()
+ const oldData = fragBlock.data.slice()
+ // 1. collect all new refs track by
+ const trackMap = {}
+ const reusedMap = {}
+ data.forEach((item, index) => {
+ const key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index)
+ /* istanbul ignore if */
+ if (key == null || key === '') {
+ return
+ }
+ trackMap[key] = item
+ })
+
+ // 2. remove unused element foreach old item
+ const reusedList = []
+ oldData.forEach((item, index) => {
+ const key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index)
+ if (trackMap.hasOwnProperty(key)) {
+ reusedMap[key] = {
+ item, index, key,
+ target: oldChildren[index],
+ vm: oldVms[index]
+ }
+ reusedList.push(item)
+ }
+ else {
+ removeTarget(vm, oldChildren[index])
+ }
+ })
+
+ // 3. create new element foreach new item
+ children.length = 0
+ vms.length = 0
+ fragBlock.data = data.slice()
+ fragBlock.updateMark = fragBlock.start
+
+ data.forEach((item, index) => {
+ const key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index)
+ const reused = reusedMap[key]
+ if (reused) {
+ if (reused.item === reusedList[0]) {
+ reusedList.shift()
+ }
+ else {
+ reusedList.$remove(reused.item)
+ moveTarget(vm, reused.target, fragBlock.updateMark, true)
+ }
+ children.push(reused.target)
+ vms.push(reused.vm)
+ if (oldStyle) {
+ reused.vm = item
+ }
+ else {
+ reused.vm[valueName] = item
+ }
+ reused.vm[keyName] = index
+ fragBlock.updateMark = reused.target
+ }
+ else {
+ compileItem(item, index, vm)
+ }
+ })
+
+ delete fragBlock.updateMark
+ }
+ )
+
+ fragBlock.data = list.slice(0)
+ list.forEach((item, index) => {
+ compileItem(item, index, vm)
+ })
+}
+
+/**
+ * Watch the display update and add/remove the element.
+ *
+ * @param {object} target
+ * @param {object} fragBlock
+ * @param {object} context
+ */
+function bindShown (vm, target, fragBlock, meta) {
+ const display = watchBlock(vm, fragBlock, target.shown, 'shown',
+ (display) => {
+ console.debug('[JS Framework] the "if" item was changed', display)
+
+ if (!fragBlock || !!fragBlock.display === !!display) {
+ return
+ }
+ fragBlock.display = !!display
+ if (display) {
+ compile(vm, target, fragBlock, meta)
+ }
+ else {
+ removeTarget(vm, fragBlock, true)
+ }
+ }
+ )
+
+ fragBlock.display = !!display
+ if (display) {
+ compile(vm, target, fragBlock, meta)
+ }
+}
+
+/**
+ * Watch calc value changes and append certain type action to differ.
+ * It is used for if or repeat data-binding generator.
+ *
+ * @param {object} fragBlock
+ * @param {function} calc
+ * @param {string} type
+ * @param {function} handler
+ * @return {any} init value of calc
+ */
+function watchBlock (vm, fragBlock, calc, type, handler) {
+ const differ = vm && vm._app && vm._app.differ
+ const config = {}
+ const depth = (fragBlock.element.depth || 0) + 1
+
+ return watch(vm, calc, (value) => {
+ config.latestValue = value
+ if (differ && !config.recorded) {
+ differ.append(type, depth, fragBlock.blockId, () => {
+ const latestValue = config.latestValue
+ handler(latestValue)
+ config.recorded = false
+ config.latestValue = undefined
+ })
+ }
+ config.recorded = true
+ })
+}
+
+/**
+ * Clone a context and merge certain data.
+ *
+ * @param {object} mergedData
+ * @return {object}
+ */
+function mergeContext (context, mergedData) {
+ const newContext = Object.create(context)
+ newContext._data = mergedData
+ initData(newContext)
+ initComputed(newContext)
+ newContext._realParent = context
+ if (context._static) {
+ newContext._static = context._static
+ }
+ return newContext
+}
[19/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/observer.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/observer.js b/html5/frameworks/legacy/core/observer.js
deleted file mode 100644
index 103dd0d..0000000
--- a/html5/frameworks/legacy/core/observer.js
+++ /dev/null
@@ -1,323 +0,0 @@
-/* eslint-disable */
-
-
-import Dep from './dep'
-import { arrayMethods } from './array'
-import {
- def,
- remove,
- isObject,
- isPlainObject,
- hasProto,
- hasOwn,
- isReserved
-} from '../util/index'
-
-const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
-
-/**
- * Observer class that are attached to each observed
- * object. Once attached, the observer converts target
- * object's property keys into getter/setters that
- * collect dependencies and dispatches updates.
- *
- * @param {Array|Object} value
- * @constructor
- */
-
-export function Observer (value) {
- this.value = value
- this.dep = new Dep()
- def(value, '__ob__', this)
- if (Array.isArray(value)) {
- const augment = hasProto
- ? protoAugment
- : copyAugment
- augment(value, arrayMethods, arrayKeys)
- this.observeArray(value)
- } else {
- this.walk(value)
- }
-}
-
-// Instance methods
-
-/**
- * Walk through each property and convert them into
- * getter/setters. This method should only be called when
- * value type is Object.
- *
- * @param {Object} obj
- */
-
-Observer.prototype.walk = function (obj) {
- for (let key in obj) {
- this.convert(key, obj[key])
- }
-}
-
-/**
- * Observe a list of Array items.
- *
- * @param {Array} items
- */
-
-Observer.prototype.observeArray = function (items) {
- for (let i = 0, l = items.length; i < l; i++) {
- observe(items[i])
- }
-}
-
-/**
- * Convert a property into getter/setter so we can emit
- * the events when the property is accessed/changed.
- *
- * @param {String} key
- * @param {*} val
- */
-
-Observer.prototype.convert = function (key, val) {
- defineReactive(this.value, key, val)
-}
-
-/**
- * Add an owner vm, so that when $set/$delete mutations
- * happen we can notify owner vms to proxy the keys and
- * digest the watchers. This is only called when the object
- * is observed as an instance's root $data.
- *
- * @param {Vue} vm
- */
-
-Observer.prototype.addVm = function (vm) {
- (this.vms || (this.vms = [])).push(vm)
-}
-
-/**
- * Remove an owner vm. This is called when the object is
- * swapped out as an instance's $data object.
- *
- * @param {Vue} vm
- */
-
-/* istanbul ignore next */
-Observer.prototype.removeVm = function (vm) {
- remove(this.vms, vm)
-}
-
-// helpers
-
-/**
- * Augment an target Object or Array by intercepting
- * the prototype chain using __proto__
- *
- * @param {Object|Array} target
- * @param {Object} src
- */
-
-function protoAugment (target, src) {
- /* eslint-disable no-proto */
- target.__proto__ = src
- /* eslint-enable no-proto */
-}
-
-/**
- * Augment an target Object or Array by defining
- * hidden properties.
- *
- * @param {Object|Array} target
- * @param {Object} proto
- */
-
-/* istanbul ignore next */
-function copyAugment (target, src, keys) {
- for (let i = 0, l = keys.length; i < l; i++) {
- const key = keys[i]
- def(target, key, src[key])
- }
-}
-
-/**
- * Attempt to create an observer instance for a value,
- * returns the new observer if successfully observed,
- * or the existing observer if the value already has one.
- *
- * @param {*} value
- * @param {Vue} [vm]
- * @return {Observer|undefined}
- * @static
- */
-
-export function observe (value, vm) {
- if (!isObject(value)) {
- return
- }
- let ob
- if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
- ob = value.__ob__
- } else if (
- (Array.isArray(value) || isPlainObject(value)) &&
- Object.isExtensible(value) &&
- !value._isVue
- ) {
- ob = new Observer(value)
- }
- if (ob && vm) {
- ob.addVm(vm)
- }
- return ob
-}
-
-/**
- * Define a reactive property on an Object.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- */
-
-export function defineReactive (obj, key, val) {
- const dep = new Dep()
-
- const property = Object.getOwnPropertyDescriptor(obj, key)
- if (property && property.configurable === false) {
- return
- }
-
- // cater for pre-defined getter/setters
- const getter = property && property.get
- const setter = property && property.set
-
- let childOb = observe(val)
- Object.defineProperty(obj, key, {
- enumerable: true,
- configurable: true,
- get: function reactiveGetter () {
- const value = getter ? getter.call(obj) : val
- if (Dep.target) {
- dep.depend()
- if (childOb) {
- childOb.dep.depend()
- }
- if (Array.isArray(value)) {
- for (let e, i = 0, l = value.length; i < l; i++) {
- e = value[i]
- e && e.__ob__ && e.__ob__.dep.depend()
- }
- }
- }
- return value
- },
- set: function reactiveSetter (newVal) {
- const value = getter ? getter.call(obj) : val
- if (newVal === value) {
- return
- }
- if (setter) {
- setter.call(obj, newVal)
- } else {
- val = newVal
- }
- childOb = observe(newVal)
- dep.notify()
- }
- })
-}
-
-/**
- * Set a property on an object. Adds the new property and
- * triggers change notification if the property doesn't
- * already exist.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- * @public
- */
-
-/* istanbul ignore next */
-export function set (obj, key, val) {
- if (Array.isArray(obj)) {
- return obj.splice(key, 1, val)
- }
- if (hasOwn(obj, key)) {
- obj[key] = val
- return
- }
- if (obj._isVue) {
- set(obj._data, key, val)
- return
- }
- const ob = obj.__ob__
- if (!ob) {
- obj[key] = val
- return
- }
- ob.convert(key, val)
- ob.dep.notify()
- if (ob.vms) {
- let i = ob.vms.length
- while (i--) {
- const vm = ob.vms[i]
- proxy(vm, key)
- // vm.$forceUpdate()
- }
- }
- return val
-}
-
-/**
- * Delete a property and trigger change if necessary.
- *
- * @param {Object} obj
- * @param {String} key
- */
-
-/* istanbul ignore next */
-export function del (obj, key) {
- if (!hasOwn(obj, key)) {
- return
- }
- delete obj[key]
- const ob = obj.__ob__
-
- if (!ob) {
- if (obj._isVue) {
- delete obj._data[key]
- // obj.$forceUpdate()
- }
- return
- }
- ob.dep.notify()
- if (ob.vms) {
- let i = ob.vms.length
- while (i--) {
- const vm = ob.vms[i]
- unproxy(vm, key)
- // vm.$forceUpdate()
- }
- }
-}
-
-const KEY_WORDS = ['$index', '$value', '$event']
-export function proxy (vm, key) {
- if (KEY_WORDS.indexOf(key) > -1 || !isReserved(key)) {
- Object.defineProperty(vm, key, {
- configurable: true,
- enumerable: true,
- get: function proxyGetter () {
- return vm._data[key]
- },
- set: function proxySetter (val) {
- vm._data[key] = val
- }
- })
- }
-}
-
-/* istanbul ignore next */
-export function unproxy (vm, key) {
- if (!isReserved(key)) {
- delete vm[key]
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/state.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/state.js b/html5/frameworks/legacy/core/state.js
deleted file mode 100644
index 5300dbf..0000000
--- a/html5/frameworks/legacy/core/state.js
+++ /dev/null
@@ -1,92 +0,0 @@
-/* eslint-disable */
-
-
-import Watcher from './watcher'
-import Dep from './dep'
-import {
- observe,
- proxy,
- unproxy
-} from './observer'
-import {
- isPlainObject,
- bind
-} from '../util/index'
-
-export function initState (vm) {
- vm._watchers = []
- initData(vm)
- initComputed(vm)
- initMethods(vm)
-}
-
-export function initData (vm) {
- let data = vm._data
-
- if (!isPlainObject(data)) {
- data = {}
- }
- // proxy data on instance
- const keys = Object.keys(data)
- let i = keys.length
- while (i--) {
- proxy(vm, keys[i])
- }
- // observe data
- observe(data, vm)
-}
-
-/* istanbul ignore next */
-function noop () {
-}
-
-export function initComputed (vm) {
- const computed = vm._computed
- if (computed) {
- for (let key in computed) {
- const userDef = computed[key]
- const def = {
- enumerable: true,
- configurable: true
- }
- if (typeof userDef === 'function') {
- def.get = makeComputedGetter(userDef, vm)
- def.set = noop
- } else {
- def.get = userDef.get
- ? userDef.cache !== false
- ? makeComputedGetter(userDef.get, vm)
- : bind(userDef.get, vm)
- : noop
- def.set = userDef.set
- ? bind(userDef.set, vm)
- : noop
- }
- Object.defineProperty(vm, key, def)
- }
- }
-}
-
-function makeComputedGetter (getter, owner) {
- const watcher = new Watcher(owner, getter, null, {
- lazy: true
- })
- return function computedGetter () {
- if (watcher.dirty) {
- watcher.evaluate()
- }
- if (Dep.target) {
- watcher.depend()
- }
- return watcher.value
- }
-}
-
-export function initMethods (vm) {
- const methods = vm._methods
- if (methods) {
- for (let key in methods) {
- vm[key] = methods[key]
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/core/watcher.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/core/watcher.js b/html5/frameworks/legacy/core/watcher.js
deleted file mode 100644
index cfd6370..0000000
--- a/html5/frameworks/legacy/core/watcher.js
+++ /dev/null
@@ -1,254 +0,0 @@
-/* eslint-disable */
-
-
-import Dep, { pushTarget, popTarget } from './dep'
-// import { pushWatcher } from './batcher'
-import {
- remove,
- extend,
- isObject,
- createNewSet
- // _Set as Set
-} from '../util/index'
-
-let uid = 0
-
-/**
- * A watcher parses an expression, collects dependencies,
- * and fires callback when the expression value changes.
- * This is used for both the $watch() api and directives.
- *
- * @param {Vue} vm
- * @param {String|Function} expOrFn
- * @param {Function} cb
- * @param {Object} options
- * - {Array} filters
- * - {Boolean} twoWay
- * - {Boolean} deep
- * - {Boolean} user
- * - {Boolean} sync
- * - {Boolean} lazy
- * - {Function} [preProcess]
- * - {Function} [postProcess]
- * @constructor
- */
-
-export default function Watcher (vm, expOrFn, cb, options) {
- // mix in options
- if (options) {
- extend(this, options)
- }
- const isFn = typeof expOrFn === 'function'
- this.vm = vm
- vm._watchers.push(this)
- this.expression = expOrFn
- this.cb = cb
- this.id = ++uid // uid for batching
- this.active = true
- this.dirty = this.lazy // for lazy watchers
- this.deps = []
- this.newDeps = []
- this.depIds = createNewSet() // new Set()
- this.newDepIds = createNewSet() // new Set()
- // parse expression for getter
- if (isFn) {
- this.getter = expOrFn
- }
- this.value = this.lazy
- ? undefined
- : this.get()
- // state for avoiding false triggers for deep and Array
- // watchers during vm._digest()
- this.queued = this.shallow = false
-}
-
-/**
- * Evaluate the getter, and re-collect dependencies.
- */
-
-Watcher.prototype.get = function () {
- pushTarget(this)
- const value = this.getter.call(this.vm, this.vm)
- // "touch" every property so they are all tracked as
- // dependencies for deep watching
- if (this.deep) {
- traverse(value)
- }
- popTarget()
- this.cleanupDeps()
- return value
-}
-
-/**
- * Add a dependency to this directive.
- *
- * @param {Dep} dep
- */
-
-Watcher.prototype.addDep = function (dep) {
- const id = dep.id
- if (!this.newDepIds.has(id)) {
- this.newDepIds.add(id)
- this.newDeps.push(dep)
- if (!this.depIds.has(id)) {
- dep.addSub(this)
- }
- }
-}
-
-/**
- * Clean up for dependency collection.
- */
-
-Watcher.prototype.cleanupDeps = function () {
- let i = this.deps.length
- while (i--) {
- const dep = this.deps[i]
- if (!this.newDepIds.has(dep.id)) {
- dep.removeSub(this)
- }
- }
- let tmp = this.depIds
- this.depIds = this.newDepIds
- this.newDepIds = tmp
- this.newDepIds.clear()
- tmp = this.deps
- this.deps = this.newDeps
- this.newDeps = tmp
- this.newDeps.length = 0
-}
-
-/**
- * Subscriber interface.
- * Will be called when a dependency changes.
- *
- * @param {Boolean} shallow
- */
-
-Watcher.prototype.update = function (shallow) {
- if (this.lazy) {
- this.dirty = true
- } else {
- this.run()
- }
- // } else if (this.sync) {
- // this.run()
- // } else {
- // // if queued, only overwrite shallow with non-shallow,
- // // but not the other way around.
- // this.shallow = this.queued
- // ? shallow
- // ? this.shallow
- // : false
- // : !!shallow
- // this.queued = true
- // pushWatcher(this)
- // }
-}
-
-/**
- * Batcher job interface.
- * Will be called by the batcher.
- */
-
-Watcher.prototype.run = function () {
- if (this.active) {
- const value = this.get()
- if (
- value !== this.value ||
- // Deep watchers and watchers on Object/Arrays should fire even
- // when the value is the same, because the value may
- // have mutated; but only do so if this is a
- // non-shallow update (caused by a vm digest).
- ((isObject(value) || this.deep) && !this.shallow)
- ) {
- // set new value
- const oldValue = this.value
- this.value = value
- this.cb.call(this.vm, value, oldValue)
- }
- this.queued = this.shallow = false
- }
-}
-
-/**
- * Evaluate the value of the watcher.
- * This only gets called for lazy watchers.
- */
-
-Watcher.prototype.evaluate = function () {
- this.value = this.get()
- this.dirty = false
-}
-
-/**
- * Depend on all deps collected by this watcher.
- */
-
-Watcher.prototype.depend = function () {
- let i = this.deps.length
- while (i--) {
- this.deps[i].depend()
- }
-}
-
-/**
- * Remove self from all dependencies' subcriber list.
- */
-
-Watcher.prototype.teardown = function () {
- if (this.active) {
- // remove self from vm's watcher list
- // this is a somewhat expensive operation so we skip it
- // if the vm is being destroyed or is performing a v-for
- // re-render (the watcher list is then filtered by v-for).
- if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
- remove(this.vm._watchers, this)
- }
- let i = this.deps.length
- while (i--) {
- this.deps[i].removeSub(this)
- }
- this.active = false
- this.vm = this.cb = this.value = null
- }
-}
-
-/**
- * Recrusively traverse an object to evoke all converted
- * getters, so that every nested property inside the object
- * is collected as a "deep" dependency.
- *
- * @param {*} val
- * @param {Set} seen
- */
-
-const seenObjects = createNewSet() // new Set()
-/* istanbul ignore next */
-function traverse (val, seen) {
- let i, keys, isA, isO
- if (!seen) {
- seen = seenObjects
- seen.clear()
- }
- isA = Array.isArray(val)
- isO = isObject(val)
- if (isA || isO) {
- if (val.__ob__) {
- const depId = val.__ob__.dep.id
- if (seen.has(depId)) {
- return
- } else {
- seen.add(depId)
- }
- }
- if (isA) {
- i = val.length
- while (i--) traverse(val[i], seen)
- } else if (isO) {
- keys = Object.keys(val)
- i = keys.length
- while (i--) traverse(val[keys[i]], seen)
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/index.js b/html5/frameworks/legacy/index.js
deleted file mode 100644
index 366ecb3..0000000
--- a/html5/frameworks/legacy/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview Weex framework entry.
- */
-
-import * as methods from './api/methods'
-
-import Vm from './vm'
-export { createInstance } from './static/create'
-export { init, refreshInstance, destroyInstance } from './static/life'
-import { registerComponents, registerModules, registerMethods } from './static/register'
-export { receiveTasks } from './static/bridge'
-export { getRoot } from './static/misc'
-
-// register special methods for Weex framework
-registerMethods(methods)
-
-/**
- * Prevent modification of Vm and Vm.prototype
- */
-Object.freeze(Vm)
-
-export { registerComponents, registerModules, registerMethods }
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/static/bridge.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/static/bridge.js b/html5/frameworks/legacy/static/bridge.js
deleted file mode 100644
index 665b1ad..0000000
--- a/html5/frameworks/legacy/static/bridge.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { instanceMap } from './map'
-import {
- fireEvent,
- callback
-} from '../app/ctrl/index'
-
-const jsHandlers = {
- fireEvent: (id, ...args) => {
- return fireEvent(instanceMap[id], ...args)
- },
- callback: (id, ...args) => {
- return callback(instanceMap[id], ...args)
- }
-}
-
-/**
- * Accept calls from native (event or callback).
- *
- * @param {string} id
- * @param {array} tasks list with `method` and `args`
- */
-export function receiveTasks (id, tasks) {
- const instance = instanceMap[id]
- if (instance && Array.isArray(tasks)) {
- const results = []
- tasks.forEach((task) => {
- const handler = jsHandlers[task.method]
- const args = [...task.args]
- /* istanbul ignore else */
- if (typeof handler === 'function') {
- args.unshift(id)
- results.push(handler(...args))
- }
- })
- return results
- }
- return new Error(`invalid instance id "${id}" or tasks`)
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/static/create.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/static/create.js b/html5/frameworks/legacy/static/create.js
deleted file mode 100644
index 1c963b3..0000000
--- a/html5/frameworks/legacy/static/create.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import App from '../app/index'
-import { instanceMap } from './map'
-import { init as initApp } from '../app/ctrl/index'
-import { resetTarget } from '../core/dep'
-
-/**
- * Create a Weex instance.
- *
- * @param {string} id
- * @param {string} code
- * @param {object} options
- * option `HAS_LOG` enable print log
- * @param {object} data
- * @param {object} info { created, ... services }
- */
-export function createInstance (id, code, options, data, info) {
- const { services } = info || {}
- resetTarget()
- let instance = instanceMap[id]
- /* istanbul ignore else */
- options = options || {}
- let result
- /* istanbul ignore else */
- if (!instance) {
- instance = new App(id, options)
- instanceMap[id] = instance
- result = initApp(instance, code, data, services)
- }
- else {
- result = new Error(`invalid instance id "${id}"`)
- }
- return (result instanceof Error) ? result : instance
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/static/life.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/static/life.js b/html5/frameworks/legacy/static/life.js
deleted file mode 100644
index 9cb8abc..0000000
--- a/html5/frameworks/legacy/static/life.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import config from '../config'
-import {
- refresh,
- destroy
-} from '../app/ctrl/index'
-import { instanceMap } from './map'
-import { resetTarget } from '../core/dep'
-
-/**
- * Init config informations for Weex framework
- * @param {object} cfg
- */
-export function init (cfg) {
- config.Document = cfg.Document
- config.Element = cfg.Element
- config.Comment = cfg.Comment
- config.sendTasks = cfg.sendTasks
- config.Listener = cfg.Listener
-}
-
-/**
- * Refresh a Weex instance with data.
- *
- * @param {string} id
- * @param {object} data
- */
-export function refreshInstance (id, data) {
- const instance = instanceMap[id]
- let result
- /* istanbul ignore else */
- if (instance) {
- result = refresh(instance, data)
- }
- else {
- result = new Error(`invalid instance id "${id}"`)
- }
- return result
-}
-
-/**
- * Destroy a Weex instance.
- * @param {string} id
- */
-export function destroyInstance (id) {
- // Markup some global state in native side
- if (typeof markupState === 'function') {
- markupState()
- }
-
- resetTarget()
- const instance = instanceMap[id]
- /* istanbul ignore else */
- if (!instance) {
- return new Error(`invalid instance id "${id}"`)
- }
- destroy(instance)
- delete instanceMap[id]
- // notifyContextDisposed is used to tell v8 to do a full GC,
- // but this would have a negative performance impact on weex,
- // because all the inline cache in v8 would get cleared
- // during a full GC.
- // To take care of both memory and performance, just tell v8
- // to do a full GC every eighteen times.
- const idNum = Math.round(id)
- const round = 18
- if (idNum > 0) {
- const remainder = idNum % round
- if (!remainder && typeof notifyTrimMemory === 'function') {
- notifyTrimMemory()
- }
- }
- return instanceMap
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/static/map.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/static/map.js b/html5/frameworks/legacy/static/map.js
deleted file mode 100644
index 8c94ef4..0000000
--- a/html5/frameworks/legacy/static/map.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-export const instanceMap = {}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/static/misc.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/static/misc.js b/html5/frameworks/legacy/static/misc.js
deleted file mode 100644
index afbc5e3..0000000
--- a/html5/frameworks/legacy/static/misc.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { instanceMap } from './map'
-import {
- getRootElement
-} from '../app/ctrl/index'
-
-/**
- * Get a whole element tree of an instance for debugging.
- * @param {string} id
- * @return {object} a virtual dom tree
- */
-export function getRoot (id) {
- const instance = instanceMap[id]
- let result
- /* istanbul ignore else */
- if (instance) {
- result = getRootElement(instance)
- }
- else {
- result = new Error(`invalid instance id "${id}"`)
- }
- return result
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/static/register.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/static/register.js b/html5/frameworks/legacy/static/register.js
deleted file mode 100644
index f21df89..0000000
--- a/html5/frameworks/legacy/static/register.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import Vm from '../vm/index'
-import config from '../config'
-import {
- initModules,
- initMethods
-} from '../app/register'
-
-const {
- nativeComponentMap
-} = config
-
-/**
- * Register the name of each native component.
- * @param {array} components array of name
- */
-export function registerComponents (components) {
- if (Array.isArray(components)) {
- components.forEach(function register (name) {
- /* istanbul ignore if */
- if (!name) {
- return
- }
- if (typeof name === 'string') {
- nativeComponentMap[name] = true
- }
- /* istanbul ignore else */
- else if (typeof name === 'object' && typeof name.type === 'string') {
- nativeComponentMap[name.type] = name
- }
- })
- }
-}
-
-/**
- * Register the name and methods of each module.
- * @param {object} modules a object of modules
- */
-export function registerModules (modules) {
- /* istanbul ignore else */
- if (typeof modules === 'object') {
- initModules(modules)
- }
-}
-
-/**
- * Register the name and methods of each api.
- * @param {object} apis a object of apis
- */
-export function registerMethods (methods) {
- /* istanbul ignore else */
- if (typeof methods === 'object') {
- initMethods(Vm, methods)
- }
-}
-
-// @todo: Hack for this framework only. Will be re-designed or removed later.
-global.registerMethods = registerMethods
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/util/LICENSE
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/util/LICENSE b/html5/frameworks/legacy/util/LICENSE
deleted file mode 100644
index 4645bc4..0000000
--- a/html5/frameworks/legacy/util/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013-2015 Yuxi Evan You
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/util/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/util/index.js b/html5/frameworks/legacy/util/index.js
deleted file mode 100644
index 0d716f4..0000000
--- a/html5/frameworks/legacy/util/index.js
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-export {
- extend,
- def,
- remove,
- hasOwn,
- bind,
- toArray,
- isObject,
- isPlainObject
-} from './shared'
-
-/**
- * Check if a string starts with $ or _
- *
- * @param {String} str
- * @return {Boolean}
- */
-
-export function isReserved (str) {
- const c = (str + '').charCodeAt(0)
- return c === 0x24 || c === 0x5F
-}
-
-// can we use __proto__?
-export const hasProto = '__proto__' in {}
-
-let _Set
-/* istanbul ignore next */
-if (typeof Set !== 'undefined' && Set.toString().match(/native code/)) {
- // use native Set when available.
- _Set = Set
-}
-else {
- // a non-standard Set polyfill that only works with primitive keys.
- _Set = function () {
- this.set = Object.create(null)
- }
- _Set.prototype.has = function (key) {
- return this.set[key] !== undefined
- }
- _Set.prototype.add = function (key) {
- if (key == null || this.set[key]) {
- return
- }
- this.set[key] = 1
- }
- _Set.prototype.clear = function () {
- this.set = Object.create(null)
- }
-}
-
-export { _Set }
-
-/**
- * Polyfill in iOS7 by native because the JavaScript polyfill has memory problem.
- * @return {object}
- */
-
-export function createNewSet () {
- /* istanbul ignore next */
- /* eslint-disable */
- if (typeof nativeSet === 'object') {
- return nativeSet.create()
- }
- /* eslint-enable */
- return new _Set()
-}
-
-/**
- * Create a cached version of a pure function.
- *
- * @param {Function} fn
- * @return {Function}
- */
-
-export function cached (fn) {
- const cache = Object.create(null)
- return function cachedFn (str) {
- const hit = cache[str]
- return hit || (cache[str] = fn(str))
- }
-}
-
-/**
- * Camelize a hyphen-delmited string.
- *
- * @param {String} str
- * @return {String}
- */
-
-const camelizeRE = /-(\w)/g
-export const camelize = cached(str => {
- return str.replace(camelizeRE, toUpper)
-})
-
-function toUpper (_, c) {
- return c ? c.toUpperCase() : ''
-}
-
-/**
- * Hyphenate a camelCase string.
- *
- * @param {String} str
- * @return {String}
- */
-
-const hyphenateRE = /([a-z\d])([A-Z])/g
-export const hyphenate = cached(str => {
- return str
- .replace(hyphenateRE, '$1-$2')
- .toLowerCase()
-})
-
-export function typof (v) {
- const s = Object.prototype.toString.call(v)
- return s.substring(8, s.length - 1).toLowerCase()
-}
-
-// weex name rules
-
-const WEEX_COMPONENT_REG = /^@weex-component\//
-const WEEX_MODULE_REG = /^@weex-module\//
-const NORMAL_MODULE_REG = /^\.{1,2}\//
-const JS_SURFIX_REG = /\.js$/
-
-export const isWeexComponent = name => !!name.match(WEEX_COMPONENT_REG)
-export const isWeexModule = name => !!name.match(WEEX_MODULE_REG)
-export const isNormalModule = name => !!name.match(NORMAL_MODULE_REG)
-export const isNpmModule = name => !isWeexComponent(name) && !isWeexModule(name) && !isNormalModule(name)
-
-export function removeWeexPrefix (str) {
- const result = str.replace(WEEX_COMPONENT_REG, '').replace(WEEX_MODULE_REG, '')
- return result
-}
-
-export function removeJSSurfix (str) {
- return str.replace(JS_SURFIX_REG, '')
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/util/shared.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/util/shared.js b/html5/frameworks/legacy/util/shared.js
deleted file mode 100644
index faf76e1..0000000
--- a/html5/frameworks/legacy/util/shared.js
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * Mix properties into target object.
- *
- * @param {Object} to
- * @param {Object} from
- */
-
-function extend (target, ...src) {
- /* istanbul ignore else */
- if (typeof Object.assign === 'function') {
- Object.assign(target, ...src)
- }
- else {
- const first = src.shift()
- for (const key in first) {
- target[key] = first[key]
- }
- if (src.length) {
- extend(target, ...src)
- }
- }
- return target
-}
-
-/**
- * Define a property.
- *
- * @param {Object} obj
- * @param {String} key
- * @param {*} val
- * @param {Boolean} [enumerable]
- */
-
-function def (obj, key, val, enumerable) {
- Object.defineProperty(obj, key, {
- value: val,
- enumerable: !!enumerable,
- writable: true,
- configurable: true
- })
-}
-
-/**
- * Remove an item from an array
- *
- * @param {Array} arr
- * @param {*} item
- */
-
-function remove (arr, item) {
- if (arr.length) {
- const index = arr.indexOf(item)
- if (index > -1) {
- return arr.splice(index, 1)
- }
- }
-}
-
-/**
- * Check whether the object has the property.
- *
- * @param {Object} obj
- * @param {String} key
- * @return {Boolean}
- */
-const hasOwnProperty = Object.prototype.hasOwnProperty
-function hasOwn (obj, key) {
- return hasOwnProperty.call(obj, key)
-}
-
-/**
- * Simple bind, faster than native
- *
- * @param {Function} fn
- * @param {Object} ctx
- * @return {Function}
- */
-
-function bind (fn, ctx) {
- return function (a) {
- const l = arguments.length
- return l
- ? l > 1
- ? fn.apply(ctx, arguments)
- : fn.call(ctx, a)
- : fn.call(ctx)
- }
-}
-
-/**
- * Convert an Array-like object to a real Array.
- *
- * @param {Array-like} list
- * @param {Number} [start] - start index
- * @return {Array}
- */
-
-function toArray (list, start) {
- start = start || 0
- let i = list.length - start
- const ret = new Array(i)
- while (i--) {
- ret[i] = list[i + start]
- }
- return ret
-}
-
-/**
- * Quick object check - this is primarily used to tell
- * Objects from primitive values when we know the value
- * is a JSON-compliant type.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
-function isObject (obj) {
- return obj !== null && typeof obj === 'object'
-}
-
-/**
- * Strict object type check. Only returns true
- * for plain JavaScript objects.
- *
- * @param {*} obj
- * @return {Boolean}
- */
-
-const toString = Object.prototype.toString
-const OBJECT_STRING = '[object Object]'
-function isPlainObject (obj) {
- return toString.call(obj) === OBJECT_STRING
-}
-
-export {
- extend,
- def,
- remove,
- hasOwn,
- bind,
- toArray,
- isObject,
- isPlainObject
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/vm/compiler.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/vm/compiler.js b/html5/frameworks/legacy/vm/compiler.js
deleted file mode 100644
index ffca01f..0000000
--- a/html5/frameworks/legacy/vm/compiler.js
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * ViewModel template parser & data-binding process
- */
-
-import {
- extend,
- isObject,
- bind
-} from '../util/index'
-import {
- initData,
- initComputed
-} from '../core/state'
-import {
- bindElement,
- setId,
- bindSubVm,
- bindSubVmAfterInitialized,
- applyNaitveComponentOptions,
- watch
-} from './directive'
-import {
- createBlock,
- createBody,
- createElement,
- attachTarget,
- moveTarget,
- removeTarget
-} from './dom-helper'
-
-/**
- * build()
- * compile(template, parentNode)
- * if (type is content) create contentNode
- * else if (dirs have v-for) foreach -> create context
- * -> compile(templateWithoutFor, parentNode): diff(list) onchange
- * else if (dirs have v-if) assert
- * -> compile(templateWithoutIf, parentNode): toggle(shown) onchange
- * else if (type is dynamic)
- * -> compile(templateWithoutDynamicType, parentNode): watch(type) onchange
- * else if (type is custom)
- * addChildVm(vm, parentVm)
- * build(externalDirs)
- * foreach childNodes -> compile(childNode, template)
- * else if (type is native)
- * set(dirs): update(id/attr/style/class) onchange
- * append(template, parentNode)
- * foreach childNodes -> compile(childNode, template)
- */
-export function build (vm) {
- const opt = vm._options || {}
- const template = opt.template || {}
-
- if (opt.replace) {
- if (template.children && template.children.length === 1) {
- compile(vm, template.children[0], vm._parentEl)
- }
- else {
- compile(vm, template.children, vm._parentEl)
- }
- }
- else {
- compile(vm, template, vm._parentEl)
- }
-
- console.debug(`[JS Framework] "ready" lifecycle in Vm(${vm._type})`)
- vm.$emit('hook:ready')
- vm._ready = true
-}
-
-/**
- * Generate elements by child or children and append to parent elements.
- * Root element info would be merged if has. The first argument may be an array
- * if the root element with options.replace has not only one child.
- *
- * @param {object|array} target
- * @param {object} dest
- * @param {object} meta
- */
-function compile (vm, target, dest, meta) {
- const app = vm._app || {}
-
- if (app.lastSignal === -1) {
- return
- }
-
- if (target.attr && target.attr.hasOwnProperty('static')) {
- vm._static = true
- }
-
- if (targetIsFragment(target)) {
- compileFragment(vm, target, dest, meta)
- return
- }
- meta = meta || {}
- if (targetIsContent(target)) {
- console.debug('[JS Framework] compile "content" block by', target)
- vm._content = createBlock(vm, dest)
- return
- }
-
- if (targetNeedCheckRepeat(target, meta)) {
- console.debug('[JS Framework] compile "repeat" logic by', target)
- if (dest.type === 'document') {
- console.warn('[JS Framework] The root element does\'t support `repeat` directive!')
- }
- else {
- compileRepeat(vm, target, dest)
- }
- return
- }
- if (targetNeedCheckShown(target, meta)) {
- console.debug('[JS Framework] compile "if" logic by', target)
- if (dest.type === 'document') {
- console.warn('[JS Framework] The root element does\'t support `if` directive!')
- }
- else {
- compileShown(vm, target, dest, meta)
- }
- return
- }
- const typeGetter = meta.type || target.type
- if (targetNeedCheckType(typeGetter, meta)) {
- compileType(vm, target, dest, typeGetter, meta)
- return
- }
- const type = typeGetter
- const component = targetIsComposed(vm, target, type)
- if (component) {
- console.debug('[JS Framework] compile composed component by', target)
- compileCustomComponent(vm, component, target, dest, type, meta)
- return
- }
- console.debug('[JS Framework] compile native component by', target)
- compileNativeComponent(vm, target, dest, type)
-}
-
-/**
- * Check if target is a fragment (an array).
- *
- * @param {object} target
- * @return {boolean}
- */
-function targetIsFragment (target) {
- return Array.isArray(target)
-}
-
-/**
- * Check if target type is content/slot.
- *
- * @param {object} target
- * @return {boolean}
- */
-function targetIsContent (target) {
- return target.type === 'content' || target.type === 'slot'
-}
-
-/**
- * Check if target need to compile by a list.
- *
- * @param {object} target
- * @param {object} meta
- * @return {boolean}
- */
-function targetNeedCheckRepeat (target, meta) {
- return !meta.hasOwnProperty('repeat') && target.repeat
-}
-
-/**
- * Check if target need to compile by a boolean value.
- *
- * @param {object} target
- * @param {object} meta
- * @return {boolean}
- */
-function targetNeedCheckShown (target, meta) {
- return !meta.hasOwnProperty('shown') && target.shown
-}
-
-/**
- * Check if target need to compile by a dynamic type.
- *
- * @param {string|function} typeGetter
- * @param {object} meta
- * @return {boolean}
- */
-function targetNeedCheckType (typeGetter, meta) {
- return (typeof typeGetter === 'function') && !meta.hasOwnProperty('type')
-}
-
-/**
- * Check if this kind of component is composed.
- *
- * @param {string} type
- * @return {boolean}
- */
-function targetIsComposed (vm, target, type) {
- let component
- if (vm._app && vm._app.customComponentMap) {
- component = vm._app.customComponentMap[type]
- }
- if (vm._options && vm._options.components) {
- component = vm._options.components[type]
- }
- if (target.component) {
- component = component || {}
- }
- return component
-}
-
-/**
- * Compile a list of targets.
- *
- * @param {object} target
- * @param {object} dest
- * @param {object} meta
- */
-function compileFragment (vm, target, dest, meta) {
- const fragBlock = createBlock(vm, dest)
- target.forEach((child) => {
- compile(vm, child, fragBlock, meta)
- })
-}
-
-/**
- * Compile a target with repeat directive.
- *
- * @param {object} target
- * @param {object} dest
- */
-function compileRepeat (vm, target, dest) {
- const repeat = target.repeat
- const oldStyle = typeof repeat === 'function'
- let getter = repeat.getter || repeat.expression || repeat
- if (typeof getter !== 'function') {
- getter = function () { return [] }
- }
- const key = repeat.key || '$index'
- const value = repeat.value || '$value'
- const trackBy = repeat.trackBy || target.trackBy ||
- (target.attr && target.attr.trackBy)
-
- const fragBlock = createBlock(vm, dest)
- fragBlock.children = []
- fragBlock.data = []
- fragBlock.vms = []
-
- bindRepeat(vm, target, fragBlock, { getter, key, value, trackBy, oldStyle })
-}
-
-/**
- * Compile a target with if directive.
- *
- * @param {object} target
- * @param {object} dest
- * @param {object} meta
- */
-function compileShown (vm, target, dest, meta) {
- const newMeta = { shown: true }
- const fragBlock = createBlock(vm, dest)
-
- if (dest.element && dest.children) {
- dest.children.push(fragBlock)
- }
-
- if (meta.repeat) {
- newMeta.repeat = meta.repeat
- }
-
- bindShown(vm, target, fragBlock, newMeta)
-}
-
-/**
- * Compile a target with dynamic component type.
- *
- * @param {object} target
- * @param {object} dest
- * @param {function} typeGetter
- */
-function compileType (vm, target, dest, typeGetter, meta) {
- const type = typeGetter.call(vm)
- const newMeta = extend({ type }, meta)
- const fragBlock = createBlock(vm, dest)
-
- if (dest.element && dest.children) {
- dest.children.push(fragBlock)
- }
-
- watch(vm, typeGetter, (value) => {
- const newMeta = extend({ type: value }, meta)
- removeTarget(vm, fragBlock, true)
- compile(vm, target, fragBlock, newMeta)
- })
-
- compile(vm, target, fragBlock, newMeta)
-}
-
-/**
- * Compile a composed component.
- *
- * @param {object} target
- * @param {object} dest
- * @param {string} type
- */
-function compileCustomComponent (vm, component, target, dest, type, meta) {
- const Ctor = vm.constructor
- const subVm = new Ctor(type, component, vm, dest, undefined, {
- 'hook:init': function () {
- if (vm._static) {
- this._static = vm._static
- }
- setId(vm, null, target.id, this)
- // bind template earlier because of lifecycle issues
- this._externalBinding = {
- parent: vm,
- template: target
- }
- },
- 'hook:created': function () {
- bindSubVm(vm, this, target, meta.repeat)
- },
- 'hook:ready': function () {
- if (this._content) {
- compileChildren(vm, target, this._content)
- }
- }
- })
- bindSubVmAfterInitialized(vm, subVm, target, dest)
-}
-
-/**
- * Generate element from template and attach to the dest if needed.
- * The time to attach depends on whether the mode status is node or tree.
- *
- * @param {object} template
- * @param {object} dest
- * @param {string} type
- */
-function compileNativeComponent (vm, template, dest, type) {
- applyNaitveComponentOptions(template)
-
- let element
- if (dest.ref === '_documentElement') {
- // if its parent is documentElement then it's a body
- console.debug(`[JS Framework] compile to create body for ${type}`)
- element = createBody(vm, type)
- }
- else {
- console.debug(`[JS Framework] compile to create element for ${type}`)
- element = createElement(vm, type)
- }
-
- if (!vm._rootEl) {
- vm._rootEl = element
- // bind event earlier because of lifecycle issues
- const binding = vm._externalBinding || {}
- const target = binding.template
- const parentVm = binding.parent
- if (target && target.events && parentVm && element) {
- for (const type in target.events) {
- const handler = parentVm[target.events[type]]
- if (handler) {
- element.addEvent(type, bind(handler, parentVm))
- }
- }
- }
- }
-
- bindElement(vm, element, template)
-
- if (template.attr && template.attr.append) { // backward, append prop in attr
- template.append = template.attr.append
- }
-
- if (template.append) { // give the append attribute for ios adaptation
- element.attr = element.attr || {}
- element.attr.append = template.append
- }
-
- const treeMode = template.append === 'tree'
- const app = vm._app || {}
- if (app.lastSignal !== -1 && !treeMode) {
- console.debug('[JS Framework] compile to append single node for', element)
- app.lastSignal = attachTarget(vm, element, dest)
- }
- if (app.lastSignal !== -1) {
- compileChildren(vm, template, element)
- }
- if (app.lastSignal !== -1 && treeMode) {
- console.debug('[JS Framework] compile to append whole tree for', element)
- app.lastSignal = attachTarget(vm, element, dest)
- }
-}
-
-/**
- * Set all children to a certain parent element.
- *
- * @param {object} template
- * @param {object} dest
- */
-function compileChildren (vm, template, dest) {
- const app = vm._app || {}
- const children = template.children
- if (children && children.length) {
- children.every((child) => {
- compile(vm, child, dest)
- return app.lastSignal !== -1
- })
- }
-}
-
-/**
- * Watch the list update and refresh the changes.
- *
- * @param {object} target
- * @param {object} fragBlock {vms, data, children}
- * @param {object} info {getter, key, value, trackBy, oldStyle}
- */
-function bindRepeat (vm, target, fragBlock, info) {
- const vms = fragBlock.vms
- const children = fragBlock.children
- const { getter, trackBy, oldStyle } = info
- const keyName = info.key
- const valueName = info.value
-
- function compileItem (item, index, context) {
- let mergedData
- if (oldStyle) {
- mergedData = item
- if (isObject(item)) {
- mergedData[keyName] = index
- if (!mergedData.hasOwnProperty('INDEX')) {
- Object.defineProperty(mergedData, 'INDEX', {
- value: () => {
- console.warn('[JS Framework] "INDEX" in repeat is deprecated, ' +
- 'please use "$index" instead')
- }
- })
- }
- }
- else {
- console.warn('[JS Framework] Each list item must be an object in old-style repeat, '
- + 'please use `repeat={{v in list}}` instead.')
- mergedData = {}
- mergedData[keyName] = index
- mergedData[valueName] = item
- }
- }
- else {
- mergedData = {}
- mergedData[keyName] = index
- mergedData[valueName] = item
- }
- const newContext = mergeContext(context, mergedData)
- vms.push(newContext)
- compile(newContext, target, fragBlock, { repeat: item })
- }
-
- const list = watchBlock(vm, fragBlock, getter, 'repeat',
- (data) => {
- console.debug('[JS Framework] the "repeat" item has changed', data)
- if (!fragBlock || !data) {
- return
- }
-
- const oldChildren = children.slice()
- const oldVms = vms.slice()
- const oldData = fragBlock.data.slice()
- // 1. collect all new refs track by
- const trackMap = {}
- const reusedMap = {}
- data.forEach((item, index) => {
- const key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index)
- /* istanbul ignore if */
- if (key == null || key === '') {
- return
- }
- trackMap[key] = item
- })
-
- // 2. remove unused element foreach old item
- const reusedList = []
- oldData.forEach((item, index) => {
- const key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index)
- if (trackMap.hasOwnProperty(key)) {
- reusedMap[key] = {
- item, index, key,
- target: oldChildren[index],
- vm: oldVms[index]
- }
- reusedList.push(item)
- }
- else {
- removeTarget(vm, oldChildren[index])
- }
- })
-
- // 3. create new element foreach new item
- children.length = 0
- vms.length = 0
- fragBlock.data = data.slice()
- fragBlock.updateMark = fragBlock.start
-
- data.forEach((item, index) => {
- const key = trackBy ? item[trackBy] : (oldStyle ? item[keyName] : index)
- const reused = reusedMap[key]
- if (reused) {
- if (reused.item === reusedList[0]) {
- reusedList.shift()
- }
- else {
- reusedList.$remove(reused.item)
- moveTarget(vm, reused.target, fragBlock.updateMark, true)
- }
- children.push(reused.target)
- vms.push(reused.vm)
- if (oldStyle) {
- reused.vm = item
- }
- else {
- reused.vm[valueName] = item
- }
- reused.vm[keyName] = index
- fragBlock.updateMark = reused.target
- }
- else {
- compileItem(item, index, vm)
- }
- })
-
- delete fragBlock.updateMark
- }
- )
-
- fragBlock.data = list.slice(0)
- list.forEach((item, index) => {
- compileItem(item, index, vm)
- })
-}
-
-/**
- * Watch the display update and add/remove the element.
- *
- * @param {object} target
- * @param {object} fragBlock
- * @param {object} context
- */
-function bindShown (vm, target, fragBlock, meta) {
- const display = watchBlock(vm, fragBlock, target.shown, 'shown',
- (display) => {
- console.debug('[JS Framework] the "if" item was changed', display)
-
- if (!fragBlock || !!fragBlock.display === !!display) {
- return
- }
- fragBlock.display = !!display
- if (display) {
- compile(vm, target, fragBlock, meta)
- }
- else {
- removeTarget(vm, fragBlock, true)
- }
- }
- )
-
- fragBlock.display = !!display
- if (display) {
- compile(vm, target, fragBlock, meta)
- }
-}
-
-/**
- * Watch calc value changes and append certain type action to differ.
- * It is used for if or repeat data-binding generator.
- *
- * @param {object} fragBlock
- * @param {function} calc
- * @param {string} type
- * @param {function} handler
- * @return {any} init value of calc
- */
-function watchBlock (vm, fragBlock, calc, type, handler) {
- const differ = vm && vm._app && vm._app.differ
- const config = {}
- const depth = (fragBlock.element.depth || 0) + 1
-
- return watch(vm, calc, (value) => {
- config.latestValue = value
- if (differ && !config.recorded) {
- differ.append(type, depth, fragBlock.blockId, () => {
- const latestValue = config.latestValue
- handler(latestValue)
- config.recorded = false
- config.latestValue = undefined
- })
- }
- config.recorded = true
- })
-}
-
-/**
- * Clone a context and merge certain data.
- *
- * @param {object} mergedData
- * @return {object}
- */
-function mergeContext (context, mergedData) {
- const newContext = Object.create(context)
- newContext._data = mergedData
- initData(newContext)
- initComputed(newContext)
- newContext._realParent = context
- if (context._static) {
- newContext._static = context._static
- }
- return newContext
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/vm/directive.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/vm/directive.js b/html5/frameworks/legacy/vm/directive.js
deleted file mode 100644
index 77ccd9a..0000000
--- a/html5/frameworks/legacy/vm/directive.js
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * Directive Parser
- */
-
-import { bind, typof } from '../util/index'
-import Watcher from '../core/watcher'
-import config from '../config'
-
-const { nativeComponentMap } = config
-
-const SETTERS = {
- attr: 'setAttr',
- style: 'setStyle',
- event: 'addEvent'
-}
-
-/**
- * apply the native component's options(specified by template.type)
- * to the template
- */
-export function applyNaitveComponentOptions (template) {
- const { type } = template
- const options = nativeComponentMap[type]
-
- if (typeof options === 'object') {
- for (const key in options) {
- if (template[key] == null) {
- template[key] = options[key]
- }
- else if (typof(template[key]) === 'object' &&
- typof(options[key]) === 'object') {
- for (const subkey in options[key]) {
- if (template[key][subkey] == null) {
- template[key][subkey] = options[key][subkey]
- }
- }
- }
- }
- }
-}
-
-/**
- * bind all id, attr, classnames, style, events to an element
- */
-export function bindElement (vm, el, template) {
- setId(vm, el, template.id, vm)
- setAttr(vm, el, template.attr)
- setClass(vm, el, template.classList)
- setStyle(vm, el, template.style)
- bindEvents(vm, el, template.events)
-}
-
-/**
- * bind all props to sub vm and bind all style, events to the root element
- * of the sub vm if it doesn't have a replaced multi-node fragment
- */
-export function bindSubVm (vm, subVm, template, repeatItem) {
- subVm = subVm || {}
- template = template || {}
-
- const options = subVm._options || {}
-
- // bind props
- let props = options.props
-
- if (Array.isArray(props)) {
- props = props.reduce((result, value) => {
- result[value] = true
- return result
- }, {})
- }
-
- mergeProps(repeatItem, props, vm, subVm)
- mergeProps(template.attr, props, vm, subVm)
-}
-
-/**
- * merge class and styles from vm to sub vm.
- */
-export function bindSubVmAfterInitialized (vm, subVm, template, target = {}) {
- mergeClassStyle(template.classList, vm, subVm)
- mergeStyle(template.style, vm, subVm)
-
- // bind subVm to the target element
- if (target.children) {
- target.children[target.children.length - 1]._vm = subVm
- }
- else {
- target._vm = subVm
- }
-}
-
-/**
- * Bind props from vm to sub vm and watch their updates.
- */
-function mergeProps (target, props, vm, subVm) {
- if (!target) {
- return
- }
- for (const key in target) {
- if (!props || props[key]) {
- const value = target[key]
- if (typeof value === 'function') {
- const returnValue = watch(vm, value, function (v) {
- subVm[key] = v
- })
- subVm[key] = returnValue
- }
- else {
- subVm[key] = value
- }
- }
- }
-}
-
-/**
- * Bind style from vm to sub vm and watch their updates.
- */
-function mergeStyle (target, vm, subVm) {
- for (const key in target) {
- const value = target[key]
- if (typeof value === 'function') {
- const returnValue = watch(vm, value, function (v) {
- if (subVm._rootEl) {
- subVm._rootEl.setStyle(key, v)
- }
- })
- subVm._rootEl.setStyle(key, returnValue)
- }
- else {
- if (subVm._rootEl) {
- subVm._rootEl.setStyle(key, value)
- }
- }
- }
-}
-
-/**
- * Bind class & style from vm to sub vm and watch their updates.
- */
-function mergeClassStyle (target, vm, subVm) {
- const css = vm._options && vm._options.style || {}
-
- /* istanbul ignore if */
- if (!subVm._rootEl) {
- return
- }
-
- const className = '@originalRootEl'
- css[className] = subVm._rootEl.classStyle
-
- function addClassName (list, name) {
- if (typof(list) === 'array') {
- list.unshift(name)
- }
- }
-
- if (typeof target === 'function') {
- const value = watch(vm, target, v => {
- addClassName(v, className)
- setClassStyle(subVm._rootEl, css, v)
- })
- addClassName(value, className)
- setClassStyle(subVm._rootEl, css, value)
- }
- else if (target != null) {
- addClassName(target, className)
- setClassStyle(subVm._rootEl, css, target)
- }
-}
-
-/**
- * bind id to an element
- * each id is unique in a whole vm
- */
-export function setId (vm, el, id, target) {
- const map = Object.create(null)
-
- Object.defineProperties(map, {
- vm: {
- value: target,
- writable: false,
- configurable: false
- },
- el: {
- get: () => el || target._rootEl,
- configurable: false
- }
- })
-
- if (typeof id === 'function') {
- const handler = id
- id = handler.call(vm)
- if (id || id === 0) {
- vm._ids[id] = map
- }
- watch(vm, handler, (newId) => {
- if (newId) {
- vm._ids[newId] = map
- }
- })
- }
- else if (id && typeof id === 'string') {
- vm._ids[id] = map
- }
-}
-
-/**
- * bind attr to an element
- */
-function setAttr (vm, el, attr) {
- bindDir(vm, el, 'attr', attr)
-}
-
-function setClassStyle (el, css, classList) {
- if (typeof classList === 'string') {
- classList = classList.split(/\s+/)
- }
- classList.forEach((name, i) => {
- classList.splice(i, 1, ...name.split(/\s+/))
- })
- const classStyle = {}
- const length = classList.length
-
- for (let i = 0; i < length; i++) {
- const style = css[classList[i]]
- if (style) {
- Object.keys(style).forEach((key) => {
- classStyle[key] = style[key]
- })
- }
- }
- el.setClassStyle(classStyle)
-}
-
-/**
- * bind classnames to an element
- */
-function setClass (vm, el, classList) {
- if (typeof classList !== 'function' && !Array.isArray(classList)) {
- return
- }
- if (Array.isArray(classList) && !classList.length) {
- el.setClassStyle({})
- return
- }
-
- const style = vm._options && vm._options.style || {}
- if (typeof classList === 'function') {
- const value = watch(vm, classList, v => {
- setClassStyle(el, style, v)
- })
- setClassStyle(el, style, value)
- }
- else {
- setClassStyle(el, style, classList)
- }
-}
-
-/**
- * bind style to an element
- */
-function setStyle (vm, el, style) {
- bindDir(vm, el, 'style', style)
-}
-
-/**
- * add an event type and handler to an element and generate a dom update
- */
-function setEvent (vm, el, type, handler) {
- el.addEvent(type, bind(handler, vm))
-}
-
-/**
- * add all events of an element
- */
-function bindEvents (vm, el, events) {
- if (!events) {
- return
- }
- const keys = Object.keys(events)
- let i = keys.length
- while (i--) {
- const key = keys[i]
- let handler = events[key]
- if (typeof handler === 'string') {
- handler = vm[handler]
- /* istanbul ignore if */
- if (!handler) {
- console.warn(`[JS Framework] The event handler "${handler}" is not defined.`)
- }
- }
- setEvent(vm, el, key, handler)
- }
-}
-
-/**
- * set a series of members as a kind of an element
- * for example: style, attr, ...
- * if the value is a function then bind the data changes
- */
-function bindDir (vm, el, name, data) {
- if (!data) {
- return
- }
- const keys = Object.keys(data)
- let i = keys.length
- while (i--) {
- const key = keys[i]
- const value = data[key]
- if (typeof value === 'function') {
- bindKey(vm, el, name, key, value)
- }
- else {
- el[SETTERS[name]](key, value)
- }
- }
-}
-
-/**
- * bind data changes to a certain key to a name series in an element
- */
-function bindKey (vm, el, name, key, calc) {
- const methodName = SETTERS[name]
- // watch the calc, and returns a value by calc.call()
- const value = watch(vm, calc, (value) => {
- function handler () {
- el[methodName](key, value)
- }
- const differ = vm && vm._app && vm._app.differ
- if (differ) {
- differ.append('element', el.depth || 0, el.ref, handler)
- }
- else {
- handler()
- }
- })
-
- el[methodName](key, value)
-}
-
-/**
- * watch a calc function and callback if the calc value changes
- */
-export function watch (vm, calc, callback) {
- if (vm._static) {
- return calc.call(vm, vm)
- }
- const watcher = new Watcher(vm, calc, function (value, oldValue) {
- /* istanbul ignore if */
- if (typeof value !== 'object' && value === oldValue) {
- return
- }
- callback(value)
- })
-
- return watcher.value
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/vm/dom-helper.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/vm/dom-helper.js b/html5/frameworks/legacy/vm/dom-helper.js
deleted file mode 100644
index 6e5a800..0000000
--- a/html5/frameworks/legacy/vm/dom-helper.js
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview Document & Element Helpers.
- *
- * required:
- * Document#: createElement, createComment, getRef
- * Element#: appendChild, insertBefore, removeChild, nextSibling
- */
-
-/**
- * Create a body by type
- * Using this._app.doc
- *
- * @param {string} type
- */
-export function createBody (vm, type) {
- const doc = vm._app.doc
- return doc.createBody(type)
-}
-
-/**
- * Create an element by type
- * Using this._app.doc
- *
- * @param {string} type
- */
-export function createElement (vm, type) {
- const doc = vm._app.doc
- return doc.createElement(type)
-}
-
-/**
- * Create and return a frag block for an element.
- * The frag block has a starter, ender and the element itself.
- *
- * @param {object} element
- */
-export function createBlock (vm, element) {
- const start = createBlockStart(vm)
- const end = createBlockEnd(vm)
- const blockId = lastestBlockId++
- if (element.element) {
- let updateMark = element.updateMark
- if (updateMark) {
- if (updateMark.element) {
- updateMark = updateMark.end
- }
- element.element.insertAfter(end, updateMark)
- element.element.insertAfter(start, updateMark)
- element.updateMark = end
- }
- else {
- element.element.insertBefore(start, element.end)
- element.element.insertBefore(end, element.end)
- }
- element = element.element
- }
- else {
- element.appendChild(start)
- element.appendChild(end)
- }
- return { start, end, element, blockId }
-}
-
-let lastestBlockId = 1
-
-/**
- * Create and return a block starter.
- * Using this._app.doc
- */
-function createBlockStart (vm) {
- const doc = vm._app.doc
- const anchor = doc.createComment('start')
- return anchor
-}
-
-/**
- * Create and return a block ender.
- * Using this._app.doc
- */
-function createBlockEnd (vm) {
- const doc = vm._app.doc
- const anchor = doc.createComment('end')
- return anchor
-}
-
-/**
- * Attach target to a certain dest using appendChild by default.
- * If the dest is a frag block then insert before the ender.
- * If the target is a frag block then attach the starter and ender in order.
- *
- * @param {object} target
- * @param {object} dest
- */
-export function attachTarget (vm, target, dest) {
- if (dest.element) {
- const before = dest.end
- const after = dest.updateMark
- // push new target for watch list update later
- if (dest.children) {
- dest.children.push(target)
- }
- // for check repeat case
- if (after) {
- const signal = moveTarget(vm, target, after)
- dest.updateMark = target.element ? target.end : target
- return signal
- }
- else if (target.element) {
- dest.element.insertBefore(target.start, before)
- dest.element.insertBefore(target.end, before)
- }
- else {
- return dest.element.insertBefore(target, before)
- }
- }
- else {
- if (target.element) {
- dest.appendChild(target.start)
- dest.appendChild(target.end)
- }
- else {
- return dest.appendChild(target)
- }
- }
-}
-
-/**
- * Move target before a certain element. The target maybe block or element.
- *
- * @param {object} target
- * @param {object} before
- */
-export function moveTarget (vm, target, after) {
- if (target.element) {
- return moveBlock(target, after)
- }
- return moveElement(target, after)
-}
-
-/**
- * Move element before a certain element.
- *
- * @param {object} element
- * @param {object} before
- */
-function moveElement (element, after) {
- const parent = after.parentNode
- if (parent) {
- return parent.insertAfter(element, after)
- }
-}
-
-/**
- * Move all elements of the block before a certain element.
- *
- * @param {object} fragBlock
- * @param {object} before
- */
-function moveBlock (fragBlock, after) {
- const parent = after.parentNode
-
- if (parent) {
- let el = fragBlock.start
- let signal
- const group = [el]
-
- while (el && el !== fragBlock.end) {
- el = el.nextSibling
- group.push(el)
- }
-
- let temp = after
- group.every((el) => {
- signal = parent.insertAfter(el, temp)
- temp = el
- return signal !== -1
- })
-
- return signal
- }
-}
-
-/**
- * Remove target from DOM tree.
- * If the target is a frag block then call _removeBlock
- *
- * @param {object} target
- */
-export function removeTarget (vm, target, preserveBlock = false) {
- if (target.element) {
- removeBlock(target, preserveBlock)
- }
- else {
- removeElement(target)
- }
- if (target._vm) {
- target._vm.$emit('hook:destroyed')
- }
-}
-
-/**
- * Remove a certain element.
- * Using this._app.doc
- *
- * @param {object} target
- */
-function removeElement (target) {
- const parent = target.parentNode
-
- if (parent) {
- parent.removeChild(target)
- }
-}
-
-/**
- * Remove a frag block.
- * The second param decides whether the block self should be removed too.
- *
- * @param {object} fragBlock
- * @param {Boolean} preserveBlock=false
- */
-function removeBlock (fragBlock, preserveBlock = false) {
- const result = []
- let el = fragBlock.start.nextSibling
-
- while (el && el !== fragBlock.end) {
- result.push(el)
- el = el.nextSibling
- }
-
- if (!preserveBlock) {
- removeElement(fragBlock.start)
- }
- result.forEach((el) => {
- removeElement(el)
- })
- if (!preserveBlock) {
- removeElement(fragBlock.end)
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/vm/events.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/vm/events.js b/html5/frameworks/legacy/vm/events.js
deleted file mode 100644
index 5691472..0000000
--- a/html5/frameworks/legacy/vm/events.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * Everything about component event which includes event object, event listener,
- * event emitter and lifecycle hooks.
- */
-
-/**
- * Event object definition. An event object has `type`, `timestamp` and
- * `detail` from which a component emit. The event object could be dispatched to
- * parents or broadcasted to children except `this.stop()` is called.
- * @param {string} type
- * @param {any} detail
- */
-function Evt (type, detail) {
- if (detail instanceof Evt) {
- return detail
- }
-
- this.timestamp = Date.now()
- this.detail = detail
- this.type = type
-
- let shouldStop = false
-
- /**
- * stop dispatch and broadcast
- */
- this.stop = function () {
- shouldStop = true
- }
-
- /**
- * check if it can't be dispatched or broadcasted
- */
- this.hasStopped = function () {
- return shouldStop
- }
-}
-
-/**
- * Emit an event but not broadcast down or dispatch up.
- * @param {string} type
- * @param {any} detail
- */
-export function $emit (type, detail) {
- const events = this._vmEvents
- const handlerList = events[type]
- if (handlerList) {
- const evt = new Evt(type, detail)
- handlerList.forEach((handler) => {
- handler.call(this, evt)
- })
- }
-}
-
-/**
- * Emit an event and dispatch it up.
- * @param {string} type
- * @param {any} detail
- */
-export function $dispatch (type, detail) {
- const evt = new Evt(type, detail)
- this.$emit(type, evt)
-
- if (!evt.hasStopped() && this._parent && this._parent.$dispatch) {
- this._parent.$dispatch(type, evt)
- }
-}
-
-/**
- * Emit an event and broadcast it down.
- * @param {string} type
- * @param {any} detail
- */
-export function $broadcast (type, detail) {
- const evt = new Evt(type, detail)
- this.$emit(type, evt)
-
- if (!evt.hasStopped() && this._childrenVms) {
- this._childrenVms.forEach((subVm) => {
- subVm.$broadcast(type, evt)
- })
- }
-}
-
-/**
- * Add event listener.
- * @param {string} type
- * @param {function} handler
- */
-export function $on (type, handler) {
- if (!type || typeof handler !== 'function') {
- return
- }
- const events = this._vmEvents
- const handlerList = events[type] || []
- handlerList.push(handler)
- events[type] = handlerList
-
- // fixed old version lifecycle design
- /* istanbul ignore if */
- if (type === 'hook:ready' && this._ready) {
- this.$emit('hook:ready')
- }
-}
-
-/**
- * Remove event listener.
- * @param {string} type
- * @param {function} handler
- */
-export function $off (type, handler) {
- if (!type) {
- return
- }
- const events = this._vmEvents
- if (!handler) {
- delete events[type]
- return
- }
- const handlerList = events[type]
- if (!handlerList) {
- return
- }
- handlerList.$remove(handler)
-}
-
-const LIFE_CYCLE_TYPES = ['init', 'created', 'ready', 'destroyed']
-
-/**
- * Init events:
- * 1. listen `events` in component options & `externalEvents`.
- * 2. bind lifecycle hooks.
- * @param {Vm} vm
- * @param {object} externalEvents
- */
-export function initEvents (vm, externalEvents) {
- const options = vm._options || {}
- const events = options.events || {}
- for (const type1 in events) {
- vm.$on(type1, events[type1])
- }
- for (const type2 in externalEvents) {
- vm.$on(type2, externalEvents[type2])
- }
- LIFE_CYCLE_TYPES.forEach((type) => {
- vm.$on(`hook:${type}`, options[type])
- })
-}
-
-/**
- * Bind event related methods to ViewModel instance.
- * @param {Vm} vm
- */
-export function mixinEvents (vm) {
- vm.$emit = $emit
- vm.$dispatch = $dispatch
- vm.$broadcast = $broadcast
- vm.$on = $on
- vm.$off = $off
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/legacy/vm/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/legacy/vm/index.js b/html5/frameworks/legacy/vm/index.js
deleted file mode 100644
index 45a33af..0000000
--- a/html5/frameworks/legacy/vm/index.js
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * @fileOverview
- * ViewModel Constructor & definition
- */
-
-import { extend } from '../util/index'
-import {
- initState
-} from '../core/state'
-import {
- build
-} from './compiler'
-import {
- set,
- del
-} from '../core/observer'
-import {
- watch
-} from './directive'
-import {
- initEvents,
- mixinEvents
-} from './events'
-
-/**
- * ViewModel constructor
- *
- * @param {string} type
- * @param {object} options component options
- * @param {object} parentVm which contains _app
- * @param {object} parentEl root element or frag block
- * @param {object} mergedData external data
- * @param {object} externalEvents external events
- */
-export default function Vm (
- type,
- options,
- parentVm,
- parentEl,
- mergedData,
- externalEvents
-) {
- parentVm = parentVm || {}
- this._parent = parentVm._realParent ? parentVm._realParent : parentVm
- this._app = parentVm._app || {}
- parentVm._childrenVms && parentVm._childrenVms.push(this)
-
- if (!options && this._app.customComponentMap) {
- options = this._app.customComponentMap[type]
- }
- options = options || {}
-
- const data = options.data || {}
-
- this._options = options
- this._methods = options.methods || {}
- this._computed = options.computed || {}
- this._css = options.style || {}
- this._ids = {}
- this._vmEvents = {}
- this._childrenVms = []
- this._type = type
-
- // bind events and lifecycles
- initEvents(this, externalEvents)
-
- console.debug(`[JS Framework] "init" lifecycle in Vm(${this._type})`)
- this.$emit('hook:init')
- this._inited = true
-
- // proxy data and methods
- // observe data and add this to vms
- this._data = typeof data === 'function' ? data() : data
- if (mergedData) {
- extend(this._data, mergedData)
- }
- initState(this)
-
- console.debug(`[JS Framework] "created" lifecycle in Vm(${this._type})`)
- this.$emit('hook:created')
- this._created = true
-
- // backward old ready entry
- if (options.methods && options.methods.ready) {
- console.warn('"exports.methods.ready" is deprecated, ' +
- 'please use "exports.created" instead')
- options.methods.ready.call(this)
- }
-
- if (!this._app.doc) {
- return
- }
-
- // if no parentElement then specify the documentElement
- this._parentEl = parentEl || this._app.doc.documentElement
- build(this)
-}
-
-mixinEvents(Vm.prototype)
-
-/**
- * Watch an function and bind all the data appeared in it. When the related
- * data changes, the callback will be called with new value as 1st param.
- *
- * @param {Function} fn
- * @param {Function} callback
- */
-Vm.prototype.$watch = function (fn, callback) {
- watch(this, fn, callback)
-}
-
-Vm.set = set
-Vm.delete = del
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/frameworks/vanilla/index.js
----------------------------------------------------------------------
diff --git a/html5/frameworks/vanilla/index.js b/html5/frameworks/vanilla/index.js
deleted file mode 100644
index f3b4bc2..0000000
--- a/html5/frameworks/vanilla/index.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-const config = {}
-
-const instanceMap = {}
-
-export function init (cfg) {
- config.Document = cfg.Document
- config.Element = cfg.Element
- config.Comment = cfg.Comment
- config.sendTasks = cfg.sendTasks
-}
-
-export function createInstance (id, code, options = {}, data = {}, serviceObjects = {}) {
- const document = new config.Document(id, options.bundleUrl)
- const callbacks = {}
- const instance = { id, data, document, callbacks }
-
- let lastCallbackId = 0
- document.addCallback = func => {
- lastCallbackId++
- callbacks[lastCallbackId] = func
- return lastCallbackId
- }
- document.handleCallback = (funcId, data, ifLast) => {
- const callback = callbacks[funcId]
- if (ifLast) {
- delete callbacks[funcId]
- }
- return callback(data)
- }
- instanceMap[id] = instance
-
- const globalObjects = Object.assign({
- Document: config.Document,
- Element: config.Element,
- Comment: config.Comment,
- sendTasks: tasks => config.sendTasks(id, tasks, -1),
- options,
- document
- }, serviceObjects)
-
- const globalKeys = []
- const globalValues = []
- for (const key in globalObjects) {
- globalKeys.push(key)
- globalValues.push(globalObjects[key])
- }
- globalKeys.push(code)
-
- const result = new Function(...globalKeys)
- result(...globalValues)
-
- config.sendTasks(id, [{ module: 'dom', method: 'createFinish', args: [] }], -1)
-
- return instance
-}
-
-export function destroyInstance (id) {
- delete instanceMap[id]
-}
-
-export function getRoot (id) {
- return instanceMap[id].document.body.toJSON()
-}
-
-export function receiveTasks (id, tasks) {
- const jsHandlers = {
- fireEvent: (id, ref, type, data, domChanges) => {
- const { document } = instanceMap[id]
- const el = document.getRef(ref)
- return document.fireEvent(el, type, data, domChanges)
- },
-
- callback: (id, funcId, data, ifLast) => {
- const { document } = instanceMap[id]
- return document.handleCallback(funcId, data, ifLast)
- }
- }
-
- const { document } = instanceMap[id] || {}
- if (document && Array.isArray(tasks)) {
- const results = []
- tasks.forEach((task) => {
- const handler = jsHandlers[task.method]
- const args = [...task.args]
- if (typeof handler === 'function') {
- args.unshift(id)
- results.push(handler(...args))
- }
- })
- return results
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/render/native/index.js
----------------------------------------------------------------------
diff --git a/html5/render/native/index.js b/html5/render/native/index.js
deleted file mode 100644
index c692995..0000000
--- a/html5/render/native/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import setup from './setup'
-import frameworks from '../../frameworks/index'
-
-setup(frameworks)
[17/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/runtime/vdom/operation.js
----------------------------------------------------------------------
diff --git a/html5/runtime/vdom/operation.js b/html5/runtime/vdom/operation.js
deleted file mode 100644
index 69a64e1..0000000
--- a/html5/runtime/vdom/operation.js
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-const docMap = {}
-
-/**
- * Add a document object into docMap.
- * @param {string} id
- * @param {object} document
- */
-export function addDoc (id, doc) {
- if (id) {
- docMap[id] = doc
- }
-}
-
-/**
- * Get the document object by id.
- * @param {string} id
- */
-export function getDoc (id) {
- return docMap[id]
-}
-
-/**
- * Remove the document from docMap by id.
- * @param {string} id
- */
-export function removeDoc (id) {
- delete docMap[id]
-}
-
-/**
- * @deprecated
- * Get listener by document id.
- * @param {string} id
- * @return {object} listener
- */
-export function getListener (id) {
- const doc = docMap[id]
- if (doc && doc.listener) {
- return doc.listener
- }
- return null
-}
-
-/**
- * Get TaskCenter instance by id.
- * @param {string} id
- * @return {object} TaskCenter
- */
-export function getTaskCenter (id) {
- const doc = docMap[id]
- if (doc && doc.taskCenter) {
- return doc.taskCenter
- }
- return null
-}
-
-/**
- * Append body node to documentElement.
- * @param {object} document
- * @param {object} node
- * @param {object} before
- */
-export function appendBody (doc, node, before) {
- const { documentElement } = doc
-
- if (documentElement.pureChildren.length > 0 || node.parentNode) {
- return
- }
- const children = documentElement.children
- const beforeIndex = children.indexOf(before)
- if (beforeIndex < 0) {
- children.push(node)
- }
- else {
- children.splice(beforeIndex, 0, node)
- }
-
- if (node.nodeType === 1) {
- if (node.role === 'body') {
- node.docId = doc.id
- node.ownerDocument = doc
- node.parentNode = documentElement
- linkParent(node, documentElement)
- }
- else {
- node.children.forEach(child => {
- child.parentNode = node
- })
- setBody(doc, node)
- node.docId = doc.id
- node.ownerDocument = doc
- linkParent(node, documentElement)
- delete doc.nodeMap[node.nodeId]
- }
- documentElement.pureChildren.push(node)
- sendBody(doc, node)
- }
- else {
- node.parentNode = documentElement
- doc.nodeMap[node.ref] = node
- }
-}
-
-function sendBody (doc, node) {
- const body = node.toJSON()
- if (doc && doc.taskCenter && typeof doc.taskCenter.send === 'function') {
- doc.taskCenter.send('dom', { action: 'createBody' }, [body])
- }
-}
-
-/**
- * Set up body node.
- * @param {object} document
- * @param {object} element
- */
-export function setBody (doc, el) {
- el.role = 'body'
- el.depth = 1
- delete doc.nodeMap[el.nodeId]
- el.ref = '_root'
- doc.nodeMap._root = el
- doc.body = el
-}
-
-/**
- * Establish the connection between parent and child node.
- * @param {object} child node
- * @param {object} parent node
- */
-export function linkParent (node, parent) {
- node.parentNode = parent
- if (parent.docId) {
- node.docId = parent.docId
- node.ownerDocument = parent.ownerDocument
- node.ownerDocument.nodeMap[node.nodeId] = node
- node.depth = parent.depth + 1
- }
- node.children.forEach(child => {
- linkParent(child, node)
- })
-}
-
-/**
- * Get the next sibling element.
- * @param {object} node
- */
-export function nextElement (node) {
- while (node) {
- if (node.nodeType === 1) {
- return node
- }
- node = node.nextSibling
- }
-}
-
-/**
- * Get the previous sibling element.
- * @param {object} node
- */
-export function previousElement (node) {
- while (node) {
- if (node.nodeType === 1) {
- return node
- }
- node = node.previousSibling
- }
-}
-
-/**
- * Insert a node into list at the specified index.
- * @param {object} target node
- * @param {array} list
- * @param {number} newIndex
- * @param {boolean} changeSibling
- * @return {number} newIndex
- */
-export function insertIndex (target, list, newIndex, changeSibling) {
- /* istanbul ignore next */
- if (newIndex < 0) {
- newIndex = 0
- }
- const before = list[newIndex - 1]
- const after = list[newIndex]
- list.splice(newIndex, 0, target)
- if (changeSibling) {
- before && (before.nextSibling = target)
- target.previousSibling = before
- target.nextSibling = after
- after && (after.previousSibling = target)
- }
- return newIndex
-}
-
-/**
- * Move the node to a new index in list.
- * @param {object} target node
- * @param {array} list
- * @param {number} newIndex
- * @param {boolean} changeSibling
- * @return {number} newIndex
- */
-export function moveIndex (target, list, newIndex, changeSibling) {
- const index = list.indexOf(target)
- /* istanbul ignore next */
- if (index < 0) {
- return -1
- }
- if (changeSibling) {
- const before = list[index - 1]
- const after = list[index + 1]
- before && (before.nextSibling = after)
- after && (after.previousSibling = before)
- }
- list.splice(index, 1)
- let newIndexAfter = newIndex
- if (index <= newIndex) {
- newIndexAfter = newIndex - 1
- }
- const beforeNew = list[newIndexAfter - 1]
- const afterNew = list[newIndexAfter]
- list.splice(newIndexAfter, 0, target)
- if (changeSibling) {
- beforeNew && (beforeNew.nextSibling = target)
- target.previousSibling = beforeNew
- target.nextSibling = afterNew
- afterNew && (afterNew.previousSibling = target)
- }
- if (index === newIndexAfter) {
- return -1
- }
- return newIndex
-}
-
-/**
- * Remove the node from list.
- * @param {object} target node
- * @param {array} list
- * @param {boolean} changeSibling
- */
-export function removeIndex (target, list, changeSibling) {
- const index = list.indexOf(target)
- /* istanbul ignore next */
- if (index < 0) {
- return
- }
- if (changeSibling) {
- const before = list[index - 1]
- const after = list[index + 1]
- before && (before.nextSibling = after)
- after && (after.previousSibling = before)
- }
- list.splice(index, 1)
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/services/amd/index.js
----------------------------------------------------------------------
diff --git a/html5/services/amd/index.js b/html5/services/amd/index.js
deleted file mode 100644
index 3a7a491..0000000
--- a/html5/services/amd/index.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @fileOverview
- * A simple implementation of AMD for weex.
- */
-
-/**
- * amd modules (<id, module> pair)
- * - id : instance id.
- * - module: {
- * name: module name
- * , factory: module's factory function
- * , cached: cached module,
- * , deps: module's dependencies, always be [] under most circumstances.
- * }
- */
-const modules = {}
-
-const amdService = {
-
- // create a amd service.
- create: (id, env, config) => {
- if (!env.framework.match(/Vue/i)) {
- return
- }
-
- const mod = {}
- modules[id] = mod
- const amdObject = {
-
- /**
- * define a module.
- * @param {String} name: module name.
- * @param {Array} deps: dependencies. Always be empty array.
- * @param {function} factory: factory function.
- */
- define (name, deps, factory) {
- if (mod[name]) {
- console.warn(`[amdService] already defined module: '${name}'`)
- }
- if (typeof deps === 'function') {
- factory = deps
- deps = []
- }
- mod[name] = { name, factory, cached: false, deps }
- },
-
- /**
- * require a module.
- * @param {string} name - module name.
- */
- require (name) {
- const servMod = mod[name]
- if (!servMod) {
- return console.warn(`[amdService] module '${name}' is not defined.`)
- }
- if (servMod.cached) {
- return servMod.cached
- }
- const exports = {}
- const module = { exports }
- const { deps } = servMod
- let ret
- if (deps && deps.length >= 1) {
- /**
- * to support:
- * define(name, ['foo', 'bar'], function (foo, bar) { ... })
- */
- const args = deps.map(depName => require(depName))
- ret = servMod.factory(...args)
- }
- else {
- ret = servMod.factory(amdObject.require, exports, module)
- }
- servMod.cached = ret || module.exports
- return servMod.cached
- }
- }
- return { instance: amdObject }
- },
-
- destroy: (id, env) => {
- delete modules[id]
- }
-}
-
-export default amdService
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/services/broadcast-channel/index.js
----------------------------------------------------------------------
diff --git a/html5/services/broadcast-channel/index.js b/html5/services/broadcast-channel/index.js
deleted file mode 100644
index cc7524e..0000000
--- a/html5/services/broadcast-channel/index.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @fileOverview
- * The polyfill of BroadcastChannel API.
- * This api can be used to achieve inter-instance communications.
- *
- * https://html.spec.whatwg.org/multipage/comms.html#broadcasting-to-other-browsing-contexts
- */
-
-import { MessageEvent } from './message-event'
-
-const channels = {}
-const instances = {}
-
-/**
- * An empty constructor for BroadcastChannel polyfill.
- * The real constructor will be defined when a Weex instance created because
- * we need to track the channel by Weex instance id.
- */
-function BroadcastChannel () {}
-
-/**
- * Sends the given message to other BroadcastChannel objects set up for this channel.
- * @param {any} message
- */
-BroadcastChannel.prototype.postMessage = function (message) {
- if (this._closed) {
- throw new Error(`BroadcastChannel "${this.name}" is closed.`)
- }
-
- const subscribers = channels[this.name]
- if (subscribers && subscribers.length) {
- for (let i = 0; i < subscribers.length; ++i) {
- const member = subscribers[i]
-
- if (member._closed || member === this) continue
-
- if (typeof member.onmessage === 'function') {
- member.onmessage(new MessageEvent('message', { data: message }))
- }
- }
- }
-}
-
-/**
- * Closes the BroadcastChannel object, opening it up to garbage collection.
- */
-BroadcastChannel.prototype.close = function () {
- if (this._closed) {
- return
- }
-
- this._closed = true
-
- // remove itself from channels.
- if (channels[this.name]) {
- const subscribers = channels[this.name].filter(x => x !== this)
- if (subscribers.length) {
- channels[this.name] = subscribers
- }
- else {
- delete channels[this.name]
- }
- }
-}
-
-export default {
- create: (id, env, config) => {
- instances[id] = []
- if (typeof global.BroadcastChannel === 'function') {
- return {}
- }
- const serviceObject = {
- /**
- * Returns a new BroadcastChannel object via which messages for the given
- * channel name can be sent and received.
- * @param {string} name
- */
- BroadcastChannel: function (name) {
- // the name property is readonly
- Object.defineProperty(this, 'name', {
- configurable: false,
- enumerable: true,
- writable: false,
- value: String(name)
- })
-
- this._closed = false
- this.onmessage = null
-
- if (!channels[this.name]) {
- channels[this.name] = []
- }
- channels[this.name].push(this)
- instances[id].push(this)
- }
- }
- serviceObject.BroadcastChannel.prototype = BroadcastChannel.prototype
- return {
- instance: serviceObject
- }
- },
- destroy: (id, env) => {
- instances[id].forEach(channel => channel.close())
- delete instances[id]
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/services/broadcast-channel/message-event.js
----------------------------------------------------------------------
diff --git a/html5/services/broadcast-channel/message-event.js b/html5/services/broadcast-channel/message-event.js
deleted file mode 100644
index 00fa36a..0000000
--- a/html5/services/broadcast-channel/message-event.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Mock MessageEvent type
- * @param {string} type
- * @param {object} dict { data, origin, source, ports }
- *
- * This type has been simplified.
- * https://html.spec.whatwg.org/multipage/comms.html#messageevent
- * https://dom.spec.whatwg.org/#interface-event
- */
-export function MessageEvent (type, dict = {}) {
- this.type = type || 'message'
-
- this.data = dict.data || null
- this.origin = dict.origin || ''
- this.source = dict.source || null
- this.ports = dict.ports || []
-
- // inherit properties
- this.target = null
- this.timeStamp = Date.now()
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/services/index.js
----------------------------------------------------------------------
diff --git a/html5/services/index.js b/html5/services/index.js
deleted file mode 100644
index 52cd97d..0000000
--- a/html5/services/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import BroadcastChannel from './broadcast-channel/index'
-
-export default {
- BroadcastChannel
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/arrayFrom.js
----------------------------------------------------------------------
diff --git a/html5/shared/arrayFrom.js b/html5/shared/arrayFrom.js
deleted file mode 100644
index af5e78c..0000000
--- a/html5/shared/arrayFrom.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/* eslint-disable */
-
-// Production steps of ECMA-262, Edition 6, 22.1.2.1
-// Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
-
-/* istanbul ignore if */
-if (!Array.from) {
- Array.from = (function() {
- var toStr = Object.prototype.toString;
- var isCallable = function(fn) {
- return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
- };
- var toInteger = function(value) {
- var number = Number(value);
- if (isNaN(number)) {
- return 0;
- }
- if (number === 0 || !isFinite(number)) {
- return number;
- }
- return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
- };
- var maxSafeInteger = Math.pow(2, 53) - 1;
- var toLength = function(value) {
- var len = toInteger(value);
- return Math.min(Math.max(len, 0), maxSafeInteger);
- };
-
- // The length property of the from method is 1.
- return function from(arrayLike/*, mapFn, thisArg */) {
- // 1. Let C be the this value.
- var C = this;
-
- // 2. Let items be ToObject(arrayLike).
- var items = Object(arrayLike);
-
- // 3. ReturnIfAbrupt(items).
- if (arrayLike == null) {
- throw new TypeError('Array.from requires an array-like object - not null or undefined');
- }
-
- // 4. If mapfn is undefined, then let mapping be false.
- var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
- var T;
- if (typeof mapFn !== 'undefined') {
- // 5. else
- // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
- if (!isCallable(mapFn)) {
- throw new TypeError('Array.from: when provided, the second argument must be a function');
- }
-
- // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
- if (arguments.length > 2) {
- T = arguments[2];
- }
- }
-
- // 10. Let lenValue be Get(items, "length").
- // 11. Let len be ToLength(lenValue).
- var len = toLength(items.length);
-
- // 13. If IsConstructor(C) is true, then
- // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
- // 14. a. Else, Let A be ArrayCreate(len).
- var A = isCallable(C) ? Object(new C(len)) : new Array(len);
-
- // 16. Let k be 0.
- var k = 0;
- // 17. Repeat, while k < len… (also steps a - h)
- var kValue;
- while (k < len) {
- kValue = items[k];
- if (mapFn) {
- A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
- } else {
- A[k] = kValue;
- }
- k += 1;
- }
- // 18. Let putStatus be Put(A, "length", len, true).
- A.length = len;
- // 20. Return A.
- return A;
- };
- }());
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/console.js
----------------------------------------------------------------------
diff --git a/html5/shared/console.js b/html5/shared/console.js
deleted file mode 100644
index eb54815..0000000
--- a/html5/shared/console.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @fileOverview
- * This file will hack `console` methods by `WXEnvironment.logLevel`.
- * So we can control how many and which messages will be sent by change the log level.
- * Additionally in native platform the message content must be primitive values and
- * using `nativeLog(...args, logLevelMark)` so we create a new `console` object in
- * global add a format process for its methods.
- */
-
-const LEVELS = ['off', 'error', 'warn', 'info', 'log', 'debug']
-let levelMap = {}
-
-const originalConsole = global.console
-
-/**
- * Hack console for native environment.
- */
-export function setNativeConsole () {
- generateLevelMap()
-
- /* istanbul ignore next */
- // mock console in native environment
- if (global.WXEnvironment && global.WXEnvironment.platform !== 'Web') {
- global.console = {
- debug: (...args) => {
- if (checkLevel('debug')) { global.nativeLog(...format(args), '__DEBUG') }
- },
- log: (...args) => {
- if (checkLevel('log')) { global.nativeLog(...format(args), '__LOG') }
- },
- info: (...args) => {
- if (checkLevel('info')) { global.nativeLog(...format(args), '__INFO') }
- },
- warn: (...args) => {
- if (checkLevel('warn')) { global.nativeLog(...format(args), '__WARN') }
- },
- error: (...args) => {
- if (checkLevel('error')) { global.nativeLog(...format(args), '__ERROR') }
- }
- }
- }
-
- // Web or Node
- else {
- const { debug, log, info, warn, error } = console
- console.__ori__ = { debug, log, info, warn, error }
- console.debug = (...args) => {
- if (checkLevel('debug')) { console.__ori__.debug.apply(console, args) }
- }
- console.log = (...args) => {
- if (checkLevel('log')) { console.__ori__.log.apply(console, args) }
- }
- console.info = (...args) => {
- if (checkLevel('info')) { console.__ori__.info.apply(console, args) }
- }
- console.warn = (...args) => {
- if (checkLevel('warn')) { console.__ori__.warn.apply(console, args) }
- }
- console.error = (...args) => {
- if (checkLevel('error')) { console.__ori__.error.apply(console, args) }
- }
- }
-}
-
-/**
- * Reset hacked console to original.
- */
-/* istanbul ignore next */
-export function resetNativeConsole () {
- levelMap = {}
- global.console = originalConsole
-}
-
-/**
- * Generate map for which types of message will be sent in a certain message level
- * as the order of LEVELS.
- */
-function generateLevelMap () {
- LEVELS.forEach(level => {
- const levelIndex = LEVELS.indexOf(level)
- levelMap[level] = {}
- LEVELS.forEach(type => {
- const typeIndex = LEVELS.indexOf(type)
- if (typeIndex <= levelIndex) {
- levelMap[level][type] = true
- }
- })
- })
-}
-
-/**
- * Check if a certain type of message will be sent in current log level of env.
- * @param {string} type
- * @return {boolean}
- */
-function checkLevel (type) {
- const logLevel = (global.WXEnvironment && global.WXEnvironment.logLevel) || 'log'
- return levelMap[logLevel] && levelMap[logLevel][type]
-}
-
-/**
- * Convert all log arguments into primitive values.
- * @param {array} args
- * @return {array}
- */
-/* istanbul ignore next */
-function format (args) {
- return args.map((v) => {
- const type = Object.prototype.toString.call(v)
- if (type.toLowerCase() === '[object object]') {
- v = JSON.stringify(v)
- }
- else {
- v = String(v)
- }
- return v
- })
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/freeze.js
----------------------------------------------------------------------
diff --git a/html5/shared/freeze.js b/html5/shared/freeze.js
deleted file mode 100644
index f997a5f..0000000
--- a/html5/shared/freeze.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * Freeze the prototype of javascript build-in objects.
- */
-/* istanbul ignore next */
-export function freezePrototype () {
- Object.freeze(Object)
- Object.freeze(Array)
-
- // Object.freeze(Object.prototype)
- freezeObjectProto()
- Object.freeze(Array.prototype)
- Object.freeze(String.prototype)
- Object.freeze(Number.prototype)
- Object.freeze(Boolean.prototype)
-
- // Object.freeze(Error.prototype)
- freezeErrorProto()
- Object.freeze(Date.prototype)
- Object.freeze(RegExp.prototype)
-}
-
-function freezeObjectProto () {
- const proto = Object.prototype
- const protoName = 'Object.prototype'
- freezeProtoProperty(proto, '__defineGetter__', protoName)
- freezeProtoProperty(proto, '__defineSetter__', protoName)
- freezeProtoProperty(proto, '__lookupGetter__', protoName)
- freezeProtoProperty(proto, '__lookupSetter__', protoName)
- freezeProtoProperty(proto, 'constructor', protoName)
- freezeProtoProperty(proto, 'hasOwnProperty', protoName)
- freezeProtoProperty(proto, 'isPrototypeOf', protoName)
- freezeProtoProperty(proto, 'propertyIsEnumerable', protoName)
- freezeProtoProperty(proto, 'toLocaleString', protoName)
- freezeProtoProperty(proto, 'toString', protoName)
- freezeProtoProperty(proto, 'valueOf', protoName)
- Object.seal(proto)
-}
-
-function freezeErrorProto () {
- const proto = Error.prototype
- const protoName = 'Error.prototype'
- freezeProtoProperty(proto, 'name', protoName)
- freezeProtoProperty(proto, 'message', protoName)
- freezeProtoProperty(proto, 'toString', protoName)
- freezeProtoProperty(proto, 'constructor', protoName)
- Object.seal(proto)
-}
-
-function freezeProtoProperty (proto, propertyName, protoName) {
- if (!proto.hasOwnProperty(propertyName)) {
- return
- }
-
- const origin = proto[propertyName]
- Object.defineProperty(proto, propertyName, {
- get: function () {
- return origin
- },
- set: function (value) {
- if (this === proto) {
- throw Error(`Cannot assign to read only property ${propertyName} of ${protoName}`)
- }
-
- Object.defineProperty(this, propertyName, {
- value: value,
- writable: true
- })
-
- return value
- }
- })
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/index.js
----------------------------------------------------------------------
diff --git a/html5/shared/index.js b/html5/shared/index.js
deleted file mode 100644
index 27b95c3..0000000
--- a/html5/shared/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import './arrayFrom'
-import './objectAssign'
-import './objectSetPrototypeOf'
-
-// import promise hack and polyfills
-import './promise'
-import 'core-js/modules/es6.object.to-string'
-import 'core-js/modules/es6.string.iterator'
-import 'core-js/modules/web.dom.iterable'
-import 'core-js/modules/es6.promise'
-
-export * from './console'
-export * from './setTimeout'
-export * from './freeze'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/objectAssign.js
----------------------------------------------------------------------
diff --git a/html5/shared/objectAssign.js b/html5/shared/objectAssign.js
deleted file mode 100644
index 7aa5993..0000000
--- a/html5/shared/objectAssign.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import 'core-js/fn/object/assign'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/objectSetPrototypeOf.js
----------------------------------------------------------------------
diff --git a/html5/shared/objectSetPrototypeOf.js b/html5/shared/objectSetPrototypeOf.js
deleted file mode 100644
index 6364ce4..0000000
--- a/html5/shared/objectSetPrototypeOf.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/* eslint-disable */
-
-// https://gist.github.com/WebReflection/5593554
-
-/* istanbul ignore if */
-if (!Object.setPrototypeOf) {
- Object.setPrototypeOf = (function(Object, magic) {
- var set;
- function setPrototypeOf(O, proto) {
- set.call(O, proto);
- return O;
- }
- try {
- // this works already in Firefox and Safari
- set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set;
- set.call({}, null);
- } catch (e) {
- if (
- // IE < 11 cannot be shimmed
- Object.prototype !== {}[magic] ||
- // neither can any browser that actually
- // implemented __proto__ correctly
- // (all but old V8 will return here)
- {__proto__: null}.__proto__ === void 0
- // this case means null objects cannot be passed
- // through setPrototypeOf in a reliable way
- // which means here a **Sham** is needed instead
- ) {
- return;
- }
- // nodejs 0.8 and 0.10 are (buggy and..) fine here
- // probably Chrome or some old Mobile stock browser
- set = function(proto) {
- this[magic] = proto;
- };
- // please note that this will **not** work
- // in those browsers that do not inherit
- // __proto__ by mistake from Object.prototype
- // in these cases we should probably throw an error
- // or at least be informed about the issue
- setPrototypeOf.polyfill = setPrototypeOf(
- setPrototypeOf({}, null),
- Object.prototype
- ) instanceof Object;
- // setPrototypeOf.polyfill === true means it works as meant
- // setPrototypeOf.polyfill === false means it's not 100% reliable
- // setPrototypeOf.polyfill === undefined
- // or
- // setPrototypeOf.polyfill == null means it's not a polyfill
- // which means it works as expected
- // we can even delete Object.prototype.__proto__;
- }
- return setPrototypeOf;
- }(Object, '__proto__'));
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/promise.js
----------------------------------------------------------------------
diff --git a/html5/shared/promise.js b/html5/shared/promise.js
deleted file mode 100644
index 39fe816..0000000
--- a/html5/shared/promise.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// fix Promise Problem on JSContext of iOS7~8
-// @see https://bugs.webkit.org/show_bug.cgi?id=135866
-
-const { WXEnvironment } = global
-
-/* istanbul ignore next */
-if (WXEnvironment && WXEnvironment.platform === 'iOS') {
- global.Promise = undefined
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/shared/setTimeout.js
----------------------------------------------------------------------
diff --git a/html5/shared/setTimeout.js b/html5/shared/setTimeout.js
deleted file mode 100644
index d545d6d..0000000
--- a/html5/shared/setTimeout.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @fileOverview
- * Polyfill `setTimeout` on Android V8 using native method
- * `setTimeoutNative(callbackId, time)` and JS method
- * `setTimeoutCallback(callbackId)`.
- * This polyfill is only used in virtual-DOM diff & flush agorithm. Not
- * accessed by JS Bundle code (The timer APIs polyfill for JS Bundle is in
- * `html5/default/app/ctrl.js`).
- */
-
-const originalSetTimeout = global.setTimeout
-const setTimeoutNative = global.setTimeoutNative
-
-/**
- * Set up native timer
- */
-/* istanbul ignore next */
-export function setNativeTimer () {
- if (typeof setTimeout === 'undefined' &&
- typeof setTimeoutNative === 'function') {
- const timeoutMap = {}
- let timeoutId = 0
-
- global.setTimeout = (cb, time) => {
- timeoutMap[++timeoutId] = cb
- setTimeoutNative(timeoutId.toString(), time)
- }
-
- global.setTimeoutCallback = (id) => {
- if (typeof timeoutMap[id] === 'function') {
- timeoutMap[id]()
- delete timeoutMap[id]
- }
- }
- }
-}
-
-/* istanbul ignore next */
-export function resetNativeTimer () {
- global.setTimeout = originalSetTimeout
- global.setTimeoutCallback = null
-}
-
-setNativeTimer()
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/.eslintrc
----------------------------------------------------------------------
diff --git a/html5/test/case/.eslintrc b/html5/test/case/.eslintrc
deleted file mode 100644
index c892a87..0000000
--- a/html5/test/case/.eslintrc
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "globals": {
- "callNativeHandler": true,
- },
-
- "rules": {
- "no-eval": "off"
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/append-root.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/append-root.output.js b/html5/test/case/basic/append-root.output.js
deleted file mode 100644
index 3c4a5a4..0000000
--- a/html5/test/case/basic/append-root.output.js
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- type: 'container',
- style: {
- flexDirection: 'column'
- },
- attr: {
- append: "tree"
- },
- children: [{
- type: 'container',
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- }
- }, {
- type: 'text',
- attr: {
- value: 'title1'
- }
- }]
- }, {
- type: 'container',
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- }
- }, {
- type: 'text',
- attr: {
- value: 'title2'
- }
- }]
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/append-root.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/append-root.source.js b/html5/test/case/basic/append-root.source.js
deleted file mode 100644
index dfe60d7..0000000
--- a/html5/test/case/basic/append-root.source.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/append', function(require, exports, module) {;
- module.exports = {
- data: function() {
- return {
- itemList: [{
- itemId: '520421163634',
- title: 'title1',
- pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- }, {
- itemId: '522076777462',
- title: 'title2',
- pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- }]
- }
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "container",
- "style": {
- "flexDirection": "column"
- },
- "append": "tree",
- "children": [{
- "type": "container",
- "children": [{
- "type": "image",
- "attr": {
- "src": function() {
- return this.pictureUrl
- }
- }
- }, {
- "type": "text",
- "attr": {
- "value": function() {
- return this.title
- }
- }
- }],
- "repeat": function() {
- return this.itemList
- }
- }]
- }
-
- ;
-})
-
-// require module
-
-bootstrap('@weex-component/append')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/append.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/append.output.js b/html5/test/case/basic/append.output.js
deleted file mode 100644
index 5259fb6..0000000
--- a/html5/test/case/basic/append.output.js
+++ /dev/null
@@ -1,79 +0,0 @@
-{
- type: 'container',
- style: {
- flexDirection: 'column'
- },
- children: [{
- type: 'container',
- event: ['click'],
- attr: {
- append: 'tree'
- },
- children: [{
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'any text'
- }
- }]
- }, {
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title1'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }, {
- type: 'container',
- event: ['click'],
- attr: {
- append: 'tree'
- },
- children: [{
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'any text'
- }
- }]
- }, {
- type: 'image',
- attr: {
- src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title2'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/append.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/append.source.js b/html5/test/case/basic/append.source.js
deleted file mode 100644
index c216578..0000000
--- a/html5/test/case/basic/append.source.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/taobao-item', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemId: '',
- title: '',
- pictureUrl: ''
- }},
- methods: {
- gotoDetail: function () {
- this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
- }
- }
- }
-
-
-;module.exports.style = {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "events": {
- "click": "gotoDetail"
- },
- "append": "tree",
- "children": [
- {
- "type": "container",
- "children": [{
- "type": "text",
- "attr": {
- "value": "any text"
- }
- }]
- },
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": function () {return this.pictureUrl}
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// module
-
-define('@weex-component/append', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemList: [
- {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
- {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
- ]
- }}
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "style": {
- "flexDirection": "column"
- },
- "children": [
- {
- "type": "taobao-item",
- "repeat": function () {return this.itemList}
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/append')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/backward1.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/backward1.output.js b/html5/test/case/basic/backward1.output.js
deleted file mode 100644
index 8f6d086..0000000
--- a/html5/test/case/basic/backward1.output.js
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- type: 'container',
- style: {
- flexDirection: 'column'
- },
- children: [{
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title1'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }, {
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title2'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/backward1.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/backward1.source.js b/html5/test/case/basic/backward1.source.js
deleted file mode 100644
index 1bf6d74..0000000
--- a/html5/test/case/basic/backward1.source.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-register('taobao-item', {
-
- data: function() {
- return {
- itemId: '',
- title: '',
- pictureUrl: ''
- };
- },
- methods: {
- gotoDetail: function() {
- this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId);
- }
- }
-
- ,
- style: {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
- },
- template: {
- "type": "container",
- "events": {
- "click": "gotoDetail"
- },
- "children": [{
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": function() {
- return this.pictureUrl
- }
- }
- }, {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": function() {
- return this.title
- }
- }
- }]
- }
-})
-
-// module
-
-register('backward1', {
-
- data: function() {
- return {
- itemList: [{
- itemId: '520421163634',
- title: 'title1',
- pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- }, {
- itemId: '522076777462',
- title: 'title2',
- pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- }]
- };
- }
-
- ,
- style: {},
- template: {
- "type": "container",
- "style": {
- "flexDirection": "column"
- },
- "children": [{
- "type": "taobao-item",
- "repeat": function() {
- return this.itemList
- }
- }]
- }
-})
-
-// require module
-
-render('backward1', {})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/backward2.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/backward2.output.js b/html5/test/case/basic/backward2.output.js
deleted file mode 100644
index 8f6d086..0000000
--- a/html5/test/case/basic/backward2.output.js
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- type: 'container',
- style: {
- flexDirection: 'column'
- },
- children: [{
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title1'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }, {
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title2'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/backward2.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/backward2.source.js b/html5/test/case/basic/backward2.source.js
deleted file mode 100644
index cf4885a..0000000
--- a/html5/test/case/basic/backward2.source.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('taobao-item', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemId: '',
- title: '',
- pictureUrl: ''
- }},
- methods: {
- gotoDetail: function () {
- this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
- }
- }
- }
-
-
-;module.exports.style = {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "events": {
- "click": "gotoDetail"
- },
- "children": [
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": function () {return this.pictureUrl}
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// module
-
-define('backward2', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemList: [
- {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
- {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
- ]
- }}
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "style": {
- "flexDirection": "column"
- },
- "children": [
- {
- "type": "taobao-item",
- "repeat": function () {return this.itemList}
- }
- ]
-}
-
-;})
-
-// require module
-
-require('backward2')()
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/components.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/components.output.js b/html5/test/case/basic/components.output.js
deleted file mode 100644
index b7acaa4..0000000
--- a/html5/test/case/basic/components.output.js
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "type": "container",
- "children": [{
- "type": "container",
- "style": {
- "marginTop": 10
- },
- "children": [{
- "type": "text",
- "attr": {
- "value": "aa"
- }
- },{
- "type": "text",
- "attr": {
- "value": "bb"
- }
- }]
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/components.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/components.source.js b/html5/test/case/basic/components.source.js
deleted file mode 100644
index f095486..0000000
--- a/html5/test/case/basic/components.source.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-function otherNameFunction () {
- var module = {}
- var exports = {}
- module.exports = exports
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.outerData.a}
- }
- },
- {
- "type": "text",
- "attr": {
- "value": function () {return this.outerData.b}
- }
- }
- ]
- }
-
- ;module.exports.created = function() {
- this.outerData.a = 'aa'
- }
-
- ;module.exports.ready = function() {
- this.outerData.b = 'bb'
- }
-
- return module.exports
-}
-
-// module
-
-define('@weex-component/subvm', function (require, exports, module) {
-
-;
- module.exports = {
- "components": {
- innertpl: otherNameFunction()
- },
- data: function () {return {
- item: {a: 'a', b: 'b'},
- className: 'fromOuter',
- marginTop: 10
- }}
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "innertpl",
- "classList": function() {
- return this.className
- },
- "style": {
- marginTop: function() {
- return this.marginTop
- }
- },
- "events": {
- "click": "clicked"
- },
- "attr": {
- "outerData": function () {return this.item}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/subvm')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/computed-in-repeat.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/computed-in-repeat.output.js b/html5/test/case/basic/computed-in-repeat.output.js
deleted file mode 100644
index 14a8d23..0000000
--- a/html5/test/case/basic/computed-in-repeat.output.js
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "div",
- "children": [{
- "type": "text",
- "attr": {
- "value": "Hello Evan You"
- }
- }, {
- "type": "text",
- "attr": {
- "value": "Hello Terry King"
- }
- }, {
- "type": "text",
- "attr": {
- "value": "Jack Ma"
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/computed-in-repeat.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/computed-in-repeat.source.js b/html5/test/case/basic/computed-in-repeat.source.js
deleted file mode 100644
index fc203a9..0000000
--- a/html5/test/case/basic/computed-in-repeat.source.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/e9b6b411765a9cc9e9d1a0469ae0a84c', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- firstName: 'Jack',
- lastName: 'Ma',
- peoples: [{
- firstName: 'Evan',
- lastName: 'You'
- }, {
- firstName: 'Terry',
- lastName: 'King'
- }]
- }
- },
- computed: {
- fullName: function() {
- return this.firstName + ' ' + this.lastName
- }
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "div",
- "classList": [
- "bg"
- ],
- "children": [{
- "type": "text",
- "repeat": function() {
- return this.peoples
- },
- "classList": [
- "text"
- ],
- "attr": {
- "value": function() {
- return 'Hello ' + (this.fullName)
- }
- }
- }, {
- "type": "text",
- "attr": {
- "value": function() {
- return this.fullName
- }
- }
- }]
- }
-
- ;
-})
-
-// require module
-bootstrap('@weex-component/e9b6b411765a9cc9e9d1a0469ae0a84c', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/created.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/created.output.js b/html5/test/case/basic/created.output.js
deleted file mode 100644
index 39c15f3..0000000
--- a/html5/test/case/basic/created.output.js
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "children": [
- {
- "attr": {
- "value": "1"
- },
- "type": "text"
- }
- ],
- "type": "container"
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/created.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/created.source.js b/html5/test/case/basic/created.source.js
deleted file mode 100644
index dd2ee5b..0000000
--- a/html5/test/case/basic/created.source.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/created', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- text: '',
- }
- },
- created: function() {
- this.text = '1'
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "container",
- "children": [{
- "type": "text",
- "attr": {
- "value": function() {
- return this.text
- }
- }
- }]
- }
-
- ;
-})
-
-// require module
-bootstrap('@weex-component/created', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/dynamic-id.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/dynamic-id.output.js b/html5/test/case/basic/dynamic-id.output.js
deleted file mode 100644
index 5029a30..0000000
--- a/html5/test/case/basic/dynamic-id.output.js
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- type: 'div',
- children: [
- {
- type: 'text',
- attr: {
- value: 'Hello',
- a: 1
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello',
- a: 1,
- b: 1
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello'
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello'
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello'
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello'
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/dynamic-id.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/dynamic-id.source.js b/html5/test/case/basic/dynamic-id.source.js
deleted file mode 100644
index 6616cec..0000000
--- a/html5/test/case/basic/dynamic-id.source.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/id', function (require, exports, module) {
-
-;
- module.exports = {
- ready: function () {
- if (this.$el('x')) {
- this.$el('x').setAttr('a', 1)
- }
- if (this.$el('y')) {
- this.$el('y').setAttr('a', 1)
- }
- if (this.$el('')) {
- this.$el('').setAttr('a', 1)
- }
- if (this.$el('0')) {
- this.$el('0').setAttr('a', 1)
- }
- if (this.$el(0)) {
- this.$el(0).setAttr('b', 1)
- }
- }
- }
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "id": function () { return "x" },
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": function () { return 0 },
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": function () { return '' },
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": function () { return null },
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": function () { return NaN },
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": function () { return },
- "attr": {
- "value": "Hello"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/id')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/dynamic-property.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/dynamic-property.output.js b/html5/test/case/basic/dynamic-property.output.js
deleted file mode 100644
index 8ccc9d5..0000000
--- a/html5/test/case/basic/dynamic-property.output.js
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "type": "div",
- "children": [{
- "type": "text",
- "attr": {
- "value": "A: undefined"
- }
- }, {
- "type": "text",
- "attr": {
- "value": "B: created"
- }
- }, {
- "type": "text",
- "attr": {
- "value": "C: ready"
- }
- }, {
- "type": "text",
- "attr": {
- "value": "D: initial"
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/dynamic-property.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/dynamic-property.source.js b/html5/test/case/basic/dynamic-property.source.js
deleted file mode 100644
index 880d468..0000000
--- a/html5/test/case/basic/dynamic-property.source.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/dynamic-property', function (require, exports, module) {
-
- ;module.exports.style = {}
-
- ;module.exports = {
- data: function () {return {
- A: {},
- B: {},
- C: {
- message: 'initial'
- },
- D: {
- message: 'initial'
- }
- }},
-
- created: function() {
- this.B.message = 'created'
- this.C.message = 'created'
- },
-
- ready: function() {
- this.A.message = 'ready'
- this.B.message = 'ready'
- this.C.message = 'ready'
- }
- }
-
- ;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return 'A: ' + (this.A.message)}
- }
- },
- {
- "type": "text",
- "attr": {
- "value": function () {return 'B: ' + (this.B.message)}
- }
- },
- {
- "type": "text",
- "attr": {
- "value": function () {return 'C: ' + (this.C.message)}
- }
- },
- {
- "type": "text",
- "attr": {
- "value": function () {return 'D: ' + (this.D.message)}
- }
- }
- ]
- }
-
-;})
-
-bootstrap('@weex-component/dynamic-property')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/dynamic-type.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/dynamic-type.output.js b/html5/test/case/basic/dynamic-type.output.js
deleted file mode 100644
index d6881a4..0000000
--- a/html5/test/case/basic/dynamic-type.output.js
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- width: 200,
- height: 200
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/dynamic-type.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/dynamic-type.source.js b/html5/test/case/basic/dynamic-type.source.js
deleted file mode 100644
index 62b8f72..0000000
--- a/html5/test/case/basic/dynamic-type.source.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/dynamic-type', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- type: 'text'
- }}
- }
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": function () {return this.type},
- "style": {
- "width": 200,
- "height": 200
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/dynamic-type')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo.output.js b/html5/test/case/basic/foo.output.js
deleted file mode 100644
index 1372f91..0000000
--- a/html5/test/case/basic/foo.output.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- type: 'container'
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo.source.js b/html5/test/case/basic/foo.source.js
deleted file mode 100644
index 027eee1..0000000
--- a/html5/test/case/basic/foo.source.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {
- x: 1
- }
- }
- }
-
-
-;module.exports.style = {
- "a": {
- "fontSize": 12
- }
-}
-
-;module.exports.template = {
- "type": "container"
-}
-
-;})
-
-
-bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo2.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo2.output.js b/html5/test/case/basic/foo2.output.js
deleted file mode 100644
index d7cc321..0000000
--- a/html5/test/case/basic/foo2.output.js
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- type: 'container',
- attr: {
- a: '1',
- b: 1
- },
- style: {
- fontSize: 12
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo2.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo2.source.js b/html5/test/case/basic/foo2.source.js
deleted file mode 100644
index cabf559..0000000
--- a/html5/test/case/basic/foo2.source.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo2', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {
- x: 1
- }
- }
- }
-
-
-;module.exports.style = {
- "a": {
- "fontSize": 12
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "attr": {
- "a": "1",
- "b": function () {return this.x}
- },
- "classList": [
- "a"
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo2')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo3.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo3.output.js b/html5/test/case/basic/foo3.output.js
deleted file mode 100644
index 51c886e..0000000
--- a/html5/test/case/basic/foo3.output.js
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo3.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo3.source.js b/html5/test/case/basic/foo3.source.js
deleted file mode 100644
index 7fda995..0000000
--- a/html5/test/case/basic/foo3.source.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo3', function (require, exports, module) {
-
-;
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "Hello World"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo3')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo4.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo4.output.js b/html5/test/case/basic/foo4.output.js
deleted file mode 100644
index bef3668..0000000
--- a/html5/test/case/basic/foo4.output.js
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- },
- style: {
- color: '#ff0000'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo4.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo4.source.js b/html5/test/case/basic/foo4.source.js
deleted file mode 100644
index f842abf..0000000
--- a/html5/test/case/basic/foo4.source.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo4', function (require, exports, module) {
-
-;
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "style": {
- "color": "#ff0000"
- },
- "attr": {
- "value": "Hello World"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo4')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo5.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo5.output.js b/html5/test/case/basic/foo5.output.js
deleted file mode 100644
index 840cefb..0000000
--- a/html5/test/case/basic/foo5.output.js
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- },
- style: {
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo5.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo5.source.js b/html5/test/case/basic/foo5.source.js
deleted file mode 100644
index b09fc03..0000000
--- a/html5/test/case/basic/foo5.source.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo5', function (require, exports, module) {
-
-;
-
-;module.exports.style = {
- "title": {
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": "Hello World"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo5')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo6.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo6.output.js b/html5/test/case/basic/foo6.output.js
deleted file mode 100644
index 1a8fd90..0000000
--- a/html5/test/case/basic/foo6.output.js
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- type: 'container',
- style: {
- flexDirection: 'row'
- },
- children: [{
- type: 'image',
- attr: {
- src: 'http://gw.alicdn.com/tfscom/TB1OMfAJFXXXXbfXXXXqVMCNVXX-400-400.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: '一个超赞的宝贝标题'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
-}
\ No newline at end of file
[07/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/index.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/index.js b/runtime/vdom/index.js
new file mode 100644
index 0000000..2947f5e
--- /dev/null
+++ b/runtime/vdom/index.js
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import Node from './Node'
+import Element from './Element'
+import Comment from './Comment'
+import Document from './Document'
+
+export {
+ registerElement,
+ unregisterElement,
+ isWeexElement,
+ clearWeexElements
+} from './WeexElement'
+
+export {
+ Document,
+ Node,
+ Element,
+ Comment
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/vdom/operation.js
----------------------------------------------------------------------
diff --git a/runtime/vdom/operation.js b/runtime/vdom/operation.js
new file mode 100644
index 0000000..69a64e1
--- /dev/null
+++ b/runtime/vdom/operation.js
@@ -0,0 +1,272 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const docMap = {}
+
+/**
+ * Add a document object into docMap.
+ * @param {string} id
+ * @param {object} document
+ */
+export function addDoc (id, doc) {
+ if (id) {
+ docMap[id] = doc
+ }
+}
+
+/**
+ * Get the document object by id.
+ * @param {string} id
+ */
+export function getDoc (id) {
+ return docMap[id]
+}
+
+/**
+ * Remove the document from docMap by id.
+ * @param {string} id
+ */
+export function removeDoc (id) {
+ delete docMap[id]
+}
+
+/**
+ * @deprecated
+ * Get listener by document id.
+ * @param {string} id
+ * @return {object} listener
+ */
+export function getListener (id) {
+ const doc = docMap[id]
+ if (doc && doc.listener) {
+ return doc.listener
+ }
+ return null
+}
+
+/**
+ * Get TaskCenter instance by id.
+ * @param {string} id
+ * @return {object} TaskCenter
+ */
+export function getTaskCenter (id) {
+ const doc = docMap[id]
+ if (doc && doc.taskCenter) {
+ return doc.taskCenter
+ }
+ return null
+}
+
+/**
+ * Append body node to documentElement.
+ * @param {object} document
+ * @param {object} node
+ * @param {object} before
+ */
+export function appendBody (doc, node, before) {
+ const { documentElement } = doc
+
+ if (documentElement.pureChildren.length > 0 || node.parentNode) {
+ return
+ }
+ const children = documentElement.children
+ const beforeIndex = children.indexOf(before)
+ if (beforeIndex < 0) {
+ children.push(node)
+ }
+ else {
+ children.splice(beforeIndex, 0, node)
+ }
+
+ if (node.nodeType === 1) {
+ if (node.role === 'body') {
+ node.docId = doc.id
+ node.ownerDocument = doc
+ node.parentNode = documentElement
+ linkParent(node, documentElement)
+ }
+ else {
+ node.children.forEach(child => {
+ child.parentNode = node
+ })
+ setBody(doc, node)
+ node.docId = doc.id
+ node.ownerDocument = doc
+ linkParent(node, documentElement)
+ delete doc.nodeMap[node.nodeId]
+ }
+ documentElement.pureChildren.push(node)
+ sendBody(doc, node)
+ }
+ else {
+ node.parentNode = documentElement
+ doc.nodeMap[node.ref] = node
+ }
+}
+
+function sendBody (doc, node) {
+ const body = node.toJSON()
+ if (doc && doc.taskCenter && typeof doc.taskCenter.send === 'function') {
+ doc.taskCenter.send('dom', { action: 'createBody' }, [body])
+ }
+}
+
+/**
+ * Set up body node.
+ * @param {object} document
+ * @param {object} element
+ */
+export function setBody (doc, el) {
+ el.role = 'body'
+ el.depth = 1
+ delete doc.nodeMap[el.nodeId]
+ el.ref = '_root'
+ doc.nodeMap._root = el
+ doc.body = el
+}
+
+/**
+ * Establish the connection between parent and child node.
+ * @param {object} child node
+ * @param {object} parent node
+ */
+export function linkParent (node, parent) {
+ node.parentNode = parent
+ if (parent.docId) {
+ node.docId = parent.docId
+ node.ownerDocument = parent.ownerDocument
+ node.ownerDocument.nodeMap[node.nodeId] = node
+ node.depth = parent.depth + 1
+ }
+ node.children.forEach(child => {
+ linkParent(child, node)
+ })
+}
+
+/**
+ * Get the next sibling element.
+ * @param {object} node
+ */
+export function nextElement (node) {
+ while (node) {
+ if (node.nodeType === 1) {
+ return node
+ }
+ node = node.nextSibling
+ }
+}
+
+/**
+ * Get the previous sibling element.
+ * @param {object} node
+ */
+export function previousElement (node) {
+ while (node) {
+ if (node.nodeType === 1) {
+ return node
+ }
+ node = node.previousSibling
+ }
+}
+
+/**
+ * Insert a node into list at the specified index.
+ * @param {object} target node
+ * @param {array} list
+ * @param {number} newIndex
+ * @param {boolean} changeSibling
+ * @return {number} newIndex
+ */
+export function insertIndex (target, list, newIndex, changeSibling) {
+ /* istanbul ignore next */
+ if (newIndex < 0) {
+ newIndex = 0
+ }
+ const before = list[newIndex - 1]
+ const after = list[newIndex]
+ list.splice(newIndex, 0, target)
+ if (changeSibling) {
+ before && (before.nextSibling = target)
+ target.previousSibling = before
+ target.nextSibling = after
+ after && (after.previousSibling = target)
+ }
+ return newIndex
+}
+
+/**
+ * Move the node to a new index in list.
+ * @param {object} target node
+ * @param {array} list
+ * @param {number} newIndex
+ * @param {boolean} changeSibling
+ * @return {number} newIndex
+ */
+export function moveIndex (target, list, newIndex, changeSibling) {
+ const index = list.indexOf(target)
+ /* istanbul ignore next */
+ if (index < 0) {
+ return -1
+ }
+ if (changeSibling) {
+ const before = list[index - 1]
+ const after = list[index + 1]
+ before && (before.nextSibling = after)
+ after && (after.previousSibling = before)
+ }
+ list.splice(index, 1)
+ let newIndexAfter = newIndex
+ if (index <= newIndex) {
+ newIndexAfter = newIndex - 1
+ }
+ const beforeNew = list[newIndexAfter - 1]
+ const afterNew = list[newIndexAfter]
+ list.splice(newIndexAfter, 0, target)
+ if (changeSibling) {
+ beforeNew && (beforeNew.nextSibling = target)
+ target.previousSibling = beforeNew
+ target.nextSibling = afterNew
+ afterNew && (afterNew.previousSibling = target)
+ }
+ if (index === newIndexAfter) {
+ return -1
+ }
+ return newIndex
+}
+
+/**
+ * Remove the node from list.
+ * @param {object} target node
+ * @param {array} list
+ * @param {boolean} changeSibling
+ */
+export function removeIndex (target, list, changeSibling) {
+ const index = list.indexOf(target)
+ /* istanbul ignore next */
+ if (index < 0) {
+ return
+ }
+ if (changeSibling) {
+ const before = list[index - 1]
+ const after = list[index + 1]
+ before && (before.nextSibling = after)
+ after && (after.previousSibling = before)
+ }
+ list.splice(index, 1)
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/.eslintrc
----------------------------------------------------------------------
diff --git a/test/js-framework/case/.eslintrc b/test/js-framework/case/.eslintrc
new file mode 100644
index 0000000..c892a87
--- /dev/null
+++ b/test/js-framework/case/.eslintrc
@@ -0,0 +1,9 @@
+{
+ "globals": {
+ "callNativeHandler": true,
+ },
+
+ "rules": {
+ "no-eval": "off"
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/append-root.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/append-root.output.js b/test/js-framework/case/basic/append-root.output.js
new file mode 100644
index 0000000..3c4a5a4
--- /dev/null
+++ b/test/js-framework/case/basic/append-root.output.js
@@ -0,0 +1,36 @@
+{
+ type: 'container',
+ style: {
+ flexDirection: 'column'
+ },
+ attr: {
+ append: "tree"
+ },
+ children: [{
+ type: 'container',
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title1'
+ }
+ }]
+ }, {
+ type: 'container',
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title2'
+ }
+ }]
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/append-root.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/append-root.source.js b/test/js-framework/case/basic/append-root.source.js
new file mode 100644
index 0000000..dfe60d7
--- /dev/null
+++ b/test/js-framework/case/basic/append-root.source.js
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/append', function(require, exports, module) {;
+ module.exports = {
+ data: function() {
+ return {
+ itemList: [{
+ itemId: '520421163634',
+ title: 'title1',
+ pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ }, {
+ itemId: '522076777462',
+ title: 'title2',
+ pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ }]
+ }
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "container",
+ "style": {
+ "flexDirection": "column"
+ },
+ "append": "tree",
+ "children": [{
+ "type": "container",
+ "children": [{
+ "type": "image",
+ "attr": {
+ "src": function() {
+ return this.pictureUrl
+ }
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": function() {
+ return this.title
+ }
+ }
+ }],
+ "repeat": function() {
+ return this.itemList
+ }
+ }]
+ }
+
+ ;
+})
+
+// require module
+
+bootstrap('@weex-component/append')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/append.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/append.output.js b/test/js-framework/case/basic/append.output.js
new file mode 100644
index 0000000..5259fb6
--- /dev/null
+++ b/test/js-framework/case/basic/append.output.js
@@ -0,0 +1,79 @@
+{
+ type: 'container',
+ style: {
+ flexDirection: 'column'
+ },
+ children: [{
+ type: 'container',
+ event: ['click'],
+ attr: {
+ append: 'tree'
+ },
+ children: [{
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'any text'
+ }
+ }]
+ }, {
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title1'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }, {
+ type: 'container',
+ event: ['click'],
+ attr: {
+ append: 'tree'
+ },
+ children: [{
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'any text'
+ }
+ }]
+ }, {
+ type: 'image',
+ attr: {
+ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title2'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/append.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/append.source.js b/test/js-framework/case/basic/append.source.js
new file mode 100644
index 0000000..c216578
--- /dev/null
+++ b/test/js-framework/case/basic/append.source.js
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/taobao-item', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemId: '',
+ title: '',
+ pictureUrl: ''
+ }},
+ methods: {
+ gotoDetail: function () {
+ this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "events": {
+ "click": "gotoDetail"
+ },
+ "append": "tree",
+ "children": [
+ {
+ "type": "container",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "any text"
+ }
+ }]
+ },
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": function () {return this.pictureUrl}
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// module
+
+define('@weex-component/append', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemList: [
+ {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
+ {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "style": {
+ "flexDirection": "column"
+ },
+ "children": [
+ {
+ "type": "taobao-item",
+ "repeat": function () {return this.itemList}
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/append')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/backward1.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/backward1.output.js b/test/js-framework/case/basic/backward1.output.js
new file mode 100644
index 0000000..8f6d086
--- /dev/null
+++ b/test/js-framework/case/basic/backward1.output.js
@@ -0,0 +1,57 @@
+{
+ type: 'container',
+ style: {
+ flexDirection: 'column'
+ },
+ children: [{
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title1'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }, {
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title2'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/backward1.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/backward1.source.js b/test/js-framework/case/basic/backward1.source.js
new file mode 100644
index 0000000..1bf6d74
--- /dev/null
+++ b/test/js-framework/case/basic/backward1.source.js
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+register('taobao-item', {
+
+ data: function() {
+ return {
+ itemId: '',
+ title: '',
+ pictureUrl: ''
+ };
+ },
+ methods: {
+ gotoDetail: function() {
+ this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId);
+ }
+ }
+
+ ,
+ style: {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+ },
+ template: {
+ "type": "container",
+ "events": {
+ "click": "gotoDetail"
+ },
+ "children": [{
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": function() {
+ return this.pictureUrl
+ }
+ }
+ }, {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function() {
+ return this.title
+ }
+ }
+ }]
+ }
+})
+
+// module
+
+register('backward1', {
+
+ data: function() {
+ return {
+ itemList: [{
+ itemId: '520421163634',
+ title: 'title1',
+ pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ }, {
+ itemId: '522076777462',
+ title: 'title2',
+ pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ }]
+ };
+ }
+
+ ,
+ style: {},
+ template: {
+ "type": "container",
+ "style": {
+ "flexDirection": "column"
+ },
+ "children": [{
+ "type": "taobao-item",
+ "repeat": function() {
+ return this.itemList
+ }
+ }]
+ }
+})
+
+// require module
+
+render('backward1', {})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/backward2.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/backward2.output.js b/test/js-framework/case/basic/backward2.output.js
new file mode 100644
index 0000000..8f6d086
--- /dev/null
+++ b/test/js-framework/case/basic/backward2.output.js
@@ -0,0 +1,57 @@
+{
+ type: 'container',
+ style: {
+ flexDirection: 'column'
+ },
+ children: [{
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title1'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }, {
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title2'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/backward2.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/backward2.source.js b/test/js-framework/case/basic/backward2.source.js
new file mode 100644
index 0000000..cf4885a
--- /dev/null
+++ b/test/js-framework/case/basic/backward2.source.js
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('taobao-item', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemId: '',
+ title: '',
+ pictureUrl: ''
+ }},
+ methods: {
+ gotoDetail: function () {
+ this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "events": {
+ "click": "gotoDetail"
+ },
+ "children": [
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": function () {return this.pictureUrl}
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// module
+
+define('backward2', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemList: [
+ {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
+ {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "style": {
+ "flexDirection": "column"
+ },
+ "children": [
+ {
+ "type": "taobao-item",
+ "repeat": function () {return this.itemList}
+ }
+ ]
+}
+
+;})
+
+// require module
+
+require('backward2')()
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/components.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/components.output.js b/test/js-framework/case/basic/components.output.js
new file mode 100644
index 0000000..b7acaa4
--- /dev/null
+++ b/test/js-framework/case/basic/components.output.js
@@ -0,0 +1,20 @@
+{
+ "type": "container",
+ "children": [{
+ "type": "container",
+ "style": {
+ "marginTop": 10
+ },
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "aa"
+ }
+ },{
+ "type": "text",
+ "attr": {
+ "value": "bb"
+ }
+ }]
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/components.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/components.source.js b/test/js-framework/case/basic/components.source.js
new file mode 100644
index 0000000..f095486
--- /dev/null
+++ b/test/js-framework/case/basic/components.source.js
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+function otherNameFunction () {
+ var module = {}
+ var exports = {}
+ module.exports = exports
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.outerData.a}
+ }
+ },
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.outerData.b}
+ }
+ }
+ ]
+ }
+
+ ;module.exports.created = function() {
+ this.outerData.a = 'aa'
+ }
+
+ ;module.exports.ready = function() {
+ this.outerData.b = 'bb'
+ }
+
+ return module.exports
+}
+
+// module
+
+define('@weex-component/subvm', function (require, exports, module) {
+
+;
+ module.exports = {
+ "components": {
+ innertpl: otherNameFunction()
+ },
+ data: function () {return {
+ item: {a: 'a', b: 'b'},
+ className: 'fromOuter',
+ marginTop: 10
+ }}
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "innertpl",
+ "classList": function() {
+ return this.className
+ },
+ "style": {
+ marginTop: function() {
+ return this.marginTop
+ }
+ },
+ "events": {
+ "click": "clicked"
+ },
+ "attr": {
+ "outerData": function () {return this.item}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/subvm')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/computed-in-repeat.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/computed-in-repeat.output.js b/test/js-framework/case/basic/computed-in-repeat.output.js
new file mode 100644
index 0000000..14a8d23
--- /dev/null
+++ b/test/js-framework/case/basic/computed-in-repeat.output.js
@@ -0,0 +1,19 @@
+{
+ "type": "div",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "Hello Evan You"
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": "Hello Terry King"
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": "Jack Ma"
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/computed-in-repeat.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/computed-in-repeat.source.js b/test/js-framework/case/basic/computed-in-repeat.source.js
new file mode 100644
index 0000000..fc203a9
--- /dev/null
+++ b/test/js-framework/case/basic/computed-in-repeat.source.js
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/e9b6b411765a9cc9e9d1a0469ae0a84c', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ firstName: 'Jack',
+ lastName: 'Ma',
+ peoples: [{
+ firstName: 'Evan',
+ lastName: 'You'
+ }, {
+ firstName: 'Terry',
+ lastName: 'King'
+ }]
+ }
+ },
+ computed: {
+ fullName: function() {
+ return this.firstName + ' ' + this.lastName
+ }
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "div",
+ "classList": [
+ "bg"
+ ],
+ "children": [{
+ "type": "text",
+ "repeat": function() {
+ return this.peoples
+ },
+ "classList": [
+ "text"
+ ],
+ "attr": {
+ "value": function() {
+ return 'Hello ' + (this.fullName)
+ }
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": function() {
+ return this.fullName
+ }
+ }
+ }]
+ }
+
+ ;
+})
+
+// require module
+bootstrap('@weex-component/e9b6b411765a9cc9e9d1a0469ae0a84c', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/created.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/created.output.js b/test/js-framework/case/basic/created.output.js
new file mode 100644
index 0000000..39c15f3
--- /dev/null
+++ b/test/js-framework/case/basic/created.output.js
@@ -0,0 +1,11 @@
+{
+ "children": [
+ {
+ "attr": {
+ "value": "1"
+ },
+ "type": "text"
+ }
+ ],
+ "type": "container"
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/created.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/created.source.js b/test/js-framework/case/basic/created.source.js
new file mode 100644
index 0000000..dd2ee5b
--- /dev/null
+++ b/test/js-framework/case/basic/created.source.js
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/created', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ text: '',
+ }
+ },
+ created: function() {
+ this.text = '1'
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "container",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": function() {
+ return this.text
+ }
+ }
+ }]
+ }
+
+ ;
+})
+
+// require module
+bootstrap('@weex-component/created', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/dynamic-id.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/dynamic-id.output.js b/test/js-framework/case/basic/dynamic-id.output.js
new file mode 100644
index 0000000..5029a30
--- /dev/null
+++ b/test/js-framework/case/basic/dynamic-id.output.js
@@ -0,0 +1,44 @@
+{
+ type: 'div',
+ children: [
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello',
+ a: 1
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello',
+ a: 1,
+ b: 1
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello'
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello'
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello'
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello'
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/dynamic-id.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/dynamic-id.source.js b/test/js-framework/case/basic/dynamic-id.source.js
new file mode 100644
index 0000000..6616cec
--- /dev/null
+++ b/test/js-framework/case/basic/dynamic-id.source.js
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/id', function (require, exports, module) {
+
+;
+ module.exports = {
+ ready: function () {
+ if (this.$el('x')) {
+ this.$el('x').setAttr('a', 1)
+ }
+ if (this.$el('y')) {
+ this.$el('y').setAttr('a', 1)
+ }
+ if (this.$el('')) {
+ this.$el('').setAttr('a', 1)
+ }
+ if (this.$el('0')) {
+ this.$el('0').setAttr('a', 1)
+ }
+ if (this.$el(0)) {
+ this.$el(0).setAttr('b', 1)
+ }
+ }
+ }
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "id": function () { return "x" },
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": function () { return 0 },
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": function () { return '' },
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": function () { return null },
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": function () { return NaN },
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": function () { return },
+ "attr": {
+ "value": "Hello"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/id')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/dynamic-property.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/dynamic-property.output.js b/test/js-framework/case/basic/dynamic-property.output.js
new file mode 100644
index 0000000..8ccc9d5
--- /dev/null
+++ b/test/js-framework/case/basic/dynamic-property.output.js
@@ -0,0 +1,24 @@
+{
+ "type": "div",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "A: undefined"
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": "B: created"
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": "C: ready"
+ }
+ }, {
+ "type": "text",
+ "attr": {
+ "value": "D: initial"
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/dynamic-property.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/dynamic-property.source.js b/test/js-framework/case/basic/dynamic-property.source.js
new file mode 100644
index 0000000..880d468
--- /dev/null
+++ b/test/js-framework/case/basic/dynamic-property.source.js
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/dynamic-property', function (require, exports, module) {
+
+ ;module.exports.style = {}
+
+ ;module.exports = {
+ data: function () {return {
+ A: {},
+ B: {},
+ C: {
+ message: 'initial'
+ },
+ D: {
+ message: 'initial'
+ }
+ }},
+
+ created: function() {
+ this.B.message = 'created'
+ this.C.message = 'created'
+ },
+
+ ready: function() {
+ this.A.message = 'ready'
+ this.B.message = 'ready'
+ this.C.message = 'ready'
+ }
+ }
+
+ ;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return 'A: ' + (this.A.message)}
+ }
+ },
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return 'B: ' + (this.B.message)}
+ }
+ },
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return 'C: ' + (this.C.message)}
+ }
+ },
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return 'D: ' + (this.D.message)}
+ }
+ }
+ ]
+ }
+
+;})
+
+bootstrap('@weex-component/dynamic-property')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/dynamic-type.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/dynamic-type.output.js b/test/js-framework/case/basic/dynamic-type.output.js
new file mode 100644
index 0000000..d6881a4
--- /dev/null
+++ b/test/js-framework/case/basic/dynamic-type.output.js
@@ -0,0 +1,10 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ width: 200,
+ height: 200
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/dynamic-type.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/dynamic-type.source.js b/test/js-framework/case/basic/dynamic-type.source.js
new file mode 100644
index 0000000..62b8f72
--- /dev/null
+++ b/test/js-framework/case/basic/dynamic-type.source.js
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/dynamic-type', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ type: 'text'
+ }}
+ }
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": function () {return this.type},
+ "style": {
+ "width": 200,
+ "height": 200
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/dynamic-type')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo.output.js b/test/js-framework/case/basic/foo.output.js
new file mode 100644
index 0000000..1372f91
--- /dev/null
+++ b/test/js-framework/case/basic/foo.output.js
@@ -0,0 +1,3 @@
+{
+ type: 'container'
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo.source.js b/test/js-framework/case/basic/foo.source.js
new file mode 100644
index 0000000..027eee1
--- /dev/null
+++ b/test/js-framework/case/basic/foo.source.js
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 1
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "a": {
+ "fontSize": 12
+ }
+}
+
+;module.exports.template = {
+ "type": "container"
+}
+
+;})
+
+
+bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo2.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo2.output.js b/test/js-framework/case/basic/foo2.output.js
new file mode 100644
index 0000000..d7cc321
--- /dev/null
+++ b/test/js-framework/case/basic/foo2.output.js
@@ -0,0 +1,10 @@
+{
+ type: 'container',
+ attr: {
+ a: '1',
+ b: 1
+ },
+ style: {
+ fontSize: 12
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo2.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo2.source.js b/test/js-framework/case/basic/foo2.source.js
new file mode 100644
index 0000000..cabf559
--- /dev/null
+++ b/test/js-framework/case/basic/foo2.source.js
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo2', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 1
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "a": {
+ "fontSize": 12
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "attr": {
+ "a": "1",
+ "b": function () {return this.x}
+ },
+ "classList": [
+ "a"
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo2')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo3.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo3.output.js b/test/js-framework/case/basic/foo3.output.js
new file mode 100644
index 0000000..51c886e
--- /dev/null
+++ b/test/js-framework/case/basic/foo3.output.js
@@ -0,0 +1,9 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo3.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo3.source.js b/test/js-framework/case/basic/foo3.source.js
new file mode 100644
index 0000000..7fda995
--- /dev/null
+++ b/test/js-framework/case/basic/foo3.source.js
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo3', function (require, exports, module) {
+
+;
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "Hello World"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo3')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo4.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo4.output.js b/test/js-framework/case/basic/foo4.output.js
new file mode 100644
index 0000000..bef3668
--- /dev/null
+++ b/test/js-framework/case/basic/foo4.output.js
@@ -0,0 +1,12 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ },
+ style: {
+ color: '#ff0000'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo4.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo4.source.js b/test/js-framework/case/basic/foo4.source.js
new file mode 100644
index 0000000..f842abf
--- /dev/null
+++ b/test/js-framework/case/basic/foo4.source.js
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo4', function (require, exports, module) {
+
+;
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "style": {
+ "color": "#ff0000"
+ },
+ "attr": {
+ "value": "Hello World"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo4')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo5.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo5.output.js b/test/js-framework/case/basic/foo5.output.js
new file mode 100644
index 0000000..840cefb
--- /dev/null
+++ b/test/js-framework/case/basic/foo5.output.js
@@ -0,0 +1,14 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ },
+ style: {
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo5.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo5.source.js b/test/js-framework/case/basic/foo5.source.js
new file mode 100644
index 0000000..b09fc03
--- /dev/null
+++ b/test/js-framework/case/basic/foo5.source.js
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo5', function (require, exports, module) {
+
+;
+
+;module.exports.style = {
+ "title": {
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": "Hello World"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo5')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo6.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo6.output.js b/test/js-framework/case/basic/foo6.output.js
new file mode 100644
index 0000000..1a8fd90
--- /dev/null
+++ b/test/js-framework/case/basic/foo6.output.js
@@ -0,0 +1,28 @@
+{
+ type: 'container',
+ style: {
+ flexDirection: 'row'
+ },
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'http://gw.alicdn.com/tfscom/TB1OMfAJFXXXXbfXXXXqVMCNVXX-400-400.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: '一个超赞的宝贝标题'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo6.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo6.source.js b/test/js-framework/case/basic/foo6.source.js
new file mode 100644
index 0000000..4301a50
--- /dev/null
+++ b/test/js-framework/case/basic/foo6.source.js
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo6', function (require, exports, module) {
+
+;
+
+;module.exports.style = {
+ "container": {
+ "flexDirection": "row"
+ },
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "classList": [
+ "container"
+ ],
+ "children": [
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": "http://gw.alicdn.com/tfscom/TB1OMfAJFXXXXbfXXXXqVMCNVXX-400-400.jpg"
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": "一个超赞的宝贝标题"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo6')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo7.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo7.output.js b/test/js-framework/case/basic/foo7.output.js
new file mode 100644
index 0000000..d19c92f
--- /dev/null
+++ b/test/js-framework/case/basic/foo7.output.js
@@ -0,0 +1,26 @@
+{
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: '一个超赞的宝贝标题'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo7.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo7.source.js b/test/js-framework/case/basic/foo7.source.js
new file mode 100644
index 0000000..2d9b43f
--- /dev/null
+++ b/test/js-framework/case/basic/foo7.source.js
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo7', function (require, exports, module) {
+
+;
+ module.exports = {
+ methods: {
+ gotoDetail: function () {
+ this.$openURL('https://item.taobao.com/item.htm?id=520421163634')
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "events": {
+ "click": "gotoDetail"
+ },
+ "children": [
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": "https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg"
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": "一个超赞的宝贝标题"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo7')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo8.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo8.output.js b/test/js-framework/case/basic/foo8.output.js
new file mode 100644
index 0000000..8ed4bb1
--- /dev/null
+++ b/test/js-framework/case/basic/foo8.output.js
@@ -0,0 +1,60 @@
+{
+ type: 'container',
+ children: [{
+ type: 'container',
+ style: {
+ flexDirection: 'row'
+ },
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title1'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }, {
+ type: 'container',
+ style: {
+ flexDirection: 'row'
+ },
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title2'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo8.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo8.source.js b/test/js-framework/case/basic/foo8.source.js
new file mode 100644
index 0000000..d2512f2
--- /dev/null
+++ b/test/js-framework/case/basic/foo8.source.js
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo8', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemList: [
+ {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
+ {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
+ ]
+ }},
+ methods: {
+ gotoDetail: function () {
+ this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "container",
+ "repeat": function () {return this.itemList},
+ "events": {
+ "click": "gotoDetail"
+ },
+ "style": {
+ "flexDirection": "row"
+ },
+ "children": [
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": function () {return this.pictureUrl}
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo8')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo9.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo9.output.js b/test/js-framework/case/basic/foo9.output.js
new file mode 100644
index 0000000..8f6d086
--- /dev/null
+++ b/test/js-framework/case/basic/foo9.output.js
@@ -0,0 +1,57 @@
+{
+ type: 'container',
+ style: {
+ flexDirection: 'column'
+ },
+ children: [{
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title1'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }, {
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: 'title2'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/foo9.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/foo9.source.js b/test/js-framework/case/basic/foo9.source.js
new file mode 100644
index 0000000..da534e9
--- /dev/null
+++ b/test/js-framework/case/basic/foo9.source.js
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/taobao-item', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemId: '',
+ title: '',
+ pictureUrl: ''
+ }},
+ methods: {
+ gotoDetail: function () {
+ this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "events": {
+ "click": "gotoDetail"
+ },
+ "children": [
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": function () {return this.pictureUrl}
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// module
+
+define('@weex-component/foo9', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ itemList: [
+ {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
+ {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "style": {
+ "flexDirection": "column"
+ },
+ "children": [
+ {
+ "type": "taobao-item",
+ "repeat": function () {return this.itemList}
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/foo9')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/global-weex-object.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/global-weex-object.output.js b/test/js-framework/case/basic/global-weex-object.output.js
new file mode 100644
index 0000000..3e1fa19
--- /dev/null
+++ b/test/js-framework/case/basic/global-weex-object.output.js
@@ -0,0 +1,6 @@
+{
+ type: 'div',
+ attr: {
+ a: 'WeexDemo'
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/global-weex-object.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/global-weex-object.source.js b/test/js-framework/case/basic/global-weex-object.source.js
new file mode 100644
index 0000000..252af7e
--- /dev/null
+++ b/test/js-framework/case/basic/global-weex-object.source.js
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+weex.define('@weex-component/foo', function (require, exports, module) {
+ module.exports = {
+ data: function () {
+ return {
+ x: weex.config.env.appName
+ }
+ },
+ template: {
+ "type": "div",
+ "attr": {
+ "a": function () {
+ return this.x
+ }
+ }
+ }
+ }
+})
+
+weex.bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/id.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/id.output.js b/test/js-framework/case/basic/id.output.js
new file mode 100644
index 0000000..7ce073c
--- /dev/null
+++ b/test/js-framework/case/basic/id.output.js
@@ -0,0 +1,32 @@
+{
+ type: 'div',
+ children: [
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello',
+ a: 1
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello',
+ a: 1,
+ b: 1
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello'
+ }
+ },
+ {
+ type: 'text',
+ attr: {
+ value: 'Hello'
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/id.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/id.source.js b/test/js-framework/case/basic/id.source.js
new file mode 100644
index 0000000..3c85886
--- /dev/null
+++ b/test/js-framework/case/basic/id.source.js
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/id', function (require, exports, module) {
+
+;
+ module.exports = {
+ ready: function () {
+ if (this.$el('x')) {
+ this.$el('x').setAttr('a', 1)
+ }
+ if (this.$el('y')) {
+ this.$el('y').setAttr('a', 1)
+ }
+ if (this.$el('')) {
+ this.$el('').setAttr('a', 1)
+ }
+ if (this.$el('0')) {
+ this.$el('0').setAttr('a', 1)
+ }
+ if (this.$el(0)) {
+ this.$el(0).setAttr('b', 1)
+ }
+ }
+ }
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "id": "x",
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": "0",
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": '',
+ "attr": {
+ "value": "Hello"
+ }
+ },
+ {
+ "type": "text",
+ "id": null,
+ "attr": {
+ "value": "Hello"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/id')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/if-repeat.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/if-repeat.output.js b/test/js-framework/case/basic/if-repeat.output.js
new file mode 100644
index 0000000..5265727
--- /dev/null
+++ b/test/js-framework/case/basic/if-repeat.output.js
@@ -0,0 +1,13 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: 'Hello World1'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/if-repeat.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/if-repeat.source.js b/test/js-framework/case/basic/if-repeat.source.js
new file mode 100644
index 0000000..aa62931
--- /dev/null
+++ b/test/js-framework/case/basic/if-repeat.source.js
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/if-repeat', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {showTitle: true, title: 'Hello World1'},
+ {showTitle: false, title: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": function () {return this.titlelist},
+ "shown": function () {return this.showTitle},
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/if-repeat')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/if-root.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/if-root.output.js b/test/js-framework/case/basic/if-root.output.js
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/test/js-framework/case/basic/if-root.output.js
@@ -0,0 +1 @@
+{}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/if-root.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/if-root.source.js b/test/js-framework/case/basic/if-root.source.js
new file mode 100644
index 0000000..ca94316
--- /dev/null
+++ b/test/js-framework/case/basic/if-root.source.js
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/if-root', function (require, exports, module) {
+
+;module.exports = {
+ data: function () {return {
+ visible: true,
+ }}
+}
+
+;module.exports.template = {
+ "type": "container",
+ "shown": function () {return this.visible},
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "container"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/if-root')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/if.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/if.output.js b/test/js-framework/case/basic/if.output.js
new file mode 100644
index 0000000..03dbeae
--- /dev/null
+++ b/test/js-framework/case/basic/if.output.js
@@ -0,0 +1,13 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: 'Hello World'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/if.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/if.source.js b/test/js-framework/case/basic/if.source.js
new file mode 100644
index 0000000..3ebb80c
--- /dev/null
+++ b/test/js-framework/case/basic/if.source.js
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/if', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ showTitle: true,
+ title: 'Hello World'
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "shown": function () {return this.showTitle},
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/if')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/promise.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/promise.output.js b/test/js-framework/case/basic/promise.output.js
new file mode 100644
index 0000000..07b17c9
--- /dev/null
+++ b/test/js-framework/case/basic/promise.output.js
@@ -0,0 +1,3 @@
+{
+ type: 'container'
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/promise.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/promise.source.js b/test/js-framework/case/basic/promise.source.js
new file mode 100644
index 0000000..67554ba
--- /dev/null
+++ b/test/js-framework/case/basic/promise.source.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo', function (require, exports, module) {
+new Promise(function (fulfill, reject){
+ fulfill(1)
+})
+Promise.all([Promise.resolve(1)])
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 1
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "a": {
+ "fontSize": 12
+ }
+}
+
+;module.exports.template = {
+ "type": "container"
+}
+
+;})
+
+
+bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/ready.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/ready.output.js b/test/js-framework/case/basic/ready.output.js
new file mode 100644
index 0000000..39c15f3
--- /dev/null
+++ b/test/js-framework/case/basic/ready.output.js
@@ -0,0 +1,11 @@
+{
+ "children": [
+ {
+ "attr": {
+ "value": "1"
+ },
+ "type": "text"
+ }
+ ],
+ "type": "container"
+}
\ No newline at end of file
[10/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/component.js
----------------------------------------------------------------------
diff --git a/runtime/api/component.js b/runtime/api/component.js
new file mode 100644
index 0000000..8a56961
--- /dev/null
+++ b/runtime/api/component.js
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { registerElement } from '../vdom/WeexElement'
+
+const weexComponents = {}
+
+/**
+ * Register native components information.
+ * @param {array} newComponents
+ */
+export function registerComponents (newComponents) {
+ if (Array.isArray(newComponents)) {
+ newComponents.forEach(component => {
+ if (!component) {
+ return
+ }
+ if (typeof component === 'string') {
+ weexComponents[component] = true
+ }
+ else if (typeof component === 'object' && typeof component.type === 'string') {
+ weexComponents[component.type] = component
+ registerElement(component.type, component.methods)
+ }
+ })
+ }
+}
+
+/**
+ * Check whether the component has been registered.
+ * @param {String} component name
+ */
+export function isRegisteredComponent (name) {
+ return !!weexComponents[name]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/config.js
----------------------------------------------------------------------
diff --git a/runtime/api/config.js b/runtime/api/config.js
new file mode 100644
index 0000000..d212f3d
--- /dev/null
+++ b/runtime/api/config.js
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Document, Element, Comment } from '../vdom'
+import Listener from '../bridge/Listener'
+import { TaskCenter } from '../bridge/TaskCenter'
+
+const config = {
+ Document, Element, Comment, Listener,
+ TaskCenter,
+ sendTasks (...args) {
+ if (typeof callNative === 'function') {
+ return callNative(...args)
+ }
+ return (global.callNative || (() => {}))(...args)
+ }
+}
+
+Document.handler = config.sendTasks
+
+export default config
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/index.js
----------------------------------------------------------------------
diff --git a/runtime/api/index.js b/runtime/api/index.js
new file mode 100644
index 0000000..a024db7
--- /dev/null
+++ b/runtime/api/index.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import init from './init'
+import config from './config'
+import { register, unregister, has } from './service'
+
+/* istanbul ignore next */
+function freezePrototype () {
+ // Object.freeze(config.Element)
+ Object.freeze(config.Comment)
+ Object.freeze(config.Listener)
+ Object.freeze(config.Document.prototype)
+ // Object.freeze(config.Element.prototype)
+ Object.freeze(config.Comment.prototype)
+ Object.freeze(config.Listener.prototype)
+}
+
+export default {
+ service: { register, unregister, has },
+ freezePrototype,
+ init,
+ config
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/init.js
----------------------------------------------------------------------
diff --git a/runtime/api/init.js b/runtime/api/init.js
new file mode 100644
index 0000000..187504a
--- /dev/null
+++ b/runtime/api/init.js
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { init as initTaskHandler } from '../bridge/TaskCenter'
+import { receiveTasks } from '../bridge/receiver'
+import { registerModules } from './module'
+import { registerComponents } from './component'
+import { services, register, unregister } from './service'
+import { track } from '../bridge/debug'
+import WeexInstance from './WeexInstance'
+import { getDoc } from '../vdom/operation'
+
+let frameworks
+let runtimeConfig
+
+const versionRegExp = /^\s*\/\/ *(\{[^}]*\}) *\r?\n/
+
+/**
+ * Detect a JS Bundle code and make sure which framework it's based to. Each JS
+ * Bundle should make sure that it starts with a line of JSON comment and is
+ * more that one line.
+ * @param {string} code
+ * @return {object}
+ */
+function getBundleType (code) {
+ const result = versionRegExp.exec(code)
+ if (result) {
+ try {
+ const info = JSON.parse(result[1])
+ return info.framework
+ }
+ catch (e) {}
+ }
+
+ // default bundle type
+ return 'Weex'
+}
+
+function createServices (id, env, config) {
+ // Init JavaScript services for this instance.
+ const serviceMap = Object.create(null)
+ serviceMap.service = Object.create(null)
+ services.forEach(({ name, options }) => {
+ if (process.env.NODE_ENV === 'development') {
+ console.debug(`[JS Runtime] create service ${name}.`)
+ }
+ const create = options.create
+ if (create) {
+ const result = create(id, env, config)
+ Object.assign(serviceMap.service, result)
+ Object.assign(serviceMap, result.instance)
+ }
+ })
+ delete serviceMap.service.instance
+ Object.freeze(serviceMap.service)
+ return serviceMap
+}
+
+const instanceTypeMap = {}
+function getFrameworkType (id) {
+ return instanceTypeMap[id]
+}
+
+function createInstanceContext (id, options = {}, data) {
+ const weex = new WeexInstance(id, options)
+ Object.freeze(weex)
+
+ const bundleType = options.bundleType || 'Vue'
+ instanceTypeMap[id] = bundleType
+ const framework = runtimeConfig.frameworks[bundleType]
+ if (!framework) {
+ return new Error(`[JS Framework] Invalid bundle type "${bundleType}".`)
+ }
+ track(id, 'bundleType', bundleType)
+
+ // prepare js service
+ const services = createServices(id, { weex, bundleType }, runtimeConfig)
+ Object.freeze(services)
+
+ // prepare runtime context
+ const runtimeContext = Object.create(null)
+ Object.assign(runtimeContext, services, {
+ weex,
+ services // Temporary compatible with some legacy APIs in Rax
+ })
+ Object.freeze(runtimeContext)
+
+ // prepare instance context
+ const instanceContext = Object.create(runtimeContext)
+ if (typeof framework.createInstanceContext === 'function') {
+ Object.assign(instanceContext, framework.createInstanceContext(id, runtimeContext, data))
+ }
+ Object.freeze(instanceContext)
+ return instanceContext
+}
+
+/**
+ * Check which framework a certain JS Bundle code based to. And create instance
+ * by this framework.
+ * @param {string} id
+ * @param {string} code
+ * @param {object} config
+ * @param {object} data
+ */
+function createInstance (id, code, config, data) {
+ if (instanceTypeMap[id]) {
+ return new Error(`The instance id "${id}" has already been used!`)
+ }
+
+ // Init instance info.
+ const bundleType = getBundleType(code)
+ instanceTypeMap[id] = bundleType
+
+ // Init instance config.
+ config = JSON.parse(JSON.stringify(config || {}))
+ config.env = JSON.parse(JSON.stringify(global.WXEnvironment || {}))
+ config.bundleType = bundleType
+
+ const framework = runtimeConfig.frameworks[bundleType]
+ if (!framework) {
+ return new Error(`[JS Framework] Invalid bundle type "${bundleType}".`)
+ }
+ if (bundleType === 'Weex') {
+ console.error(`[JS Framework] COMPATIBILITY WARNING: `
+ + `Weex DSL 1.0 (.we) framework is no longer supported! `
+ + `It will be removed in the next version of WeexSDK, `
+ + `your page would be crash if you still using the ".we" framework. `
+ + `Please upgrade it to Vue.js or Rax.`)
+ }
+
+ const instanceContext = createInstanceContext(id, config, data)
+ if (typeof framework.createInstance === 'function') {
+ // Temporary compatible with some legacy APIs in Rax,
+ // some Rax page is using the legacy ".we" framework.
+ if (bundleType === 'Rax' || bundleType === 'Weex') {
+ const raxInstanceContext = Object.assign({
+ config,
+ created: Date.now(),
+ framework: bundleType
+ }, instanceContext)
+ return framework.createInstance(id, code, config, data, raxInstanceContext)
+ }
+ return framework.createInstance(id, code, config, data, instanceContext)
+ }
+ // console.error(`[JS Framework] Can't find available "createInstance" method in ${bundleType}!`)
+ runInContext(code, instanceContext)
+}
+
+/**
+ * Run js code in a specific context.
+ * @param {string} code
+ * @param {object} context
+ */
+function runInContext (code, context) {
+ const keys = []
+ const args = []
+ for (const key in context) {
+ keys.push(key)
+ args.push(context[key])
+ }
+
+ const bundle = `
+ (function (global) {
+ ${code}
+ })(Object.create(this))
+ `
+
+ return (new Function(...keys, bundle))(...args)
+}
+
+/**
+ * Get the JSON object of the root element.
+ * @param {string} instanceId
+ */
+function getRoot (instanceId) {
+ const document = getDoc(instanceId)
+ try {
+ if (document && document.body) {
+ return document.body.toJSON()
+ }
+ }
+ catch (e) {
+ console.error(`[JS Framework] Failed to get the virtual dom tree.`)
+ return
+ }
+}
+
+const methods = {
+ createInstance,
+ createInstanceContext,
+ getRoot,
+ getDocument: getDoc,
+ registerService: register,
+ unregisterService: unregister,
+ callJS (id, tasks) {
+ const framework = frameworks[getFrameworkType(id)]
+ if (framework && typeof framework.receiveTasks === 'function') {
+ return framework.receiveTasks(id, tasks)
+ }
+ return receiveTasks(id, tasks)
+ }
+}
+
+/**
+ * Register methods which will be called for each instance.
+ * @param {string} methodName
+ */
+function genInstance (methodName) {
+ methods[methodName] = function (...args) {
+ const id = args[0]
+ const type = getFrameworkType(id)
+ if (type && frameworks[type]) {
+ const result = frameworks[type][methodName](...args)
+ const info = { framework: type }
+
+ // Lifecycle methods
+ if (methodName === 'refreshInstance') {
+ services.forEach(service => {
+ const refresh = service.options.refresh
+ if (refresh) {
+ refresh(id, { info, runtime: runtimeConfig })
+ }
+ })
+ }
+ else if (methodName === 'destroyInstance') {
+ services.forEach(service => {
+ const destroy = service.options.destroy
+ if (destroy) {
+ destroy(id, { info, runtime: runtimeConfig })
+ }
+ })
+ delete instanceTypeMap[id]
+ }
+
+ return result
+ }
+ return new Error(`[JS Framework] Using invalid instance id `
+ + `"${id}" when calling ${methodName}.`)
+ }
+}
+
+/**
+ * Register methods which init each frameworks.
+ * @param {string} methodName
+ * @param {function} sharedMethod
+ */
+function adaptMethod (methodName, sharedMethod) {
+ methods[methodName] = function (...args) {
+ if (typeof sharedMethod === 'function') {
+ sharedMethod(...args)
+ }
+
+ // TODO: deprecated
+ for (const name in runtimeConfig.frameworks) {
+ const framework = runtimeConfig.frameworks[name]
+ if (framework && framework[methodName]) {
+ framework[methodName](...args)
+ }
+ }
+ }
+}
+
+export default function init (config) {
+ runtimeConfig = config || {}
+ frameworks = runtimeConfig.frameworks || {}
+ initTaskHandler()
+
+ // Init each framework by `init` method and `config` which contains three
+ // virtual-DOM Class: `Document`, `Element` & `Comment`, and a JS bridge method:
+ // `sendTasks(...args)`.
+ for (const name in frameworks) {
+ const framework = frameworks[name]
+ if (typeof framework.init === 'function') {
+ try {
+ framework.init(config)
+ }
+ catch (e) {}
+ }
+ }
+
+ adaptMethod('registerComponents', registerComponents)
+ adaptMethod('registerModules', registerModules)
+ adaptMethod('registerMethods')
+
+ ; ['destroyInstance', 'refreshInstance'].forEach(genInstance)
+
+ return methods
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/module.js
----------------------------------------------------------------------
diff --git a/runtime/api/module.js b/runtime/api/module.js
new file mode 100644
index 0000000..df26b92
--- /dev/null
+++ b/runtime/api/module.js
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+const weexModules = {}
+
+/**
+ * Register native modules information.
+ * @param {object} newModules
+ */
+export function registerModules (newModules) {
+ for (const name in newModules) {
+ if (!weexModules[name]) {
+ weexModules[name] = {}
+ }
+ newModules[name].forEach(method => {
+ if (typeof method === 'string') {
+ weexModules[name][method] = true
+ }
+ else {
+ weexModules[name][method.name] = method.args
+ }
+ })
+ }
+}
+
+/**
+ * Check whether the module or the method has been registered.
+ * @param {String} module name
+ * @param {String} method name (optional)
+ */
+export function isRegisteredModule (name, method) {
+ if (typeof method === 'string') {
+ return !!(weexModules[name] && weexModules[name][method])
+ }
+ return !!weexModules[name]
+}
+
+export function getModuleDescription (name) {
+ return weexModules[name]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/api/service.js
----------------------------------------------------------------------
diff --git a/runtime/api/service.js b/runtime/api/service.js
new file mode 100644
index 0000000..6f2e72e
--- /dev/null
+++ b/runtime/api/service.js
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// JS Services
+
+export const services = []
+
+/**
+ * Register a JavaScript service.
+ * A JavaScript service options could have a set of lifecycle methods
+ * for each Weex instance. For example: create, refresh, destroy.
+ * For the JS framework maintainer if you want to supply some features
+ * which need to work well in different Weex instances, even in different
+ * frameworks separately. You can make a JavaScript service to init
+ * its variables or classes for each Weex instance when it's created
+ * and recycle them when it's destroyed.
+ * @param {object} options Could have { create, refresh, destroy }
+ * lifecycle methods. In create method it should
+ * return an object of what variables or classes
+ * would be injected into the Weex instance.
+ */
+export function register (name, options) {
+ if (has(name)) {
+ console.warn(`Service "${name}" has been registered already!`)
+ }
+ else {
+ options = Object.assign({}, options)
+ services.push({ name, options })
+ }
+}
+
+/**
+ * Unregister a JavaScript service by name
+ * @param {string} name
+ */
+export function unregister (name) {
+ services.some((service, index) => {
+ if (service.name === name) {
+ services.splice(index, 1)
+ return true
+ }
+ })
+}
+
+/**
+ * Check if a JavaScript service with a certain name existed.
+ * @param {string} name
+ * @return {Boolean}
+ */
+export function has (name) {
+ return indexOf(name) >= 0
+}
+
+/**
+ * Find the index of a JavaScript service by name
+ * @param {string} name
+ * @return {number}
+ */
+function indexOf (name) {
+ return services.map(service => service.name).indexOf(name)
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/CallbackManager.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/CallbackManager.js b/runtime/bridge/CallbackManager.js
new file mode 100644
index 0000000..70bd729
--- /dev/null
+++ b/runtime/bridge/CallbackManager.js
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { decodePrimitive } from './normalize'
+
+function getHookKey (componentId, type, hookName) {
+ return `${type}@${hookName}#${componentId}`
+}
+
+/**
+ * For general callback management of a certain Weex instance.
+ * Because function can not passed into native, so we create callback
+ * callback id for each function and pass the callback id into native
+ * in fact. And when a callback called from native, we can find the real
+ * callback through the callback id we have passed before.
+ */
+export default class CallbackManager {
+ constructor (instanceId) {
+ this.instanceId = String(instanceId)
+ this.lastCallbackId = 0
+ this.callbacks = {}
+ this.hooks = {}
+ }
+ add (callback) {
+ this.lastCallbackId++
+ this.callbacks[this.lastCallbackId] = callback
+ return this.lastCallbackId
+ }
+ remove (callbackId) {
+ const callback = this.callbacks[callbackId]
+ delete this.callbacks[callbackId]
+ return callback
+ }
+ registerHook (componentId, type, hookName, hookFunction) {
+ // TODO: validate arguments
+ const key = getHookKey(componentId, type, hookName)
+ if (this.hooks[key]) {
+ console.warn(`[JS Framework] Override an existing component hook "${key}".`)
+ }
+ this.hooks[key] = hookFunction
+ }
+ triggerHook (componentId, type, hookName, options = {}) {
+ // TODO: validate arguments
+ const key = getHookKey(componentId, type, hookName)
+ const hookFunction = this.hooks[key]
+ if (typeof hookFunction !== 'function') {
+ console.error(`[JS Framework] Invalid hook function type (${typeof hookFunction}) on "${key}".`)
+ return null
+ }
+ let result = null
+ try {
+ result = hookFunction.apply(null, options.args || [])
+ }
+ catch (e) {
+ console.error(`[JS Framework] Failed to execute the hook function on "${key}".`)
+ }
+ return result
+ }
+ consume (callbackId, data, ifKeepAlive) {
+ const callback = this.callbacks[callbackId]
+ if (typeof ifKeepAlive === 'undefined' || ifKeepAlive === false) {
+ delete this.callbacks[callbackId]
+ }
+ if (typeof callback === 'function') {
+ return callback(decodePrimitive(data))
+ }
+ return new Error(`invalid callback id "${callbackId}"`)
+ }
+ close () {
+ this.callbacks = {}
+ this.hooks = {}
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/Handler.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/Handler.js b/runtime/bridge/Handler.js
new file mode 100644
index 0000000..71bf4c5
--- /dev/null
+++ b/runtime/bridge/Handler.js
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @fileOverview
+ * Task handler for communication between javascript and native.
+ */
+
+const handlerMap = {
+ createBody: 'callCreateBody',
+ addElement: 'callAddElement',
+ removeElement: 'callRemoveElement',
+ moveElement: 'callMoveElement',
+ updateAttrs: 'callUpdateAttrs',
+ updateStyle: 'callUpdateStyle',
+ addEvent: 'callAddEvent',
+ removeEvent: 'callRemoveEvent'
+}
+
+/**
+ * Create a task handler.
+ * @param {string} id
+ * @param {function} handler
+ * @return {function} taskHandler
+ */
+export function createHandler (id, handler) {
+ const defaultHandler = handler || global.callNative
+
+ /* istanbul ignore if */
+ if (typeof defaultHandler !== 'function') {
+ console.error('[JS Runtime] no default handler')
+ }
+
+ return function taskHandler (tasks) {
+ /* istanbul ignore if */
+ if (!Array.isArray(tasks)) {
+ tasks = [tasks]
+ }
+ for (let i = 0; i < tasks.length; i++) {
+ const returnValue = dispatchTask(id, tasks[i], defaultHandler)
+ if (returnValue === -1) {
+ return returnValue
+ }
+ }
+ }
+}
+
+/**
+ * Check if there is a corresponding available handler in the environment.
+ * @param {string} module
+ * @param {string} method
+ * @return {boolean}
+ */
+function hasAvailableHandler (module, method) {
+ return module === 'dom'
+ && handlerMap[method]
+ && typeof global[handlerMap[method]] === 'function'
+}
+
+/**
+ * Dispatch the task to the specified handler.
+ * @param {string} id
+ * @param {object} task
+ * @param {function} defaultHandler
+ * @return {number} signal returned from native
+ */
+function dispatchTask (id, task, defaultHandler) {
+ const { module, method, args } = task
+
+ if (hasAvailableHandler(module, method)) {
+ return global[handlerMap[method]](id, ...args, '-1')
+ }
+
+ return defaultHandler(id, [task], '-1')
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/Listener.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/Listener.js b/runtime/bridge/Listener.js
new file mode 100644
index 0000000..2bf3893
--- /dev/null
+++ b/runtime/bridge/Listener.js
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+* Create the action object.
+* @param {string} name
+* @param {array} arguments
+* @return {object} action
+*/
+function createAction (name, args = []) {
+ return { module: 'dom', method: name, args: args }
+}
+
+export default class Listener {
+ constructor (id, handler) {
+ this.id = id
+ this.batched = false
+ this.updates = []
+ if (typeof handler === 'function') {
+ Object.defineProperty(this, 'handler', {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: handler
+ })
+ }
+ else {
+ console.error('[JS Runtime] invalid parameter, handler must be a function')
+ }
+ }
+
+ /**
+ * Send the "createFinish" signal.
+ * @param {function} callback
+ * @return {undefined | number} the signal sent by native
+ */
+ createFinish (callback) {
+ const handler = this.handler
+ return handler([createAction('createFinish')], callback)
+ }
+
+ /**
+ * Send the "updateFinish" signal.
+ * @param {function} callback
+ * @return {undefined | number} the signal sent by native
+ */
+ updateFinish (callback) {
+ const handler = this.handler
+ return handler([createAction('updateFinish')], callback)
+ }
+
+ /**
+ * Send the "refreshFinish" signal.
+ * @param {function} callback
+ * @return {undefined | number} the signal sent by native
+ */
+ refreshFinish (callback) {
+ const handler = this.handler
+ return handler([createAction('refreshFinish')], callback)
+ }
+
+ /**
+ * Send the "createBody" signal.
+ * @param {object} element
+ * @return {undefined | number} the signal sent by native
+ */
+ createBody (element) {
+ const body = element.toJSON()
+ const children = body.children
+ delete body.children
+ const actions = [createAction('createBody', [body])]
+ if (children) {
+ actions.push.apply(actions, children.map(child => {
+ return createAction('addElement', [body.ref, child, -1])
+ }))
+ }
+ return this.addActions(actions)
+ }
+
+ /**
+ * Send the "addElement" signal.
+ * @param {object} element
+ * @param {stirng} reference id
+ * @param {number} index
+ * @return {undefined | number} the signal sent by native
+ */
+ addElement (element, ref, index) {
+ if (!(index >= 0)) {
+ index = -1
+ }
+ return this.addActions(createAction('addElement', [ref, element.toJSON(), index]))
+ }
+
+ /**
+ * Send the "removeElement" signal.
+ * @param {stirng} reference id
+ * @return {undefined | number} the signal sent by native
+ */
+ removeElement (ref) {
+ if (Array.isArray(ref)) {
+ const actions = ref.map((r) => createAction('removeElement', [r]))
+ return this.addActions(actions)
+ }
+ return this.addActions(createAction('removeElement', [ref]))
+ }
+
+ /**
+ * Send the "moveElement" signal.
+ * @param {stirng} target reference id
+ * @param {stirng} parent reference id
+ * @param {number} index
+ * @return {undefined | number} the signal sent by native
+ */
+ moveElement (targetRef, parentRef, index) {
+ return this.addActions(createAction('moveElement', [targetRef, parentRef, index]))
+ }
+
+ /**
+ * Send the "updateAttrs" signal.
+ * @param {stirng} reference id
+ * @param {stirng} key
+ * @param {stirng} value
+ * @return {undefined | number} the signal sent by native
+ */
+ setAttr (ref, key, value) {
+ const result = {}
+ result[key] = value
+ return this.addActions(createAction('updateAttrs', [ref, result]))
+ }
+
+ /**
+ * Send the "updateStyle" signal, update a sole style.
+ * @param {stirng} reference id
+ * @param {stirng} key
+ * @param {stirng} value
+ * @return {undefined | number} the signal sent by native
+ */
+ setStyle (ref, key, value) {
+ const result = {}
+ result[key] = value
+ return this.addActions(createAction('updateStyle', [ref, result]))
+ }
+
+ /**
+ * Send the "updateStyle" signal.
+ * @param {stirng} reference id
+ * @param {object} style
+ * @return {undefined | number} the signal sent by native
+ */
+ setStyles (ref, style) {
+ return this.addActions(createAction('updateStyle', [ref, style]))
+ }
+
+ /**
+ * Send the "addEvent" signal.
+ * @param {stirng} reference id
+ * @param {string} event type
+ * @return {undefined | number} the signal sent by native
+ */
+ addEvent (ref, type) {
+ return this.addActions(createAction('addEvent', [ref, type]))
+ }
+
+ /**
+ * Send the "removeEvent" signal.
+ * @param {stirng} reference id
+ * @param {string} event type
+ * @return {undefined | number} the signal sent by native
+ */
+ removeEvent (ref, type) {
+ return this.addActions(createAction('removeEvent', [ref, type]))
+ }
+
+ /**
+ * Default handler.
+ * @param {object | array} actions
+ * @param {function} callback
+ * @return {} anything returned by callback function
+ */
+ handler (actions, cb) {
+ return cb && cb()
+ }
+
+ /**
+ * Add actions into updates.
+ * @param {object | array} actions
+ * @return {undefined | number} the signal sent by native
+ */
+ addActions (actions) {
+ const updates = this.updates
+ const handler = this.handler
+
+ if (!Array.isArray(actions)) {
+ actions = [actions]
+ }
+
+ if (this.batched) {
+ updates.push.apply(updates, actions)
+ }
+ else {
+ return handler(actions)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/TaskCenter.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/TaskCenter.js b/runtime/bridge/TaskCenter.js
new file mode 100644
index 0000000..c2652c0
--- /dev/null
+++ b/runtime/bridge/TaskCenter.js
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import CallbackManager from './CallbackManager'
+import Element from '../vdom/Element'
+import { typof } from '../shared/utils'
+import { normalizePrimitive } from './normalize'
+
+let fallback = function () {}
+
+// The API of TaskCenter would be re-design.
+export class TaskCenter {
+ constructor (id, sendTasks) {
+ Object.defineProperty(this, 'instanceId', {
+ enumerable: true,
+ value: String(id)
+ })
+ Object.defineProperty(this, 'callbackManager', {
+ enumerable: true,
+ value: new CallbackManager(id)
+ })
+ fallback = sendTasks || function () {}
+ }
+
+ callback (callbackId, data, ifKeepAlive) {
+ return this.callbackManager.consume(callbackId, data, ifKeepAlive)
+ }
+
+ registerHook (...args) {
+ return this.callbackManager.registerHook(...args)
+ }
+
+ triggerHook (...args) {
+ return this.callbackManager.triggerHook(...args)
+ }
+
+ updateData (componentId, newData, callback) {
+ this.send('module', {
+ module: 'dom',
+ method: 'updateComponentData'
+ }, [componentId, newData, callback])
+ }
+
+ destroyCallback () {
+ return this.callbackManager.close()
+ }
+
+ /**
+ * Normalize a value. Specially, if the value is a function, then generate a function id
+ * and save it to `CallbackManager`, at last return the function id.
+ * @param {any} v
+ * @return {primitive}
+ */
+ normalize (v) {
+ const type = typof(v)
+ if (v && v instanceof Element) {
+ return v.ref
+ }
+ if (v && v._isVue && v.$el instanceof Element) {
+ return v.$el.ref
+ }
+ if (type === 'Function') {
+ return this.callbackManager.add(v).toString()
+ }
+ return normalizePrimitive(v)
+ }
+
+ send (type, params, args, options) {
+ const { action, component, ref, module, method } = params
+
+ args = args.map(arg => this.normalize(arg))
+
+ switch (type) {
+ case 'dom':
+ return this[action](this.instanceId, args)
+ case 'component':
+ return this.componentHandler(this.instanceId, ref, method, args, Object.assign({ component }, options))
+ default:
+ return this.moduleHandler(this.instanceId, module, method, args, options)
+ }
+ }
+
+ callDOM (action, args) {
+ return this[action](this.instanceId, args)
+ }
+
+ callComponent (ref, method, args, options) {
+ return this.componentHandler(this.instanceId, ref, method, args, options)
+ }
+
+ callModule (module, method, args, options) {
+ return this.moduleHandler(this.instanceId, module, method, args, options)
+ }
+}
+
+export function init () {
+ const DOM_METHODS = {
+ createFinish: global.callCreateFinish,
+ updateFinish: global.callUpdateFinish,
+ refreshFinish: global.callRefreshFinish,
+
+ createBody: global.callCreateBody,
+
+ addElement: global.callAddElement,
+ removeElement: global.callRemoveElement,
+ moveElement: global.callMoveElement,
+ updateAttrs: global.callUpdateAttrs,
+ updateStyle: global.callUpdateStyle,
+
+ addEvent: global.callAddEvent,
+ removeEvent: global.callRemoveEvent
+ }
+ const proto = TaskCenter.prototype
+
+ for (const name in DOM_METHODS) {
+ const method = DOM_METHODS[name]
+ proto[name] = method ?
+ (id, args) => method(id, ...args) :
+ (id, args) => fallback(id, [{ module: 'dom', method: name, args }], '-1')
+ }
+
+ proto.componentHandler = global.callNativeComponent ||
+ ((id, ref, method, args, options) =>
+ fallback(id, [{ component: options.component, ref, method, args }]))
+
+ proto.moduleHandler = global.callNativeModule ||
+ ((id, module, method, args) =>
+ fallback(id, [{ module, method, args }]))
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/debug.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/debug.js b/runtime/bridge/debug.js
new file mode 100644
index 0000000..6e24c6a
--- /dev/null
+++ b/runtime/bridge/debug.js
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { getTaskCenter } from '../vdom/operation'
+import { isRegisteredModule } from '../api/module'
+
+export function track (id, type, value) {
+ const taskCenter = getTaskCenter(id)
+ if (!taskCenter || typeof taskCenter.send !== 'function') {
+ console.error(`[JS Framework] Failed to create tracker!`)
+ return
+ }
+ if (!type || !value) {
+ console.warn(`[JS Framework] Invalid track type (${type}) or value (${value})`)
+ return
+ }
+ const label = `jsfm.${type}.${value}`
+ try {
+ if (isRegisteredModule('userTrack', 'addPerfPoint')) {
+ const message = Object.create(null)
+ message[label] = '4'
+ taskCenter.send('module', {
+ module: 'userTrack',
+ method: 'addPerfPoint'
+ }, [message])
+ }
+ }
+ catch (err) {
+ console.error(`[JS Framework] Failed to trace "${label}"!`)
+ }
+}
+
+export function error (...messages) {
+ if (typeof console.error === 'function') {
+ console.error(`[JS Framework] `, ...messages)
+ }
+}
+
+export function handleException (err) {
+ if (typeof console.error === 'function') {
+ try {
+ console.error(err.toString())
+ }
+ catch (e) {}
+ }
+ if (process.env.NODE_ENV !== 'production') {
+ throw err
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/normalize.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/normalize.js b/runtime/bridge/normalize.js
new file mode 100644
index 0000000..4c6a058
--- /dev/null
+++ b/runtime/bridge/normalize.js
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { typof, bufferToBase64, base64ToBuffer } from '../shared/utils'
+
+/**
+ * Normalize a primitive value.
+ * @param {any} v
+ * @return {primitive}
+ */
+export function normalizePrimitive (v) {
+ const type = typof(v)
+
+ switch (type) {
+ case 'Undefined':
+ case 'Null':
+ return ''
+
+ case 'RegExp':
+ return v.toString()
+ case 'Date':
+ return v.toISOString()
+
+ case 'Number':
+ case 'String':
+ case 'Boolean':
+ case 'Array':
+ case 'Object':
+ return v
+
+ case 'ArrayBuffer':
+ return {
+ '@type': 'binary',
+ dataType: type,
+ base64: bufferToBase64(v)
+ }
+
+ case 'Int8Array':
+ case 'Uint8Array':
+ case 'Uint8ClampedArray':
+ case 'Int16Array':
+ case 'Uint16Array':
+ case 'Int32Array':
+ case 'Uint32Array':
+ case 'Float32Array':
+ case 'Float64Array':
+ return {
+ '@type': 'binary',
+ dataType: type,
+ base64: bufferToBase64(v.buffer)
+ }
+
+ default:
+ return JSON.stringify(v)
+ }
+}
+
+export function decodePrimitive (data) {
+ if (typof(data) === 'Object') {
+ // decode base64 into binary
+ if (data['@type'] && data['@type'] === 'binary') {
+ return base64ToBuffer(data.base64 || '')
+ }
+
+ const realData = {}
+ for (const key in data) {
+ realData[key] = decodePrimitive(data[key])
+ }
+ return realData
+ }
+ if (typof(data) === 'Array') {
+ return data.map(decodePrimitive)
+ }
+ return data
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/bridge/receiver.js
----------------------------------------------------------------------
diff --git a/runtime/bridge/receiver.js b/runtime/bridge/receiver.js
new file mode 100644
index 0000000..e6dea06
--- /dev/null
+++ b/runtime/bridge/receiver.js
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { getDoc } from '../vdom/operation'
+
+function fireEvent (document, nodeId, type, event, domChanges, params) {
+ const el = document.getRef(nodeId)
+ if (el) {
+ return document.fireEvent(el, type, event, domChanges, params)
+ }
+ return new Error(`invalid element reference "${nodeId}"`)
+}
+
+function callback (document, callbackId, data, ifKeepAlive) {
+ return document.taskCenter.callback(callbackId, data, ifKeepAlive)
+}
+
+function componentHook (document, componentId, type, hook, options) {
+ if (!document || !document.taskCenter) {
+ console.error(`[JS Framework] Can't find "document" or "taskCenter".`)
+ return null
+ }
+ let result = null
+ try {
+ result = document.taskCenter.triggerHook(componentId, type, hook, options)
+ }
+ catch (e) {
+ console.error(`[JS Framework] Failed to trigger the "${type}@${hook}" hook on ${componentId}.`)
+ }
+ return result
+}
+
+/**
+ * Accept calls from native (event or callback).
+ *
+ * @param {string} id
+ * @param {array} tasks list with `method` and `args`
+ */
+export function receiveTasks (id, tasks) {
+ const document = getDoc(id)
+ if (!document) {
+ return new Error(`[JS Framework] Failed to receiveTasks, `
+ + `instance (${id}) is not available.`)
+ }
+ if (Array.isArray(tasks)) {
+ return tasks.map(task => {
+ switch (task.method) {
+ case 'callback': return callback(document, ...task.args)
+ case 'fireEventSync':
+ case 'fireEvent': return fireEvent(document, ...task.args)
+ case 'componentHook': return componentHook(document, ...task.args)
+ }
+ })
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/entries/index.js
----------------------------------------------------------------------
diff --git a/runtime/entries/index.js b/runtime/entries/index.js
new file mode 100644
index 0000000..9d590b6
--- /dev/null
+++ b/runtime/entries/index.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import setup from './setup'
+import frameworks from '../frameworks'
+
+setup(frameworks)
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/entries/rax.js
----------------------------------------------------------------------
diff --git a/runtime/entries/rax.js b/runtime/entries/rax.js
new file mode 100644
index 0000000..2aa17fd
--- /dev/null
+++ b/runtime/entries/rax.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import setup from './setup'
+import * as Rax from 'weex-rax-framework'
+
+setup({ Rax })
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/entries/setup.js
----------------------------------------------------------------------
diff --git a/runtime/entries/setup.js b/runtime/entries/setup.js
new file mode 100644
index 0000000..7c59712
--- /dev/null
+++ b/runtime/entries/setup.js
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { subversion } from '../../package.json'
+import * as shared from '../shared'
+import runtime from '../api'
+import services from '../services'
+
+/**
+ * Setup frameworks with runtime.
+ * You can package more frameworks by
+ * passing them as arguments.
+ */
+export default function (frameworks) {
+ const { init, config } = runtime
+ config.frameworks = frameworks
+ const { native, transformer } = subversion
+
+ for (const serviceName in services) {
+ runtime.service.register(serviceName, services[serviceName])
+ }
+
+ shared.freezePrototype()
+ shared.setNativeConsole()
+ runtime.freezePrototype()
+
+ // register framework meta info
+ global.frameworkVersion = native
+ global.transformerVersion = transformer
+
+ // init frameworks
+ const globalMethods = init(config)
+
+ // set global methods
+ for (const methodName in globalMethods) {
+ global[methodName] = (...args) => {
+ const ret = globalMethods[methodName](...args)
+ if (ret instanceof Error) {
+ console.error(ret.toString())
+ }
+ return ret
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/entries/vue.js
----------------------------------------------------------------------
diff --git a/runtime/entries/vue.js b/runtime/entries/vue.js
new file mode 100644
index 0000000..3cc816b
--- /dev/null
+++ b/runtime/entries/vue.js
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import setup from './setup'
+import * as Vue from 'weex-vue-framework'
+
+setup({ Vue })
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/index.js b/runtime/frameworks/index.js
new file mode 100644
index 0000000..8880f75
--- /dev/null
+++ b/runtime/frameworks/index.js
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import * as Vanilla from './vanilla/index'
+import * as Vue from 'weex-vue-framework'
+import * as Weex from './legacy/index'
+import Rax from 'weex-rax-framework'
+
+export default {
+ Vanilla,
+ Vue,
+ Rax,
+ Weex
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/api/methods.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/api/methods.js b/runtime/frameworks/legacy/api/methods.js
new file mode 100644
index 0000000..19f1cdc
--- /dev/null
+++ b/runtime/frameworks/legacy/api/methods.js
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview The api for invoking with "$" prefix
+ */
+
+/**
+ * @deprecated use $vm instead
+ * find the vm by id
+ * Note: there is only one id in whole component
+ * @param {string} id
+ * @return {Vm}
+ */
+export function $ (id) {
+ console.warn('[JS Framework] Vm#$ is deprecated, please use Vm#$vm instead')
+ const info = this._ids[id]
+ if (info) {
+ return info.vm
+ }
+}
+
+/**
+ * find the element by id
+ * Note: there is only one id in whole component
+ * @param {string} id
+ * @return {Element}
+ */
+export function $el (id) {
+ const info = this._ids[id]
+ if (info) {
+ return info.el
+ }
+}
+
+/**
+ * find the vm of the custom component by id
+ * Note: there is only one id in whole component
+ * @param {string} id
+ * @return {Vm}
+ */
+export function $vm (id) {
+ const info = this._ids[id]
+ if (info) {
+ return info.vm
+ }
+}
+
+/**
+ * Fire when differ rendering finished
+ *
+ * @param {Function} fn
+ */
+export function $renderThen (fn) {
+ const app = this._app
+ const differ = app.differ
+ return differ.then(() => {
+ fn()
+ })
+}
+
+/**
+ * scroll an element specified by id into view,
+ * moreover specify a number of offset optionally
+ * @param {string} id
+ * @param {number} offset
+ */
+export function $scrollTo (id, offset) {
+ console.warn('[JS Framework] Vm#$scrollTo is deprecated, ' +
+ 'please use "require(\'@weex-module/dom\')' +
+ '.scrollTo(el, options)" instead')
+ const el = this.$el(id)
+ if (el) {
+ const dom = this._app.requireModule('dom')
+ dom.scrollToElement(el.ref, { offset: offset })
+ }
+}
+
+/**
+ * perform transition animation on an element specified by id
+ * @param {string} id
+ * @param {object} options
+ * @param {object} options.styles
+ * @param {object} options.duration(ms)
+ * @param {object} [options.timingFunction]
+ * @param {object} [options.delay=0(ms)]
+ * @param {Function} callback
+ */
+export function $transition (id, options, callback) {
+ const el = this.$el(id)
+ if (el && options && options.styles) {
+ const animation = this._app.requireModule('animation')
+ animation.transition(el.ref, options, (...args) => {
+ this._setStyle(el, options.styles)
+ callback && callback(...args)
+ })
+ }
+}
+
+/**
+ * get some config
+ * @return {object} some config for app instance
+ * @property {string} bundleUrl
+ * @property {boolean} debug
+ * @property {object} env
+ * @property {string} env.weexVersion(ex. 1.0.0)
+ * @property {string} env.appName(ex. TB/TM)
+ * @property {string} env.appVersion(ex. 5.0.0)
+ * @property {string} env.platform(ex. iOS/Android)
+ * @property {string} env.osVersion(ex. 7.0.0)
+ * @property {string} env.deviceModel **native only**
+ * @property {number} env.[deviceWidth=750]
+ * @property {number} env.deviceHeight
+ */
+export function $getConfig (callback) {
+ const config = this._app.options
+ if (typeof callback === 'function') {
+ console.warn('[JS Framework] the callback of Vm#$getConfig(callback) is deprecated, ' +
+ 'this api now can directly RETURN config info.')
+ callback(config)
+ }
+ return config
+}
+
+/**
+ * @deprecated
+ * request network via http protocol
+ * @param {object} params
+ * @param {Function} callback
+ */
+export function $sendHttp (params, callback) {
+ console.warn('[JS Framework] Vm#$sendHttp is deprecated, ' +
+ 'please use "require(\'@weex-module/stream\')' +
+ '.sendHttp(params, callback)" instead')
+ const stream = this._app.requireModule('stream')
+ stream.sendHttp(params, callback)
+}
+
+/**
+ * @deprecated
+ * open a url
+ * @param {string} url
+ */
+export function $openURL (url) {
+ console.warn('[JS Framework] Vm#$openURL is deprecated, ' +
+ 'please use "require(\'@weex-module/event\')' +
+ '.openURL(url)" instead')
+ const event = this._app.requireModule('event')
+ event.openURL(url)
+}
+
+/**
+ * @deprecated
+ * set a title for page
+ * @param {string} title
+ */
+export function $setTitle (title) {
+ console.warn('[JS Framework] Vm#$setTitle is deprecated, ' +
+ 'please use "require(\'@weex-module/pageInfo\')' +
+ '.setTitle(title)" instead')
+ const pageInfo = this._app.requireModule('pageInfo')
+ pageInfo.setTitle(title)
+}
+
+/**
+ * @deprecated use "require('@weex-module/moduleName') instead"
+ * invoke a native method by specifing the name of module and method
+ * @param {string} moduleName
+ * @param {string} methodName
+ * @param {...*} the rest arguments
+ */
+export function $call (moduleName, methodName, ...args) {
+ console.warn('[JS Framework] Vm#$call is deprecated, ' +
+ 'please use "require(\'@weex-module/moduleName\')" instead')
+ const module = this._app.requireModule(moduleName)
+ if (module && module[methodName]) {
+ module[methodName](...args)
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/api/modules.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/api/modules.js b/runtime/frameworks/legacy/api/modules.js
new file mode 100644
index 0000000..60123b0
--- /dev/null
+++ b/runtime/frameworks/legacy/api/modules.js
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @deprecated after native register these modules
+ */
+
+/**
+ * @module dom
+ * @type {Array}
+ */
+export const dom = [
+ /**
+ * @method scrollToElement
+ * @param {string} ref
+ * @param {object} options
+ * @param {number} options.offset
+ */
+ {
+ name: 'scrollToElement',
+ args: ['string', 'object']
+ }
+]
+
+/**
+ * @module stream
+ */
+export const stream = [
+ /**
+ * @method sendHttp
+ * @param {object} params
+ * @param {string} params.url
+ * @param {string} [params.method]
+ * @param {object} [params.header]
+ * @param {object} params.body
+ * @param {function} callback
+ */
+ {
+ name: 'sendHttp',
+ args: ['object', 'function']
+ }
+]
+
+/**
+ * @module event
+ */
+export const event = [
+ /**
+ * @method openURL
+ * @param {string} url
+ */
+ {
+ name: 'openURL',
+ args: ['string']
+ }
+]
+
+/**
+ * @module pageInfo
+ */
+export const pageInfo = [
+ /**
+ * @method setTitle
+ * @param {string} text
+ */
+ {
+ name: 'setTitle',
+ args: ['string']
+ }
+]
+
+/**
+ * @module animation
+ */
+export const animation = [
+
+ {
+ name: 'transition',
+ args: ['string', 'object', 'function']
+ }
+]
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/bundle/bootstrap.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/bundle/bootstrap.js b/runtime/frameworks/legacy/app/bundle/bootstrap.js
new file mode 100644
index 0000000..8821873
--- /dev/null
+++ b/runtime/frameworks/legacy/app/bundle/bootstrap.js
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import semver from 'semver'
+import Vm from '../../vm/index'
+import * as downgrade from '../downgrade'
+import { setViewport } from '../viewport'
+import {
+ requireCustomComponent
+} from '../register'
+import {
+ isPlainObject,
+ isWeexComponent,
+ isNpmModule,
+ removeWeexPrefix,
+ removeJSSurfix
+} from '../../util/index'
+
+/**
+ * bootstrap app from a certain custom component with config & data
+ */
+export function bootstrap (app, name, config, data) {
+ console.debug(`[JS Framework] bootstrap for ${name}`)
+
+ // 1. validate custom component name first
+ let cleanName
+ if (isWeexComponent(name)) {
+ cleanName = removeWeexPrefix(name)
+ }
+ else if (isNpmModule(name)) {
+ cleanName = removeJSSurfix(name)
+ // check if define by old 'define' method
+ /* istanbul ignore if */
+ if (!requireCustomComponent(app, cleanName)) {
+ return new Error(`It's not a component: ${name}`)
+ }
+ }
+ else {
+ return new Error(`Wrong component name: ${name}`)
+ }
+
+ // 2. validate configuration
+ config = isPlainObject(config) ? config : {}
+ // 2.1 transformer version check
+ if (typeof config.transformerVersion === 'string' &&
+ typeof global.transformerVersion === 'string' &&
+ !semver.satisfies(config.transformerVersion,
+ global.transformerVersion)) {
+ return new Error(`JS Bundle version: ${config.transformerVersion} ` +
+ `not compatible with ${global.transformerVersion}`)
+ }
+ // 2.2 downgrade version check
+ const downgradeResult = downgrade.check(config.downgrade)
+ /* istanbul ignore if */
+ if (downgradeResult.isDowngrade) {
+ app.callTasks([{
+ module: 'instanceWrap',
+ method: 'error',
+ args: [
+ downgradeResult.errorType,
+ downgradeResult.code,
+ downgradeResult.errorMessage
+ ]
+ }])
+ return new Error(`Downgrade[${downgradeResult.code}]: ${downgradeResult.errorMessage}`)
+ }
+
+ // set viewport
+ if (config.viewport) {
+ setViewport(app, config.viewport)
+ }
+
+ // 3. create a new Vm with custom component name and data
+ app.vm = new Vm(cleanName, null, { _app: app }, null, data)
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/bundle/define.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/bundle/define.js b/runtime/frameworks/legacy/app/bundle/define.js
new file mode 100644
index 0000000..aec30f7
--- /dev/null
+++ b/runtime/frameworks/legacy/app/bundle/define.js
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import {
+ isWeexComponent,
+ isWeexModule,
+ isNormalModule,
+ isNpmModule,
+ removeWeexPrefix,
+ removeJSSurfix
+} from '../../util/index'
+import {
+ registerCustomComponent,
+ requireCustomComponent,
+ initModules
+} from '../register'
+
+/**
+ * define(name, factory) for primary usage
+ * or
+ * define(name, deps, factory) for compatibility
+ * Notice: DO NOT use function define() {},
+ * it will cause error after builded by webpack
+ */
+export const defineFn = function (app, name, ...args) {
+ console.debug(`[JS Framework] define a component ${name}`)
+
+ // adapt args:
+ // 1. name, deps[], factory()
+ // 2. name, factory()
+ // 3. name, definition{}
+ let factory, definition
+ if (args.length > 1) {
+ definition = args[1]
+ }
+ else {
+ definition = args[0]
+ }
+ if (typeof definition === 'function') {
+ factory = definition
+ definition = null
+ }
+
+ // resolve definition from factory
+ if (factory) {
+ const r = (name) => {
+ if (isWeexComponent(name)) {
+ const cleanName = removeWeexPrefix(name)
+ return requireCustomComponent(app, cleanName)
+ }
+ if (isWeexModule(name)) {
+ const cleanName = removeWeexPrefix(name)
+ return app.requireModule(cleanName)
+ }
+ if (isNormalModule(name) || isNpmModule(name)) {
+ const cleanName = removeJSSurfix(name)
+ return app.commonModules[cleanName]
+ }
+ }
+ const m = { exports: {}}
+ factory(r, m.exports, m)
+ definition = m.exports
+ }
+
+ // apply definition
+ if (isWeexComponent(name)) {
+ const cleanName = removeWeexPrefix(name)
+ registerCustomComponent(app, cleanName, definition)
+ }
+ else if (isWeexModule(name)) {
+ const cleanName = removeWeexPrefix(name)
+ initModules({ [cleanName]: definition })
+ }
+ else if (isNormalModule(name)) {
+ const cleanName = removeJSSurfix(name)
+ app.commonModules[cleanName] = definition
+ }
+ else if (isNpmModule(name)) {
+ const cleanName = removeJSSurfix(name)
+ if (definition.template ||
+ definition.style ||
+ definition.methods) {
+ // downgrade to old define method (define('componentName', factory))
+ // the exports contain one key of template, style or methods
+ // but it has risk!!!
+ registerCustomComponent(app, cleanName, definition)
+ }
+ else {
+ app.commonModules[cleanName] = definition
+ }
+ }
+}
+
+/**
+ * @deprecated
+ */
+export function register (app, type, options) {
+ console.warn('[JS Framework] Register is deprecated, please install lastest transformer.')
+ registerCustomComponent(app, type, options)
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/bundle/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/bundle/index.js b/runtime/frameworks/legacy/app/bundle/index.js
new file mode 100644
index 0000000..40126cf
--- /dev/null
+++ b/runtime/frameworks/legacy/app/bundle/index.js
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * api that invoked by js bundle code
+ *
+ * - define(name, factory): define a new composed component type
+ * - bootstrap(type, config, data): require a certain type &
+ * render with (optional) data
+ *
+ * deprecated:
+ * - register(type, options): register a new composed component type
+ * - render(type, data): render by a certain type with (optional) data
+ * - require(type)(data): require a type then render with data
+ */
+
+export { bootstrap } from './bootstrap'
+export { defineFn, register } from './define'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/ctrl/index.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/ctrl/index.js b/runtime/frameworks/legacy/app/ctrl/index.js
new file mode 100644
index 0000000..99fb3a7
--- /dev/null
+++ b/runtime/frameworks/legacy/app/ctrl/index.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * instance controls from native
+ *
+ * - init bundle
+ * - fire event
+ * - callback
+ * - destroy
+ *
+ * corresponded with the API of instance manager (framework.js)
+ */
+export { init } from './init'
+
+export {
+ refresh,
+ destroy,
+ getRootElement,
+ fireEvent,
+ callback,
+ updateActions,
+ callTasks
+} from './misc'
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/ctrl/init.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/ctrl/init.js b/runtime/frameworks/legacy/app/ctrl/init.js
new file mode 100644
index 0000000..401d614
--- /dev/null
+++ b/runtime/frameworks/legacy/app/ctrl/init.js
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * instance controls from native
+ *
+ * - init bundle
+ *
+ * corresponded with the API of instance manager (framework.js)
+ */
+
+import Vm from '../../vm/index'
+import { removeWeexPrefix } from '../../util/index'
+import {
+ defineFn,
+ bootstrap,
+ register
+} from '../bundle/index'
+import { updateActions } from './misc'
+
+/**
+ * Init an app by run code witgh data
+ * @param {object} app
+ * @param {string} code
+ * @param {object} data
+ */
+export function init (app, code, data, services) {
+ console.debug('[JS Framework] Intialize an instance with:\n', data)
+ let result
+
+ // prepare app env methods
+ const bundleDefine = (...args) => defineFn(app, ...args)
+ const bundleBootstrap = (name, config, _data) => {
+ result = bootstrap(app, name, config, _data || data)
+ updateActions(app)
+ app.doc.listener.createFinish()
+ console.debug(`[JS Framework] After intialized an instance(${app.id})`)
+ }
+ const bundleVm = Vm
+ /* istanbul ignore next */
+ const bundleRegister = (...args) => register(app, ...args)
+ /* istanbul ignore next */
+ const bundleRender = (name, _data) => {
+ result = bootstrap(app, name, {}, _data)
+ }
+ /* istanbul ignore next */
+ const bundleRequire = name => _data => {
+ result = bootstrap(app, name, {}, _data)
+ }
+ const bundleDocument = app.doc
+ /* istanbul ignore next */
+ const bundleRequireModule = name => app.requireModule(removeWeexPrefix(name))
+
+ const weexGlobalObject = {
+ config: app.options,
+ define: bundleDefine,
+ bootstrap: bundleBootstrap,
+ requireModule: bundleRequireModule,
+ document: bundleDocument,
+ Vm: bundleVm
+ }
+
+ Object.freeze(weexGlobalObject)
+
+ // prepare code
+ let functionBody
+ /* istanbul ignore if */
+ if (typeof code === 'function') {
+ // `function () {...}` -> `{...}`
+ // not very strict
+ functionBody = code.toString().substr(12)
+ }
+ /* istanbul ignore next */
+ else if (code) {
+ functionBody = code.toString()
+ }
+ // wrap IFFE and use strict mode
+ functionBody = `(function(global){\n\n"use strict";\n\n ${functionBody} \n\n})(Object.create(this))`
+
+ // run code and get result
+ const { WXEnvironment } = global
+ const timerAPIs = {}
+
+ /* istanbul ignore if */
+ if (WXEnvironment && WXEnvironment.platform !== 'Web') {
+ // timer APIs polyfill in native
+ const timer = app.requireModule('timer')
+ Object.assign(timerAPIs, {
+ setTimeout: (...args) => {
+ const handler = function () {
+ args[0](...args.slice(2))
+ }
+ timer.setTimeout(handler, args[1])
+ return app.doc.taskCenter.callbackManager.lastCallbackId.toString()
+ },
+ setInterval: (...args) => {
+ const handler = function () {
+ args[0](...args.slice(2))
+ }
+ timer.setInterval(handler, args[1])
+ return app.doc.taskCenter.callbackManager.lastCallbackId.toString()
+ },
+ clearTimeout: (n) => {
+ timer.clearTimeout(n)
+ },
+ clearInterval: (n) => {
+ timer.clearInterval(n)
+ }
+ })
+ }
+ // run code and get result
+ const globalObjects = Object.assign({
+ define: bundleDefine,
+ require: bundleRequire,
+ bootstrap: bundleBootstrap,
+ register: bundleRegister,
+ render: bundleRender,
+ __weex_define__: bundleDefine, // alias for define
+ __weex_bootstrap__: bundleBootstrap, // alias for bootstrap
+ __weex_document__: bundleDocument,
+ __weex_require__: bundleRequireModule,
+ __weex_viewmodel__: bundleVm,
+ weex: weexGlobalObject
+ }, timerAPIs, services)
+ if (!callFunctionNative(globalObjects, functionBody)) {
+ // If failed to compile functionBody on native side,
+ // fallback to callFunction.
+ callFunction(globalObjects, functionBody)
+ }
+
+ return result
+}
+
+/**
+ * Call a new function body with some global objects.
+ * @param {object} globalObjects
+ * @param {string} code
+ * @return {any}
+ */
+function callFunction (globalObjects, body) {
+ const globalKeys = []
+ const globalValues = []
+ for (const key in globalObjects) {
+ globalKeys.push(key)
+ globalValues.push(globalObjects[key])
+ }
+ globalKeys.push(body)
+
+ const result = new Function(...globalKeys)
+ return result(...globalValues)
+}
+
+/**
+ * Call a new function generated on the V8 native side.
+ * @param {object} globalObjects
+ * @param {string} body
+ * @return {boolean} return true if no error occurred.
+ */
+function callFunctionNative (globalObjects, body) {
+ if (typeof compileAndRunBundle !== 'function') {
+ return false
+ }
+
+ let fn = void 0
+ let isNativeCompileOk = false
+ let script = '(function ('
+ const globalKeys = []
+ const globalValues = []
+ for (const key in globalObjects) {
+ globalKeys.push(key)
+ globalValues.push(globalObjects[key])
+ }
+ for (let i = 0; i < globalKeys.length - 1; ++i) {
+ script += globalKeys[i]
+ script += ','
+ }
+ script += globalKeys[globalKeys.length - 1]
+ script += ') {'
+ script += body
+ script += '} )'
+
+ try {
+ const weex = globalObjects.weex || {}
+ const config = weex.config || {}
+ fn = compileAndRunBundle(script,
+ config.bundleUrl,
+ config.bundleDigest,
+ config.codeCachePath)
+ if (fn && typeof fn === 'function') {
+ fn(...globalValues)
+ isNativeCompileOk = true
+ }
+ }
+ catch (e) {
+ console.error(e)
+ }
+
+ return isNativeCompileOk
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/ctrl/misc.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/ctrl/misc.js b/runtime/frameworks/legacy/app/ctrl/misc.js
new file mode 100644
index 0000000..13ab09e
--- /dev/null
+++ b/runtime/frameworks/legacy/app/ctrl/misc.js
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/**
+ * @fileOverview
+ * instance controls from native
+ *
+ * - fire event
+ * - callback
+ * - refresh
+ * - destroy
+ *
+ * corresponded with the API of instance manager (framework.js)
+ */
+import { extend, typof } from '../../util/index'
+
+/**
+ * Refresh an app with data to its root component options.
+ * @param {object} app
+ * @param {any} data
+ */
+export function refresh (app, data) {
+ console.debug(`[JS Framework] Refresh with`, data,
+ `in instance[${app.id}]`)
+ const vm = app.vm
+ if (vm && data) {
+ if (typeof vm.refreshData === 'function') {
+ vm.refreshData(data)
+ }
+ else {
+ extend(vm, data)
+ }
+ app.differ.flush()
+ app.doc.taskCenter.send('dom', { action: 'refreshFinish' }, [])
+ return
+ }
+ return new Error(`invalid data "${data}"`)
+}
+
+/**
+ * Destroy an app.
+ * @param {object} app
+ */
+export function destroy (app) {
+ console.debug(`[JS Framework] Destory an instance(${app.id})`)
+
+ if (app.vm) {
+ destroyVm(app.vm)
+ }
+
+ app.id = ''
+ app.options = null
+ app.blocks = null
+ app.vm = null
+ app.doc.taskCenter.destroyCallback()
+ app.doc.destroy()
+ app.doc = null
+ app.customComponentMap = null
+ app.commonModules = null
+}
+
+/**
+ * Destroy an Vm.
+ * @param {object} vm
+ */
+export function destroyVm (vm) {
+ delete vm._app
+ delete vm._computed
+ delete vm._css
+ delete vm._data
+ delete vm._ids
+ delete vm._methods
+ delete vm._options
+ delete vm._parent
+ delete vm._parentEl
+ delete vm._rootEl
+
+ // remove all watchers
+ if (vm._watchers) {
+ let watcherCount = vm._watchers.length
+ while (watcherCount--) {
+ vm._watchers[watcherCount].teardown()
+ }
+ delete vm._watchers
+ }
+
+ // destroy child vms recursively
+ if (vm._childrenVms) {
+ let vmCount = vm._childrenVms.length
+ while (vmCount--) {
+ destroyVm(vm._childrenVms[vmCount])
+ }
+ delete vm._childrenVms
+ }
+
+ console.debug(`[JS Framework] "destroyed" lifecycle in Vm(${vm._type})`)
+ vm.$emit('hook:destroyed')
+
+ delete vm._type
+ delete vm._vmEvents
+}
+
+/**
+ * Get a JSON object to describe the document body.
+ * @param {object} app
+ * @return {object}
+ */
+export function getRootElement (app) {
+ const doc = app.doc || {}
+ const body = doc.body || {}
+ return body.toJSON ? body.toJSON() : {}
+}
+
+/**
+ * Fire an event from renderer. The event has type, an event object and an
+ * element ref. If the event comes with some virtual-DOM changes, it should
+ * have one more parameter to describe the changes.
+ * @param {object} app
+ * @param {string} ref
+ * @param {type} type
+ * @param {object} e
+ * @param {object} domChanges
+ */
+export function fireEvent (app, ref, type, e, domChanges) {
+ console.debug(`[JS Framework] Fire a "${type}" event on an element(${ref}) in instance(${app.id})`)
+ if (Array.isArray(ref)) {
+ ref.some((ref) => {
+ return fireEvent(app, ref, type, e) !== false
+ })
+ return
+ }
+ const el = app.doc.getRef(ref)
+ if (el) {
+ const result = app.doc.fireEvent(el, type, e, domChanges)
+ app.differ.flush()
+ app.doc.taskCenter.send('dom', { action: 'updateFinish' }, [])
+ return result
+ }
+ return new Error(`invalid element reference "${ref}"`)
+}
+
+/**
+ * Make a callback for a certain app.
+ * @param {object} app
+ * @param {number} callbackId
+ * @param {any} data
+ * @param {boolean} ifKeepAlive
+ */
+export function callback (app, callbackId, data, ifKeepAlive) {
+ console.debug(`[JS Framework] Invoke a callback(${callbackId}) with`, data,
+ `in instance(${app.id})`)
+ const result = app.doc.taskCenter.callback(callbackId, data, ifKeepAlive)
+ updateActions(app)
+ app.doc.taskCenter.send('dom', { action: 'updateFinish' }, [])
+ return result
+}
+
+/**
+ * Collect all virtual-DOM mutations together and send them to renderer.
+ * @param {object} app
+ */
+export function updateActions (app) {
+ app.differ.flush()
+}
+
+/**
+ * Call all tasks from an app to renderer (native).
+ * @param {object} app
+ * @param {array} tasks
+ */
+export function callTasks (app, tasks) {
+ let result
+
+ /* istanbul ignore next */
+ if (typof(tasks) !== 'array') {
+ tasks = [tasks]
+ }
+
+ tasks.forEach(task => {
+ result = app.doc.taskCenter.send(
+ 'module',
+ {
+ module: task.module,
+ method: task.method
+ },
+ task.args
+ )
+ })
+
+ return result
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/runtime/frameworks/legacy/app/differ.js
----------------------------------------------------------------------
diff --git a/runtime/frameworks/legacy/app/differ.js b/runtime/frameworks/legacy/app/differ.js
new file mode 100644
index 0000000..61e25ef
--- /dev/null
+++ b/runtime/frameworks/legacy/app/differ.js
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+export default class Differ {
+ constructor (id) {
+ this.id = id
+ this.map = []
+ this.hooks = []
+ }
+ isEmpty () {
+ return this.map.length === 0
+ }
+ append (type, depth = 0, ref, handler) {
+ if (!this.hasTimer) {
+ this.hasTimer = true
+ setTimeout(() => {
+ this.hasTimer = false
+ this.flush(true)
+ }, 0)
+ }
+ const map = this.map
+ if (!map[depth]) {
+ map[depth] = {}
+ }
+ const group = map[depth]
+ if (!group[type]) {
+ group[type] = {}
+ }
+ if (type === 'element') {
+ if (!group[type][ref]) {
+ group[type][ref] = []
+ }
+ group[type][ref].push(handler)
+ }
+ else {
+ group[type][ref] = handler
+ }
+ }
+ flush (isTimeout) {
+ const map = this.map.slice()
+ this.map.length = 0
+ map.forEach((group) => {
+ callTypeMap(group, 'repeat')
+ callTypeMap(group, 'shown')
+ callTypeList(group, 'element')
+ })
+
+ const hooks = this.hooks.slice()
+ this.hooks.length = 0
+ hooks.forEach((fn) => {
+ fn()
+ })
+
+ if (!this.isEmpty()) {
+ this.flush()
+ }
+ }
+ then (fn) {
+ this.hooks.push(fn)
+ }
+}
+
+function callTypeMap (group, type) {
+ const map = group[type]
+ for (const ref in map) {
+ map[ref]()
+ }
+}
+
+function callTypeList (group, type) {
+ const map = group[type]
+ for (const ref in map) {
+ const list = map[ref]
+ list.forEach((handler) => { handler() })
+ }
+}
[22/22] incubator-weex git commit: [jsfm] Adjust the file structure
and build scripts of js framework (#964)
Posted by ha...@apache.org.
[jsfm] Adjust the file structure and build scripts of js framework (#964)
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/c0b2cfd5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/c0b2cfd5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/c0b2cfd5
Branch: refs/heads/master
Commit: c0b2cfd502dacd2d22058925b3cdeb244b2074a9
Parents: d724832 9dd6cba
Author: Hanks <zh...@gmail.com>
Authored: Wed Jan 3 15:03:44 2018 +0800
Committer: Hanks <zh...@gmail.com>
Committed: Wed Jan 3 15:03:44 2018 +0800
----------------------------------------------------------------------
.flowconfig | 17 -
build/build.js | 118 +-
build/config.js | 143 +-
dangerfile.js | 15 +-
html5/frameworks/index.js | 29 -
html5/frameworks/legacy/api/methods.js | 194 --
html5/frameworks/legacy/api/modules.js | 96 -
html5/frameworks/legacy/app/bundle/bootstrap.js | 90 -
html5/frameworks/legacy/app/bundle/define.js | 115 -
html5/frameworks/legacy/app/bundle/index.js | 34 -
html5/frameworks/legacy/app/ctrl/index.js | 40 -
html5/frameworks/legacy/app/ctrl/init.js | 215 --
html5/frameworks/legacy/app/ctrl/misc.js | 206 --
html5/frameworks/legacy/app/differ.js | 91 -
html5/frameworks/legacy/app/downgrade.js | 172 --
html5/frameworks/legacy/app/index.js | 55 -
html5/frameworks/legacy/app/instance.js | 47 -
html5/frameworks/legacy/app/register.js | 131 --
html5/frameworks/legacy/app/viewport.js | 56 -
html5/frameworks/legacy/config.js | 35 -
html5/frameworks/legacy/core/LICENSE | 21 -
html5/frameworks/legacy/core/array.js | 100 -
html5/frameworks/legacy/core/dep.js | 80 -
html5/frameworks/legacy/core/object.js | 91 -
html5/frameworks/legacy/core/observer.js | 323 ---
html5/frameworks/legacy/core/state.js | 92 -
html5/frameworks/legacy/core/watcher.js | 254 ---
html5/frameworks/legacy/index.js | 40 -
html5/frameworks/legacy/static/bridge.js | 56 -
html5/frameworks/legacy/static/create.js | 51 -
html5/frameworks/legacy/static/life.js | 91 -
html5/frameworks/legacy/static/map.js | 19 -
html5/frameworks/legacy/static/misc.js | 40 -
html5/frameworks/legacy/static/register.js | 75 -
html5/frameworks/legacy/util/LICENSE | 21 -
html5/frameworks/legacy/util/index.js | 156 --
html5/frameworks/legacy/util/shared.js | 162 --
html5/frameworks/legacy/vm/compiler.js | 636 ------
html5/frameworks/legacy/vm/directive.js | 377 ----
html5/frameworks/legacy/vm/dom-helper.js | 258 ---
html5/frameworks/legacy/vm/events.js | 179 --
html5/frameworks/legacy/vm/index.js | 131 --
html5/frameworks/vanilla/index.js | 110 -
html5/render/native/index.js | 22 -
html5/render/native/setup.js | 58 -
html5/render/vue/README.md | 3 -
html5/runtime/api/WeexInstance.js | 138 --
html5/runtime/api/component.js | 51 -
html5/runtime/api/config.js | 37 -
html5/runtime/api/init.js | 304 ---
html5/runtime/api/module.js | 56 -
html5/runtime/api/service.js | 77 -
html5/runtime/bridge/CallbackManager.js | 89 -
html5/runtime/bridge/Handler.js | 91 -
html5/runtime/bridge/Listener.js | 220 --
html5/runtime/bridge/TaskCenter.js | 145 --
html5/runtime/bridge/debug.js | 65 -
html5/runtime/bridge/normalize.js | 91 -
html5/runtime/bridge/receiver.js | 71 -
html5/runtime/index.js | 55 -
html5/runtime/utils.js | 71 -
html5/runtime/vdom/Comment.js | 43 -
html5/runtime/vdom/Document.js | 189 --
html5/runtime/vdom/Element.js | 524 -----
html5/runtime/vdom/Node.js | 47 -
html5/runtime/vdom/WeexElement.js | 84 -
html5/runtime/vdom/index.js | 37 -
html5/runtime/vdom/operation.js | 272 ---
html5/services/amd/index.js | 105 -
html5/services/broadcast-channel/index.js | 125 --
.../services/broadcast-channel/message-event.js | 40 -
html5/services/index.js | 23 -
html5/shared/arrayFrom.js | 105 -
html5/shared/console.js | 137 --
html5/shared/freeze.js | 90 -
html5/shared/index.js | 32 -
html5/shared/objectAssign.js | 19 -
html5/shared/objectSetPrototypeOf.js | 74 -
html5/shared/promise.js | 28 -
html5/shared/setTimeout.js | 63 -
html5/test/case/.eslintrc | 9 -
html5/test/case/basic/append-root.output.js | 36 -
html5/test/case/basic/append-root.source.js | 75 -
html5/test/case/basic/append.output.js | 79 -
html5/test/case/basic/append.source.js | 123 --
html5/test/case/basic/backward1.output.js | 57 -
html5/test/case/basic/backward1.source.js | 113 -
html5/test/case/basic/backward2.output.js | 57 -
html5/test/case/basic/backward2.source.js | 113 -
html5/test/case/basic/components.output.js | 20 -
html5/test/case/basic/components.source.js | 101 -
.../case/basic/computed-in-repeat.output.js | 19 -
.../case/basic/computed-in-repeat.source.js | 82 -
html5/test/case/basic/created.output.js | 11 -
html5/test/case/basic/created.source.js | 56 -
html5/test/case/basic/dynamic-id.output.js | 44 -
html5/test/case/basic/dynamic-id.source.js | 94 -
.../test/case/basic/dynamic-property.output.js | 24 -
.../test/case/basic/dynamic-property.source.js | 79 -
html5/test/case/basic/dynamic-type.output.js | 10 -
html5/test/case/basic/dynamic-type.source.js | 45 -
html5/test/case/basic/foo.output.js | 3 -
html5/test/case/basic/foo.source.js | 44 -
html5/test/case/basic/foo2.output.js | 10 -
html5/test/case/basic/foo2.source.js | 52 -
html5/test/case/basic/foo3.output.js | 9 -
html5/test/case/basic/foo3.source.js | 41 -
html5/test/case/basic/foo4.output.js | 12 -
html5/test/case/basic/foo4.source.js | 44 -
html5/test/case/basic/foo5.output.js | 14 -
html5/test/case/basic/foo5.source.js | 50 -
html5/test/case/basic/foo6.output.js | 28 -
html5/test/case/basic/foo6.source.js | 71 -
html5/test/case/basic/foo7.output.js | 26 -
html5/test/case/basic/foo7.source.js | 76 -
html5/test/case/basic/foo8.output.js | 60 -
html5/test/case/basic/foo8.source.js | 91 -
html5/test/case/basic/foo9.output.js | 57 -
html5/test/case/basic/foo9.source.js | 113 -
.../case/basic/global-weex-object.output.js | 6 -
.../case/basic/global-weex-object.source.js | 37 -
html5/test/case/basic/id.output.js | 32 -
html5/test/case/basic/id.source.js | 80 -
html5/test/case/basic/if-repeat.output.js | 13 -
html5/test/case/basic/if-repeat.source.js | 60 -
html5/test/case/basic/if-root.output.js | 1 -
html5/test/case/basic/if-root.source.js | 44 -
html5/test/case/basic/if.output.js | 13 -
html5/test/case/basic/if.source.js | 57 -
html5/test/case/basic/promise.output.js | 3 -
html5/test/case/basic/promise.source.js | 47 -
html5/test/case/basic/ready.output.js | 11 -
html5/test/case/basic/ready.source.js | 56 -
html5/test/case/basic/repeat-array-kv.output.js | 22 -
html5/test/case/basic/repeat-array-kv.source.js | 63 -
.../case/basic/repeat-array-no-kv.output.js | 22 -
.../case/basic/repeat-array-no-kv.source.js | 61 -
.../case/basic/repeat-array-non-obj.output.js | 22 -
.../case/basic/repeat-array-non-obj.source.js | 62 -
html5/test/case/basic/repeat-array-v.output.js | 22 -
html5/test/case/basic/repeat-array-v.source.js | 62 -
html5/test/case/basic/repeat-index.output.js | 22 -
html5/test/case/basic/repeat-index.source.js | 59 -
html5/test/case/basic/repeat-root.output.js | 1 -
html5/test/case/basic/repeat-root.source.js | 47 -
html5/test/case/basic/repeat-watch.output.js | 46 -
html5/test/case/basic/repeat-watch.source.js | 75 -
html5/test/case/basic/require.output.js | 9 -
html5/test/case/basic/require.source.js | 52 -
html5/test/case/basic/reset-style.output.js | 15 -
html5/test/case/basic/reset-style.source.js | 58 -
html5/test/case/basic/static1.output.js | 12 -
html5/test/case/basic/static1.source.js | 51 -
html5/test/case/basic/static2.output.js | 30 -
html5/test/case/basic/static2.source.js | 62 -
html5/test/case/basic/static3.output.js | 33 -
html5/test/case/basic/static3.source.js | 62 -
html5/test/case/basic/static4.output.js | 35 -
html5/test/case/basic/static4.source.js | 93 -
html5/test/case/basic/subvm.output.js | 20 -
html5/test/case/basic/subvm.source.js | 98 -
html5/test/case/basic/transformer1.output.js | 3 -
html5/test/case/basic/transformer1.source.js | 46 -
.../case/complex/append-root-event.output.js | 13 -
.../case/complex/append-root-event.source.js | 63 -
html5/test/case/complex/click.output.js | 26 -
html5/test/case/complex/click.source.js | 76 -
.../complex/component-append-tree.output.js | 22 -
.../complex/component-append-tree.source.js | 87 -
html5/test/case/complex/computed.output.js | 15 -
html5/test/case/complex/computed.source.js | 72 -
html5/test/case/complex/if-refresh.output.js | 3 -
html5/test/case/complex/if-refresh.source.js | 57 -
.../case/complex/if-repeat-refresh.output.js | 22 -
.../case/complex/if-repeat-refresh.source.js | 60 -
html5/test/case/complex/inline-click.output.js | 14 -
html5/test/case/complex/inline-click.source.js | 54 -
html5/test/case/complex/input-binding.output.js | 12 -
html5/test/case/complex/input-binding.source.js | 78 -
html5/test/case/complex/refresh2.output.js | 20 -
html5/test/case/complex/refresh2.source.js | 133 --
.../test/case/complex/repeat-track-by.output.js | 24 -
.../test/case/complex/repeat-track-by.source.js | 64 -
html5/test/case/complex/transformer2.output.js | 3 -
html5/test/case/complex/transformer2.source.js | 46 -
html5/test/case/complex/transformer3.output.js | 3 -
html5/test/case/complex/transformer3.source.js | 46 -
.../case/multi/clear-dep-target-error.source.js | 45 -
.../case/multi/clear-dep-target-fine.output.js | 11 -
.../case/multi/clear-dep-target-fine.source.js | 48 -
html5/test/case/multi/clear-moduleA.output.js | 12 -
html5/test/case/multi/clear-moduleA.source.js | 61 -
html5/test/case/multi/clear-moduleB.output.js | 11 -
html5/test/case/multi/clear-moduleB.source.js | 50 -
html5/test/case/prepare.js | 83 -
html5/test/case/signals/modal.output.js | 9 -
html5/test/case/signals/modal.source.js | 60 -
html5/test/case/signals/signals-long.source.js | 1223 -----------
html5/test/case/signals/signals.source.js | 84 -
html5/test/case/signals/timer.output.js | 9 -
html5/test/case/signals/timer.source.js | 54 -
html5/test/case/tester.js | 528 -----
.../test/case/throws/global-variable1.source.js | 35 -
.../test/case/throws/global-variable2.source.js | 33 -
.../test/case/throws/global-variable3.source.js | 40 -
html5/test/unit/default/api/methods.js | 190 --
html5/test/unit/default/api/modules.js | 43 -
html5/test/unit/default/app/bundle.js | 409 ----
html5/test/unit/default/app/ctrl.js | 230 --
html5/test/unit/default/app/downgrade.js | 265 ---
html5/test/unit/default/app/index.js | 147 --
html5/test/unit/default/app/register.js | 200 --
html5/test/unit/default/app/viewport.js | 79 -
html5/test/unit/default/util/index.js | 185 --
html5/test/unit/default/util/shared.js | 143 --
html5/test/unit/default/vm/directive.js | 228 --
html5/test/unit/default/vm/dom-helper.js | 405 ----
html5/test/unit/default/vm/events.js | 416 ----
html5/test/unit/default/vm/vm.js | 1975 ------------------
html5/test/unit/runtime/legacy-framework.js | 348 ---
html5/test/unit/runtime/runner/helper.js | 73 -
html5/test/unit/runtime/runner/vanilla.js | 59 -
html5/test/unit/runtime/runner/vue.js | 67 -
html5/test/unit/runtime/utils.js | 41 -
html5/test/unit/runtime/vdom/index.js | 639 ------
html5/test/unit/runtime/vdom/listener.js | 381 ----
html5/test/unit/runtime/vdom/node.js | 39 -
html5/test/unit/shared/BroadcastChannel.js | 231 --
html5/test/unit/shared/arrayFrom.js | 90 -
html5/test/unit/shared/console.js | 224 --
html5/test/unit/shared/index.js | 73 -
html5/test/unit/shared/objectAssign.js | 50 -
html5/test/unit/shared/objectSetPrototypeOf.js | 42 -
html5/test/unit/vanilla/index.js | 159 --
package.json | 31 +-
runtime/api/WeexInstance.js | 138 ++
runtime/api/component.js | 51 +
runtime/api/config.js | 37 +
runtime/api/index.js | 40 +
runtime/api/init.js | 304 +++
runtime/api/module.js | 56 +
runtime/api/service.js | 77 +
runtime/bridge/CallbackManager.js | 89 +
runtime/bridge/Handler.js | 91 +
runtime/bridge/Listener.js | 220 ++
runtime/bridge/TaskCenter.js | 145 ++
runtime/bridge/debug.js | 65 +
runtime/bridge/normalize.js | 91 +
runtime/bridge/receiver.js | 71 +
runtime/entries/index.js | 23 +
runtime/entries/rax.js | 23 +
runtime/entries/setup.js | 60 +
runtime/entries/vue.js | 23 +
runtime/frameworks/index.js | 29 +
runtime/frameworks/legacy/api/methods.js | 194 ++
runtime/frameworks/legacy/api/modules.js | 96 +
.../frameworks/legacy/app/bundle/bootstrap.js | 90 +
runtime/frameworks/legacy/app/bundle/define.js | 115 +
runtime/frameworks/legacy/app/bundle/index.js | 34 +
runtime/frameworks/legacy/app/ctrl/index.js | 40 +
runtime/frameworks/legacy/app/ctrl/init.js | 215 ++
runtime/frameworks/legacy/app/ctrl/misc.js | 206 ++
runtime/frameworks/legacy/app/differ.js | 91 +
runtime/frameworks/legacy/app/downgrade.js | 172 ++
runtime/frameworks/legacy/app/index.js | 55 +
runtime/frameworks/legacy/app/instance.js | 47 +
runtime/frameworks/legacy/app/register.js | 131 ++
runtime/frameworks/legacy/app/viewport.js | 56 +
runtime/frameworks/legacy/config.js | 35 +
runtime/frameworks/legacy/core/LICENSE | 21 +
runtime/frameworks/legacy/core/array.js | 100 +
runtime/frameworks/legacy/core/dep.js | 80 +
runtime/frameworks/legacy/core/object.js | 91 +
runtime/frameworks/legacy/core/observer.js | 323 +++
runtime/frameworks/legacy/core/state.js | 92 +
runtime/frameworks/legacy/core/watcher.js | 254 +++
runtime/frameworks/legacy/index.js | 40 +
runtime/frameworks/legacy/static/bridge.js | 56 +
runtime/frameworks/legacy/static/create.js | 51 +
runtime/frameworks/legacy/static/life.js | 91 +
runtime/frameworks/legacy/static/map.js | 19 +
runtime/frameworks/legacy/static/misc.js | 40 +
runtime/frameworks/legacy/static/register.js | 75 +
runtime/frameworks/legacy/util/LICENSE | 21 +
runtime/frameworks/legacy/util/index.js | 156 ++
runtime/frameworks/legacy/util/shared.js | 162 ++
runtime/frameworks/legacy/vm/compiler.js | 636 ++++++
runtime/frameworks/legacy/vm/directive.js | 377 ++++
runtime/frameworks/legacy/vm/dom-helper.js | 258 +++
runtime/frameworks/legacy/vm/events.js | 179 ++
runtime/frameworks/legacy/vm/index.js | 131 ++
runtime/frameworks/vanilla/index.js | 110 +
runtime/services/amd/index.js | 105 +
runtime/services/broadcast-channel/index.js | 125 ++
.../services/broadcast-channel/message-event.js | 40 +
runtime/services/index.js | 23 +
runtime/shared/env/console.js | 137 ++
runtime/shared/env/freeze.js | 90 +
runtime/shared/env/setTimeout.js | 63 +
runtime/shared/index.js | 33 +
runtime/shared/polyfill/arrayFrom.js | 105 +
runtime/shared/polyfill/objectAssign.js | 19 +
runtime/shared/polyfill/objectSetPrototypeOf.js | 74 +
runtime/shared/polyfill/promise.js | 28 +
runtime/shared/utils.js | 71 +
runtime/vdom/Comment.js | 43 +
runtime/vdom/Document.js | 189 ++
runtime/vdom/Element.js | 524 +++++
runtime/vdom/Node.js | 47 +
runtime/vdom/WeexElement.js | 84 +
runtime/vdom/index.js | 37 +
runtime/vdom/operation.js | 272 +++
test/js-framework/case/.eslintrc | 9 +
.../case/basic/append-root.output.js | 36 +
.../case/basic/append-root.source.js | 75 +
test/js-framework/case/basic/append.output.js | 79 +
test/js-framework/case/basic/append.source.js | 123 ++
.../js-framework/case/basic/backward1.output.js | 57 +
.../js-framework/case/basic/backward1.source.js | 113 +
.../js-framework/case/basic/backward2.output.js | 57 +
.../js-framework/case/basic/backward2.source.js | 113 +
.../case/basic/components.output.js | 20 +
.../case/basic/components.source.js | 101 +
.../case/basic/computed-in-repeat.output.js | 19 +
.../case/basic/computed-in-repeat.source.js | 82 +
test/js-framework/case/basic/created.output.js | 11 +
test/js-framework/case/basic/created.source.js | 56 +
.../case/basic/dynamic-id.output.js | 44 +
.../case/basic/dynamic-id.source.js | 94 +
.../case/basic/dynamic-property.output.js | 24 +
.../case/basic/dynamic-property.source.js | 79 +
.../case/basic/dynamic-type.output.js | 10 +
.../case/basic/dynamic-type.source.js | 45 +
test/js-framework/case/basic/foo.output.js | 3 +
test/js-framework/case/basic/foo.source.js | 44 +
test/js-framework/case/basic/foo2.output.js | 10 +
test/js-framework/case/basic/foo2.source.js | 52 +
test/js-framework/case/basic/foo3.output.js | 9 +
test/js-framework/case/basic/foo3.source.js | 41 +
test/js-framework/case/basic/foo4.output.js | 12 +
test/js-framework/case/basic/foo4.source.js | 44 +
test/js-framework/case/basic/foo5.output.js | 14 +
test/js-framework/case/basic/foo5.source.js | 50 +
test/js-framework/case/basic/foo6.output.js | 28 +
test/js-framework/case/basic/foo6.source.js | 71 +
test/js-framework/case/basic/foo7.output.js | 26 +
test/js-framework/case/basic/foo7.source.js | 76 +
test/js-framework/case/basic/foo8.output.js | 60 +
test/js-framework/case/basic/foo8.source.js | 91 +
test/js-framework/case/basic/foo9.output.js | 57 +
test/js-framework/case/basic/foo9.source.js | 113 +
.../case/basic/global-weex-object.output.js | 6 +
.../case/basic/global-weex-object.source.js | 37 +
test/js-framework/case/basic/id.output.js | 32 +
test/js-framework/case/basic/id.source.js | 80 +
.../js-framework/case/basic/if-repeat.output.js | 13 +
.../js-framework/case/basic/if-repeat.source.js | 60 +
test/js-framework/case/basic/if-root.output.js | 1 +
test/js-framework/case/basic/if-root.source.js | 44 +
test/js-framework/case/basic/if.output.js | 13 +
test/js-framework/case/basic/if.source.js | 57 +
test/js-framework/case/basic/promise.output.js | 3 +
test/js-framework/case/basic/promise.source.js | 47 +
test/js-framework/case/basic/ready.output.js | 11 +
test/js-framework/case/basic/ready.source.js | 56 +
.../case/basic/repeat-array-kv.output.js | 22 +
.../case/basic/repeat-array-kv.source.js | 63 +
.../case/basic/repeat-array-no-kv.output.js | 22 +
.../case/basic/repeat-array-no-kv.source.js | 61 +
.../case/basic/repeat-array-non-obj.output.js | 22 +
.../case/basic/repeat-array-non-obj.source.js | 62 +
.../case/basic/repeat-array-v.output.js | 22 +
.../case/basic/repeat-array-v.source.js | 62 +
.../case/basic/repeat-index.output.js | 22 +
.../case/basic/repeat-index.source.js | 59 +
.../case/basic/repeat-root.output.js | 1 +
.../case/basic/repeat-root.source.js | 47 +
.../case/basic/repeat-watch.output.js | 46 +
.../case/basic/repeat-watch.source.js | 75 +
test/js-framework/case/basic/require.output.js | 9 +
test/js-framework/case/basic/require.source.js | 52 +
.../case/basic/reset-style.output.js | 15 +
.../case/basic/reset-style.source.js | 58 +
test/js-framework/case/basic/static1.output.js | 12 +
test/js-framework/case/basic/static1.source.js | 51 +
test/js-framework/case/basic/static2.output.js | 30 +
test/js-framework/case/basic/static2.source.js | 62 +
test/js-framework/case/basic/static3.output.js | 33 +
test/js-framework/case/basic/static3.source.js | 62 +
test/js-framework/case/basic/static4.output.js | 35 +
test/js-framework/case/basic/static4.source.js | 93 +
test/js-framework/case/basic/subvm.output.js | 20 +
test/js-framework/case/basic/subvm.source.js | 98 +
.../case/basic/transformer1.output.js | 3 +
.../case/basic/transformer1.source.js | 46 +
.../case/complex/append-root-event.output.js | 13 +
.../case/complex/append-root-event.source.js | 63 +
test/js-framework/case/complex/click.output.js | 26 +
test/js-framework/case/complex/click.source.js | 76 +
.../complex/component-append-tree.output.js | 22 +
.../complex/component-append-tree.source.js | 87 +
.../case/complex/computed.output.js | 15 +
.../case/complex/computed.source.js | 72 +
.../case/complex/if-refresh.output.js | 3 +
.../case/complex/if-refresh.source.js | 57 +
.../case/complex/if-repeat-refresh.output.js | 22 +
.../case/complex/if-repeat-refresh.source.js | 60 +
.../case/complex/inline-click.output.js | 14 +
.../case/complex/inline-click.source.js | 54 +
.../case/complex/input-binding.output.js | 12 +
.../case/complex/input-binding.source.js | 78 +
.../case/complex/refresh2.output.js | 20 +
.../case/complex/refresh2.source.js | 133 ++
.../case/complex/repeat-track-by.output.js | 24 +
.../case/complex/repeat-track-by.source.js | 64 +
.../case/complex/transformer2.output.js | 3 +
.../case/complex/transformer2.source.js | 46 +
.../case/complex/transformer3.output.js | 3 +
.../case/complex/transformer3.source.js | 46 +
.../case/multi/clear-dep-target-error.source.js | 45 +
.../case/multi/clear-dep-target-fine.output.js | 11 +
.../case/multi/clear-dep-target-fine.source.js | 48 +
.../case/multi/clear-moduleA.output.js | 12 +
.../case/multi/clear-moduleA.source.js | 61 +
.../case/multi/clear-moduleB.output.js | 11 +
.../case/multi/clear-moduleB.source.js | 50 +
test/js-framework/case/prepare.js | 83 +
test/js-framework/case/signals/modal.output.js | 9 +
test/js-framework/case/signals/modal.source.js | 60 +
.../case/signals/signals-long.source.js | 1223 +++++++++++
.../js-framework/case/signals/signals.source.js | 84 +
test/js-framework/case/signals/timer.output.js | 9 +
test/js-framework/case/signals/timer.source.js | 54 +
test/js-framework/case/tester.js | 528 +++++
.../case/throws/global-variable1.source.js | 35 +
.../case/throws/global-variable2.source.js | 33 +
.../case/throws/global-variable3.source.js | 40 +
test/js-framework/unit/default/api/methods.js | 190 ++
test/js-framework/unit/default/api/modules.js | 43 +
test/js-framework/unit/default/app/bundle.js | 409 ++++
test/js-framework/unit/default/app/ctrl.js | 230 ++
test/js-framework/unit/default/app/downgrade.js | 265 +++
test/js-framework/unit/default/app/index.js | 147 ++
test/js-framework/unit/default/app/register.js | 200 ++
test/js-framework/unit/default/app/viewport.js | 79 +
test/js-framework/unit/default/util/index.js | 185 ++
test/js-framework/unit/default/util/shared.js | 143 ++
test/js-framework/unit/default/vm/directive.js | 228 ++
test/js-framework/unit/default/vm/dom-helper.js | 405 ++++
test/js-framework/unit/default/vm/events.js | 416 ++++
test/js-framework/unit/default/vm/vm.js | 1975 ++++++++++++++++++
.../unit/runtime/legacy-framework.js | 348 +++
test/js-framework/unit/runtime/runner/helper.js | 73 +
.../js-framework/unit/runtime/runner/vanilla.js | 59 +
test/js-framework/unit/runtime/runner/vue.js | 67 +
test/js-framework/unit/runtime/utils.js | 41 +
test/js-framework/unit/runtime/vdom/index.js | 639 ++++++
test/js-framework/unit/runtime/vdom/listener.js | 381 ++++
test/js-framework/unit/runtime/vdom/node.js | 39 +
.../unit/shared/BroadcastChannel.js | 231 ++
test/js-framework/unit/shared/arrayFrom.js | 90 +
test/js-framework/unit/shared/console.js | 227 ++
test/js-framework/unit/shared/index.js | 73 +
test/js-framework/unit/shared/objectAssign.js | 50 +
.../unit/shared/objectSetPrototypeOf.js | 42 +
test/js-framework/unit/vanilla/index.js | 159 ++
466 files changed, 23441 insertions(+), 23444 deletions(-)
----------------------------------------------------------------------
[12/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/vm/directive.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/vm/directive.js b/html5/test/unit/default/vm/directive.js
deleted file mode 100644
index fa21969..0000000
--- a/html5/test/unit/default/vm/directive.js
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import {
- applyNaitveComponentOptions,
- bindSubVm,
- bindSubVmAfterInitialized
-} from '../../../../frameworks/legacy/vm/directive'
-
-import {
- initState
-} from '../../../../frameworks/legacy/core/state'
-import config from '../../../../frameworks/legacy/config'
-
-const { nativeComponentMap } = config
-const directive = {}
-
-function extendVm (vm, methodNames) {
- methodNames.forEach((name) => {
- vm[name] = directive[name]
- })
- initState(vm)
-}
-
-function initElement (el) {
- el.setAttr = function (k, v) { this.attr[k] = v }
- el.setStyle = function (k, v) { this.style[k] = v }
- el.setClassStyle = function (style) { this.classStyle = style }
- el.addEvent = function (t, h) {
- this.event[t] = h
- }
-}
-
-describe('apply component options', () => {
- it('apply top prop', () => {
- nativeComponentMap['test-apply'] = {
- type: 'test-apply1',
- append: 'tree'
- }
- const template = {
- type: 'test-apply'
- }
- applyNaitveComponentOptions(template)
- expect(template.type).to.be.equal('test-apply')
- expect(template.append).to.be.equal('tree')
-
- delete nativeComponentMap['test-apply']
- })
-
- it('apply a object', () => {
- nativeComponentMap['test-apply'] = {
- classList: ['c'],
- attr: {
- a: 'a',
- b: 'b'
- }
- }
- const spy = sinon.spy()
- const template = {
- type: 'test-apply',
- classList: spy,
- attr: {
- b: '2'
- }
- }
- applyNaitveComponentOptions(template)
-
- expect(template).to.deep.equal({
- type: 'test-apply',
- classList: spy,
- attr: {
- a: 'a',
- b: '2'
- }
- })
-
- delete nativeComponentMap['test-apply']
- })
-})
-
-// exports._bindSubVm(subVm, template)
-describe('bind external infomations to sub vm', () => {
- let vm, subVm
- // const methodNames = [
- // '_watch', '_bindKey', '_bindDir',
- // '_setId', '_setAttr', '_setClass', '_setStyle',
- // '_setEvent', '_bindEvents', '_bindElement',
- // '_bindSubVm', '_bindSubVmAfterInitialized']
- beforeEach(() => {
- vm = {
- _data: { a: 1, b: 2, c: 'class-style1' },
- _watchers: [],
- _app: { eventManager: { add: () => {} }},
- _options: {
- style: {
- 'class-style1': {
- aaa: 1,
- bbb: 2
- },
- 'class-style2': {
- aaa: 2,
- ccc: 3
- }
- }
- },
- foo: function () {}
- }
- extendVm(vm, [])
- subVm = {
- _options: {
- props: {
- a: String,
- b: String
- }
- }
- }
- })
-
- it('bind to no-root-element sub vm', () => {
- bindSubVm(vm, subVm, {
- attr: { a: 3, c: 4 },
- style: { a: 2 },
- events: { click: 'foo' }
- })
- expect(subVm.a).eql(3)
- expect(subVm.c).is.undefined
- expect(subVm._rootEl).is.undefined
- })
-
- it('bind props with external data', () => {
- bindSubVm(vm, subVm, {
- attr: { a: function () { return this.b } }
- })
- expect(subVm.a).eql(2)
- })
-
- it('bind styles to a sub vm with root element', () => {
- subVm._rootEl = {
- attr: {},
- style: {},
- event: []
- }
- const template = {
- style: { aaa: 2, bbb: function () { return this.a } }
- }
- initElement(subVm._rootEl)
- bindSubVm(vm, subVm, template)
- bindSubVmAfterInitialized(vm, subVm, template)
- expect(subVm._rootEl.style.aaa).eql(2)
- expect(subVm._rootEl.style.bbb).eql(1)
- vm.a = 3
- expect(subVm._rootEl.style.bbb).eql(3)
- })
-
- it('bind simply classlist to a sub vm with root element', () => {
- subVm._rootEl = {
- attr: {},
- style: {},
- event: []
- }
- const template = {
- classList: ['class-style1']
- }
- initElement(subVm._rootEl)
- bindSubVm(vm, subVm, template)
- bindSubVmAfterInitialized(vm, subVm, template)
- expect(subVm._rootEl.classStyle.aaa).eql(1)
- expect(subVm._rootEl.classStyle.bbb).eql(2)
- })
-
- it('bind classlist to a sub vm with root element', () => {
- subVm._rootEl = {
- attr: {},
- style: {},
- event: []
- }
- const template = {
- classList: function () {
- return [this.c]
- }
- }
- initElement(subVm._rootEl)
- bindSubVm(vm, subVm, template)
- bindSubVmAfterInitialized(vm, subVm, template)
- expect(subVm._rootEl.classStyle.aaa).eql(1)
- expect(subVm._rootEl.classStyle.bbb).eql(2)
- vm.c = 'class-style2'
- expect(subVm._rootEl.classStyle.aaa).eql(2)
- expect(subVm._rootEl.classStyle.bbb).to.be.undefined
- expect(subVm._rootEl.classStyle.ccc).eql(3)
- })
-
- it('bind events to a sub vm with root element', () => {
- subVm._rootEl = {
- attr: {},
- style: {},
- event: {}
- }
- const template = {
- events: { click: 'foo' }
- }
- initElement(subVm._rootEl)
- bindSubVm(vm, subVm, template)
- bindSubVmAfterInitialized(vm, subVm, template)
- // expect(subVm._rootEl.event.click).a('function')
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/vm/dom-helper.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/vm/dom-helper.js b/html5/test/unit/default/vm/dom-helper.js
deleted file mode 100644
index 48c0a87..0000000
--- a/html5/test/unit/default/vm/dom-helper.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import {
- createElement,
- createBlock,
- createBody,
- attachTarget,
- moveTarget,
- removeTarget
-} from '../../../../frameworks/legacy/vm/dom-helper'
-import { Document } from '../../../../runtime/vdom'
-import Listener from '../../../../runtime/bridge/Listener'
-
-describe('help create body', () => {
- let vm
-
- beforeEach(() => {
- vm = {
- _app: { doc: new Document('foo', null, null, Listener) }
- }
- })
-
- afterEach(() => {
- vm._app.doc.destroy()
- vm = null
- })
-
- it('create body with type', () => {
- const result = createBody(vm, 'bar')
- expect(result).is.an.object
- expect(result.type).eql('bar')
- expect(result.ref).eql('_root')
- expect(result.docId).is.not.ok
- })
-})
-
-describe('help create element', () => {
- let vm
-
- beforeEach(() => {
- vm = {
- _app: { doc: new Document('foo', null, null, Listener) }
- }
- })
-
- afterEach(() => {
- vm._app.doc.destroy()
- vm = null
- })
-
- it('create element with type', () => {
- const result = createElement(vm, 'bar')
- expect(result).is.an.object
- expect(result.type).eql('bar')
- expect(result.docId).is.not.ok
- })
-})
-
-describe('help create block', () => {
- let vm
-
- beforeEach(() => {
- vm = {
- _app: { doc: new Document('foo', null, null, Listener) }
- }
- })
-
- afterEach(() => {
- vm._app.doc.destroy()
- vm = null
- })
-
- it('create block with element', () => {
- const element = vm._app.doc.createElement('bar')
- const result = createBlock(vm, element)
- expect(result).is.an.object
- expect(result.start).is.an.object
- expect(result.end).is.an.object
- expect(result.start.type).eql('comment')
- expect(result.end.type).eql('comment')
- expect(result.start.value).eql('start')
- expect(result.end.value).eql('end')
- expect(result.element).equal(element)
- expect(result.element.children).eql([result.start, result.end])
- })
-})
-
-describe('help attach target', () => {
- let vm
-
- beforeEach(() => {
- vm = {
- _app: { doc: new Document('foo', null, null, Listener) }
- }
- })
-
- afterEach(() => {
- vm._app.doc.destroy()
- vm = null
- })
-
- it('attach body to documentElement', () => {
- const oriCallnative = global.callNative
- global.callNative = function () {}
- const target = createBody(vm, 'bar')
- const dest = vm._app.doc.documentElement
- attachTarget(vm, target, dest)
- expect(dest.children).eql([target])
- global.callNative = oriCallnative
- })
-
- it('attach element to body', () => {
- const target = createElement(vm, 'bar')
- const dest = createBody(vm, 'baz')
- attachTarget(vm, target, dest)
- expect(dest.children).eql([target])
- })
-
- it('attach element to element', () => {
- const target = createElement(vm, 'bar')
- const dest = createElement(vm, 'baz')
- attachTarget(vm, target, dest)
- expect(dest.children).eql([target])
- })
-
- it('attach block to element', () => {
- const parent = createElement(vm, 'bar')
- const target = createBlock(vm, parent)
- const dest = createElement(vm, 'baz')
- attachTarget(vm, target, dest)
- // block can't attach to another element
- expect(dest.children).eql([])
- expect(parent.children).eql([target.start, target.end])
- })
-
- it('attach element to block', () => {
- const target = createElement(vm, 'bar')
- const parent = createElement(vm, 'baz')
- const dest = createBlock(vm, parent)
- attachTarget(vm, target, dest)
- expect(parent.children).eql([dest.start, target, dest.end])
- })
-
- it('attach block to block', () => {
- const element = createElement(vm, 'bar')
- const target = createBlock(vm, element)
- const parent = createElement(vm, 'baz')
- const dest = createBlock(vm, parent)
- attachTarget(vm, target, dest)
- // block can't attach to another element
- expect(parent.children).eql([dest.start, dest.end])
- expect(element.children).eql([target.start, target.end])
- })
-
- it('attach element to block with an update mark', () => {
- const target = createElement(vm, 'bar')
- const parent = createElement(vm, 'baz')
- const dest = createBlock(vm, parent)
- const mark = createElement(vm, 'qux')
-
- attachTarget(vm, target, dest)
- attachTarget(vm, mark, dest)
- expect(parent.children).eql([dest.start, target, mark, dest.end])
-
- dest.updateMark = mark
- attachTarget(vm, target, dest)
- expect(parent.children).eql([dest.start, mark, target, dest.end])
- expect(dest.updateMark).eql(target)
- })
-
- it('attach block to block with an update mark', () => {
- const element = createElement(vm, 'bar')
- const target = createBlock(vm, element)
- const parent = createElement(vm, 'baz')
- const dest = createBlock(vm, parent)
- const mark = createElement(vm, 'qux')
-
- attachTarget(vm, target, dest)
- attachTarget(vm, mark, dest)
- // block can't attach to another element
- expect(parent.children).eql([dest.start, mark, dest.end])
- expect(element.children).eql([target.start, target.end])
-
- dest.updateMark = mark
- attachTarget(vm, target, dest)
- // block can't attach to another element
- expect(parent.children).eql([dest.start, mark, dest.end])
- expect(element.children).eql([target.start, target.end])
- })
-})
-
-describe('help move target', () => {
- let vm, parent, dest, target1, block1, target2, block2, target3, block3
-
- beforeEach(() => {
- vm = {
- _app: { doc: new Document('foo', null, null, Listener) }
- }
- parent = createElement(vm, 'r')
- dest = createBlock(vm, parent)
- target1 = createElement(vm, 't1')
- attachTarget(vm, target1, dest)
- block1 = createBlock(vm, dest)
- target2 = createElement(vm, 't2')
- attachTarget(vm, target2, dest)
- block2 = createBlock(vm, dest)
- target3 = createElement(vm, 't3')
- attachTarget(vm, target3, block2)
- block3 = createBlock(vm, block2)
- })
-
- afterEach(() => {
- vm._app.doc.destroy()
- vm = null
- })
-
- it('move an element to an element mark', () => {
- /* eslint-disable indent */
- expect(parent.children).eql([
- dest.start,
- target1, block1.start, block1.end,
- target2, block2.start,
- target3, block3.start, block3.end,
- block2.end,
- dest.end])
- /* eslint-enable indent */
-
- const mark = target2
- dest.updateMark = mark
-
- moveTarget(vm, target1, mark)
-
- /* eslint-disable indent */
- expect(parent.children).eql([
- dest.start,
- block1.start, block1.end,
- target2, target1, block2.start,
- target3, block3.start, block3.end,
- block2.end,
- dest.end])
- /* eslint-enable indent */
- })
-
- it('move an element to a block mark', () => {
- const mark = block2.end
- dest.updateMark = mark
-
- moveTarget(vm, target1, mark)
-
- /* eslint-disable indent */
- expect(parent.children).eql([
- dest.start,
- block1.start, block1.end,
- target2, block2.start,
- target3, block3.start, block3.end,
- block2.end, target1,
- dest.end])
- /* eslint-enable indent */
- })
-
- it('move a block to an element mark', () => {
- const mark = target2
- dest.updateMark = mark
-
- moveTarget(vm, block1, mark)
-
- /* eslint-disable indent */
- expect(parent.children).eql([
- dest.start,
- target1,
- target2, block1.start, block1.end,
- block2.start,
- target3, block3.start, block3.end,
- block2.end,
- dest.end])
- /* eslint-enable indent */
- })
-
- it('move a block to a block mark', () => {
- const mark = block2.end
- dest.updateMark = mark
-
- moveTarget(vm, block1, mark)
-
- /* eslint-disable indent */
- expect(parent.children).eql([
- dest.start,
- target1,
- target2,
- block2.start,
- target3, block3.start, block3.end,
- block2.end, block1.start, block1.end,
- dest.end])
- /* eslint-enable indent */
- })
-
- it('move a whole block to a block mark', () => {
- const mark = block1.end
- dest.updateMark = mark
-
- moveTarget(vm, block2, mark)
-
- /* eslint-disable indent */
- expect(parent.children).eql([
- dest.start,
- target1, block1.start, block1.end,
- block2.start,
- target3, block3.start, block3.end,
- block2.end,
- target2,
- dest.end])
- /* eslint-enable indent */
- })
-})
-
-describe('help remove target', () => {
- let vm
-
- beforeEach(() => {
- vm = {
- _app: { doc: new Document('foo', null, null, Listener) }
- }
- })
-
- afterEach(() => {
- vm._app.doc.destroy()
- vm = null
- })
-
- it('remove body', () => {
- const oriCallnative = global.callNative
- global.callNative = function () {}
- const parent = vm._app.doc.documentElement
- const element = createBody(vm, 'baz')
- parent.appendChild(element)
- expect(parent.children).eql([element])
- removeTarget(vm, element)
- expect(parent.children).eql([])
- global.callNative = oriCallnative
- })
-
- it('remove element', () => {
- const parent = createElement(vm, 'bar')
- const element = createElement(vm, 'baz')
- parent.appendChild(element)
- expect(parent.children).eql([element])
- removeTarget(vm, element)
- expect(parent.children).eql([])
- })
-
- it('remove block', () => {
- const element = createElement(vm, 'baz')
- const prevElement = createElement(vm, 'prev')
- const nextElement = createElement(vm, 'next')
- const parent = createElement(vm, 'bar')
- attachTarget(vm, prevElement, parent)
- const block = createBlock(vm, parent)
- attachTarget(vm, element, block)
- attachTarget(vm, nextElement, parent)
-
- expect(parent.children).eql([
- prevElement, block.start, element, block.end, nextElement])
-
- removeTarget(vm, block)
- expect(parent.children).eql([
- prevElement, nextElement])
- })
-
- it('remove block but preserved itself', () => {
- const element = createElement(vm, 'baz')
- const prevElement = createElement(vm, 'prev')
- const nextElement = createElement(vm, 'next')
- const parent = createElement(vm, 'bar')
- attachTarget(vm, prevElement, parent)
- const block = createBlock(vm, parent)
- attachTarget(vm, element, block)
- attachTarget(vm, nextElement, parent)
-
- expect(parent.children).eql([
- prevElement, block.start, element, block.end, nextElement])
-
- removeTarget(vm, block, true)
- expect(parent.children).eql([
- prevElement, block.start, block.end, nextElement])
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/vm/events.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/vm/events.js b/html5/test/unit/default/vm/events.js
deleted file mode 100644
index a3af0d2..0000000
--- a/html5/test/unit/default/vm/events.js
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import Vm from '../../../../frameworks/legacy/vm'
-import { Document } from '../../../../runtime/vdom'
-
-describe('bind and fire events', () => {
- let doc, customComponentMap, spy
-
- function checkReady (vm, handler) {
- /* istanbul ignore else */
- if (vm._ready) {
- handler()
- }
- else {
- vm.$on('hook:ready', handler)
- }
- }
-
- beforeEach(() => {
- spy = sinon.spy()
- doc = new Document('test', '', spy)
- customComponentMap = {}
- })
-
- afterEach(() => {
- doc.destroy()
- })
-
- it('bind event and fire in a single dom', (done) => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- a: function () { return this.x }
- },
- events: { click: 'handleClick' }
- },
- data: function () {
- return { x: 1 }
- },
- methods: {
- handleClick: function () {
- this.x = 2
- }
- }
- }
-
- const app = { doc, customComponentMap }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- checkReady(vm, function () {
- expect(doc.body.event.click.handler).a('function')
-
- const el = doc.body
- expect(el.attr.a).eql(1)
- expect(spy.args.length).eql(1)
- expect(doc.listener.updates.length).eql(0)
-
- el.event.click.handler({ xxx: 1 })
- expect(el.attr.a).eql(2)
- expect(spy.args.length).eql(2)
- expect(spy.args[1][0]).eql([
- { module: 'dom', method: 'updateAttrs', args: [el.ref, { a: 2 }] }
- ])
-
- done()
- })
- })
-
- it('emit, broadcast and dispatch vm events', (done) => {
- customComponentMap.foo = {
- template: {
- type: 'aaa',
- children: [{ type: 'bar', component: true }]
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'bbb'
- }
- }
-
- const app = { doc, customComponentMap }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- checkReady(vm, function () {
- doc.close()
-
- expect(vm._childrenVms.length).eql(1)
-
- const subVm = vm._childrenVms[0]
- expect(vm._type).eql('foo')
- expect(subVm._type).eql('bar')
-
- const spyA = sinon.spy()
- const spyB = sinon.spy()
-
- vm.$on('customTypeA', spyA)
- subVm.$on('customTypeA', spyB)
-
- let detail = { aaa: 111 }
- vm.$emit('customTypeA', detail)
- expect(spyA.args.length).eql(1)
- expect(spyB.args.length).eql(0)
-
- detail = { aaa: 111 }
- subVm.$emit('customTypeA', detail)
- expect(spyA.args.length).eql(1)
- expect(spyB.args.length).eql(1)
-
- detail = { aaa: 111 }
- vm.$broadcast('customTypeA', detail)
- expect(spyA.args.length).eql(2)
- expect(spyB.args.length).eql(2)
-
- detail = { aaa: 111 }
- subVm.$broadcast('customTypeA', detail)
- expect(spyA.args.length).eql(2)
- expect(spyB.args.length).eql(3)
-
- detail = { aaa: 111 }
- vm.$dispatch('customTypeA', detail)
- expect(spyA.args.length).eql(3)
- expect(spyB.args.length).eql(3)
-
- detail = { aaa: 111 }
- subVm.$dispatch('customTypeA', detail)
- expect(spyA.args.length).eql(4)
- expect(spyB.args.length).eql(4)
-
- vm.$off('customTypeA', spyA)
- subVm.$off('customTypeA')
-
- detail = { aaa: 111 }
- vm.$emit('customTypeA', detail)
- detail = { aaa: 111 }
- subVm.$emit('customTypeA', detail)
- detail = { aaa: 111 }
- vm.$broadcast('customTypeA', detail)
- detail = { aaa: 111 }
- subVm.$broadcast('customTypeA', detail)
- detail = { aaa: 111 }
- vm.$dispatch('customTypeA', detail)
- detail = { aaa: 111 }
- subVm.$dispatch('customTypeA', detail)
-
- expect(spyA.args.length).eql(4)
- expect(spyB.args.length).eql(4)
-
- const spyAA = function (e) {
- e.stop()
- spyA()
- }
- const spyBB = function (e) {
- e.stop()
- spyB()
- }
-
- vm.$on('customTypeA', spyAA)
- subVm.$on('customTypeA', spyBB)
- vm.$off()
- vm.$off('unknownTypeA', spyA)
-
- detail = { aaa: 111 }
- vm.$emit('customTypeA', detail)
- expect(spyA.args.length).eql(5)
- expect(spyB.args.length).eql(4)
- detail = { aaa: 111 }
- subVm.$emit('customTypeA', detail)
- expect(spyA.args.length).eql(5)
- expect(spyB.args.length).eql(5)
- detail = { aaa: 111 }
- vm.$broadcast('customTypeA', detail)
- expect(spyA.args.length).eql(6)
- expect(spyB.args.length).eql(5)
- detail = { aaa: 111 }
- subVm.$broadcast('customTypeA', detail)
- expect(spyA.args.length).eql(6)
- expect(spyB.args.length).eql(6)
- detail = { aaa: 111 }
- vm.$dispatch('customTypeA', detail)
- expect(spyA.args.length).eql(7)
- expect(spyB.args.length).eql(6)
- detail = { aaa: 111 }
- subVm.$dispatch('customTypeA', detail)
- expect(spyA.args.length).eql(7)
- expect(spyB.args.length).eql(7)
-
- done()
- })
- })
-
- it('broadcast for repeat vms', (done) => {
- const vmSpy = sinon.spy()
- const subVmSpy = sinon.spy()
-
- customComponentMap.foo = {
- data: function () {
- return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] }
- },
- template: {
- type: 'container',
- children: [{
- type: 'bar', component: true,
- repeat: function () { return this.list }
- }]
- },
- events: {
- customTypeA: function (e) {
- vmSpy(this, e)
- }
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'aaa'
- },
- events: {
- customTypeA: function (e) {
- subVmSpy(this, e)
- }
- }
- }
-
- const app = { doc, customComponentMap }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- checkReady(vm, function () {
- doc.close()
- expect(vm._childrenVms.length).eql(3)
-
- let detail = { aaa: 111 }
- vm.$emit('customTypeA', detail)
- expect(vmSpy.args.length).eql(1)
- expect(subVmSpy.args.length).eql(0)
- expect(vmSpy.args[0][0]).equal(vm)
- expect(vmSpy.args[0][1]).is.an.object
- expect(vmSpy.args[0][1].detail).equal(detail)
-
- detail = { aaa: 111 }
- vm.$broadcast('customTypeA', detail)
- expect(vmSpy.args.length).eql(2)
- expect(subVmSpy.args.length).eql(3)
- expect(vmSpy.args[1][0]).equal(vm)
- expect(vmSpy.args[1][1]).is.an.object
- expect(vmSpy.args[1][1].detail).equal(detail)
- expect(subVmSpy.args[1][0]).equal(vm._childrenVms[1])
- expect(subVmSpy.args[1][1]).is.an.object
- expect(subVmSpy.args[1][1].detail).equal(detail)
-
- done()
- })
- })
-
- it('dispatch from repeat vms', (done) => {
- const vmSpy = sinon.spy()
- const subVmSpy = sinon.spy()
-
- customComponentMap.foo = {
- data: function () {
- return { list: [{ a: 1 }, { a: 2 }, { a: 3 }] }
- },
- template: {
- type: 'container',
- children: [{
- type: 'bar', component: true,
- repeat: function () { return this.list }
- }]
- },
- events: {
- customTypeA: function (e) {
- vmSpy(this, e)
- }
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'aaa'
- },
- events: {
- customTypeA: function (e) {
- subVmSpy(this, e)
- }
- }
- }
-
- const app = { doc, customComponentMap }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- checkReady(vm, function () {
- doc.close()
- expect(vm._childrenVms.length).eql(3)
-
- let detail = { aaa: 111 }
- const subVm = vm._childrenVms[1]
- subVm.$emit('customTypeA', detail)
- expect(vmSpy.args.length).eql(0)
- expect(subVmSpy.args.length).eql(1)
- expect(subVmSpy.args[0][0]).equal(subVm)
- expect(subVmSpy.args[0][1]).is.an.object
- expect(subVmSpy.args[0][1].detail).equal(detail)
-
- detail = { aaa: 111 }
- subVm.$dispatch('customTypeA', detail)
- expect(vmSpy.args.length).eql(1)
- expect(subVmSpy.args.length).eql(2)
- expect(vmSpy.args[0][0]).equal(vm)
- expect(vmSpy.args[0][1]).is.an.object
- expect(vmSpy.args[0][1].detail).equal(detail)
- expect(subVmSpy.args[1][0]).equal(subVm)
- expect(subVmSpy.args[1][1]).is.an.object
- expect(subVmSpy.args[1][1].detail).equal(detail)
-
- done()
- })
- })
-
- it('lifecycel events', (done) => {
- const vmSpy = sinon.spy()
-
- customComponentMap.foo = {
- template: {
- type: 'aaa',
- children: [{ type: 'bar', component: true }]
- },
- data: function () {
- return {
- x: 1
- }
- },
- init: function (e) {
- vmSpy(this, e)
- expect(this._data).is.not.ok
- expect(this.x).is.not.ok
- expect(this._parentEl).is.not.ok
- },
- created: function (e) {
- vmSpy(this, e)
- expect(this._data).is.ok
- expect(this.x).is.ok
- expect(this._parentEl).is.not.ok
- },
- ready: function (e) {
- vmSpy(this, e)
- expect(this._data).is.ok
- expect(this.x).is.ok
- expect(this._parentEl).is.ok
- expect(this._parentEl.children.length).eql(1)
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'bbb'
- },
- created: function (e) {
- vmSpy(this, e)
- }
- }
-
- const app = { doc, customComponentMap }
- const evSpy = sinon.spy()
- const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, null,
- {
- 'hook:init': () => evSpy('hook:init'),
- 'hook:created': () => evSpy('hook:created'),
- 'hook:ready': () => evSpy('hook:ready')
- }
- )
-
- checkReady(vm, function () {
- doc.close()
-
- expect(vmSpy.args.length).eql(4)
-
- const subVm = vm._childrenVms[0]
- const calls = vmSpy.args.map(args => [args[0], args[1].type])
- expect(calls).eql([
- [vm, 'hook:init'],
- [vm, 'hook:created'],
- [subVm, 'hook:created'],
- [vm, 'hook:ready']
- ])
-
- expect(evSpy.callCount).to.be.equal(3)
- expect(evSpy.args).to.deep.equal([
- ['hook:init'],
- ['hook:created'],
- ['hook:ready']
- ])
-
- done()
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/vm/vm.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/vm/vm.js b/html5/test/unit/default/vm/vm.js
deleted file mode 100644
index 1ce0db3..0000000
--- a/html5/test/unit/default/vm/vm.js
+++ /dev/null
@@ -1,1975 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import Vm from '../../../../frameworks/legacy/vm'
-import { Document } from '../../../../runtime/vdom'
-import { init as resetTaskHandler } from '../../../../runtime/bridge/TaskCenter'
-import Differ from '../../../../frameworks/legacy/app/differ'
-
-const oriCallNative = global.callNative
-
-describe('generate virtual dom for a single vm', () => {
- const spy = sinon.spy()
- const spy1 = sinon.spy()
- let doc
- let customComponentMap
- let differ
-
- beforeEach(() => {
- differ = new Differ('test')
- doc = new Document('test', '', function (actions) {
- actions.forEach((action) => {
- spy.apply(null, ['test', action.method].concat(action.args))
- })
- })
- customComponentMap = {}
- })
-
- afterEach(() => {
- spy.reset()
- spy1.reset()
- doc.destroy()
- })
-
- it('$watch', () => {
- const data = {
- a: {
- b: 1
- }
- }
-
- customComponentMap.foo = {
- template: {
- type: 'container'
- },
- data: data
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(doc.body).is.an.object
-
- vm.$watch(function () {
- return this.a.b
- }, (value) => {
- expect(value).eql(2)
- })
-
- data.a.b = 2
- })
-
- it('vm.data is not a object', () => {
- const data = 'hello'
-
- customComponentMap.foo = {
- template: {
- type: 'container'
- },
- data: data
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(doc.body).is.an.object
- })
-
- it('no param parentVm', () => {
- customComponentMap.foo = {
- template: {
- type: 'container'
- }
- }
-
- const vm = new Vm('foo', customComponentMap.foo, null)
-
- expect(vm._app).is.an.object
- expect(doc.body).is.an.object
- })
-
- it('no param options', () => {
- const app = {}
- const vm = new Vm('foo', null, { _app: app })
-
- expect(vm._app).is.an.object
- expect(doc.body).is.an.object
- })
-
- it('old method.ready', () => {
- customComponentMap.foo = {
- template: {
- type: 'container'
- },
- methods: {
- ready: spy1
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(doc.body).is.an.object
- expect(doc.body.type).eql('container')
- expect(spy1).callCount(1)
- })
-
- it('generate an static element ', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- a: 1,
- b: 2,
- static: ''
- },
- style: {
- c: 3,
- d: 4
- }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm._static).eql(true)
- expect(doc.body).is.an.object
- expect(doc.body.type).eql('container')
- expect(doc.body.attr).eql({ a: 1, b: 2, static: '' })
- expect(doc.body.style).eql({ c: 3, d: 4 })
- expect(doc.body.children).is.an.array
- expect(doc.body.children.length).eql(0)
- })
-
- it('generate an single element', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- a: 1,
- b: 2
- },
- style: {
- c: 3,
- d: 4
- }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(doc.body).is.an.object
- expect(doc.body.type).eql('container')
- expect(doc.body.attr).eql({ a: 1, b: 2 })
- expect(doc.body.style).eql({ c: 3, d: 4 })
- expect(doc.body.children).is.an.array
- expect(doc.body.children.length).eql(0)
- })
-
- it('generate an element tree', () => {
- customComponentMap.foo = {
- template: {
- type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
- children: [
- { type: 'image', attr: { src: '<some image url>' }},
- { type: 'text', attr: { value: '<some text content>' }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.attr).eql({ a: 1, b: 2 })
- expect(el.style).eql({ c: 3, d: 4 })
- expect(el.children).is.an.array
- expect(el.children.length).eql(2)
-
- const image = el.children[0]
- const text = el.children[1]
- expect(image.type).eql('image')
- expect(image.attr).eql({ src: '<some image url>' })
- expect(text.type).eql('text')
- expect(text.attr).eql({ value: '<some text content>' })
- })
-
- it('generate an element tree with component options', () => {
- customComponentMap.foo = {
- template: {
- type: 'cell',
- children: [
- { type: 'text', attr: { value: '<some text content>' }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(spy.firstCall.args[0]).to.be.equal('test')
- expect(spy.firstCall.args[1]).to.be.equal('createBody')
- expect(spy.firstCall.args[2]).to.deep.equal({
- ref: '_root',
- type: 'cell',
- attr: {
- append: 'tree'
- },
- children: [{
- ref: spy.firstCall.args[2].children[0].ref,
- type: 'text',
- attr: {
- value: '<some text content>'
- },
- style: {}
- }],
- style: {}
- })
-
- expect(vm._app).equal(app)
- const el = doc.body
- expect(el.type).eql('cell')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const text = el.children[0]
- expect(text.type).eql('text')
- expect(text.attr).eql({ value: '<some text content>' })
- })
-
- it('generate an element tree with data binding', () => {
- customComponentMap.foo = {
- template: {
- type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
- children: [
- { type: 'image', attr: { src: function () { return this.x } }},
- { type: 'text', attr: { value: function () { return this.n } }},
- { type: 'text', attr: { value: function () { return this.m } }}
- ]
- },
- data: {
- x: '<some image url>', y: '<some text content>'
- },
- computed: {
- n: function () {
- return this.y.toUpperCase()
- },
- m: {
- get: function () {
- return this.y.toUpperCase()
- },
- set: function (v) {
- this.y = v
- }
- }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.x).eql('<some image url>')
- expect(vm.y).eql('<some text content>')
- expect(vm.n).eql('<SOME TEXT CONTENT>')
- expect(vm.m).eql('<SOME TEXT CONTENT>')
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.attr).eql({ a: 1, b: 2 })
- expect(el.style).eql({ c: 3, d: 4 })
- expect(el.children).is.an.array
- expect(el.children.length).eql(3)
-
- const image = el.children[0]
- const text = el.children[1]
- const text2 = el.children[2]
- expect(image.type).eql('image')
- expect(image.attr).eql({ src: '<some image url>' })
- expect(text.type).eql('text')
- expect(text.attr).eql({ value: '<SOME TEXT CONTENT>' })
- expect(text2.type).eql('text')
- expect(text2.attr).eql({ value: '<SOME TEXT CONTENT>' })
-
- vm.x = '<some image url>'
- differ.flush()
- expect(el).equal(doc.body)
- expect(image).equal(el.children[0])
- expect(text).equal(el.children[1])
- expect(text2).equal(el.children[2])
-
- vm.x = 'other string value'
- differ.flush()
- expect(el).equal(doc.body)
- expect(image).equal(el.children[0])
- expect(image.attr).eql({ src: 'other string value' })
-
- vm.y = 'other string value'
- differ.flush()
- expect(el).equal(doc.body)
- expect(text).equal(el.children[1])
- expect(text.attr).eql({ value: 'OTHER STRING VALUE' })
- expect(text2).equal(el.children[2])
- expect(text2.attr).eql({ value: 'OTHER STRING VALUE' })
-
- vm.m = 'third string value'
- differ.flush()
- expect(vm.x).eql('other string value')
- expect(vm.y).eql('third string value')
- expect(vm.n).eql('THIRD STRING VALUE')
- expect(vm.m).eql('THIRD STRING VALUE')
- expect(el).equal(doc.body)
- expect(text).equal(el.children[1])
- expect(text.attr).eql({ value: 'THIRD STRING VALUE' })
- expect(text2).equal(el.children[2])
- expect(text2.attr).eql({ value: 'THIRD STRING VALUE' })
- })
-
- it('generate an element tree with shown', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'prev' },
- {
- shown: function () { return this.y },
- type: 'image', attr: { src: function () { return this.x } }
- },
- { type: 'next' }
- ]
- },
- data: {
- x: '<some image url>', y: true
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.x).eql('<some image url>')
- expect(vm.y).eql(true)
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(5)
-
- const prev = el.children[0]
- const starter = el.children[1]
- const image = el.children[2]
- const ender = el.children[3]
- const next = el.children[4]
- expect(prev.type).eql('prev')
- expect(starter.type).eql('comment')
- expect(ender.type).eql('comment')
- expect(next.type).eql('next')
- expect(image.type).eql('image')
- expect(image.attr).eql({ src: '<some image url>' })
-
- vm.y = false
- differ.flush()
-
- expect(el).equal(doc.body)
- expect(el.children).is.an.array
- expect(el.children.length).eql(4)
- expect(prev).equal(el.children[0])
- expect(starter).equal(el.children[1])
- expect(ender).equal(el.children[2])
- expect(next).equal(el.children[3])
-
- vm.y = true
- differ.flush()
-
- expect(el).equal(doc.body)
- expect(el.children).is.an.array
- expect(el.children.length).eql(5)
- expect(prev).equal(el.children[0])
- expect(starter).equal(el.children[1])
-
- const image2 = el.children[2]
- expect(image2.type).eql('image')
- expect(image2.attr).eql({ src: '<some image url>' })
- expect(ender).equal(el.children[3])
- expect(next).equal(el.children[4])
- })
-
- it('generate an element tree with repeat', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'prev' },
- {
- repeat: function () { return this.list },
- type: 'image', attr: { src: function () { return this.x } }
- },
- { type: 'next' }
- ]
- },
- data: {
- x: '<some image url>',
- list: [
- { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.x).eql('<some image url>')
- expect(vm.list).eql([
- { uid: 1, x: 1, $index: 0 },
- { uid: 2, x: 2, $index: 1 },
- { uid: 3, $index: 2 }])
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(7)
-
- const prev = el.children[0]
- const starter = el.children[1]
- const ender = el.children[5]
- const next = el.children[6]
- expect(prev.type).eql('prev')
- expect(starter.type).eql('comment')
- expect(ender.type).eql('comment')
- expect(next.type).eql('next')
-
- expect(el.children[2].type).eql('image')
- expect(el.children[2].attr).eql({ src: 1 })
- expect(el.children[3].type).eql('image')
- expect(el.children[3].attr).eql({ src: 2 })
- expect(el.children[4].type).eql('image')
- expect(el.children[4].attr).eql({ src: '<some image url>' })
-
- vm.list[1].x = 3
- differ.flush()
- expect(el.children.length).eql(7)
- expect(el.children[2].attr).eql({ src: 1 })
- expect(el.children[3].attr).eql({ src: 3 })
- expect(el.children[4].attr).eql({ src: '<some image url>' })
-
- vm.x = 'other string value'
- differ.flush()
- expect(el.children.length).eql(7)
- expect(el.children[2].attr).eql({ src: 1 })
- expect(el.children[3].attr).eql({ src: 3 })
- expect(el.children[4].attr).eql({ src: 'other string value' })
-
- vm.list.push({ uid: 4, x: 4 })
- vm.list.push({ uid: 5 }, { uid: 6, x: 6 })
-
- differ.flush()
-
- expect(el.children.length).eql(10)
- expect(el.children[2].attr).eql({ src: 1 })
- expect(el.children[3].attr).eql({ src: 3 })
- expect(el.children[4].attr).eql({ src: 'other string value' })
- expect(el.children[5].attr).eql({ src: 4 })
- expect(el.children[6].attr).eql({ src: 'other string value' })
- expect(el.children[7].attr).eql({ src: 6 })
-
- vm.list.splice(1, 2, { uid: 7, x: 7 })
- differ.flush()
-
- expect(el.children.length).eql(9)
- expect(el.children[2].attr).eql({ src: 1 })
- expect(el.children[3].attr).eql({ src: 7 })
- expect(el.children[4].attr).eql({ src: 4 })
- expect(el.children[5].attr).eql({ src: 'other string value' })
- expect(el.children[6].attr).eql({ src: 6 })
-
- vm.list.$set(0, { uid: 321, x: 32 })
- vm.list.$set(10, { uid: 8889, x: 8888 })
- differ.flush()
-
- expect(el.children.length).eql(10)
- expect(el.children[2].attr).eql({ src: 32 })
- expect(el.children[7].attr).eql({ src: 8888 })
-
- vm.list.unshift({ uid: 12345, x: 123456 })
- differ.flush()
-
- expect(el.children.length).eql(11)
- expect(el.children[2].attr).eql({ src: 123456 })
- })
-
- it('generate an static element tree with shown and repeat', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- static: ''
- },
- children: [
- { type: 'prev' },
- {
- shown: function () { return this.x % 2 === 0 },
- repeat: function () { return this.list },
- type: 'image', attr: { src: function () { return this.x } }
- },
- { type: 'next' }
- ]
- },
- data: {
- x: '<some image url>',
- list: [
- { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm._static).equal(true)
- expect(vm.x).eql('<some image url>')
- expect(vm.list).eql([
- { uid: 1, x: 1, $index: 0 },
- { uid: 2, x: 2, $index: 1 },
- { uid: 3, $index: 2 }])
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(11)
-
- const prev = el.children[0]
- const next = el.children[10]
- expect(prev.type).eql('prev')
- expect(el.children[1].type).eql('comment')
- expect(el.children[1].value).eql('start')
- expect(el.children[9].type).eql('comment')
- expect(el.children[9].value).eql('end')
-
- expect(el.children[2].type).eql('comment')
- expect(el.children[2].value).eql('start')
- expect(el.children[3].type).eql('comment')
- expect(el.children[3].value).eql('end')
-
- expect(el.children[4].type).eql('comment')
- expect(el.children[4].value).eql('start')
- expect(el.children[5].type).eql('image')
- expect(el.children[5].attr).eql({ src: 2 })
- expect(el.children[6].type).eql('comment')
- expect(el.children[6].value).eql('end')
-
- expect(el.children[7].type).eql('comment')
- expect(el.children[7].value).eql('start')
- expect(el.children[8].type).eql('comment')
- expect(el.children[8].value).eql('end')
- expect(next.type).eql('next')
-
- vm.list[0].x = 4
- differ.flush()
-
- expect(el.children.length).eql(11)
- expect(el.children[5].type).eql('image')
- expect(el.children[5].attr).eql({ src: 2 })
- })
-
- it('generate an element tree which root element with shown', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- shown: function () { return this.x % 2 === 0 }
- },
- data: {
- x: 2
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.x).eql(2)
- })
-
- it('append tree', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- append: 'tree'
- },
- children: [
- { type: 'a' },
- { repeat: {}}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- })
-
- it('repeat is not a function', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'a' },
- { repeat: {}}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- })
-
- it('repeat oldStyle with item which not a object', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'a' },
- { repeat: function () { return [1, 2, 3] } }
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- })
-
- it('classList length is zero', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- classList: []
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- })
-
- it('classList is a function', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- classList: function () { return [] }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- })
-
- it('generate an element tree which root element with repeat', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- repeat: function () { return this.list }
- },
- data: {
- list: [
- { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.list).eql([
- { uid: 1, x: 1 },
- { uid: 2, x: 2 },
- { uid: 3 }
- ])
- })
-
- it('generate an element tree with shown and repeat', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'prev' },
- {
- shown: function () { return this.x % 2 === 0 },
- repeat: function () { return this.list },
- type: 'image', attr: { src: function () { return this.x } }
- },
- { type: 'next' }
- ]
- },
- data: {
- x: '<some image url>',
- list: [
- { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.x).eql('<some image url>')
- expect(vm.list).eql([
- { uid: 1, x: 1, $index: 0 },
- { uid: 2, x: 2, $index: 1 },
- { uid: 3, $index: 2 }])
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(11)
-
- const prev = el.children[0]
- const next = el.children[10]
- expect(prev.type).eql('prev')
- expect(el.children[1].type).eql('comment')
- expect(el.children[1].value).eql('start')
- expect(el.children[9].type).eql('comment')
- expect(el.children[9].value).eql('end')
-
- expect(el.children[2].type).eql('comment')
- expect(el.children[2].value).eql('start')
- expect(el.children[3].type).eql('comment')
- expect(el.children[3].value).eql('end')
-
- expect(el.children[4].type).eql('comment')
- expect(el.children[4].value).eql('start')
- expect(el.children[5].type).eql('image')
- expect(el.children[5].attr).eql({ src: 2 })
- expect(el.children[6].type).eql('comment')
- expect(el.children[6].value).eql('end')
-
- expect(el.children[7].type).eql('comment')
- expect(el.children[7].value).eql('start')
- expect(el.children[8].type).eql('comment')
- expect(el.children[8].value).eql('end')
- expect(next.type).eql('next')
-
- vm.list[0].x = 4
- differ.flush()
-
- expect(el.children.length).eql(12)
- expect(el.children[3].type).eql('image')
- expect(el.children[3].attr).eql({ src: 4 })
- expect(el.children[6].type).eql('image')
- expect(el.children[6].attr).eql({ src: 2 })
- })
-
- it('generate more than one group of elements with the same repeat data', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'begin' },
- {
- repeat: {
- expression: function () { return this.list },
- value: 'v1'
- },
- type: 'image', attr: { src: function () { return this.v1.x } }
- },
- { type: 'middle' },
- {
- repeat: {
- expression: function () { return this.list },
- value: 'v2'
- },
- type: 'text', attr: { value: function () { return this.v2.x } }
- },
- { type: 'end' }
- ]
- },
- data: {
- list: [
- { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm.list).eql([
- { uid: 1, x: 1 },
- { uid: 2, x: 2 },
- { uid: 3 }])
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
-
- // [begin, comment, image x 3, comment, middle, comment, text x 3, comment, end]
- expect(el.children.length).eql(13)
-
- expect(el.children[0].type).eql('begin')
- expect(el.children[1].type).eql('comment')
- expect(el.children[1].value).eql('start')
- expect(el.children[2].type).eql('image')
- expect(el.children[2].attr).eql({ src: 1 })
- expect(el.children[3].type).eql('image')
- expect(el.children[3].attr).eql({ src: 2 })
- expect(el.children[4].type).eql('image')
- expect(el.children[4].attr).eql({})
- expect(el.children[5].type).eql('comment')
- expect(el.children[5].value).eql('end')
- expect(el.children[6].type).eql('middle')
- expect(el.children[7].type).eql('comment')
- expect(el.children[7].value).eql('start')
- expect(el.children[8].type).eql('text')
- expect(el.children[8].attr).eql({ value: 1 })
- expect(el.children[9].type).eql('text')
- expect(el.children[9].attr).eql({ value: 2 })
- expect(el.children[10].type).eql('text')
- expect(el.children[10].attr).eql({})
- expect(el.children[11].type).eql('comment')
- expect(el.children[11].value).eql('end')
- expect(el.children[12].type).eql('end')
-
- vm.list[0].x = 4
- differ.flush()
-
- expect(el.children.length).eql(13)
- expect(el.children[2].attr).eql({ src: 4 })
- expect(el.children[8].attr).eql({ value: 4 })
-
- // [begin, comment, image x 4, comment, middle, comment, text x 4, comment, end]
- vm.list.push({ uid: 10, x: 10 })
- differ.flush()
-
- expect(el.children.length).eql(15)
- expect(el.children[5].attr).eql({ src: 10 })
- expect(el.children[12].attr).eql({ value: 10 })
-
- // [begin, comment, image x 2, comment, middle, comment, text x 2, comment, end]
- vm.list = [
- { uid: 100, x: 100 }, { uid: 1, x: 1 }
- ]
- differ.flush()
-
- expect(el.children.length).eql(11)
- expect(el.children[2].attr).eql({ src: 100 })
- expect(el.children[3].attr).eql({ src: 1 })
- expect(el.children[7].attr).eql({ value: 100 })
- expect(el.children[8].attr).eql({ value: 1 })
-
- vm.list[0].x = 4
- differ.flush()
-
- expect(el.children.length).eql(11)
- expect(el.children[2].attr).eql({ src: 4 })
- expect(el.children[3].attr).eql({ src: 1 })
- expect(el.children[7].attr).eql({ value: 4 })
- expect(el.children[8].attr).eql({ value: 1 })
-
- vm.list[1].x = 5
- differ.flush()
-
- expect(el.children.length).eql(11)
- expect(el.children[2].attr).eql({ src: 4 })
- expect(el.children[3].attr).eql({ src: 5 })
- expect(el.children[7].attr).eql({ value: 4 })
- expect(el.children[8].attr).eql({ value: 5 })
- })
-
- it('generate an element with external data', () => {
- customComponentMap.foo = {
- data: () => {
- return { a: 10, b: 20 }
- },
- template: {
- type: 'container',
- attr: {
- x: function () { return this.a },
- y: function () { return this.b }
- }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app }, null, { a: 1000 })
-
- expect(vm._app).equal(app)
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.attr).eql({ x: 1000, y: 20 })
-
- vm.a = 100
- vm.b = 200
- differ.flush()
-
- expect(el).equal(doc.body)
- expect(el.attr).eql({ x: 100, y: 200 })
- })
-})
-
-describe('generate virtual dom for sub vm', () => {
- let doc
- let customComponentMap
- let differ
-
- beforeEach(() => {
- global.callNative = function () {}
- resetTaskHandler()
- doc = new Document('test', null, null)
- customComponentMap = {}
- differ = new Differ('test')
- })
-
- afterEach(() => {
- doc.destroy()
- global.callNative = oriCallNative
- })
-
- it('generate sub elements', () => {
- customComponentMap.foo = {
- data: function () {
- return {
- showbar1: false,
- showbar2: false,
- bar2list: [{
- id: 'bar2-1'
- }, {
- id: 'bar2-2'
- }]
- }
- },
- template: {
- type: 'div',
- children: [
- { type: 'bar', id: 'bar', component: true,
- events: { click: 'handleClick' }
- },
- { type: 'bar1',
- shown: function () { return this.showbar1 },
- id: 'bar1', component: true
- },
- { type: 'bar2',
- shown: function () { return this.showbar2 },
- repeat: function () { return this.bar2list },
- id: function () { return this.id },
- component: true
- }
- ]
- },
- methods: {
- handleClick: sinon.spy()
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'container',
- children: [{ type: 'aaa' }, { type: 'bbb' }]
- }
- }
- customComponentMap.bar1 = {
- template: {
- type: 'container',
- children: [{ type: 'aaaa' }, { type: 'bbbb' }]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm._rootEl).to.deep.equal(vm._parentEl.children[0])
-
- expect(vm._childrenVms.length).to.be.equal(1)
- expect(vm._childrenVms[0]).to.deep.equal(vm._ids['bar'].vm)
- expect(vm._childrenVms[0]._rootEl).to.deep.equal(vm._ids['bar'].el)
-
- const el = doc.body
- expect(el.type).eql('div')
- expect(el.pureChildren).is.an.array
- expect(el.pureChildren.length).eql(1)
-
- const sub = el.children[0]
- expect(sub.type).eql('container')
- expect(sub.children).is.an.array
- expect(sub.children.length).eql(2)
- expect(sub.children[0].type).eql('aaa')
- expect(sub.children[1].type).eql('bbb')
- expect(sub.event.click).is.a.function
-
- const spy = customComponentMap.foo.methods.handleClick
- sub.event.click.handler(1, 2, 3)
- expect(spy.args.length).eql(1)
- expect(spy.args[0]).eql([1, 2, 3])
-
- vm.showbar1 = true
- differ.flush()
-
- expect(vm._childrenVms.length).to.be.equal(2)
- expect(vm._childrenVms[1]).to.deep.equal(vm._ids['bar1'].vm)
- expect(vm._childrenVms[1]._rootEl).to.deep.equal(vm._ids['bar1'].el)
-
- vm.showbar2 = true
- differ.flush()
-
- expect(vm._ids['bar2-1'].vm).to.be.not.undefined
- expect(vm._ids['bar2-1'].el).to.be.not.undefined
- expect(vm._ids['bar2-2'].vm).to.be.not.undefined
- expect(vm._ids['bar2-2'].el).to.be.not.undefined
- })
-
- it('generate sub element with static', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- static: ''
- },
- children: [{ type: 'bar', component: true }]
- }
- }
- customComponentMap.bar = {
- replace: true,
- template: {
- type: 'container',
- children: [{ type: 'aaa' }]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- expect(vm._static).eql(true)
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const aaa = el.children[0]
- expect(aaa.type).eql('aaa')
- expect(vm._childrenVms.length).to.be.equal(1)
- expect(vm._childrenVms[0]._static).eql(true)
- })
-
- it('generate replaced sub element', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true }]
- }
- }
- customComponentMap.bar = {
- replace: true,
- template: {
- type: 'container',
- children: [{ type: 'aaa' }]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const aaa = el.children[0]
- expect(aaa.type).eql('aaa')
- })
-
- it('generate replaced sub elements', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true }]
- }
- }
- customComponentMap.bar = {
- replace: true,
- template: {
- type: 'container',
- children: [{ type: 'aaa' }, { type: 'bbb' }]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(4)
-
- expect(el.children[0].type).eql('comment')
- const aaa = el.children[1]
- expect(aaa.type).eql('aaa')
- const bbb = el.children[2]
- expect(bbb.type).eql('bbb')
- expect(el.children[3].type).eql('comment')
- })
-
- it('generate sub elements with no props', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
- }
- }
- customComponentMap.bar = {
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const sub = el.children[0]
- const aaa = sub.children[0]
- expect(aaa.type).eql('aaa')
- expect(aaa.attr).eql({ a: 10 })
- const bbb = sub.children[1]
- expect(bbb.type).eql('bbb')
- expect(bbb.attr).eql({ b: 20 })
- })
-
- it('generate sub elements with array props', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
- }
- }
- customComponentMap.bar = {
- props: ['x'],
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const sub = el.children[0]
- const aaa = sub.children[0]
- expect(aaa.type).eql('aaa')
- expect(aaa.attr).eql({ a: 10 })
- const bbb = sub.children[1]
- expect(bbb.type).eql('bbb')
- expect(bbb.attr).eql({ b: 2 })
- })
-
- it('generate sub elements with props', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: { x: 10, y: 20 }}]
- }
- }
- customComponentMap.bar = {
- props: { x: Number },
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const sub = el.children[0]
- const aaa = sub.children[0]
- expect(aaa.type).eql('aaa')
- expect(aaa.attr).eql({ a: 10 })
- const bbb = sub.children[1]
- expect(bbb.type).eql('bbb')
- expect(bbb.attr).eql({ b: 2 })
- })
-
- it('generate sub elements with data', () => {
- customComponentMap.foo = {
- data: () => {
- return { a: 10, b: 20 }
- },
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: {
- x: function () { return this.a },
- y: function () { return this.b }
- }}]
- }
- }
- customComponentMap.bar = {
- props: { x: Number },
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(1)
-
- const sub = el.children[0]
- const aaa = sub.children[0]
- expect(aaa.type).eql('aaa')
- expect(aaa.attr).eql({ a: 10 })
- const bbb = sub.children[1]
- expect(bbb.type).eql('bbb')
- expect(bbb.attr).eql({ b: 2 })
-
- vm.a = 100
- vm.b = 200
- differ.flush()
-
- expect(el).equal(doc.body)
- expect(sub).equal(el.children[0])
- expect(aaa).equal(sub.children[0])
- expect(aaa.attr).eql({ a: 100 })
- expect(bbb).equal(sub.children[1])
- expect(bbb.attr).eql({ b: 2 })
- })
-
- it('generate sub elements with shown data', () => {
- customComponentMap.foo = {
- data: () => {
- return { a: 10, b: 20 }
- },
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: {
- x: function () { return this.a },
- y: function () { return this.b }
- }, shown: function () { return this.a < 15 } }]
- }
- }
- customComponentMap.bar = {
- props: { x: Number },
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(3)
-
- const sub = el.children[1]
- const aaa = sub.children[0]
- expect(aaa.type).eql('aaa')
- expect(aaa.attr).eql({ a: 10 })
- const bbb = sub.children[1]
- expect(bbb.type).eql('bbb')
- expect(bbb.attr).eql({ b: 2 })
-
- vm.a = 20
- differ.flush()
-
- expect(el).equal(doc.body)
- expect(el.children).is.an.array
- expect(el.children.length).eql(2)
- })
-
- it('generate sub elements with repeat data', () => {
- customComponentMap.foo = {
- data: () => {
- return { list: [{ uid: 1, a: 1 }, { uid: 2, a: 2 }, { uid: 3, a: 3 }] }
- },
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: {
- x: function () { return this.a },
- y: function () { return this.b }
- }, repeat: function () { return this.list } }]
- }
- }
- customComponentMap.bar = {
- props: { x: Number },
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(vm._app).equal(app)
-
- const el = doc.body
- expect(el.type).eql('container')
- expect(el.children).is.an.array
- expect(el.children.length).eql(5)
-
- const sub1 = el.children[1]
- const aaa1 = sub1.children[0]
- expect(aaa1.type).eql('aaa')
- expect(aaa1.attr).eql({ a: 1 })
- const bbb1 = sub1.children[1]
- expect(bbb1.type).eql('bbb')
- expect(bbb1.attr).eql({ b: 2 })
-
- const sub2 = el.children[2]
- const aaa2 = sub2.children[0]
- expect(aaa2.type).eql('aaa')
- expect(aaa2.attr).eql({ a: 2 })
- const bbb2 = sub2.children[1]
- expect(bbb2.type).eql('bbb')
- expect(bbb2.attr).eql({ b: 2 })
-
- const sub3 = el.children[3]
- const aaa3 = sub3.children[0]
- expect(aaa3.type).eql('aaa')
- expect(aaa3.attr).eql({ a: 3 })
- const bbb3 = sub3.children[1]
- expect(bbb3.type).eql('bbb')
- expect(bbb3.attr).eql({ b: 2 })
- })
-
- it('generate sub elements with content', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, children: [
- { type: 'a' }, { type: 'b', attr: { bbb: function () { return this.x } }}
- ] }]
- },
- data: () => {
- return {
- x: 1, y: 2
- }
- }
- }
- customComponentMap.bar = {
- replace: true,
- template: {
- type: 'container',
- children: [{ type: 'aaa' }, { type: 'content' }, { type: 'bbb' }]
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- const el = doc.body
-
- expect(el.type).eql('container')
- // [comment, aaa, comment, a, b, comment, bbb, comment]
- expect(el.children.length).eql(8)
- expect(el.children[0].type).eql('comment')
- expect(el.children[2].type).eql('comment')
- expect(el.children[5].type).eql('comment')
- expect(el.children[7].type).eql('comment')
-
- expect(el.pureChildren.length).eql(4)
- expect(el.pureChildren[0].type).eql('aaa')
- expect(el.pureChildren[1].type).eql('a')
- expect(el.pureChildren[2].type).eql('b')
- expect(el.pureChildren[2].attr).eql({ bbb: 1 })
- expect(el.pureChildren[3].type).eql('bbb')
-
- vm.x = 10
- differ.flush()
- expect(el.pureChildren[2].attr).eql({ bbb: 10 })
- })
-
- it('generate sub elements with dynamic types', (done) => {
- customComponentMap.foo = {
- data: {
- x: 'bar',
- y: 'hello'
- },
- template: {
- type: 'div',
- children: [{
- type: function () { return this.x },
- attr: { value: function () { return this.y } }
- }]
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'text',
- attr: { value: 'bar' }
- }
- }
- customComponentMap.baz = {
- data: function () {
- return {
- value: ''
- }
- },
- template: {
- type: 'text',
- attr: { value: function () { return this.value + ' baz' } }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(doc.body.pureChildren[0].type).eql('text')
- expect(doc.body.pureChildren[0].attr).eql({ value: 'bar' })
-
- vm.x = 'baz'
- expect(doc.body.pureChildren[0].type).eql('text')
- expect(doc.body.pureChildren[0].attr).eql({ value: 'hello baz' })
-
- vm.y = 'bye'
- setTimeout(() => {
- expect(doc.body.pureChildren[0].type).eql('text')
- expect(doc.body.pureChildren[0].attr).eql({ value: 'bye baz' })
-
- vm.x = 'text'
- expect(doc.body.pureChildren[0].type).eql('text')
- expect(doc.body.pureChildren[0].attr).eql({ value: 'bye' })
-
- done()
- })
- })
-
- it('generate sub elements with repeat dynamic types', (done) => {
- customComponentMap.foo = {
- data: {
- list: [
- { uid: 1, type: 'bar' },
- { uid: 2, type: 'baz' },
- { uid: 3, type: 'bar' },
- { uid: 4, type: 'baz' }
- ]
- },
- template: {
- type: 'div',
- children: [{
- type: function () { return this.v.type },
- repeat: {
- expression: function () { return this.list },
- trackBy: 'uid',
- value: 'v'
- }
- }]
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'text',
- attr: { value: 'bar' }
- }
- }
- customComponentMap.baz = {
- template: {
- type: 'text',
- attr: { value: 'baz' }
- }
- }
-
- const app = { doc, customComponentMap, differ }
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(doc.body.pureChildren.length).eql(4)
- expect(doc.body.pureChildren.map(el => el.attr.value)).eql(['bar', 'baz', 'bar', 'baz'])
-
- vm.list.splice(2, 0, { uid: 5, type: 'baz' })
- setTimeout(() => {
- expect(doc.body.pureChildren.length).eql(5)
- expect(doc.body.pureChildren.map(el => el.attr.value)).eql(['bar', 'baz', 'baz', 'bar', 'baz'])
-
- done()
- })
- })
-})
-
-describe('generate dom actions', () => {
- let doc, app, spy, customComponentMap, differ
-
- beforeEach(() => {
- spy = sinon.spy()
- doc = new Document('foo', '', function (actions) {
- actions.forEach((action) => {
- spy.apply(null, ['bar', action.method].concat(action.args))
- })
- })
- differ = new Differ('foo')
- customComponentMap = {}
- app = { doc, customComponentMap, differ }
- })
-
- afterEach(() => {
- customComponentMap = {}
- doc.destroy()
- app = doc = spy = null
- })
-
- it('received create body and add element actions', () => {
- const handler = sinon.spy()
-
- customComponentMap.foo = {
- template: {
- type: 'container',
- attr: {
- a: 1,
- b: 2
- },
- style: {
- c: 3,
- d: 4
- },
- classList: ['classA'],
- events: { click: 'handleClick' }
- },
- style: {
- classA: { d: 5, e: 6 }
- },
- methods: {
- handleClick: handler
- }
- }
-
- new Vm('foo', customComponentMap.foo, { _app: app })
- const el = {
- ref: '_root',
- type: 'container',
- attr: { a: 1, b: 2 }, style: { c: 3, d: 4, e: 6 },
- event: ['click']
- }
-
- expect(spy.args.length).eql(1)
- expect(spy.args[0]).eql(['bar', 'createBody', el])
- expect(doc.body.event.click).is.a.function
- expect(handler.args.length).eql(0)
- doc.body.fireEvent('click')
- expect(handler.args.length).eql(0)
- })
-
- it('received actions for a template with if & repeat', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [
- { type: 'prev' },
- {
- shown: function () { return this.x % 2 === 0 },
- repeat: function () { return this.list },
- trackBy: 'uid',
- type: 'image', attr: { src: function () { return this.x } }
- },
- { type: 'next' }
- ]
- },
- data: {
- x: '<some image url>',
- list: [
- { uid: 1, x: 1 }, { uid: 2, x: 2 }, { uid: 3 }
- ]
- }
- }
-
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- const pureChildren = doc.body.pureChildren
- const el = { ref: '_root', type: 'container', attr: {}, style: {}}
- const prev = {
- ref: pureChildren[0].ref,
- type: 'prev', attr: {}, style: {}
- }
- const img = {
- ref: pureChildren[1].ref,
- type: 'image', attr: { src: 2 }, style: {}
- }
- const next = {
- ref: pureChildren[2].ref,
- type: 'next', attr: {}, style: {}
- }
-
- expect(spy.args.length).eql(4)
- expect(spy.args[0]).eql(['bar', 'createBody', el])
- expect(spy.args[1]).eql(['bar', 'addElement', '_root', prev, -1])
- expect(spy.args[2]).eql(['bar', 'addElement', '_root', img, 1])
- expect(spy.args[3]).eql(['bar', 'addElement', '_root', next, -1])
-
- vm.list[1].x = 3
- differ.flush()
-
- // [1, 3, undefined]
- expect(spy.args.length).eql(5)
- expect(spy.args[4]).eql(['bar', 'removeElement', img.ref])
-
- vm.list[1].x = 12
- differ.flush()
-
- // [1, !12, undefined]
- expect(spy.args.length).eql(6)
- img.ref = pureChildren[1].ref
- img.attr.src = 12
- expect(spy.args[5]).eql(['bar', 'addElement', '_root', img, 1])
-
- vm.x = 'other string value'
- differ.flush()
-
- expect(spy.args.length).eql(6)
-
- vm.list.push({ uid: 4, x: 4 })
- vm.list.push({ uid: 5 }, { uid: 6, x: 6 })
- differ.flush()
-
- // [1, !12, undefined, !4, undefined, !6]
- const img2 = {
- ref: pureChildren[2].ref,
- type: 'image', attr: { src: 4 }, style: {}
- }
- const img3 = {
- ref: pureChildren[3].ref,
- type: 'image', attr: { src: 6 }, style: {}
- }
- expect(spy.args.length).eql(8)
- expect(spy.args[6]).eql(['bar', 'addElement', '_root', img2, 2])
- expect(spy.args[7]).eql(['bar', 'addElement', '_root', img3, 3])
-
- const temp1 = vm.list[1] // 12
- const temp2 = vm.list[5] // 6
- // vm.list.splice(0, 6, temp2, {uid: 7, x: 7}, temp1)
- vm.list = []
- vm.list.push(temp2, { uid: 7, x: 7 }, temp1)
- differ.flush()
-
- // [!6, 7, !12]
- expect(spy.args.length).eql(10)
- expect(spy.args[8]).eql(['bar', 'removeElement', img2.ref])
- expect(spy.args[9]).eql(['bar', 'moveElement', img3.ref, '_root', 1])
- })
-
- it('received actions for element updates', () => {
- customComponentMap.foo = {
- template: {
- type: 'container', attr: { a: 1, b: 2 }, style: { c: 3, d: 4 },
- children: [
- { type: 'image', attr: { src: function () { return this.x } }},
- { type: 'text', attr: { value: function () { return this.y } }}
- ]
- },
- data: {
- x: '<some image url>', y: '<some text content>'
- }
- }
-
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
- const pureChildren = doc.body.pureChildren
- const length = spy.args.length
-
- vm.x = '<some image url>'
- differ.flush()
- expect(spy.args.length - length).eql(0)
-
- vm.x = 'other string value'
- differ.flush()
- const change = [
- 'bar', 'updateAttrs',
- pureChildren[0].ref,
- { src: 'other string value' }
- ]
- expect(spy.args.length - length).eql(1)
- expect(spy.args[length]).eql(change)
- })
-
- it('received no action when no virtual dom different', () => {
- customComponentMap.foo = {
- template: {
- type: 'container', children: [
- {
- type: 'text',
- shown: function () { return this.name.length > 3 },
- attr: {
- value: function () { return this.name.toUpperCase() }
- }
- }
- ]
- },
- data: {
- name: 'Mike'
- }
- }
-
- const vm = new Vm('foo', customComponentMap.foo, { _app: app })
-
- expect(doc.body.pureChildren.length).eql(1)
- const text = doc.body.pureChildren[0]
- expect(text.attr.value).eql('MIKE')
-
- const initCalls = spy.args.length
-
- vm.name = 'MiKe'
- differ.flush()
-
- expect(spy.args.length).eql(initCalls)
-
- text.setAttr('value', 'MIKE')
- differ.flush()
-
- expect(spy.args.length).eql(initCalls)
-
- text.setAttr('value', 'STEVE')
- differ.flush()
-
- expect(spy.args.length).eql(initCalls + 1)
- expect(spy.args[initCalls]).eql([
- 'bar', 'updateAttrs', text.ref, { value: 'STEVE' }])
-
- vm.name = 'Steve'
- differ.flush()
-
- expect(spy.args.length).eql(initCalls + 1)
- })
-
- it('received actions for components', () => {
- customComponentMap.foo = {
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true }]
- }
- }
- customComponentMap.bar = {
- template: {
- type: 'container',
- children: [{ type: 'aaa' }, { type: 'bbb' }]
- }
- }
-
- new Vm('foo', customComponentMap.foo, { _app: app })
- const pureChildren = doc.body.pureChildren
- const first = pureChildren[0]
- const second = first.pureChildren[0]
- const third = first.pureChildren[1]
- expect(spy.args.length).eql(4)
- let el = { ref: '_root', type: 'container', attr: {}, style: {}}
- expect(spy.args[0]).eql(['bar', 'createBody', el])
- el = { ref: first.ref, type: 'container', attr: {}, style: {}}
- expect(spy.args[1]).eql(['bar', 'addElement', '_root', el, -1])
- el = { ref: second.ref, type: 'aaa', attr: {}, style: {}}
- expect(spy.args[2]).eql(['bar', 'addElement', first.ref, el, -1])
- el = { ref: third.ref, type: 'bbb', attr: {}, style: {}}
- expect(spy.args[3]).eql(['bar', 'addElement', first.ref, el, -1])
- })
-
- it('received actions for complicated components', () => {
- customComponentMap.foo = {
- data: () => {
- return { list: [{ uid: 1, a: 1 }, { uid: 2, a: 2 }, { uid: 3, a: 3 }] }
- },
- template: {
- type: 'container',
- children: [{ type: 'bar', component: true, attr: {
- x: function () { return this.a },
- y: function () { return this.b }
- }, repeat: function () { return this.list } }]
- }
- }
- customComponentMap.bar = {
- props: { x: Number },
- data: () => {
- return { x: 1, y: 2 }
- },
- template: {
- type: 'container',
- children: [
- { type: 'aaa', attr: { a: function () { return this.x } }},
- { type: 'bbb', attr: { b: function () { return this.y } }}
- ]
- }
- }
-
- new Vm('foo', customComponentMap.foo, { _app: app })
- const pureChildren = doc.body.pureChildren
- const first = pureChildren[0]
- const second = pureChildren[1]
- const third = pureChildren[2]
-
- /* eslint-disable indent */
- // expect(spy.args[0]).eql([ 'bar', 'createBody', 'container' ])
- expect(spy.args[0]).eql(['bar', 'createBody', { ref: '_root', type: 'container', attr: {}, style: {}}])
- expect(spy.args[1]).eql(['bar', 'addElement', '_root', { ref: first.ref, type: 'container', attr: {}, style: {}}, 0])
- expect(spy.args[2]).eql(['bar', 'addElement', first.ref, { ref: first.pureChildren[0].ref, type: 'aaa', attr: { a: 1 }, style: {}}, -1])
- expect(spy.args[3]).eql(['bar', 'addElement', first.ref, { ref: first.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
- expect(spy.args[4]).eql(['bar', 'addElement', '_root', { ref: second.ref, type: 'container', attr: {}, style: {}}, 1])
- expect(spy.args[5]).eql(['bar', 'addElement', second.ref, { ref: second.pureChildren[0].ref, type: 'aaa', attr: { a: 2 }, style: {}}, -1])
- expect(spy.args[6]).eql(['bar', 'addElement', second.ref, { ref: second.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
- expect(spy.args[7]).eql(['bar', 'addElement', '_root', { ref: third.ref, type: 'container', attr: {}, style: {}}, 2])
- expect(spy.args[8]).eql(['bar', 'addElement', third.ref, { ref: third.pureChildren[0].ref, type: 'aaa', attr: { a: 3 }, style: {}}, -1])
- expect(spy.args[9]).eql(['bar', 'addElement', third.ref, { ref: third.pureChildren[1].ref, type: 'bbb', attr: { b: 2 }, style: {}}, -1])
- /* eslint-enable indent */
- })
-
- it('received actions for add a tree element', () => {
- customComponentMap.foo = {
- template: {
- type: 'r',
- children: [
- { type: 'a' }, { type: 'b', children: [
- { type: 'd' }, { type: 'e', append: 'tree', children: [
- { type: 'g' }, { type: 'h' }, { type: 'i' }
- ] }, { type: 'f' }
- ] }, { type: 'c' }
- ]
- }
- }
-
- new Vm('foo', customComponentMap.foo, { _app: app })
- const pureChildren = doc.body.pureChildren
-
- expect(spy.args.length).eql(7)
- // body, r, r.a, r.b, r.b.d, r.b.e(tree), r.b.f, r.c
-
- expect(spy.args[0][2].ref).eql('_root')
- expect(spy.args[0][2].type).eql('r')
-
- expect(spy.args[1][3].ref).eql(pureChildren[0].ref)
- expect(spy.args[1][3].type).eql('a')
- expect(spy.args[1][2]).eql('_root')
- expect(spy.args[1][4]).eql(-1)
-
- expect(spy.args[2][3].ref).eql(pureChildren[1].ref)
- expect(spy.args[2][3].type).eql('b')
- expect(spy.args[2][2]).eql('_root')
- expect(spy.args[2][4]).eql(-1)
-
- expect(spy.args[3][3].ref).eql(pureChildren[1].pureChildren[0].ref)
- expect(spy.args[3][3].type).eql('d')
- expect(spy.args[3][2]).eql(pureChildren[1].ref)
- expect(spy.args[3][4]).eql(-1)
-
- const tree = pureChildren[1].pureChildren[1]
- expect(spy.args[4][3].ref).eql(tree.ref)
- expect(spy.args[4][3].type).eql('e')
- expect(spy.args[4][2]).eql(pureChildren[1].ref)
- expect(spy.args[4][4]).eql(-1)
- expect(spy.args[4][3].children).eql([
- { ref: tree.pureChildren[0].ref, type: 'g', attr: {}, style: {}},
- { ref: tree.pureChildren[1].ref, type: 'h', attr: {}, style: {}},
- { ref: tree.pureChildren[2].ref, type: 'i', attr: {}, style: {}}])
-
- expect(spy.args[5][3].ref).eql(pureChildren[1].pureChildren[2].ref)
- expect(spy.args[5][3].type).eql('f')
- expect(spy.args[5][2]).eql(pureChildren[1].ref)
- expect(spy.args[5][4]).eql(-1)
-
- expect(spy.args[6][3].ref).eql(pureChildren[2].ref)
- expect(spy.args[6][3].type).eql('c')
- expect(spy.args[6][2]).eql('_root')
- expect(spy.args[6][4]).eql(-1)
- })
-})
[03/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/signals/signals.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/signals/signals.source.js b/test/js-framework/case/signals/signals.source.js
new file mode 100644
index 0000000..c16234e
--- /dev/null
+++ b/test/js-framework/case/signals/signals.source.js
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/signals-sub', function (require, exports, module) {
+ module.exports = {
+ data: function () {return {
+ thumb: '', title: ''
+ }},
+ style: {},
+ template: {
+ type: 'div',
+ children: [
+ {type: 'image', attr: {src: function () {return this.thumb}}},
+ {type: 'text', attr: {value: function () {return this.title}}}
+ ]
+ }
+ }
+})
+
+define('@weex-component/signals', function (require, exports, module) {
+ module.exports = {
+ data: function () {return {
+ list: [
+ {thumb: '<some image url 1>', title: 'Hello World 1'},
+ {thumb: '<some image url 2>', title: 'Hello World 2'},
+ {thumb: '<some image url 3>', title: 'Hello World 3'},
+ {thumb: '<some image url 4>', title: 'Hello World 4'},
+ {thumb: '<some image url 5>', title: 'Hello World 5'},
+ {thumb: '<some image url 6>', title: 'Hello World 6'},
+ {thumb: '<some image url 7>', title: 'Hello World 7'},
+ {thumb: '<some image url 8>', title: 'Hello World 8'},
+ {thumb: '<some image url 9>', title: 'Hello World 9'},
+ {thumb: '<some image url 10>', title: 'Hello World 10'},
+ {thumb: '<some image url 11>', title: 'Hello World 11'},
+ {thumb: '<some image url 12>', title: 'Hello World 12'},
+ {thumb: '<some image url 13>', title: 'Hello World 13'},
+ {thumb: '<some image url 14>', title: 'Hello World 14'},
+ {thumb: '<some image url 15>', title: 'Hello World 15'},
+ {thumb: '<some image url 16>', title: 'Hello World 16'},
+ {thumb: '<some image url 17>', title: 'Hello World 17'},
+ {thumb: '<some image url 18>', title: 'Hello World 18'},
+ {thumb: '<some image url 19>', title: 'Hello World 19'},
+ {thumb: '<some image url 20>', title: 'Hello World 20'}
+ ]
+ }},
+ style: {},
+ template: {
+ type: 'div',
+ children: [
+ {
+ type: 'signals-sub',
+ repeat: {
+ expression: function () {return this.list},
+ key: 'i',
+ value: 'item'
+ },
+ attr: {
+ thumb: function () {return this.item.thumb},
+ title: function () {return this.item.title}
+ }
+ }
+ ]
+ }
+ }
+})
+
+// // require module
+
+bootstrap('@weex-component/signals')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/signals/timer.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/signals/timer.output.js b/test/js-framework/case/signals/timer.output.js
new file mode 100644
index 0000000..f645aa2
--- /dev/null
+++ b/test/js-framework/case/signals/timer.output.js
@@ -0,0 +1,9 @@
+{
+ type: 'div',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'foo'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/signals/timer.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/signals/timer.source.js b/test/js-framework/case/signals/timer.source.js
new file mode 100644
index 0000000..4222d3e
--- /dev/null
+++ b/test/js-framework/case/signals/timer.source.js
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/timer', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 'foo'
+ }
+ },
+ created: function () {
+ setTimeout(function () {
+ this.x = 'bar'
+ }.bind(this), 1500)
+ }
+ }
+
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {
+ return this.x
+ }
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/timer')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/tester.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/tester.js b/test/js-framework/case/tester.js
new file mode 100644
index 0000000..c885fef
--- /dev/null
+++ b/test/js-framework/case/tester.js
@@ -0,0 +1,528 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+
+const expect = chai.expect
+chai.use(sinonChai)
+
+import { createRuntime, createApp, getCode } from './prepare'
+
+describe('test input and output', function () {
+ let runtime
+
+ before(() => {
+ runtime = createRuntime()
+ sinon.stub(console, 'info')
+ sinon.stub(console, 'warn')
+ sinon.stub(console, 'error')
+ })
+
+ after(() => {
+ console.info.restore()
+ console.warn.restore()
+ console.error.restore()
+ })
+
+ describe('one-time rendering cases', () => {
+ let app
+
+ beforeEach(() => {
+ app = createApp(runtime)
+ callNativeHandler = (...args) => app._target.callNative(...args)
+ })
+
+ afterEach(() => {
+ app = null
+ callNativeHandler = function () {}
+ })
+
+ function checkOutput (app, name) {
+ const source = getCode('basic/' + name + '.source.js')
+ const output = getCode('basic/' + name + '.output.js')
+ const result = eval('(' + output + ')')
+
+ app.$create(source)
+ expect(app.getRealRoot()).eql(result)
+ app.$destroy()
+ }
+
+ it('global Weex object', () => checkOutput(app, 'global-weex-object'))
+
+ it('single case', () => checkOutput(app, 'foo'))
+ it('foo2 case', () => checkOutput(app, 'foo2'))
+ it('foo3 case', () => checkOutput(app, 'foo3'))
+ it('foo4 case', () => checkOutput(app, 'foo4'))
+ it('foo5 case', () => checkOutput(app, 'foo5'))
+ it('foo6 case', () => checkOutput(app, 'foo6'))
+ it('foo7 case', () => checkOutput(app, 'foo7'))
+ it('foo8 case', () => checkOutput(app, 'foo8'))
+ it('foo9 case', () => checkOutput(app, 'foo9'))
+
+ it('static1 case', () => checkOutput(app, 'static1'))
+ it('static2 case', () => checkOutput(app, 'static2'))
+ it('static3 case', () => checkOutput(app, 'static3'))
+ it('static4 case', () => checkOutput(app, 'static4'))
+
+ it('computed in repeat case', () => checkOutput(app, 'computed-in-repeat'))
+ it('backward(register/render) case', () => checkOutput(app, 'backward1'))
+ it('backward(define/require) case', () => checkOutput(app, 'backward2'))
+ it('append case', () => checkOutput(app, 'append'))
+ it('append-root case', () => checkOutput(app, 'append-root'))
+
+ it('if case', () => checkOutput(app, 'if'))
+ it('if-repeat case', () => checkOutput(app, 'if-repeat'))
+ it('if in root element case', () => checkOutput(app, 'if-root'))
+ it('repeat in root element case', () => checkOutput(app, 'repeat-root'))
+ it('repeat with index case case', () => checkOutput(app, 'repeat-index'))
+ it('repeat with array v case', () => checkOutput(app, 'repeat-array-v'))
+ it('repeat with array kv case', () => checkOutput(app, 'repeat-array-kv'))
+ it('repeat with array no-kv case', () => checkOutput(app, 'repeat-array-no-kv'))
+ it('repeat with array non-obj case', () => checkOutput(app, 'repeat-array-non-obj'))
+ it('repeat watch case', () => checkOutput(app, 'repeat-watch'))
+
+ it('id case', () => checkOutput(app, 'id'))
+ it('dynamic id case', () => checkOutput(app, 'dynamic-id'))
+
+ it('reset style case', () => checkOutput(app, 'reset-style'))
+ it('dynamic type case', () => checkOutput(app, 'dynamic-type'))
+ it('dynamic property case', () => checkOutput(app, 'dynamic-property'))
+
+ it('bind subvm', () => checkOutput(app, 'subvm'))
+ it('components options', () => checkOutput(app, 'components'))
+ it('change data when created', () => checkOutput(app, 'created'))
+ it('change data when ready', () => checkOutput(app, 'ready'))
+
+ it('require 3rd', () => checkOutput(app, 'require'))
+ it('a correct transformer version', () => checkOutput(app, 'transformer1'))
+
+ it('promise case', () => checkOutput(app, 'promise'))
+ })
+
+ describe('invalid usage', function () {
+ describe('strict mode', () => {
+ const readSource = name => getCode('throws/' + name + '.source.js')
+
+ let app
+ beforeEach(() => { app = createApp(runtime) })
+ afterEach(() => { app = null })
+
+ it('global variable 1', () => {
+ const sourceCode = readSource('global-variable1')
+ expect(() => app.$create(sourceCode)).to.throw(ReferenceError)
+ })
+
+ it('global variable 2', () => {
+ const sourceCode = readSource('global-variable2')
+ expect(() => app.$create(sourceCode)).to.throw(ReferenceError)
+ })
+
+ it('global variable 3', () => {
+ const sourceCode = readSource('global-variable3')
+ expect(() => app.$create(sourceCode)).to.throw(ReferenceError)
+ })
+ })
+ })
+
+ describe('complex cases', function () {
+ let app
+
+ beforeEach(() => {
+ app = createApp(runtime)
+ callNativeHandler = (...args) => app._target.callNative(...args)
+ })
+
+ afterEach(() => {
+ app = null
+ callNativeHandler = function () {}
+ })
+
+ const readSource = name => getCode('complex/' + name + '.source.js')
+ const readOutput = name => getCode('complex/' + name + '.output.js')
+
+ it('computed case', () => {
+ const name = 'computed'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$refresh({ x: 10 })
+ expected.children[0].attr.value = 12
+ expected.children[1].attr.value = 12
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$refresh({ m: 10 })
+ expected.children[0].attr.value = 20
+ expected.children[1].attr.value = 20
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+
+ it('append-root-event case', () => {
+ const name = 'append-root-event'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ const actual = app.getRealRoot()
+ expect(actual).eql(expected)
+
+ app.$fireEvent(app.doc.body.children[0].ref, 'click', {})
+ const actual2 = app.getRealRoot()
+ expect(actual2.children[0].attr.value).eql(2)
+
+ app.$destroy()
+ })
+
+ it('use append tree and sub components', (done) => {
+ const name = 'component-append-tree'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ const actual = app.getRealRoot()
+ expect(actual).eql(expected)
+
+ setTimeout(() => {
+ const actual2 = app.getRealRoot()
+ expect(actual2.children[0].children[0].attr.value).eql('timeout')
+ expect(actual2.children[1].children[0].attr.value).eql('timeout')
+ app.$destroy()
+ done()
+ }, 200)
+ })
+
+ it('repeat with array track-by case', () => {
+ const name = 'repeat-track-by'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ app.$refresh({
+ titlelist: [
+ { text: 'Hello World2' },
+ { text: 'Hello World1' }
+ ]
+ })
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+
+ it('if-refresh case', () => {
+ const name = 'if-refresh'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ app.$refresh({ showTitle: false })
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+
+ it('if-repeat-refresh case', () => {
+ const name = 'if-repeat-refresh'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ app.$refresh({
+ titlelist: [
+ { showTitle: false, title: 'Hello World1' },
+ { showTitle: true, title: 'Hello World2' },
+ { showTitle: true, title: 'Hello World3' }
+ ]
+ })
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+
+ it('click case', () => {
+ const name = 'click'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$fireEvent(app.doc.body.children[0].ref, 'click', {})
+
+ app.$destroy()
+ })
+
+ it('inline click case', () => {
+ const name = 'inline-click'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$fireEvent(app.doc.body.children[0].ref, 'click', {})
+
+ expected.children[0].attr.value = 'Hello World2'
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+
+ it('refresh twice', () => {
+ const name = 'refresh2'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ expect(app.getRealRoot()).eql({ type: 'container' })
+
+ app.$refresh({ ext: { showbar1: false }})
+ app.$refresh({ ext: { showbar1: true }})
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+
+ it('a less wrong transformer version', () => {
+ const name = 'transformer2'
+ const sourceCode = readSource(name)
+
+ const result = app.$create(sourceCode)
+ expect(result).to.be.an.instanceof(Error)
+ app.$destroy()
+ })
+
+ it('a bigger wrong transformer version', () => {
+ const name = 'transformer3'
+ const sourceCode = readSource(name)
+
+ const result = app.$create(sourceCode)
+ expect(result).to.be.an.instanceof(Error)
+ app.$destroy()
+ })
+
+ it('input binding', () => {
+ const name = 'input-binding'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ app.doc.body.children[0].attr.value = 'abcdefg'
+ app.$fireEvent(app.doc.body.children[0].ref, 'change', {}, { attrs: { value: 'abcdefg' }})
+ expected.children[0].attr.value = 'abcdefg'
+ expected.children.push({ type: 'text', attr: { value: '1 - abcdefg' }})
+ expect(app.getRealRoot()).eql(expected)
+
+ app.doc.body.children[0].attr.value = '12345'
+ app.$fireEvent(app.doc.body.children[0].ref, 'change', {}, { attrs: { value: '12345' }})
+ expected.children[0].attr.value = '12345'
+ expected.children.push({ type: 'text', attr: { value: '2 - 12345' }})
+ expect(app.getRealRoot()).eql(expected)
+
+ app.$destroy()
+ })
+ })
+
+ describe('multi page cases', function () {
+ let appA
+ let appB
+
+ beforeEach(() => {
+ appA = createApp(runtime)
+ appB = createApp(runtime)
+
+ callNativeHandler = (id, ...args) => {
+ switch (true) {
+ case (appA.id === id) : { appA._target.callNative(id, ...args) } break
+ case (appB.id === id) : { appB._target.callNative(id, ...args) } break
+ }
+ }
+ })
+
+ afterEach(() => {
+ appA = null
+ appB = null
+ callNativeHandler = function () {}
+ })
+
+ const readSource = name => getCode('multi/' + name + '.source.js')
+ const readOutput = name => getCode('multi/' + name + '.output.js')
+
+ it('clear-module case', () => {
+ const nameA = 'clear-moduleA'
+ const nameB = 'clear-moduleB'
+ const sourceCodeA = readSource(nameA)
+ const sourceCodeB = readSource(nameB)
+ const expectedA = eval('(' + readOutput(nameA) + ')')
+ const expectedB = eval('(' + readOutput(nameB) + ')')
+
+ appA.$create(sourceCodeA)
+ appB.$create(sourceCodeB)
+
+ expect(appB.getRealRoot()).eql(expectedB)
+
+ appB.$destroy()
+ appA.$fireEvent(appA.doc.body.children[0].ref, 'click', {})
+ expect(appA.getRealRoot()).eql(expectedA)
+
+ appA.$destroy()
+ })
+
+ it('clear-dep-target case', () => {
+ const nameError = 'clear-dep-target-error'
+ const nameFine = 'clear-dep-target-fine'
+ const sourceCodeError = readSource(nameError)
+ const sourceCodeFine = readSource(nameFine)
+ const expectedFine = eval('(' + readOutput(nameFine) + ')')
+
+ // should throw
+ expect(() => { appA.$create(sourceCodeError) }).to.throw(TypeError)
+ appA.$destroy()
+
+ // not throw
+ appB.$create(sourceCodeFine)
+ expect(appB.getRealRoot()).eql(expectedFine)
+
+ appB.$destroy()
+ })
+ })
+
+ describe('timer & callNative signals', function () {
+ let app
+
+ const callNativeSpy = sinon.spy()
+ function genCallNativeWrapper (count) {
+ return (name, tasks, cbId) => {
+ callNativeSpy(tasks)
+ const length = callNativeSpy.callCount
+ if (length > count) {
+ return -1
+ }
+ return length
+ }
+ }
+ beforeEach(() => {
+ app = createApp(runtime)
+ callNativeHandler = (...args) => app._target.callNative(...args)
+ })
+
+ afterEach(() => {
+ app = null
+ callNativeSpy.reset()
+ callNativeHandler = function () {}
+ })
+
+ const readSource = name => getCode('signals/' + name + '.source.js')
+ const readOutput = name => getCode('signals/' + name + '.output.js')
+
+ it('use HTML5 timer API', function (done) {
+ this.timeout(5000)
+ const name = 'timer'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ setTimeout(_ => {
+ expect(app.getRealRoot()).eql(expected)
+ setTimeout(_ => {
+ expected.children[0].attr.value = 'bar'
+ expect(app.getRealRoot()).eql(expected)
+ app.$destroy()
+ done()
+ }, 1000)
+ }, 1000)
+ })
+
+ it('use modal API', function (done) {
+ this.timeout(5000)
+ const name = 'modal'
+ const sourceCode = readSource(name)
+ const outputCode = readOutput(name)
+
+ app.$create(sourceCode)
+ const expected = eval('(' + outputCode + ')')
+ expect(app.getRealRoot()).eql(expected)
+
+ // the test driver will hold the API callback about 1 sec
+ setTimeout(_ => {
+ expected.children[0].attr.value = 'bar'
+ expect(app.getRealRoot()).eql(expected)
+ app.$destroy()
+ done()
+ }, 1500)
+ })
+
+ it('signals control', function () {
+ this.timeout(15000)
+
+ const name = 'signals'
+ const sourceCode = readSource(name)
+
+ function run (calls) {
+ callNativeSpy.reset()
+ callNativeHandler = genCallNativeWrapper(calls)
+ app.$create(sourceCode)
+ app.$destroy()
+ expect(callNativeSpy.callCount).eql(calls + 2)
+ }
+
+ for (let i = 5; i < 60; i++) {
+ run(i)
+ }
+ })
+
+ it('long signals control', function () {
+ this.timeout(500000)
+
+ const name = 'signals-long'
+ const sourceCode = readSource(name)
+
+ function run (calls) {
+ callNativeSpy.reset()
+ callNativeHandler = genCallNativeWrapper(calls)
+ app.$create(sourceCode)
+ app.$destroy()
+ expect(callNativeSpy.callCount).eql(calls + 2)
+ }
+
+ run(10)
+ run(30)
+ run(90)
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/throws/global-variable1.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/throws/global-variable1.source.js b/test/js-framework/case/throws/global-variable1.source.js
new file mode 100644
index 0000000..b60fc47
--- /dev/null
+++ b/test/js-framework/case/throws/global-variable1.source.js
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+something = 'whatever'
+
+define('@weex-component/global-variable1', function (require, exports, module) {
+
+ module.exports.template = { "type": "container" }
+
+ module.exports.style = {}
+
+ module.exports = {
+ ready: function () {
+ console.log('I an ready')
+ }
+ }
+
+})
+
+bootstrap('@weex-component/global-variable1')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/throws/global-variable2.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/throws/global-variable2.source.js b/test/js-framework/case/throws/global-variable2.source.js
new file mode 100644
index 0000000..b1b4f4e
--- /dev/null
+++ b/test/js-framework/case/throws/global-variable2.source.js
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/global-variable2', function (require, exports, module) {
+
+ module.exports.template = { "type": "container" }
+
+ module.exports.style = {}
+
+ module.exports = {
+ ready: function () {
+ abc = 'abc'
+ }
+ }
+
+})
+
+bootstrap('@weex-component/global-variable2')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/throws/global-variable3.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/throws/global-variable3.source.js b/test/js-framework/case/throws/global-variable3.source.js
new file mode 100644
index 0000000..e010ca1
--- /dev/null
+++ b/test/js-framework/case/throws/global-variable3.source.js
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/global-variable3', function (require, exports, module) {
+
+ module.exports.template = { "type": "container" }
+
+ module.exports.style = {}
+
+ module.exports = {
+ data: function() {
+ return {
+ lists: ['A', 'B', 'C']
+ }
+ },
+ ready: function () {
+ for (i = 0; i < this.lists.length; ++i) {
+ console.log(this.lists[i])
+ }
+ }
+ }
+
+})
+
+bootstrap('@weex-component/global-variable3')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/api/methods.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/api/methods.js b/test/js-framework/unit/default/api/methods.js
new file mode 100644
index 0000000..83f6586
--- /dev/null
+++ b/test/js-framework/unit/default/api/methods.js
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import '../../../../../runtime/shared/env/console'
+import * as modules from '../../../../../runtime/frameworks/legacy/api/modules'
+import * as methods from '../../../../../runtime/frameworks/legacy/api/methods'
+import Differ from '../../../../../runtime/frameworks/legacy/app/differ'
+import { initModules, requireModule, clearModules, initMethods } from '../../../../../runtime/frameworks/legacy/app/register'
+
+function Vm () {
+}
+
+describe('built-in methods', () => {
+ let vm
+ const requireSpy = sinon.spy()
+ const moduleSpy = sinon.spy()
+
+ before(() => {
+ clearModules()
+
+ initModules(modules)
+ initMethods(Vm, methods)
+
+ vm = new Vm()
+
+ Object.assign(vm, {
+ _app: {
+ options: {
+ debug: true,
+ bundleUrl: 'path_to_bundleUrl'
+ },
+ differ: new Differ(),
+ requireModule: (name) => {
+ requireSpy(name)
+ const module = requireModule(this, name)
+ const mockModule = {}
+ for (const moduleName in module) {
+ mockModule[moduleName] = function (...args) {
+ moduleSpy(...args)
+ if (typeof args[args.length - 1] === 'function') {
+ args[args.length - 1]()
+ }
+ }
+ }
+ return mockModule
+ }
+ },
+ _setStyle: function () {},
+ _ids: {
+ a: {
+ vm: {},
+ el: {
+ ref: '_root'
+ }
+ }
+ }
+ })
+
+ for (const apiName in vm) {
+ if (apiName.indexOf('$') === 0) {
+ vm[apiName] = sinon.spy(vm, apiName)
+ }
+ }
+ sinon.stub(console, 'warn')
+ })
+
+ beforeEach(() => {
+ requireSpy.reset()
+ moduleSpy.reset()
+ console.warn.reset()
+ })
+
+ after(() => {
+ clearModules()
+ console.warn.restore()
+ })
+
+ it('$', () => {
+ expect(vm.$('a')).to.deep.equal(vm._ids.a.vm)
+ expect(vm.$('invalid')).to.be.undefined
+ expect(console.warn.callCount).to.be.equal(2)
+ })
+
+ it('$el', () => {
+ expect(vm.$el('a')).to.deep.equal(vm._ids.a.el)
+ expect(vm.$el('invalid')).to.be.undefined
+ })
+
+ it('$vm', () => {
+ expect(vm.$vm('a')).to.deep.equal(vm._ids.a.vm)
+ expect(vm.$vm('invalid')).to.be.undefined
+ })
+
+ it('$renderThen', () => {
+ const fnSpy = sinon.spy()
+ vm.$renderThen(fnSpy)
+ vm._app.differ.flush()
+ expect(fnSpy.callCount).to.be.equal(1)
+ })
+
+ it('$scrollTo', () => {
+ vm.$scrollTo('a', 100)
+ expect(vm.$scrollTo('invalid', 100)).to.be.undefined
+ expect(requireSpy.firstCall.args[0]).to.be.equal('dom')
+ expect(moduleSpy.firstCall.args.length).to.be.equal(2)
+ })
+
+ it('$transition', () => {
+ const callback = sinon.spy()
+ vm.$transition('a', { styles: { color: '#FF0000' }}, callback)
+ expect(vm.$transition('invalid', {})).to.be.undefined
+ expect(requireSpy.firstCall.args[0]).eql('animation')
+ expect(moduleSpy.firstCall.args.length).eql(3)
+ expect(moduleSpy.firstCall.args[0]).eql('_root')
+ expect(moduleSpy.firstCall.args[1]).eql({
+ styles: { color: '#FF0000' }
+ })
+ expect(callback.callCount).eql(1)
+ })
+
+ it('$getConfig', () => {
+ const config = vm.$getConfig()
+ expect(config).eql({
+ debug: true,
+ bundleUrl: 'path_to_bundleUrl'
+ })
+
+ const configSpy = sinon.spy()
+ vm.$getConfig(configSpy)
+ expect(console.warn.callCount).to.be.equal(1)
+ expect(configSpy.args.length).eql(1)
+ expect(configSpy.args[0][0]).eql({
+ debug: true,
+ bundleUrl: 'path_to_bundleUrl'
+ })
+ })
+
+ it('$sendHttp', () => {
+ const callback = sinon.spy()
+ vm.$sendHttp({ a: 1 }, callback)
+ expect(requireSpy.firstCall.args[0]).eql('stream')
+ expect(moduleSpy.firstCall.args.length).eql(2)
+ expect(moduleSpy.firstCall.args).eql([{ a: 1 }, callback])
+ expect(callback.callCount).eql(1)
+ })
+
+ it('$openURL', () => {
+ vm.$openURL('url')
+ expect(requireSpy.firstCall.args[0]).eql('event')
+ expect(moduleSpy.firstCall.args.length).eql(1)
+ expect(moduleSpy.firstCall.args).eql(['url'])
+ })
+
+ it('$setTitle', () => {
+ vm.$setTitle('title')
+ expect(requireSpy.firstCall.args[0]).eql('pageInfo')
+ expect(moduleSpy.firstCall.args.length).eql(1)
+ expect(moduleSpy.firstCall.args).eql(['title'])
+ })
+
+ it('$call', () => {
+ vm.$call('event', 'openURL', 'url')
+ expect(vm.$call('invalid', 'module')).to.be.undefined
+ expect(vm.$call('event', 'invalid')).to.be.undefined
+ expect(requireSpy.firstCall.args[0]).eql('event')
+ expect(moduleSpy.firstCall.args.length).eql(1)
+ expect(moduleSpy.firstCall.args[0]).eql('url')
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/api/modules.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/api/modules.js b/test/js-framework/unit/default/api/modules.js
new file mode 100644
index 0000000..5545337
--- /dev/null
+++ b/test/js-framework/unit/default/api/modules.js
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import * as modules from '../../../../../runtime/frameworks/legacy/api/modules'
+import { initModules, requireModule, clearModules } from '../../../../../runtime/frameworks/legacy/app/register'
+
+describe('built-in modules', () => {
+ before(() => {
+ clearModules()
+ })
+
+ after(() => {
+ clearModules()
+ })
+
+ it('have keys', () => {
+ const app = {}
+ initModules(modules)
+ expect(requireModule(app, 'dom')).to.have.all.keys('scrollToElement')
+ expect(requireModule(app, 'stream')).to.have.all.keys('sendHttp')
+ expect(requireModule(app, 'event')).to.have.all.keys('openURL')
+ expect(requireModule(app, 'pageInfo')).to.have.all.keys('setTitle')
+ expect(requireModule(app, 'animation')).to.have.all.keys('transition')
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/app/bundle.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/app/bundle.js b/test/js-framework/unit/default/app/bundle.js
new file mode 100644
index 0000000..8ee6ae6
--- /dev/null
+++ b/test/js-framework/unit/default/app/bundle.js
@@ -0,0 +1,409 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import * as bundle from '../../../../../runtime/frameworks/legacy/app/bundle'
+import * as register from '../../../../../runtime/frameworks/legacy/app/register'
+import { removeWeexPrefix } from '../../../../../runtime/frameworks/legacy/util'
+import { Document } from '../../../../../runtime/vdom'
+import Listener from '../../../../../runtime/bridge/Listener'
+
+describe('parsing a bundle file', () => {
+ const componentTemplate = {
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ }
+ }]
+ }
+
+ before(() => {
+ sinon.stub(console, 'info')
+ sinon.stub(console, 'warn')
+ sinon.stub(console, 'error')
+ sinon.stub(console, 'debug')
+ })
+
+ after(() => {
+ console.info.restore()
+ console.warn.restore()
+ console.error.restore()
+ console.debug.restore()
+ })
+
+ describe('use define/bootstrap', () => {
+ let app
+ let callTasksSpy
+
+ before(() => {
+ const id = Date.now()
+ callTasksSpy = sinon.spy()
+
+ const doc = new Document(id, '', (tasks) => {
+ app.callTasks(tasks)
+ })
+
+ app = {
+ id, doc,
+ customComponentMap: {},
+ commonModules: {},
+ callbacks: {},
+ callTasks: callTasksSpy,
+ requireModule: function (name) {
+ return register.requireModule(this, name)
+ }
+ }
+ })
+
+ afterEach(() => {
+ callTasksSpy.reset()
+ })
+
+ describe('define', () => {
+ it('a weex component with factory and deps', () => {
+ bundle.defineFn(app, '@weex-component/a', (require, exports, module) => {
+ module.exports = {
+ template: componentTemplate
+ }
+ })
+ bundle.defineFn(app, '@weex-component/aa', [], (require, exports, module) => {
+ module.exports = {
+ template: componentTemplate
+ }
+ })
+
+ expect(app.customComponentMap['a'].template).to.deep.equal(componentTemplate)
+ expect(app.customComponentMap['aa'].template).to.deep.equal(componentTemplate)
+ })
+
+ it('a weex component with definition object and deps', () => {
+ bundle.defineFn(app, '@weex-component/aaa', {
+ template: componentTemplate
+ })
+ bundle.defineFn(app, '@weex-component/aaaa', [], {
+ template: componentTemplate
+ })
+
+ expect(app.customComponentMap['aaa'].template).to.deep.equal(componentTemplate)
+ expect(app.customComponentMap['aaaa'].template).to.deep.equal(componentTemplate)
+ })
+
+ it('a weex module', () => {
+ const methods = [{
+ name: 'createBody',
+ args: []
+ }]
+
+ bundle.defineFn(app, '@weex-module/dom', (require, exports, module) => {
+ module.exports = methods
+ })
+ })
+
+ it('a normal module', () => {
+ bundle.defineFn(app, './a', (require, exports, module) => {
+ exports.version = '0.1'
+ })
+ })
+
+ it('a npm module', () => {
+ bundle.defineFn(app, 'lib-httpurl', (require, exports, module) => {
+ exports.version = '0.2'
+ })
+ })
+
+ it('a CMD module', () => {
+ bundle.defineFn(app, 'kg/base', [], (require, exports, module) => {
+ exports.version = '0.3'
+ })
+ })
+ })
+
+ describe('require', () => {
+ it('a weex component', (done) => {
+ bundle.defineFn(app, '@weex-component/b', (require, exports, module) => {
+ const componentA = require('@weex-component/a')
+
+ expect(componentA.template).to.be.equal(componentTemplate)
+ done()
+ })
+ })
+
+ it('a weex module', (done) => {
+ // eslint-disable-next-line camelcase
+ const __weex_require__ = name => register.requireModule(app, removeWeexPrefix(name))
+ bundle.defineFn(app, '@weex-component/c', (require, exports, module) => {
+ const dom = require('@weex-module/dom')
+ expect(dom.createBody).to.be.a('function')
+ const dom2 = __weex_require__('dom')
+ expect(dom2.createBody).to.be.a('function')
+ const dom3 = __weex_require__('@weex-module/dom')
+ expect(dom3.createBody).to.be.a('function')
+ done()
+ })
+ })
+
+ it('a normal module', (done) => {
+ bundle.defineFn(app, '@weex-component/d', (require, exports, module) => {
+ const a = require('./a')
+
+ expect(a.version).to.be.equal('0.1')
+ done()
+ })
+ })
+
+ it('a npm module', (done) => {
+ bundle.defineFn(app, '@weex-component/e', (require, exports, module) => {
+ const HttpUrl = require('lib-httpurl')
+
+ expect(HttpUrl.version).to.be.equal('0.2')
+ done()
+ })
+ })
+
+ it('a CMD module', (done) => {
+ bundle.defineFn(app, 'kg/sample', ['kg/base'], (require, exports, module) => {
+ const base = require('kg/base')
+
+ expect(base.version).to.be.equal('0.3')
+ done()
+ })
+ })
+ })
+
+ describe('bootstrap', () => {
+ const ready = sinon.spy()
+
+ before(() => {
+ global.transformerVersion = '>=0.1 <1.0'
+ bundle.defineFn(app, '@weex-component/main', (require, exports, module) => {
+ module.exports = {
+ template: componentTemplate,
+ ready: ready
+ }
+ })
+ })
+
+ after(() => {
+ global.transformerVersion = undefined
+ })
+
+ it('not a weex component', () => {
+ const result = bundle.bootstrap(app, '@weex-module/dom')
+ expect(result).instanceof(Error)
+ })
+
+ it('a weex component', () => {
+ const result = bundle.bootstrap(
+ app,
+ '@weex-component/main',
+ { transformerVersion: '0.1.99' }
+ )
+
+ expect(result).not.instanceof(Error)
+ expect(callTasksSpy.calledTwice).to.be.true
+
+ expect(ready.calledOnce).to.be.true
+ const task1 = callTasksSpy.firstCall.args[0][0]
+ expect(task1.module).to.be.equal('dom')
+ expect(task1.method).to.be.equal('createBody')
+ expect(task1.args[0]).to.deep.equal({
+ type: 'container',
+ ref: '_root',
+ attr: {},
+ style: {}
+ })
+
+ const task2 = callTasksSpy.secondCall.args[0][0]
+ expect(task2.module).to.be.equal('dom')
+ expect(task2.method).to.be.equal('addElement')
+ expect(task2.args[1]).to.deep.equal({
+ type: 'text',
+ ref: app.doc.body.children[0].ref,
+ attr: {
+ value: 'Hello World'
+ },
+ style: {}
+ })
+ expect(task2.args[0]).to.be.equal('_root')
+ expect(task2.args[2]).to.be.equal(-1)
+ })
+
+ it('with a less wrong transformer version', () => {
+ const result = bundle.bootstrap(
+ app,
+ '@weex-component/main',
+ { transformerVersion: '0.0.1' }
+ )
+ expect(result).instanceof(Error)
+ })
+
+ it('with a bigger wrong transformer version', () => {
+ const result = bundle.bootstrap(
+ app,
+ '@weex-component/main',
+ { transformerVersion: '9.9.9' }
+ )
+ expect(result).instanceof(Error)
+ })
+
+ it('with viewport config', () => {
+ bundle.bootstrap(
+ app,
+ '@weex-component/undefined',
+ {
+ viewport: { width: 640 }
+ }
+ )
+ expect(callTasksSpy.callCount).to.be.equal(1)
+ const tasks = callTasksSpy.lastCall.args[0]
+ expect(tasks[0].module).to.be.equal('meta')
+ expect(tasks[0].method).to.be.equal('setViewport')
+ expect(tasks[0].args).to.deep.equal([{ width: 640 }])
+ })
+ })
+ })
+
+ describe('use regsiter/render(backward compatibility)', () => {
+ let app
+ let callTasksSpy
+ let readySpy
+ const template = {
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ }
+ }, {
+ type: 'custom'
+ }]
+ }
+
+ before(() => {
+ const id = Date.now()
+ callTasksSpy = sinon.spy()
+ readySpy = sinon.spy()
+
+ const doc = new Document(id, '', (tasks, callback) => {
+ app.callTasks(tasks, callback)
+ }, Listener)
+
+ app = {
+ id, doc,
+ customComponentMap: {},
+ callbacks: {},
+ callTasks: (tasks, callback) => {
+ callTasksSpy(tasks)
+ callback && callback()
+ },
+ requireModule: function (name) {
+ return register.requireModule(this, name)
+ }
+ }
+
+ Object.assign(app, bundle)
+ })
+
+ afterEach(() => {
+ callTasksSpy.reset()
+ })
+
+ describe('register', () => {
+ const readyfn = function () {
+ readySpy(this)
+ }
+
+ it('a component', () => {
+ bundle.register(app, 'custom', {
+ template: componentTemplate,
+ data: {
+ b: 'c'
+ },
+ methods: {
+ ready: readyfn
+ }
+ })
+
+ bundle.register(app, 'main', {
+ template: template,
+ data: {
+ a: 'b'
+ },
+ methods: {
+ ready: readyfn
+ }
+ })
+
+ expect(app.customComponentMap['custom'].template)
+ .to.deep.equal(componentTemplate)
+ expect(app.customComponentMap['main'].template)
+ .to.deep.equal(template)
+ })
+ })
+ })
+
+ describe('use define/require(backward compatibility)', () => {
+ let app
+ let callTasksSpy
+
+ before(() => {
+ const id = Date.now()
+ callTasksSpy = sinon.spy()
+
+ const doc = new Document(id, '', (tasks, callback) => {
+ app.callTasks(tasks, callback)
+ }, Listener)
+
+ app = {
+ id, doc,
+ customComponentMap: {},
+ callbacks: {},
+ callTasks: (tasks, callback) => {
+ callTasksSpy(tasks)
+ callback && callback()
+ },
+ requireModule: function (name) {
+ return register.requireModule(this, name)
+ }
+ }
+ })
+
+ afterEach(() => {
+ callTasksSpy.reset()
+ })
+
+ describe('define(old)', () => {
+ it('a component', () => {
+ bundle.defineFn(app, 'main', (require, exports, module) => {
+ module.exports = {
+ template: componentTemplate
+ }
+ })
+ expect(app.customComponentMap['main'].template)
+ .to.deep.equal(componentTemplate)
+ })
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/app/ctrl.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/app/ctrl.js b/test/js-framework/unit/default/app/ctrl.js
new file mode 100644
index 0000000..9937626
--- /dev/null
+++ b/test/js-framework/unit/default/app/ctrl.js
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import * as ctrl from '../../../../../runtime/frameworks/legacy/app/ctrl'
+import Differ from '../../../../../runtime/frameworks/legacy/app/differ'
+import { Document } from '../../../../../runtime/vdom'
+
+describe('the api of app', () => {
+ let app
+ let spy1
+ let spy2
+
+ function createApp () {
+ const id = Date.now()
+
+ const app = {
+ id: id,
+ customComponentMap: {},
+ registerComponent: function () {},
+ // define: sinon.spy(),
+ // bootstrap: sinon.stub(),
+ vm: {},
+ differ: new Differ(id)
+ }
+
+ app.doc = new Document(id, '', spy1)
+ app.doc.createBody('div')
+
+ app.doc.taskCenter.callbackManager.add(spy2)
+ // app.bootstrap.returns()
+
+ return app
+ }
+
+ before(() => {
+ spy1 = sinon.spy()
+ spy2 = sinon.spy()
+ app = createApp()
+ !console.debug && (console.debug = function () {})
+ })
+
+ afterEach(() => {
+ spy1.reset()
+ // spy2.reset()
+ })
+
+ describe('init', () => {
+ before(() => {
+ global.transformerVersion = '0.1.3'
+ })
+
+ after(() => {
+ global.transformerVersion = undefined
+ })
+
+ it('a simple bundle', () => {
+ app.requireModule = () => {}
+ ctrl.init(app, `
+ define('main', function (r, e, m) {
+ e.template = {
+ "type": "container",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "Hello World"
+ }
+ }]
+ }
+ })
+
+ bootstrap('main')
+ `)
+
+ // expect(app.define.calledOnce).to.be.true
+ // expect(app.bootstrap.calledOnce).to.be.true
+
+ const task = spy1.lastCall.args[0][0]
+ expect(task.module).to.be.equal('dom')
+ expect(task.method).to.be.equal('createFinish')
+ expect(task.args.length).to.be.equal(0)
+ })
+ })
+
+ describe('getRootElement', () => {
+ it('from a simple', () => {
+ const json = ctrl.getRootElement(app)
+ expect(json.ref).eql('_root')
+ expect(json.type).eql('div')
+ expect(json.children.length).eql(1)
+ })
+ it('from empty object', () => {
+ expect(ctrl.getRootElement({})).to.deep.equal({})
+ })
+ })
+
+ describe('fireEvent', () => {
+ it('click on root', () => {
+ ctrl.fireEvent(app, '_root', 'click')
+ const task = spy1.lastCall.args[0][0]
+ expect(task.module).to.be.equal('dom')
+ expect(task.method).to.be.equal('updateFinish')
+ expect(task.args.length).to.be.equal(0)
+ })
+
+ it('error', () => {
+ const result = ctrl.fireEvent(app, '_rootTest', 'click')
+ expect(result).to.be.an.instanceof(Error)
+ })
+
+ it('click on both root & _rootTest', () => {
+ ctrl.fireEvent(app, ['_root', '_rootTest'], 'click')
+ const task = spy1.lastCall.args[0][0]
+ expect(task.module).to.be.equal('dom')
+ expect(task.method).to.be.equal('updateFinish')
+ expect(task.args.length).to.be.equal(0)
+ })
+ })
+
+ describe('callback', () => {
+ it('with a simple data', () => {
+ const data = { a: 'b' }
+ ctrl.callback(app, '1', data, true)
+ expect(spy2.calledOnce).to.be.true
+
+ const task = spy1.firstCall.args[0][0]
+ expect(task.module).to.be.equal('dom')
+ expect(task.method).to.be.equal('updateFinish')
+ expect(task.args.length).to.be.equal(0)
+ })
+
+ it('multiple called', () => {
+ const data = { a: 'b' }
+ ctrl.callback(app, '1', data, true)
+ expect(spy2.calledTwice).to.be.true
+
+ ctrl.callback(app, '1', data, false)
+ expect(spy2.calledThrice).to.be.true
+ })
+
+ it('error', () => {
+ const data = null
+ const result = ctrl.callback(app, '1', data, true)
+ expect(result).to.be.an.instanceof(Error)
+ })
+ })
+
+ describe('refreshData', () => {
+ it('a simple data', () => {
+ const data = { b: 'c' }
+ ctrl.refresh(app, data)
+ expect(app.vm.b).to.deep.equal(data.b)
+
+ const task = spy1.lastCall.args[0][0]
+ expect(task.module).to.be.equal('dom')
+ expect(task.method).to.be.equal('refreshFinish')
+ expect(task.args.length).to.be.equal(0)
+ })
+
+ it('call refresh with refreshData function', () => {
+ app.vm.refreshData = function () {
+ app.vm.data = 'hello'
+ }
+ const data = { b: 'c' }
+ ctrl.refresh(app, data)
+ expect(app.vm.data).to.equal('hello')
+ })
+
+ it('error', () => {
+ const data = null
+ const result = ctrl.refresh(app, data)
+ expect(result).to.be.an.instanceof(Error)
+ })
+ })
+
+ describe('destory', () => {
+ it('the simple data', () => {
+ ctrl.destroy(app)
+ expect(app.id).to.be.empty
+ expect(app.blocks).to.be.null
+ expect(app.vm).to.be.null
+ expect(app.doc).to.be.null
+ expect(app.customComponentMap).to.be.null
+ })
+ it('the incomplete data', () => {
+ const appx = createApp()
+ delete appx.vm
+ ctrl.destroy(appx)
+ expect(appx.id).to.be.empty
+ expect(appx.blocks).to.be.null
+ expect(appx.vm).to.be.null
+ expect(appx.doc).to.be.null
+ expect(appx.customComponentMap).to.be.null
+ })
+ it('clear vms', () => {
+ const appy = createApp()
+ appy.vm = {
+ $emit () {},
+ _watchers: [{ teardown () {} }],
+ _childrenVms: [{ $emit () {} }]
+ }
+ ctrl.destroy(appy)
+ expect(appy.id).to.be.empty
+ expect(appy.blocks).to.be.null
+ expect(appy.vm).to.be.null
+ expect(appy.doc).to.be.null
+ expect(appy.customComponentMap).to.be.null
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/app/downgrade.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/app/downgrade.js b/test/js-framework/unit/default/app/downgrade.js
new file mode 100644
index 0000000..6c84378
--- /dev/null
+++ b/test/js-framework/unit/default/app/downgrade.js
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import * as Downgrade from '../../../../../runtime/frameworks/legacy/app/downgrade'
+
+describe('downgrade', () => {
+ describe('normalizeVersion', () => {
+ it('should be normalize version format', () => {
+ const cases = [
+ ['', '0.0.0'],
+ ['1', '1.0.0'],
+ ['1.0', '1.0.0'],
+ ['1.0.0', '1.0.0'],
+ ['1.0.0.0', '1.0.0'],
+ ['1.3.4.1230', '1.3.4']
+ ]
+
+ cases.map(function (item, index) {
+ const input = item[0]
+ const should = item[1]
+ const test = Downgrade.normalizeVersion(input)
+
+ expect(test).to.be.equal(should)
+ })
+ })
+
+ it('invalid version format', () => {
+ expect(Downgrade.normalizeVersion([])).to.be.equal('0.0.0')
+ expect(Downgrade.normalizeVersion({})).to.be.equal('0.0.0')
+ expect(Downgrade.normalizeVersion(2.0)).to.be.equal('0.0.0')
+ })
+ })
+
+ describe('getError', () => {
+ it('should be get right error message', () => {
+ const cases = [
+ [1000, 'osName', 'iphone', 'iphone'],
+ [1001, 'osVersion', '1.0.0', '1.0.0'],
+ [1002, 'appVersion', '3.2.2', '>3.0.0'],
+ [1003, 'weexVersion', '1.2.3', '>=1.2.3'],
+ [1004, 'deviceModel', '1.0.0', ['1.0.0']]
+ ]
+
+ cases.map(function (item, index) {
+ const code = item[0]
+ const key = item[1]
+ const val = item[2]
+ const criteria = item[3]
+ const test = Downgrade.getError(key, val, criteria)
+
+ expect(test.code).to.be.equal(code)
+ expect(test.errorType).to.be.equal(1)
+ expect(test.isDowngrade).to.be.equal(true)
+ })
+ })
+ })
+
+ describe('check', () => {
+ it('should be match config', () => {
+ const deviceInfo = {
+ platform: 'ios',
+ osVersion: '9.2.1',
+ appVersion: '5.4.0',
+ weexVersion: '1.3.0',
+ deviceModel: 'iPhone6.2'
+ }
+
+ const cases = [
+ [{ ios: { osVersion: '>=9' }}, true],
+ [{ ios: { appVersion: '<10.0.0' }}, true],
+ [{ ios: { appVersion: '>10.0.0' }}, false],
+ [{ ios: { appVersion: '5.4.0' }}, true],
+ [{ ios: { deviceModel: 'ABC' }}, false],
+ [{ ios: { deviceModel: 'iPhone6.2' }}, true],
+ [{ ios: { deviceModel: ['iPhone6.2', 'ABC'] }}, true],
+ [{ ios: { osVersion: '>9', deviceModel: ['iPhone6.2', 'ABC'] }}, true],
+ [{ ios: { osVersion: '>=9', deviceModel: ['iPhone6.2', 'ABC'] }}, true],
+ [{ ios: { weexVersion: '<=9' }}, true]
+ ]
+
+ cases.map(function (item, index) {
+ const criteria = item[0]
+ const should = item[1]
+ const test = Downgrade.check(criteria, deviceInfo)
+
+ expect(test.isDowngrade).to.be.equal(should)
+ })
+ })
+
+ it('should be match config without app version', () => {
+ const deviceInfo = {
+ platform: 'iOS',
+ osVersion: '9.2',
+ weexVersion: '1.3.0',
+ deviceModel: 'iPhone6.2'
+ }
+
+ const cases = [
+ [{ ios: { osVersion: '>=9' }}, true],
+ [{ ios: { osVersion: '>8' }}, true],
+ [{ ios: { appVersion: '<10.0.0' }}, false],
+ [{ ios: { appVersion: '>10.0.0' }}, false],
+ [{ ios: { appVersion: '5.4.0' }}, false],
+ [{ ios: { deviceModel: 'ABC' }}, false],
+ [{ ios: { deviceModel: 'iPhone6.2' }}, true],
+ [{ ios: { deviceModel: ['MF353TA/A', 'ABC'] }}, false],
+ [{ ios: { osVersion: '>9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
+ [{ ios: { osVersion: '>=9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
+ [{ ios: { weexVersion: '<=9' }}, true],
+ [{ ios: { weexVersion: '>=1.3.0' }}, true],
+ [{ ios: { weexVersion: '>=1.3.0' }}, true]
+ ]
+
+ cases.map(function (item, index) {
+ const criteria = item[0]
+ const should = item[1]
+ const test = Downgrade.check(criteria, deviceInfo)
+
+ expect(test.isDowngrade).to.be.equal(should)
+ })
+ })
+
+ it('should be match config and deviceInfo from global var', () => {
+ global.WXEnvironment = {
+ platform: 'iOS',
+ osVersion: '9.2',
+ appVersion: '5.4.0',
+ weexVersion: '1.3.0',
+ deviceModel: 'iPhone6.2'
+ }
+
+ const cases = [
+ [{ ios: { osVersion: '>=9' }}, true],
+ [{ ios: { osVersion: '>8' }}, true],
+ [{ ios: { appVersion: '<10.0.0' }}, true],
+ [{ ios: { appVersion: '>10.0.0' }}, false],
+ [{ ios: { appVersion: '5.4.0' }}, true],
+ [{ ios: { deviceModel: 'ABC' }}, false],
+ [{ ios: { deviceModel: 'iPhone6.2' }}, true],
+ [{ ios: { deviceModel: ['MF353TA/A', 'ABC'] }}, false],
+ [{ ios: { osVersion: '>9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
+ [{ ios: { osVersion: '>=9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
+ [{ ios: { weexVersion: '<=9' }}, true],
+ [{ ios: { weexVersion: '>=1.3.0' }}, true],
+ [{ ios: { weexVersion: '>=1.3.0' }}, true]
+ ]
+
+ cases.map(function (item, index) {
+ const criteria = item[0]
+ const should = item[1]
+ const test = Downgrade.check(criteria)
+
+ expect(test.isDowngrade).to.be.equal(should)
+ })
+ })
+
+ it('should be using using custom check', () => {
+ const deviceInfo = {
+ platform: 'iOS',
+ osVersion: '9.2',
+ appVersion: '5.4.0',
+ weexVersion: '1.3.0',
+ deviceModel: 'iPhone6.2'
+ }
+
+ const cases = [
+ [
+ function () {
+
+ }, false
+ ],
+ [
+ function () {
+ return true
+ }, true
+ ],
+ [
+ function () {
+ return false
+ }, false
+ ],
+ [
+ function (deviceInfo) {
+ if (deviceInfo.platform === 'iOS') {
+ return true
+ }
+ return false
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ if (deviceInfo.osVersion === '9.2') {
+ return true
+ }
+ return false
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ if (tools.normalizeVersion(deviceInfo.osVersion) === '9.2.0') {
+ return true
+ }
+ return false
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ return tools.semver.satisfies(tools.normalizeVersion(deviceInfo.osVersion), '9.2.0')
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ return tools.semver.satisfies(deviceInfo.appVersion, '5.4.0')
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ return tools.semver.satisfies(deviceInfo.weexVersion, '1.3.0')
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ return deviceInfo.deviceModel === 'iPhone6.2'
+ }, true
+ ],
+ [
+ function (deviceInfo, tools) {
+ return deviceInfo.deviceModel === 'AndroidPad'
+ }, false
+ ],
+ [
+ function (deviceInfo, tools) {
+ return ['iPhone6.2', 'iPhone7.1'].indexOf(deviceInfo.deviceModel) >= 0
+ }, true
+ ]
+ ]
+
+ cases.map(function (item, index) {
+ const criteria = item[0]
+ const should = item[1]
+ const test = Downgrade.check(criteria, deviceInfo)
+
+ expect(test.isDowngrade).to.be.equal(should)
+ })
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/app/index.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/app/index.js b/test/js-framework/unit/default/app/index.js
new file mode 100644
index 0000000..fdfb9ac
--- /dev/null
+++ b/test/js-framework/unit/default/app/index.js
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import App from '../../../../../runtime/frameworks/legacy/app'
+import { Element, Document } from '../../../../../runtime/vdom'
+
+describe('App Instance', () => {
+ const oriDocumentHandler = Document.handler
+ const sendTasksSpy = sinon.spy()
+ let app
+
+ beforeEach(() => {
+ Document.handler = sendTasksSpy
+ const id = Date.now() + ''
+ app = new App(id, {})
+ })
+
+ afterEach(() => {
+ Document.handler = oriDocumentHandler
+ })
+
+ describe('normal check', () => {
+ it('is a class', () => {
+ expect(App).to.be.an('function')
+ })
+
+ it('being created', () => {
+ expect(app).to.be.an('object')
+ expect(app).to.be.instanceof(App)
+ })
+
+ it('with some apis', () => {
+ expect(app.requireModule).a.function
+ expect(app.updateActions).a.function
+ expect(app.callTasks).a.function
+ })
+
+ it('run apis', () => {
+ expect(app.requireModule('stream')).to.deep.equal({})
+ expect(app.updateActions()).to.be.undefined
+ expect(app.callTasks([])).to.be.undefined
+ })
+ })
+
+ describe('call tasks', () => {
+ it('with no args & callback', () => {
+ const tasks = [{
+ module: 'dom',
+ method: 'createBody',
+ args: []
+ }]
+
+ app.callTasks(tasks)
+ expect(sendTasksSpy.lastCall.args[1]).to.deep.equal(tasks)
+ })
+
+ it('with callback', (done) => {
+ const tasks = [{
+ module: 'dom',
+ method: 'createBody',
+ args: []
+ }]
+
+ app.callTasks(tasks)
+ expect(sendTasksSpy.lastCall.args[1]).to.deep.equal(tasks)
+ done()
+ })
+
+ it('with function arg', (done) => {
+ const callbackId = '1'
+
+ const tasks = [{
+ module: 'dom',
+ method: 'createBody',
+ args: [() => {}]
+ }]
+
+ app.callTasks(tasks)
+ expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'createBody',
+ args: [callbackId]
+ }])
+ done()
+ })
+
+ it('with node arg', (done) => {
+ const node = new Element()
+ node.ref = '1'
+
+ const tasks = [{
+ module: 'dom',
+ method: 'createBody',
+ args: [node]
+ }]
+
+ app.callTasks(tasks)
+ expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'createBody',
+ args: [node.ref]
+ }])
+ done()
+ })
+
+ it('with callback after close', (done) => {
+ const callbackId = '1'
+
+ const tasks = [{
+ module: 'dom',
+ method: 'createBody',
+ args: [() => {}]
+ }]
+
+ app.doc.close()
+
+ app.callTasks(tasks)
+ expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
+ module: 'dom',
+ method: 'createBody',
+ args: [callbackId]
+ }])
+ done()
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/app/register.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/app/register.js b/test/js-framework/unit/default/app/register.js
new file mode 100644
index 0000000..853b428
--- /dev/null
+++ b/test/js-framework/unit/default/app/register.js
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import {
+ getModule,
+ clearModules,
+ initModules,
+ initMethods,
+ requireModule,
+ requireCustomComponent,
+ registerCustomComponent
+} from '../../../../../runtime/frameworks/legacy/app/register'
+
+function Ctx () {
+ this.customComponentMap = {}
+ this.callTasks = sinon.spy()
+}
+
+describe('register', () => {
+ let ctx
+
+ before(() => {
+ clearModules()
+ ctx = new Ctx()
+ })
+
+ after(() => {
+ clearModules()
+ })
+
+ describe('component', () => {
+ it('with exports', () => {
+ const def = {
+ a: 'b'
+ }
+ registerCustomComponent(ctx, 'componentA', def)
+ expect(requireCustomComponent(ctx, 'componentA')).to.deep.equal(def)
+ })
+
+ it('with a existing name', () => {
+ const def = {
+ a: 'b'
+ }
+ sinon.stub(console, 'error')
+ registerCustomComponent(ctx, 'componentA', def)
+ expect(console.error).callCount(1)
+ console.error.restore()
+ })
+ })
+
+ describe('module', () => {
+ it('with a old format', () => {
+ initModules({
+ dom: [
+ 'createBody',
+ 'addElement'
+ ]
+ })
+ expect(requireModule(ctx, 'dom')).to.have.any.keys('createBody', 'addElement')
+ })
+
+ it('with a new format', () => {
+ initModules({
+ dom: [
+ {
+ name: 'moveElement',
+ args: ['string', 'string']
+ }
+ ],
+ stream: [
+ {
+ name: 'sendMtop',
+ args: ['object', 'function']
+ }
+ ]
+ })
+ expect(requireModule(ctx, 'dom')).to.have.all.keys('createBody', 'addElement', 'moveElement')
+ expect(requireModule(ctx, 'stream')).to.have.all.keys('sendMtop')
+ })
+
+ it('with a existed module.method', () => {
+ initModules({
+ dom: [
+ {
+ name: 'moveElement',
+ args: ['string', 'string', 'string']
+ }
+ ]
+ }, true)
+ initModules({
+ stream: [
+ {
+ name: 'sendMtop',
+ args: ['object']
+ }
+ ]
+ })
+ expect(getModule('dom').moveElement).to.deep.equal({
+ name: 'moveElement',
+ args: ['string', 'string', 'string']
+ })
+
+ expect(getModule('stream').sendMtop).to.deep.equal({
+ name: 'sendMtop',
+ args: ['object', 'function']
+ })
+ })
+
+ it('run registered module', () => {
+ initModules({
+ event: [{
+ name: 'openURL',
+ args: ['string']
+ }]
+ })
+ const event = requireModule(ctx, 'event')
+ expect(event).to.have.keys('openURL')
+
+ event.openURL('http://test.com')
+ expect(ctx.callTasks.callCount).to.be.equal(1)
+ })
+ })
+
+ describe('api', () => {
+ it('a common api', () => {
+ initMethods(Ctx, {
+ $test1: function () {
+ return {
+ ctx: this,
+ value: 'test1'
+ }
+ },
+ $test2: function () {
+ return {
+ ctx: this,
+ value: 'test2'
+ }
+ }
+ })
+
+ expect(ctx.$test1).to.be.a('Function')
+ expect(ctx.$test1()).to.deep.equal({
+ ctx: ctx,
+ value: 'test1'
+ })
+ expect(ctx.$test2).to.be.an('Function')
+ expect(ctx.$test2()).to.deep.equal({
+ ctx: ctx,
+ value: 'test2'
+ })
+ })
+
+ it('override api', () => {
+ initMethods(Ctx, {
+ $override: function () {
+ return {
+ ctx: this,
+ value: 'first'
+ }
+ }
+ })
+
+ initMethods(Ctx, {
+ $override: function () {
+ return {
+ ctx: this,
+ value: 'ignored'
+ }
+ }
+ })
+
+ expect(ctx.$override).to.be.a('Function')
+ expect(ctx.$override()).to.deep.equal({
+ ctx: ctx,
+ value: 'first'
+ })
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/app/viewport.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/app/viewport.js b/test/js-framework/unit/default/app/viewport.js
new file mode 100644
index 0000000..2caf37c
--- /dev/null
+++ b/test/js-framework/unit/default/app/viewport.js
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+const { expect } = chai
+chai.use(sinonChai)
+
+import * as viewport from '../../../../../runtime/frameworks/legacy/app/viewport'
+
+describe('viewport', function () {
+ const originalCallNative = global.callNative
+ const { setViewport, validateViewport } = viewport
+ const mockApp = {
+ id: 'mock',
+ callTasks (...args) {
+ global.callNative(...args)
+ }
+ }
+
+ before(() => {
+ sinon.stub(console, 'warn')
+ })
+
+ beforeEach(() => {
+ global.callNative = sinon.spy()
+ })
+ afterEach(() => {
+ global.callNative = originalCallNative
+ console.warn.reset()
+ })
+
+ it('invalid setViewport', () => {
+ setViewport()
+ expect(global.callNative.callCount).to.be.equal(0)
+ setViewport({})
+ expect(global.callNative.callCount).to.be.equal(0)
+ })
+
+ it('setViewport', () => {
+ setViewport(mockApp, {})
+ expect(global.callNative.callCount).to.be.equal(1)
+ setViewport(mockApp, { width: 640 })
+ expect(global.callNative.callCount).to.be.equal(2)
+ setViewport(mockApp, { width: 'device-width' })
+ expect(global.callNative.callCount).to.be.equal(3)
+ })
+
+ it('validateViewport', () => {
+ expect(validateViewport()).to.be.false
+ expect(console.warn.callCount).to.be.equal(1)
+ expect(validateViewport({})).to.be.false
+ expect(console.warn.callCount).to.be.equal(2)
+
+ expect(validateViewport({ width: 200 })).to.be.true
+ expect(console.warn.callCount).to.be.equal(2)
+ expect(validateViewport({ width: 'device-width' })).to.be.true
+ expect(console.warn.callCount).to.be.equal(2)
+
+ expect(validateViewport({ width: 'initial-width' })).to.be.false
+ expect(console.warn.callCount).to.be.equal(3)
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/util/index.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/util/index.js b/test/js-framework/unit/default/util/index.js
new file mode 100644
index 0000000..0d778f7
--- /dev/null
+++ b/test/js-framework/unit/default/util/index.js
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import chai from 'chai'
+const { expect } = chai
+
+import * as util from '../../../../../runtime/frameworks/legacy/util'
+
+describe('Util', () => {
+ describe('isReserved', () => {
+ it('should be first char is $ or _', () => {
+ expect(util.isReserved('$isReserved')).eql(true)
+ expect(util.isReserved('_isReserved')).eql(true)
+ expect(util.isReserved('isReserved$')).eql(false)
+ expect(util.isReserved('is$Reserved')).eql(false)
+ expect(util.isReserved('isReserved')).eql(false)
+ })
+ })
+
+ describe('camelize', () => {
+ it('should be camelize a hyphen-delmited string', () => {
+ expect(util.camelize('mini-camelize')).eql('miniCamelize')
+ expect(util.camelize('mini-camelize-test')).eql('miniCamelizeTest')
+ })
+ })
+
+ describe('toArray', () => {
+ it('should be convert an Array-like object to a real Array', () => {
+ const mockup = {
+ '0': 1,
+ '1': 2,
+ '2': 3,
+ length: 3
+ }
+
+ expect(util.toArray(mockup)).eql([1, 2, 3])
+ expect(util.toArray(mockup, 2)).eql([3])
+ })
+ })
+
+ describe('extend', () => {
+ it('should be extend object', () => {
+ const mockup = {
+ a: 1,
+ b: 2
+ }
+
+ expect(util.extend(mockup, { b: 4, c: 5 })).eql({
+ a: 1,
+ b: 4,
+ c: 5
+ })
+
+ expect(util.extend(mockup, { c: 5 })).eql({
+ a: 1,
+ b: 4,
+ c: 5
+ })
+
+ expect(util.extend(mockup, { c: 5 }, { d: 6 }, { e: 7 })).eql({
+ a: 1,
+ b: 4,
+ c: 5,
+ d: 6,
+ e: 7
+ })
+ })
+
+ it('polyfill Object.assign', () => {
+ const _assign = Object.assign
+ Object.assign = undefined
+
+ const mockup = {
+ a: 1,
+ b: 2
+ }
+
+ expect(util.extend(mockup, { b: 4, c: 5 })).eql({
+ a: 1,
+ b: 4,
+ c: 5
+ })
+
+ expect(util.extend(mockup, { c: 5 })).eql({
+ a: 1,
+ b: 4,
+ c: 5
+ })
+
+ expect(util.extend(mockup, { c: 5 }, { d: 6 }, { e: 7 })).eql({
+ a: 1,
+ b: 4,
+ c: 5,
+ d: 6,
+ e: 7
+ })
+
+ Object.assign = _assign
+ })
+ })
+
+ describe('isObject', () => {
+ it('should be an array or object', () => {
+ expect(util.isObject({})).eql(true)
+ expect(util.isObject([])).eql(true)
+ expect(util.isObject('a')).eql(false)
+ expect(util.isObject(1)).eql(false)
+ expect(util.isObject(true)).eql(false)
+ expect(util.isObject(null)).eql(false)
+ expect(util.isObject(undefined)).eql(false)
+ expect(util.isObject(function () {})).eql(false)
+ expect(util.isObject(/\w*/)).eql(true) // regexp is object
+ expect(util.isObject(new Date())).eql(true)
+ })
+ })
+
+ describe('isPlainObject', () => {
+ it('should be an real object', () => {
+ expect(util.isPlainObject({})).eql(true)
+ expect(util.isPlainObject([])).eql(false)
+ expect(util.isPlainObject('a')).eql(false)
+ expect(util.isPlainObject(1)).eql(false)
+ expect(util.isPlainObject(true)).eql(false)
+ expect(util.isPlainObject(null)).eql(false)
+ expect(util.isPlainObject(undefined)).eql(false)
+ expect(util.isPlainObject(function () {})).eql(false)
+ expect(util.isPlainObject(/\w*/)).eql(false)
+ expect(util.isPlainObject(new Date())).eql(false)
+ })
+ })
+
+ describe('typof', () => {
+ it('should be real type', () => {
+ expect(util.typof({})).eql('object')
+ expect(util.typof([])).eql('array')
+ expect(util.typof('a')).eql('string')
+ expect(util.typof(1)).eql('number')
+ expect(util.typof(true)).eql('boolean')
+ expect(util.typof(null)).eql('null')
+ expect(util.typof(undefined)).eql('undefined')
+ expect(util.typof(function () {})).eql('function')
+ expect(util.typof(/\w*/)).eql('regexp')
+ expect(util.typof(new Date())).eql('date')
+ })
+ })
+
+ describe('def', () => {
+ it('should be define a non-enumerable property', () => {
+ const obj = {}
+ util.def(obj, 'a', 1, true)
+ expect(obj).eql({ a: 1 })
+
+ util.def(obj, 'b', 1, false)
+ expect(obj).eql({ a: 1 })
+
+ util.def(obj, 'c', 1, true)
+ expect(obj).eql({ a: 1, c: 1 })
+
+ util.def(obj, 'd', 1)
+ expect(obj).eql({ a: 1, c: 1 })
+ })
+ })
+
+ describe('hyphenate', () => {
+ it('should hyphenate a camelCase string', () => {
+ const str = 'helloWorldWeex'
+ expect(util.hyphenate(str)).eql('hello-world-weex')
+ })
+ })
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/unit/default/util/shared.js
----------------------------------------------------------------------
diff --git a/test/js-framework/unit/default/util/shared.js b/test/js-framework/unit/default/util/shared.js
new file mode 100644
index 0000000..6778206
--- /dev/null
+++ b/test/js-framework/unit/default/util/shared.js
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { expect } from 'chai'
+
+import * as utils from '../../../../../runtime/frameworks/legacy/util/shared'
+
+describe('test util functions', () => {
+ it('extend', () => {
+ expect(typeof utils.extend).to.be.equal('function')
+
+ const a = { name: 'A', a: true, c: true }
+ const b = { name: 'B', b: true }
+ utils.extend(a, b, { c: false })
+ expect(a).to.be.deep.equal({ name: 'B', a: true, b: true, c: false })
+ expect(b).to.be.deep.equal({ name: 'B', b: true })
+ })
+
+ it('def', () => {
+ expect(typeof utils.def).to.be.equal('function')
+ const obj = { type: 'none' }
+ utils.def(obj, 'count', 42, false)
+
+ expect(obj.hasOwnProperty('count')).to.be.true
+ expect(obj.propertyIsEnumerable('count')).to.be.false
+ expect(obj.type).to.be.equal('none')
+ expect(obj.count).to.be.equal(42)
+ obj.count = 24
+ expect(obj.count).to.be.equal(24)
+ })
+
+ it('remove', () => {
+ expect(typeof utils.remove).to.be.equal('function')
+
+ const arr = ['first', null, 42, null, 28]
+ const obj = { 0: 'first', 1: null, 2: 42 }
+
+ utils.remove(arr, null)
+ expect(arr).to.deep.equal(['first', 42, null, 28])
+ utils.remove(arr, null)
+ expect(arr).to.deep.equal(['first', 42, 28])
+ utils.remove(arr, null)
+ expect(arr).to.deep.equal(['first', 42, 28])
+ utils.remove(arr, 42)
+ expect(arr).to.deep.equal(['first', 28])
+
+ utils.remove(obj, 42)
+ expect(obj).to.deep.equal(obj)
+ })
+
+ it('hasOwn', () => {
+ expect(typeof utils.hasOwn).to.be.equal('function')
+
+ function Point () {
+ this.x = 0
+ }
+ Point.prototype.y = 1
+
+ const p = new Point()
+ expect(p.x).to.be.equal(0)
+ expect(p.y).to.be.equal(1)
+
+ expect(utils.hasOwn(p, 'x')).to.be.true
+ expect(utils.hasOwn(p, 'y')).to.be.false
+ })
+
+ it('bind', () => {
+ expect(typeof utils.bind).to.be.equal('function')
+
+ function who () {
+ return this.name
+ }
+ const obj = { name: 'fixed' }
+ const ctx = { name: 'changed' }
+ const askWho = utils.bind(who, obj)
+
+ expect(who()).to.be.undefined
+ expect(askWho()).to.be.equal('fixed')
+ expect(askWho.call(ctx)).to.be.equal('fixed')
+ expect(askWho.apply(ctx)).to.be.equal('fixed')
+ expect(who.apply(ctx)).to.be.equal('changed')
+ })
+
+ it('toArray', () => {
+ expect(typeof utils.toArray).to.be.equal('function')
+ const obj = { length: 2 }
+ const arr = utils.toArray(obj)
+
+ expect(arr).to.deep.equal([undefined, undefined])
+ expect(arr.hasOwnProperty('0')).to.be.true
+ expect(arr.hasOwnProperty('1')).to.be.true
+ expect(arr.hasOwnProperty('2')).to.be.false
+
+ const arrayLike = {
+ 0: 'empty',
+ 1: 'first',
+ 2: 'second',
+ length: 3
+ }
+ expect(utils.toArray(arrayLike, 1)).to.deep.equal(['first', 'second'])
+ })
+
+ it('isObject', () => {
+ expect(typeof utils.isObject).to.be.equal('function')
+ expect(utils.isObject({})).to.be.true
+ expect(utils.isObject([])).to.be.true
+ expect(utils.isObject(new Date())).to.be.true
+ expect(utils.isObject()).to.be.false
+ expect(utils.isObject('')).to.be.false
+ expect(utils.isObject(42)).to.be.false
+ expect(utils.isObject(NaN)).to.be.false
+ expect(utils.isObject(null)).to.be.false
+ expect(utils.isObject(undefined)).to.be.false
+ })
+
+ it('isPlainObject', () => {
+ expect(typeof utils.isPlainObject).to.be.equal('function')
+ expect(utils.isPlainObject({})).to.be.true
+ expect(utils.isPlainObject([])).to.be.false
+ expect(utils.isPlainObject(new Date())).to.be.false
+ expect(utils.isPlainObject()).to.be.false
+ expect(utils.isPlainObject('')).to.be.false
+ expect(utils.isPlainObject(42)).to.be.false
+ expect(utils.isPlainObject(NaN)).to.be.false
+ expect(utils.isPlainObject(null)).to.be.false
+ expect(utils.isPlainObject(undefined)).to.be.false
+ })
+})
[13/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/signals/signals.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/signals/signals.source.js b/html5/test/case/signals/signals.source.js
deleted file mode 100644
index c16234e..0000000
--- a/html5/test/case/signals/signals.source.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/signals-sub', function (require, exports, module) {
- module.exports = {
- data: function () {return {
- thumb: '', title: ''
- }},
- style: {},
- template: {
- type: 'div',
- children: [
- {type: 'image', attr: {src: function () {return this.thumb}}},
- {type: 'text', attr: {value: function () {return this.title}}}
- ]
- }
- }
-})
-
-define('@weex-component/signals', function (require, exports, module) {
- module.exports = {
- data: function () {return {
- list: [
- {thumb: '<some image url 1>', title: 'Hello World 1'},
- {thumb: '<some image url 2>', title: 'Hello World 2'},
- {thumb: '<some image url 3>', title: 'Hello World 3'},
- {thumb: '<some image url 4>', title: 'Hello World 4'},
- {thumb: '<some image url 5>', title: 'Hello World 5'},
- {thumb: '<some image url 6>', title: 'Hello World 6'},
- {thumb: '<some image url 7>', title: 'Hello World 7'},
- {thumb: '<some image url 8>', title: 'Hello World 8'},
- {thumb: '<some image url 9>', title: 'Hello World 9'},
- {thumb: '<some image url 10>', title: 'Hello World 10'},
- {thumb: '<some image url 11>', title: 'Hello World 11'},
- {thumb: '<some image url 12>', title: 'Hello World 12'},
- {thumb: '<some image url 13>', title: 'Hello World 13'},
- {thumb: '<some image url 14>', title: 'Hello World 14'},
- {thumb: '<some image url 15>', title: 'Hello World 15'},
- {thumb: '<some image url 16>', title: 'Hello World 16'},
- {thumb: '<some image url 17>', title: 'Hello World 17'},
- {thumb: '<some image url 18>', title: 'Hello World 18'},
- {thumb: '<some image url 19>', title: 'Hello World 19'},
- {thumb: '<some image url 20>', title: 'Hello World 20'}
- ]
- }},
- style: {},
- template: {
- type: 'div',
- children: [
- {
- type: 'signals-sub',
- repeat: {
- expression: function () {return this.list},
- key: 'i',
- value: 'item'
- },
- attr: {
- thumb: function () {return this.item.thumb},
- title: function () {return this.item.title}
- }
- }
- ]
- }
- }
-})
-
-// // require module
-
-bootstrap('@weex-component/signals')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/signals/timer.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/signals/timer.output.js b/html5/test/case/signals/timer.output.js
deleted file mode 100644
index f645aa2..0000000
--- a/html5/test/case/signals/timer.output.js
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- type: 'div',
- children: [{
- type: 'text',
- attr: {
- value: 'foo'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/signals/timer.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/signals/timer.source.js b/html5/test/case/signals/timer.source.js
deleted file mode 100644
index 4222d3e..0000000
--- a/html5/test/case/signals/timer.source.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/timer', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {
- x: 'foo'
- }
- },
- created: function () {
- setTimeout(function () {
- this.x = 'bar'
- }.bind(this), 1500)
- }
- }
-
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {
- return this.x
- }
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/timer')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/tester.js
----------------------------------------------------------------------
diff --git a/html5/test/case/tester.js b/html5/test/case/tester.js
deleted file mode 100644
index c885fef..0000000
--- a/html5/test/case/tester.js
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-
-const expect = chai.expect
-chai.use(sinonChai)
-
-import { createRuntime, createApp, getCode } from './prepare'
-
-describe('test input and output', function () {
- let runtime
-
- before(() => {
- runtime = createRuntime()
- sinon.stub(console, 'info')
- sinon.stub(console, 'warn')
- sinon.stub(console, 'error')
- })
-
- after(() => {
- console.info.restore()
- console.warn.restore()
- console.error.restore()
- })
-
- describe('one-time rendering cases', () => {
- let app
-
- beforeEach(() => {
- app = createApp(runtime)
- callNativeHandler = (...args) => app._target.callNative(...args)
- })
-
- afterEach(() => {
- app = null
- callNativeHandler = function () {}
- })
-
- function checkOutput (app, name) {
- const source = getCode('basic/' + name + '.source.js')
- const output = getCode('basic/' + name + '.output.js')
- const result = eval('(' + output + ')')
-
- app.$create(source)
- expect(app.getRealRoot()).eql(result)
- app.$destroy()
- }
-
- it('global Weex object', () => checkOutput(app, 'global-weex-object'))
-
- it('single case', () => checkOutput(app, 'foo'))
- it('foo2 case', () => checkOutput(app, 'foo2'))
- it('foo3 case', () => checkOutput(app, 'foo3'))
- it('foo4 case', () => checkOutput(app, 'foo4'))
- it('foo5 case', () => checkOutput(app, 'foo5'))
- it('foo6 case', () => checkOutput(app, 'foo6'))
- it('foo7 case', () => checkOutput(app, 'foo7'))
- it('foo8 case', () => checkOutput(app, 'foo8'))
- it('foo9 case', () => checkOutput(app, 'foo9'))
-
- it('static1 case', () => checkOutput(app, 'static1'))
- it('static2 case', () => checkOutput(app, 'static2'))
- it('static3 case', () => checkOutput(app, 'static3'))
- it('static4 case', () => checkOutput(app, 'static4'))
-
- it('computed in repeat case', () => checkOutput(app, 'computed-in-repeat'))
- it('backward(register/render) case', () => checkOutput(app, 'backward1'))
- it('backward(define/require) case', () => checkOutput(app, 'backward2'))
- it('append case', () => checkOutput(app, 'append'))
- it('append-root case', () => checkOutput(app, 'append-root'))
-
- it('if case', () => checkOutput(app, 'if'))
- it('if-repeat case', () => checkOutput(app, 'if-repeat'))
- it('if in root element case', () => checkOutput(app, 'if-root'))
- it('repeat in root element case', () => checkOutput(app, 'repeat-root'))
- it('repeat with index case case', () => checkOutput(app, 'repeat-index'))
- it('repeat with array v case', () => checkOutput(app, 'repeat-array-v'))
- it('repeat with array kv case', () => checkOutput(app, 'repeat-array-kv'))
- it('repeat with array no-kv case', () => checkOutput(app, 'repeat-array-no-kv'))
- it('repeat with array non-obj case', () => checkOutput(app, 'repeat-array-non-obj'))
- it('repeat watch case', () => checkOutput(app, 'repeat-watch'))
-
- it('id case', () => checkOutput(app, 'id'))
- it('dynamic id case', () => checkOutput(app, 'dynamic-id'))
-
- it('reset style case', () => checkOutput(app, 'reset-style'))
- it('dynamic type case', () => checkOutput(app, 'dynamic-type'))
- it('dynamic property case', () => checkOutput(app, 'dynamic-property'))
-
- it('bind subvm', () => checkOutput(app, 'subvm'))
- it('components options', () => checkOutput(app, 'components'))
- it('change data when created', () => checkOutput(app, 'created'))
- it('change data when ready', () => checkOutput(app, 'ready'))
-
- it('require 3rd', () => checkOutput(app, 'require'))
- it('a correct transformer version', () => checkOutput(app, 'transformer1'))
-
- it('promise case', () => checkOutput(app, 'promise'))
- })
-
- describe('invalid usage', function () {
- describe('strict mode', () => {
- const readSource = name => getCode('throws/' + name + '.source.js')
-
- let app
- beforeEach(() => { app = createApp(runtime) })
- afterEach(() => { app = null })
-
- it('global variable 1', () => {
- const sourceCode = readSource('global-variable1')
- expect(() => app.$create(sourceCode)).to.throw(ReferenceError)
- })
-
- it('global variable 2', () => {
- const sourceCode = readSource('global-variable2')
- expect(() => app.$create(sourceCode)).to.throw(ReferenceError)
- })
-
- it('global variable 3', () => {
- const sourceCode = readSource('global-variable3')
- expect(() => app.$create(sourceCode)).to.throw(ReferenceError)
- })
- })
- })
-
- describe('complex cases', function () {
- let app
-
- beforeEach(() => {
- app = createApp(runtime)
- callNativeHandler = (...args) => app._target.callNative(...args)
- })
-
- afterEach(() => {
- app = null
- callNativeHandler = function () {}
- })
-
- const readSource = name => getCode('complex/' + name + '.source.js')
- const readOutput = name => getCode('complex/' + name + '.output.js')
-
- it('computed case', () => {
- const name = 'computed'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$refresh({ x: 10 })
- expected.children[0].attr.value = 12
- expected.children[1].attr.value = 12
- expect(app.getRealRoot()).eql(expected)
-
- app.$refresh({ m: 10 })
- expected.children[0].attr.value = 20
- expected.children[1].attr.value = 20
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
-
- it('append-root-event case', () => {
- const name = 'append-root-event'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- const actual = app.getRealRoot()
- expect(actual).eql(expected)
-
- app.$fireEvent(app.doc.body.children[0].ref, 'click', {})
- const actual2 = app.getRealRoot()
- expect(actual2.children[0].attr.value).eql(2)
-
- app.$destroy()
- })
-
- it('use append tree and sub components', (done) => {
- const name = 'component-append-tree'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- const actual = app.getRealRoot()
- expect(actual).eql(expected)
-
- setTimeout(() => {
- const actual2 = app.getRealRoot()
- expect(actual2.children[0].children[0].attr.value).eql('timeout')
- expect(actual2.children[1].children[0].attr.value).eql('timeout')
- app.$destroy()
- done()
- }, 200)
- })
-
- it('repeat with array track-by case', () => {
- const name = 'repeat-track-by'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- app.$refresh({
- titlelist: [
- { text: 'Hello World2' },
- { text: 'Hello World1' }
- ]
- })
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
-
- it('if-refresh case', () => {
- const name = 'if-refresh'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- app.$refresh({ showTitle: false })
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
-
- it('if-repeat-refresh case', () => {
- const name = 'if-repeat-refresh'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- app.$refresh({
- titlelist: [
- { showTitle: false, title: 'Hello World1' },
- { showTitle: true, title: 'Hello World2' },
- { showTitle: true, title: 'Hello World3' }
- ]
- })
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
-
- it('click case', () => {
- const name = 'click'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$fireEvent(app.doc.body.children[0].ref, 'click', {})
-
- app.$destroy()
- })
-
- it('inline click case', () => {
- const name = 'inline-click'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$fireEvent(app.doc.body.children[0].ref, 'click', {})
-
- expected.children[0].attr.value = 'Hello World2'
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
-
- it('refresh twice', () => {
- const name = 'refresh2'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- expect(app.getRealRoot()).eql({ type: 'container' })
-
- app.$refresh({ ext: { showbar1: false }})
- app.$refresh({ ext: { showbar1: true }})
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
-
- it('a less wrong transformer version', () => {
- const name = 'transformer2'
- const sourceCode = readSource(name)
-
- const result = app.$create(sourceCode)
- expect(result).to.be.an.instanceof(Error)
- app.$destroy()
- })
-
- it('a bigger wrong transformer version', () => {
- const name = 'transformer3'
- const sourceCode = readSource(name)
-
- const result = app.$create(sourceCode)
- expect(result).to.be.an.instanceof(Error)
- app.$destroy()
- })
-
- it('input binding', () => {
- const name = 'input-binding'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- app.doc.body.children[0].attr.value = 'abcdefg'
- app.$fireEvent(app.doc.body.children[0].ref, 'change', {}, { attrs: { value: 'abcdefg' }})
- expected.children[0].attr.value = 'abcdefg'
- expected.children.push({ type: 'text', attr: { value: '1 - abcdefg' }})
- expect(app.getRealRoot()).eql(expected)
-
- app.doc.body.children[0].attr.value = '12345'
- app.$fireEvent(app.doc.body.children[0].ref, 'change', {}, { attrs: { value: '12345' }})
- expected.children[0].attr.value = '12345'
- expected.children.push({ type: 'text', attr: { value: '2 - 12345' }})
- expect(app.getRealRoot()).eql(expected)
-
- app.$destroy()
- })
- })
-
- describe('multi page cases', function () {
- let appA
- let appB
-
- beforeEach(() => {
- appA = createApp(runtime)
- appB = createApp(runtime)
-
- callNativeHandler = (id, ...args) => {
- switch (true) {
- case (appA.id === id) : { appA._target.callNative(id, ...args) } break
- case (appB.id === id) : { appB._target.callNative(id, ...args) } break
- }
- }
- })
-
- afterEach(() => {
- appA = null
- appB = null
- callNativeHandler = function () {}
- })
-
- const readSource = name => getCode('multi/' + name + '.source.js')
- const readOutput = name => getCode('multi/' + name + '.output.js')
-
- it('clear-module case', () => {
- const nameA = 'clear-moduleA'
- const nameB = 'clear-moduleB'
- const sourceCodeA = readSource(nameA)
- const sourceCodeB = readSource(nameB)
- const expectedA = eval('(' + readOutput(nameA) + ')')
- const expectedB = eval('(' + readOutput(nameB) + ')')
-
- appA.$create(sourceCodeA)
- appB.$create(sourceCodeB)
-
- expect(appB.getRealRoot()).eql(expectedB)
-
- appB.$destroy()
- appA.$fireEvent(appA.doc.body.children[0].ref, 'click', {})
- expect(appA.getRealRoot()).eql(expectedA)
-
- appA.$destroy()
- })
-
- it('clear-dep-target case', () => {
- const nameError = 'clear-dep-target-error'
- const nameFine = 'clear-dep-target-fine'
- const sourceCodeError = readSource(nameError)
- const sourceCodeFine = readSource(nameFine)
- const expectedFine = eval('(' + readOutput(nameFine) + ')')
-
- // should throw
- expect(() => { appA.$create(sourceCodeError) }).to.throw(TypeError)
- appA.$destroy()
-
- // not throw
- appB.$create(sourceCodeFine)
- expect(appB.getRealRoot()).eql(expectedFine)
-
- appB.$destroy()
- })
- })
-
- describe('timer & callNative signals', function () {
- let app
-
- const callNativeSpy = sinon.spy()
- function genCallNativeWrapper (count) {
- return (name, tasks, cbId) => {
- callNativeSpy(tasks)
- const length = callNativeSpy.callCount
- if (length > count) {
- return -1
- }
- return length
- }
- }
- beforeEach(() => {
- app = createApp(runtime)
- callNativeHandler = (...args) => app._target.callNative(...args)
- })
-
- afterEach(() => {
- app = null
- callNativeSpy.reset()
- callNativeHandler = function () {}
- })
-
- const readSource = name => getCode('signals/' + name + '.source.js')
- const readOutput = name => getCode('signals/' + name + '.output.js')
-
- it('use HTML5 timer API', function (done) {
- this.timeout(5000)
- const name = 'timer'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- setTimeout(_ => {
- expect(app.getRealRoot()).eql(expected)
- setTimeout(_ => {
- expected.children[0].attr.value = 'bar'
- expect(app.getRealRoot()).eql(expected)
- app.$destroy()
- done()
- }, 1000)
- }, 1000)
- })
-
- it('use modal API', function (done) {
- this.timeout(5000)
- const name = 'modal'
- const sourceCode = readSource(name)
- const outputCode = readOutput(name)
-
- app.$create(sourceCode)
- const expected = eval('(' + outputCode + ')')
- expect(app.getRealRoot()).eql(expected)
-
- // the test driver will hold the API callback about 1 sec
- setTimeout(_ => {
- expected.children[0].attr.value = 'bar'
- expect(app.getRealRoot()).eql(expected)
- app.$destroy()
- done()
- }, 1500)
- })
-
- it('signals control', function () {
- this.timeout(15000)
-
- const name = 'signals'
- const sourceCode = readSource(name)
-
- function run (calls) {
- callNativeSpy.reset()
- callNativeHandler = genCallNativeWrapper(calls)
- app.$create(sourceCode)
- app.$destroy()
- expect(callNativeSpy.callCount).eql(calls + 2)
- }
-
- for (let i = 5; i < 60; i++) {
- run(i)
- }
- })
-
- it('long signals control', function () {
- this.timeout(500000)
-
- const name = 'signals-long'
- const sourceCode = readSource(name)
-
- function run (calls) {
- callNativeSpy.reset()
- callNativeHandler = genCallNativeWrapper(calls)
- app.$create(sourceCode)
- app.$destroy()
- expect(callNativeSpy.callCount).eql(calls + 2)
- }
-
- run(10)
- run(30)
- run(90)
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/throws/global-variable1.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/throws/global-variable1.source.js b/html5/test/case/throws/global-variable1.source.js
deleted file mode 100644
index b60fc47..0000000
--- a/html5/test/case/throws/global-variable1.source.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-something = 'whatever'
-
-define('@weex-component/global-variable1', function (require, exports, module) {
-
- module.exports.template = { "type": "container" }
-
- module.exports.style = {}
-
- module.exports = {
- ready: function () {
- console.log('I an ready')
- }
- }
-
-})
-
-bootstrap('@weex-component/global-variable1')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/throws/global-variable2.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/throws/global-variable2.source.js b/html5/test/case/throws/global-variable2.source.js
deleted file mode 100644
index b1b4f4e..0000000
--- a/html5/test/case/throws/global-variable2.source.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/global-variable2', function (require, exports, module) {
-
- module.exports.template = { "type": "container" }
-
- module.exports.style = {}
-
- module.exports = {
- ready: function () {
- abc = 'abc'
- }
- }
-
-})
-
-bootstrap('@weex-component/global-variable2')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/throws/global-variable3.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/throws/global-variable3.source.js b/html5/test/case/throws/global-variable3.source.js
deleted file mode 100644
index e010ca1..0000000
--- a/html5/test/case/throws/global-variable3.source.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/global-variable3', function (require, exports, module) {
-
- module.exports.template = { "type": "container" }
-
- module.exports.style = {}
-
- module.exports = {
- data: function() {
- return {
- lists: ['A', 'B', 'C']
- }
- },
- ready: function () {
- for (i = 0; i < this.lists.length; ++i) {
- console.log(this.lists[i])
- }
- }
- }
-
-})
-
-bootstrap('@weex-component/global-variable3')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/api/methods.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/api/methods.js b/html5/test/unit/default/api/methods.js
deleted file mode 100644
index ec458ff..0000000
--- a/html5/test/unit/default/api/methods.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import '../../../../shared/console'
-import * as modules from '../../../../frameworks/legacy/api/modules'
-import * as methods from '../../../../frameworks/legacy/api/methods'
-import Differ from '../../../../frameworks/legacy/app/differ'
-import { initModules, requireModule, clearModules, initMethods } from '../../../../frameworks/legacy/app/register'
-
-function Vm () {
-}
-
-describe('built-in methods', () => {
- let vm
- const requireSpy = sinon.spy()
- const moduleSpy = sinon.spy()
-
- before(() => {
- clearModules()
-
- initModules(modules)
- initMethods(Vm, methods)
-
- vm = new Vm()
-
- Object.assign(vm, {
- _app: {
- options: {
- debug: true,
- bundleUrl: 'path_to_bundleUrl'
- },
- differ: new Differ(),
- requireModule: (name) => {
- requireSpy(name)
- const module = requireModule(this, name)
- const mockModule = {}
- for (const moduleName in module) {
- mockModule[moduleName] = function (...args) {
- moduleSpy(...args)
- if (typeof args[args.length - 1] === 'function') {
- args[args.length - 1]()
- }
- }
- }
- return mockModule
- }
- },
- _setStyle: function () {},
- _ids: {
- a: {
- vm: {},
- el: {
- ref: '_root'
- }
- }
- }
- })
-
- for (const apiName in vm) {
- if (apiName.indexOf('$') === 0) {
- vm[apiName] = sinon.spy(vm, apiName)
- }
- }
- sinon.stub(console, 'warn')
- })
-
- beforeEach(() => {
- requireSpy.reset()
- moduleSpy.reset()
- console.warn.reset()
- })
-
- after(() => {
- clearModules()
- console.warn.restore()
- })
-
- it('$', () => {
- expect(vm.$('a')).to.deep.equal(vm._ids.a.vm)
- expect(vm.$('invalid')).to.be.undefined
- expect(console.warn.callCount).to.be.equal(2)
- })
-
- it('$el', () => {
- expect(vm.$el('a')).to.deep.equal(vm._ids.a.el)
- expect(vm.$el('invalid')).to.be.undefined
- })
-
- it('$vm', () => {
- expect(vm.$vm('a')).to.deep.equal(vm._ids.a.vm)
- expect(vm.$vm('invalid')).to.be.undefined
- })
-
- it('$renderThen', () => {
- const fnSpy = sinon.spy()
- vm.$renderThen(fnSpy)
- vm._app.differ.flush()
- expect(fnSpy.callCount).to.be.equal(1)
- })
-
- it('$scrollTo', () => {
- vm.$scrollTo('a', 100)
- expect(vm.$scrollTo('invalid', 100)).to.be.undefined
- expect(requireSpy.firstCall.args[0]).to.be.equal('dom')
- expect(moduleSpy.firstCall.args.length).to.be.equal(2)
- })
-
- it('$transition', () => {
- const callback = sinon.spy()
- vm.$transition('a', { styles: { color: '#FF0000' }}, callback)
- expect(vm.$transition('invalid', {})).to.be.undefined
- expect(requireSpy.firstCall.args[0]).eql('animation')
- expect(moduleSpy.firstCall.args.length).eql(3)
- expect(moduleSpy.firstCall.args[0]).eql('_root')
- expect(moduleSpy.firstCall.args[1]).eql({
- styles: { color: '#FF0000' }
- })
- expect(callback.callCount).eql(1)
- })
-
- it('$getConfig', () => {
- const config = vm.$getConfig()
- expect(config).eql({
- debug: true,
- bundleUrl: 'path_to_bundleUrl'
- })
-
- const configSpy = sinon.spy()
- vm.$getConfig(configSpy)
- expect(console.warn.callCount).to.be.equal(1)
- expect(configSpy.args.length).eql(1)
- expect(configSpy.args[0][0]).eql({
- debug: true,
- bundleUrl: 'path_to_bundleUrl'
- })
- })
-
- it('$sendHttp', () => {
- const callback = sinon.spy()
- vm.$sendHttp({ a: 1 }, callback)
- expect(requireSpy.firstCall.args[0]).eql('stream')
- expect(moduleSpy.firstCall.args.length).eql(2)
- expect(moduleSpy.firstCall.args).eql([{ a: 1 }, callback])
- expect(callback.callCount).eql(1)
- })
-
- it('$openURL', () => {
- vm.$openURL('url')
- expect(requireSpy.firstCall.args[0]).eql('event')
- expect(moduleSpy.firstCall.args.length).eql(1)
- expect(moduleSpy.firstCall.args).eql(['url'])
- })
-
- it('$setTitle', () => {
- vm.$setTitle('title')
- expect(requireSpy.firstCall.args[0]).eql('pageInfo')
- expect(moduleSpy.firstCall.args.length).eql(1)
- expect(moduleSpy.firstCall.args).eql(['title'])
- })
-
- it('$call', () => {
- vm.$call('event', 'openURL', 'url')
- expect(vm.$call('invalid', 'module')).to.be.undefined
- expect(vm.$call('event', 'invalid')).to.be.undefined
- expect(requireSpy.firstCall.args[0]).eql('event')
- expect(moduleSpy.firstCall.args.length).eql(1)
- expect(moduleSpy.firstCall.args[0]).eql('url')
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/api/modules.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/api/modules.js b/html5/test/unit/default/api/modules.js
deleted file mode 100644
index 1adf66b..0000000
--- a/html5/test/unit/default/api/modules.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import * as modules from '../../../../frameworks/legacy/api/modules'
-import { initModules, requireModule, clearModules } from '../../../../frameworks/legacy/app/register'
-
-describe('built-in modules', () => {
- before(() => {
- clearModules()
- })
-
- after(() => {
- clearModules()
- })
-
- it('have keys', () => {
- const app = {}
- initModules(modules)
- expect(requireModule(app, 'dom')).to.have.all.keys('scrollToElement')
- expect(requireModule(app, 'stream')).to.have.all.keys('sendHttp')
- expect(requireModule(app, 'event')).to.have.all.keys('openURL')
- expect(requireModule(app, 'pageInfo')).to.have.all.keys('setTitle')
- expect(requireModule(app, 'animation')).to.have.all.keys('transition')
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/app/bundle.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/app/bundle.js b/html5/test/unit/default/app/bundle.js
deleted file mode 100644
index f44b2f6..0000000
--- a/html5/test/unit/default/app/bundle.js
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as bundle from '../../../../frameworks/legacy/app/bundle'
-import * as register from '../../../../frameworks/legacy/app/register'
-import { removeWeexPrefix } from '../../../../frameworks/legacy/util'
-import { Document } from '../../../../runtime/vdom'
-import Listener from '../../../../runtime/bridge/Listener'
-
-describe('parsing a bundle file', () => {
- const componentTemplate = {
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- }
- }]
- }
-
- before(() => {
- sinon.stub(console, 'info')
- sinon.stub(console, 'warn')
- sinon.stub(console, 'error')
- sinon.stub(console, 'debug')
- })
-
- after(() => {
- console.info.restore()
- console.warn.restore()
- console.error.restore()
- console.debug.restore()
- })
-
- describe('use define/bootstrap', () => {
- let app
- let callTasksSpy
-
- before(() => {
- const id = Date.now()
- callTasksSpy = sinon.spy()
-
- const doc = new Document(id, '', (tasks) => {
- app.callTasks(tasks)
- })
-
- app = {
- id, doc,
- customComponentMap: {},
- commonModules: {},
- callbacks: {},
- callTasks: callTasksSpy,
- requireModule: function (name) {
- return register.requireModule(this, name)
- }
- }
- })
-
- afterEach(() => {
- callTasksSpy.reset()
- })
-
- describe('define', () => {
- it('a weex component with factory and deps', () => {
- bundle.defineFn(app, '@weex-component/a', (require, exports, module) => {
- module.exports = {
- template: componentTemplate
- }
- })
- bundle.defineFn(app, '@weex-component/aa', [], (require, exports, module) => {
- module.exports = {
- template: componentTemplate
- }
- })
-
- expect(app.customComponentMap['a'].template).to.deep.equal(componentTemplate)
- expect(app.customComponentMap['aa'].template).to.deep.equal(componentTemplate)
- })
-
- it('a weex component with definition object and deps', () => {
- bundle.defineFn(app, '@weex-component/aaa', {
- template: componentTemplate
- })
- bundle.defineFn(app, '@weex-component/aaaa', [], {
- template: componentTemplate
- })
-
- expect(app.customComponentMap['aaa'].template).to.deep.equal(componentTemplate)
- expect(app.customComponentMap['aaaa'].template).to.deep.equal(componentTemplate)
- })
-
- it('a weex module', () => {
- const methods = [{
- name: 'createBody',
- args: []
- }]
-
- bundle.defineFn(app, '@weex-module/dom', (require, exports, module) => {
- module.exports = methods
- })
- })
-
- it('a normal module', () => {
- bundle.defineFn(app, './a', (require, exports, module) => {
- exports.version = '0.1'
- })
- })
-
- it('a npm module', () => {
- bundle.defineFn(app, 'lib-httpurl', (require, exports, module) => {
- exports.version = '0.2'
- })
- })
-
- it('a CMD module', () => {
- bundle.defineFn(app, 'kg/base', [], (require, exports, module) => {
- exports.version = '0.3'
- })
- })
- })
-
- describe('require', () => {
- it('a weex component', (done) => {
- bundle.defineFn(app, '@weex-component/b', (require, exports, module) => {
- const componentA = require('@weex-component/a')
-
- expect(componentA.template).to.be.equal(componentTemplate)
- done()
- })
- })
-
- it('a weex module', (done) => {
- // eslint-disable-next-line camelcase
- const __weex_require__ = name => register.requireModule(app, removeWeexPrefix(name))
- bundle.defineFn(app, '@weex-component/c', (require, exports, module) => {
- const dom = require('@weex-module/dom')
- expect(dom.createBody).to.be.a('function')
- const dom2 = __weex_require__('dom')
- expect(dom2.createBody).to.be.a('function')
- const dom3 = __weex_require__('@weex-module/dom')
- expect(dom3.createBody).to.be.a('function')
- done()
- })
- })
-
- it('a normal module', (done) => {
- bundle.defineFn(app, '@weex-component/d', (require, exports, module) => {
- const a = require('./a')
-
- expect(a.version).to.be.equal('0.1')
- done()
- })
- })
-
- it('a npm module', (done) => {
- bundle.defineFn(app, '@weex-component/e', (require, exports, module) => {
- const HttpUrl = require('lib-httpurl')
-
- expect(HttpUrl.version).to.be.equal('0.2')
- done()
- })
- })
-
- it('a CMD module', (done) => {
- bundle.defineFn(app, 'kg/sample', ['kg/base'], (require, exports, module) => {
- const base = require('kg/base')
-
- expect(base.version).to.be.equal('0.3')
- done()
- })
- })
- })
-
- describe('bootstrap', () => {
- const ready = sinon.spy()
-
- before(() => {
- global.transformerVersion = '>=0.1 <1.0'
- bundle.defineFn(app, '@weex-component/main', (require, exports, module) => {
- module.exports = {
- template: componentTemplate,
- ready: ready
- }
- })
- })
-
- after(() => {
- global.transformerVersion = undefined
- })
-
- it('not a weex component', () => {
- const result = bundle.bootstrap(app, '@weex-module/dom')
- expect(result).instanceof(Error)
- })
-
- it('a weex component', () => {
- const result = bundle.bootstrap(
- app,
- '@weex-component/main',
- { transformerVersion: '0.1.99' }
- )
-
- expect(result).not.instanceof(Error)
- expect(callTasksSpy.calledTwice).to.be.true
-
- expect(ready.calledOnce).to.be.true
- const task1 = callTasksSpy.firstCall.args[0][0]
- expect(task1.module).to.be.equal('dom')
- expect(task1.method).to.be.equal('createBody')
- expect(task1.args[0]).to.deep.equal({
- type: 'container',
- ref: '_root',
- attr: {},
- style: {}
- })
-
- const task2 = callTasksSpy.secondCall.args[0][0]
- expect(task2.module).to.be.equal('dom')
- expect(task2.method).to.be.equal('addElement')
- expect(task2.args[1]).to.deep.equal({
- type: 'text',
- ref: app.doc.body.children[0].ref,
- attr: {
- value: 'Hello World'
- },
- style: {}
- })
- expect(task2.args[0]).to.be.equal('_root')
- expect(task2.args[2]).to.be.equal(-1)
- })
-
- it('with a less wrong transformer version', () => {
- const result = bundle.bootstrap(
- app,
- '@weex-component/main',
- { transformerVersion: '0.0.1' }
- )
- expect(result).instanceof(Error)
- })
-
- it('with a bigger wrong transformer version', () => {
- const result = bundle.bootstrap(
- app,
- '@weex-component/main',
- { transformerVersion: '9.9.9' }
- )
- expect(result).instanceof(Error)
- })
-
- it('with viewport config', () => {
- bundle.bootstrap(
- app,
- '@weex-component/undefined',
- {
- viewport: { width: 640 }
- }
- )
- expect(callTasksSpy.callCount).to.be.equal(1)
- const tasks = callTasksSpy.lastCall.args[0]
- expect(tasks[0].module).to.be.equal('meta')
- expect(tasks[0].method).to.be.equal('setViewport')
- expect(tasks[0].args).to.deep.equal([{ width: 640 }])
- })
- })
- })
-
- describe('use regsiter/render(backward compatibility)', () => {
- let app
- let callTasksSpy
- let readySpy
- const template = {
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- }
- }, {
- type: 'custom'
- }]
- }
-
- before(() => {
- const id = Date.now()
- callTasksSpy = sinon.spy()
- readySpy = sinon.spy()
-
- const doc = new Document(id, '', (tasks, callback) => {
- app.callTasks(tasks, callback)
- }, Listener)
-
- app = {
- id, doc,
- customComponentMap: {},
- callbacks: {},
- callTasks: (tasks, callback) => {
- callTasksSpy(tasks)
- callback && callback()
- },
- requireModule: function (name) {
- return register.requireModule(this, name)
- }
- }
-
- Object.assign(app, bundle)
- })
-
- afterEach(() => {
- callTasksSpy.reset()
- })
-
- describe('register', () => {
- const readyfn = function () {
- readySpy(this)
- }
-
- it('a component', () => {
- bundle.register(app, 'custom', {
- template: componentTemplate,
- data: {
- b: 'c'
- },
- methods: {
- ready: readyfn
- }
- })
-
- bundle.register(app, 'main', {
- template: template,
- data: {
- a: 'b'
- },
- methods: {
- ready: readyfn
- }
- })
-
- expect(app.customComponentMap['custom'].template)
- .to.deep.equal(componentTemplate)
- expect(app.customComponentMap['main'].template)
- .to.deep.equal(template)
- })
- })
- })
-
- describe('use define/require(backward compatibility)', () => {
- let app
- let callTasksSpy
-
- before(() => {
- const id = Date.now()
- callTasksSpy = sinon.spy()
-
- const doc = new Document(id, '', (tasks, callback) => {
- app.callTasks(tasks, callback)
- }, Listener)
-
- app = {
- id, doc,
- customComponentMap: {},
- callbacks: {},
- callTasks: (tasks, callback) => {
- callTasksSpy(tasks)
- callback && callback()
- },
- requireModule: function (name) {
- return register.requireModule(this, name)
- }
- }
- })
-
- afterEach(() => {
- callTasksSpy.reset()
- })
-
- describe('define(old)', () => {
- it('a component', () => {
- bundle.defineFn(app, 'main', (require, exports, module) => {
- module.exports = {
- template: componentTemplate
- }
- })
- expect(app.customComponentMap['main'].template)
- .to.deep.equal(componentTemplate)
- })
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/app/ctrl.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/app/ctrl.js b/html5/test/unit/default/app/ctrl.js
deleted file mode 100644
index 4e3163b..0000000
--- a/html5/test/unit/default/app/ctrl.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as ctrl from '../../../../frameworks/legacy/app/ctrl'
-import Differ from '../../../../frameworks/legacy/app/differ'
-import { Document } from '../../../../runtime/vdom'
-
-describe('the api of app', () => {
- let app
- let spy1
- let spy2
-
- function createApp () {
- const id = Date.now()
-
- const app = {
- id: id,
- customComponentMap: {},
- registerComponent: function () {},
- // define: sinon.spy(),
- // bootstrap: sinon.stub(),
- vm: {},
- differ: new Differ(id)
- }
-
- app.doc = new Document(id, '', spy1)
- app.doc.createBody('div')
-
- app.doc.taskCenter.callbackManager.add(spy2)
- // app.bootstrap.returns()
-
- return app
- }
-
- before(() => {
- spy1 = sinon.spy()
- spy2 = sinon.spy()
- app = createApp()
- !console.debug && (console.debug = function () {})
- })
-
- afterEach(() => {
- spy1.reset()
- // spy2.reset()
- })
-
- describe('init', () => {
- before(() => {
- global.transformerVersion = '0.1.3'
- })
-
- after(() => {
- global.transformerVersion = undefined
- })
-
- it('a simple bundle', () => {
- app.requireModule = () => {}
- ctrl.init(app, `
- define('main', function (r, e, m) {
- e.template = {
- "type": "container",
- "children": [{
- "type": "text",
- "attr": {
- "value": "Hello World"
- }
- }]
- }
- })
-
- bootstrap('main')
- `)
-
- // expect(app.define.calledOnce).to.be.true
- // expect(app.bootstrap.calledOnce).to.be.true
-
- const task = spy1.lastCall.args[0][0]
- expect(task.module).to.be.equal('dom')
- expect(task.method).to.be.equal('createFinish')
- expect(task.args.length).to.be.equal(0)
- })
- })
-
- describe('getRootElement', () => {
- it('from a simple', () => {
- const json = ctrl.getRootElement(app)
- expect(json.ref).eql('_root')
- expect(json.type).eql('div')
- expect(json.children.length).eql(1)
- })
- it('from empty object', () => {
- expect(ctrl.getRootElement({})).to.deep.equal({})
- })
- })
-
- describe('fireEvent', () => {
- it('click on root', () => {
- ctrl.fireEvent(app, '_root', 'click')
- const task = spy1.lastCall.args[0][0]
- expect(task.module).to.be.equal('dom')
- expect(task.method).to.be.equal('updateFinish')
- expect(task.args.length).to.be.equal(0)
- })
-
- it('error', () => {
- const result = ctrl.fireEvent(app, '_rootTest', 'click')
- expect(result).to.be.an.instanceof(Error)
- })
-
- it('click on both root & _rootTest', () => {
- ctrl.fireEvent(app, ['_root', '_rootTest'], 'click')
- const task = spy1.lastCall.args[0][0]
- expect(task.module).to.be.equal('dom')
- expect(task.method).to.be.equal('updateFinish')
- expect(task.args.length).to.be.equal(0)
- })
- })
-
- describe('callback', () => {
- it('with a simple data', () => {
- const data = { a: 'b' }
- ctrl.callback(app, '1', data, true)
- expect(spy2.calledOnce).to.be.true
-
- const task = spy1.firstCall.args[0][0]
- expect(task.module).to.be.equal('dom')
- expect(task.method).to.be.equal('updateFinish')
- expect(task.args.length).to.be.equal(0)
- })
-
- it('multiple called', () => {
- const data = { a: 'b' }
- ctrl.callback(app, '1', data, true)
- expect(spy2.calledTwice).to.be.true
-
- ctrl.callback(app, '1', data, false)
- expect(spy2.calledThrice).to.be.true
- })
-
- it('error', () => {
- const data = null
- const result = ctrl.callback(app, '1', data, true)
- expect(result).to.be.an.instanceof(Error)
- })
- })
-
- describe('refreshData', () => {
- it('a simple data', () => {
- const data = { b: 'c' }
- ctrl.refresh(app, data)
- expect(app.vm.b).to.deep.equal(data.b)
-
- const task = spy1.lastCall.args[0][0]
- expect(task.module).to.be.equal('dom')
- expect(task.method).to.be.equal('refreshFinish')
- expect(task.args.length).to.be.equal(0)
- })
-
- it('call refresh with refreshData function', () => {
- app.vm.refreshData = function () {
- app.vm.data = 'hello'
- }
- const data = { b: 'c' }
- ctrl.refresh(app, data)
- expect(app.vm.data).to.equal('hello')
- })
-
- it('error', () => {
- const data = null
- const result = ctrl.refresh(app, data)
- expect(result).to.be.an.instanceof(Error)
- })
- })
-
- describe('destory', () => {
- it('the simple data', () => {
- ctrl.destroy(app)
- expect(app.id).to.be.empty
- expect(app.blocks).to.be.null
- expect(app.vm).to.be.null
- expect(app.doc).to.be.null
- expect(app.customComponentMap).to.be.null
- })
- it('the incomplete data', () => {
- const appx = createApp()
- delete appx.vm
- ctrl.destroy(appx)
- expect(appx.id).to.be.empty
- expect(appx.blocks).to.be.null
- expect(appx.vm).to.be.null
- expect(appx.doc).to.be.null
- expect(appx.customComponentMap).to.be.null
- })
- it('clear vms', () => {
- const appy = createApp()
- appy.vm = {
- $emit () {},
- _watchers: [{ teardown () {} }],
- _childrenVms: [{ $emit () {} }]
- }
- ctrl.destroy(appy)
- expect(appy.id).to.be.empty
- expect(appy.blocks).to.be.null
- expect(appy.vm).to.be.null
- expect(appy.doc).to.be.null
- expect(appy.customComponentMap).to.be.null
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/app/downgrade.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/app/downgrade.js b/html5/test/unit/default/app/downgrade.js
deleted file mode 100644
index 562d0d7..0000000
--- a/html5/test/unit/default/app/downgrade.js
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import * as Downgrade from '../../../../frameworks/legacy/app/downgrade'
-
-describe('downgrade', () => {
- describe('normalizeVersion', () => {
- it('should be normalize version format', () => {
- const cases = [
- ['', '0.0.0'],
- ['1', '1.0.0'],
- ['1.0', '1.0.0'],
- ['1.0.0', '1.0.0'],
- ['1.0.0.0', '1.0.0'],
- ['1.3.4.1230', '1.3.4']
- ]
-
- cases.map(function (item, index) {
- const input = item[0]
- const should = item[1]
- const test = Downgrade.normalizeVersion(input)
-
- expect(test).to.be.equal(should)
- })
- })
-
- it('invalid version format', () => {
- expect(Downgrade.normalizeVersion([])).to.be.equal('0.0.0')
- expect(Downgrade.normalizeVersion({})).to.be.equal('0.0.0')
- expect(Downgrade.normalizeVersion(2.0)).to.be.equal('0.0.0')
- })
- })
-
- describe('getError', () => {
- it('should be get right error message', () => {
- const cases = [
- [1000, 'osName', 'iphone', 'iphone'],
- [1001, 'osVersion', '1.0.0', '1.0.0'],
- [1002, 'appVersion', '3.2.2', '>3.0.0'],
- [1003, 'weexVersion', '1.2.3', '>=1.2.3'],
- [1004, 'deviceModel', '1.0.0', ['1.0.0']]
- ]
-
- cases.map(function (item, index) {
- const code = item[0]
- const key = item[1]
- const val = item[2]
- const criteria = item[3]
- const test = Downgrade.getError(key, val, criteria)
-
- expect(test.code).to.be.equal(code)
- expect(test.errorType).to.be.equal(1)
- expect(test.isDowngrade).to.be.equal(true)
- })
- })
- })
-
- describe('check', () => {
- it('should be match config', () => {
- const deviceInfo = {
- platform: 'ios',
- osVersion: '9.2.1',
- appVersion: '5.4.0',
- weexVersion: '1.3.0',
- deviceModel: 'iPhone6.2'
- }
-
- const cases = [
- [{ ios: { osVersion: '>=9' }}, true],
- [{ ios: { appVersion: '<10.0.0' }}, true],
- [{ ios: { appVersion: '>10.0.0' }}, false],
- [{ ios: { appVersion: '5.4.0' }}, true],
- [{ ios: { deviceModel: 'ABC' }}, false],
- [{ ios: { deviceModel: 'iPhone6.2' }}, true],
- [{ ios: { deviceModel: ['iPhone6.2', 'ABC'] }}, true],
- [{ ios: { osVersion: '>9', deviceModel: ['iPhone6.2', 'ABC'] }}, true],
- [{ ios: { osVersion: '>=9', deviceModel: ['iPhone6.2', 'ABC'] }}, true],
- [{ ios: { weexVersion: '<=9' }}, true]
- ]
-
- cases.map(function (item, index) {
- const criteria = item[0]
- const should = item[1]
- const test = Downgrade.check(criteria, deviceInfo)
-
- expect(test.isDowngrade).to.be.equal(should)
- })
- })
-
- it('should be match config without app version', () => {
- const deviceInfo = {
- platform: 'iOS',
- osVersion: '9.2',
- weexVersion: '1.3.0',
- deviceModel: 'iPhone6.2'
- }
-
- const cases = [
- [{ ios: { osVersion: '>=9' }}, true],
- [{ ios: { osVersion: '>8' }}, true],
- [{ ios: { appVersion: '<10.0.0' }}, false],
- [{ ios: { appVersion: '>10.0.0' }}, false],
- [{ ios: { appVersion: '5.4.0' }}, false],
- [{ ios: { deviceModel: 'ABC' }}, false],
- [{ ios: { deviceModel: 'iPhone6.2' }}, true],
- [{ ios: { deviceModel: ['MF353TA/A', 'ABC'] }}, false],
- [{ ios: { osVersion: '>9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
- [{ ios: { osVersion: '>=9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
- [{ ios: { weexVersion: '<=9' }}, true],
- [{ ios: { weexVersion: '>=1.3.0' }}, true],
- [{ ios: { weexVersion: '>=1.3.0' }}, true]
- ]
-
- cases.map(function (item, index) {
- const criteria = item[0]
- const should = item[1]
- const test = Downgrade.check(criteria, deviceInfo)
-
- expect(test.isDowngrade).to.be.equal(should)
- })
- })
-
- it('should be match config and deviceInfo from global var', () => {
- global.WXEnvironment = {
- platform: 'iOS',
- osVersion: '9.2',
- appVersion: '5.4.0',
- weexVersion: '1.3.0',
- deviceModel: 'iPhone6.2'
- }
-
- const cases = [
- [{ ios: { osVersion: '>=9' }}, true],
- [{ ios: { osVersion: '>8' }}, true],
- [{ ios: { appVersion: '<10.0.0' }}, true],
- [{ ios: { appVersion: '>10.0.0' }}, false],
- [{ ios: { appVersion: '5.4.0' }}, true],
- [{ ios: { deviceModel: 'ABC' }}, false],
- [{ ios: { deviceModel: 'iPhone6.2' }}, true],
- [{ ios: { deviceModel: ['MF353TA/A', 'ABC'] }}, false],
- [{ ios: { osVersion: '>9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
- [{ ios: { osVersion: '>=9', deviceModel: ['MF353TA/A', 'ABC'] }}, true],
- [{ ios: { weexVersion: '<=9' }}, true],
- [{ ios: { weexVersion: '>=1.3.0' }}, true],
- [{ ios: { weexVersion: '>=1.3.0' }}, true]
- ]
-
- cases.map(function (item, index) {
- const criteria = item[0]
- const should = item[1]
- const test = Downgrade.check(criteria)
-
- expect(test.isDowngrade).to.be.equal(should)
- })
- })
-
- it('should be using using custom check', () => {
- const deviceInfo = {
- platform: 'iOS',
- osVersion: '9.2',
- appVersion: '5.4.0',
- weexVersion: '1.3.0',
- deviceModel: 'iPhone6.2'
- }
-
- const cases = [
- [
- function () {
-
- }, false
- ],
- [
- function () {
- return true
- }, true
- ],
- [
- function () {
- return false
- }, false
- ],
- [
- function (deviceInfo) {
- if (deviceInfo.platform === 'iOS') {
- return true
- }
- return false
- }, true
- ],
- [
- function (deviceInfo, tools) {
- if (deviceInfo.osVersion === '9.2') {
- return true
- }
- return false
- }, true
- ],
- [
- function (deviceInfo, tools) {
- if (tools.normalizeVersion(deviceInfo.osVersion) === '9.2.0') {
- return true
- }
- return false
- }, true
- ],
- [
- function (deviceInfo, tools) {
- return tools.semver.satisfies(tools.normalizeVersion(deviceInfo.osVersion), '9.2.0')
- }, true
- ],
- [
- function (deviceInfo, tools) {
- return tools.semver.satisfies(deviceInfo.appVersion, '5.4.0')
- }, true
- ],
- [
- function (deviceInfo, tools) {
- return tools.semver.satisfies(deviceInfo.weexVersion, '1.3.0')
- }, true
- ],
- [
- function (deviceInfo, tools) {
- return deviceInfo.deviceModel === 'iPhone6.2'
- }, true
- ],
- [
- function (deviceInfo, tools) {
- return deviceInfo.deviceModel === 'AndroidPad'
- }, false
- ],
- [
- function (deviceInfo, tools) {
- return ['iPhone6.2', 'iPhone7.1'].indexOf(deviceInfo.deviceModel) >= 0
- }, true
- ]
- ]
-
- cases.map(function (item, index) {
- const criteria = item[0]
- const should = item[1]
- const test = Downgrade.check(criteria, deviceInfo)
-
- expect(test.isDowngrade).to.be.equal(should)
- })
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/app/index.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/app/index.js b/html5/test/unit/default/app/index.js
deleted file mode 100644
index e0e2c3f..0000000
--- a/html5/test/unit/default/app/index.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import App from '../../../../frameworks/legacy/app'
-import { Element, Document } from '../../../../runtime/vdom'
-
-describe('App Instance', () => {
- const oriDocumentHandler = Document.handler
- const sendTasksSpy = sinon.spy()
- let app
-
- beforeEach(() => {
- Document.handler = sendTasksSpy
- const id = Date.now() + ''
- app = new App(id, {})
- })
-
- afterEach(() => {
- Document.handler = oriDocumentHandler
- })
-
- describe('normal check', () => {
- it('is a class', () => {
- expect(App).to.be.an('function')
- })
-
- it('being created', () => {
- expect(app).to.be.an('object')
- expect(app).to.be.instanceof(App)
- })
-
- it('with some apis', () => {
- expect(app.requireModule).a.function
- expect(app.updateActions).a.function
- expect(app.callTasks).a.function
- })
-
- it('run apis', () => {
- expect(app.requireModule('stream')).to.deep.equal({})
- expect(app.updateActions()).to.be.undefined
- expect(app.callTasks([])).to.be.undefined
- })
- })
-
- describe('call tasks', () => {
- it('with no args & callback', () => {
- const tasks = [{
- module: 'dom',
- method: 'createBody',
- args: []
- }]
-
- app.callTasks(tasks)
- expect(sendTasksSpy.lastCall.args[1]).to.deep.equal(tasks)
- })
-
- it('with callback', (done) => {
- const tasks = [{
- module: 'dom',
- method: 'createBody',
- args: []
- }]
-
- app.callTasks(tasks)
- expect(sendTasksSpy.lastCall.args[1]).to.deep.equal(tasks)
- done()
- })
-
- it('with function arg', (done) => {
- const callbackId = '1'
-
- const tasks = [{
- module: 'dom',
- method: 'createBody',
- args: [() => {}]
- }]
-
- app.callTasks(tasks)
- expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'createBody',
- args: [callbackId]
- }])
- done()
- })
-
- it('with node arg', (done) => {
- const node = new Element()
- node.ref = '1'
-
- const tasks = [{
- module: 'dom',
- method: 'createBody',
- args: [node]
- }]
-
- app.callTasks(tasks)
- expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'createBody',
- args: [node.ref]
- }])
- done()
- })
-
- it('with callback after close', (done) => {
- const callbackId = '1'
-
- const tasks = [{
- module: 'dom',
- method: 'createBody',
- args: [() => {}]
- }]
-
- app.doc.close()
-
- app.callTasks(tasks)
- expect(sendTasksSpy.lastCall.args[1]).to.deep.equal([{
- module: 'dom',
- method: 'createBody',
- args: [callbackId]
- }])
- done()
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/app/register.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/app/register.js b/html5/test/unit/default/app/register.js
deleted file mode 100644
index 6c23982..0000000
--- a/html5/test/unit/default/app/register.js
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import {
- getModule,
- clearModules,
- initModules,
- initMethods,
- requireModule,
- requireCustomComponent,
- registerCustomComponent
-} from '../../../../frameworks/legacy/app/register'
-
-function Ctx () {
- this.customComponentMap = {}
- this.callTasks = sinon.spy()
-}
-
-describe('register', () => {
- let ctx
-
- before(() => {
- clearModules()
- ctx = new Ctx()
- })
-
- after(() => {
- clearModules()
- })
-
- describe('component', () => {
- it('with exports', () => {
- const def = {
- a: 'b'
- }
- registerCustomComponent(ctx, 'componentA', def)
- expect(requireCustomComponent(ctx, 'componentA')).to.deep.equal(def)
- })
-
- it('with a existing name', () => {
- const def = {
- a: 'b'
- }
- sinon.stub(console, 'error')
- registerCustomComponent(ctx, 'componentA', def)
- expect(console.error).callCount(1)
- console.error.restore()
- })
- })
-
- describe('module', () => {
- it('with a old format', () => {
- initModules({
- dom: [
- 'createBody',
- 'addElement'
- ]
- })
- expect(requireModule(ctx, 'dom')).to.have.any.keys('createBody', 'addElement')
- })
-
- it('with a new format', () => {
- initModules({
- dom: [
- {
- name: 'moveElement',
- args: ['string', 'string']
- }
- ],
- stream: [
- {
- name: 'sendMtop',
- args: ['object', 'function']
- }
- ]
- })
- expect(requireModule(ctx, 'dom')).to.have.all.keys('createBody', 'addElement', 'moveElement')
- expect(requireModule(ctx, 'stream')).to.have.all.keys('sendMtop')
- })
-
- it('with a existed module.method', () => {
- initModules({
- dom: [
- {
- name: 'moveElement',
- args: ['string', 'string', 'string']
- }
- ]
- }, true)
- initModules({
- stream: [
- {
- name: 'sendMtop',
- args: ['object']
- }
- ]
- })
- expect(getModule('dom').moveElement).to.deep.equal({
- name: 'moveElement',
- args: ['string', 'string', 'string']
- })
-
- expect(getModule('stream').sendMtop).to.deep.equal({
- name: 'sendMtop',
- args: ['object', 'function']
- })
- })
-
- it('run registered module', () => {
- initModules({
- event: [{
- name: 'openURL',
- args: ['string']
- }]
- })
- const event = requireModule(ctx, 'event')
- expect(event).to.have.keys('openURL')
-
- event.openURL('http://test.com')
- expect(ctx.callTasks.callCount).to.be.equal(1)
- })
- })
-
- describe('api', () => {
- it('a common api', () => {
- initMethods(Ctx, {
- $test1: function () {
- return {
- ctx: this,
- value: 'test1'
- }
- },
- $test2: function () {
- return {
- ctx: this,
- value: 'test2'
- }
- }
- })
-
- expect(ctx.$test1).to.be.a('Function')
- expect(ctx.$test1()).to.deep.equal({
- ctx: ctx,
- value: 'test1'
- })
- expect(ctx.$test2).to.be.an('Function')
- expect(ctx.$test2()).to.deep.equal({
- ctx: ctx,
- value: 'test2'
- })
- })
-
- it('override api', () => {
- initMethods(Ctx, {
- $override: function () {
- return {
- ctx: this,
- value: 'first'
- }
- }
- })
-
- initMethods(Ctx, {
- $override: function () {
- return {
- ctx: this,
- value: 'ignored'
- }
- }
- })
-
- expect(ctx.$override).to.be.a('Function')
- expect(ctx.$override()).to.deep.equal({
- ctx: ctx,
- value: 'first'
- })
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/app/viewport.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/app/viewport.js b/html5/test/unit/default/app/viewport.js
deleted file mode 100644
index 0b0d122..0000000
--- a/html5/test/unit/default/app/viewport.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-import sinon from 'sinon'
-import sinonChai from 'sinon-chai'
-const { expect } = chai
-chai.use(sinonChai)
-
-import * as viewport from '../../../../frameworks/legacy/app/viewport'
-
-describe('viewport', function () {
- const originalCallNative = global.callNative
- const { setViewport, validateViewport } = viewport
- const mockApp = {
- id: 'mock',
- callTasks (...args) {
- global.callNative(...args)
- }
- }
-
- before(() => {
- sinon.stub(console, 'warn')
- })
-
- beforeEach(() => {
- global.callNative = sinon.spy()
- })
- afterEach(() => {
- global.callNative = originalCallNative
- console.warn.reset()
- })
-
- it('invalid setViewport', () => {
- setViewport()
- expect(global.callNative.callCount).to.be.equal(0)
- setViewport({})
- expect(global.callNative.callCount).to.be.equal(0)
- })
-
- it('setViewport', () => {
- setViewport(mockApp, {})
- expect(global.callNative.callCount).to.be.equal(1)
- setViewport(mockApp, { width: 640 })
- expect(global.callNative.callCount).to.be.equal(2)
- setViewport(mockApp, { width: 'device-width' })
- expect(global.callNative.callCount).to.be.equal(3)
- })
-
- it('validateViewport', () => {
- expect(validateViewport()).to.be.false
- expect(console.warn.callCount).to.be.equal(1)
- expect(validateViewport({})).to.be.false
- expect(console.warn.callCount).to.be.equal(2)
-
- expect(validateViewport({ width: 200 })).to.be.true
- expect(console.warn.callCount).to.be.equal(2)
- expect(validateViewport({ width: 'device-width' })).to.be.true
- expect(console.warn.callCount).to.be.equal(2)
-
- expect(validateViewport({ width: 'initial-width' })).to.be.false
- expect(console.warn.callCount).to.be.equal(3)
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/util/index.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/util/index.js b/html5/test/unit/default/util/index.js
deleted file mode 100644
index a33be27..0000000
--- a/html5/test/unit/default/util/index.js
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import chai from 'chai'
-const { expect } = chai
-
-import * as util from '../../../../frameworks/legacy/util'
-
-describe('Util', () => {
- describe('isReserved', () => {
- it('should be first char is $ or _', () => {
- expect(util.isReserved('$isReserved')).eql(true)
- expect(util.isReserved('_isReserved')).eql(true)
- expect(util.isReserved('isReserved$')).eql(false)
- expect(util.isReserved('is$Reserved')).eql(false)
- expect(util.isReserved('isReserved')).eql(false)
- })
- })
-
- describe('camelize', () => {
- it('should be camelize a hyphen-delmited string', () => {
- expect(util.camelize('mini-camelize')).eql('miniCamelize')
- expect(util.camelize('mini-camelize-test')).eql('miniCamelizeTest')
- })
- })
-
- describe('toArray', () => {
- it('should be convert an Array-like object to a real Array', () => {
- const mockup = {
- '0': 1,
- '1': 2,
- '2': 3,
- length: 3
- }
-
- expect(util.toArray(mockup)).eql([1, 2, 3])
- expect(util.toArray(mockup, 2)).eql([3])
- })
- })
-
- describe('extend', () => {
- it('should be extend object', () => {
- const mockup = {
- a: 1,
- b: 2
- }
-
- expect(util.extend(mockup, { b: 4, c: 5 })).eql({
- a: 1,
- b: 4,
- c: 5
- })
-
- expect(util.extend(mockup, { c: 5 })).eql({
- a: 1,
- b: 4,
- c: 5
- })
-
- expect(util.extend(mockup, { c: 5 }, { d: 6 }, { e: 7 })).eql({
- a: 1,
- b: 4,
- c: 5,
- d: 6,
- e: 7
- })
- })
-
- it('polyfill Object.assign', () => {
- const _assign = Object.assign
- Object.assign = undefined
-
- const mockup = {
- a: 1,
- b: 2
- }
-
- expect(util.extend(mockup, { b: 4, c: 5 })).eql({
- a: 1,
- b: 4,
- c: 5
- })
-
- expect(util.extend(mockup, { c: 5 })).eql({
- a: 1,
- b: 4,
- c: 5
- })
-
- expect(util.extend(mockup, { c: 5 }, { d: 6 }, { e: 7 })).eql({
- a: 1,
- b: 4,
- c: 5,
- d: 6,
- e: 7
- })
-
- Object.assign = _assign
- })
- })
-
- describe('isObject', () => {
- it('should be an array or object', () => {
- expect(util.isObject({})).eql(true)
- expect(util.isObject([])).eql(true)
- expect(util.isObject('a')).eql(false)
- expect(util.isObject(1)).eql(false)
- expect(util.isObject(true)).eql(false)
- expect(util.isObject(null)).eql(false)
- expect(util.isObject(undefined)).eql(false)
- expect(util.isObject(function () {})).eql(false)
- expect(util.isObject(/\w*/)).eql(true) // regexp is object
- expect(util.isObject(new Date())).eql(true)
- })
- })
-
- describe('isPlainObject', () => {
- it('should be an real object', () => {
- expect(util.isPlainObject({})).eql(true)
- expect(util.isPlainObject([])).eql(false)
- expect(util.isPlainObject('a')).eql(false)
- expect(util.isPlainObject(1)).eql(false)
- expect(util.isPlainObject(true)).eql(false)
- expect(util.isPlainObject(null)).eql(false)
- expect(util.isPlainObject(undefined)).eql(false)
- expect(util.isPlainObject(function () {})).eql(false)
- expect(util.isPlainObject(/\w*/)).eql(false)
- expect(util.isPlainObject(new Date())).eql(false)
- })
- })
-
- describe('typof', () => {
- it('should be real type', () => {
- expect(util.typof({})).eql('object')
- expect(util.typof([])).eql('array')
- expect(util.typof('a')).eql('string')
- expect(util.typof(1)).eql('number')
- expect(util.typof(true)).eql('boolean')
- expect(util.typof(null)).eql('null')
- expect(util.typof(undefined)).eql('undefined')
- expect(util.typof(function () {})).eql('function')
- expect(util.typof(/\w*/)).eql('regexp')
- expect(util.typof(new Date())).eql('date')
- })
- })
-
- describe('def', () => {
- it('should be define a non-enumerable property', () => {
- const obj = {}
- util.def(obj, 'a', 1, true)
- expect(obj).eql({ a: 1 })
-
- util.def(obj, 'b', 1, false)
- expect(obj).eql({ a: 1 })
-
- util.def(obj, 'c', 1, true)
- expect(obj).eql({ a: 1, c: 1 })
-
- util.def(obj, 'd', 1)
- expect(obj).eql({ a: 1, c: 1 })
- })
- })
-
- describe('hyphenate', () => {
- it('should hyphenate a camelCase string', () => {
- const str = 'helloWorldWeex'
- expect(util.hyphenate(str)).eql('hello-world-weex')
- })
- })
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/unit/default/util/shared.js
----------------------------------------------------------------------
diff --git a/html5/test/unit/default/util/shared.js b/html5/test/unit/default/util/shared.js
deleted file mode 100644
index bf24684..0000000
--- a/html5/test/unit/default/util/shared.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { expect } from 'chai'
-
-import * as utils from '../../../../frameworks/legacy/util/shared'
-
-describe('test util functions', () => {
- it('extend', () => {
- expect(typeof utils.extend).to.be.equal('function')
-
- const a = { name: 'A', a: true, c: true }
- const b = { name: 'B', b: true }
- utils.extend(a, b, { c: false })
- expect(a).to.be.deep.equal({ name: 'B', a: true, b: true, c: false })
- expect(b).to.be.deep.equal({ name: 'B', b: true })
- })
-
- it('def', () => {
- expect(typeof utils.def).to.be.equal('function')
- const obj = { type: 'none' }
- utils.def(obj, 'count', 42, false)
-
- expect(obj.hasOwnProperty('count')).to.be.true
- expect(obj.propertyIsEnumerable('count')).to.be.false
- expect(obj.type).to.be.equal('none')
- expect(obj.count).to.be.equal(42)
- obj.count = 24
- expect(obj.count).to.be.equal(24)
- })
-
- it('remove', () => {
- expect(typeof utils.remove).to.be.equal('function')
-
- const arr = ['first', null, 42, null, 28]
- const obj = { 0: 'first', 1: null, 2: 42 }
-
- utils.remove(arr, null)
- expect(arr).to.deep.equal(['first', 42, null, 28])
- utils.remove(arr, null)
- expect(arr).to.deep.equal(['first', 42, 28])
- utils.remove(arr, null)
- expect(arr).to.deep.equal(['first', 42, 28])
- utils.remove(arr, 42)
- expect(arr).to.deep.equal(['first', 28])
-
- utils.remove(obj, 42)
- expect(obj).to.deep.equal(obj)
- })
-
- it('hasOwn', () => {
- expect(typeof utils.hasOwn).to.be.equal('function')
-
- function Point () {
- this.x = 0
- }
- Point.prototype.y = 1
-
- const p = new Point()
- expect(p.x).to.be.equal(0)
- expect(p.y).to.be.equal(1)
-
- expect(utils.hasOwn(p, 'x')).to.be.true
- expect(utils.hasOwn(p, 'y')).to.be.false
- })
-
- it('bind', () => {
- expect(typeof utils.bind).to.be.equal('function')
-
- function who () {
- return this.name
- }
- const obj = { name: 'fixed' }
- const ctx = { name: 'changed' }
- const askWho = utils.bind(who, obj)
-
- expect(who()).to.be.undefined
- expect(askWho()).to.be.equal('fixed')
- expect(askWho.call(ctx)).to.be.equal('fixed')
- expect(askWho.apply(ctx)).to.be.equal('fixed')
- expect(who.apply(ctx)).to.be.equal('changed')
- })
-
- it('toArray', () => {
- expect(typeof utils.toArray).to.be.equal('function')
- const obj = { length: 2 }
- const arr = utils.toArray(obj)
-
- expect(arr).to.deep.equal([undefined, undefined])
- expect(arr.hasOwnProperty('0')).to.be.true
- expect(arr.hasOwnProperty('1')).to.be.true
- expect(arr.hasOwnProperty('2')).to.be.false
-
- const arrayLike = {
- 0: 'empty',
- 1: 'first',
- 2: 'second',
- length: 3
- }
- expect(utils.toArray(arrayLike, 1)).to.deep.equal(['first', 'second'])
- })
-
- it('isObject', () => {
- expect(typeof utils.isObject).to.be.equal('function')
- expect(utils.isObject({})).to.be.true
- expect(utils.isObject([])).to.be.true
- expect(utils.isObject(new Date())).to.be.true
- expect(utils.isObject()).to.be.false
- expect(utils.isObject('')).to.be.false
- expect(utils.isObject(42)).to.be.false
- expect(utils.isObject(NaN)).to.be.false
- expect(utils.isObject(null)).to.be.false
- expect(utils.isObject(undefined)).to.be.false
- })
-
- it('isPlainObject', () => {
- expect(typeof utils.isPlainObject).to.be.equal('function')
- expect(utils.isPlainObject({})).to.be.true
- expect(utils.isPlainObject([])).to.be.false
- expect(utils.isPlainObject(new Date())).to.be.false
- expect(utils.isPlainObject()).to.be.false
- expect(utils.isPlainObject('')).to.be.false
- expect(utils.isPlainObject(42)).to.be.false
- expect(utils.isPlainObject(NaN)).to.be.false
- expect(utils.isPlainObject(null)).to.be.false
- expect(utils.isPlainObject(undefined)).to.be.false
- })
-})
[15/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/if-repeat-refresh.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/if-repeat-refresh.source.js b/html5/test/case/complex/if-repeat-refresh.source.js
deleted file mode 100644
index aa62931..0000000
--- a/html5/test/case/complex/if-repeat-refresh.source.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/if-repeat', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {showTitle: true, title: 'Hello World1'},
- {showTitle: false, title: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": function () {return this.titlelist},
- "shown": function () {return this.showTitle},
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/if-repeat')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/inline-click.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/inline-click.output.js b/html5/test/case/complex/inline-click.output.js
deleted file mode 100644
index bf3208e..0000000
--- a/html5/test/case/complex/inline-click.output.js
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "Hello World1"
- },
- "event": [
- "click"
- ]
- }
- ]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/inline-click.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/inline-click.source.js b/html5/test/case/complex/inline-click.source.js
deleted file mode 100644
index e447c9e..0000000
--- a/html5/test/case/complex/inline-click.source.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/test', function (require, exports, module) {
-
-;
-module.exports = {
- data: function () {return {
- text: 'Hello World1'
- }},
- methods: {
- clicked: function(text, e) {
- this.text = text
- }
- }
-}
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "events": {
- "click": function ($event) {this.clicked('Hello World2', $event)}
- },
- "attr": {
- "value": function () {return this.text}
- }
- }
- ]
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/test', {"transformerVersion":"0.3.0"})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/input-binding.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/input-binding.output.js b/html5/test/case/complex/input-binding.output.js
deleted file mode 100644
index 30b9957..0000000
--- a/html5/test/case/complex/input-binding.output.js
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "children": [
- {
- "attr": {
- "value": "abcde"
- },
- "event": ["change"],
- "type": "input"
- }
- ],
- "type": "div"
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/input-binding.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/input-binding.source.js b/html5/test/case/complex/input-binding.source.js
deleted file mode 100644
index ae96760..0000000
--- a/html5/test/case/complex/input-binding.source.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/d6b20355da35c77d07f0a11ec5256f42', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- x: 'abcde',
- changes: []
- }
- },
- methods: {
- change: function(e) {
- var value = e.target.attr.value
- this.x = value
- this.changes.push(value)
- }
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "div",
- "children": [{
- "type": "input",
- "attr": {
- "value": function() {
- return this.x
- }
- },
- "events": {
- "change": "change"
- }
- }, {
- "type": "text",
- "repeat": {
- "expression": function() {
- return this.changes
- },
- "key": "k",
- "value": "v"
- },
- "attr": {
- "value": function() {
- return (this.k + 1) + ' - ' + (this.v)
- }
- }
- }]
- }
-
- ;
-})
-
-// require module
-bootstrap('@weex-component/d6b20355da35c77d07f0a11ec5256f42', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/refresh2.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/refresh2.output.js b/html5/test/case/complex/refresh2.output.js
deleted file mode 100644
index 823fda9..0000000
--- a/html5/test/case/complex/refresh2.output.js
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "type": "container",
- "children": [{
- "type": "container",
- "children": [{
- "type": "text",
- "attr": {
- "value": "bar1"
- }
- }, {
- "type": "container",
- "children": [{
- "type": "text",
- "attr": {
- "value": "bar2-refresh"
- }
- }]
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/refresh2.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/refresh2.source.js b/html5/test/case/complex/refresh2.source.js
deleted file mode 100644
index 6fa770c..0000000
--- a/html5/test/case/complex/refresh2.source.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-define('@weex-component/bar1', function(require, exports, module) {;;
- module.exports.template = {
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'bar1'
- }
- }, {
- type: 'bar2',
- id: 'bar2',
- component: true
- }]
- }
-
- ;
- module.exports.methods = {
- ready: function(isRefresh) {
- if (isRefresh) {
- this.$vm('bar2').ready(true)
- }
- }
- }
-
-})
-
-define('@weex-component/bar2', function(require, exports, module) {;;
- module.exports.template = {
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: function() {
- return this.text
- }
- }
- }]
- }
-
- ;
- module.exports.data = function() {
- return {
- text: 'bar2'
- }
- }
-
- ;
- module.exports.methods = {
- ready: function(isRefresh) {
- if (isRefresh) {
- this.text = 'bar2-refresh'
- }
- }
- }
-
-
-})
-
-define('@weex-component/foo', function(require, exports, module) {
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- type: 'container',
- children: [{
- type: 'bar1',
- shown: function() {
- return this.showbar1
- },
- id: 'bar1',
- component: true
- }]
- }
-
- ;
- module.exports.data = function() {
- return {
- showbar1: false,
- ext: {
- showbar1: false
- }
- }
- }
-
- ;module.exports.methods = {
- refreshData: function(data) {
- for (var key in data) {
- this[key] = data[key]
- }
- this.ready(true)
- },
- ready: function(isRefresh) {
- var self = this
- this.showbar1 = this.ext.showbar1
-
- if (isRefresh) {
- if (this.showbar1) {
- this.$renderThen(() => {
- this.$vm('bar1').$on('hook:ready', function() {
- self.$vm('bar1').ready(true)
- })
- })
- }
- }
- }
- }
-
-})
-
-// require module
-
-bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/repeat-track-by.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/repeat-track-by.output.js b/html5/test/case/complex/repeat-track-by.output.js
deleted file mode 100644
index 7e64c10..0000000
--- a/html5/test/case/complex/repeat-track-by.output.js
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- trackBy: 'text',
- value: '0: Hello World2'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- trackBy: 'text',
- value: '1: Hello World1'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/repeat-track-by.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/repeat-track-by.source.js b/html5/test/case/complex/repeat-track-by.source.js
deleted file mode 100644
index 127acb0..0000000
--- a/html5/test/case/complex/repeat-track-by.source.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-track-by', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {text: 'Hello World1'},
- {text: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": {
- expression: function() { return this.titlelist },
- key: 'index',
- value: 'title'
- },
- "classList": [
- "title"
- ],
- "attr": {
- "trackBy": "text",
- "value": function () {return this.index + ': ' + this.title.text}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-track-by')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/transformer2.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/transformer2.output.js b/html5/test/case/complex/transformer2.output.js
deleted file mode 100644
index 1372f91..0000000
--- a/html5/test/case/complex/transformer2.output.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- type: 'container'
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/transformer2.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/transformer2.source.js b/html5/test/case/complex/transformer2.source.js
deleted file mode 100644
index af31348..0000000
--- a/html5/test/case/complex/transformer2.source.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {
- x: 1
- }
- }
- }
-
-
-;module.exports.style = {
- "a": {
- "fontSize": 12
- }
-}
-
-;module.exports.template = {
- "type": "container"
-}
-
-;})
-
-
-bootstrap('@weex-component/foo', {
- 'transformerVersion': '0.0.1'
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/transformer3.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/transformer3.output.js b/html5/test/case/complex/transformer3.output.js
deleted file mode 100644
index 1372f91..0000000
--- a/html5/test/case/complex/transformer3.output.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- type: 'container'
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/transformer3.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/transformer3.source.js b/html5/test/case/complex/transformer3.source.js
deleted file mode 100644
index 2ca15a3..0000000
--- a/html5/test/case/complex/transformer3.source.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {
- x: 1
- }
- }
- }
-
-
-;module.exports.style = {
- "a": {
- "fontSize": 12
- }
-}
-
-;module.exports.template = {
- "type": "container"
-}
-
-;})
-
-
-bootstrap('@weex-component/foo', {
- 'transformerVersion': '9.9.9'
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-dep-target-error.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-dep-target-error.source.js b/html5/test/case/multi/clear-dep-target-error.source.js
deleted file mode 100644
index 0001d1c..0000000
--- a/html5/test/case/multi/clear-dep-target-error.source.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-define('@weex-component/DepTargetError', function(require, exports, module) {
-
- ;module.exports = {
- data: function () {return {
- a: {}
- }}
- }
-
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () { return this.a.x.y }
- }
- }
- ]
- }
-
-})
-
-bootstrap('@weex-component/DepTargetError', { "transformerVersion": "0.3.1" })
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-dep-target-fine.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-dep-target-fine.output.js b/html5/test/case/multi/clear-dep-target-fine.output.js
deleted file mode 100644
index e129423..0000000
--- a/html5/test/case/multi/clear-dep-target-fine.output.js
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "correct"
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-dep-target-fine.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-dep-target-fine.source.js b/html5/test/case/multi/clear-dep-target-fine.source.js
deleted file mode 100644
index fd7c7a2..0000000
--- a/html5/test/case/multi/clear-dep-target-fine.source.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-define('@weex-component/DepTargetFine', function(require, exports, module) {
-
- ;module.exports = {
- data: function () {return {
- lists: []
- }},
- created: function() {
- this.lists.$set(0, 'correct')
- }
- }
-
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () { return this.lists[0] }
- }
- }
- ]
- }
-
-})
-
-bootstrap('@weex-component/DepTargetFine', { "transformerVersion": "0.3.1" })
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-moduleA.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-moduleA.output.js b/html5/test/case/multi/clear-moduleA.output.js
deleted file mode 100644
index 5e7eac3..0000000
--- a/html5/test/case/multi/clear-moduleA.output.js
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "type": "div",
- "children": [
- {
- "type": "text",
- "event": ["click"],
- "attr": {
- "value": "sample"
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-moduleA.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-moduleA.source.js b/html5/test/case/multi/clear-moduleA.source.js
deleted file mode 100644
index 190b36f..0000000
--- a/html5/test/case/multi/clear-moduleA.source.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-define('@weex-component/moduleA', function(require, exports, module) {
-
- define('sample', function(require, exports, module) {
- module.exports = { name: 'sample' }
- })
-
- ;module.exports = {
- data: {
- text: ''
- },
- methods: {
- update: function() {
- var outer = require('sample')
- this.text = outer ? outer.name : 'nothing'
- }
- }
- }
-
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "events": {
- "click": "update"
- },
- "attr": {
- "value": function() { return this.text }
- }
- }
- ]
- }
-
-})
-
-// require module
-bootstrap('@weex-component/moduleA', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-moduleB.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-moduleB.output.js b/html5/test/case/multi/clear-moduleB.output.js
deleted file mode 100644
index c31de94..0000000
--- a/html5/test/case/multi/clear-moduleB.output.js
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "nothing"
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/multi/clear-moduleB.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/multi/clear-moduleB.source.js b/html5/test/case/multi/clear-moduleB.source.js
deleted file mode 100644
index c6338fd..0000000
--- a/html5/test/case/multi/clear-moduleB.source.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/moduleB', function(require, exports, module) {
-
- ;module.exports = {
- data: {
- text: ''
- },
- created: function() {
- var smp = require('sample')
- this.text = smp ? smp.name : 'nothing'
- }
- }
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function() { return this.text }
- }
- }
- ]
- }
-
-})
-
-// require module
-bootstrap('@weex-component/moduleB', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/prepare.js
----------------------------------------------------------------------
diff --git a/html5/test/case/prepare.js b/html5/test/case/prepare.js
deleted file mode 100644
index d787c42..0000000
--- a/html5/test/case/prepare.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import fs from 'fs'
-import path from 'path'
-
-// load test driver
-import {
- Runtime,
- Instance
-} from 'weex-vdom-tester'
-
-// load env
-import shared from '../../shared'
-import { Document, Element, Comment } from '../../runtime/vdom'
-import Listener from '../../runtime/bridge/Listener'
-import { TaskCenter, init } from '../../runtime/bridge/TaskCenter'
-
-// load framework
-import * as defaultFramework from '../../frameworks/legacy'
-import { subversion } from '../../../package.json'
-
-shared.setNativeConsole()
-
-// mock config & global APIs
-global.callNativeHandler = function () {}
-
-// init special API called `callAddElement()`
-// which is supported temporarily in native render
-global.callAddElement = function (id, ref, json, index) {
- return callNativeHandler(id, [{ module: 'dom', method: 'addElement', args: [ref, json, index] }])
-}
-
-init()
-
-// create test driver runtime
-export function createRuntime () {
- const config = {
- Document, Element, Comment, Listener,
- TaskCenter,
- sendTasks (...args) {
- return callNativeHandler(...args)
- }
- }
-
- Document.Listener = Listener
- Document.handler = config.sendTasks
-
- defaultFramework.init(config)
-
- Object.assign(global, {
- frameworkVersion: subversion.native,
- transformerVersion: subversion.transformer
- })
-
- return new Runtime(defaultFramework)
-}
-
-// create framework instance
-export function createApp (runtime) {
- return new Instance(runtime)
-}
-
-// read source code from file
-export function getCode (filePath) {
- const absolutPath = path.join(__dirname, filePath)
- return fs.readFileSync(absolutPath, 'utf8')
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/signals/modal.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/signals/modal.output.js b/html5/test/case/signals/modal.output.js
deleted file mode 100644
index f645aa2..0000000
--- a/html5/test/case/signals/modal.output.js
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- type: 'div',
- children: [{
- type: 'text',
- attr: {
- value: 'foo'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/signals/modal.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/signals/modal.source.js b/html5/test/case/signals/modal.source.js
deleted file mode 100644
index bdef1b8..0000000
--- a/html5/test/case/signals/modal.source.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/modal', function (require, exports, module) {
-
-;
- var modal = require('@weex-module/modal')
- module.exports = {
- data: function () {
- return {
- x: 'foo'
- }
- },
- created: function () {
- var message = 'Here is a message for you!'
- var okTitle = 'OK'
- modal.alert({
- message: message,
- okTitle: okTitle
- }, function() {
- this.x = 'bar'
- }.bind(this))
- }
- }
-
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {
- return this.x
- }
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/modal')
[16/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo6.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo6.source.js b/html5/test/case/basic/foo6.source.js
deleted file mode 100644
index 4301a50..0000000
--- a/html5/test/case/basic/foo6.source.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo6', function (require, exports, module) {
-
-;
-
-;module.exports.style = {
- "container": {
- "flexDirection": "row"
- },
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "classList": [
- "container"
- ],
- "children": [
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": "http://gw.alicdn.com/tfscom/TB1OMfAJFXXXXbfXXXXqVMCNVXX-400-400.jpg"
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": "一个超赞的宝贝标题"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo6')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo7.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo7.output.js b/html5/test/case/basic/foo7.output.js
deleted file mode 100644
index d19c92f..0000000
--- a/html5/test/case/basic/foo7.output.js
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: '一个超赞的宝贝标题'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo7.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo7.source.js b/html5/test/case/basic/foo7.source.js
deleted file mode 100644
index 2d9b43f..0000000
--- a/html5/test/case/basic/foo7.source.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo7', function (require, exports, module) {
-
-;
- module.exports = {
- methods: {
- gotoDetail: function () {
- this.$openURL('https://item.taobao.com/item.htm?id=520421163634')
- }
- }
- }
-
-
-;module.exports.style = {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "events": {
- "click": "gotoDetail"
- },
- "children": [
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": "https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg"
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": "一个超赞的宝贝标题"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo7')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo8.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo8.output.js b/html5/test/case/basic/foo8.output.js
deleted file mode 100644
index 8ed4bb1..0000000
--- a/html5/test/case/basic/foo8.output.js
+++ /dev/null
@@ -1,60 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'container',
- style: {
- flexDirection: 'row'
- },
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title1'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }, {
- type: 'container',
- style: {
- flexDirection: 'row'
- },
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title2'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo8.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo8.source.js b/html5/test/case/basic/foo8.source.js
deleted file mode 100644
index d2512f2..0000000
--- a/html5/test/case/basic/foo8.source.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo8', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemList: [
- {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
- {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
- ]
- }},
- methods: {
- gotoDetail: function () {
- this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
- }
- }
- }
-
-
-;module.exports.style = {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "container",
- "repeat": function () {return this.itemList},
- "events": {
- "click": "gotoDetail"
- },
- "style": {
- "flexDirection": "row"
- },
- "children": [
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": function () {return this.pictureUrl}
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo8')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo9.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo9.output.js b/html5/test/case/basic/foo9.output.js
deleted file mode 100644
index 8f6d086..0000000
--- a/html5/test/case/basic/foo9.output.js
+++ /dev/null
@@ -1,57 +0,0 @@
-{
- type: 'container',
- style: {
- flexDirection: 'column'
- },
- children: [{
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title1'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }, {
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: 'title2'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/foo9.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/foo9.source.js b/html5/test/case/basic/foo9.source.js
deleted file mode 100644
index da534e9..0000000
--- a/html5/test/case/basic/foo9.source.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/taobao-item', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemId: '',
- title: '',
- pictureUrl: ''
- }},
- methods: {
- gotoDetail: function () {
- this.$openURL('https://item.taobao.com/item.htm?id=' + this.itemId)
- }
- }
- }
-
-
-;module.exports.style = {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "events": {
- "click": "gotoDetail"
- },
- "children": [
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": function () {return this.pictureUrl}
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// module
-
-define('@weex-component/foo9', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- itemList: [
- {itemId: '520421163634', title: 'title1', pictureUrl: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'},
- {itemId: '522076777462', title: 'title2', pictureUrl: 'https://gd1.alicdn.com/bao/uploaded/i1/TB1PXJCJFXXXXciXFXXXXXXXXXX_!!0-item_pic.jpg'}
- ]
- }}
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "style": {
- "flexDirection": "column"
- },
- "children": [
- {
- "type": "taobao-item",
- "repeat": function () {return this.itemList}
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/foo9')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/global-weex-object.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/global-weex-object.output.js b/html5/test/case/basic/global-weex-object.output.js
deleted file mode 100644
index 3e1fa19..0000000
--- a/html5/test/case/basic/global-weex-object.output.js
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- type: 'div',
- attr: {
- a: 'WeexDemo'
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/global-weex-object.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/global-weex-object.source.js b/html5/test/case/basic/global-weex-object.source.js
deleted file mode 100644
index 252af7e..0000000
--- a/html5/test/case/basic/global-weex-object.source.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-weex.define('@weex-component/foo', function (require, exports, module) {
- module.exports = {
- data: function () {
- return {
- x: weex.config.env.appName
- }
- },
- template: {
- "type": "div",
- "attr": {
- "a": function () {
- return this.x
- }
- }
- }
- }
-})
-
-weex.bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/id.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/id.output.js b/html5/test/case/basic/id.output.js
deleted file mode 100644
index 7ce073c..0000000
--- a/html5/test/case/basic/id.output.js
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- type: 'div',
- children: [
- {
- type: 'text',
- attr: {
- value: 'Hello',
- a: 1
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello',
- a: 1,
- b: 1
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello'
- }
- },
- {
- type: 'text',
- attr: {
- value: 'Hello'
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/id.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/id.source.js b/html5/test/case/basic/id.source.js
deleted file mode 100644
index 3c85886..0000000
--- a/html5/test/case/basic/id.source.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/id', function (require, exports, module) {
-
-;
- module.exports = {
- ready: function () {
- if (this.$el('x')) {
- this.$el('x').setAttr('a', 1)
- }
- if (this.$el('y')) {
- this.$el('y').setAttr('a', 1)
- }
- if (this.$el('')) {
- this.$el('').setAttr('a', 1)
- }
- if (this.$el('0')) {
- this.$el('0').setAttr('a', 1)
- }
- if (this.$el(0)) {
- this.$el(0).setAttr('b', 1)
- }
- }
- }
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "id": "x",
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": "0",
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": '',
- "attr": {
- "value": "Hello"
- }
- },
- {
- "type": "text",
- "id": null,
- "attr": {
- "value": "Hello"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/id')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/if-repeat.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/if-repeat.output.js b/html5/test/case/basic/if-repeat.output.js
deleted file mode 100644
index 5265727..0000000
--- a/html5/test/case/basic/if-repeat.output.js
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: 'Hello World1'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/if-repeat.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/if-repeat.source.js b/html5/test/case/basic/if-repeat.source.js
deleted file mode 100644
index aa62931..0000000
--- a/html5/test/case/basic/if-repeat.source.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/if-repeat', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {showTitle: true, title: 'Hello World1'},
- {showTitle: false, title: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": function () {return this.titlelist},
- "shown": function () {return this.showTitle},
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/if-repeat')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/if-root.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/if-root.output.js b/html5/test/case/basic/if-root.output.js
deleted file mode 100644
index 0967ef4..0000000
--- a/html5/test/case/basic/if-root.output.js
+++ /dev/null
@@ -1 +0,0 @@
-{}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/if-root.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/if-root.source.js b/html5/test/case/basic/if-root.source.js
deleted file mode 100644
index ca94316..0000000
--- a/html5/test/case/basic/if-root.source.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/if-root', function (require, exports, module) {
-
-;module.exports = {
- data: function () {return {
- visible: true,
- }}
-}
-
-;module.exports.template = {
- "type": "container",
- "shown": function () {return this.visible},
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "container"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/if-root')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/if.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/if.output.js b/html5/test/case/basic/if.output.js
deleted file mode 100644
index 03dbeae..0000000
--- a/html5/test/case/basic/if.output.js
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: 'Hello World'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/if.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/if.source.js b/html5/test/case/basic/if.source.js
deleted file mode 100644
index 3ebb80c..0000000
--- a/html5/test/case/basic/if.source.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/if', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- showTitle: true,
- title: 'Hello World'
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "shown": function () {return this.showTitle},
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/if')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/promise.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/promise.output.js b/html5/test/case/basic/promise.output.js
deleted file mode 100644
index 07b17c9..0000000
--- a/html5/test/case/basic/promise.output.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- type: 'container'
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/promise.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/promise.source.js b/html5/test/case/basic/promise.source.js
deleted file mode 100644
index 67554ba..0000000
--- a/html5/test/case/basic/promise.source.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo', function (require, exports, module) {
-new Promise(function (fulfill, reject){
- fulfill(1)
-})
-Promise.all([Promise.resolve(1)])
-;
- module.exports = {
- data: function () {
- return {
- x: 1
- }
- }
- }
-
-
-;module.exports.style = {
- "a": {
- "fontSize": 12
- }
-}
-
-;module.exports.template = {
- "type": "container"
-}
-
-;})
-
-
-bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/ready.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/ready.output.js b/html5/test/case/basic/ready.output.js
deleted file mode 100644
index 39c15f3..0000000
--- a/html5/test/case/basic/ready.output.js
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "children": [
- {
- "attr": {
- "value": "1"
- },
- "type": "text"
- }
- ],
- "type": "container"
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/ready.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/ready.source.js b/html5/test/case/basic/ready.source.js
deleted file mode 100644
index 08ee893..0000000
--- a/html5/test/case/basic/ready.source.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/created', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- text: '',
- }
- },
- ready: function() {
- this.text = '1'
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "container",
- "children": [{
- "type": "text",
- "attr": {
- "value": function() {
- return this.text
- }
- }
- }]
- }
-
- ;
-})
-
-// require module
-bootstrap('@weex-component/created', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-kv.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-kv.output.js b/html5/test/case/basic/repeat-array-kv.output.js
deleted file mode 100644
index 4d4991a..0000000
--- a/html5/test/case/basic/repeat-array-kv.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '0: Hello World1'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '1: Hello World2'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-kv.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-kv.source.js b/html5/test/case/basic/repeat-array-kv.source.js
deleted file mode 100644
index 21f26c7..0000000
--- a/html5/test/case/basic/repeat-array-kv.source.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-array-kv', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {text: 'Hello World1'},
- {text: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": {
- expression: function() { return this.titlelist },
- key: 'index',
- value: 'title'
- },
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.index + ': ' + this.title.text}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-array-kv')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-no-kv.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-no-kv.output.js b/html5/test/case/basic/repeat-array-no-kv.output.js
deleted file mode 100644
index 4d4991a..0000000
--- a/html5/test/case/basic/repeat-array-no-kv.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '0: Hello World1'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '1: Hello World2'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-no-kv.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-no-kv.source.js b/html5/test/case/basic/repeat-array-no-kv.source.js
deleted file mode 100644
index 910bf04..0000000
--- a/html5/test/case/basic/repeat-array-no-kv.source.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-array-no-kv', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {text: 'Hello World1'},
- {text: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": {
- expression: function() { return this.titlelist }
- },
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.$index + ': ' + this.$value.text}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-array-no-kv')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-non-obj.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-non-obj.output.js b/html5/test/case/basic/repeat-array-non-obj.output.js
deleted file mode 100644
index 4d4991a..0000000
--- a/html5/test/case/basic/repeat-array-non-obj.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '0: Hello World1'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '1: Hello World2'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-non-obj.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-non-obj.source.js b/html5/test/case/basic/repeat-array-non-obj.source.js
deleted file mode 100644
index 71de5d2..0000000
--- a/html5/test/case/basic/repeat-array-non-obj.source.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-array-non-obj', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- 'Hello World1',
- 'Hello World2'
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": {
- expression: function() { return this.titlelist },
- value: 'title'
- },
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.$index + ': ' + this.title}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-array-non-obj')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-v.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-v.output.js b/html5/test/case/basic/repeat-array-v.output.js
deleted file mode 100644
index 4d4991a..0000000
--- a/html5/test/case/basic/repeat-array-v.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '0: Hello World1'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '1: Hello World2'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-array-v.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-array-v.source.js b/html5/test/case/basic/repeat-array-v.source.js
deleted file mode 100644
index 0fecb04..0000000
--- a/html5/test/case/basic/repeat-array-v.source.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-array-v', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {text: 'Hello World1'},
- {text: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": {
- expression: function() { return this.titlelist },
- value: 'title'
- },
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.$index + ': ' + this.title.text}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-array-v')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-index.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-index.output.js b/html5/test/case/basic/repeat-index.output.js
deleted file mode 100644
index 4d4991a..0000000
--- a/html5/test/case/basic/repeat-index.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '0: Hello World1'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: '1: Hello World2'
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-index.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-index.source.js b/html5/test/case/basic/repeat-index.source.js
deleted file mode 100644
index 5bdc4ea..0000000
--- a/html5/test/case/basic/repeat-index.source.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-index', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- titlelist: [
- {title: 'Hello World1'},
- {title: 'Hello World2'}
- ]
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "repeat": function () {return this.titlelist},
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.$index + ': ' + this.title}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-index')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-root.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-root.output.js b/html5/test/case/basic/repeat-root.output.js
deleted file mode 100644
index 0967ef4..0000000
--- a/html5/test/case/basic/repeat-root.output.js
+++ /dev/null
@@ -1 +0,0 @@
-{}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-root.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-root.source.js b/html5/test/case/basic/repeat-root.source.js
deleted file mode 100644
index ac79ae4..0000000
--- a/html5/test/case/basic/repeat-root.source.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/repeat-root', function (require, exports, module) {
-
-;module.exports = {
- data: function () {return {
- containers: [
- {name: 'a'},
- {name: 'b'}
- ]
- }}
-}
-
-;module.exports.template = {
- "type": "container",
- "repeat": function () {return this.containers},
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "container"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/repeat-root')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-watch.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-watch.output.js b/html5/test/case/basic/repeat-watch.output.js
deleted file mode 100644
index 1170f8b..0000000
--- a/html5/test/case/basic/repeat-watch.output.js
+++ /dev/null
@@ -1,46 +0,0 @@
-{
- "type": "list",
- "children": [{
- "type": "cell",
- "attr": {
- "append": "tree"
- },
- "children": [{
- "type": "text",
- "attr": {
- "value": 1
- },
- "style": {
- "height": 600
- }
- }]
- }, {
- "type": "cell",
- "attr": {
- "append": "tree"
- },
- "children": [{
- "type": "text",
- "attr": {
- "value": 2
- },
- "style": {
- "height": 600
- }
- }]
- }, {
- "type": "cell",
- "attr": {
- "append": "tree"
- },
- "children": [{
- "type": "text",
- "attr": {
- "value": 3
- },
- "style": {
- "height": 600
- }
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/repeat-watch.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/repeat-watch.source.js b/html5/test/case/basic/repeat-watch.source.js
deleted file mode 100644
index 0f989d8..0000000
--- a/html5/test/case/basic/repeat-watch.source.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/04f1048c50eca3454bc70de93d3213d4', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- list: [{
- text: 1
- }, {
- text: 2
- }],
- more: [{
- text: 3
- }]
- }
- },
- ready: function() {
- for (var i = 0; i < this.more.length; i++) {
- this.list.push(this.more[i]);
- }
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "list",
- "children": [{
- "type": "cell",
- "append": "tree",
- "repeat": function() {
- return this.list
- },
- "children": [{
- "type": "text",
- "style": {
- "height": 600
- },
- "attr": {
- "value": function() {
- return this.text
- }
- }
- }]
- }]
- }
-
- ;
-})
-
-// require module
-bootstrap('@weex-component/04f1048c50eca3454bc70de93d3213d4', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/require.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/require.output.js b/html5/test/case/basic/require.output.js
deleted file mode 100644
index 51c886e..0000000
--- a/html5/test/case/basic/require.output.js
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- attr: {
- value: 'Hello World'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/require.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/require.source.js b/html5/test/case/basic/require.source.js
deleted file mode 100644
index db1fed7..0000000
--- a/html5/test/case/basic/require.source.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-var browserifyRequire=function r(e,n,o){function t(u,i){if(!n[u]){if(!e[u]){var a="function"==typeof browserifyRequire&&browserifyRequire;if(!i&&a)return a(u,!0);if(f)return f(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[u]={exports:{}};e[u][0].call(l.exports,function(r){var n=e[u][1][r];return t(n?n:r)},l,l.exports,r,e,n,o)}return n[u].exports}for(var f="function"==typeof browserifyRequire&&browserifyRequire,u=0;u<o.length;u++)t(o[u]);return t}({"1ba80324acff072bbb2b768911a5e4f1":[function(r,e,n){e.exports="Hello World"},{}]},{},[]);
-
-
-define('@weex-component/foo', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- text: ''
- }},
- created: function() {
- this.text = browserifyRequire("1ba80324acff072bbb2b768911a5e4f1")
- }
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.text}
- }
- }
- ]
-}
-
-;})
-
-// require module
-bootstrap('@weex-component/foo', {"transformerVersion":"0.3.0"})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/reset-style.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/reset-style.output.js b/html5/test/case/basic/reset-style.output.js
deleted file mode 100644
index ed6bbaf..0000000
--- a/html5/test/case/basic/reset-style.output.js
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "type": "container",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "Hello Weex"
- },
- "style": {
- "fontSize": 40,
- "color": ""
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/reset-style.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/reset-style.source.js b/html5/test/case/basic/reset-style.source.js
deleted file mode 100644
index a96b891..0000000
--- a/html5/test/case/basic/reset-style.source.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/reset-style', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- className: 'highlight'
- }},
- ready: function() {
- this.className = 'normal'
- }
- }
-
-
-;module.exports.style = {
- "normal": {
- "fontSize": 40
- },
- "highlight": {
- "fontSize": 60,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "classList": function () {return [this.className]},
- "attr": {
- "value": "Hello Weex"
- }
- }
- ]
-}
-
-;})
-
-
-bootstrap('@weex-component/reset-style')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static1.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static1.output.js b/html5/test/case/basic/static1.output.js
deleted file mode 100644
index e400730..0000000
--- a/html5/test/case/basic/static1.output.js
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": "hello",
- "static": ""
- }
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static1.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static1.source.js b/html5/test/case/basic/static1.source.js
deleted file mode 100644
index 575ef66..0000000
--- a/html5/test/case/basic/static1.source.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/static1', function (require, exports, module) {
-
-;
- module.exports = {
- ready: function() {
- this.x = 'world'
- },
- data: function () {return {
- x: 'hello'
- }}
- }
-
-
-;module.exports.style = {
-}
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "static": "",
- "value": function () {return this.x}
- }
- }
- ]
-}
-
-;})
-
-
-bootstrap('@weex-component/static1')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static2.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static2.output.js b/html5/test/case/basic/static2.output.js
deleted file mode 100644
index fd5ee57..0000000
--- a/html5/test/case/basic/static2.output.js
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "type": "div",
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": 1
- }
- }
- ]
- },
- {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": 2
- }
- }
- ]
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static2.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static2.source.js b/html5/test/case/basic/static2.source.js
deleted file mode 100644
index 93e1cf6..0000000
--- a/html5/test/case/basic/static2.source.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/static2', function (require, exports, module) {
-
-;
- module.exports = {
- ready: function() {
- this.arr.$set(2, 3)
- },
- data: function () {return {
- arr: [1, 2]
- }}
- }
-
-
-;module.exports.style = {
-}
-
-;module.exports.template = {
- "type": "div",
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "div",
- "repeat": {
- "expression": function () {return this.arr},
- "value": "x"
- },
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.x}
- }
- }
- ]
- }
- ]
-}
-
-;})
-
-
-bootstrap('@weex-component/static2')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static3.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static3.output.js b/html5/test/case/basic/static3.output.js
deleted file mode 100644
index 73eaaab..0000000
--- a/html5/test/case/basic/static3.output.js
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "type": "div",
- "children": [
- {
- "type": "div",
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "text",
- "attr": {
- "value": 1
- }
- }
- ]
- },
- {
- "type": "div",
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "text",
- "attr": {
- "value": 2
- }
- }
- ]
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static3.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static3.source.js b/html5/test/case/basic/static3.source.js
deleted file mode 100644
index 9179ea7..0000000
--- a/html5/test/case/basic/static3.source.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/static3', function (require, exports, module) {
-
-;
- module.exports = {
- ready: function() {
- this.arr.$set(2, 3)
- },
- data: function () {return {
- arr: [1, 2]
- }}
- }
-
-
-;module.exports.style = {
-}
-
-;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "div",
- "repeat": {
- "expression": function () {return this.arr},
- "value": "x"
- },
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.x}
- }
- }
- ]
- }
- ]
-}
-
-;})
-
-
-bootstrap('@weex-component/static3')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static4.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static4.output.js b/html5/test/case/basic/static4.output.js
deleted file mode 100644
index a53e484..0000000
--- a/html5/test/case/basic/static4.output.js
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "type": "div",
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "div",
- "children": [
- {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": 1
- }
- }
- ]
- },
- {
- "type": "div",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": 2
- }
- }
- ]
- }
- ]
- }
- ]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/static4.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/static4.source.js b/html5/test/case/basic/static4.source.js
deleted file mode 100644
index fe31bcc..0000000
--- a/html5/test/case/basic/static4.source.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-function otherNameFunction () {
- var module = {}
- var exports = {}
- module.exports = exports
-
- ;module.exports.style = {}
-
- ;module.exports.template = {
- "type": "div",
- "children": [
- {
- "type": "div",
- "repeat": {
- "expression": function () {return this.outer},
- "value": "x"
- },
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.x}
- }
- }
- ]
- }
- ]
- }
-
- ;module.exports.data = function() {return {
- outer: null
- }}
-
- return module.exports
-}
-
-// module
-
-define('@weex-component/static4', function (require, exports, module) {
-
-;
- module.exports = {
- "components": {
- innertpl: otherNameFunction()
- },
- ready: function() {
- this.arr.$set(2, 3)
- },
- data: function () {return {
- arr: [1, 2]
- }}
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "div",
- "attr": {
- "static": ""
- },
- "children": [
- {
- "type": "innertpl",
- "attr": {
- "outer": function () {return this.arr}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/static4')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/subvm.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/subvm.output.js b/html5/test/case/basic/subvm.output.js
deleted file mode 100644
index b7acaa4..0000000
--- a/html5/test/case/basic/subvm.output.js
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "type": "container",
- "children": [{
- "type": "container",
- "style": {
- "marginTop": 10
- },
- "children": [{
- "type": "text",
- "attr": {
- "value": "aa"
- }
- },{
- "type": "text",
- "attr": {
- "value": "bb"
- }
- }]
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/subvm.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/subvm.source.js b/html5/test/case/basic/subvm.source.js
deleted file mode 100644
index 1b054a5..0000000
--- a/html5/test/case/basic/subvm.source.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/innertpl', function (require, exports, module) {
-
-;
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.outerData.a}
- }
- },
- {
- "type": "text",
- "attr": {
- "value": function () {return this.outerData.b}
- }
- }
- ]
-}
-
-;module.exports.created = function() {
- this.outerData.a = 'aa'
-}
-
-;module.exports.methods = {
- "ready": function() {
- this.outerData.b = 'bb'
- }
-}
-
-;})
-
-// module
-
-define('@weex-component/subvm', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- item: {a: 'a', b: 'b'},
- className: 'fromOuter',
- marginTop: 10
- }}
- }
-
-
-;module.exports.style = {}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "innertpl",
- "classList": function() {
- return this.className
- },
- "style": {
- marginTop: function() {
- return this.marginTop
- }
- },
- "events": {
- "click": "clicked"
- },
- "attr": {
- "outerData": function () {return this.item}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/subvm')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/transformer1.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/transformer1.output.js b/html5/test/case/basic/transformer1.output.js
deleted file mode 100644
index 1372f91..0000000
--- a/html5/test/case/basic/transformer1.output.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- type: 'container'
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/basic/transformer1.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/basic/transformer1.source.js b/html5/test/case/basic/transformer1.source.js
deleted file mode 100644
index 7985e28..0000000
--- a/html5/test/case/basic/transformer1.source.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/foo', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {
- x: 1
- }
- }
- }
-
-
-;module.exports.style = {
- "a": {
- "fontSize": 12
- }
-}
-
-;module.exports.template = {
- "type": "container"
-}
-
-;})
-
-
-bootstrap('@weex-component/foo', {
- 'transformerVersion': '0.3.0'
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/append-root-event.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/append-root-event.output.js b/html5/test/case/complex/append-root-event.output.js
deleted file mode 100644
index 2a1b77c..0000000
--- a/html5/test/case/complex/append-root-event.output.js
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- type: 'div',
- attr: {
- append: "tree"
- },
- children: [{
- type: 'text',
- event: ['click'],
- attr: {
- value: 1
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/append-root-event.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/append-root-event.source.js b/html5/test/case/complex/append-root-event.source.js
deleted file mode 100644
index 49455e5..0000000
--- a/html5/test/case/complex/append-root-event.source.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/append-root-event', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- x: 1
- }
- },
- methods: {
- update: function() {
- this.x = 2
- }
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "div",
- "append": "tree",
- "children": [{
- "type": "text",
- "events": {
- "click": "update"
- },
- "attr": {
- "value": function() {
- return this.x
- }
- }
- }]
- }
-
- ;
-})
-
-// require module
-
-bootstrap('@weex-component/append-root-event', {
- "transformerVersion": "0.3.1"
-})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/click.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/click.output.js b/html5/test/case/complex/click.output.js
deleted file mode 100644
index d19c92f..0000000
--- a/html5/test/case/complex/click.output.js
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- type: 'container',
- event: ['click'],
- children: [{
- type: 'image',
- attr: {
- src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
- },
- style: {
- width: 200,
- height: 200
- }
- }, {
- type: 'text',
- attr: {
- value: '一个超赞的宝贝标题'
- },
- style: {
- flex: 1,
- color: '#ff0000',
- fontSize: 48,
- fontWeight: 'bold',
- backgroundColor: '#eeeeee'
- }
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/click.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/click.source.js b/html5/test/case/complex/click.source.js
deleted file mode 100644
index 039c98b..0000000
--- a/html5/test/case/complex/click.source.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/click', function (require, exports, module) {
-
-;
- module.exports = {
- methods: {
- gotoDetail: function () {
- this.$openURL('https://item.taobao.com/item.htm?id=520421163634')
- }
- }
- }
-
-
-;module.exports.style = {
- "thumb": {
- "width": 200,
- "height": 200
- },
- "title": {
- "flex": 1,
- "color": "#ff0000",
- "fontSize": 48,
- "fontWeight": "bold",
- "backgroundColor": "#eeeeee"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "events": {
- "click": "gotoDetail"
- },
- "children": [
- {
- "type": "image",
- "classList": [
- "thumb"
- ],
- "attr": {
- "src": "https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg"
- }
- },
- {
- "type": "text",
- "classList": [
- "title"
- ],
- "attr": {
- "value": "一个超赞的宝贝标题"
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/click')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/component-append-tree.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/component-append-tree.output.js b/html5/test/case/complex/component-append-tree.output.js
deleted file mode 100644
index 6c036ec..0000000
--- a/html5/test/case/complex/component-append-tree.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'scroller',
- children: [{
- type: 'div',
- attr: { "append": "node" },
- children: [{
- type: 'text',
- attr: {
- value: 'ready'
- }
- }]
- }, {
- type: 'div',
- attr: { "append": "tree" },
- children: [{
- type: 'text',
- attr: {
- value: 'ready'
- }
- }]
- }]
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/component-append-tree.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/component-append-tree.source.js b/html5/test/case/complex/component-append-tree.source.js
deleted file mode 100644
index 7088eea..0000000
--- a/html5/test/case/complex/component-append-tree.source.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-define('@weex-component/sub', function(require, exports, module) {
-
- ;
- module.exports = {
- data: function() {
- return {
- str: '-----'
- }
- },
- ready: function() {
- this.str = 'ready'
- setTimeout(() => {
- this.str = 'timeout'
- }, 100)
- }
- }
-
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "text",
- "attr": {
- "value": function() {
- return this.str
- }
- }
- }
-
- ;
- })
-
- // module
-
- define('@weex-component/ad164d40f42747f598b56eccfd0eae8e', function(require, exports, module) {
-
- ;
-
- ;
- module.exports.style = {}
-
- ;
- module.exports.template = {
- "type": "scroller",
- "children": [{
- "type": "div",
- "append": "node",
- "children": [{
- "type": "sub"
- }]
- }, {
- "type": "div",
- "append": "tree",
- "children": [{
- "type": "sub"
- }]
- }]
- }
-
- ;
- })
-
- // require module
- bootstrap('@weex-component/ad164d40f42747f598b56eccfd0eae8e', {
- "transformerVersion": "0.4.3"
- })
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/computed.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/computed.output.js b/html5/test/case/complex/computed.output.js
deleted file mode 100644
index 8c5534d..0000000
--- a/html5/test/case/complex/computed.output.js
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- type: 'container',
- event: ['click'],
- children: [{
- type: 'text',
- attr: {
- value: 3
- },
- }, {
- type: 'text',
- attr: {
- value: 3
- }
- }]
-}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/computed.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/computed.source.js b/html5/test/case/complex/computed.source.js
deleted file mode 100644
index 8d59ca3..0000000
--- a/html5/test/case/complex/computed.source.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/computed', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {
- return {x: 1, y: 2}
- },
- computed: {
- n: function () {
- return this.x + this.y
- },
- m: {
- get: function () {
- return this.x + this.y
- },
- set: function (v) {
- this.y = v
- }
- }
- },
- methods: {
- foo: function () {
- this.m = 10
- }
- }
- }
-
-
-;module.exports.template = {
- "type": "container",
- "events": {
- "click": "foo"
- },
- "children": [
- {
- "type": "text",
- "attr": {
- "value": function () {return this.n}
- }
- },
- {
- "type": "text",
- "attr": {
- "value": function () {return this.m}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/computed')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/if-refresh.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/if-refresh.output.js b/html5/test/case/complex/if-refresh.output.js
deleted file mode 100644
index 1372f91..0000000
--- a/html5/test/case/complex/if-refresh.output.js
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- type: 'container'
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/if-refresh.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/if-refresh.source.js b/html5/test/case/complex/if-refresh.source.js
deleted file mode 100644
index 3ebb80c..0000000
--- a/html5/test/case/complex/if-refresh.source.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-define('@weex-component/if', function (require, exports, module) {
-
-;
- module.exports = {
- data: function () {return {
- showTitle: true,
- title: 'Hello World'
- }}
- }
-
-
-;module.exports.style = {
- "title": {
- "fontSize": 26,
- "color": "#FF0000"
- }
-}
-
-;module.exports.template = {
- "type": "container",
- "children": [
- {
- "type": "text",
- "shown": function () {return this.showTitle},
- "classList": [
- "title"
- ],
- "attr": {
- "value": function () {return this.title}
- }
- }
- ]
-}
-
-;})
-
-// require module
-
-bootstrap('@weex-component/if')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/complex/if-repeat-refresh.output.js
----------------------------------------------------------------------
diff --git a/html5/test/case/complex/if-repeat-refresh.output.js b/html5/test/case/complex/if-repeat-refresh.output.js
deleted file mode 100644
index d4831cc..0000000
--- a/html5/test/case/complex/if-repeat-refresh.output.js
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- type: 'container',
- children: [{
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: 'Hello World2'
- }
- }, {
- type: 'text',
- style: {
- color: '#FF0000',
- fontSize: 26
- },
- attr: {
- value: 'Hello World3'
- }
- }]
-}
\ No newline at end of file
[14/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/html5/test/case/signals/signals-long.source.js
----------------------------------------------------------------------
diff --git a/html5/test/case/signals/signals-long.source.js b/html5/test/case/signals/signals-long.source.js
deleted file mode 100644
index 06b541f..0000000
--- a/html5/test/case/signals/signals-long.source.js
+++ /dev/null
@@ -1,1223 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-new Promise(function () {})
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-;define('systemConfig', function (require, exports, module) {
- module.exports = {"isAliIntranet":false,"serverTime":"2016-07-04 17:00:00"};
- module.exports.serverTime = new Date(module.exports.serverTime).getTime();
- module.exports.clientTime = new Date().getTime();
-});
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-;define('zebraConfig', function (require, exports, module) {
- module.exports = {"spma":"0","spmb":"0","name":"zebra-act-item-240x240","title":"zebra-act-item-240x240","pageStatus":"online","modules":[{"name":"zebra-act-item-240x240","rmcId":"zebra-act-item-240x240","zebraId":"zebra-act-item-240x240","moduleId":"zebra-act-item-240x240","meta":{"size":"10px"}}],"closeCustom":true};
-});
-
-;define('zebraDoms', function (require, exports, module) {
- var els = [
- {"isZebraModule":true,"zebraId":"zebra-act-item-240x240","name":"zebra-act-item-240x240","data":{"$config":{"$dynamic":true,"mobileNoLogo":false},"item":[{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemIm
g":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png",
"itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/",
"itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpX
XQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":
567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","
brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.ali
cdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.al
icdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXX
XJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.
com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com
/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子
短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短
裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","bra
ndLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"item
MPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicd
n.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXX
XGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg"
:"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","i
temDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","i
temTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQ
U6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":56
7,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","br
andLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicd
n.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alic
dn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJ
XFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.co
m/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/t
ps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子�
�裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短�
�连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brand
Logo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMP
rice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.
com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXG
XFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"
http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","ite
mDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","ite
mTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6
CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,
"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","bran
dLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.
com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn
.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXF
XXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/
tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps
/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短�
��连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙�
��衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLo
go":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPri
ce":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.co
m/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXF
XXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"ht
tp://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemD
esc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemT
itle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CG
XXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"i
temActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandL
ogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.co
m/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.c
om/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXX
mqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tp
s/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i
1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙
连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连
衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo
":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice
":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/
tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXX
G9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http
://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDes
c":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTit
le":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXX
X-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"ite
mActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLog
o":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/
tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com
/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmq
jTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/
i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/
TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙�
�衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连�
�裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":
"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":
12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tp
s/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9
gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http:/
/gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc"
:"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle
":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-
348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemA
ctPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo"
:"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","itemTagPrice":567,"itemActPrice":356,"itemMPrice":123456,"itemActPriceTitle":"狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tp
s/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","itemTitle":"套头格子短裙连衣裙","couponValue":300,"couponUrl":"http://www.tmall.com/","itemTagPrice":567,"itemActPrice":356,"itemMPrice":12345.6,"itemActPriceTitle":"双11狂欢价","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/tps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","itemDesc":"全店满500送130!","btnText":""},{"itemImg":"http://gtms01.alicdn.com/tps/i1/TB1JQtzJFXXXXciXpXXQU6CGXXX-348-428.png","itemUrl":"http://www.tmall.com/","couponValue":10,"couponUrl":"http://www.tmall.com/","brandLogo":"http://gtms03.alicdn.com/tps/i3/TB1V8lkJFXXXXXGXFXXG9gsFXXX-140-70.png","iconImg":"http://gtms04.alicdn.com/t
ps/i4/TB1bURwJFXXXXXJXFXXmqjTHFXX-60-60.png","btnText":"快来买"},{"i
<TRUNCATED>
[06/22] incubator-weex git commit: * [jsfm] Adjust the file structure
of js framework
Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/ready.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/ready.source.js b/test/js-framework/case/basic/ready.source.js
new file mode 100644
index 0000000..08ee893
--- /dev/null
+++ b/test/js-framework/case/basic/ready.source.js
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/created', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ text: '',
+ }
+ },
+ ready: function() {
+ this.text = '1'
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "container",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": function() {
+ return this.text
+ }
+ }
+ }]
+ }
+
+ ;
+})
+
+// require module
+bootstrap('@weex-component/created', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-kv.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-kv.output.js b/test/js-framework/case/basic/repeat-array-kv.output.js
new file mode 100644
index 0000000..4d4991a
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-kv.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '0: Hello World1'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '1: Hello World2'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-kv.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-kv.source.js b/test/js-framework/case/basic/repeat-array-kv.source.js
new file mode 100644
index 0000000..21f26c7
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-kv.source.js
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-array-kv', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {text: 'Hello World1'},
+ {text: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": {
+ expression: function() { return this.titlelist },
+ key: 'index',
+ value: 'title'
+ },
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.index + ': ' + this.title.text}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-array-kv')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-no-kv.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-no-kv.output.js b/test/js-framework/case/basic/repeat-array-no-kv.output.js
new file mode 100644
index 0000000..4d4991a
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-no-kv.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '0: Hello World1'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '1: Hello World2'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-no-kv.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-no-kv.source.js b/test/js-framework/case/basic/repeat-array-no-kv.source.js
new file mode 100644
index 0000000..910bf04
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-no-kv.source.js
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-array-no-kv', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {text: 'Hello World1'},
+ {text: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": {
+ expression: function() { return this.titlelist }
+ },
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.$index + ': ' + this.$value.text}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-array-no-kv')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-non-obj.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-non-obj.output.js b/test/js-framework/case/basic/repeat-array-non-obj.output.js
new file mode 100644
index 0000000..4d4991a
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-non-obj.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '0: Hello World1'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '1: Hello World2'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-non-obj.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-non-obj.source.js b/test/js-framework/case/basic/repeat-array-non-obj.source.js
new file mode 100644
index 0000000..71de5d2
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-non-obj.source.js
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-array-non-obj', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ 'Hello World1',
+ 'Hello World2'
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": {
+ expression: function() { return this.titlelist },
+ value: 'title'
+ },
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.$index + ': ' + this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-array-non-obj')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-v.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-v.output.js b/test/js-framework/case/basic/repeat-array-v.output.js
new file mode 100644
index 0000000..4d4991a
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-v.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '0: Hello World1'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '1: Hello World2'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-array-v.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-array-v.source.js b/test/js-framework/case/basic/repeat-array-v.source.js
new file mode 100644
index 0000000..0fecb04
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-array-v.source.js
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-array-v', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {text: 'Hello World1'},
+ {text: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": {
+ expression: function() { return this.titlelist },
+ value: 'title'
+ },
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.$index + ': ' + this.title.text}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-array-v')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-index.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-index.output.js b/test/js-framework/case/basic/repeat-index.output.js
new file mode 100644
index 0000000..4d4991a
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-index.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '0: Hello World1'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: '1: Hello World2'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-index.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-index.source.js b/test/js-framework/case/basic/repeat-index.source.js
new file mode 100644
index 0000000..5bdc4ea
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-index.source.js
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-index', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {title: 'Hello World1'},
+ {title: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": function () {return this.titlelist},
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.$index + ': ' + this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-index')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-root.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-root.output.js b/test/js-framework/case/basic/repeat-root.output.js
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-root.output.js
@@ -0,0 +1 @@
+{}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-root.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-root.source.js b/test/js-framework/case/basic/repeat-root.source.js
new file mode 100644
index 0000000..ac79ae4
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-root.source.js
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-root', function (require, exports, module) {
+
+;module.exports = {
+ data: function () {return {
+ containers: [
+ {name: 'a'},
+ {name: 'b'}
+ ]
+ }}
+}
+
+;module.exports.template = {
+ "type": "container",
+ "repeat": function () {return this.containers},
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "container"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-root')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-watch.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-watch.output.js b/test/js-framework/case/basic/repeat-watch.output.js
new file mode 100644
index 0000000..1170f8b
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-watch.output.js
@@ -0,0 +1,46 @@
+{
+ "type": "list",
+ "children": [{
+ "type": "cell",
+ "attr": {
+ "append": "tree"
+ },
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": 1
+ },
+ "style": {
+ "height": 600
+ }
+ }]
+ }, {
+ "type": "cell",
+ "attr": {
+ "append": "tree"
+ },
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": 2
+ },
+ "style": {
+ "height": 600
+ }
+ }]
+ }, {
+ "type": "cell",
+ "attr": {
+ "append": "tree"
+ },
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": 3
+ },
+ "style": {
+ "height": 600
+ }
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/repeat-watch.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/repeat-watch.source.js b/test/js-framework/case/basic/repeat-watch.source.js
new file mode 100644
index 0000000..0f989d8
--- /dev/null
+++ b/test/js-framework/case/basic/repeat-watch.source.js
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/04f1048c50eca3454bc70de93d3213d4', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ list: [{
+ text: 1
+ }, {
+ text: 2
+ }],
+ more: [{
+ text: 3
+ }]
+ }
+ },
+ ready: function() {
+ for (var i = 0; i < this.more.length; i++) {
+ this.list.push(this.more[i]);
+ }
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "list",
+ "children": [{
+ "type": "cell",
+ "append": "tree",
+ "repeat": function() {
+ return this.list
+ },
+ "children": [{
+ "type": "text",
+ "style": {
+ "height": 600
+ },
+ "attr": {
+ "value": function() {
+ return this.text
+ }
+ }
+ }]
+ }]
+ }
+
+ ;
+})
+
+// require module
+bootstrap('@weex-component/04f1048c50eca3454bc70de93d3213d4', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/require.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/require.output.js b/test/js-framework/case/basic/require.output.js
new file mode 100644
index 0000000..51c886e
--- /dev/null
+++ b/test/js-framework/case/basic/require.output.js
@@ -0,0 +1,9 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Hello World'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/require.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/require.source.js b/test/js-framework/case/basic/require.source.js
new file mode 100644
index 0000000..db1fed7
--- /dev/null
+++ b/test/js-framework/case/basic/require.source.js
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var browserifyRequire=function r(e,n,o){function t(u,i){if(!n[u]){if(!e[u]){var a="function"==typeof browserifyRequire&&browserifyRequire;if(!i&&a)return a(u,!0);if(f)return f(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[u]={exports:{}};e[u][0].call(l.exports,function(r){var n=e[u][1][r];return t(n?n:r)},l,l.exports,r,e,n,o)}return n[u].exports}for(var f="function"==typeof browserifyRequire&&browserifyRequire,u=0;u<o.length;u++)t(o[u]);return t}({"1ba80324acff072bbb2b768911a5e4f1":[function(r,e,n){e.exports="Hello World"},{}]},{},[]);
+
+
+define('@weex-component/foo', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ text: ''
+ }},
+ created: function() {
+ this.text = browserifyRequire("1ba80324acff072bbb2b768911a5e4f1")
+ }
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.text}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+bootstrap('@weex-component/foo', {"transformerVersion":"0.3.0"})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/reset-style.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/reset-style.output.js b/test/js-framework/case/basic/reset-style.output.js
new file mode 100644
index 0000000..ed6bbaf
--- /dev/null
+++ b/test/js-framework/case/basic/reset-style.output.js
@@ -0,0 +1,15 @@
+{
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "Hello Weex"
+ },
+ "style": {
+ "fontSize": 40,
+ "color": ""
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/reset-style.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/reset-style.source.js b/test/js-framework/case/basic/reset-style.source.js
new file mode 100644
index 0000000..a96b891
--- /dev/null
+++ b/test/js-framework/case/basic/reset-style.source.js
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/reset-style', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ className: 'highlight'
+ }},
+ ready: function() {
+ this.className = 'normal'
+ }
+ }
+
+
+;module.exports.style = {
+ "normal": {
+ "fontSize": 40
+ },
+ "highlight": {
+ "fontSize": 60,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "classList": function () {return [this.className]},
+ "attr": {
+ "value": "Hello Weex"
+ }
+ }
+ ]
+}
+
+;})
+
+
+bootstrap('@weex-component/reset-style')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static1.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static1.output.js b/test/js-framework/case/basic/static1.output.js
new file mode 100644
index 0000000..e400730
--- /dev/null
+++ b/test/js-framework/case/basic/static1.output.js
@@ -0,0 +1,12 @@
+{
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "hello",
+ "static": ""
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static1.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static1.source.js b/test/js-framework/case/basic/static1.source.js
new file mode 100644
index 0000000..575ef66
--- /dev/null
+++ b/test/js-framework/case/basic/static1.source.js
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/static1', function (require, exports, module) {
+
+;
+ module.exports = {
+ ready: function() {
+ this.x = 'world'
+ },
+ data: function () {return {
+ x: 'hello'
+ }}
+ }
+
+
+;module.exports.style = {
+}
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "static": "",
+ "value": function () {return this.x}
+ }
+ }
+ ]
+}
+
+;})
+
+
+bootstrap('@weex-component/static1')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static2.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static2.output.js b/test/js-framework/case/basic/static2.output.js
new file mode 100644
index 0000000..fd5ee57
--- /dev/null
+++ b/test/js-framework/case/basic/static2.output.js
@@ -0,0 +1,30 @@
+{
+ "type": "div",
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": 2
+ }
+ }
+ ]
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static2.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static2.source.js b/test/js-framework/case/basic/static2.source.js
new file mode 100644
index 0000000..93e1cf6
--- /dev/null
+++ b/test/js-framework/case/basic/static2.source.js
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/static2', function (require, exports, module) {
+
+;
+ module.exports = {
+ ready: function() {
+ this.arr.$set(2, 3)
+ },
+ data: function () {return {
+ arr: [1, 2]
+ }}
+ }
+
+
+;module.exports.style = {
+}
+
+;module.exports.template = {
+ "type": "div",
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "div",
+ "repeat": {
+ "expression": function () {return this.arr},
+ "value": "x"
+ },
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.x}
+ }
+ }
+ ]
+ }
+ ]
+}
+
+;})
+
+
+bootstrap('@weex-component/static2')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static3.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static3.output.js b/test/js-framework/case/basic/static3.output.js
new file mode 100644
index 0000000..73eaaab
--- /dev/null
+++ b/test/js-framework/case/basic/static3.output.js
@@ -0,0 +1,33 @@
+{
+ "type": "div",
+ "children": [
+ {
+ "type": "div",
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "div",
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": 2
+ }
+ }
+ ]
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static3.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static3.source.js b/test/js-framework/case/basic/static3.source.js
new file mode 100644
index 0000000..9179ea7
--- /dev/null
+++ b/test/js-framework/case/basic/static3.source.js
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/static3', function (require, exports, module) {
+
+;
+ module.exports = {
+ ready: function() {
+ this.arr.$set(2, 3)
+ },
+ data: function () {return {
+ arr: [1, 2]
+ }}
+ }
+
+
+;module.exports.style = {
+}
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "div",
+ "repeat": {
+ "expression": function () {return this.arr},
+ "value": "x"
+ },
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.x}
+ }
+ }
+ ]
+ }
+ ]
+}
+
+;})
+
+
+bootstrap('@weex-component/static3')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static4.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static4.output.js b/test/js-framework/case/basic/static4.output.js
new file mode 100644
index 0000000..a53e484
--- /dev/null
+++ b/test/js-framework/case/basic/static4.output.js
@@ -0,0 +1,35 @@
+{
+ "type": "div",
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "div",
+ "children": [
+ {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": 1
+ }
+ }
+ ]
+ },
+ {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": 2
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/static4.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/static4.source.js b/test/js-framework/case/basic/static4.source.js
new file mode 100644
index 0000000..fe31bcc
--- /dev/null
+++ b/test/js-framework/case/basic/static4.source.js
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+function otherNameFunction () {
+ var module = {}
+ var exports = {}
+ module.exports = exports
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "div",
+ "repeat": {
+ "expression": function () {return this.outer},
+ "value": "x"
+ },
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.x}
+ }
+ }
+ ]
+ }
+ ]
+ }
+
+ ;module.exports.data = function() {return {
+ outer: null
+ }}
+
+ return module.exports
+}
+
+// module
+
+define('@weex-component/static4', function (require, exports, module) {
+
+;
+ module.exports = {
+ "components": {
+ innertpl: otherNameFunction()
+ },
+ ready: function() {
+ this.arr.$set(2, 3)
+ },
+ data: function () {return {
+ arr: [1, 2]
+ }}
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "div",
+ "attr": {
+ "static": ""
+ },
+ "children": [
+ {
+ "type": "innertpl",
+ "attr": {
+ "outer": function () {return this.arr}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/static4')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/subvm.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/subvm.output.js b/test/js-framework/case/basic/subvm.output.js
new file mode 100644
index 0000000..b7acaa4
--- /dev/null
+++ b/test/js-framework/case/basic/subvm.output.js
@@ -0,0 +1,20 @@
+{
+ "type": "container",
+ "children": [{
+ "type": "container",
+ "style": {
+ "marginTop": 10
+ },
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "aa"
+ }
+ },{
+ "type": "text",
+ "attr": {
+ "value": "bb"
+ }
+ }]
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/subvm.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/subvm.source.js b/test/js-framework/case/basic/subvm.source.js
new file mode 100644
index 0000000..1b054a5
--- /dev/null
+++ b/test/js-framework/case/basic/subvm.source.js
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/innertpl', function (require, exports, module) {
+
+;
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.outerData.a}
+ }
+ },
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.outerData.b}
+ }
+ }
+ ]
+}
+
+;module.exports.created = function() {
+ this.outerData.a = 'aa'
+}
+
+;module.exports.methods = {
+ "ready": function() {
+ this.outerData.b = 'bb'
+ }
+}
+
+;})
+
+// module
+
+define('@weex-component/subvm', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ item: {a: 'a', b: 'b'},
+ className: 'fromOuter',
+ marginTop: 10
+ }}
+ }
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "innertpl",
+ "classList": function() {
+ return this.className
+ },
+ "style": {
+ marginTop: function() {
+ return this.marginTop
+ }
+ },
+ "events": {
+ "click": "clicked"
+ },
+ "attr": {
+ "outerData": function () {return this.item}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/subvm')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/transformer1.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/transformer1.output.js b/test/js-framework/case/basic/transformer1.output.js
new file mode 100644
index 0000000..1372f91
--- /dev/null
+++ b/test/js-framework/case/basic/transformer1.output.js
@@ -0,0 +1,3 @@
+{
+ type: 'container'
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/basic/transformer1.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/basic/transformer1.source.js b/test/js-framework/case/basic/transformer1.source.js
new file mode 100644
index 0000000..7985e28
--- /dev/null
+++ b/test/js-framework/case/basic/transformer1.source.js
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 1
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "a": {
+ "fontSize": 12
+ }
+}
+
+;module.exports.template = {
+ "type": "container"
+}
+
+;})
+
+
+bootstrap('@weex-component/foo', {
+ 'transformerVersion': '0.3.0'
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/append-root-event.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/append-root-event.output.js b/test/js-framework/case/complex/append-root-event.output.js
new file mode 100644
index 0000000..2a1b77c
--- /dev/null
+++ b/test/js-framework/case/complex/append-root-event.output.js
@@ -0,0 +1,13 @@
+{
+ type: 'div',
+ attr: {
+ append: "tree"
+ },
+ children: [{
+ type: 'text',
+ event: ['click'],
+ attr: {
+ value: 1
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/append-root-event.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/append-root-event.source.js b/test/js-framework/case/complex/append-root-event.source.js
new file mode 100644
index 0000000..49455e5
--- /dev/null
+++ b/test/js-framework/case/complex/append-root-event.source.js
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/append-root-event', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ x: 1
+ }
+ },
+ methods: {
+ update: function() {
+ this.x = 2
+ }
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "div",
+ "append": "tree",
+ "children": [{
+ "type": "text",
+ "events": {
+ "click": "update"
+ },
+ "attr": {
+ "value": function() {
+ return this.x
+ }
+ }
+ }]
+ }
+
+ ;
+})
+
+// require module
+
+bootstrap('@weex-component/append-root-event', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/click.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/click.output.js b/test/js-framework/case/complex/click.output.js
new file mode 100644
index 0000000..d19c92f
--- /dev/null
+++ b/test/js-framework/case/complex/click.output.js
@@ -0,0 +1,26 @@
+{
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'image',
+ attr: {
+ src: 'https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg'
+ },
+ style: {
+ width: 200,
+ height: 200
+ }
+ }, {
+ type: 'text',
+ attr: {
+ value: '一个超赞的宝贝标题'
+ },
+ style: {
+ flex: 1,
+ color: '#ff0000',
+ fontSize: 48,
+ fontWeight: 'bold',
+ backgroundColor: '#eeeeee'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/click.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/click.source.js b/test/js-framework/case/complex/click.source.js
new file mode 100644
index 0000000..039c98b
--- /dev/null
+++ b/test/js-framework/case/complex/click.source.js
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/click', function (require, exports, module) {
+
+;
+ module.exports = {
+ methods: {
+ gotoDetail: function () {
+ this.$openURL('https://item.taobao.com/item.htm?id=520421163634')
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "thumb": {
+ "width": 200,
+ "height": 200
+ },
+ "title": {
+ "flex": 1,
+ "color": "#ff0000",
+ "fontSize": 48,
+ "fontWeight": "bold",
+ "backgroundColor": "#eeeeee"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "events": {
+ "click": "gotoDetail"
+ },
+ "children": [
+ {
+ "type": "image",
+ "classList": [
+ "thumb"
+ ],
+ "attr": {
+ "src": "https://gd2.alicdn.com/bao/uploaded/i2/T14H1LFwBcXXXXXXXX_!!0-item_pic.jpg"
+ }
+ },
+ {
+ "type": "text",
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": "一个超赞的宝贝标题"
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/click')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/component-append-tree.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/component-append-tree.output.js b/test/js-framework/case/complex/component-append-tree.output.js
new file mode 100644
index 0000000..6c036ec
--- /dev/null
+++ b/test/js-framework/case/complex/component-append-tree.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'scroller',
+ children: [{
+ type: 'div',
+ attr: { "append": "node" },
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'ready'
+ }
+ }]
+ }, {
+ type: 'div',
+ attr: { "append": "tree" },
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'ready'
+ }
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/component-append-tree.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/component-append-tree.source.js b/test/js-framework/case/complex/component-append-tree.source.js
new file mode 100644
index 0000000..7088eea
--- /dev/null
+++ b/test/js-framework/case/complex/component-append-tree.source.js
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+define('@weex-component/sub', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ str: '-----'
+ }
+ },
+ ready: function() {
+ this.str = 'ready'
+ setTimeout(() => {
+ this.str = 'timeout'
+ }, 100)
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "text",
+ "attr": {
+ "value": function() {
+ return this.str
+ }
+ }
+ }
+
+ ;
+ })
+
+ // module
+
+ define('@weex-component/ad164d40f42747f598b56eccfd0eae8e', function(require, exports, module) {
+
+ ;
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "scroller",
+ "children": [{
+ "type": "div",
+ "append": "node",
+ "children": [{
+ "type": "sub"
+ }]
+ }, {
+ "type": "div",
+ "append": "tree",
+ "children": [{
+ "type": "sub"
+ }]
+ }]
+ }
+
+ ;
+ })
+
+ // require module
+ bootstrap('@weex-component/ad164d40f42747f598b56eccfd0eae8e', {
+ "transformerVersion": "0.4.3"
+ })
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/computed.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/computed.output.js b/test/js-framework/case/complex/computed.output.js
new file mode 100644
index 0000000..8c5534d
--- /dev/null
+++ b/test/js-framework/case/complex/computed.output.js
@@ -0,0 +1,15 @@
+{
+ type: 'container',
+ event: ['click'],
+ children: [{
+ type: 'text',
+ attr: {
+ value: 3
+ },
+ }, {
+ type: 'text',
+ attr: {
+ value: 3
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/computed.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/computed.source.js b/test/js-framework/case/complex/computed.source.js
new file mode 100644
index 0000000..8d59ca3
--- /dev/null
+++ b/test/js-framework/case/complex/computed.source.js
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/computed', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {x: 1, y: 2}
+ },
+ computed: {
+ n: function () {
+ return this.x + this.y
+ },
+ m: {
+ get: function () {
+ return this.x + this.y
+ },
+ set: function (v) {
+ this.y = v
+ }
+ }
+ },
+ methods: {
+ foo: function () {
+ this.m = 10
+ }
+ }
+ }
+
+
+;module.exports.template = {
+ "type": "container",
+ "events": {
+ "click": "foo"
+ },
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.n}
+ }
+ },
+ {
+ "type": "text",
+ "attr": {
+ "value": function () {return this.m}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/computed')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/if-refresh.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/if-refresh.output.js b/test/js-framework/case/complex/if-refresh.output.js
new file mode 100644
index 0000000..1372f91
--- /dev/null
+++ b/test/js-framework/case/complex/if-refresh.output.js
@@ -0,0 +1,3 @@
+{
+ type: 'container'
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/if-refresh.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/if-refresh.source.js b/test/js-framework/case/complex/if-refresh.source.js
new file mode 100644
index 0000000..3ebb80c
--- /dev/null
+++ b/test/js-framework/case/complex/if-refresh.source.js
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/if', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ showTitle: true,
+ title: 'Hello World'
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "shown": function () {return this.showTitle},
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/if')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/if-repeat-refresh.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/if-repeat-refresh.output.js b/test/js-framework/case/complex/if-repeat-refresh.output.js
new file mode 100644
index 0000000..d4831cc
--- /dev/null
+++ b/test/js-framework/case/complex/if-repeat-refresh.output.js
@@ -0,0 +1,22 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: 'Hello World2'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ value: 'Hello World3'
+ }
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/if-repeat-refresh.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/if-repeat-refresh.source.js b/test/js-framework/case/complex/if-repeat-refresh.source.js
new file mode 100644
index 0000000..aa62931
--- /dev/null
+++ b/test/js-framework/case/complex/if-repeat-refresh.source.js
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/if-repeat', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {showTitle: true, title: 'Hello World1'},
+ {showTitle: false, title: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": function () {return this.titlelist},
+ "shown": function () {return this.showTitle},
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "value": function () {return this.title}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/if-repeat')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/inline-click.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/inline-click.output.js b/test/js-framework/case/complex/inline-click.output.js
new file mode 100644
index 0000000..bf3208e
--- /dev/null
+++ b/test/js-framework/case/complex/inline-click.output.js
@@ -0,0 +1,14 @@
+{
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "Hello World1"
+ },
+ "event": [
+ "click"
+ ]
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/inline-click.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/inline-click.source.js b/test/js-framework/case/complex/inline-click.source.js
new file mode 100644
index 0000000..e447c9e
--- /dev/null
+++ b/test/js-framework/case/complex/inline-click.source.js
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/test', function (require, exports, module) {
+
+;
+module.exports = {
+ data: function () {return {
+ text: 'Hello World1'
+ }},
+ methods: {
+ clicked: function(text, e) {
+ this.text = text
+ }
+ }
+}
+
+
+;module.exports.style = {}
+
+;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "events": {
+ "click": function ($event) {this.clicked('Hello World2', $event)}
+ },
+ "attr": {
+ "value": function () {return this.text}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+bootstrap('@weex-component/test', {"transformerVersion":"0.3.0"})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/input-binding.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/input-binding.output.js b/test/js-framework/case/complex/input-binding.output.js
new file mode 100644
index 0000000..30b9957
--- /dev/null
+++ b/test/js-framework/case/complex/input-binding.output.js
@@ -0,0 +1,12 @@
+{
+ "children": [
+ {
+ "attr": {
+ "value": "abcde"
+ },
+ "event": ["change"],
+ "type": "input"
+ }
+ ],
+ "type": "div"
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/input-binding.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/input-binding.source.js b/test/js-framework/case/complex/input-binding.source.js
new file mode 100644
index 0000000..ae96760
--- /dev/null
+++ b/test/js-framework/case/complex/input-binding.source.js
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/d6b20355da35c77d07f0a11ec5256f42', function(require, exports, module) {
+
+ ;
+ module.exports = {
+ data: function() {
+ return {
+ x: 'abcde',
+ changes: []
+ }
+ },
+ methods: {
+ change: function(e) {
+ var value = e.target.attr.value
+ this.x = value
+ this.changes.push(value)
+ }
+ }
+ }
+
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ "type": "div",
+ "children": [{
+ "type": "input",
+ "attr": {
+ "value": function() {
+ return this.x
+ }
+ },
+ "events": {
+ "change": "change"
+ }
+ }, {
+ "type": "text",
+ "repeat": {
+ "expression": function() {
+ return this.changes
+ },
+ "key": "k",
+ "value": "v"
+ },
+ "attr": {
+ "value": function() {
+ return (this.k + 1) + ' - ' + (this.v)
+ }
+ }
+ }]
+ }
+
+ ;
+})
+
+// require module
+bootstrap('@weex-component/d6b20355da35c77d07f0a11ec5256f42', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/refresh2.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/refresh2.output.js b/test/js-framework/case/complex/refresh2.output.js
new file mode 100644
index 0000000..823fda9
--- /dev/null
+++ b/test/js-framework/case/complex/refresh2.output.js
@@ -0,0 +1,20 @@
+{
+ "type": "container",
+ "children": [{
+ "type": "container",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "bar1"
+ }
+ }, {
+ "type": "container",
+ "children": [{
+ "type": "text",
+ "attr": {
+ "value": "bar2-refresh"
+ }
+ }]
+ }]
+ }]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/refresh2.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/refresh2.source.js b/test/js-framework/case/complex/refresh2.source.js
new file mode 100644
index 0000000..6fa770c
--- /dev/null
+++ b/test/js-framework/case/complex/refresh2.source.js
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+define('@weex-component/bar1', function(require, exports, module) {;;
+ module.exports.template = {
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'bar1'
+ }
+ }, {
+ type: 'bar2',
+ id: 'bar2',
+ component: true
+ }]
+ }
+
+ ;
+ module.exports.methods = {
+ ready: function(isRefresh) {
+ if (isRefresh) {
+ this.$vm('bar2').ready(true)
+ }
+ }
+ }
+
+})
+
+define('@weex-component/bar2', function(require, exports, module) {;;
+ module.exports.template = {
+ type: 'container',
+ children: [{
+ type: 'text',
+ attr: {
+ value: function() {
+ return this.text
+ }
+ }
+ }]
+ }
+
+ ;
+ module.exports.data = function() {
+ return {
+ text: 'bar2'
+ }
+ }
+
+ ;
+ module.exports.methods = {
+ ready: function(isRefresh) {
+ if (isRefresh) {
+ this.text = 'bar2-refresh'
+ }
+ }
+ }
+
+
+})
+
+define('@weex-component/foo', function(require, exports, module) {
+
+ ;
+ module.exports.style = {}
+
+ ;
+ module.exports.template = {
+ type: 'container',
+ children: [{
+ type: 'bar1',
+ shown: function() {
+ return this.showbar1
+ },
+ id: 'bar1',
+ component: true
+ }]
+ }
+
+ ;
+ module.exports.data = function() {
+ return {
+ showbar1: false,
+ ext: {
+ showbar1: false
+ }
+ }
+ }
+
+ ;module.exports.methods = {
+ refreshData: function(data) {
+ for (var key in data) {
+ this[key] = data[key]
+ }
+ this.ready(true)
+ },
+ ready: function(isRefresh) {
+ var self = this
+ this.showbar1 = this.ext.showbar1
+
+ if (isRefresh) {
+ if (this.showbar1) {
+ this.$renderThen(() => {
+ this.$vm('bar1').$on('hook:ready', function() {
+ self.$vm('bar1').ready(true)
+ })
+ })
+ }
+ }
+ }
+ }
+
+})
+
+// require module
+
+bootstrap('@weex-component/foo')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/repeat-track-by.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/repeat-track-by.output.js b/test/js-framework/case/complex/repeat-track-by.output.js
new file mode 100644
index 0000000..7e64c10
--- /dev/null
+++ b/test/js-framework/case/complex/repeat-track-by.output.js
@@ -0,0 +1,24 @@
+{
+ type: 'container',
+ children: [{
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ trackBy: 'text',
+ value: '0: Hello World2'
+ }
+ }, {
+ type: 'text',
+ style: {
+ color: '#FF0000',
+ fontSize: 26
+ },
+ attr: {
+ trackBy: 'text',
+ value: '1: Hello World1'
+ }
+ }]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/repeat-track-by.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/repeat-track-by.source.js b/test/js-framework/case/complex/repeat-track-by.source.js
new file mode 100644
index 0000000..127acb0
--- /dev/null
+++ b/test/js-framework/case/complex/repeat-track-by.source.js
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/repeat-track-by', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {return {
+ titlelist: [
+ {text: 'Hello World1'},
+ {text: 'Hello World2'}
+ ]
+ }}
+ }
+
+
+;module.exports.style = {
+ "title": {
+ "fontSize": 26,
+ "color": "#FF0000"
+ }
+}
+
+;module.exports.template = {
+ "type": "container",
+ "children": [
+ {
+ "type": "text",
+ "repeat": {
+ expression: function() { return this.titlelist },
+ key: 'index',
+ value: 'title'
+ },
+ "classList": [
+ "title"
+ ],
+ "attr": {
+ "trackBy": "text",
+ "value": function () {return this.index + ': ' + this.title.text}
+ }
+ }
+ ]
+}
+
+;})
+
+// require module
+
+bootstrap('@weex-component/repeat-track-by')
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/transformer2.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/transformer2.output.js b/test/js-framework/case/complex/transformer2.output.js
new file mode 100644
index 0000000..1372f91
--- /dev/null
+++ b/test/js-framework/case/complex/transformer2.output.js
@@ -0,0 +1,3 @@
+{
+ type: 'container'
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/transformer2.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/transformer2.source.js b/test/js-framework/case/complex/transformer2.source.js
new file mode 100644
index 0000000..af31348
--- /dev/null
+++ b/test/js-framework/case/complex/transformer2.source.js
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 1
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "a": {
+ "fontSize": 12
+ }
+}
+
+;module.exports.template = {
+ "type": "container"
+}
+
+;})
+
+
+bootstrap('@weex-component/foo', {
+ 'transformerVersion': '0.0.1'
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/transformer3.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/transformer3.output.js b/test/js-framework/case/complex/transformer3.output.js
new file mode 100644
index 0000000..1372f91
--- /dev/null
+++ b/test/js-framework/case/complex/transformer3.output.js
@@ -0,0 +1,3 @@
+{
+ type: 'container'
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/complex/transformer3.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/complex/transformer3.source.js b/test/js-framework/case/complex/transformer3.source.js
new file mode 100644
index 0000000..2ca15a3
--- /dev/null
+++ b/test/js-framework/case/complex/transformer3.source.js
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+define('@weex-component/foo', function (require, exports, module) {
+
+;
+ module.exports = {
+ data: function () {
+ return {
+ x: 1
+ }
+ }
+ }
+
+
+;module.exports.style = {
+ "a": {
+ "fontSize": 12
+ }
+}
+
+;module.exports.template = {
+ "type": "container"
+}
+
+;})
+
+
+bootstrap('@weex-component/foo', {
+ 'transformerVersion': '9.9.9'
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-dep-target-error.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-dep-target-error.source.js b/test/js-framework/case/multi/clear-dep-target-error.source.js
new file mode 100644
index 0000000..0001d1c
--- /dev/null
+++ b/test/js-framework/case/multi/clear-dep-target-error.source.js
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+define('@weex-component/DepTargetError', function(require, exports, module) {
+
+ ;module.exports = {
+ data: function () {return {
+ a: {}
+ }}
+ }
+
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () { return this.a.x.y }
+ }
+ }
+ ]
+ }
+
+})
+
+bootstrap('@weex-component/DepTargetError', { "transformerVersion": "0.3.1" })
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-dep-target-fine.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-dep-target-fine.output.js b/test/js-framework/case/multi/clear-dep-target-fine.output.js
new file mode 100644
index 0000000..e129423
--- /dev/null
+++ b/test/js-framework/case/multi/clear-dep-target-fine.output.js
@@ -0,0 +1,11 @@
+{
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "correct"
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-dep-target-fine.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-dep-target-fine.source.js b/test/js-framework/case/multi/clear-dep-target-fine.source.js
new file mode 100644
index 0000000..fd7c7a2
--- /dev/null
+++ b/test/js-framework/case/multi/clear-dep-target-fine.source.js
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+define('@weex-component/DepTargetFine', function(require, exports, module) {
+
+ ;module.exports = {
+ data: function () {return {
+ lists: []
+ }},
+ created: function() {
+ this.lists.$set(0, 'correct')
+ }
+ }
+
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": function () { return this.lists[0] }
+ }
+ }
+ ]
+ }
+
+})
+
+bootstrap('@weex-component/DepTargetFine', { "transformerVersion": "0.3.1" })
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-moduleA.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-moduleA.output.js b/test/js-framework/case/multi/clear-moduleA.output.js
new file mode 100644
index 0000000..5e7eac3
--- /dev/null
+++ b/test/js-framework/case/multi/clear-moduleA.output.js
@@ -0,0 +1,12 @@
+{
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "event": ["click"],
+ "attr": {
+ "value": "sample"
+ }
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-moduleA.source.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-moduleA.source.js b/test/js-framework/case/multi/clear-moduleA.source.js
new file mode 100644
index 0000000..190b36f
--- /dev/null
+++ b/test/js-framework/case/multi/clear-moduleA.source.js
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+define('@weex-component/moduleA', function(require, exports, module) {
+
+ define('sample', function(require, exports, module) {
+ module.exports = { name: 'sample' }
+ })
+
+ ;module.exports = {
+ data: {
+ text: ''
+ },
+ methods: {
+ update: function() {
+ var outer = require('sample')
+ this.text = outer ? outer.name : 'nothing'
+ }
+ }
+ }
+
+
+ ;module.exports.style = {}
+
+ ;module.exports.template = {
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "events": {
+ "click": "update"
+ },
+ "attr": {
+ "value": function() { return this.text }
+ }
+ }
+ ]
+ }
+
+})
+
+// require module
+bootstrap('@weex-component/moduleA', {
+ "transformerVersion": "0.3.1"
+})
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/51dd277e/test/js-framework/case/multi/clear-moduleB.output.js
----------------------------------------------------------------------
diff --git a/test/js-framework/case/multi/clear-moduleB.output.js b/test/js-framework/case/multi/clear-moduleB.output.js
new file mode 100644
index 0000000..c31de94
--- /dev/null
+++ b/test/js-framework/case/multi/clear-moduleB.output.js
@@ -0,0 +1,11 @@
+{
+ "type": "div",
+ "children": [
+ {
+ "type": "text",
+ "attr": {
+ "value": "nothing"
+ }
+ }
+ ]
+}