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: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: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: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 && npm run test:weex",
|
||||
"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": "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:unit": "vitest run",
|
||||
"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",
|
||||
"lint": "eslint src scripts test",
|
||||
"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",
|
||||
"release": "bash scripts/release.sh",
|
||||
"release:weex": "bash scripts/release-weex.sh",
|
||||
"release:note": "node scripts/gen-release-note.js",
|
||||
"commit": "git-cz"
|
||||
},
|
||||
|
@ -110,8 +99,6 @@
|
|||
"typescript": "^4.6.4",
|
||||
"vitest": "^0.12.6",
|
||||
"webpack": "^5.72.1",
|
||||
"weex-js-runtime": "^0.23.6",
|
||||
"weex-styler": "^0.3.0",
|
||||
"yorkie": "^2.0.0"
|
||||
},
|
||||
"config": {
|
||||
|
|
|
@ -160,9 +160,6 @@ export interface ASTElement {
|
|||
|
||||
// 2.4 ssr optimization
|
||||
ssrOptimizability?: SSROptimizability;
|
||||
|
||||
// weex specific
|
||||
appendAsTree?: boolean;
|
||||
}
|
||||
|
||||
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
|
||||
vitest: ^0.12.6
|
||||
webpack: ^5.72.1
|
||||
weex-js-runtime: ^0.23.6
|
||||
weex-styler: ^0.3.0
|
||||
yorkie: ^2.0.0
|
||||
|
||||
devDependencies:
|
||||
|
@ -92,8 +90,6 @@ devDependencies:
|
|||
typescript: 4.6.4
|
||||
vitest: 0.12.6_jsdom@19.0.0
|
||||
webpack: 5.72.1
|
||||
weex-js-runtime: 0.23.7
|
||||
weex-styler: 0.3.1
|
||||
yorkie: 2.0.0
|
||||
|
||||
packages:
|
||||
|
@ -837,12 +833,6 @@ packages:
|
|||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
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:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
dev: true
|
||||
|
@ -1315,15 +1305,6 @@ packages:
|
|||
which: 2.0.2
|
||||
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:
|
||||
resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==}
|
||||
dev: true
|
||||
|
@ -1448,11 +1429,6 @@ packages:
|
|||
resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==}
|
||||
dev: true
|
||||
|
||||
/decode-uri-component/0.2.0:
|
||||
resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=}
|
||||
engines: {node: '>=0.10'}
|
||||
dev: true
|
||||
|
||||
/dedent/0.7.0:
|
||||
resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=}
|
||||
dev: true
|
||||
|
@ -3629,11 +3605,6 @@ packages:
|
|||
dev: 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:
|
||||
resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
|
||||
hasBin: true
|
||||
|
@ -3861,17 +3832,6 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
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:
|
||||
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
|
||||
dependencies:
|
||||
|
@ -3879,11 +3839,6 @@ packages:
|
|||
source-map: 0.6.1
|
||||
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:
|
||||
resolution: {integrity: sha1-dc449SvwczxafwwRjYEzSiu19BI=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -4350,11 +4305,6 @@ packages:
|
|||
punycode: 2.1.1
|
||||
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:
|
||||
resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==}
|
||||
dev: true
|
||||
|
@ -4510,17 +4460,6 @@ packages:
|
|||
- uglify-js
|
||||
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:
|
||||
resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
|
@ -8,7 +8,6 @@ module.exports = {
|
|||
core: resolve('src/core'),
|
||||
shared: resolve('src/shared'),
|
||||
web: resolve('src/platforms/web'),
|
||||
weex: resolve('src/platforms/weex'),
|
||||
server: resolve('src/server'),
|
||||
sfc: resolve('src/sfc')
|
||||
}
|
||||
|
|
|
@ -16,11 +16,6 @@ if (process.argv[2]) {
|
|||
builds = builds.filter(b => {
|
||||
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)
|
||||
|
|
|
@ -6,9 +6,6 @@ const node = require('@rollup/plugin-node-resolve').nodeResolve
|
|||
const ts = require('rollup-plugin-typescript2')
|
||||
|
||||
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 banner =
|
||||
|
@ -18,15 +15,6 @@ const banner =
|
|||
' * Released under the MIT License.\n' +
|
||||
' */'
|
||||
|
||||
const weexFactoryPlugin = {
|
||||
intro() {
|
||||
return 'module.exports = function weexFactory (exports, document) {'
|
||||
},
|
||||
outro() {
|
||||
return '}'
|
||||
}
|
||||
}
|
||||
|
||||
const aliases = require('./alias')
|
||||
const resolve = (p) => {
|
||||
const base = p.split('/')[0]
|
||||
|
@ -199,31 +187,6 @@ const builds = {
|
|||
external: Object.keys(
|
||||
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
|
||||
const vars = {
|
||||
__WEEX__: !!opts.weex,
|
||||
__WEEX_VERSION__: weexVersion,
|
||||
__VERSION__: version,
|
||||
__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 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
|
||||
const keyCodes: { [key: string]: number | Array<number> } = {
|
||||
|
@ -13,7 +13,7 @@ const keyCodes: { [key: string]: number | Array<number> } = {
|
|||
left: 37,
|
||||
right: 39,
|
||||
down: 40,
|
||||
delete: [8, 46],
|
||||
delete: [8, 46]
|
||||
}
|
||||
|
||||
// KeyboardEvent.key aliases
|
||||
|
@ -30,7 +30,7 @@ const keyNames: { [key: string]: string | Array<string> } = {
|
|||
right: ['Right', 'ArrowRight'],
|
||||
down: ['Down', 'ArrowDown'],
|
||||
// #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
|
||||
|
@ -48,7 +48,7 @@ const modifierCode: { [key: string]: string } = {
|
|||
meta: genGuard(`!$event.metaKey`),
|
||||
left: genGuard(`'button' in $event && $event.button !== 0`),
|
||||
middle: genGuard(`'button' in $event && $event.button !== 1`),
|
||||
right: genGuard(`'button' in $event && $event.button !== 2`),
|
||||
right: genGuard(`'button' in $event && $event.button !== 2`)
|
||||
}
|
||||
|
||||
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(
|
||||
handler: ASTElementHandler | Array<ASTElementHandler>
|
||||
): string {
|
||||
|
@ -118,10 +96,6 @@ function genHandler(
|
|||
if (isMethodPath || isFunctionExpression) {
|
||||
return handler.value
|
||||
}
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && handler.params) {
|
||||
return genWeexHandler(handler.params, handler.value)
|
||||
}
|
||||
return `function($event){${
|
||||
isFunctionInvocation ? `return ${handler.value}` : handler.value
|
||||
}}` // inline statement
|
||||
|
@ -162,10 +136,6 @@ function genHandler(
|
|||
: isFunctionInvocation
|
||||
? `return ${handler.value}`
|
||||
: handler.value
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && handler.params) {
|
||||
return genWeexHandler(handler.params, code + handlerCode)
|
||||
}
|
||||
return `function($event){${code}${handlerCode}}`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { genHandlers } from './events'
|
||||
import baseDirectives from '../directives/index'
|
||||
import { camelize, no, extend } from 'shared/util'
|
||||
|
@ -58,7 +57,7 @@ export function generate(
|
|||
: '_c("div")'
|
||||
return {
|
||||
render: `with(this){return ${code}}`,
|
||||
staticRenderFns: state.staticRenderFns,
|
||||
staticRenderFns: state.staticRenderFns
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,13 +560,16 @@ function genSlot(el: ASTElement, state: CodegenState): string {
|
|||
const slotName = el.slotName || '"default"'
|
||||
const children = genChildren(el, state)
|
||||
let res = `_t(${slotName}${children ? `,function(){return ${children}}` : ''}`
|
||||
const attrs = el.attrs || el.dynamicAttrs
|
||||
? genProps((el.attrs || []).concat(el.dynamicAttrs || []).map(attr => ({
|
||||
const attrs =
|
||||
el.attrs || el.dynamicAttrs
|
||||
? genProps(
|
||||
(el.attrs || []).concat(el.dynamicAttrs || []).map((attr) => ({
|
||||
// slot props are camelized
|
||||
name: camelize(attr.name),
|
||||
value: attr.value,
|
||||
dynamic: attr.dynamic
|
||||
})))
|
||||
}))
|
||||
)
|
||||
: null
|
||||
const bind = el.attrsMap['v-bind']
|
||||
if ((attrs || bind) && !children) {
|
||||
|
@ -599,9 +601,7 @@ function genProps(props: Array<ASTAttr>): string {
|
|||
let dynamicProps = ``
|
||||
for (let i = 0; i < props.length; i++) {
|
||||
const prop = props[i]
|
||||
const value = __WEEX__
|
||||
? generateValue(prop.value)
|
||||
: transformSpecialNewlines(prop.value)
|
||||
const value = transformSpecialNewlines(prop.value)
|
||||
if (prop.dynamic) {
|
||||
dynamicProps += `${prop.name},${value},`
|
||||
} 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
|
||||
function transformSpecialNewlines(text: string): string {
|
||||
return text.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
|
||||
// can we use __proto__?
|
||||
export const hasProto = '__proto__' in {}
|
||||
|
||||
// Browser environment sniffing
|
||||
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 isIE = UA && /msie|trident/.test(UA)
|
||||
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
|
||||
export const isEdge = UA && UA.indexOf('edge/') > 0
|
||||
export const isAndroid =
|
||||
(UA && UA.indexOf('android') > 0) || weexPlatform === 'android'
|
||||
export const isIOS =
|
||||
(UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform === 'ios'
|
||||
export const isAndroid = UA && UA.indexOf('android') > 0
|
||||
export const isIOS = UA && /iphone|ipad|ipod|ios/.test(UA)
|
||||
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
|
||||
export const isPhantomJS = UA && /phantomjs/.test(UA)
|
||||
export const isFF = UA && UA.match(/firefox\/(\d+)/)
|
||||
|
@ -30,7 +25,7 @@ if (inBrowser) {
|
|||
get() {
|
||||
/* istanbul ignore next */
|
||||
supportsPassive = true
|
||||
},
|
||||
}
|
||||
} as object) // https://github.com/facebook/flow/issues/285
|
||||
window.addEventListener('test-passive', null as any, opts)
|
||||
} catch (e: any) {}
|
||||
|
@ -42,7 +37,7 @@ let _isServer
|
|||
export const isServerRendering = () => {
|
||||
if (_isServer === undefined) {
|
||||
/* istanbul ignore if */
|
||||
if (!inBrowser && !inWeex && typeof global !== 'undefined') {
|
||||
if (!inBrowser && typeof global !== 'undefined') {
|
||||
// detect presence of vue-server-renderer and avoid
|
||||
// Webpack shimming the process
|
||||
_isServer =
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { warn } from './debug'
|
||||
import { observe, toggleObserving, shouldObserve } from '../observer/index'
|
||||
import {
|
||||
|
@ -7,7 +6,7 @@ import {
|
|||
toRawType,
|
||||
hyphenate,
|
||||
capitalize,
|
||||
isPlainObject,
|
||||
isPlainObject
|
||||
} from 'shared/util'
|
||||
import type { Component } from 'typescript/component'
|
||||
|
||||
|
@ -51,11 +50,7 @@ export function validateProp(
|
|||
observe(value)
|
||||
toggleObserving(prevShouldObserve)
|
||||
}
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
// skip validation for weex recycle-list child component props
|
||||
!(__WEEX__ && isObject(value) && '@binding' in value)
|
||||
) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assertProp(prop, key, value, vm, absent)
|
||||
}
|
||||
return value
|
||||
|
@ -182,7 +177,7 @@ function assertType(
|
|||
}
|
||||
return {
|
||||
valid,
|
||||
expectedType,
|
||||
expectedType
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,10 +20,6 @@ import {
|
|||
deactivateChildComponent,
|
||||
} from '../instance/lifecycle'
|
||||
|
||||
import {
|
||||
isRecyclableComponent,
|
||||
renderRecyclableComponentTemplate,
|
||||
} from 'weex/runtime/recycle-list/render-component-template'
|
||||
import type {
|
||||
MountedComponentVNode,
|
||||
VNodeData,
|
||||
|
@ -206,14 +202,6 @@ export function createComponent(
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import config from '../config'
|
||||
import VNode, { createEmptyVNode } from './vnode'
|
||||
import { createComponent } from './create-component'
|
||||
|
@ -11,7 +10,7 @@ import {
|
|||
isTrue,
|
||||
isObject,
|
||||
isPrimitive,
|
||||
resolveAsset,
|
||||
resolveAsset
|
||||
} from '../util/index'
|
||||
|
||||
import { normalizeChildren, simpleNormalizeChildren } from './helpers/index'
|
||||
|
@ -74,15 +73,12 @@ export function _createElement(
|
|||
isDef(data.key) &&
|
||||
!isPrimitive(data.key)
|
||||
) {
|
||||
// @ts-expect-error
|
||||
if (!__WEEX__ || !('@binding' in data.key)) {
|
||||
warn(
|
||||
'Avoid using non-primitive value as key, ' +
|
||||
'use string/number value instead.',
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
// support single function children as default scoped slot
|
||||
if (Array.isArray(children) && typeof children[0] === 'function') {
|
||||
data = data || {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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'
|
||||
|
||||
const normalizeEvent = cached((name: string): {
|
||||
|
@ -69,11 +69,6 @@ export function updateListeners(
|
|||
def = cur = on[name]
|
||||
old = oldOn[name]
|
||||
event = normalizeEvent(name)
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__ && isPlainObject(def)) {
|
||||
cur = def.handler
|
||||
event.params = def.params
|
||||
}
|
||||
if (isUndef(cur)) {
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
warn(
|
||||
|
|
|
@ -170,32 +170,11 @@ export function createPatchFunction(backend) {
|
|||
: nodeOps.createElement(tag, vnode)
|
||||
setScope(vnode)
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (__WEEX__) {
|
||||
// in Weex, the default insertion order is parent-first.
|
||||
// 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)
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production' && data && data.pre) {
|
||||
creatingElmInVPre--
|
||||
|
|
|
@ -1,32 +1,9 @@
|
|||
declare const __WEEX__: 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 {
|
||||
__VUE_DEVTOOLS_GLOBAL_HOOK__: DevtoolsHook;
|
||||
}
|
||||
|
||||
|
||||
// from https://github.com/vuejs/vue-devtools/blob/bc719c95a744614f5c3693460b64dc21dfa339a8/packages/app-backend-api/src/global-hook.ts#L3
|
||||
interface DevtoolsHook {
|
||||
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
|
||||
|
||||
process.env.NEW_SLOT_SYNTAX = 'true'
|
||||
|
||||
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