mirror of https://github.com/vuejs/vue.git
refactor: remove weex from codebase
This commit is contained in:
parent
2d019e4e25
commit
d8c3bbfa44
|
@ -1,131 +0,0 @@
|
||||||
version: 2
|
|
||||||
|
|
||||||
defaults: &defaults
|
|
||||||
working_directory: ~/project/vue
|
|
||||||
docker:
|
|
||||||
- image: node:lts
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
install:
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- restore_cache:
|
|
||||||
keys:
|
|
||||||
- v1-vue-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
|
||||||
- v1-vue-{{ .Branch }}-
|
|
||||||
- v1-vue-
|
|
||||||
|
|
||||||
- run: npm install
|
|
||||||
- save_cache:
|
|
||||||
key: v1-vue-{{ .Branch }}-{{ checksum "yarn.lock" }}
|
|
||||||
paths:
|
|
||||||
- node_modules/
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: ~/project
|
|
||||||
paths:
|
|
||||||
- vue
|
|
||||||
|
|
||||||
lint-ts-types:
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- attach_workspace:
|
|
||||||
at: ~/project
|
|
||||||
- run: npm run lint
|
|
||||||
- run: npm run ts-check
|
|
||||||
- run: npm run test:types
|
|
||||||
|
|
||||||
test-cover:
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- attach_workspace:
|
|
||||||
at: ~/project
|
|
||||||
- run: npm run test:cover
|
|
||||||
- run:
|
|
||||||
name: report coverage stats for non-PRs
|
|
||||||
command: |
|
|
||||||
if [[ -z $CI_PULL_REQUEST ]]; then
|
|
||||||
./node_modules/.bin/codecov
|
|
||||||
fi
|
|
||||||
|
|
||||||
test-e2e:
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- attach_workspace:
|
|
||||||
at: ~/project
|
|
||||||
- run: npm run test:e2e -- --env phantomjs
|
|
||||||
|
|
||||||
test-ssr-weex:
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- attach_workspace:
|
|
||||||
at: ~/project
|
|
||||||
- run: npm run test:ssr
|
|
||||||
- run: npm run test:weex
|
|
||||||
|
|
||||||
trigger-regression-test:
|
|
||||||
<<: *defaults
|
|
||||||
steps:
|
|
||||||
- run:
|
|
||||||
command: |
|
|
||||||
curl --user ${CIRCLE_TOKEN}: \
|
|
||||||
--data build_parameters[CIRCLE_JOB]=update \
|
|
||||||
--data build_parameters[VUE_REVISION]=${CIRCLE_SHA1} \
|
|
||||||
https://circleci.com/api/v1.1/project/github/vuejs/regression-testing/tree/master
|
|
||||||
|
|
||||||
workflows:
|
|
||||||
version: 2
|
|
||||||
install-and-parallel-test:
|
|
||||||
jobs:
|
|
||||||
- install
|
|
||||||
- test-cover:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- lint-ts-types:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- test-e2e:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- test-ssr-weex:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- trigger-regression-test:
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- "2.6"
|
|
||||||
- regression-test
|
|
||||||
requires:
|
|
||||||
- test-cover
|
|
||||||
- lint-ts-types
|
|
||||||
- test-e2e
|
|
||||||
- test-ssr-weex
|
|
||||||
weekly_regression_test:
|
|
||||||
triggers:
|
|
||||||
- schedule:
|
|
||||||
# At 13:00 UTC (9:00 EDT) on every Monday
|
|
||||||
cron: "0 13 * * 1"
|
|
||||||
filters:
|
|
||||||
branches:
|
|
||||||
only: dev
|
|
||||||
jobs:
|
|
||||||
- install
|
|
||||||
- test-cover:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- lint-ts-types:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- test-e2e:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- test-ssr-weex:
|
|
||||||
requires:
|
|
||||||
- install
|
|
||||||
- trigger-regression-test:
|
|
||||||
requires:
|
|
||||||
- test-cover
|
|
||||||
- lint-ts-types
|
|
||||||
- test-e2e
|
|
||||||
- test-ssr-weex
|
|
23
.flowconfig
23
.flowconfig
|
@ -1,23 +0,0 @@
|
||||||
[ignore]
|
|
||||||
.*/node_modules/.*
|
|
||||||
.*/test/.*
|
|
||||||
.*/scripts/.*
|
|
||||||
.*/examples/.*
|
|
||||||
.*/benchmarks/.*
|
|
||||||
|
|
||||||
[include]
|
|
||||||
|
|
||||||
[libs]
|
|
||||||
flow
|
|
||||||
|
|
||||||
[options]
|
|
||||||
# unsafe.enable_getters_and_setters=true
|
|
||||||
module.name_mapper='^compiler/\(.*\)$' -> '<PROJECT_ROOT>/src/compiler/\1'
|
|
||||||
module.name_mapper='^core/\(.*\)$' -> '<PROJECT_ROOT>/src/core/\1'
|
|
||||||
module.name_mapper='^shared/\(.*\)$' -> '<PROJECT_ROOT>/src/shared/\1'
|
|
||||||
module.name_mapper='^web/\(.*\)$' -> '<PROJECT_ROOT>/src/platforms/web/\1'
|
|
||||||
module.name_mapper='^weex/\(.*\)$' -> '<PROJECT_ROOT>/src/platforms/weex/\1'
|
|
||||||
module.name_mapper='^server/\(.*\)$' -> '<PROJECT_ROOT>/src/server/\1'
|
|
||||||
module.name_mapper='^entries/\(.*\)$' -> '<PROJECT_ROOT>/src/entries/\1'
|
|
||||||
module.name_mapper='^sfc/\(.*\)$' -> '<PROJECT_ROOT>/src/sfc/\1'
|
|
||||||
# suppress_comment= \\(.\\|\n\\)*\\$flow-disable-line
|
|
17
package.json
17
package.json
|
@ -20,27 +20,16 @@
|
||||||
"dev:test": "karma start test/unit/karma.dev.config.ts",
|
"dev:test": "karma start test/unit/karma.dev.config.ts",
|
||||||
"dev:ssr": "rollup -w -c scripts/config.js --environment TARGET:web-server-renderer",
|
"dev:ssr": "rollup -w -c scripts/config.js --environment TARGET:web-server-renderer",
|
||||||
"dev:compiler": "rollup -w -c scripts/config.js --environment TARGET:web-compiler ",
|
"dev:compiler": "rollup -w -c scripts/config.js --environment TARGET:web-compiler ",
|
||||||
"dev:weex": "rollup -w -c scripts/config.js --environment TARGET:weex-framework",
|
|
||||||
"dev:weex:factory": "rollup -w -c scripts/config.js --environment TARGET:weex-factory",
|
|
||||||
"dev:weex:compiler": "rollup -w -c scripts/config.js --environment TARGET:weex-compiler ",
|
|
||||||
"build": "node scripts/build.js",
|
"build": "node scripts/build.js",
|
||||||
"build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
|
"build:ssr": "npm run build -- web-runtime-cjs,web-server-renderer",
|
||||||
"build:weex": "npm run build -- weex",
|
"test": "npm run lint && npm run ts-check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr",
|
||||||
"test": "npm run lint && npm run ts-check && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr && npm run test:weex",
|
"test:unit": "vitest run",
|
||||||
"test:dtw": "npm run lint && npm run test:types && npm run test:cover && npm run test:e2e -- --env phantomjs && npm run test:ssr && npm run test:weex",
|
|
||||||
"test:unit": "karma start test/unit/karma.unit.config.ts",
|
|
||||||
"test:cover": "karma start test/unit/karma.cover.config.ts",
|
|
||||||
"test:e2e": "npm run build -- web-full-prod,web-server-basic-renderer && node test/e2e/runner.ts",
|
"test:e2e": "npm run build -- web-full-prod,web-server-basic-renderer && node test/e2e/runner.ts",
|
||||||
"test:weex": "npm run build:weex && jasmine-ts JASMINE_CONFIG_PATH=test/weex/jasmine.ts",
|
|
||||||
"test:ssr": "npm run build:ssr && jasmine JASMINE_CONFIG_PATH=test/ssr/jasmine.ts",
|
|
||||||
"test:sauce": "npm run sauce -- 0 && npm run sauce -- 1 && npm run sauce -- 2",
|
|
||||||
"test:types": "tsc -p ./types/tsconfig.json",
|
"test:types": "tsc -p ./types/tsconfig.json",
|
||||||
"lint": "eslint src scripts test",
|
"lint": "eslint src scripts test",
|
||||||
"ts-check": "tsc --noEmit",
|
"ts-check": "tsc --noEmit",
|
||||||
"sauce": "karma start test/unit/karma.sauce.config.ts",
|
|
||||||
"bench:ssr": "npm run build:ssr && node benchmarks/ssr/renderToString.js && node benchmarks/ssr/renderToStream.js",
|
"bench:ssr": "npm run build:ssr && node benchmarks/ssr/renderToString.js && node benchmarks/ssr/renderToStream.js",
|
||||||
"release": "bash scripts/release.sh",
|
"release": "bash scripts/release.sh",
|
||||||
"release:weex": "bash scripts/release-weex.sh",
|
|
||||||
"release:note": "node scripts/gen-release-note.js",
|
"release:note": "node scripts/gen-release-note.js",
|
||||||
"commit": "git-cz"
|
"commit": "git-cz"
|
||||||
},
|
},
|
||||||
|
@ -110,8 +99,6 @@
|
||||||
"typescript": "^4.6.4",
|
"typescript": "^4.6.4",
|
||||||
"vitest": "^0.12.6",
|
"vitest": "^0.12.6",
|
||||||
"webpack": "^5.72.1",
|
"webpack": "^5.72.1",
|
||||||
"weex-js-runtime": "^0.23.6",
|
|
||||||
"weex-styler": "^0.3.0",
|
|
||||||
"yorkie": "^2.0.0"
|
"yorkie": "^2.0.0"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
|
|
@ -160,9 +160,6 @@ export interface ASTElement {
|
||||||
|
|
||||||
// 2.4 ssr optimization
|
// 2.4 ssr optimization
|
||||||
ssrOptimizability?: SSROptimizability;
|
ssrOptimizability?: SSROptimizability;
|
||||||
|
|
||||||
// weex specific
|
|
||||||
appendAsTree?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ASTExpression {
|
export interface ASTExpression {
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
# weex-template-compiler
|
|
||||||
|
|
||||||
> This package is auto-generated. For pull requests please see [src/platforms/weex/entry-compiler.js](https://github.com/vuejs/vue/tree/dev/src/platforms/weex/entry-compiler.js).
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +0,0 @@
|
||||||
try {
|
|
||||||
var vueVersion = require('weex-vue-framework').version
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
var packageName = require('./package.json').name
|
|
||||||
var packageVersion = require('./package.json').version
|
|
||||||
if (vueVersion && vueVersion !== packageVersion) {
|
|
||||||
throw new Error(
|
|
||||||
'\n\nVue packages version mismatch:\n\n' +
|
|
||||||
'- vue@' + vueVersion + '\n' +
|
|
||||||
'- ' + packageName + '@' + packageVersion + '\n\n' +
|
|
||||||
'This may cause things to work incorrectly. Make sure to use the same version for both.\n' +
|
|
||||||
'If you are using weex-vue-loader, re-installing them should bump ' + packageName + ' to the latest.\n'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = require('./build')
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"name": "weex-template-compiler",
|
|
||||||
"version": "2.4.2-weex.1",
|
|
||||||
"description": "Weex template compiler for Vue 2.0",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/vuejs/vue.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"vue",
|
|
||||||
"compiler"
|
|
||||||
],
|
|
||||||
"author": "Evan You",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/vuejs/vue/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/weex-template-compiler#readme",
|
|
||||||
"dependencies": {
|
|
||||||
"acorn": "^8.1.0",
|
|
||||||
"acorn-walk": "^8.0.2",
|
|
||||||
"escodegen": "^1.8.1",
|
|
||||||
"he": "^1.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
# weex-vue-framework
|
|
||||||
|
|
||||||
> This package is auto-generated. For pull requests please see [src/platforms/weex/entry-framework.js](https://github.com/vuejs/vue/blob/dev/src/platforms/weex/entry-framework.js).
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,203 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', { value: true });
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
// this will be preserved during build
|
|
||||||
// $flow-disable-line
|
|
||||||
var VueFactory = require('./factory');
|
|
||||||
|
|
||||||
var instanceOptions = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create instance context.
|
|
||||||
*/
|
|
||||||
function createInstanceContext (
|
|
||||||
instanceId,
|
|
||||||
runtimeContext,
|
|
||||||
data
|
|
||||||
) {
|
|
||||||
if ( data === void 0 ) data = {};
|
|
||||||
|
|
||||||
var weex = runtimeContext.weex;
|
|
||||||
var instance = instanceOptions[instanceId] = {
|
|
||||||
instanceId: instanceId,
|
|
||||||
config: weex.config,
|
|
||||||
document: weex.document,
|
|
||||||
data: data
|
|
||||||
};
|
|
||||||
|
|
||||||
// Each instance has an independent `Vue` module instance
|
|
||||||
var Vue = instance.Vue = createVueModuleInstance(instanceId, weex);
|
|
||||||
|
|
||||||
// DEPRECATED
|
|
||||||
var timerAPIs = getInstanceTimer(instanceId, weex.requireModule);
|
|
||||||
|
|
||||||
var instanceContext = Object.assign({ Vue: Vue }, timerAPIs);
|
|
||||||
Object.freeze(instanceContext);
|
|
||||||
return instanceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy an instance with id. It will make sure all memory of
|
|
||||||
* this instance released and no more leaks.
|
|
||||||
*/
|
|
||||||
function destroyInstance (instanceId) {
|
|
||||||
var instance = instanceOptions[instanceId];
|
|
||||||
if (instance && instance.app instanceof instance.Vue) {
|
|
||||||
try {
|
|
||||||
instance.app.$destroy();
|
|
||||||
instance.document.destroy();
|
|
||||||
} catch (e) {}
|
|
||||||
delete instance.document;
|
|
||||||
delete instance.app;
|
|
||||||
}
|
|
||||||
delete instanceOptions[instanceId];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh an instance with id and new top-level component data.
|
|
||||||
* It will use `Vue.set` on all keys of the new data. So it's better
|
|
||||||
* define all possible meaningful keys when instance created.
|
|
||||||
*/
|
|
||||||
function refreshInstance (
|
|
||||||
instanceId,
|
|
||||||
data
|
|
||||||
) {
|
|
||||||
var instance = instanceOptions[instanceId];
|
|
||||||
if (!instance || !(instance.app instanceof instance.Vue)) {
|
|
||||||
return new Error(("refreshInstance: instance " + instanceId + " not found!"))
|
|
||||||
}
|
|
||||||
if (instance.Vue && instance.Vue.set) {
|
|
||||||
for (var key in data) {
|
|
||||||
instance.Vue.set(instance.app, key, data[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Finally `refreshFinish` signal needed.
|
|
||||||
instance.document.taskCenter.send('dom', { action: 'refreshFinish' }, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a fresh instance of Vue for each Weex instance.
|
|
||||||
*/
|
|
||||||
function createVueModuleInstance (
|
|
||||||
instanceId,
|
|
||||||
weex
|
|
||||||
) {
|
|
||||||
var exports = {};
|
|
||||||
VueFactory(exports, weex.document);
|
|
||||||
var Vue = exports.Vue;
|
|
||||||
|
|
||||||
var instance = instanceOptions[instanceId];
|
|
||||||
|
|
||||||
// patch reserved tag detection to account for dynamically registered
|
|
||||||
// components
|
|
||||||
var weexRegex = /^weex:/i;
|
|
||||||
var isReservedTag = Vue.config.isReservedTag || (function () { return false; });
|
|
||||||
var isRuntimeComponent = Vue.config.isRuntimeComponent || (function () { return false; });
|
|
||||||
Vue.config.isReservedTag = function (name) {
|
|
||||||
return (!isRuntimeComponent(name) && weex.supports(("@component/" + name))) ||
|
|
||||||
isReservedTag(name) ||
|
|
||||||
weexRegex.test(name)
|
|
||||||
};
|
|
||||||
Vue.config.parsePlatformTagName = function (name) { return name.replace(weexRegex, ''); };
|
|
||||||
|
|
||||||
// expose weex-specific info
|
|
||||||
Vue.prototype.$instanceId = instanceId;
|
|
||||||
Vue.prototype.$document = instance.document;
|
|
||||||
|
|
||||||
// expose weex native module getter on subVue prototype so that
|
|
||||||
// vdom runtime modules can access native modules via vnode.context
|
|
||||||
Vue.prototype.$requireWeexModule = weex.requireModule;
|
|
||||||
|
|
||||||
// Hack `Vue` behavior to handle instance information and data
|
|
||||||
// before root component created.
|
|
||||||
Vue.mixin({
|
|
||||||
beforeCreate: function beforeCreate () {
|
|
||||||
var options = this.$options;
|
|
||||||
// root component (vm)
|
|
||||||
if (options.el) {
|
|
||||||
// set external data of instance
|
|
||||||
var dataOption = options.data;
|
|
||||||
var internalData = (typeof dataOption === 'function' ? dataOption() : dataOption) || {};
|
|
||||||
options.data = Object.assign(internalData, instance.data);
|
|
||||||
// record instance by id
|
|
||||||
instance.app = this;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: function mounted () {
|
|
||||||
var options = this.$options;
|
|
||||||
// root component (vm)
|
|
||||||
if (options.el && weex.document && instance.app === this) {
|
|
||||||
try {
|
|
||||||
// Send "createFinish" signal to native.
|
|
||||||
weex.document.taskCenter.send('dom', { action: 'createFinish' }, []);
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Just instance variable `weex.config`
|
|
||||||
* Get instance config.
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
Vue.prototype.$getConfig = function () {
|
|
||||||
if (instance.app instanceof Vue) {
|
|
||||||
return instance.config
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Vue
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED
|
|
||||||
* Generate HTML5 Timer APIs. An important point is that the callback
|
|
||||||
* will be converted into callback id when sent to native. So the
|
|
||||||
* framework can make sure no side effect of the callback happened after
|
|
||||||
* an instance destroyed.
|
|
||||||
*/
|
|
||||||
function getInstanceTimer (
|
|
||||||
instanceId,
|
|
||||||
moduleGetter
|
|
||||||
) {
|
|
||||||
var instance = instanceOptions[instanceId];
|
|
||||||
var timer = moduleGetter('timer');
|
|
||||||
var timerAPIs = {
|
|
||||||
setTimeout: function () {
|
|
||||||
var args = [], len = arguments.length;
|
|
||||||
while ( len-- ) args[ len ] = arguments[ len ];
|
|
||||||
|
|
||||||
var handler = function () {
|
|
||||||
args[0].apply(args, args.slice(2));
|
|
||||||
};
|
|
||||||
|
|
||||||
timer.setTimeout(handler, args[1]);
|
|
||||||
return instance.document.taskCenter.callbackManager.lastCallbackId.toString()
|
|
||||||
},
|
|
||||||
setInterval: function () {
|
|
||||||
var args = [], len = arguments.length;
|
|
||||||
while ( len-- ) args[ len ] = arguments[ len ];
|
|
||||||
|
|
||||||
var handler = function () {
|
|
||||||
args[0].apply(args, args.slice(2));
|
|
||||||
};
|
|
||||||
|
|
||||||
timer.setInterval(handler, args[1]);
|
|
||||||
return instance.document.taskCenter.callbackManager.lastCallbackId.toString()
|
|
||||||
},
|
|
||||||
clearTimeout: function (n) {
|
|
||||||
timer.clearTimeout(n);
|
|
||||||
},
|
|
||||||
clearInterval: function (n) {
|
|
||||||
timer.clearInterval(n);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return timerAPIs
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.createInstanceContext = createInstanceContext;
|
|
||||||
exports.destroyInstance = destroyInstance;
|
|
||||||
exports.refreshInstance = refreshInstance;
|
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"name": "weex-vue-framework",
|
|
||||||
"version": "2.4.2-weex.1",
|
|
||||||
"description": "Vue 2.0 Framework for Weex",
|
|
||||||
"main": "index.js",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/vuejs/vue.git"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"vue",
|
|
||||||
"compiler"
|
|
||||||
],
|
|
||||||
"author": "Evan You",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/vuejs/vue/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/weex-vue-framework#readme"
|
|
||||||
}
|
|
|
@ -44,8 +44,6 @@ specifiers:
|
||||||
typescript: ^4.6.4
|
typescript: ^4.6.4
|
||||||
vitest: ^0.12.6
|
vitest: ^0.12.6
|
||||||
webpack: ^5.72.1
|
webpack: ^5.72.1
|
||||||
weex-js-runtime: ^0.23.6
|
|
||||||
weex-styler: ^0.3.0
|
|
||||||
yorkie: ^2.0.0
|
yorkie: ^2.0.0
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
@ -92,8 +90,6 @@ devDependencies:
|
||||||
typescript: 4.6.4
|
typescript: 4.6.4
|
||||||
vitest: 0.12.6_jsdom@19.0.0
|
vitest: 0.12.6_jsdom@19.0.0
|
||||||
webpack: 5.72.1
|
webpack: 5.72.1
|
||||||
weex-js-runtime: 0.23.7
|
|
||||||
weex-styler: 0.3.1
|
|
||||||
yorkie: 2.0.0
|
yorkie: 2.0.0
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
@ -837,12 +833,6 @@ packages:
|
||||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/atob/2.1.2:
|
|
||||||
resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==}
|
|
||||||
engines: {node: '>= 4.5.0'}
|
|
||||||
hasBin: true
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/balanced-match/1.0.2:
|
/balanced-match/1.0.2:
|
||||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -1315,15 +1305,6 @@ packages:
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/css/2.2.4:
|
|
||||||
resolution: {integrity: sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==}
|
|
||||||
dependencies:
|
|
||||||
inherits: 2.0.4
|
|
||||||
source-map: 0.6.1
|
|
||||||
source-map-resolve: 0.5.3
|
|
||||||
urix: 0.1.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/cssom/0.3.8:
|
/cssom/0.3.8:
|
||||||
resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
|
resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -1448,11 +1429,6 @@ packages:
|
||||||
resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==}
|
resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/decode-uri-component/0.2.0:
|
|
||||||
resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=}
|
|
||||||
engines: {node: '>=0.10'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/dedent/0.7.0:
|
/dedent/0.7.0:
|
||||||
resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=}
|
resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -3629,11 +3605,6 @@ packages:
|
||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/resolve-url/0.2.1:
|
|
||||||
resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=}
|
|
||||||
deprecated: https://github.com/lydell/resolve-url#deprecated
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/resolve/1.22.0:
|
/resolve/1.22.0:
|
||||||
resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
|
resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
@ -3861,17 +3832,6 @@ packages:
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/source-map-resolve/0.5.3:
|
|
||||||
resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==}
|
|
||||||
deprecated: See https://github.com/lydell/source-map-resolve#deprecated
|
|
||||||
dependencies:
|
|
||||||
atob: 2.1.2
|
|
||||||
decode-uri-component: 0.2.0
|
|
||||||
resolve-url: 0.2.1
|
|
||||||
source-map-url: 0.4.1
|
|
||||||
urix: 0.1.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/source-map-support/0.5.21:
|
/source-map-support/0.5.21:
|
||||||
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -3879,11 +3839,6 @@ packages:
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/source-map-url/0.4.1:
|
|
||||||
resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==}
|
|
||||||
deprecated: See https://github.com/lydell/source-map-url#deprecated
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/source-map/0.5.6:
|
/source-map/0.5.6:
|
||||||
resolution: {integrity: sha1-dc449SvwczxafwwRjYEzSiu19BI=}
|
resolution: {integrity: sha1-dc449SvwczxafwwRjYEzSiu19BI=}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -4350,11 +4305,6 @@ packages:
|
||||||
punycode: 2.1.1
|
punycode: 2.1.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/urix/0.1.0:
|
|
||||||
resolution: {integrity: sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=}
|
|
||||||
deprecated: Please see https://github.com/lydell/urix#deprecated
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/url-join/4.0.1:
|
/url-join/4.0.1:
|
||||||
resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
|
resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -4510,17 +4460,6 @@ packages:
|
||||||
- uglify-js
|
- uglify-js
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/weex-js-runtime/0.23.7:
|
|
||||||
resolution: {integrity: sha512-3BFd5GXTo0X/GWh0KjzXDpIcPJuSwYuc9fE9llgez35IfVHs/nUmfkFBjifzxOJS2YLhtKf0Cy8eTQ00CJDWZA==}
|
|
||||||
engines: {node: '>=4'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/weex-styler/0.3.1:
|
|
||||||
resolution: {integrity: sha512-xkX5/wS/QLiJXKwbdpeytbLN0kHviQwj9CLdvBxqu+RRZABZpTniKZr1oxjh9Q0+n/aRC+smwFpQpUKvXh9V1g==}
|
|
||||||
dependencies:
|
|
||||||
css: 2.2.4
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/whatwg-encoding/2.0.0:
|
/whatwg-encoding/2.0.0:
|
||||||
resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
|
resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
|
|
|
@ -8,7 +8,6 @@ module.exports = {
|
||||||
core: resolve('src/core'),
|
core: resolve('src/core'),
|
||||||
shared: resolve('src/shared'),
|
shared: resolve('src/shared'),
|
||||||
web: resolve('src/platforms/web'),
|
web: resolve('src/platforms/web'),
|
||||||
weex: resolve('src/platforms/weex'),
|
|
||||||
server: resolve('src/server'),
|
server: resolve('src/server'),
|
||||||
sfc: resolve('src/sfc')
|
sfc: resolve('src/sfc')
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,6 @@ if (process.argv[2]) {
|
||||||
builds = builds.filter(b => {
|
builds = builds.filter(b => {
|
||||||
return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
|
return filters.some(f => b.output.file.indexOf(f) > -1 || b._name.indexOf(f) > -1)
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
// filter out weex builds by default
|
|
||||||
builds = builds.filter(b => {
|
|
||||||
return b.output.file.indexOf('weex') === -1
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build(builds)
|
build(builds)
|
||||||
|
|
|
@ -6,9 +6,6 @@ const node = require('@rollup/plugin-node-resolve').nodeResolve
|
||||||
const ts = require('rollup-plugin-typescript2')
|
const ts = require('rollup-plugin-typescript2')
|
||||||
|
|
||||||
const version = process.env.VERSION || require('../package.json').version
|
const version = process.env.VERSION || require('../package.json').version
|
||||||
const weexVersion =
|
|
||||||
process.env.WEEX_VERSION ||
|
|
||||||
require('../packages/weex-vue-framework/package.json').version
|
|
||||||
const featureFlags = require('./feature-flags')
|
const featureFlags = require('./feature-flags')
|
||||||
|
|
||||||
const banner =
|
const banner =
|
||||||
|
@ -18,15 +15,6 @@ const banner =
|
||||||
' * Released under the MIT License.\n' +
|
' * Released under the MIT License.\n' +
|
||||||
' */'
|
' */'
|
||||||
|
|
||||||
const weexFactoryPlugin = {
|
|
||||||
intro() {
|
|
||||||
return 'module.exports = function weexFactory (exports, document) {'
|
|
||||||
},
|
|
||||||
outro() {
|
|
||||||
return '}'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const aliases = require('./alias')
|
const aliases = require('./alias')
|
||||||
const resolve = (p) => {
|
const resolve = (p) => {
|
||||||
const base = p.split('/')[0]
|
const base = p.split('/')[0]
|
||||||
|
@ -199,31 +187,6 @@ const builds = {
|
||||||
external: Object.keys(
|
external: Object.keys(
|
||||||
require('../packages/vue-server-renderer/package.json').dependencies
|
require('../packages/vue-server-renderer/package.json').dependencies
|
||||||
)
|
)
|
||||||
},
|
|
||||||
// Weex runtime factory
|
|
||||||
'weex-factory': {
|
|
||||||
weex: true,
|
|
||||||
entry: resolve('weex/entry-runtime-factory.ts'),
|
|
||||||
dest: resolve('packages/weex-vue-framework/factory.js'),
|
|
||||||
format: 'cjs',
|
|
||||||
plugins: [weexFactoryPlugin]
|
|
||||||
},
|
|
||||||
// Weex runtime framework (CommonJS).
|
|
||||||
'weex-framework': {
|
|
||||||
weex: true,
|
|
||||||
entry: resolve('weex/entry-framework.ts'),
|
|
||||||
dest: resolve('packages/weex-vue-framework/index.js'),
|
|
||||||
format: 'cjs'
|
|
||||||
},
|
|
||||||
// Weex compiler (CommonJS). Used by Weex's Webpack loader.
|
|
||||||
'weex-compiler': {
|
|
||||||
weex: true,
|
|
||||||
entry: resolve('weex/entry-compiler.ts'),
|
|
||||||
dest: resolve('packages/weex-template-compiler/build.js'),
|
|
||||||
format: 'cjs',
|
|
||||||
external: Object.keys(
|
|
||||||
require('../packages/weex-template-compiler/package.json').dependencies
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,8 +230,6 @@ function genConfig(name) {
|
||||||
|
|
||||||
// built-in vars
|
// built-in vars
|
||||||
const vars = {
|
const vars = {
|
||||||
__WEEX__: !!opts.weex,
|
|
||||||
__WEEX_VERSION__: weexVersion,
|
|
||||||
__VERSION__: version,
|
__VERSION__: version,
|
||||||
__SSR_TEST__: false
|
__SSR_TEST__: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
const coreVersion = require('../package.json').version
|
|
||||||
const weexVersion = require('../packages/weex-vue-framework/package.json').version
|
|
||||||
let weexBaseVersion = weexVersion.match(/^[\d.]+/)[0]
|
|
||||||
let weexSubVersion = Number(weexVersion.match(/-weex\.(\d+)$/)[1])
|
|
||||||
|
|
||||||
if (weexBaseVersion === coreVersion) {
|
|
||||||
// same core version, increment sub version
|
|
||||||
weexSubVersion++
|
|
||||||
} else {
|
|
||||||
// new core version, reset sub version
|
|
||||||
weexBaseVersion = coreVersion
|
|
||||||
weexSubVersion = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.argv[2] === '-c') {
|
|
||||||
console.log(weexVersion)
|
|
||||||
} else {
|
|
||||||
console.log(weexBaseVersion + '-weex.' + weexSubVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
base: weexBaseVersion,
|
|
||||||
sub: weexSubVersion
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
CUR_VERSION=$(node build/get-weex-version.js -c)
|
|
||||||
NEXT_VERSION=$(node build/get-weex-version.js)
|
|
||||||
|
|
||||||
echo "Current: $CUR_VERSION"
|
|
||||||
read -p "Enter new version ($NEXT_VERSION): " -n 1 -r
|
|
||||||
if ! [[ -z $REPLY ]]; then
|
|
||||||
NEXT_VERSION=$REPLY
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -p "Releasing weex-vue-framework@$NEXT_VERSION - are you sure? (y/n) " -n 1 -r
|
|
||||||
echo
|
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
||||||
echo "Releasing weex-vue-framework@$NEXT_VERSION ..."
|
|
||||||
npm run lint
|
|
||||||
npm run flow
|
|
||||||
npm run test:weex
|
|
||||||
|
|
||||||
# build
|
|
||||||
WEEX_VERSION=$NEXT_VERSION npm run build:weex
|
|
||||||
|
|
||||||
# update package
|
|
||||||
# using subshells to avoid having to cd back
|
|
||||||
( cd packages/weex-vue-framework
|
|
||||||
npm version "$NEXT_VERSION"
|
|
||||||
npm publish
|
|
||||||
)
|
|
||||||
|
|
||||||
( cd packages/weex-template-compiler
|
|
||||||
npm version "$NEXT_VERSION"
|
|
||||||
npm publish
|
|
||||||
)
|
|
||||||
|
|
||||||
# commit
|
|
||||||
git add packages/weex*
|
|
||||||
git commit -m "[release] weex-vue-framework@$NEXT_VERSION"
|
|
||||||
fi
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/
|
const fnExpRE = /^([\w$_]+|\([^)]*?\))\s*=>|^function(?:\s+[\w$]+)?\s*\(/
|
||||||
const fnInvokeRE = /\([^)]*?\);*$/
|
const fnInvokeRE = /\([^)]*?\);*$/
|
||||||
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
|
const simplePathRE =
|
||||||
|
/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
|
||||||
|
|
||||||
// KeyboardEvent.keyCode aliases
|
// KeyboardEvent.keyCode aliases
|
||||||
const keyCodes: { [key: string]: number | Array<number> } = {
|
const keyCodes: { [key: string]: number | Array<number> } = {
|
||||||
|
@ -13,7 +13,7 @@ const keyCodes: { [key: string]: number | Array<number> } = {
|
||||||
left: 37,
|
left: 37,
|
||||||
right: 39,
|
right: 39,
|
||||||
down: 40,
|
down: 40,
|
||||||
delete: [8, 46],
|
delete: [8, 46]
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyboardEvent.key aliases
|
// KeyboardEvent.key aliases
|
||||||
|
@ -30,7 +30,7 @@ const keyNames: { [key: string]: string | Array<string> } = {
|
||||||
right: ['Right', 'ArrowRight'],
|
right: ['Right', 'ArrowRight'],
|
||||||
down: ['Down', 'ArrowDown'],
|
down: ['Down', 'ArrowDown'],
|
||||||
// #9112: IE11 uses `Del` for Delete key name.
|
// #9112: IE11 uses `Del` for Delete key name.
|
||||||
delete: ['Backspace', 'Delete', 'Del'],
|
delete: ['Backspace', 'Delete', 'Del']
|
||||||
}
|
}
|
||||||
|
|
||||||
// #4868: modifiers that prevent the execution of the listener
|
// #4868: modifiers that prevent the execution of the listener
|
||||||
|
@ -48,7 +48,7 @@ const modifierCode: { [key: string]: string } = {
|
||||||
meta: genGuard(`!$event.metaKey`),
|
meta: genGuard(`!$event.metaKey`),
|
||||||
left: genGuard(`'button' in $event && $event.button !== 0`),
|
left: genGuard(`'button' in $event && $event.button !== 0`),
|
||||||
middle: genGuard(`'button' in $event && $event.button !== 1`),
|
middle: genGuard(`'button' in $event && $event.button !== 1`),
|
||||||
right: genGuard(`'button' in $event && $event.button !== 2`),
|
right: genGuard(`'button' in $event && $event.button !== 2`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function genHandlers(
|
export function genHandlers(
|
||||||
|
@ -75,28 +75,6 @@ export function genHandlers(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate handler code with binding params on Weex
|
|
||||||
/* istanbul ignore next */
|
|
||||||
function genWeexHandler(params: Array<any>, handlerCode: string) {
|
|
||||||
let innerHandlerCode = handlerCode
|
|
||||||
const exps = params.filter(
|
|
||||||
(exp) => simplePathRE.test(exp) && exp !== '$event'
|
|
||||||
)
|
|
||||||
const bindings = exps.map((exp) => ({ '@binding': exp }))
|
|
||||||
const args = exps.map((exp, i) => {
|
|
||||||
const key = `$_${i + 1}`
|
|
||||||
innerHandlerCode = innerHandlerCode.replace(exp, key)
|
|
||||||
return key
|
|
||||||
})
|
|
||||||
args.push('$event')
|
|
||||||
return (
|
|
||||||
'{\n' +
|
|
||||||
`handler:function(${args.join(',')}){${innerHandlerCode}},\n` +
|
|
||||||
`params:${JSON.stringify(bindings)}\n` +
|
|
||||||
'}'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function genHandler(
|
function genHandler(
|
||||||
handler: ASTElementHandler | Array<ASTElementHandler>
|
handler: ASTElementHandler | Array<ASTElementHandler>
|
||||||
): string {
|
): string {
|
||||||
|
@ -118,10 +96,6 @@ function genHandler(
|
||||||
if (isMethodPath || isFunctionExpression) {
|
if (isMethodPath || isFunctionExpression) {
|
||||||
return handler.value
|
return handler.value
|
||||||
}
|
}
|
||||||
/* istanbul ignore if */
|
|
||||||
if (__WEEX__ && handler.params) {
|
|
||||||
return genWeexHandler(handler.params, handler.value)
|
|
||||||
}
|
|
||||||
return `function($event){${
|
return `function($event){${
|
||||||
isFunctionInvocation ? `return ${handler.value}` : handler.value
|
isFunctionInvocation ? `return ${handler.value}` : handler.value
|
||||||
}}` // inline statement
|
}}` // inline statement
|
||||||
|
@ -162,10 +136,6 @@ function genHandler(
|
||||||
: isFunctionInvocation
|
: isFunctionInvocation
|
||||||
? `return ${handler.value}`
|
? `return ${handler.value}`
|
||||||
: handler.value
|
: handler.value
|
||||||
/* istanbul ignore if */
|
|
||||||
if (__WEEX__ && handler.params) {
|
|
||||||
return genWeexHandler(handler.params, code + handlerCode)
|
|
||||||
}
|
|
||||||
return `function($event){${code}${handlerCode}}`
|
return `function($event){${code}${handlerCode}}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { genHandlers } from './events'
|
import { genHandlers } from './events'
|
||||||
import baseDirectives from '../directives/index'
|
import baseDirectives from '../directives/index'
|
||||||
import { camelize, no, extend } from 'shared/util'
|
import { camelize, no, extend } from 'shared/util'
|
||||||
|
@ -58,7 +57,7 @@ export function generate(
|
||||||
: '_c("div")'
|
: '_c("div")'
|
||||||
return {
|
return {
|
||||||
render: `with(this){return ${code}}`,
|
render: `with(this){return ${code}}`,
|
||||||
staticRenderFns: state.staticRenderFns,
|
staticRenderFns: state.staticRenderFns
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,14 +560,17 @@ function genSlot(el: ASTElement, state: CodegenState): string {
|
||||||
const slotName = el.slotName || '"default"'
|
const slotName = el.slotName || '"default"'
|
||||||
const children = genChildren(el, state)
|
const children = genChildren(el, state)
|
||||||
let res = `_t(${slotName}${children ? `,function(){return ${children}}` : ''}`
|
let res = `_t(${slotName}${children ? `,function(){return ${children}}` : ''}`
|
||||||
const attrs = el.attrs || el.dynamicAttrs
|
const attrs =
|
||||||
? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
|
el.attrs || el.dynamicAttrs
|
||||||
// slot props are camelized
|
? genProps(
|
||||||
name: camelize(attr.name),
|
(el.attrs || []).concat(el.dynamicAttrs || []).map((attr) => ({
|
||||||
value: attr.value,
|
// slot props are camelized
|
||||||
dynamic: attr.dynamic
|
name: camelize(attr.name),
|
||||||
})))
|
value: attr.value,
|
||||||
: null
|
dynamic: attr.dynamic
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
: null
|
||||||
const bind = el.attrsMap['v-bind']
|
const bind = el.attrsMap['v-bind']
|
||||||
if ((attrs || bind) && !children) {
|
if ((attrs || bind) && !children) {
|
||||||
res += `,null`
|
res += `,null`
|
||||||
|
@ -599,9 +601,7 @@ function genProps(props: Array<ASTAttr>): string {
|
||||||
let dynamicProps = ``
|
let dynamicProps = ``
|
||||||
for (let i = 0; i < props.length; i++) {
|
for (let i = 0; i < props.length; i++) {
|
||||||
const prop = props[i]
|
const prop = props[i]
|
||||||
const value = __WEEX__
|
const value = transformSpecialNewlines(prop.value)
|
||||||
? generateValue(prop.value)
|
|
||||||
: transformSpecialNewlines(prop.value)
|
|
||||||
if (prop.dynamic) {
|
if (prop.dynamic) {
|
||||||
dynamicProps += `${prop.name},${value},`
|
dynamicProps += `${prop.name},${value},`
|
||||||
} else {
|
} else {
|
||||||
|
@ -616,14 +616,6 @@ function genProps(props: Array<ASTAttr>): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* istanbul ignore next */
|
|
||||||
function generateValue(value) {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
return transformSpecialNewlines(value)
|
|
||||||
}
|
|
||||||
return JSON.stringify(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// #3895, #4268
|
// #3895, #4268
|
||||||
function transformSpecialNewlines(text: string): string {
|
function transformSpecialNewlines(text: string): string {
|
||||||
return text.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')
|
return text.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
|
|
||||||
// can we use __proto__?
|
// can we use __proto__?
|
||||||
export const hasProto = '__proto__' in {}
|
export const hasProto = '__proto__' in {}
|
||||||
|
|
||||||
// Browser environment sniffing
|
// Browser environment sniffing
|
||||||
export const inBrowser = typeof window !== 'undefined'
|
export const inBrowser = typeof window !== 'undefined'
|
||||||
export const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
|
|
||||||
export const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
|
|
||||||
export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
|
export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
|
||||||
export const isIE = UA && /msie|trident/.test(UA)
|
export const isIE = UA && /msie|trident/.test(UA)
|
||||||
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
|
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
|
||||||
export const isEdge = UA && UA.indexOf('edge/') > 0
|
export const isEdge = UA && UA.indexOf('edge/') > 0
|
||||||
export const isAndroid =
|
export const isAndroid = UA && UA.indexOf('android') > 0
|
||||||
(UA && UA.indexOf('android') > 0) || weexPlatform === 'android'
|
export const isIOS = UA && /iphone|ipad|ipod|ios/.test(UA)
|
||||||
export const isIOS =
|
|
||||||
(UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === 'ios'
|
|
||||||
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
|
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
|
||||||
export const isPhantomJS = UA && /phantomjs/.test(UA)
|
export const isPhantomJS = UA && /phantomjs/.test(UA)
|
||||||
export const isFF = UA && UA.match(/firefox\/(\d+)/)
|
export const isFF = UA && UA.match(/firefox\/(\d+)/)
|
||||||
|
@ -30,7 +25,7 @@ if (inBrowser) {
|
||||||
get() {
|
get() {
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
supportsPassive = true
|
supportsPassive = true
|
||||||
},
|
}
|
||||||
} as object) // https://github.com/facebook/flow/issues/285
|
} as object) // https://github.com/facebook/flow/issues/285
|
||||||
window.addEventListener('test-passive', null as any, opts)
|
window.addEventListener('test-passive', null as any, opts)
|
||||||
} catch (e: any) {}
|
} catch (e: any) {}
|
||||||
|
@ -42,7 +37,7 @@ let _isServer
|
||||||
export const isServerRendering = () => {
|
export const isServerRendering = () => {
|
||||||
if (_isServer === undefined) {
|
if (_isServer === undefined) {
|
||||||
/* istanbul ignore if */
|
/* istanbul ignore if */
|
||||||
if (!inBrowser && !inWeex && typeof global !== 'undefined') {
|
if (!inBrowser && typeof global !== 'undefined') {
|
||||||
// detect presence of vue-server-renderer and avoid
|
// detect presence of vue-server-renderer and avoid
|
||||||
// Webpack shimming the process
|
// Webpack shimming the process
|
||||||
_isServer =
|
_isServer =
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import { warn } from './debug'
|
import { warn } from './debug'
|
||||||
import { observe, toggleObserving, shouldObserve } from '../observer/index'
|
import { observe, toggleObserving, shouldObserve } from '../observer/index'
|
||||||
import {
|
import {
|
||||||
|
@ -7,7 +6,7 @@ import {
|
||||||
toRawType,
|
toRawType,
|
||||||
hyphenate,
|
hyphenate,
|
||||||
capitalize,
|
capitalize,
|
||||||
isPlainObject,
|
isPlainObject
|
||||||
} from 'shared/util'
|
} from 'shared/util'
|
||||||
import type { Component } from 'typescript/component'
|
import type { Component } from 'typescript/component'
|
||||||
|
|
||||||
|
@ -51,11 +50,7 @@ export function validateProp(
|
||||||
observe(value)
|
observe(value)
|
||||||
toggleObserving(prevShouldObserve)
|
toggleObserving(prevShouldObserve)
|
||||||
}
|
}
|
||||||
if (
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
process.env.NODE_ENV !== 'production' &&
|
|
||||||
// skip validation for weex recycle-list child component props
|
|
||||||
!(__WEEX__ && isObject(value) && '@binding' in value)
|
|
||||||
) {
|
|
||||||
assertProp(prop, key, value, vm, absent)
|
assertProp(prop, key, value, vm, absent)
|
||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
|
@ -182,7 +177,7 @@ function assertType(
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
valid,
|
valid,
|
||||||
expectedType,
|
expectedType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,6 @@ import {
|
||||||
deactivateChildComponent,
|
deactivateChildComponent,
|
||||||
} from '../instance/lifecycle'
|
} from '../instance/lifecycle'
|
||||||
|
|
||||||
import {
|
|
||||||
isRecyclableComponent,
|
|
||||||
renderRecyclableComponentTemplate,
|
|
||||||
} from 'weex/runtime/recycle-list/render-component-template'
|
|
||||||
import type {
|
import type {
|
||||||
MountedComponentVNode,
|
MountedComponentVNode,
|
||||||
VNodeData,
|
VNodeData,
|
||||||
|
@ -206,14 +202,6 @@ export function createComponent(
|
||||||
asyncFactory
|
asyncFactory
|
||||||
)
|
)
|
||||||
|
|
||||||
// Weex specific: invoke recycle-list optimized @render function for
|
|
||||||
// extracting cell-slot template.
|
|
||||||
// https://github.com/Hanks10100/weex-native-directive/tree/master/component
|
|
||||||
/* istanbul ignore if */
|
|
||||||
if (__WEEX__ && isRecyclableComponent(vnode)) {
|
|
||||||
return renderRecyclableComponentTemplate(vnode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return vnode
|
return vnode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
import VNode, { createEmptyVNode } from './vnode'
|
import VNode, { createEmptyVNode } from './vnode'
|
||||||
import { createComponent } from './create-component'
|
import { createComponent } from './create-component'
|
||||||
|
@ -11,7 +10,7 @@ import {
|
||||||
isTrue,
|
isTrue,
|
||||||
isObject,
|
isObject,
|
||||||
isPrimitive,
|
isPrimitive,
|
||||||
resolveAsset,
|
resolveAsset
|
||||||
} from '../util/index'
|
} from '../util/index'
|
||||||
|
|
||||||
import { normalizeChildren, simpleNormalizeChildren } from './helpers/index'
|
import { normalizeChildren, simpleNormalizeChildren } from './helpers/index'
|
||||||
|
@ -74,14 +73,11 @@ export function _createElement(
|
||||||
isDef(data.key) &&
|
isDef(data.key) &&
|
||||||
!isPrimitive(data.key)
|
!isPrimitive(data.key)
|
||||||
) {
|
) {
|
||||||
// @ts-expect-error
|
warn(
|
||||||
if (!__WEEX__ || !('@binding' in data.key)) {
|
'Avoid using non-primitive value as key, ' +
|
||||||
warn(
|
'use string/number value instead.',
|
||||||
'Avoid using non-primitive value as key, ' +
|
context
|
||||||
'use string/number value instead.',
|
)
|
||||||
context
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// support single function children as default scoped slot
|
// support single function children as default scoped slot
|
||||||
if (Array.isArray(children) && typeof children[0] === 'function') {
|
if (Array.isArray(children) && typeof children[0] === 'function') {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { warn, invokeWithErrorHandling } from 'core/util/index'
|
import { warn, invokeWithErrorHandling } from 'core/util/index'
|
||||||
import { cached, isUndef, isTrue, isPlainObject } from 'shared/util'
|
import { cached, isUndef, isTrue } from 'shared/util'
|
||||||
import type { Component } from 'typescript/component'
|
import type { Component } from 'typescript/component'
|
||||||
|
|
||||||
const normalizeEvent = cached((name: string): {
|
const normalizeEvent = cached((name: string): {
|
||||||
|
@ -69,11 +69,6 @@ export function updateListeners(
|
||||||
def = cur = on[name]
|
def = cur = on[name]
|
||||||
old = oldOn[name]
|
old = oldOn[name]
|
||||||
event = normalizeEvent(name)
|
event = normalizeEvent(name)
|
||||||
/* istanbul ignore if */
|
|
||||||
if (__WEEX__ && isPlainObject(def)) {
|
|
||||||
cur = def.handler
|
|
||||||
event.params = def.params
|
|
||||||
}
|
|
||||||
if (isUndef(cur)) {
|
if (isUndef(cur)) {
|
||||||
process.env.NODE_ENV !== 'production' &&
|
process.env.NODE_ENV !== 'production' &&
|
||||||
warn(
|
warn(
|
||||||
|
|
|
@ -170,32 +170,11 @@ export function createPatchFunction(backend) {
|
||||||
: nodeOps.createElement(tag, vnode)
|
: nodeOps.createElement(tag, vnode)
|
||||||
setScope(vnode)
|
setScope(vnode)
|
||||||
|
|
||||||
/* istanbul ignore if */
|
createChildren(vnode, children, insertedVnodeQueue)
|
||||||
if (__WEEX__) {
|
if (isDef(data)) {
|
||||||
// in Weex, the default insertion order is parent-first.
|
invokeCreateHooks(vnode, insertedVnodeQueue)
|
||||||
// List items can be optimized to use children-first insertion
|
|
||||||
// with append="tree".
|
|
||||||
const appendAsTree = isDef(data) && isTrue(data.appendAsTree)
|
|
||||||
if (!appendAsTree) {
|
|
||||||
if (isDef(data)) {
|
|
||||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
|
||||||
}
|
|
||||||
insert(parentElm, vnode.elm, refElm)
|
|
||||||
}
|
|
||||||
createChildren(vnode, children, insertedVnodeQueue)
|
|
||||||
if (appendAsTree) {
|
|
||||||
if (isDef(data)) {
|
|
||||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
|
||||||
}
|
|
||||||
insert(parentElm, vnode.elm, refElm)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
createChildren(vnode, children, insertedVnodeQueue)
|
|
||||||
if (isDef(data)) {
|
|
||||||
invokeCreateHooks(vnode, insertedVnodeQueue)
|
|
||||||
}
|
|
||||||
insert(parentElm, vnode.elm, refElm)
|
|
||||||
}
|
}
|
||||||
|
insert(parentElm, vnode.elm, refElm)
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production' && data && data.pre) {
|
if (process.env.NODE_ENV !== 'production' && data && data.pre) {
|
||||||
creatingElmInVPre--
|
creatingElmInVPre--
|
||||||
|
|
|
@ -1,32 +1,9 @@
|
||||||
declare const __WEEX__: boolean;
|
|
||||||
declare const __SSR_TEST__: boolean;
|
declare const __SSR_TEST__: boolean;
|
||||||
declare type WeexEnvironment = {
|
|
||||||
platform: string; // could be "Web", "iOS", "Android"
|
|
||||||
weexVersion: string; // the version of WeexSDK
|
|
||||||
|
|
||||||
osName: string; // could be "iOS", "Android" or others
|
|
||||||
osVersion: string;
|
|
||||||
appName: string; // mobile app name or browser name
|
|
||||||
appVersion: string;
|
|
||||||
|
|
||||||
// information about current running device
|
|
||||||
deviceModel: string; // phone device model
|
|
||||||
deviceWidth: number;
|
|
||||||
deviceHeight: number;
|
|
||||||
scale: number;
|
|
||||||
|
|
||||||
// only available on the web
|
|
||||||
userAgent?: string;
|
|
||||||
dpr?: number;
|
|
||||||
rem?: number;
|
|
||||||
};
|
|
||||||
declare let WXEnvironment: WeexEnvironment;
|
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
__VUE_DEVTOOLS_GLOBAL_HOOK__: DevtoolsHook;
|
__VUE_DEVTOOLS_GLOBAL_HOOK__: DevtoolsHook;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// from https://github.com/vuejs/vue-devtools/blob/bc719c95a744614f5c3693460b64dc21dfa339a8/packages/app-backend-api/src/global-hook.ts#L3
|
// from https://github.com/vuejs/vue-devtools/blob/bc719c95a744614f5c3693460b64dc21dfa339a8/packages/app-backend-api/src/global-hook.ts#L3
|
||||||
interface DevtoolsHook {
|
interface DevtoolsHook {
|
||||||
emit: (event: string, ...payload: any[]) => void
|
emit: (event: string, ...payload: any[]) => void
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
import model from './model'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
model,
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
|
|
||||||
import { addHandler, addAttr } from 'compiler/helpers'
|
|
||||||
import { genComponentModel, genAssignmentCode } from 'compiler/directives/model'
|
|
||||||
|
|
||||||
export default function model(el: ASTElement, dir: ASTDirective): void {
|
|
||||||
if (el.tag === 'input' || el.tag === 'textarea') {
|
|
||||||
genDefaultModel(el, dir.value, dir.modifiers)
|
|
||||||
} else {
|
|
||||||
genComponentModel(el, dir.value, dir.modifiers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function genDefaultModel(
|
|
||||||
el: ASTElement,
|
|
||||||
value: string,
|
|
||||||
modifiers: ASTModifiers | null
|
|
||||||
) {
|
|
||||||
const { lazy, trim, number } = modifiers || {}
|
|
||||||
const event = lazy ? 'change' : 'input'
|
|
||||||
|
|
||||||
let valueExpression = `$event.target.attr.value${trim ? '.trim()' : ''}`
|
|
||||||
if (number) {
|
|
||||||
valueExpression = `_n(${valueExpression})`
|
|
||||||
}
|
|
||||||
|
|
||||||
const code = genAssignmentCode(value, valueExpression)
|
|
||||||
addAttr(el, 'value', `(${value})`)
|
|
||||||
addHandler(el, event, code, null, true)
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
import { genStaticKeys } from 'shared/util'
|
|
||||||
import { createCompiler } from 'compiler/index'
|
|
||||||
|
|
||||||
import modules from './modules/index'
|
|
||||||
import directives from './directives/index'
|
|
||||||
|
|
||||||
import {
|
|
||||||
isUnaryTag,
|
|
||||||
mustUseProp,
|
|
||||||
isReservedTag,
|
|
||||||
canBeLeftOpenTag,
|
|
||||||
getTagNamespace,
|
|
||||||
} from '../util/element'
|
|
||||||
import type { WeexCompiledResult, WeexCompilerOptions } from 'typescript/weex'
|
|
||||||
|
|
||||||
export const baseOptions: WeexCompilerOptions = {
|
|
||||||
modules,
|
|
||||||
directives,
|
|
||||||
isUnaryTag,
|
|
||||||
mustUseProp,
|
|
||||||
canBeLeftOpenTag,
|
|
||||||
isReservedTag,
|
|
||||||
getTagNamespace,
|
|
||||||
preserveWhitespace: false,
|
|
||||||
recyclable: false,
|
|
||||||
staticKeys: genStaticKeys(modules),
|
|
||||||
}
|
|
||||||
|
|
||||||
const compiler = createCompiler(baseOptions)
|
|
||||||
|
|
||||||
export function compile(
|
|
||||||
template: string,
|
|
||||||
options?: WeexCompilerOptions
|
|
||||||
): WeexCompiledResult {
|
|
||||||
let generateAltRender = false
|
|
||||||
if (options && options.recyclable === true) {
|
|
||||||
generateAltRender = true
|
|
||||||
options.recyclable = false
|
|
||||||
}
|
|
||||||
const result = compiler.compile(template, options)
|
|
||||||
|
|
||||||
// generate @render function for <recycle-list>
|
|
||||||
if (options && generateAltRender) {
|
|
||||||
options.recyclable = true
|
|
||||||
// disable static optimizations
|
|
||||||
options.optimize = false
|
|
||||||
const { render } = compiler.compile(template, options)
|
|
||||||
result['@render'] = render
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
|
|
||||||
import { makeMap } from 'shared/util'
|
|
||||||
|
|
||||||
// The "unitary tag" means that the tag node and its children
|
|
||||||
// must be sent to the native together.
|
|
||||||
const isUnitaryTag = makeMap('cell,header,cell-slot,recycle-list', true)
|
|
||||||
|
|
||||||
function preTransformNode(el: ASTElement) {
|
|
||||||
if (
|
|
||||||
isUnitaryTag(el.tag) &&
|
|
||||||
!el.attrsList.some((item) => item.name === 'append')
|
|
||||||
) {
|
|
||||||
el.attrsMap.append = 'tree'
|
|
||||||
el.attrsList.push({ name: 'append', value: 'tree' })
|
|
||||||
}
|
|
||||||
if (el.attrsMap.append === 'tree') {
|
|
||||||
el.appendAsTree = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function genData(el: ASTElement): string {
|
|
||||||
return el.appendAsTree ? `appendAsTree:true,` : ''
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
staticKeys: ['appendAsTree'],
|
|
||||||
preTransformNode,
|
|
||||||
genData,
|
|
||||||
} as ModuleOptions
|
|
|
@ -1,75 +0,0 @@
|
||||||
|
|
||||||
import { parseText } from 'compiler/parser/text-parser'
|
|
||||||
import { getAndRemoveAttr, getBindingAttr, baseWarn } from 'compiler/helpers'
|
|
||||||
|
|
||||||
type StaticClassResult = {
|
|
||||||
dynamic: boolean
|
|
||||||
classResult: string
|
|
||||||
}
|
|
||||||
|
|
||||||
function transformNode(el: ASTElement, options: CompilerOptions) {
|
|
||||||
const warn = options.warn || baseWarn
|
|
||||||
const staticClass = getAndRemoveAttr(el, 'class')
|
|
||||||
const { dynamic, classResult } = parseStaticClass(staticClass, options)
|
|
||||||
if (process.env.NODE_ENV !== 'production' && dynamic && staticClass) {
|
|
||||||
warn(
|
|
||||||
`class="${staticClass}": ` +
|
|
||||||
'Interpolation inside attributes has been deprecated. ' +
|
|
||||||
'Use v-bind or the colon shorthand instead.',
|
|
||||||
el.rawAttrsMap['class']
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!dynamic && classResult) {
|
|
||||||
el.staticClass = classResult
|
|
||||||
}
|
|
||||||
const classBinding = getBindingAttr(el, 'class', false /* getStatic */)
|
|
||||||
if (classBinding) {
|
|
||||||
el.classBinding = classBinding
|
|
||||||
} else if (dynamic) {
|
|
||||||
el.classBinding = classResult
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function genData(el: ASTElement): string {
|
|
||||||
let data = ''
|
|
||||||
if (el.staticClass) {
|
|
||||||
data += `staticClass:${el.staticClass},`
|
|
||||||
}
|
|
||||||
if (el.classBinding) {
|
|
||||||
data += `class:${el.classBinding},`
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseStaticClass(
|
|
||||||
staticClass: string | null | undefined,
|
|
||||||
options: CompilerOptions
|
|
||||||
): StaticClassResult {
|
|
||||||
// "a b c" -> ["a", "b", "c"] => staticClass: ["a", "b", "c"]
|
|
||||||
// "a {{x}} c" -> ["a", x, "c"] => classBinding: '["a", x, "c"]'
|
|
||||||
let dynamic = false
|
|
||||||
let classResult = ''
|
|
||||||
if (staticClass) {
|
|
||||||
const classList = staticClass
|
|
||||||
.trim()
|
|
||||||
.split(' ')
|
|
||||||
.map((name) => {
|
|
||||||
const result = parseText(name, options.delimiters)
|
|
||||||
if (result) {
|
|
||||||
dynamic = true
|
|
||||||
return result.expression
|
|
||||||
}
|
|
||||||
return JSON.stringify(name)
|
|
||||||
})
|
|
||||||
if (classList.length) {
|
|
||||||
classResult = '[' + classList.join(',') + ']'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { dynamic, classResult }
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
staticKeys: ['staticClass'],
|
|
||||||
transformNode,
|
|
||||||
genData,
|
|
||||||
} as ModuleOptions
|
|
|
@ -1,7 +0,0 @@
|
||||||
import klass from './class'
|
|
||||||
import style from './style'
|
|
||||||
import props from './props'
|
|
||||||
import append from './append'
|
|
||||||
import recycleList from './recycle-list/index'
|
|
||||||
|
|
||||||
export default [recycleList, klass, style, props, append]
|
|
|
@ -1,36 +0,0 @@
|
||||||
|
|
||||||
import { cached, camelize } from 'shared/util'
|
|
||||||
|
|
||||||
const normalize = cached(camelize)
|
|
||||||
|
|
||||||
function normalizeKeyName(str: string): string {
|
|
||||||
if (str.match(/^v\-/)) {
|
|
||||||
return str.replace(/(v-[a-z\-]+\:)([a-z\-]+)$/i, ($, directive, prop) => {
|
|
||||||
return directive + normalize(prop)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return normalize(str)
|
|
||||||
}
|
|
||||||
|
|
||||||
function transformNode(el: ASTElement) {
|
|
||||||
if (Array.isArray(el.attrsList)) {
|
|
||||||
el.attrsList.forEach((attr) => {
|
|
||||||
if (attr.name && attr.name.match(/\-/)) {
|
|
||||||
const realName = normalizeKeyName(attr.name)
|
|
||||||
if (el.attrsMap) {
|
|
||||||
el.attrsMap[realName] = el.attrsMap[attr.name]
|
|
||||||
delete el.attrsMap[attr.name]
|
|
||||||
}
|
|
||||||
if (el.rawAttrsMap && el.rawAttrsMap[attr.name]) {
|
|
||||||
el.rawAttrsMap[realName] = el.rawAttrsMap[attr.name]
|
|
||||||
// $flow-disable-line
|
|
||||||
delete el.rawAttrsMap[attr.name]
|
|
||||||
}
|
|
||||||
attr.name = realName
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default {
|
|
||||||
transformNode,
|
|
||||||
} as ModuleOptions
|
|
|
@ -1,12 +0,0 @@
|
||||||
|
|
||||||
import { addAttr } from 'compiler/helpers'
|
|
||||||
|
|
||||||
// mark component root nodes as
|
|
||||||
export function postTransformComponentRoot(el: ASTElement) {
|
|
||||||
if (!el.parent) {
|
|
||||||
// component root
|
|
||||||
addAttr(el, '@isComponentRoot', 'true')
|
|
||||||
addAttr(el, '@templateId', '_uid')
|
|
||||||
addAttr(el, '@componentProps', '$props || {}')
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
|
|
||||||
import { addAttr } from 'compiler/helpers'
|
|
||||||
import type { WeexCompilerOptions } from 'typescript/weex'
|
|
||||||
import { RECYCLE_LIST_MARKER } from 'weex/util/index'
|
|
||||||
|
|
||||||
// mark components as inside recycle-list so that we know we need to invoke
|
|
||||||
// their special @render function instead of render in create-component.js
|
|
||||||
export function postTransformComponent(
|
|
||||||
el: ASTElement,
|
|
||||||
options: WeexCompilerOptions
|
|
||||||
) {
|
|
||||||
// $flow-disable-line (we know isReservedTag is there)
|
|
||||||
if (!options.isReservedTag!(el.tag) && el.tag !== 'cell-slot') {
|
|
||||||
addAttr(el, RECYCLE_LIST_MARKER, 'true')
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
|
|
||||||
import { preTransformRecycleList } from './recycle-list'
|
|
||||||
import { postTransformComponent } from './component'
|
|
||||||
import { postTransformComponentRoot } from './component-root'
|
|
||||||
import { postTransformText } from './text'
|
|
||||||
import { preTransformVBind } from './v-bind'
|
|
||||||
import { preTransformVIf } from './v-if'
|
|
||||||
import { preTransformVFor } from './v-for'
|
|
||||||
import { postTransformVOn } from './v-on'
|
|
||||||
import { preTransformVOnce } from './v-once'
|
|
||||||
import type { WeexCompilerOptions } from 'typescript/weex'
|
|
||||||
|
|
||||||
let currentRecycleList: null | ASTElement = null
|
|
||||||
|
|
||||||
function shouldCompile(el: ASTElement, options: WeexCompilerOptions) {
|
|
||||||
return options.recyclable || (currentRecycleList && el !== currentRecycleList)
|
|
||||||
}
|
|
||||||
|
|
||||||
function preTransformNode(el: ASTElement, options: WeexCompilerOptions) {
|
|
||||||
if (el.tag === 'recycle-list') {
|
|
||||||
preTransformRecycleList(el, options)
|
|
||||||
currentRecycleList = el
|
|
||||||
}
|
|
||||||
if (shouldCompile(el, options)) {
|
|
||||||
preTransformVBind(el)
|
|
||||||
preTransformVIf(el, options) // also v-else-if and v-else
|
|
||||||
preTransformVFor(el, options)
|
|
||||||
preTransformVOnce(el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function transformNode(el: ASTElement, options: WeexCompilerOptions) {
|
|
||||||
if (shouldCompile(el, options)) {
|
|
||||||
// do nothing yet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function postTransformNode(el: ASTElement, options: WeexCompilerOptions) {
|
|
||||||
if (shouldCompile(el, options)) {
|
|
||||||
// mark child component in parent template
|
|
||||||
postTransformComponent(el, options)
|
|
||||||
// mark root in child component template
|
|
||||||
postTransformComponentRoot(el)
|
|
||||||
// <text>: transform children text into value attr
|
|
||||||
if (el.tag === 'text') {
|
|
||||||
postTransformText(el)
|
|
||||||
}
|
|
||||||
postTransformVOn(el)
|
|
||||||
}
|
|
||||||
if (el === currentRecycleList) {
|
|
||||||
currentRecycleList = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
preTransformNode,
|
|
||||||
transformNode,
|
|
||||||
postTransformNode,
|
|
||||||
} as ModuleOptions
|
|
|
@ -1,50 +0,0 @@
|
||||||
|
|
||||||
import { parseFor } from 'compiler/parser/index'
|
|
||||||
import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
|
|
||||||
import type { WeexCompilerOptions } from 'typescript/weex'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map the following syntax to corresponding attrs:
|
|
||||||
*
|
|
||||||
* <recycle-list for="(item, i) in longList" switch="cellType">
|
|
||||||
* <cell-slot case="A"> ... </cell-slot>
|
|
||||||
* <cell-slot case="B"> ... </cell-slot>
|
|
||||||
* </recycle-list>
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function preTransformRecycleList(
|
|
||||||
el: ASTElement,
|
|
||||||
options: WeexCompilerOptions
|
|
||||||
) {
|
|
||||||
const exp = getAndRemoveAttr(el, 'for')
|
|
||||||
if (!exp) {
|
|
||||||
if (options.warn) {
|
|
||||||
options.warn(`Invalid <recycle-list> syntax: missing "for" expression.`)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = parseFor(exp)
|
|
||||||
if (!res) {
|
|
||||||
if (options.warn) {
|
|
||||||
options.warn(`Invalid <recycle-list> syntax: ${exp}.`)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
addRawAttr(el, ':list-data', res.for)
|
|
||||||
addRawAttr(el, 'binding-expression', res.for)
|
|
||||||
addRawAttr(el, 'alias', res.alias)
|
|
||||||
if (res.iterator2) {
|
|
||||||
// (item, key, index) for object iteration
|
|
||||||
// is this even supported?
|
|
||||||
addRawAttr(el, 'index', res.iterator2)
|
|
||||||
} else if (res.iterator1) {
|
|
||||||
addRawAttr(el, 'index', res.iterator1)
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchKey = getAndRemoveAttr(el, 'switch')
|
|
||||||
if (switchKey) {
|
|
||||||
addRawAttr(el, 'switch', switchKey)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
|
|
||||||
import { addAttr } from 'compiler/helpers'
|
|
||||||
|
|
||||||
function genText(node: ASTNode) {
|
|
||||||
const value =
|
|
||||||
node.type === 3
|
|
||||||
? node.text
|
|
||||||
: node.type === 2
|
|
||||||
? node.tokens.length === 1
|
|
||||||
? node.tokens[0]
|
|
||||||
: node.tokens
|
|
||||||
: ''
|
|
||||||
return JSON.stringify(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function postTransformText(el: ASTElement) {
|
|
||||||
// weex <text> can only contain text, so the parser
|
|
||||||
// always generates a single child.
|
|
||||||
if (el.children.length) {
|
|
||||||
addAttr(el, 'value', genText(el.children[0]))
|
|
||||||
el.children = []
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
import { camelize } from 'shared/util'
|
|
||||||
import { generateBinding } from 'weex/util/parser'
|
|
||||||
import { bindRE } from 'compiler/parser/index'
|
|
||||||
import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
|
|
||||||
|
|
||||||
function parseAttrName(name: string): string {
|
|
||||||
return camelize(name.replace(bindRE, ''))
|
|
||||||
}
|
|
||||||
|
|
||||||
export function preTransformVBind(el: ASTElement) {
|
|
||||||
for (const attr in el.attrsMap) {
|
|
||||||
if (bindRE.test(attr)) {
|
|
||||||
const name: string = parseAttrName(attr)
|
|
||||||
const value = generateBinding(getAndRemoveAttr(el, attr))
|
|
||||||
delete el.attrsMap[attr]
|
|
||||||
addRawAttr(el, name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
|
|
||||||
import { parseFor } from 'compiler/parser/index'
|
|
||||||
import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
|
|
||||||
import type { WeexCompilerOptions } from 'typescript/weex'
|
|
||||||
|
|
||||||
export function preTransformVFor(el: ASTElement, options: WeexCompilerOptions) {
|
|
||||||
const exp = getAndRemoveAttr(el, 'v-for')
|
|
||||||
if (!exp) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = parseFor(exp)
|
|
||||||
if (!res) {
|
|
||||||
if (process.env.NODE_ENV !== 'production' && options.warn) {
|
|
||||||
options.warn(`Invalid v-for expression: ${exp}`)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const desc: Object = {
|
|
||||||
'@expression': res.for,
|
|
||||||
'@alias': res.alias,
|
|
||||||
}
|
|
||||||
if (res.iterator2) {
|
|
||||||
desc['@key'] = res.iterator1
|
|
||||||
desc['@index'] = res.iterator2
|
|
||||||
} else {
|
|
||||||
desc['@index'] = res.iterator1
|
|
||||||
}
|
|
||||||
|
|
||||||
delete el.attrsMap['v-for']
|
|
||||||
addRawAttr(el, '[[repeat]]', desc)
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
import { addIfCondition } from "compiler/parser/index";
|
|
||||||
import { getAndRemoveAttr, addRawAttr } from "compiler/helpers";
|
|
||||||
import type { WeexCompilerOptions } from "typescript/weex";
|
|
||||||
|
|
||||||
function hasConditionDirective(el: ASTElement): boolean {
|
|
||||||
for (const attr in el.attrsMap) {
|
|
||||||
if (/^v\-if|v\-else|v\-else\-if$/.test(attr)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPreviousConditions(el: ASTElement): Array<string> {
|
|
||||||
const conditions: any[] = [];
|
|
||||||
if (el.parent && el.parent.children) {
|
|
||||||
for (let c = 0, n = el.parent.children.length; c < n; ++c) {
|
|
||||||
const ifConditions = (el.parent.children[c] as ASTElement).ifConditions;
|
|
||||||
if (ifConditions) {
|
|
||||||
for (let i = 0, l = ifConditions.length; i < l; ++i) {
|
|
||||||
const condition = ifConditions[i];
|
|
||||||
if (condition && condition.exp) {
|
|
||||||
conditions.push(condition.exp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return conditions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function preTransformVIf(el: ASTElement, options: WeexCompilerOptions) {
|
|
||||||
if (hasConditionDirective(el)) {
|
|
||||||
let exp;
|
|
||||||
const ifExp = getAndRemoveAttr(el, "v-if", true /* remove from attrsMap */);
|
|
||||||
const elseifExp = getAndRemoveAttr(el, "v-else-if", true);
|
|
||||||
// don't need the value, but remove it to avoid being generated as a
|
|
||||||
// custom directive
|
|
||||||
getAndRemoveAttr(el, "v-else", true);
|
|
||||||
if (ifExp) {
|
|
||||||
exp = ifExp;
|
|
||||||
addIfCondition(el, { exp: ifExp, block: el });
|
|
||||||
} else {
|
|
||||||
elseifExp && addIfCondition(el, { exp: elseifExp, block: el });
|
|
||||||
const prevConditions = getPreviousConditions(el);
|
|
||||||
if (prevConditions.length) {
|
|
||||||
const prevMatch = prevConditions.join(" || ");
|
|
||||||
exp = elseifExp
|
|
||||||
? `!(${prevMatch}) && (${elseifExp})` // v-else-if
|
|
||||||
: `!(${prevMatch})`; // v-else
|
|
||||||
} else if (process.env.NODE_ENV !== "production" && options.warn) {
|
|
||||||
options.warn(
|
|
||||||
`v-${elseifExp ? 'else-if="' + elseifExp + '"' : "else"} ` +
|
|
||||||
`used on element <${el.tag}> without corresponding v-if.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addRawAttr(el, "[[match]]", exp);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
|
|
||||||
const inlineStatementRE = /^\s*([A-Za-z_$0-9\['\."\]]+)*\s*\(\s*(([A-Za-z_$0-9\['\."\]]+)?(\s*,\s*([A-Za-z_$0-9\['\."\]]+))*)\s*\)$/
|
|
||||||
|
|
||||||
function parseHandlerParams(handler: ASTElementHandler) {
|
|
||||||
const res = inlineStatementRE.exec(handler.value)
|
|
||||||
if (res && res[2]) {
|
|
||||||
handler.params = res[2].split(/\s*,\s*/)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function postTransformVOn(el: ASTElement) {
|
|
||||||
const events: ASTElementHandlers | void = el.events
|
|
||||||
if (!events) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for (const name in events) {
|
|
||||||
const handler: ASTElementHandler | Array<ASTElementHandler> = events[name]
|
|
||||||
if (Array.isArray(handler)) {
|
|
||||||
handler.map((fn) => parseHandlerParams(fn))
|
|
||||||
} else {
|
|
||||||
parseHandlerParams(handler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
|
|
||||||
import { getAndRemoveAttr, addRawAttr } from 'compiler/helpers'
|
|
||||||
|
|
||||||
function containVOnce(el: ASTElement): boolean {
|
|
||||||
for (const attr in el.attrsMap) {
|
|
||||||
if (/^v\-once$/i.test(attr)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
export function preTransformVOnce(el: ASTElement) {
|
|
||||||
if (containVOnce(el)) {
|
|
||||||
getAndRemoveAttr(el, 'v-once', true)
|
|
||||||
addRawAttr(el, '[[once]]', true)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
|
|
||||||
import { cached, camelize, isPlainObject } from 'shared/util'
|
|
||||||
import { parseText } from 'compiler/parser/text-parser'
|
|
||||||
import { getAndRemoveAttr, getBindingAttr, baseWarn } from 'compiler/helpers'
|
|
||||||
|
|
||||||
type StaticStyleResult = {
|
|
||||||
dynamic: boolean
|
|
||||||
styleResult: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const normalize = cached(camelize)
|
|
||||||
|
|
||||||
function transformNode(el: ASTElement, options: CompilerOptions) {
|
|
||||||
const warn = options.warn || baseWarn
|
|
||||||
const staticStyle = getAndRemoveAttr(el, 'style')
|
|
||||||
const { dynamic, styleResult } = parseStaticStyle(staticStyle!, options)
|
|
||||||
if (process.env.NODE_ENV !== 'production' && dynamic) {
|
|
||||||
warn(
|
|
||||||
`style="${String(staticStyle)}": ` +
|
|
||||||
'Interpolation inside attributes has been deprecated. ' +
|
|
||||||
'Use v-bind or the colon shorthand instead.',
|
|
||||||
el.rawAttrsMap['style']
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!dynamic && styleResult) {
|
|
||||||
el.staticStyle = styleResult
|
|
||||||
}
|
|
||||||
const styleBinding = getBindingAttr(el, 'style', false /* getStatic */)
|
|
||||||
if (styleBinding) {
|
|
||||||
el.styleBinding = styleBinding
|
|
||||||
} else if (dynamic) {
|
|
||||||
el.styleBinding = styleResult
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function genData(el: ASTElement): string {
|
|
||||||
let data = ''
|
|
||||||
if (el.staticStyle) {
|
|
||||||
data += `staticStyle:${el.staticStyle},`
|
|
||||||
}
|
|
||||||
if (el.styleBinding) {
|
|
||||||
data += `style:${el.styleBinding},`
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseStaticStyle(
|
|
||||||
staticStyle: string | null,
|
|
||||||
options: CompilerOptions
|
|
||||||
): StaticStyleResult {
|
|
||||||
// "width: 200px; height: 200px;" -> {width: 200, height: 200}
|
|
||||||
// "width: 200px; height: {{y}}" -> {width: 200, height: y}
|
|
||||||
let dynamic = false
|
|
||||||
let styleResult = ''
|
|
||||||
if (typeof staticStyle === 'string') {
|
|
||||||
const styleList = staticStyle
|
|
||||||
.trim()
|
|
||||||
.split(';')
|
|
||||||
.map((style) => {
|
|
||||||
const result = style.trim().split(':')
|
|
||||||
if (result.length !== 2) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const key = normalize(result[0].trim())
|
|
||||||
const value = result[1].trim()
|
|
||||||
const dynamicValue = parseText(value, options.delimiters)
|
|
||||||
if (dynamicValue) {
|
|
||||||
dynamic = true
|
|
||||||
return key + ':' + dynamicValue.expression
|
|
||||||
}
|
|
||||||
return key + ':' + JSON.stringify(value)
|
|
||||||
})
|
|
||||||
.filter((result) => result)
|
|
||||||
if (styleList.length) {
|
|
||||||
styleResult = '{' + styleList.join(',') + '}'
|
|
||||||
}
|
|
||||||
} else if (isPlainObject(staticStyle)) {
|
|
||||||
styleResult = JSON.stringify(staticStyle) || ''
|
|
||||||
}
|
|
||||||
return { dynamic, styleResult }
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
staticKeys: ['staticStyle'],
|
|
||||||
transformNode,
|
|
||||||
genData,
|
|
||||||
} as ModuleOptions
|
|
|
@ -1,2 +0,0 @@
|
||||||
export { compile } from 'weex/compiler/index'
|
|
||||||
export { generateCodeFrame } from 'compiler/codeframe'
|
|
|
@ -1,196 +0,0 @@
|
||||||
|
|
||||||
import type { GlobalAPI } from 'typescript/global-api'
|
|
||||||
import type {
|
|
||||||
Weex,
|
|
||||||
WeexInstanceContext,
|
|
||||||
WeexInstanceOption,
|
|
||||||
WeexRuntimeContext,
|
|
||||||
} from 'typescript/weex'
|
|
||||||
|
|
||||||
// this will be preserved during build
|
|
||||||
const VueFactory = require('./factory')
|
|
||||||
|
|
||||||
const instanceOptions: { [key: string]: WeexInstanceOption } = {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create instance context.
|
|
||||||
*/
|
|
||||||
export function createInstanceContext(
|
|
||||||
instanceId: string,
|
|
||||||
runtimeContext: WeexRuntimeContext,
|
|
||||||
data: any = {}
|
|
||||||
): WeexInstanceContext {
|
|
||||||
const weex: Weex = runtimeContext.weex
|
|
||||||
const instance: WeexInstanceOption = (instanceOptions[instanceId] = {
|
|
||||||
instanceId,
|
|
||||||
config: weex.config,
|
|
||||||
document: weex.document,
|
|
||||||
data
|
|
||||||
})
|
|
||||||
|
|
||||||
// Each instance has an independent `Vue` module instance
|
|
||||||
const Vue = instance.Vue = createVueModuleInstance(instanceId, weex)
|
|
||||||
|
|
||||||
// DEPRECATED
|
|
||||||
const timerAPIs = getInstanceTimer(instanceId, weex.requireModule)
|
|
||||||
|
|
||||||
const instanceContext = Object.assign({ Vue }, timerAPIs)
|
|
||||||
Object.freeze(instanceContext)
|
|
||||||
return instanceContext
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy an instance with id. It will make sure all memory of
|
|
||||||
* this instance released and no more leaks.
|
|
||||||
*/
|
|
||||||
export function destroyInstance(instanceId: string): void {
|
|
||||||
const instance = instanceOptions[instanceId]
|
|
||||||
//@ts-expect-error
|
|
||||||
if (instance && instance.app instanceof instance.Vue) {
|
|
||||||
try {
|
|
||||||
instance.app!.$destroy()
|
|
||||||
instance.document.destroy()
|
|
||||||
} catch (e: any) {}
|
|
||||||
//@ts-expect-error
|
|
||||||
delete instance.document
|
|
||||||
delete instance.app
|
|
||||||
}
|
|
||||||
delete instanceOptions[instanceId]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh an instance with id and new top-level component data.
|
|
||||||
* It will use `Vue.set` on all keys of the new data. So it's better
|
|
||||||
* define all possible meaningful keys when instance created.
|
|
||||||
*/
|
|
||||||
export function refreshInstance(
|
|
||||||
instanceId: string,
|
|
||||||
data: Object
|
|
||||||
): Error | void {
|
|
||||||
const instance = instanceOptions[instanceId]
|
|
||||||
//@ts-expect-error
|
|
||||||
if (!instance || !(instance.app instanceof instance.Vue)) {
|
|
||||||
return new Error(`refreshInstance: instance ${instanceId} not found!`)
|
|
||||||
}
|
|
||||||
if (instance.Vue && instance.Vue.set) {
|
|
||||||
for (const key in data) {
|
|
||||||
instance.Vue.set(instance.app!, key, data[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Finally `refreshFinish` signal needed.
|
|
||||||
instance.document.taskCenter.send('dom', { action: 'refreshFinish' }, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a fresh instance of Vue for each Weex instance.
|
|
||||||
*/
|
|
||||||
function createVueModuleInstance(instanceId: string, weex: Weex): GlobalAPI {
|
|
||||||
const exports = {}
|
|
||||||
VueFactory(exports, weex.document)
|
|
||||||
//@ts-expect-error
|
|
||||||
const Vue = exports.Vue
|
|
||||||
|
|
||||||
const instance = instanceOptions[instanceId]
|
|
||||||
|
|
||||||
// patch reserved tag detection to account for dynamically registered
|
|
||||||
// components
|
|
||||||
const weexRegex = /^weex:/i
|
|
||||||
const isReservedTag = Vue.config.isReservedTag || (() => false)
|
|
||||||
const isRuntimeComponent = Vue.config.isRuntimeComponent || (() => false)
|
|
||||||
Vue.config.isReservedTag = (name) => {
|
|
||||||
return (
|
|
||||||
(!isRuntimeComponent(name) && weex.supports(`@component/${name}`)) ||
|
|
||||||
isReservedTag(name) ||
|
|
||||||
weexRegex.test(name)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Vue.config.parsePlatformTagName = (name) => name.replace(weexRegex, '')
|
|
||||||
|
|
||||||
// expose weex-specific info
|
|
||||||
Vue.prototype.$instanceId = instanceId
|
|
||||||
Vue.prototype.$document = instance.document
|
|
||||||
|
|
||||||
// expose weex native module getter on subVue prototype so that
|
|
||||||
// vdom runtime modules can access native modules via vnode.context
|
|
||||||
Vue.prototype.$requireWeexModule = weex.requireModule
|
|
||||||
|
|
||||||
// Hack `Vue` behavior to handle instance information and data
|
|
||||||
// before root component created.
|
|
||||||
Vue.mixin({
|
|
||||||
beforeCreate() {
|
|
||||||
const options = this.$options
|
|
||||||
// root component (vm)
|
|
||||||
if (options.el) {
|
|
||||||
// set external data of instance
|
|
||||||
const dataOption = options.data
|
|
||||||
const internalData =
|
|
||||||
(typeof dataOption === 'function' ? dataOption() : dataOption) || {}
|
|
||||||
options.data = Object.assign(internalData, instance.data)
|
|
||||||
// record instance by id
|
|
||||||
instance.app = this
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
const options = this.$options
|
|
||||||
// root component (vm)
|
|
||||||
if (options.el && weex.document && instance.app === this) {
|
|
||||||
try {
|
|
||||||
// Send "createFinish" signal to native.
|
|
||||||
weex.document.taskCenter.send('dom', { action: 'createFinish' }, [])
|
|
||||||
} catch (e: any) {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Just instance variable `weex.config`
|
|
||||||
* Get instance config.
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
Vue.prototype.$getConfig = function () {
|
|
||||||
if (instance.app instanceof Vue) {
|
|
||||||
return instance.config
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Vue
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DEPRECATED
|
|
||||||
* Generate HTML5 Timer APIs. An important point is that the callback
|
|
||||||
* will be converted into callback id when sent to native. So the
|
|
||||||
* framework can make sure no side effect of the callback happened after
|
|
||||||
* an instance destroyed.
|
|
||||||
*/
|
|
||||||
function getInstanceTimer(instanceId: string, moduleGetter: Function): Object {
|
|
||||||
const instance = instanceOptions[instanceId]
|
|
||||||
const timer = moduleGetter('timer')
|
|
||||||
const timerAPIs = {
|
|
||||||
setTimeout: (...args) => {
|
|
||||||
const handler = function () {
|
|
||||||
args[0](...args.slice(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.setTimeout(handler, args[1])
|
|
||||||
//@ts-expect-error
|
|
||||||
return instance.document.taskCenter.callbackManager.lastCallbackId.toString()
|
|
||||||
},
|
|
||||||
setInterval: (...args) => {
|
|
||||||
const handler = function () {
|
|
||||||
args[0](...args.slice(2))
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.setInterval(handler, args[1])
|
|
||||||
//@ts-expect-error
|
|
||||||
return instance.document.taskCenter.callbackManager.lastCallbackId.toString()
|
|
||||||
},
|
|
||||||
clearTimeout: (n) => {
|
|
||||||
timer.clearTimeout(n)
|
|
||||||
},
|
|
||||||
clearInterval: (n) => {
|
|
||||||
timer.clearInterval(n)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return timerAPIs
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
// this entry is built and wrapped with a factory function
|
|
||||||
// used to generate a fresh copy of Vue for every Weex instance.
|
|
||||||
|
|
||||||
import Vue from './runtime/index'
|
|
||||||
|
|
||||||
exports.Vue = Vue
|
|
|
@ -1,9 +0,0 @@
|
||||||
import Richtext from './richtext'
|
|
||||||
import Transition from './transition'
|
|
||||||
import TransitionGroup from './transition-group'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
Richtext,
|
|
||||||
Transition,
|
|
||||||
TransitionGroup,
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
|
|
||||||
import VNode from 'core/vdom/vnode'
|
|
||||||
|
|
||||||
function getVNodeType(vnode: VNode): string {
|
|
||||||
if (!vnode.tag) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return vnode.tag.replace(/vue\-component\-(\d+\-)?/, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
function isSimpleSpan(vnode: VNode): boolean {
|
|
||||||
return (vnode.children &&
|
|
||||||
vnode.children.length === 1 &&
|
|
||||||
!vnode.children[0].tag) as any
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseStyle(vnode: VNode): Object | void {
|
|
||||||
if (!vnode || !vnode.data) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const { staticStyle, staticClass } = vnode.data
|
|
||||||
if (vnode.data.style || vnode.data.class || staticStyle || staticClass) {
|
|
||||||
const styles = Object.assign({}, staticStyle, vnode.data.style)
|
|
||||||
// @ts-expect-error
|
|
||||||
const cssMap = vnode.context!.$options.style || {}
|
|
||||||
const classList = ([] as string[]).concat(staticClass!, vnode.data.class)
|
|
||||||
classList.forEach((name) => {
|
|
||||||
if (name && cssMap[name]) {
|
|
||||||
Object.assign(styles, cssMap[name])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return styles
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertVNodeChildren(
|
|
||||||
children: Array<VNode>
|
|
||||||
): Array<VNode> | undefined {
|
|
||||||
if (!children.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return children.map(
|
|
||||||
(vnode): VNode => {
|
|
||||||
const type: string = getVNodeType(vnode)
|
|
||||||
const props: any = { type }
|
|
||||||
|
|
||||||
// convert raw text node
|
|
||||||
if (!type) {
|
|
||||||
props.type = 'span'
|
|
||||||
props.attr = {
|
|
||||||
value: (vnode.text || '').trim(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
props.style = parseStyle(vnode)
|
|
||||||
if (vnode.data) {
|
|
||||||
props.attr = vnode.data.attrs
|
|
||||||
if (vnode.data.on) {
|
|
||||||
props.events = vnode.data.on
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type === 'span' && isSimpleSpan(vnode)) {
|
|
||||||
props.attr = props.attr || {}
|
|
||||||
//@ts-expect-error
|
|
||||||
props.attr.value = vnode.children[0].text.trim()
|
|
||||||
return props
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vnode.children && vnode.children.length) {
|
|
||||||
props.children = convertVNodeChildren(vnode.children)
|
|
||||||
}
|
|
||||||
|
|
||||||
return props
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'richtext',
|
|
||||||
render(h: Function) {
|
|
||||||
return h('weex:richtext', {
|
|
||||||
on: this._events,
|
|
||||||
attrs: {
|
|
||||||
value: convertVNodeChildren(this.$options._renderChildren || []),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
import { warn, extend } from 'core/util/index'
|
|
||||||
import { transitionProps, extractTransitionData } from './transition'
|
|
||||||
|
|
||||||
const props = extend(
|
|
||||||
{
|
|
||||||
tag: String,
|
|
||||||
moveClass: String,
|
|
||||||
},
|
|
||||||
transitionProps
|
|
||||||
)
|
|
||||||
|
|
||||||
delete props.mode
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props,
|
|
||||||
|
|
||||||
created() {
|
|
||||||
const dom = this.$requireWeexModule('dom')
|
|
||||||
this.getPosition = (el) =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
dom.getComponentRect(el.ref, (res) => {
|
|
||||||
if (!res.result) {
|
|
||||||
reject(new Error(`failed to get rect for element: ${el.tag}`))
|
|
||||||
} else {
|
|
||||||
resolve(res.size)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const animation = this.$requireWeexModule('animation')
|
|
||||||
this.animate = (el, options) =>
|
|
||||||
new Promise((resolve) => {
|
|
||||||
animation.transition(el.ref, options, resolve)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
render(h) {
|
|
||||||
const tag = this.tag || this.$vnode.data.tag || 'span'
|
|
||||||
const map = Object.create(null)
|
|
||||||
const prevChildren = (this.prevChildren = this.children)
|
|
||||||
const rawChildren = this.$slots.default || []
|
|
||||||
const children: any[] = (this.children = [])
|
|
||||||
const transitionData = extractTransitionData(this)
|
|
||||||
|
|
||||||
for (let i = 0; i < rawChildren.length; i++) {
|
|
||||||
const c = rawChildren[i]
|
|
||||||
if (c.tag) {
|
|
||||||
if (c.key != null && String(c.key).indexOf('__vlist') !== 0) {
|
|
||||||
children.push(c)
|
|
||||||
map[c.key] = c
|
|
||||||
;(c.data || (c.data = {})).transition = transitionData
|
|
||||||
} else if (process.env.NODE_ENV !== 'production') {
|
|
||||||
const opts = c.componentOptions
|
|
||||||
const name = opts ? opts.Ctor.options.name || opts.tag : c.tag
|
|
||||||
warn(`<transition-group> children must be keyed: <${name}>`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevChildren) {
|
|
||||||
const kept: any[] = []
|
|
||||||
const removed: any[] = []
|
|
||||||
prevChildren.forEach((c) => {
|
|
||||||
c.data.transition = transitionData
|
|
||||||
|
|
||||||
// TODO: record before patch positions
|
|
||||||
|
|
||||||
if (map[c.key]) {
|
|
||||||
kept.push(c)
|
|
||||||
} else {
|
|
||||||
removed.push(c)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.kept = h(tag, null, kept)
|
|
||||||
this.removed = removed
|
|
||||||
}
|
|
||||||
|
|
||||||
return h(tag, null, children)
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeUpdate() {
|
|
||||||
// force removing pass
|
|
||||||
this.__patch__(
|
|
||||||
this._vnode,
|
|
||||||
this.kept,
|
|
||||||
false, // hydrating
|
|
||||||
true // removeOnly (!important, avoids unnecessary moves)
|
|
||||||
)
|
|
||||||
this._vnode = this.kept
|
|
||||||
},
|
|
||||||
|
|
||||||
updated() {
|
|
||||||
const children = this.prevChildren
|
|
||||||
const moveClass = this.moveClass || (this.name || 'v') + '-move'
|
|
||||||
const moveData =
|
|
||||||
children.length && this.getMoveData(children[0].context, moveClass)
|
|
||||||
if (!moveData) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: finish implementing move animations once
|
|
||||||
// we have access to sync getComponentRect()
|
|
||||||
|
|
||||||
// children.forEach(callPendingCbs)
|
|
||||||
|
|
||||||
// Promise.all(children.map(c => {
|
|
||||||
// const oldPos = c.data.pos
|
|
||||||
// const newPos = c.data.newPos
|
|
||||||
// const dx = oldPos.left - newPos.left
|
|
||||||
// const dy = oldPos.top - newPos.top
|
|
||||||
// if (dx || dy) {
|
|
||||||
// c.data.moved = true
|
|
||||||
// return this.animate(c.elm, {
|
|
||||||
// styles: {
|
|
||||||
// transform: `translate(${dx}px,${dy}px)`
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })).then(() => {
|
|
||||||
// children.forEach(c => {
|
|
||||||
// if (c.data.moved) {
|
|
||||||
// this.animate(c.elm, {
|
|
||||||
// styles: {
|
|
||||||
// transform: ''
|
|
||||||
// },
|
|
||||||
// duration: moveData.duration || 0,
|
|
||||||
// delay: moveData.delay || 0,
|
|
||||||
// timingFunction: moveData.timingFunction || 'linear'
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
getMoveData(context, moveClass) {
|
|
||||||
const stylesheet = context.$options.style || {}
|
|
||||||
return stylesheet['@TRANSITION'] && stylesheet['@TRANSITION'][moveClass]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// function callPendingCbs (c) {
|
|
||||||
// /* istanbul ignore if */
|
|
||||||
// if (c.elm._moveCb) {
|
|
||||||
// c.elm._moveCb()
|
|
||||||
// }
|
|
||||||
// /* istanbul ignore if */
|
|
||||||
// if (c.elm._enterCb) {
|
|
||||||
// c.elm._enterCb()
|
|
||||||
// }
|
|
||||||
// }
|
|
|
@ -1,9 +0,0 @@
|
||||||
// reuse same transition component logic from web
|
|
||||||
export {
|
|
||||||
transitionProps,
|
|
||||||
extractTransitionData,
|
|
||||||
} from 'web/runtime/components/transition'
|
|
||||||
|
|
||||||
import Transition from 'web/runtime/components/transition'
|
|
||||||
|
|
||||||
export default Transition
|
|
|
@ -1 +0,0 @@
|
||||||
export default {}
|
|
|
@ -1,35 +0,0 @@
|
||||||
import Vue from 'core/index'
|
|
||||||
import { patch } from 'weex/runtime/patch'
|
|
||||||
import { mountComponent } from 'core/instance/lifecycle'
|
|
||||||
import platformDirectives from 'weex/runtime/directives/index'
|
|
||||||
import platformComponents from 'weex/runtime/components/index'
|
|
||||||
|
|
||||||
import {
|
|
||||||
query,
|
|
||||||
mustUseProp,
|
|
||||||
isReservedTag,
|
|
||||||
isRuntimeComponent,
|
|
||||||
isUnknownElement,
|
|
||||||
} from 'weex/util/element'
|
|
||||||
|
|
||||||
import { Component} from 'typescript/component'
|
|
||||||
|
|
||||||
// install platform specific utils
|
|
||||||
Vue.config.mustUseProp = mustUseProp
|
|
||||||
Vue.config.isReservedTag = isReservedTag
|
|
||||||
Vue.config.isRuntimeComponent = isRuntimeComponent
|
|
||||||
Vue.config.isUnknownElement = isUnknownElement
|
|
||||||
|
|
||||||
// install platform runtime directives and components
|
|
||||||
Vue.options.directives = platformDirectives
|
|
||||||
Vue.options.components = platformComponents
|
|
||||||
|
|
||||||
// install platform patch function
|
|
||||||
Vue.prototype.__patch__ = patch
|
|
||||||
|
|
||||||
// wrap mount
|
|
||||||
Vue.prototype.$mount = function (el?: any, hydrating?: boolean): Component {
|
|
||||||
return mountComponent(this, el && query(el, this.$document), hydrating)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Vue
|
|
|
@ -1,40 +0,0 @@
|
||||||
|
|
||||||
import { extend } from 'shared/util'
|
|
||||||
import type { VNodeWithData } from 'typescript/vnode'
|
|
||||||
|
|
||||||
function updateAttrs(oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
|
||||||
if (!oldVnode.data.attrs && !vnode.data.attrs) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let key, cur, old
|
|
||||||
const elm = vnode.elm
|
|
||||||
const oldAttrs = oldVnode.data.attrs || {}
|
|
||||||
let attrs = vnode.data.attrs || {}
|
|
||||||
// clone observed objects, as the user probably wants to mutate it
|
|
||||||
if (attrs.__ob__) {
|
|
||||||
attrs = vnode.data.attrs = extend({}, attrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
const supportBatchUpdate = typeof elm.setAttrs === 'function'
|
|
||||||
const batchedAttrs = {}
|
|
||||||
for (key in attrs) {
|
|
||||||
cur = attrs[key]
|
|
||||||
old = oldAttrs[key]
|
|
||||||
if (old !== cur) {
|
|
||||||
supportBatchUpdate ? (batchedAttrs[key] = cur) : elm.setAttr(key, cur)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (key in oldAttrs) {
|
|
||||||
if (attrs[key] == null) {
|
|
||||||
supportBatchUpdate ? (batchedAttrs[key] = undefined) : elm.setAttr(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (supportBatchUpdate) {
|
|
||||||
elm.setAttrs(batchedAttrs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
create: updateAttrs,
|
|
||||||
update: updateAttrs,
|
|
||||||
}
|
|
|
@ -1,86 +0,0 @@
|
||||||
|
|
||||||
import { extend, isObject } from 'shared/util'
|
|
||||||
import type { Component } from 'typescript/component'
|
|
||||||
import type { VNodeData, VNodeWithData } from 'typescript/vnode'
|
|
||||||
|
|
||||||
function updateClass(oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
|
||||||
const el = vnode.elm
|
|
||||||
const ctx = vnode.context
|
|
||||||
|
|
||||||
const data: VNodeData = vnode.data
|
|
||||||
const oldData: VNodeData = oldVnode.data
|
|
||||||
if (
|
|
||||||
!data.staticClass &&
|
|
||||||
!data.class &&
|
|
||||||
(!oldData || (!oldData.staticClass && !oldData.class))
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldClassList = makeClassList(oldData)
|
|
||||||
const classList = makeClassList(data)
|
|
||||||
|
|
||||||
if (typeof el.setClassList === 'function') {
|
|
||||||
el.setClassList(classList)
|
|
||||||
} else {
|
|
||||||
const style = getStyle(oldClassList, classList, ctx)
|
|
||||||
if (typeof el.setStyles === 'function') {
|
|
||||||
el.setStyles(style)
|
|
||||||
} else {
|
|
||||||
for (const key in style) {
|
|
||||||
el.setStyle(key, style[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeClassList(data: VNodeData): Array<string> {
|
|
||||||
const classList: any[] = []
|
|
||||||
// unlike web, weex vnode staticClass is an Array
|
|
||||||
const staticClass: any = data.staticClass
|
|
||||||
const dataClass = data.class
|
|
||||||
if (staticClass) {
|
|
||||||
classList.push.apply(classList, staticClass)
|
|
||||||
}
|
|
||||||
if (Array.isArray(dataClass)) {
|
|
||||||
classList.push.apply(classList, dataClass)
|
|
||||||
} else if (isObject(dataClass)) {
|
|
||||||
classList.push.apply(
|
|
||||||
classList,
|
|
||||||
Object.keys(dataClass).filter((className) => dataClass[className])
|
|
||||||
)
|
|
||||||
} else if (typeof dataClass === 'string') {
|
|
||||||
classList.push.apply(classList, dataClass.trim().split(/\s+/))
|
|
||||||
}
|
|
||||||
return classList
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStyle(
|
|
||||||
oldClassList: Array<string>,
|
|
||||||
classList: Array<string>,
|
|
||||||
ctx: Component
|
|
||||||
): Object {
|
|
||||||
// style is a weex-only injected object
|
|
||||||
// compiled from <style> tags in weex files
|
|
||||||
//@ts-expect-error
|
|
||||||
const stylesheet: any = ctx.$options.style || {}
|
|
||||||
const result = {}
|
|
||||||
classList.forEach((name) => {
|
|
||||||
const style = stylesheet[name]
|
|
||||||
extend(result, style)
|
|
||||||
})
|
|
||||||
oldClassList.forEach((name) => {
|
|
||||||
const style = stylesheet[name]
|
|
||||||
for (const key in style) {
|
|
||||||
if (!result.hasOwnProperty(key)) {
|
|
||||||
result[key] = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
create: updateClass,
|
|
||||||
update: updateClass,
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
|
|
||||||
import { updateListeners } from 'core/vdom/helpers/update-listeners'
|
|
||||||
import type { VNodeWithData } from 'typescript/vnode'
|
|
||||||
|
|
||||||
let target: any
|
|
||||||
|
|
||||||
function createOnceHandler(event, handler, capture) {
|
|
||||||
const _target = target // save current target element in closure
|
|
||||||
return function onceHandler() {
|
|
||||||
const res = handler.apply(null, arguments)
|
|
||||||
if (res !== null) {
|
|
||||||
remove(event, onceHandler, capture, _target)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add(
|
|
||||||
event: string,
|
|
||||||
handler: Function,
|
|
||||||
capture: boolean,
|
|
||||||
passive?: boolean,
|
|
||||||
params?: Array<any>
|
|
||||||
) {
|
|
||||||
if (capture) {
|
|
||||||
console.log('Weex do not support event in bubble phase.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
target.addEvent(event, handler, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove(event: string, handler: any, capture: any, _target?: any) {
|
|
||||||
(_target || target).removeEvent(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateDOMListeners(oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
|
||||||
if (!oldVnode.data.on && !vnode.data.on) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const on = vnode.data.on || {}
|
|
||||||
const oldOn = oldVnode.data.on || {}
|
|
||||||
target = vnode.elm
|
|
||||||
updateListeners(on, oldOn, add, remove, createOnceHandler, vnode.context)
|
|
||||||
target = undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
create: updateDOMListeners,
|
|
||||||
update: updateDOMListeners,
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
import attrs from './attrs'
|
|
||||||
import klass from './class'
|
|
||||||
import events from './events'
|
|
||||||
import style from './style'
|
|
||||||
import transition from './transition'
|
|
||||||
|
|
||||||
export default [attrs, klass, events, style, transition]
|
|
|
@ -1,84 +0,0 @@
|
||||||
|
|
||||||
import { extend, cached, camelize } from 'shared/util'
|
|
||||||
import type { VNodeWithData } from 'typescript/vnode'
|
|
||||||
|
|
||||||
const normalize = cached(camelize)
|
|
||||||
|
|
||||||
function createStyle(oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
|
||||||
if (!vnode.data.staticStyle) {
|
|
||||||
updateStyle(oldVnode, vnode)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const elm = vnode.elm
|
|
||||||
const staticStyle = vnode.data.staticStyle
|
|
||||||
const supportBatchUpdate = typeof elm.setStyles === 'function'
|
|
||||||
const batchedStyles = {}
|
|
||||||
for (const name in staticStyle) {
|
|
||||||
if (staticStyle[name]) {
|
|
||||||
supportBatchUpdate
|
|
||||||
? (batchedStyles[normalize(name)] = staticStyle[name])
|
|
||||||
: elm.setStyle(normalize(name), staticStyle[name])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (supportBatchUpdate) {
|
|
||||||
elm.setStyles(batchedStyles)
|
|
||||||
}
|
|
||||||
updateStyle(oldVnode, vnode)
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStyle(oldVnode: VNodeWithData, vnode: VNodeWithData) {
|
|
||||||
if (!oldVnode.data.style && !vnode.data.style) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let cur, name
|
|
||||||
const elm = vnode.elm
|
|
||||||
const oldStyle: any = oldVnode.data.style || {}
|
|
||||||
let style: any = vnode.data.style || {}
|
|
||||||
|
|
||||||
const needClone = style.__ob__
|
|
||||||
|
|
||||||
// handle array syntax
|
|
||||||
if (Array.isArray(style)) {
|
|
||||||
style = vnode.data.style = toObject(style)
|
|
||||||
}
|
|
||||||
|
|
||||||
// clone the style for future updates,
|
|
||||||
// in case the user mutates the style object in-place.
|
|
||||||
if (needClone) {
|
|
||||||
style = vnode.data.style = extend({}, style)
|
|
||||||
}
|
|
||||||
|
|
||||||
const supportBatchUpdate = typeof elm.setStyles === 'function'
|
|
||||||
const batchedStyles = {}
|
|
||||||
for (name in oldStyle) {
|
|
||||||
if (!style[name]) {
|
|
||||||
supportBatchUpdate
|
|
||||||
? (batchedStyles[normalize(name)] = '')
|
|
||||||
: elm.setStyle(normalize(name), '')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (name in style) {
|
|
||||||
cur = style[name]
|
|
||||||
supportBatchUpdate
|
|
||||||
? (batchedStyles[normalize(name)] = cur)
|
|
||||||
: elm.setStyle(normalize(name), cur)
|
|
||||||
}
|
|
||||||
if (supportBatchUpdate) {
|
|
||||||
elm.setStyles(batchedStyles)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toObject(arr) {
|
|
||||||
const res = {}
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
|
||||||
if (arr[i]) {
|
|
||||||
extend(res, arr[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
create: createStyle,
|
|
||||||
update: updateStyle,
|
|
||||||
}
|
|
|
@ -1,310 +0,0 @@
|
||||||
import { warn } from 'core/util/debug'
|
|
||||||
import { extend, once, noop } from 'shared/util'
|
|
||||||
import { activeInstance } from 'core/instance/lifecycle'
|
|
||||||
import { resolveTransition } from 'web/runtime/transition-util'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
create: enter,
|
|
||||||
activate: enter,
|
|
||||||
remove: leave,
|
|
||||||
}
|
|
||||||
|
|
||||||
function enter(_, vnode) {
|
|
||||||
const el = vnode.elm
|
|
||||||
|
|
||||||
// call leave callback now
|
|
||||||
if (el._leaveCb) {
|
|
||||||
el._leaveCb.cancelled = true
|
|
||||||
el._leaveCb()
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = resolveTransition(vnode.data.transition)
|
|
||||||
if (!data) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* istanbul ignore if */
|
|
||||||
if (el._enterCb) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
enterClass,
|
|
||||||
enterToClass,
|
|
||||||
enterActiveClass,
|
|
||||||
appearClass,
|
|
||||||
appearToClass,
|
|
||||||
appearActiveClass,
|
|
||||||
beforeEnter,
|
|
||||||
enter,
|
|
||||||
afterEnter,
|
|
||||||
enterCancelled,
|
|
||||||
beforeAppear,
|
|
||||||
appear,
|
|
||||||
afterAppear,
|
|
||||||
appearCancelled,
|
|
||||||
} = data
|
|
||||||
|
|
||||||
let context = activeInstance
|
|
||||||
let transitionNode = activeInstance.$vnode
|
|
||||||
while (transitionNode && transitionNode.parent) {
|
|
||||||
transitionNode = transitionNode.parent
|
|
||||||
context = transitionNode.context
|
|
||||||
}
|
|
||||||
|
|
||||||
const isAppear = !context._isMounted || !vnode.isRootInsert
|
|
||||||
|
|
||||||
if (isAppear && !appear && appear !== '') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const startClass = isAppear ? appearClass : enterClass
|
|
||||||
const toClass = isAppear ? appearToClass : enterToClass
|
|
||||||
const activeClass = isAppear ? appearActiveClass : enterActiveClass
|
|
||||||
const beforeEnterHook = isAppear ? beforeAppear || beforeEnter : beforeEnter
|
|
||||||
const enterHook = isAppear
|
|
||||||
? typeof appear === 'function'
|
|
||||||
? appear
|
|
||||||
: enter
|
|
||||||
: enter
|
|
||||||
const afterEnterHook = isAppear ? afterAppear || afterEnter : afterEnter
|
|
||||||
const enterCancelledHook = isAppear
|
|
||||||
? appearCancelled || enterCancelled
|
|
||||||
: enterCancelled
|
|
||||||
|
|
||||||
const userWantsControl =
|
|
||||||
enterHook &&
|
|
||||||
// enterHook may be a bound method which exposes
|
|
||||||
// the length of original fn as _length
|
|
||||||
(enterHook._length || enterHook.length) > 1
|
|
||||||
|
|
||||||
const stylesheet = vnode.context.$options.style || {}
|
|
||||||
const startState = stylesheet[startClass]
|
|
||||||
const transitionProperties =
|
|
||||||
(stylesheet['@TRANSITION'] && stylesheet['@TRANSITION'][activeClass]) || {}
|
|
||||||
const endState = getEnterTargetState(
|
|
||||||
el,
|
|
||||||
stylesheet,
|
|
||||||
startClass,
|
|
||||||
toClass,
|
|
||||||
activeClass
|
|
||||||
)
|
|
||||||
const needAnimation = Object.keys(endState).length > 0
|
|
||||||
|
|
||||||
const cb = (el._enterCb = once(() => {
|
|
||||||
//@ts-expect-error
|
|
||||||
if (cb.cancelled) {
|
|
||||||
enterCancelledHook && enterCancelledHook(el)
|
|
||||||
} else {
|
|
||||||
afterEnterHook && afterEnterHook(el)
|
|
||||||
}
|
|
||||||
el._enterCb = null
|
|
||||||
}))
|
|
||||||
|
|
||||||
// We need to wait until the native element has been inserted, but currently
|
|
||||||
// there's no API to do that. So we have to wait "one frame" - not entirely
|
|
||||||
// sure if this is guaranteed to be enough (e.g. on slow devices?)
|
|
||||||
setTimeout(() => {
|
|
||||||
const parent = el.parentNode
|
|
||||||
const pendingNode = parent && parent._pending && parent._pending[vnode.key]
|
|
||||||
if (
|
|
||||||
pendingNode &&
|
|
||||||
pendingNode.context === vnode.context &&
|
|
||||||
pendingNode.tag === vnode.tag &&
|
|
||||||
pendingNode.elm._leaveCb
|
|
||||||
) {
|
|
||||||
pendingNode.elm._leaveCb()
|
|
||||||
}
|
|
||||||
enterHook && enterHook(el, cb)
|
|
||||||
|
|
||||||
if (needAnimation) {
|
|
||||||
const animation = vnode.context.$requireWeexModule('animation')
|
|
||||||
animation.transition(
|
|
||||||
el.ref,
|
|
||||||
{
|
|
||||||
styles: endState,
|
|
||||||
duration: transitionProperties.duration || 0,
|
|
||||||
delay: transitionProperties.delay || 0,
|
|
||||||
timingFunction: transitionProperties.timingFunction || 'linear',
|
|
||||||
},
|
|
||||||
userWantsControl ? noop : cb
|
|
||||||
)
|
|
||||||
} else if (!userWantsControl) {
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
}, 16)
|
|
||||||
|
|
||||||
// start enter transition
|
|
||||||
beforeEnterHook && beforeEnterHook(el)
|
|
||||||
|
|
||||||
if (startState) {
|
|
||||||
if (typeof el.setStyles === 'function') {
|
|
||||||
el.setStyles(startState)
|
|
||||||
} else {
|
|
||||||
for (const key in startState) {
|
|
||||||
el.setStyle(key, startState[key])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!needAnimation && !userWantsControl) {
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function leave(vnode, rm) {
|
|
||||||
const el = vnode.elm
|
|
||||||
|
|
||||||
// call enter callback now
|
|
||||||
if (el._enterCb) {
|
|
||||||
el._enterCb.cancelled = true
|
|
||||||
el._enterCb()
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = resolveTransition(vnode.data.transition)
|
|
||||||
if (!data) {
|
|
||||||
return rm()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (el._leaveCb) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
leaveClass,
|
|
||||||
leaveToClass,
|
|
||||||
leaveActiveClass,
|
|
||||||
beforeLeave,
|
|
||||||
leave,
|
|
||||||
afterLeave,
|
|
||||||
leaveCancelled,
|
|
||||||
delayLeave,
|
|
||||||
} = data
|
|
||||||
|
|
||||||
const userWantsControl =
|
|
||||||
leave &&
|
|
||||||
// leave hook may be a bound method which exposes
|
|
||||||
// the length of original fn as _length
|
|
||||||
(leave._length || leave.length) > 1
|
|
||||||
|
|
||||||
const stylesheet = vnode.context.$options.style || {}
|
|
||||||
const startState = stylesheet[leaveClass]
|
|
||||||
const endState = stylesheet[leaveToClass] || stylesheet[leaveActiveClass]
|
|
||||||
const transitionProperties =
|
|
||||||
(stylesheet['@TRANSITION'] &&
|
|
||||||
stylesheet['@TRANSITION'][leaveActiveClass]) ||
|
|
||||||
{}
|
|
||||||
|
|
||||||
const cb = (el._leaveCb = once(() => {
|
|
||||||
if (el.parentNode && el.parentNode._pending) {
|
|
||||||
el.parentNode._pending[vnode.key] = null
|
|
||||||
}
|
|
||||||
//@ts-expect-error
|
|
||||||
if (cb.cancelled) {
|
|
||||||
leaveCancelled && leaveCancelled(el)
|
|
||||||
} else {
|
|
||||||
rm()
|
|
||||||
afterLeave && afterLeave(el)
|
|
||||||
}
|
|
||||||
el._leaveCb = null
|
|
||||||
}))
|
|
||||||
|
|
||||||
if (delayLeave) {
|
|
||||||
delayLeave(performLeave)
|
|
||||||
} else {
|
|
||||||
performLeave()
|
|
||||||
}
|
|
||||||
|
|
||||||
function performLeave() {
|
|
||||||
const animation = vnode.context.$requireWeexModule('animation')
|
|
||||||
// the delayed leave may have already been cancelled
|
|
||||||
//@ts-expect-error
|
|
||||||
if (cb.cancelled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// record leaving element
|
|
||||||
if (!vnode.data.show) {
|
|
||||||
(el.parentNode._pending || (el.parentNode._pending = {}))[
|
|
||||||
vnode.key
|
|
||||||
] = vnode
|
|
||||||
}
|
|
||||||
beforeLeave && beforeLeave(el)
|
|
||||||
|
|
||||||
if (startState) {
|
|
||||||
animation.transition(
|
|
||||||
el.ref,
|
|
||||||
{
|
|
||||||
styles: startState,
|
|
||||||
},
|
|
||||||
next
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
|
|
||||||
function next() {
|
|
||||||
animation.transition(
|
|
||||||
el.ref,
|
|
||||||
{
|
|
||||||
styles: endState,
|
|
||||||
duration: transitionProperties.duration || 0,
|
|
||||||
delay: transitionProperties.delay || 0,
|
|
||||||
timingFunction: transitionProperties.timingFunction || 'linear',
|
|
||||||
},
|
|
||||||
userWantsControl ? noop : cb
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
leave && leave(el, cb)
|
|
||||||
if (!endState && !userWantsControl) {
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine the target animation style for an entering transition.
|
|
||||||
function getEnterTargetState(
|
|
||||||
el,
|
|
||||||
stylesheet,
|
|
||||||
startClass,
|
|
||||||
endClass,
|
|
||||||
activeClass
|
|
||||||
) {
|
|
||||||
const targetState = {}
|
|
||||||
const startState = stylesheet[startClass]
|
|
||||||
const endState = stylesheet[endClass]
|
|
||||||
const activeState = stylesheet[activeClass]
|
|
||||||
// 1. fallback to element's default styling
|
|
||||||
if (startState) {
|
|
||||||
for (const key in startState) {
|
|
||||||
targetState[key] = el.style[key]
|
|
||||||
if (
|
|
||||||
process.env.NODE_ENV !== 'production' &&
|
|
||||||
targetState[key] == null &&
|
|
||||||
(!activeState || activeState[key] == null) &&
|
|
||||||
(!endState || endState[key] == null)
|
|
||||||
) {
|
|
||||||
warn(
|
|
||||||
`transition property "${key}" is declared in enter starting class (.${startClass}), ` +
|
|
||||||
`but not declared anywhere in enter ending class (.${endClass}), ` +
|
|
||||||
`enter active cass (.${activeClass}) or the element's default styling. ` +
|
|
||||||
`Note in Weex, CSS properties need explicit values to be transitionable.`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 2. if state is mixed in active state, extract them while excluding
|
|
||||||
// transition properties
|
|
||||||
if (activeState) {
|
|
||||||
for (const key in activeState) {
|
|
||||||
if (key.indexOf('transition') !== 0) {
|
|
||||||
targetState[key] = activeState[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 3. explicit endState has highest priority
|
|
||||||
if (endState) {
|
|
||||||
extend(targetState, endState)
|
|
||||||
}
|
|
||||||
return targetState
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
declare let document: WeexDocument
|
|
||||||
|
|
||||||
import type { WeexDocument, WeexElement } from 'typescript/weex'
|
|
||||||
import TextNode from 'weex/runtime/text-node'
|
|
||||||
|
|
||||||
export const namespaceMap = {}
|
|
||||||
|
|
||||||
export function createElement(tagName: string): WeexElement {
|
|
||||||
return document.createElement(tagName)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createElementNS(
|
|
||||||
namespace: string,
|
|
||||||
tagName: string
|
|
||||||
): WeexElement {
|
|
||||||
return document.createElement(namespace + ':' + tagName)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createTextNode(text: string) {
|
|
||||||
return new TextNode(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createComment(text: string) {
|
|
||||||
return document.createComment(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function insertBefore(
|
|
||||||
node: WeexElement,
|
|
||||||
target: WeexElement,
|
|
||||||
before: WeexElement
|
|
||||||
) {
|
|
||||||
if (target.nodeType === 3) {
|
|
||||||
if (node.type === 'text') {
|
|
||||||
node.setAttr('value', target.text)
|
|
||||||
target.parentNode = node
|
|
||||||
} else {
|
|
||||||
const text = createElement('text')
|
|
||||||
text.setAttr('value', target.text)
|
|
||||||
node.insertBefore(text, before)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
node.insertBefore(target, before)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeChild(node: WeexElement, child: WeexElement) {
|
|
||||||
if (child.nodeType === 3) {
|
|
||||||
node.setAttr('value', '')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
node.removeChild(child)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function appendChild(node: WeexElement, child: WeexElement) {
|
|
||||||
if (child.nodeType === 3) {
|
|
||||||
if (node.type === 'text') {
|
|
||||||
node.setAttr('value', child.text)
|
|
||||||
child.parentNode = node
|
|
||||||
} else {
|
|
||||||
const text = createElement('text')
|
|
||||||
text.setAttr('value', child.text)
|
|
||||||
node.appendChild(text)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
node.appendChild(child)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function parentNode(node: WeexElement): WeexElement | void {
|
|
||||||
return node.parentNode
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nextSibling(node: WeexElement): WeexElement | void {
|
|
||||||
return node.nextSibling
|
|
||||||
}
|
|
||||||
|
|
||||||
export function tagName(node: WeexElement): string {
|
|
||||||
return node.type
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setTextContent(node: WeexElement, text: string) {
|
|
||||||
if (node.parentNode) {
|
|
||||||
node.parentNode.setAttr('value', text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setAttribute(node: WeexElement, key: string, val: any) {
|
|
||||||
node.setAttr(key, val)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setStyleScope(node: WeexElement, scopeId: string) {
|
|
||||||
node.setAttr('@styleScope', scopeId)
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
|
|
||||||
import * as nodeOps from 'weex/runtime/node-ops'
|
|
||||||
import { createPatchFunction } from 'core/vdom/patch'
|
|
||||||
import baseModules from 'core/vdom/modules/index'
|
|
||||||
import platformModules from 'weex/runtime/modules/index'
|
|
||||||
|
|
||||||
// the directive module should be applied last, after all
|
|
||||||
// built-in modules have been applied.
|
|
||||||
const modules = platformModules.concat(baseModules)
|
|
||||||
|
|
||||||
export const patch: Function = createPatchFunction({
|
|
||||||
nodeOps,
|
|
||||||
modules,
|
|
||||||
LONG_LIST_THRESHOLD: 10,
|
|
||||||
})
|
|
|
@ -1,35 +0,0 @@
|
||||||
|
|
||||||
import { warn } from 'core/util/debug'
|
|
||||||
import { handleError } from 'core/util/error'
|
|
||||||
import { RECYCLE_LIST_MARKER } from 'weex/util/index'
|
|
||||||
import { createComponentInstanceForVnode } from 'core/vdom/create-component'
|
|
||||||
import { resolveVirtualComponent } from './virtual-component'
|
|
||||||
import type { MountedComponentVNode, VNodeWithData } from 'typescript/vnode'
|
|
||||||
import VNode from 'core/vdom/vnode'
|
|
||||||
|
|
||||||
export function isRecyclableComponent(vnode: VNodeWithData | VNode): boolean {
|
|
||||||
return vnode.data!.attrs ? RECYCLE_LIST_MARKER in vnode.data!.attrs : false
|
|
||||||
}
|
|
||||||
|
|
||||||
export function renderRecyclableComponentTemplate(
|
|
||||||
vnode: MountedComponentVNode | VNode
|
|
||||||
): VNode | undefined {
|
|
||||||
//@ts-expect-error
|
|
||||||
delete vnode.data.attrs[RECYCLE_LIST_MARKER]
|
|
||||||
resolveVirtualComponent(vnode)
|
|
||||||
const vm = createComponentInstanceForVnode(vnode)
|
|
||||||
const render = (vm.$options as any)['@render']
|
|
||||||
if (render) {
|
|
||||||
try {
|
|
||||||
return render.call(vm)
|
|
||||||
} catch (err:any) {
|
|
||||||
handleError(err, vm, `@render`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn(
|
|
||||||
`@render function not defined on component used in <recycle-list>. ` +
|
|
||||||
`Make sure to declare \`recyclable="true"\` on the component's template.`,
|
|
||||||
vm
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
|
|
||||||
// https://github.com/Hanks10100/weex-native-directive/tree/master/component
|
|
||||||
|
|
||||||
import { mergeOptions, isPlainObject, noop } from 'core/util/index'
|
|
||||||
import Watcher from 'core/observer/watcher'
|
|
||||||
import { initProxy } from 'core/instance/proxy'
|
|
||||||
import { initState, getData } from 'core/instance/state'
|
|
||||||
import { initRender } from 'core/instance/render'
|
|
||||||
import { initEvents } from 'core/instance/events'
|
|
||||||
import { initProvide, initInjections } from 'core/instance/inject'
|
|
||||||
import { initLifecycle, callHook } from 'core/instance/lifecycle'
|
|
||||||
import {
|
|
||||||
initInternalComponent,
|
|
||||||
resolveConstructorOptions,
|
|
||||||
} from 'core/instance/init'
|
|
||||||
import { registerComponentHook, updateComponentData } from '../../util/index'
|
|
||||||
import type { Component } from 'typescript/component'
|
|
||||||
import VNode from 'core/vdom/vnode'
|
|
||||||
import type { MountedComponentVNode } from 'typescript/vnode'
|
|
||||||
|
|
||||||
let uid = 0
|
|
||||||
|
|
||||||
// override Vue.prototype._init
|
|
||||||
function initVirtualComponent(options: Record<string, any> = {}) {
|
|
||||||
const vm: Component = this
|
|
||||||
const componentId = options.componentId
|
|
||||||
|
|
||||||
// virtual component uid
|
|
||||||
vm._uid = `virtual-component-${uid++}`
|
|
||||||
|
|
||||||
// a flag to avoid this being observed
|
|
||||||
vm._isVue = true
|
|
||||||
// merge options
|
|
||||||
if (options && options._isComponent) {
|
|
||||||
// optimize internal component instantiation
|
|
||||||
// since dynamic options merging is pretty slow, and none of the
|
|
||||||
// internal component options needs special treatment.
|
|
||||||
//@ts-expect-error
|
|
||||||
initInternalComponent(vm, options)
|
|
||||||
} else {
|
|
||||||
vm.$options = mergeOptions(
|
|
||||||
//@ts-expect-error
|
|
||||||
resolveConstructorOptions(vm.constructor),
|
|
||||||
options || {},
|
|
||||||
vm
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* istanbul ignore else */
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
|
||||||
initProxy(vm)
|
|
||||||
} else {
|
|
||||||
vm._renderProxy = vm
|
|
||||||
}
|
|
||||||
|
|
||||||
vm._self = vm
|
|
||||||
initLifecycle(vm)
|
|
||||||
initEvents(vm)
|
|
||||||
initRender(vm)
|
|
||||||
callHook(vm, 'beforeCreate')
|
|
||||||
initInjections(vm) // resolve injections before data/props
|
|
||||||
initState(vm)
|
|
||||||
initProvide(vm) // resolve provide after data/props
|
|
||||||
callHook(vm, 'created')
|
|
||||||
|
|
||||||
// send initial data to native
|
|
||||||
const data = vm.$options.data
|
|
||||||
const params = typeof data === 'function' ? getData(data, vm) : data || {}
|
|
||||||
if (isPlainObject(params)) {
|
|
||||||
updateComponentData(componentId, params)
|
|
||||||
}
|
|
||||||
|
|
||||||
registerComponentHook(componentId, 'lifecycle', 'attach', () => {
|
|
||||||
callHook(vm, 'beforeMount')
|
|
||||||
|
|
||||||
const updateComponent = () => {
|
|
||||||
vm._update(vm._vnode!, false)
|
|
||||||
}
|
|
||||||
new Watcher(vm, updateComponent, noop, null, true)
|
|
||||||
|
|
||||||
vm._isMounted = true
|
|
||||||
callHook(vm, 'mounted')
|
|
||||||
})
|
|
||||||
|
|
||||||
registerComponentHook(componentId, 'lifecycle', 'detach', () => {
|
|
||||||
vm.$destroy()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// override Vue.prototype._update
|
|
||||||
function updateVirtualComponent(vnode?: VNode) {
|
|
||||||
const vm: Component = this
|
|
||||||
const componentId = vm.$options.componentId
|
|
||||||
if (vm._isMounted) {
|
|
||||||
callHook(vm, 'beforeUpdate')
|
|
||||||
}
|
|
||||||
vm._vnode = vnode
|
|
||||||
if (vm._isMounted && componentId) {
|
|
||||||
// TODO: data should be filtered and without bindings
|
|
||||||
const data = Object.assign({}, vm._data)
|
|
||||||
updateComponentData(componentId, data, () => {
|
|
||||||
callHook(vm, 'updated')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// listening on native callback
|
|
||||||
export function resolveVirtualComponent(
|
|
||||||
vnode: MountedComponentVNode | VNode
|
|
||||||
): void {
|
|
||||||
const BaseCtor = vnode.componentOptions!.Ctor
|
|
||||||
const VirtualComponent = BaseCtor.extend({})
|
|
||||||
const cid = VirtualComponent.cid
|
|
||||||
VirtualComponent.prototype._init = initVirtualComponent
|
|
||||||
VirtualComponent.prototype._update = updateVirtualComponent
|
|
||||||
|
|
||||||
vnode.componentOptions!.Ctor = BaseCtor.extend({
|
|
||||||
beforeCreate() {
|
|
||||||
// const vm: Component = this
|
|
||||||
|
|
||||||
// TODO: listen on all events and dispatch them to the
|
|
||||||
// corresponding virtual components according to the componentId.
|
|
||||||
// vm._virtualComponents = {}
|
|
||||||
const createVirtualComponent = (componentId, propsData) => {
|
|
||||||
// create virtual component
|
|
||||||
// const subVm =
|
|
||||||
new VirtualComponent({
|
|
||||||
componentId,
|
|
||||||
propsData,
|
|
||||||
})
|
|
||||||
// if (vm._virtualComponents) {
|
|
||||||
// vm._virtualComponents[componentId] = subVm
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
registerComponentHook(cid, 'lifecycle', 'create', createVirtualComponent)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
delete this._virtualComponents
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
let latestNodeId = 1
|
|
||||||
|
|
||||||
export default function TextNode(text) {
|
|
||||||
this.instanceId = ''
|
|
||||||
this.nodeId = latestNodeId++
|
|
||||||
this.parentNode = null
|
|
||||||
this.nodeType = 3
|
|
||||||
this.text = text
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
import "core/config";
|
|
||||||
|
|
||||||
declare module "core/config" {
|
|
||||||
interface Config {
|
|
||||||
isRuntimeComponent: (key: string) => true | undefined;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
// These util functions are split into its own file because Rollup cannot drop
|
|
||||||
// makeMap() due to potential side effects, so these variables end up
|
|
||||||
// bloating the web builds.
|
|
||||||
|
|
||||||
import { makeMap, noop } from "shared/util";
|
|
||||||
|
|
||||||
export const isReservedTag = makeMap(
|
|
||||||
"template,script,style,element,content,slot,link,meta,svg,view," +
|
|
||||||
"a,div,img,image,text,span,input,switch,textarea,spinner,select," +
|
|
||||||
"slider,slider-neighbor,indicator,canvas," +
|
|
||||||
"list,cell,header,loading,loading-indicator,refresh,scrollable,scroller," +
|
|
||||||
"video,web,embed,tabbar,tabheader,datepicker,timepicker,marquee,countdown",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// Elements that you can, intentionally, leave open (and which close themselves)
|
|
||||||
// more flexible than web
|
|
||||||
export const canBeLeftOpenTag = makeMap(
|
|
||||||
"web,spinner,switch,video,textarea,canvas," + "indicator,marquee,countdown",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
export const isRuntimeComponent = makeMap(
|
|
||||||
"richtext,transition,transition-group",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
export const isUnaryTag = makeMap("embed,img,image,input,link,meta", true);
|
|
||||||
|
|
||||||
export function mustUseProp(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getTagNamespace() {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isUnknownElement(): boolean {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function query(el: string | Element, document: any) {
|
|
||||||
// document is injected by weex factory wrapper
|
|
||||||
const placeholder = document.createComment("root");
|
|
||||||
placeholder.hasAttribute = placeholder.removeAttribute = noop; // hack for patch
|
|
||||||
document.documentElement.appendChild(placeholder);
|
|
||||||
return placeholder;
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
declare let document: WeexDocument
|
|
||||||
|
|
||||||
import { warn } from 'core/util/index'
|
|
||||||
import type { WeexDocument } from 'typescript/weex'
|
|
||||||
|
|
||||||
export const RECYCLE_LIST_MARKER = '@inRecycleList'
|
|
||||||
|
|
||||||
// Register the component hook to weex native render engine.
|
|
||||||
// The hook will be triggered by native, not javascript.
|
|
||||||
export function registerComponentHook(
|
|
||||||
componentId: string,
|
|
||||||
type: string, // hook type, could be "lifecycle" or "instance"
|
|
||||||
hook: string, // hook name
|
|
||||||
fn: Function
|
|
||||||
) {
|
|
||||||
if (!document || !document.taskCenter) {
|
|
||||||
warn(`Can't find available "document" or "taskCenter".`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (typeof document.taskCenter.registerHook === 'function') {
|
|
||||||
return document.taskCenter.registerHook(componentId, type, hook, fn)
|
|
||||||
}
|
|
||||||
warn(`Failed to register component hook "${type}@${hook}#${componentId}".`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates the state of the component to weex native render engine.
|
|
||||||
export function updateComponentData(
|
|
||||||
componentId: string,
|
|
||||||
newData: Object | void,
|
|
||||||
callback?: Function
|
|
||||||
) {
|
|
||||||
if (!document || !document.taskCenter) {
|
|
||||||
warn(`Can't find available "document" or "taskCenter".`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (typeof document.taskCenter.updateData === 'function') {
|
|
||||||
return document.taskCenter.updateData(componentId, newData, callback)
|
|
||||||
}
|
|
||||||
warn(`Failed to update component data (${componentId}).`)
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
// import { warn } from 'core/util/index'
|
|
||||||
|
|
||||||
import acorn from 'acorn'
|
|
||||||
import walk from "acorn-walk";
|
|
||||||
const escodegen = require("escodegen");
|
|
||||||
|
|
||||||
|
|
||||||
export function nodeToBinding(node: any): any {
|
|
||||||
switch (node.type) {
|
|
||||||
case "Literal":
|
|
||||||
return node.value;
|
|
||||||
case "Identifier":
|
|
||||||
case "UnaryExpression":
|
|
||||||
case "BinaryExpression":
|
|
||||||
case "LogicalExpression":
|
|
||||||
case "ConditionalExpression":
|
|
||||||
case "MemberExpression":
|
|
||||||
return { "@binding": escodegen.generate(node) };
|
|
||||||
case "ArrayExpression":
|
|
||||||
return node.elements.map((_) => nodeToBinding(_));
|
|
||||||
case "ObjectExpression": {
|
|
||||||
const object = {};
|
|
||||||
node.properties.forEach((prop) => {
|
|
||||||
if (!prop.key || prop.key.type !== "Identifier") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const key = escodegen.generate(prop.key);
|
|
||||||
const value = nodeToBinding(prop.value);
|
|
||||||
if (key && value) {
|
|
||||||
object[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
// warn(`Not support ${node.type}: "${escodegen.generate(node)}"`)
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateBinding(exp?: string): any {
|
|
||||||
if (exp && typeof exp === "string") {
|
|
||||||
let ast: acorn.Node| null = null;
|
|
||||||
try {
|
|
||||||
ast = acorn.parse(`(${exp})`, {ecmaVersion: 5});
|
|
||||||
} catch (e: any) {
|
|
||||||
// warn(`Failed to parse the expression: "${exp}"`)
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = "";
|
|
||||||
walk.simple(ast, {
|
|
||||||
Expression(node) {
|
|
||||||
output = nodeToBinding(node);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
;(global as any).__WEEX__ = false
|
|
||||||
;(global as any).__SSR_TEST__ = false
|
;(global as any).__SSR_TEST__ = false
|
||||||
|
|
||||||
process.env.NEW_SLOT_SYNTAX = 'true'
|
process.env.NEW_SLOT_SYNTAX = 'true'
|
||||||
|
|
||||||
import './helpers/shim-done'
|
import './helpers/shim-done'
|
||||||
|
|
|
@ -1,238 +0,0 @@
|
||||||
import {
|
|
||||||
readFile,
|
|
||||||
readObject,
|
|
||||||
compileVue,
|
|
||||||
compileWithDeps,
|
|
||||||
createInstance,
|
|
||||||
addTaskHook,
|
|
||||||
resetTaskHook,
|
|
||||||
getRoot,
|
|
||||||
getEvents,
|
|
||||||
fireEvent
|
|
||||||
} from '../helpers'
|
|
||||||
|
|
||||||
// Create one-off render test case
|
|
||||||
function createRenderTestCase (name) {
|
|
||||||
const source = readFile(`${name}.vue`)
|
|
||||||
const target = readObject(`${name}.vdom.js`)
|
|
||||||
return done => {
|
|
||||||
compileVue(source).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(getRoot(instance)).toEqual(target)
|
|
||||||
instance.$destroy()
|
|
||||||
done()
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create event test case, will trigger the first bind event
|
|
||||||
function createEventTestCase (name) {
|
|
||||||
const source = readFile(`${name}.vue`)
|
|
||||||
const before = readObject(`${name}.before.vdom.js`)
|
|
||||||
const after = readObject(`${name}.after.vdom.js`)
|
|
||||||
return done => {
|
|
||||||
compileVue(source).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(getRoot(instance)).toEqual(before)
|
|
||||||
const event = getEvents(instance)[0]
|
|
||||||
fireEvent(instance, event.ref, event.type, {})
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(getRoot(instance)).toEqual(after)
|
|
||||||
instance.$destroy()
|
|
||||||
done()
|
|
||||||
}, 50)
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Usage', () => {
|
|
||||||
describe('render', () => {
|
|
||||||
it('sample', createRenderTestCase('render/sample'))
|
|
||||||
it('class', createRenderTestCase('render/class'))
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('event', () => {
|
|
||||||
it('click', createEventTestCase('event/click'))
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('recycle-list', () => {
|
|
||||||
it('text node', createRenderTestCase('recycle-list/text-node'))
|
|
||||||
it('attributes', createRenderTestCase('recycle-list/attrs'))
|
|
||||||
// it('class name', createRenderTestCase('recycle-list/classname'))
|
|
||||||
it('inline style', createRenderTestCase('recycle-list/inline-style'))
|
|
||||||
it('v-if', createRenderTestCase('recycle-list/v-if'))
|
|
||||||
it('v-else', createRenderTestCase('recycle-list/v-else'))
|
|
||||||
it('v-else-if', createRenderTestCase('recycle-list/v-else-if'))
|
|
||||||
it('v-for', createRenderTestCase('recycle-list/v-for'))
|
|
||||||
it('v-for-iterator', createRenderTestCase('recycle-list/v-for-iterator'))
|
|
||||||
it('v-on', createRenderTestCase('recycle-list/v-on'))
|
|
||||||
it('v-on-inline', createRenderTestCase('recycle-list/v-on-inline'))
|
|
||||||
it('v-once', createRenderTestCase('recycle-list/v-once'))
|
|
||||||
|
|
||||||
it('stateless component', done => {
|
|
||||||
compileWithDeps('recycle-list/components/stateless.vue', [{
|
|
||||||
name: 'banner',
|
|
||||||
path: 'recycle-list/components/banner.vue'
|
|
||||||
}]).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
setTimeout(() => {
|
|
||||||
const target = readObject('recycle-list/components/stateless.vdom.js')
|
|
||||||
expect(getRoot(instance)).toEqual(target)
|
|
||||||
instance.$destroy()
|
|
||||||
done()
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('stateless component with props', done => {
|
|
||||||
compileWithDeps('recycle-list/components/stateless-with-props.vue', [{
|
|
||||||
name: 'poster',
|
|
||||||
path: 'recycle-list/components/poster.vue'
|
|
||||||
}]).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
setTimeout(() => {
|
|
||||||
const target = readObject('recycle-list/components/stateless-with-props.vdom.js')
|
|
||||||
expect(getRoot(instance)).toEqual(target)
|
|
||||||
instance.$destroy()
|
|
||||||
done()
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('multi stateless components', done => {
|
|
||||||
compileWithDeps('recycle-list/components/stateless-multi-components.vue', [{
|
|
||||||
name: 'banner',
|
|
||||||
path: 'recycle-list/components/banner.vue'
|
|
||||||
}, {
|
|
||||||
name: 'poster',
|
|
||||||
path: 'recycle-list/components/poster.vue'
|
|
||||||
}, {
|
|
||||||
name: 'footer',
|
|
||||||
path: 'recycle-list/components/footer.vue'
|
|
||||||
}]).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
setTimeout(() => {
|
|
||||||
const target = readObject('recycle-list/components/stateless-multi-components.vdom.js')
|
|
||||||
expect(getRoot(instance)).toEqual(target)
|
|
||||||
instance.$destroy()
|
|
||||||
done()
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('stateful component', done => {
|
|
||||||
const tasks: any[] = []
|
|
||||||
addTaskHook((_, task) => tasks.push(task))
|
|
||||||
compileWithDeps('recycle-list/components/stateful.vue', [{
|
|
||||||
name: 'counter',
|
|
||||||
path: 'recycle-list/components/counter.vue'
|
|
||||||
}]).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
// expect(tasks.length).toEqual(3)
|
|
||||||
setTimeout(() => {
|
|
||||||
// check the render results
|
|
||||||
const target = readObject('recycle-list/components/stateful.vdom.js')
|
|
||||||
expect(getRoot(instance)).toEqual(target)
|
|
||||||
tasks.length = 0
|
|
||||||
|
|
||||||
// // trigger component hooks
|
|
||||||
// instance.$triggerHook(
|
|
||||||
// 2, // cid of the virtual component template
|
|
||||||
// 'create', // lifecycle hook name
|
|
||||||
|
|
||||||
// // arguments for the callback
|
|
||||||
// [
|
|
||||||
// 'x-1', // componentId of the virtual component
|
|
||||||
// { start: 3 } // propsData of the virtual component
|
|
||||||
// ]
|
|
||||||
// )
|
|
||||||
// instance.$triggerHook(2, 'create', ['x-2', { start: 11 }])
|
|
||||||
|
|
||||||
// // the state (_data) of the virtual component should be sent to native
|
|
||||||
// expect(tasks.length).toEqual(2)
|
|
||||||
// expect(tasks[0].method).toEqual('updateComponentData')
|
|
||||||
// expect(tasks[0].args).toEqual(['x-1', { count: 6 }, ''])
|
|
||||||
// expect(tasks[1].method).toEqual('updateComponentData')
|
|
||||||
// expect(tasks[1].args).toEqual(['x-2', { count: 22 }, ''])
|
|
||||||
|
|
||||||
// instance.$triggerHook('x-1', 'attach')
|
|
||||||
// instance.$triggerHook('x-2', 'attach')
|
|
||||||
// tasks.length = 0
|
|
||||||
|
|
||||||
// // simulate a click event
|
|
||||||
// // the event will be caught by the virtual component template and
|
|
||||||
// // should be dispatched to virtual component according to the componentId
|
|
||||||
// const event = getEvents(instance)[0]
|
|
||||||
// fireEvent(instance, event.ref, 'click', { componentId: 'x-1' })
|
|
||||||
setTimeout(() => {
|
|
||||||
// expect(tasks.length).toEqual(1)
|
|
||||||
// expect(tasks[0].method).toEqual('updateComponentData')
|
|
||||||
// expect(tasks[0].args).toEqual([{ count: 7 }])
|
|
||||||
instance.$destroy()
|
|
||||||
resetTaskHook()
|
|
||||||
done()
|
|
||||||
})
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
})
|
|
||||||
|
|
||||||
// it('component lifecycle', done => {
|
|
||||||
// global.__lifecycles = []
|
|
||||||
// compileWithDeps('recycle-list/components/stateful-lifecycle.vue', [{
|
|
||||||
// name: 'lifecycle',
|
|
||||||
// path: 'recycle-list/components/lifecycle.vue'
|
|
||||||
// }]).then(code => {
|
|
||||||
// const id = String(Date.now() * Math.random())
|
|
||||||
// const instance = createInstance(id, code)
|
|
||||||
// setTimeout(() => {
|
|
||||||
// const target = readObject('recycle-list/components/stateful-lifecycle.vdom.js')
|
|
||||||
// expect(getRoot(instance)).toEqual(target)
|
|
||||||
|
|
||||||
// instance.$triggerHook(2, 'create', ['y-1'])
|
|
||||||
// instance.$triggerHook('y-1', 'attach')
|
|
||||||
// instance.$triggerHook('y-1', 'detach')
|
|
||||||
// expect(global.__lifecycles).toEqual([
|
|
||||||
// 'beforeCreate undefined',
|
|
||||||
// 'created 0',
|
|
||||||
// 'beforeMount 1',
|
|
||||||
// 'mounted 1',
|
|
||||||
// 'beforeUpdate 2',
|
|
||||||
// 'updated 2',
|
|
||||||
// 'beforeDestroy 2',
|
|
||||||
// 'destroyed 2'
|
|
||||||
// ])
|
|
||||||
|
|
||||||
// delete global.__lifecycles
|
|
||||||
// instance.$destroy()
|
|
||||||
// done()
|
|
||||||
// }, 50)
|
|
||||||
// }).catch(done.fail)
|
|
||||||
// })
|
|
||||||
|
|
||||||
it('stateful component with v-model', done => {
|
|
||||||
compileWithDeps('recycle-list/components/stateful-v-model.vue', [{
|
|
||||||
name: 'editor',
|
|
||||||
path: 'recycle-list/components/editor.vue'
|
|
||||||
}]).then(code => {
|
|
||||||
const id = String(Date.now() * Math.random())
|
|
||||||
const instance = createInstance(id, code)
|
|
||||||
setTimeout(() => {
|
|
||||||
const target = readObject('recycle-list/components/stateful-v-model.vdom.js')
|
|
||||||
expect(getRoot(instance)).toEqual(target)
|
|
||||||
instance.$destroy()
|
|
||||||
done()
|
|
||||||
}, 50)
|
|
||||||
}).catch(done.fail)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -1,10 +0,0 @@
|
||||||
({
|
|
||||||
type: 'div',
|
|
||||||
event: ['click'],
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: '43'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,10 +0,0 @@
|
||||||
({
|
|
||||||
type: 'div',
|
|
||||||
event: ['click'],
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: '42'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,20 +0,0 @@
|
||||||
<template>
|
|
||||||
<div @click="inc">
|
|
||||||
<text>{{count}}</text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
count: 42
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
inc () {
|
|
||||||
this.count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,34 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A', count: 1, source: 'http://whatever.com/x.png' },
|
|
||||||
{ type: 'A', count: 2, source: 'http://whatever.com/y.png' },
|
|
||||||
{ type: 'A', count: 3, source: 'http://whatever.com/z.png' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'image',
|
|
||||||
attr: {
|
|
||||||
resize: 'cover',
|
|
||||||
src: {
|
|
||||||
'@binding': 'item.source'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
lines: '3',
|
|
||||||
count: {
|
|
||||||
'@binding': 'item.count'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<image resize="cover" :src="item.source">
|
|
||||||
<text lines="3" v-bind:count="item.count"></text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A', count: 1, source: 'http://whatever.com/x.png' },
|
|
||||||
{ type: 'A', count: 2, source: 'http://whatever.com/y.png' },
|
|
||||||
{ type: 'A', count: 3, source: 'http://whatever.com/z.png' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A', color: 'red' },
|
|
||||||
{ type: 'A', color: 'blue' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
style: {
|
|
||||||
backgroundColor: '#FF6600'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
// not supported yet
|
|
||||||
// classList: ['text', { '@binding': 'item.color' }],
|
|
||||||
value: 'content'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,37 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A" class="cell">
|
|
||||||
<text :class="['text', item.color]">content</text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.cell {
|
|
||||||
background-color: #FF6600;
|
|
||||||
}
|
|
||||||
.text {
|
|
||||||
font-size: 100px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.red {
|
|
||||||
color: #FF0000;
|
|
||||||
}
|
|
||||||
.blue {
|
|
||||||
color: #0000FF;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A', color: 'red' },
|
|
||||||
{ type: 'A', color: 'blue' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<template recyclable="true">
|
|
||||||
<div class="banner">
|
|
||||||
<text class="title">BANNER</text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.banner {
|
|
||||||
height: 120px;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
background-color: rgb(162, 217, 192);
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #41B883;
|
|
||||||
font-size: 60px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,36 +0,0 @@
|
||||||
<template recyclable="true">
|
|
||||||
<div>
|
|
||||||
<text class="output">{{count}}</text>
|
|
||||||
<text class="button" @click="inc">+</text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
props: ['start'],
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
count: parseInt(this.start, 10) * 2 || 42
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
inc () {
|
|
||||||
this.count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.output {
|
|
||||||
font-size: 150px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.button {
|
|
||||||
font-size: 100px;
|
|
||||||
text-align: center;
|
|
||||||
border-width: 2px;
|
|
||||||
border-color: #DDD;
|
|
||||||
background-color: #F5F5F5;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,31 +0,0 @@
|
||||||
<template recyclable="true">
|
|
||||||
<div>
|
|
||||||
<text class="output">{{output}}</text>
|
|
||||||
<input class="input" type="text" v-model="output" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
props: ['message'],
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
output: this.message || ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.output {
|
|
||||||
height: 80px;
|
|
||||||
font-size: 60px;
|
|
||||||
color: #41B883;
|
|
||||||
}
|
|
||||||
.input {
|
|
||||||
font-size: 50px;
|
|
||||||
color: #666666;
|
|
||||||
border-width: 2px;
|
|
||||||
border-color: #41B883;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template recyclable="true">
|
|
||||||
<div class="footer">
|
|
||||||
<text class="copyright">All rights reserved.</text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.footer {
|
|
||||||
height: 80px;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: #EEEEEE;
|
|
||||||
}
|
|
||||||
.copyright {
|
|
||||||
color: #AAAAAA;
|
|
||||||
font-size: 32px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,39 +0,0 @@
|
||||||
<template recyclable="true">
|
|
||||||
<div>
|
|
||||||
<text>{{number}}</text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return { number: 0 }
|
|
||||||
},
|
|
||||||
beforeCreate () {
|
|
||||||
try { __lifecycles.push('beforeCreate ' + this.number) } catch (e) {}
|
|
||||||
},
|
|
||||||
created () {
|
|
||||||
try { __lifecycles.push('created ' + this.number) } catch (e) {}
|
|
||||||
this.number++
|
|
||||||
},
|
|
||||||
beforeMount () {
|
|
||||||
try { __lifecycles.push('beforeMount ' + this.number) } catch (e) {}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
try { __lifecycles.push('mounted ' + this.number) } catch (e) {}
|
|
||||||
this.number++
|
|
||||||
},
|
|
||||||
beforeUpdate () {
|
|
||||||
try { __lifecycles.push('beforeUpdate ' + this.number) } catch (e) {}
|
|
||||||
},
|
|
||||||
updated () {
|
|
||||||
try { __lifecycles.push('updated ' + this.number) } catch (e) {}
|
|
||||||
},
|
|
||||||
beforeDestroy () {
|
|
||||||
try { __lifecycles.push('beforeDestroy ' + this.number) } catch (e) {}
|
|
||||||
},
|
|
||||||
destroyed () {
|
|
||||||
try { __lifecycles.push('destroyed ' + this.number) } catch (e) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<template recyclable="true">
|
|
||||||
<div>
|
|
||||||
<image class="image" :src="imageUrl"></image>
|
|
||||||
<text class="title">{{title}}</text>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
props: {
|
|
||||||
imageUrl: {
|
|
||||||
type: String,
|
|
||||||
default: 'https://gw.alicdn.com/tfs/TB1KF_ybRTH8KJjy0FiXXcRsXXa-890-1186.png'
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: 'I WANT YOU!'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.image {
|
|
||||||
width: 750px;
|
|
||||||
height: 1000px;
|
|
||||||
}
|
|
||||||
.title {
|
|
||||||
font-size: 80px;
|
|
||||||
text-align: center;
|
|
||||||
color: #E95659;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,29 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'X' },
|
|
||||||
{ type: 'X' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'X' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {}
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: { '@binding': 'number' }
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,21 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="X">
|
|
||||||
<lifecycle></lifecycle>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// require('./lifecycle.vue')
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'X' },
|
|
||||||
{ type: 'X' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,40 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A' },
|
|
||||||
{ type: 'A' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {
|
|
||||||
message: 'No binding'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
classList: ['output'],
|
|
||||||
attr: {
|
|
||||||
value: { '@binding': 'output' }
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'input',
|
|
||||||
event: ['input'],
|
|
||||||
classList: ['input'],
|
|
||||||
attr: {
|
|
||||||
type: 'text',
|
|
||||||
value: 'No binding'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,21 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<editor message="No binding"></editor>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// require('./editor.vue')
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A' },
|
|
||||||
{ type: 'A' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,40 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A', number: 24 },
|
|
||||||
{ type: 'A', number: 42 }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {
|
|
||||||
start: { '@binding': 'item.number' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
classList: ['output'],
|
|
||||||
attr: {
|
|
||||||
value: { '@binding': 'count' } // need confirm
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
event: ['click'],
|
|
||||||
classList: ['button'],
|
|
||||||
attr: { value: '+' }
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: { value: 'other' }
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,22 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<counter :start="item.number"></counter>
|
|
||||||
<text>other</text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// require('./counter.vue')
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A', number: 24 },
|
|
||||||
{ type: 'A', number: 42 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,83 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A' },
|
|
||||||
{ type: 'B', poster: 'yy', title: 'y' },
|
|
||||||
{ type: 'A' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {}
|
|
||||||
},
|
|
||||||
classList: ['banner'],
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
classList: ['title'],
|
|
||||||
attr: { value: 'BANNER' }
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: { value: '----' }
|
|
||||||
}, {
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {}
|
|
||||||
},
|
|
||||||
classList: ['footer'],
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
classList: ['copyright'],
|
|
||||||
attr: { value: 'All rights reserved.' }
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'B' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {}
|
|
||||||
},
|
|
||||||
classList: ['banner'],
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
classList: ['title'],
|
|
||||||
attr: { value: 'BANNER' }
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {
|
|
||||||
imageUrl: { '@binding': 'item.poster' },
|
|
||||||
title: { '@binding': 'item.title' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'image',
|
|
||||||
classList: ['image'],
|
|
||||||
attr: {
|
|
||||||
src: { '@binding': 'imageUrl' }
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
classList: ['title'],
|
|
||||||
attr: {
|
|
||||||
value: { '@binding': 'title' }
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,30 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<banner></banner>
|
|
||||||
<text>----</text>
|
|
||||||
<footer></footer>
|
|
||||||
</cell-slot>
|
|
||||||
<cell-slot case="B">
|
|
||||||
<banner></banner>
|
|
||||||
<poster :image-url="item.poster" :title="item.title"></poster>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// require('./banner.vue')
|
|
||||||
// require('./footer.vue')
|
|
||||||
// require('./poster.vue')
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A' },
|
|
||||||
{ type: 'B', poster: 'yy', title: 'y' },
|
|
||||||
{ type: 'A' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,44 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A', poster: 'xx', title: 'x' },
|
|
||||||
{ type: 'A', poster: 'yy', title: 'y' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {
|
|
||||||
imageUrl: { '@binding': 'item.poster' },
|
|
||||||
title: { '@binding': 'item.title' }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'image',
|
|
||||||
classList: ['image'],
|
|
||||||
attr: {
|
|
||||||
src: { '@binding': 'imageUrl' }
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
classList: ['title'],
|
|
||||||
attr: {
|
|
||||||
value: { '@binding': 'title' }
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: 'content'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,22 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<poster :image-url="item.poster" :title="item.title"></poster>
|
|
||||||
<text>content</text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// require('./poster.vue')
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A', poster: 'xx', title: 'x' },
|
|
||||||
{ type: 'A', poster: 'yy', title: 'y' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,36 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A' },
|
|
||||||
{ type: 'A' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'div',
|
|
||||||
attr: {
|
|
||||||
'@isComponentRoot': true,
|
|
||||||
'@componentProps': {}
|
|
||||||
},
|
|
||||||
classList: ['banner'],
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
classList: ['title'],
|
|
||||||
attr: {
|
|
||||||
value: 'BANNER'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: 'content'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,22 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<banner></banner>
|
|
||||||
<text>content</text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// require('./banner.vue')
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A' },
|
|
||||||
{ type: 'A' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,29 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A', color: '#606060' },
|
|
||||||
{ type: 'A', color: '#E5E5E5' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
style: {
|
|
||||||
backgroundColor: '#FF6600'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
style: {
|
|
||||||
fontSize: '100px',
|
|
||||||
color: { '@binding': 'item.color' }
|
|
||||||
},
|
|
||||||
attr: {
|
|
||||||
value: 'content'
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,21 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A" style="background-color:#FF6600">
|
|
||||||
<text :style="{ fontSize: '100px', color: item.color }">content</text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A', color: '#606060' },
|
|
||||||
{ type: 'A', color: '#E5E5E5' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
({
|
|
||||||
type: 'recycle-list',
|
|
||||||
attr: {
|
|
||||||
append: 'tree',
|
|
||||||
listData: [
|
|
||||||
{ type: 'A', dynamic: 'decimal', two: '2', four: '4' },
|
|
||||||
{ type: 'A', dynamic: 'binary', two: '10', four: '100' }
|
|
||||||
],
|
|
||||||
switch: 'type',
|
|
||||||
alias: 'item'
|
|
||||||
},
|
|
||||||
children: [{
|
|
||||||
type: 'cell-slot',
|
|
||||||
attr: { append: 'tree', case: 'A' },
|
|
||||||
children: [{
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: 'static'
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: { '@binding': 'item.dynamic' }
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
type: 'text',
|
|
||||||
attr: {
|
|
||||||
value: [
|
|
||||||
'one ',
|
|
||||||
{ '@binding': 'item.two' },
|
|
||||||
' three ',
|
|
||||||
{ '@binding': 'item.four' },
|
|
||||||
' five'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}]
|
|
||||||
})
|
|
|
@ -1,23 +0,0 @@
|
||||||
<template>
|
|
||||||
<recycle-list for="item in longList" switch="type">
|
|
||||||
<cell-slot case="A">
|
|
||||||
<text>static</text>
|
|
||||||
<text>{{item.dynamic}}</text>
|
|
||||||
<text>one {{item.two}} three {{ item.four }} five</text>
|
|
||||||
</cell-slot>
|
|
||||||
</recycle-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
module.exports = {
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
longList: [
|
|
||||||
{ type: 'A', dynamic: 'decimal', two: '2', four: '4' },
|
|
||||||
{ type: 'A', dynamic: 'binary', two: '10', four: '100' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue