diff --git a/examples/README.md b/examples/README.md
index 38a79edf2c..061970438c 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -25,4 +25,4 @@ npm run build
* app-lifecycle: 使用 app 生命周期
* page-lifecycle-with-router: 使用 page 生命周期 + 路由跳转
* event-handler: 事件绑定(编译时小程序)
-
+* get-element: document/element getElementXXX 相关 API
diff --git a/examples/get-element/.eslintrc.js b/examples/get-element/.eslintrc.js
new file mode 100644
index 0000000000..04f3c852d6
--- /dev/null
+++ b/examples/get-element/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ extends: ['rax']
+};
\ No newline at end of file
diff --git a/examples/get-element/.gitignore b/examples/get-element/.gitignore
new file mode 100644
index 0000000000..50a53daceb
--- /dev/null
+++ b/examples/get-element/.gitignore
@@ -0,0 +1,17 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+*~
+*.swp
+*.log
+
+.DS_Store
+.idea/
+.temp/
+
+build/
+dist/
+lib/
+coverage/
+node_modules/
+
+template.yml
diff --git a/examples/get-element/README.md b/examples/get-element/README.md
new file mode 100644
index 0000000000..94c45d1ddc
--- /dev/null
+++ b/examples/get-element/README.md
@@ -0,0 +1,15 @@
+# rax-materials-basic-app
+
+## Getting Started
+
+### `npm run start`
+
+Runs the app in development mode.
+
+Open [http://localhost:9999](http://localhost:9999) to view it in the browser.
+
+The page will reload if you make edits.
+
+### `npm run build`
+
+Builds the app for production to the `build` folder.
diff --git a/examples/get-element/abc.json b/examples/get-element/abc.json
new file mode 100644
index 0000000000..f9ee40f714
--- /dev/null
+++ b/examples/get-element/abc.json
@@ -0,0 +1,7 @@
+{
+ "type": "rax",
+ "builder": "@ali/builder-rax-v1",
+ "info": {
+ "raxVersion": "1.x"
+ }
+}
diff --git a/examples/get-element/build.json b/examples/get-element/build.json
new file mode 100644
index 0000000000..01a37c18e1
--- /dev/null
+++ b/examples/get-element/build.json
@@ -0,0 +1,20 @@
+{
+ "inlineStyle": false,
+ "plugins": [
+ [
+ "build-plugin-rax-app",
+ {
+ "targets": [
+ "miniapp",
+ "wechat-miniprogram"
+ ],
+ "miniapp": {
+ "buildType": "runtime"
+ },
+ "wechat-miniprogram": {
+ "buildType": "runtime"
+ }
+ }
+ ]
+ ]
+}
diff --git a/examples/get-element/package.json b/examples/get-element/package.json
new file mode 100644
index 0000000000..7d0a89bc64
--- /dev/null
+++ b/examples/get-element/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "@rax-materials/scaffolds-app-js",
+ "author": "rax",
+ "description": "Rax 无线跨端应用工程,使用 JavaScript。",
+ "version": "0.1.0",
+ "scripts": {
+ "build": "build-scripts build",
+ "start": "build-scripts start",
+ "lint": "eslint --ext .js --ext .jsx ./"
+ },
+ "dependencies": {
+ "rax": "^1.1.0",
+ "rax-app": "^2.0.0",
+ "driver-universal": "^3.0.0",
+ "rax-image": "^2.0.0",
+ "rax-link": "^1.0.1",
+ "rax-text": "^1.0.0",
+ "rax-view": "^1.0.0",
+ "rax-document": "^0.1.0"
+ },
+ "devDependencies": {
+ "@alib/build-scripts": "^0.1.0",
+ "babel-eslint": "^10.0.3",
+ "build-plugin-rax-app": "^5.0.0",
+ "eslint": "^6.8.0",
+ "eslint-config-rax": "^0.1.0",
+ "eslint-plugin-import": "^2.20.0",
+ "eslint-plugin-module": "^0.1.0",
+ "eslint-plugin-react": "^7.18.0"
+ },
+ "private": true,
+ "originTemplate": "@rax-materials/scaffolds-app-js"
+}
diff --git a/examples/get-element/src/app.js b/examples/get-element/src/app.js
new file mode 100644
index 0000000000..d78985c28d
--- /dev/null
+++ b/examples/get-element/src/app.js
@@ -0,0 +1,28 @@
+import { runApp, useAppLaunch, useAppShow, useAppHide, useAppShare, useAppError } from 'rax-app';
+import appConfig from './app.json';
+
+useAppLaunch((options) => {
+ console.log('app launch', options);
+});
+
+useAppShow((options) => {
+ console.log('app show', options);
+});
+
+useAppHide(() => {
+ console.log('app hide');
+});
+
+useAppShare(() => {
+ return {
+ title: '分享标题',
+ desc: '分享详细说明',
+ path: 'pages/Home/index'
+ };
+});
+
+useAppError(() => {
+ console.log('app error');
+});
+
+runApp(appConfig);
diff --git a/examples/get-element/src/app.json b/examples/get-element/src/app.json
new file mode 100644
index 0000000000..ffbc0add84
--- /dev/null
+++ b/examples/get-element/src/app.json
@@ -0,0 +1,11 @@
+{
+ "routes": [
+ {
+ "path": "/",
+ "source": "pages/Home/index"
+ }
+ ],
+ "window": {
+ "title": "Rax App"
+ }
+}
diff --git a/examples/get-element/src/components/Logo/index.css b/examples/get-element/src/components/Logo/index.css
new file mode 100644
index 0000000000..2f8d8d1144
--- /dev/null
+++ b/examples/get-element/src/components/Logo/index.css
@@ -0,0 +1,5 @@
+.logo {
+ width: 200rpx;
+ height: 180rpx;
+ margin-bottom: 20rpx;
+}
\ No newline at end of file
diff --git a/examples/get-element/src/components/Logo/index.jsx b/examples/get-element/src/components/Logo/index.jsx
new file mode 100644
index 0000000000..ef191bc442
--- /dev/null
+++ b/examples/get-element/src/components/Logo/index.jsx
@@ -0,0 +1,15 @@
+import { createElement } from 'rax';
+import Image from 'rax-image';
+
+import './index.css';
+
+export default (props) => {
+ const { uri } = props;
+ const source = { uri };
+ return (
+
+ );
+};
diff --git a/examples/get-element/src/document/index.jsx b/examples/get-element/src/document/index.jsx
new file mode 100644
index 0000000000..ae0b8d0cdb
--- /dev/null
+++ b/examples/get-element/src/document/index.jsx
@@ -0,0 +1,21 @@
+import { createElement } from 'rax';
+import { Root, Style, Script} from 'rax-document';
+
+function Document() {
+ return (
+
+
+
+
+ rax-materials-basic-app
+
+
+
+ {/* root container */}
+
+
+
+
+ );
+}
+export default Document;
diff --git a/examples/get-element/src/pages/Home/index.css b/examples/get-element/src/pages/Home/index.css
new file mode 100644
index 0000000000..cd3b101696
--- /dev/null
+++ b/examples/get-element/src/pages/Home/index.css
@@ -0,0 +1,16 @@
+.home {
+ align-items: center;
+ margin-top: 200rpx;
+}
+
+.title {
+ font-size: 45rpx;
+ font-weight: bold;
+ margin: 20rpx 0;
+}
+
+.info {
+ font-size: 36rpx;
+ margin: 8rpx 0;
+ color: #555;
+}
diff --git a/examples/get-element/src/pages/Home/index.jsx b/examples/get-element/src/pages/Home/index.jsx
new file mode 100644
index 0000000000..afed11a751
--- /dev/null
+++ b/examples/get-element/src/pages/Home/index.jsx
@@ -0,0 +1,61 @@
+import { createElement, useEffect } from 'rax';
+import View from 'rax-view';
+import Text from 'rax-text';
+
+import './index.css';
+
+import Logo from '../../components/Logo';
+
+export default function Home() {
+ useEffect(() => {
+ const father1 = document.getElementById('father');
+ const father2 = document.querySelector('#father');
+ const father3 = document.querySelectorAll('#father');
+
+ console.log('Home -> father1', father1);
+ console.log('Home -> father2', father2);
+ console.log('Home -> father3', father3);
+
+ const home1 = document.getElementsByClassName('home');
+ const home2 = document.querySelector('.home');
+ const home3 = document.querySelectorAll('.home');
+ console.log('Home -> home1', home1);
+ console.log('Home -> home2', home2);
+ console.log('Home -> home3', home3);
+
+ const div1 = document.getElementsByTagName('div');
+ const div2 = document.querySelector('div');
+ const div3 = document.querySelectorAll('div');
+ console.log('Home -> div1', div1);
+ console.log('Home -> div2', div2);
+ console.log('Home -> div3', div3);
+
+ const child = document.getElementById('child1');
+ const subDiv1 = child.getElementsByTagName('div');
+ const subDiv2 = child.querySelector('div');
+ const subDiv3 = child.querySelectorAll('div');
+ console.log('Home -> subDiv1', subDiv1);
+ console.log('Home -> subDiv2', subDiv2);
+ console.log('Home -> subDiv3', subDiv3);
+
+ const red1 = child.getElementsByClassName('red');
+ const red2 = child.querySelector('.red');
+ const red3 = child.querySelectorAll('.red');
+ console.log('Home -> red1', red1);
+ console.log('Home -> red2', red2);
+ console.log('Home -> red3', red3);
+ });
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/examples/with-miniapp-native-custom-component/src/public/WechatNativeComp/index.js b/examples/with-miniapp-native-custom-component/src/public/WechatNativeComp/index.js
index 618b97d871..f5d878880f 100644
--- a/examples/with-miniapp-native-custom-component/src/public/WechatNativeComp/index.js
+++ b/examples/with-miniapp-native-custom-component/src/public/WechatNativeComp/index.js
@@ -1,4 +1,7 @@
Component({
+ options: {
+ multipleSlots: true
+ },
methods: {
onClick() {
this.triggerEvent('click');
diff --git a/examples/with-miniapp-plugin-component/project.config.json b/examples/with-miniapp-plugin-component/project.config.json
index bfbad8a731..34fa0576b1 100644
--- a/examples/with-miniapp-plugin-component/project.config.json
+++ b/examples/with-miniapp-plugin-component/project.config.json
@@ -2,7 +2,33 @@
"miniprogramRoot": "build/wechat-miniprogram/",
"pluginRoot": "wechat-miniprogram-plugin/",
"compileType": "plugin",
- "setting": {},
+ "setting": {
+ "urlCheck": true,
+ "es6": true,
+ "enhance": false,
+ "postcss": true,
+ "preloadBackgroundData": false,
+ "minified": true,
+ "newFeature": false,
+ "coverView": true,
+ "nodeModules": false,
+ "autoAudits": false,
+ "showShadowRootInWxmlPanel": true,
+ "scopeDataCheck": false,
+ "uglifyFileName": false,
+ "checkInvalidKey": true,
+ "checkSiteMap": true,
+ "uploadWithSourceMap": true,
+ "compileHotReLoad": false,
+ "babelSetting": {
+ "ignore": [],
+ "disablePlugins": [],
+ "outputPath": ""
+ },
+ "useIsolateContext": true,
+ "useCompilerModule": true,
+ "userConfirmedUseCompilerModuleSwitch": false
+ },
"appid": "wxc0575284fd6f4091",
"projectname": "with-miniapp-plugin-component",
"simulatorType": "wechat",
diff --git a/packages/driver-miniapp/package.json b/packages/driver-miniapp/package.json
index 179048336e..db34a8d81f 100644
--- a/packages/driver-miniapp/package.json
+++ b/packages/driver-miniapp/package.json
@@ -1,6 +1,6 @@
{
"name": "driver-miniapp",
- "version": "0.1.2",
+ "version": "0.1.3",
"description": "MiniApp (runtime) driver for Rax",
"license": "BSD-3-Clause",
"main": "lib/index.js",
diff --git a/packages/driver-miniapp/src/index.js b/packages/driver-miniapp/src/index.js
index bf9ccb878a..108a74a4e9 100644
--- a/packages/driver-miniapp/src/index.js
+++ b/packages/driver-miniapp/src/index.js
@@ -1,11 +1,81 @@
import * as DriverDOM from 'driver-dom';
+function cached(fn) {
+ const cache = Object.create(null);
+ return function cachedFn(str) {
+ return cache[str] || (cache[str] = fn(str));
+ };
+}
+
+const EVENT_PREFIX_REG = /^on[A-Z]/;
+const NON_DIMENSIONAL_REG = /opa|ntw|ne[ch]|ex(?:s|g|n|p|$)|^ord|zoo|grid|orp|ows|mnc|^columns$|bs|erim|onit/i;
+const isDimensionalProp = cached(prop => !NON_DIMENSIONAL_REG.test(prop));
+
+const setStyle = (node, style) => {
+ for (let prop in style) {
+ const value = style[prop];
+ let convertedValue;
+ if (typeof value === 'number' && isDimensionalProp(prop)) {
+ convertedValue = value + 'rpx';
+ } else {
+ convertedValue = value;
+ }
+ // Support CSS custom properties (variables) like { --main-color: "black" }
+ if (prop[0] === '-' && prop[1] === '-') {
+ // reference: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty.
+ // style.setProperty do not support Camel-Case style properties.
+ node.style.setProperty(prop, convertedValue);
+ } else {
+ node.style[prop] = convertedValue;
+ }
+ }
+};
+
+const isEventProp = cached(prop => EVENT_PREFIX_REG.test(prop));
+
// Convert Unitless To Rpx defaultly
export default Object.assign({}, DriverDOM, {
- createElement(type, props, component) {
- return DriverDOM.createElement(type, props, component, true, false);
+ createElement(type, props) {
+ let style;
+ let attrs = {};
+ let events = [];
+
+ for (let prop in props) {
+ const value = props[prop];
+ if (prop === 'children') continue;
+
+ if (value != null) {
+ if (prop === 'style') {
+ style = value;
+ } else if (isEventProp(prop)) {
+ events.push({
+ name: prop.slice(2).toLowerCase(),
+ handler: value
+ });
+ } else {
+ if (prop === 'className') {
+ prop = 'class';
+ }
+ attrs[prop] = value;
+ }
+ }
+ }
+
+ const node = document._createElement({
+ tagName: type,
+ document,
+ attrs
+ });
+
+ if (style) {
+ setStyle(node, style);
+ }
+
+ events.forEach(({name, handler}) => {
+ node.addEventListener(name, handler);
+ });
+
+ return node;
},
- setStyle(node, style) {
- return DriverDOM.setStyle(node, style, true, false);
- }
+ setStyle
});
diff --git a/packages/miniapp-render/__tests__/document.test.js b/packages/miniapp-render/__tests__/document.test.js
index 77e25a160b..37c1640e5e 100644
--- a/packages/miniapp-render/__tests__/document.test.js
+++ b/packages/miniapp-render/__tests__/document.test.js
@@ -15,7 +15,7 @@ test('document: nodeType', () => {
});
test('document: documentElement', () => {
- expect(document.documentElement.tagName).toBe('HTML');
+ expect(document.documentElement.tagName).toBe('BODY'); // Hack in miniapp, not be consistent with W3C
expect(document.documentElement.parentNode).toBe(document);
});
@@ -27,10 +27,6 @@ test('document: nodeName', () => {
expect(document.nodeName).toBe('#document');
});
-test('document: head', () => {
- expect(document.head.tagName).toBe('HEAD');
-});
-
test('document: defaultView', () => {
expect(document.defaultView).toBe(window);
});
@@ -67,22 +63,19 @@ test('document: querySelector', () => {
const node1 = document.querySelector('#bb');
expect(node1.tagName).toBe('DIV');
expect(node1.id).toBe('bb');
-
- const node2 = document.querySelector('#bb .bb4');
+ const node2 = document.querySelector('.bb4');
expect(node2.tagName).toBe('SPAN');
expect(node2.id).toBe('bb4');
-
expect(document.querySelector('#aa')).toBe(null);
});
test('document: querySelectorAll', () => {
- const nodes = document.querySelectorAll('#bb .bb4');
+ const nodes = document.querySelectorAll('.bb4');
expect(nodes.length).toBe(3);
expect(nodes[0].tagName).toBe('SPAN');
expect(nodes[0].id).toBe('bb4');
expect(nodes[1].tagName).toBe('SPAN');
expect(nodes[2].tagName).toBe('SPAN');
-
expect(document.querySelectorAll('#aa').length).toBe(0);
});
diff --git a/packages/miniapp-render/__tests__/node/class-list.test.js b/packages/miniapp-render/__tests__/node/class-list.test.js
index 0e6bd187cc..bc6b92dcd4 100644
--- a/packages/miniapp-render/__tests__/node/class-list.test.js
+++ b/packages/miniapp-render/__tests__/node/class-list.test.js
@@ -1,4 +1,5 @@
import mock from '../../renderMock';
+import ClassList from '../../src/node/class-list';
let document;
@@ -9,8 +10,8 @@ beforeAll(() => {
test('class-list', () => {
const element = document.createElement('div');
+ element.setAttribute('class', 'a b c');
const classList = element.classList;
- classList.$$parse('a b c');
// item
expect(classList.item(0)).toBe('a');
@@ -53,7 +54,4 @@ test('class-list', () => {
// toString
expect(classList.toString()).toBe('a d c');
-
- classList.$$parse('c b a dd');
- expect(classList.toString()).toBe('c b a dd');
});
diff --git a/packages/miniapp-render/__tests__/node/comment.test.js b/packages/miniapp-render/__tests__/node/comment.test.js
index 790f29fbf9..658d5979d1 100644
--- a/packages/miniapp-render/__tests__/node/comment.test.js
+++ b/packages/miniapp-render/__tests__/node/comment.test.js
@@ -18,7 +18,7 @@ test('comment: cloneNode', () => {
const node1 = document.createComment('abc cba');
const node2 = node1.cloneNode();
expect(node2).not.toBe(node1);
- expect(node2.$$nodeId).not.toBe(node1.$$nodeId);
+ expect(node2.__nodeId).not.toBe(node1.__nodeId);
expect(node2.__pageId).toBe(node1.__pageId);
expect(node2.nodeType).toBe(Node.COMMENT_NODE);
});
diff --git a/packages/miniapp-render/__tests__/node/element.test.js b/packages/miniapp-render/__tests__/node/element.test.js
index 371593b243..f269053187 100644
--- a/packages/miniapp-render/__tests__/node/element.test.js
+++ b/packages/miniapp-render/__tests__/node/element.test.js
@@ -30,12 +30,12 @@ test('element: id/tagName', () => {
test('element: className/classList', () => {
const node1 = document.querySelector('#bb');
expect(node1.className).toBe('bb');
- expect(node1.classList).toBeInstanceOf(Array);
+ expect(node1.classList).toBeInstanceOf(Set);
const node2 = document.querySelector('header');
expect(node2.tagName).toBe('HEADER');
expect(node2.className).toBe('');
- expect(node2.classList).toBeInstanceOf(Array);
+ expect(node2.classList).toBeInstanceOf(Set);
node2.className = 'header1 header2';
expect(node2.className).toBe('header1 header2');
@@ -72,7 +72,7 @@ test('element: nodeName/nodeType', () => {
expect(parent.nodeName).toBe('HEADER');
expect(document.nodeName).toBe('#document');
expect(node.childNodes[0].nodeName).toBe('#text');
- expect(document.documentElement.nodeName).toBe('HTML');
+ expect(document.documentElement.nodeName).toBe('BODY'); // Hack in miniapp, not be consistent with W3C
});
test('element: childNodes/children/firstChild/lastChild', () => {
@@ -122,72 +122,20 @@ test('element: innerHTML/outerHTML', () => {
node3.style.left = '20px';
expect(node1.tagName).toBe('ARTICLE');
expect(node1.id).toBe('outer');
- expect(node1.innerHTML).toBe('123555321
');
- expect(node1.outerHTML).toBe('123555321
');
-
- node1.innerHTML = '321765123
555
I am content
';
- expect(node1.childNodes.length).toBe(3);
- expect(node1.childNodes[0].id).toBe('a');
- expect(node1.childNodes[0].childNodes.length).toBe(3);
- expect(node1.childNodes[0].childNodes[0].textContent).toBe('321');
- expect(node1.childNodes[0].childNodes[1].id).toBe('inner');
- expect(node1.childNodes[0].childNodes[1].tagName).toBe('SPAN');
- expect(node1.childNodes[0].childNodes[1].childNodes.length).toBe(1);
- expect(node1.childNodes[0].childNodes[1].childNodes[0].textContent).toBe('765');
- expect(node1.childNodes[0].childNodes[2].textContent).toBe('123');
- expect(node1.childNodes[1].id).toBe('c');
- expect(node1.childNodes[1].childNodes.length).toBe(1);
- expect(node1.childNodes[1].childNodes[0].textContent).toBe('555');
- expect(node1.childNodes[2].tagName).toBe('P');
- expect(node1.childNodes[2].style.color).toBe('green');
- expect(node1.childNodes[2].style.textAlign).toBe('center');
- expect(node1.childNodes[2].childNodes.length).toBe(1);
- expect(node1.childNodes[2].childNodes[0].textContent).toBe('I am content');
-
- node1.outerHTML = '';
- expect(node1.tagName).toBe('HEADER');
- expect(node1.id).toBe('outer2');
- expect(node1.childNodes.length).toBe(3);
- expect(node1.childNodes[0].id).toBe('a');
- expect(node1.childNodes[0].childNodes.length).toBe(3);
- expect(node1.childNodes[0].childNodes[0].textContent).toBe('321');
- expect(node1.childNodes[0].childNodes[1].id).toBe('inner');
- expect(node1.childNodes[0].childNodes[1].tagName).toBe('SPAN');
- expect(node1.childNodes[0].childNodes[1].childNodes.length).toBe(1);
- expect(node1.childNodes[0].childNodes[1].childNodes[0].textContent).toBe('765');
- expect(node1.childNodes[0].childNodes[2].textContent).toBe('123');
- expect(node1.childNodes[1].id).toBe('c');
- expect(node1.childNodes[1].childNodes.length).toBe(1);
- expect(node1.childNodes[1].childNodes[0].textContent).toBe('555');
- expect(node1.childNodes[2].tagName).toBe('P');
- expect(node1.childNodes[2].style.color).toBe('green');
- expect(node1.childNodes[2].style.textAlign).toBe('center');
- expect(node1.childNodes[2].childNodes.length).toBe(1);
- expect(node1.childNodes[2].childNodes[0].textContent).toBe('I am content');
document.body.removeChild(node1);
});
test('element: innerText/textContent', () => {
const node1 = document.createElement('div');
- node1.innerHTML = 'ak';
- document.body.appendChild(node1);
-
- expect(node1.innerText).toBe('abcdefghijk');
- expect(node1.textContent).toBe('abcdefghijk');
-
node1.innerText = '123
';
expect(node1.childNodes.length).toBe(1);
- expect(node1.innerHTML).toBe('123
');
expect(node1.textContent).toBe('123
');
node1.textContent = '321';
expect(node1.childNodes.length).toBe(1);
- expect(node1.innerHTML).toBe('321');
expect(node1.innerText).toBe('321');
- node1.innerHTML = '321';
- expect(node1.childNodes.length).toBe(1);
node1.textContent = '';
expect(node1.childNodes.length).toBe(0);
@@ -196,50 +144,43 @@ test('element: innerText/textContent', () => {
test('element: dataset', () => {
const node1 = document.createElement('div');
- node1.innerHTML = '';
+ const child = document.createElement('div');
+ child.setAttribute('data-a', 'abc');
+ child.setAttribute('data-bc-d-efg', 'efg');
+ child.setAttribute('data-hi-j', '123');
+ node1.appendChild(child);
const node2 = node1.childNodes[0];
- expect(node2.dataset).toEqual({
- a: 'abc',
- bcDEfg: 'efg',
- hiJ: '123',
- });
+ expect(node2.dataset.a).toEqual('abc');
+ expect(node2.dataset.bcDEfg).toEqual('efg');
+ expect(node2.dataset.hiJ).toEqual('123');
node2.dataset.bcDEfg = 'hij';
node2.dataset.kLmNOpQr = 'klm';
- expect(node2.dataset).toEqual({
- a: 'abc',
- bcDEfg: 'hij',
- hiJ: '123',
- kLmNOpQr: 'klm'
- });
- expect(node1.innerHTML).toEqual('');
- expect(node2.outerHTML).toEqual('');
+ expect(node2.dataset.a).toEqual('abc');
+ expect(node2.dataset.bcDEfg).toEqual('hij');
+ expect(node2.dataset.hiJ).toEqual('123');
+ expect(node2.dataset.kLmNOpQr).toEqual('klm');
const node3 = node2.cloneNode();
node3.dataset.hiJ = '321';
- expect(node3.dataset).toEqual({
- a: 'abc',
- bcDEfg: 'hij',
- hiJ: '321',
- kLmNOpQr: 'klm'
- });
- expect(node3.outerHTML).toEqual('');
+ expect(node3.dataset.a).toEqual('abc');
+ expect(node3.dataset.bcDEfg).toEqual('hij');
+ expect(node3.dataset.hiJ).toEqual('321');
+ expect(node3.dataset.kLmNOpQr).toEqual('klm');
const node4 = document.createElement('div');
node4.setAttribute('data-a', 'abc');
node4.setAttribute('data-bc-d-efg', 'hij');
node4.setAttribute('data-hi-j', '321');
node4.setAttribute('data-k-lm-n-op-qr', 'klm');
- expect(node4.dataset).toEqual({
- a: 'abc',
- bcDEfg: 'hij',
- hiJ: '321',
- kLmNOpQr: 'klm'
- });
- expect(node4.outerHTML).toEqual('');
+ expect(node4.dataset.a).toEqual('abc');
+ expect(node4.dataset.bcDEfg).toEqual('hij');
+ expect(node4.dataset.hiJ).toEqual('321');
+ expect(node4.dataset.kLmNOpQr).toEqual('klm');
+
node4.dataset.bcDEfg = 'haha';
expect(node4.getAttribute('data-bc-d-efg')).toBe('haha');
expect(node4.hasAttribute('data-bc-d-efg')).toBe(true);
@@ -249,14 +190,10 @@ test('element: dataset', () => {
expect(node4.hasAttribute('data-bc-d-efg')).toBe(false);
});
-test('element: attributes', () => {
- const node = document.createElement('div');
- expect(node.attributes).toBeInstanceOf(Array);
-});
test('element: src', () => {
const node = document.createElement('div');
- expect(node.src).toBe('');
+ expect(node.src).toBe(undefined);
node.src = 'https://aa.bb.cc';
expect(node.src).toBe('https://aa.bb.cc');
@@ -285,7 +222,7 @@ test('element: cloneNode', () => {
const node7 = node1.cloneNode();
expect(node7).not.toBe(node1);
- expect(node7.$$nodeId).not.toBe(node1.$$nodeId);
+ expect(node7.__nodeId).not.toBe(node1.__nodeId);
expect(node7.__pageId).toBe(node1.__pageId);
expect(node7.id).toBe(node1.id);
expect(node7.className).toBe(node1.className);
@@ -294,7 +231,7 @@ test('element: cloneNode', () => {
const node8 = node1.cloneNode(true);
expect(node8).not.toBe(node1);
- expect(node7.$$nodeId).not.toBe(node1.$$nodeId);
+ expect(node7.__nodeId).not.toBe(node1.__nodeId);
expect(node7.__pageId).toBe(node1.__pageId);
expect(node8.id).toBe(node1.id);
expect(node8.className).toBe(node1.className);
@@ -367,39 +304,22 @@ test('node: querySelector', () => {
expect(node2.tagName).toBe('DIV');
expect(node2.id).toBe('bb');
- const node3 = node1.querySelector('#bb .bb4');
- expect(node3.tagName).toBe('SPAN');
- expect(node3.id).toBe('bb4');
-
expect(node1.querySelector('#aa')).toBe(null);
});
-test('node: querySelectorAll', () => {
- const node = document.querySelector('.aa');
- const nodes = node.querySelectorAll('#bb .bb4');
- expect(nodes.length).toBe(3);
- expect(nodes[0].tagName).toBe('SPAN');
- expect(nodes[0].id).toBe('bb4');
- expect(nodes[1].tagName).toBe('SPAN');
- expect(nodes[2].tagName).toBe('SPAN');
-
- expect(node.querySelectorAll('#aa').length).toBe(0);
-});
-
test('element: setAttribute/getAttribute/hasAttribute/removeAttribute', () => {
const node = document.createElement('div');
document.body.appendChild(node);
const attributes = node.attributes;
- expect(node.getAttribute('id')).toBe('');
- expect(node.getAttribute('class')).toBe('');
- expect(node.getAttribute('style')).toBe('');
- expect(node.getAttribute('src')).toBe(undefined);
+ expect(node.getAttribute('id')).toBe(null);
+ expect(node.getAttribute('class')).toBe(null);
+ expect(node.getAttribute('style')).toBe(null);
+ expect(node.getAttribute('src')).toBe(null);
expect(node.hasAttribute('id')).toBe(false);
expect(node.hasAttribute('class')).toBe(false);
expect(node.hasAttribute('style')).toBe(false);
expect(node.hasAttribute('src')).toBe(false);
- expect(attributes).toEqual([]);
expect(attributes.id).toBe(undefined);
expect(attributes.class).toBe(undefined);
expect(attributes.style).toBe(undefined);
@@ -412,23 +332,18 @@ test('element: setAttribute/getAttribute/hasAttribute/removeAttribute', () => {
node.src = 'javascript: void(0);';
expect(node.getAttribute('id')).toBe('abc');
expect(node.getAttribute('class')).toBe('a b');
- expect(node.getAttribute('style')).toBe('display:block;');
+ expect(node.getAttribute('style')).toBe('display: block;');
// eslint-disable-next-line no-script-url
expect(node.getAttribute('src')).toBe('javascript: void(0);');
expect(node.hasAttribute('id')).toBe(true);
expect(node.hasAttribute('class')).toBe(true);
expect(node.hasAttribute('style')).toBe(true);
expect(node.hasAttribute('src')).toBe(true);
- expect(attributes.length).toBe(4);
- expect(attributes.id).toBe(attributes[1]);
- expect(attributes.id).toEqual({name: 'id', value: 'abc'});
- expect(attributes.class).toBe(attributes[2]);
- expect(attributes.class).toEqual({name: 'class', value: 'a b'});
- expect(attributes.style).toBe(attributes[3]);
- expect(attributes.style).toEqual({name: 'style', value: 'display:block;'});
- expect(attributes.src).toBe(attributes[0]);
+ expect(attributes.id).toEqual('abc');
+ expect(attributes.class).toEqual('a b');
+ expect(attributes.style).toEqual('display: block;');
// eslint-disable-next-line no-script-url
- expect(attributes.src).toEqual({name: 'src', value: 'javascript: void(0);'});
+ expect(attributes.src).toEqual('javascript: void(0);');
node.setAttribute('id', 'cba');
node.setAttribute('class', 'c b a');
@@ -436,21 +351,16 @@ test('element: setAttribute/getAttribute/hasAttribute/removeAttribute', () => {
node.setAttribute('src', 'moc.haha.www');
expect(node.id).toBe('cba');
expect(node.className).toBe('c b a');
- expect(node.style.cssText).toBe('display:inline;');
+ expect(node.style.cssText).toBe('display: inline;');
expect(node.src).toBe('moc.haha.www');
expect(node.hasAttribute('id')).toBe(true);
expect(node.hasAttribute('class')).toBe(true);
expect(node.hasAttribute('style')).toBe(true);
expect(node.hasAttribute('src')).toBe(true);
- expect(attributes.length).toEqual(4);
- expect(attributes.id).toBe(attributes[1]);
- expect(attributes.id).toEqual({name: 'id', value: 'cba'});
- expect(attributes.class).toBe(attributes[2]);
- expect(attributes.class).toEqual({name: 'class', value: 'c b a'});
- expect(attributes.style).toBe(attributes[3]);
- expect(attributes.style).toEqual({name: 'style', value: 'display:inline;'});
- expect(attributes.src).toBe(attributes[0]);
- expect(attributes.src).toEqual({name: 'src', value: 'moc.haha.www'});
+ expect(attributes.id).toEqual('cba');
+ expect(attributes.class).toEqual('c b a');
+ expect(attributes.style).toEqual('display: inline;');
+ expect(attributes.src).toEqual('moc.haha.www');
node.removeAttribute('id');
node.removeAttribute('class');
@@ -460,15 +370,14 @@ test('element: setAttribute/getAttribute/hasAttribute/removeAttribute', () => {
expect(node.className).toBe('');
expect(node.style.cssText).toBe('');
expect(node.src).toBe(undefined);
- expect(node.getAttribute('id')).toBe('');
- expect(node.getAttribute('class')).toBe('');
- expect(node.getAttribute('style')).toBe('');
- expect(node.getAttribute('src')).toBe(undefined);
+ expect(node.getAttribute('id')).toBe(null);
+ expect(node.getAttribute('class')).toBe(null);
+ expect(node.getAttribute('style')).toBe(null);
+ expect(node.getAttribute('src')).toBe(null);
expect(node.hasAttribute('id')).toBe(false);
expect(node.hasAttribute('class')).toBe(false);
expect(node.hasAttribute('style')).toBe(false);
expect(node.hasAttribute('src')).toBe(false);
- expect(attributes).toEqual([]);
expect(attributes.id).toBe(undefined);
expect(attributes.class).toBe(undefined);
expect(attributes.style).toBe(undefined);
@@ -478,11 +387,9 @@ test('element: setAttribute/getAttribute/hasAttribute/removeAttribute', () => {
const obj = {a: 123, b: {c: 321, d: [1, 2, 3]}};
node.setAttribute('object-attr', obj);
expect(node.getAttribute('object-attr')).toBe(obj);
- expect(attributes.length).toEqual(1);
const arr = [{a: obj}, 123, null, 'haha'];
node.setAttribute('array-attr', arr);
expect(node.getAttribute('array-attr')).toBe(arr);
- expect(attributes.length).toEqual(2);
document.body.removeChild(node);
});
diff --git a/packages/miniapp-render/__tests__/node/element/image.test.js b/packages/miniapp-render/__tests__/node/element/image.test.js
deleted file mode 100644
index 8e6d368137..0000000000
--- a/packages/miniapp-render/__tests__/node/element/image.test.js
+++ /dev/null
@@ -1,102 +0,0 @@
-import mock from '../../../renderMock';
-
-let window;
-
-beforeAll(() => {
- const res = mock.createPage('home');
- window = res.window;
-});
-
-test('image', async() => {
- global.expectSuccess = false;
- const Image = window.Image;
-
- // 带宽高
- const image1 = new Image(50, 60);
- let image1Count = 0;
- let expectImage1Count = 0;
- image1.onload = function() {
- expect(image1.width).toBe(50);
- expect(image1.height).toBe(60);
- expect(image1.naturalWidth).toBe(100);
- expect(image1.naturalHeight).toBe(88);
- expect(image1.src).toBe('https://c.b.a');
- expect(image1Count).toBe(expectImage1Count);
- };
- image1.onerror = function() {
- expect(image1.width).toBe(50);
- expect(image1.height).toBe(60);
- expect(image1.naturalWidth).toBe(0);
- expect(image1.naturalHeight).toBe(0);
- expect(image1.src).toBe('https://a.b.c');
- expect(image1Count).toBe(expectImage1Count);
- };
- expect(image1.width).toBe(50);
- expect(image1.height).toBe(60);
- expect(image1.naturalWidth).toBe(0);
- expect(image1.naturalHeight).toBe(0);
- expect(image1.src).toBe('');
- image1Count++;
- expectImage1Count = 1;
- image1.src = 'https://a.b.c';
- await mock.sleep(20);
- global.expectSuccess = true; // 下一次请求为成功
- image1Count++;
- expectImage1Count = 2;
- image1.src = 'https://c.b.a';
- await mock.sleep(20);
- image1Count++;
- expectImage1Count = 3;
- image1.src = 'https://c.b.a';
- await mock.sleep(20);
-
- // 不带宽高
- global.expectSuccess = false;
- const image2 = new Image();
- let image2Count = 0;
- let expectImage2Count = 0;
- image2.onload = function() {
- expect(image2.width).toBe(0);
- expect(image2.height).toBe(0);
- expect(image2.naturalWidth).toBe(100);
- expect(image2.naturalHeight).toBe(88);
- expect(image2.src).toBe('https://f.e.d');
- expect(image2Count).toBe(expectImage2Count);
- };
- image2.onerror = function() {
- expect(image2.width).toBe(0);
- expect(image2.height).toBe(0);
- expect(image2.naturalWidth).toBe(0);
- expect(image2.naturalHeight).toBe(0);
- expect(image2.src).toBe('https://d.e.f');
- expect(image2Count).toBe(expectImage2Count);
- };
- expect(image2.width).toBe(0);
- expect(image2.height).toBe(0);
- expect(image2.naturalWidth).toBe(0);
- expect(image2.naturalHeight).toBe(0);
- expect(image2.src).toBe('');
- image2Count++;
- expectImage2Count = 1;
- image2.src = 'https://d.e.f';
- await mock.sleep(20);
- global.expectSuccess = true; // 下一次请求为成功
- image2Count++;
- expectImage2Count = 2;
- image2.src = 'https://f.e.d';
- await mock.sleep(20);
- image2Count++;
- expectImage2Count = 3;
- image2.src = 'https://f.e.d';
- await mock.sleep(20);
-
- // 设置宽高
- image1.width = 123;
- image1.height = 321;
- expect(image1.style.cssText).toBe('width:123px;height:321px;');
-
- // base64
- const image3 = new Image();
- image3.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAyCAMAAAD/RKLmAAAATlBMVEUAAAD////ExMT////////////////////////////Dw8PDw8PExMTExMTDw8P////Hx8fT09Px8fH39/f4+Pj09PTi4uLb29vNzc3V1dUaiLcsAAAADnRSTlMAG7Vs8ptO2bbz4/OFSegrJ6sAAAD5SURBVEjH1dXZjoMgGEDhIq61/Q/g2vd/0TEzZjBVIdw09bvS5MSILN4u7HmXU/fne73Egfy9FrmdEvl4/WgfCXUrbdqzv2SUaXUmG1lafdFRLrK0+rqjVLquoKq1iteq4F+hIm9S5mzkZbDWAG6ajZknB6ADdQl0Vla2A8rTWuXgjJhxgGFcLhzk6qwuoDNie371VkwHxUmtACsWVuuNOq41ODG9r3sjDvRxXcMkIxujTFAf1xXMMrAxyAzVcd2AEXjJ6gVioEmv96d9F3iT/Z/EhUbpxb+gF5+dnejMe/FV5cVXrBffDV58p4XtdnHQ3wnRNP6ESPUDsqoqrpVL95sAAAAASUVORK5CYII=';
- expect(image3.src).toBe('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAyCAMAAAD/RKLmAAAATlBMVEUAAAD////ExMT////////////////////////////Dw8PDw8PExMTExMTDw8P////Hx8fT09Px8fH39/f4+Pj09PTi4uLb29vNzc3V1dUaiLcsAAAADnRSTlMAG7Vs8ptO2bbz4/OFSegrJ6sAAAD5SURBVEjH1dXZjoMgGEDhIq61/Q/g2vd/0TEzZjBVIdw09bvS5MSILN4u7HmXU/fne73Egfy9FrmdEvl4/WgfCXUrbdqzv2SUaXUmG1lafdFRLrK0+rqjVLquoKq1iteq4F+hIm9S5mzkZbDWAG6ajZknB6ADdQl0Vla2A8rTWuXgjJhxgGFcLhzk6qwuoDNie371VkwHxUmtACsWVuuNOq41ODG9r3sjDvRxXcMkIxujTFAf1xXMMrAxyAzVcd2AEXjJ6gVioEmv96d9F3iT/Z/EhUbpxb+gF5+dnejMe/FV5cVXrBffDV58p4XtdnHQ3wnRNP6ESPUDsqoqrpVL95sAAAAASUVORK5CYII=');
-});
diff --git a/packages/miniapp-render/__tests__/node/style.test.js b/packages/miniapp-render/__tests__/node/style.test.js
index eafbc13a69..6474675a8f 100644
--- a/packages/miniapp-render/__tests__/node/style.test.js
+++ b/packages/miniapp-render/__tests__/node/style.test.js
@@ -22,7 +22,7 @@ test('style', () => {
style.height = '13px';
expect(style.height).toBe('13px');
- expect(style.cssText).toBe('position:absolute;top:0;left:0;width:100%;height:13px;');
+ expect(style.cssText).toBe('position: absolute;top: 0;left: 0;width: 100%;height: 13px;');
style.cssText = 'position: relative; display: block;';
expect(style.position).toBe('relative');
@@ -30,9 +30,10 @@ test('style', () => {
expect(style.left).toBe('');
expect(style.display).toBe('block');
- expect(style.cssText).toBe('position:relative;display:block;');
+ expect(style.cssText).toBe('position: relative;display: block;');
+ // TODO:
// base64
- style.cssText = 'width: 100px; height: 100px; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAyCAMAAAD/RKLmAAAATlBMVEUAAAD////ExMT////////////////////////////Dw8PDw8PExMTExMTDw8P////Hx8fT09Px8fH39/f4+Pj09PTi4uLb29vNzc3V1dUaiLcsAAAADnRSTlMAG7Vs8ptO2bbz4/OFSegrJ6sAAAD5SURBVEjH1dXZjoMgGEDhIq61/Q/g2vd/0TEzZjBVIdw09bvS5MSILN4u7HmXU/fne73Egfy9FrmdEvl4/WgfCXUrbdqzv2SUaXUmG1lafdFRLrK0+rqjVLquoKq1iteq4F+hIm9S5mzkZbDWAG6ajZknB6ADdQl0Vla2A8rTWuXgjJhxgGFcLhzk6qwuoDNie371VkwHxUmtACsWVuuNOq41ODG9r3sjDvRxXcMkIxujTFAf1xXMMrAxyAzVcd2AEXjJ6gVioEmv96d9F3iT/Z/EhUbpxb+gF5+dnejMe/FV5cVXrBffDV58p4XtdnHQ3wnRNP6ESPUDsqoqrpVL95sAAAAASUVORK5CYII=")';
- expect(style.cssText).toBe('width:100px;height:100px;background-image:url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAyCAMAAAD/RKLmAAAATlBMVEUAAAD////ExMT////////////////////////////Dw8PDw8PExMTExMTDw8P////Hx8fT09Px8fH39/f4+Pj09PTi4uLb29vNzc3V1dUaiLcsAAAADnRSTlMAG7Vs8ptO2bbz4/OFSegrJ6sAAAD5SURBVEjH1dXZjoMgGEDhIq61/Q/g2vd/0TEzZjBVIdw09bvS5MSILN4u7HmXU/fne73Egfy9FrmdEvl4/WgfCXUrbdqzv2SUaXUmG1lafdFRLrK0+rqjVLquoKq1iteq4F+hIm9S5mzkZbDWAG6ajZknB6ADdQl0Vla2A8rTWuXgjJhxgGFcLhzk6qwuoDNie371VkwHxUmtACsWVuuNOq41ODG9r3sjDvRxXcMkIxujTFAf1xXMMrAxyAzVcd2AEXjJ6gVioEmv96d9F3iT/Z/EhUbpxb+gF5+dnejMe/FV5cVXrBffDV58p4XtdnHQ3wnRNP6ESPUDsqoqrpVL95sAAAAASUVORK5CYII=\');');
+ // style.cssText = 'width: 100px; height: 100px; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAyCAMAAAD/RKLmAAAATlBMVEUAAAD////ExMT////////////////////////////Dw8PDw8PExMTExMTDw8P////Hx8fT09Px8fH39/f4+Pj09PTi4uLb29vNzc3V1dUaiLcsAAAADnRSTlMAG7Vs8ptO2bbz4/OFSegrJ6sAAAD5SURBVEjH1dXZjoMgGEDhIq61/Q/g2vd/0TEzZjBVIdw09bvS5MSILN4u7HmXU/fne73Egfy9FrmdEvl4/WgfCXUrbdqzv2SUaXUmG1lafdFRLrK0+rqjVLquoKq1iteq4F+hIm9S5mzkZbDWAG6ajZknB6ADdQl0Vla2A8rTWuXgjJhxgGFcLhzk6qwuoDNie371VkwHxUmtACsWVuuNOq41ODG9r3sjDvRxXcMkIxujTFAf1xXMMrAxyAzVcd2AEXjJ6gVioEmv96d9F3iT/Z/EhUbpxb+gF5+dnejMe/FV5cVXrBffDV58p4XtdnHQ3wnRNP6ESPUDsqoqrpVL95sAAAAASUVORK5CYII=")';
+ // expect(style.cssText).toBe('width:100px;height:100px;background-image:url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAyCAMAAAD/RKLmAAAATlBMVEUAAAD////ExMT////////////////////////////Dw8PDw8PExMTExMTDw8P////Hx8fT09Px8fH39/f4+Pj09PTi4uLb29vNzc3V1dUaiLcsAAAADnRSTlMAG7Vs8ptO2bbz4/OFSegrJ6sAAAD5SURBVEjH1dXZjoMgGEDhIq61/Q/g2vd/0TEzZjBVIdw09bvS5MSILN4u7HmXU/fne73Egfy9FrmdEvl4/WgfCXUrbdqzv2SUaXUmG1lafdFRLrK0+rqjVLquoKq1iteq4F+hIm9S5mzkZbDWAG6ajZknB6ADdQl0Vla2A8rTWuXgjJhxgGFcLhzk6qwuoDNie371VkwHxUmtACsWVuuNOq41ODG9r3sjDvRxXcMkIxujTFAf1xXMMrAxyAzVcd2AEXjJ6gVioEmv96d9F3iT/Z/EhUbpxb+gF5+dnejMe/FV5cVXrBffDV58p4XtdnHQ3wnRNP6ESPUDsqoqrpVL95sAAAAASUVORK5CYII=\');');
});
diff --git a/packages/miniapp-render/__tests__/node/text-node.test.js b/packages/miniapp-render/__tests__/node/text-node.test.js
index fec2c7c1b0..980c95cba1 100644
--- a/packages/miniapp-render/__tests__/node/text-node.test.js
+++ b/packages/miniapp-render/__tests__/node/text-node.test.js
@@ -38,7 +38,7 @@ test('text-node: cloneNode', () => {
const node1 = document.createTextNode('abc');
const node2 = node1.cloneNode();
expect(node2).not.toBe(node1);
- expect(node2.$$nodeId).not.toBe(node1.$$nodeId);
+ expect(node2.__nodeId).not.toBe(node1.__nodeId);
expect(node2.__pageId).toBe(node1.__pageId);
expect(node2.textContent).toBe(node1.textContent);
expect(node2.nodeType).toBe(Node.TEXT_NODE);
diff --git a/packages/miniapp-render/__tests__/tree/parser.test.js b/packages/miniapp-render/__tests__/tree/parser.test.js
deleted file mode 100644
index eb6f0e259f..0000000000
--- a/packages/miniapp-render/__tests__/tree/parser.test.js
+++ /dev/null
@@ -1,158 +0,0 @@
-import mock from '../../renderMock';
-
-import parser from '../../src/tree/parser';
-
-function getTokenizeResult(content) {
- const startStack = [];
- const endStack = [];
- const textStack = [];
-
- parser.tokenize(content, {
- start(tagName, attrs, unary) {
- startStack.push({tagName, attrs, unary});
- },
- end(tagName) {
- endStack.push(tagName);
- },
- text(content) {
- content = content.trim();
- if (content) textStack.push(content);
- },
- });
-
- return {startStack, endStack, textStack};
-}
-
-test('tokenize html', () => {
- const res1 = getTokenizeResult('
');
- expect(res1.startStack.length).toBe(2);
- expect(res1.endStack.length).toBe(1);
- expect(res1.textStack.length).toBe(0);
- expect(res1.startStack).toEqual([{tagName: 'div', attrs: [], unary: false}, {tagName: 'br', attrs: [], unary: true}]);
- expect(res1.endStack).toEqual(['div']);
-
- const res2 = getTokenizeResult(`
-
- 123123
-
-
- `);
- expect(res2.startStack.length).toBe(12);
- expect(res2.endStack.length).toBe(10);
- expect(res2.textStack.length).toBe(4);
- expect(res2.startStack).toEqual([
- {tagName: 'div', attrs: [], unary: false},
- {tagName: 'br', attrs: [], unary: true},
- {tagName: 'div', attrs: [{name: 'id', value: 'a'}, {name: 'class', value: 'xx'}], unary: false},
- {tagName: 'input', attrs: [{name: 'id', value: 'b'}, {name: 'type', value: 'checkbox'}, {name: 'checked', value: undefined}], unary: true},
- {tagName: 'div', attrs: [], unary: false},
- {tagName: 'ul', attrs: [], unary: false},
- {tagName: 'li', attrs: [], unary: false},
- {tagName: 'span', attrs: [], unary: false},
- {tagName: 'li', attrs: [], unary: false},
- {tagName: 'span', attrs: [], unary: false},
- {tagName: 'li', attrs: [], unary: false},
- {tagName: 'span', attrs: [], unary: false}
- ]);
- expect(res2.endStack).toEqual(['div', 'div', 'span', 'li', 'span', 'li', 'span', 'li', 'ul', 'div']);
- expect(res2.textStack).toEqual(['123123', '123', '321', '567']);
-
- const res3 = getTokenizeResult(`
- 123
-
- haha
- 321
- `);
- expect(res3.startStack.length).toBe(4);
- expect(res3.endStack.length).toBe(4);
- expect(res3.textStack.length).toBe(4);
- expect(res3.startStack).toEqual([
- {tagName: 'div', attrs: [], unary: false},
- {tagName: 'script', attrs: [{name: 'type', value: 'text/javascript'}], unary: false},
- {tagName: 'span', attrs: [], unary: false},
- {tagName: 'div', attrs: [], unary: false}
- ]);
- expect(res3.endStack).toEqual(['div', 'script', 'span', 'div']);
- expect(res3.textStack).toEqual(['123', 'var msg = "hello world";\n console.log(msg);', 'haha', '321']);
-});
-
-test('parse html', () => {
- const res = parser.parse(mock.html);
-
- expect(res).toEqual([{
- type: 'element',
- tagName: 'div',
- attrs: [{name: 'class', value: 'aa'}],
- unary: false,
- children: [{
- type: 'element',
- tagName: 'div',
- attrs: [{name: 'id', value: 'bb'}, {name: 'class', value: 'bb'}],
- unary: false,
- children: [{
- type: 'element',
- tagName: 'header',
- attrs: [],
- unary: false,
- children: [{
- type: 'element',
- tagName: 'div',
- attrs: [{name: 'class', value: 'bb1'}],
- unary: false,
- children: [{type: 'text', content: '123'}]
- }, {
- type: 'element',
- tagName: 'div',
- attrs: [{name: 'class', value: 'bb2'}, {name: 'data-a', value: '123'}],
- unary: false,
- children: [{type: 'text', content: '321'}]
- }],
- }, {
- type: 'element',
- tagName: 'div',
- attrs: [{name: 'class', value: 'bb3'}],
- unary: false,
- children: [{type: 'text', content: 'middle'}],
- }, {
- type: 'element',
- tagName: 'footer',
- attrs: [],
- unary: false,
- children: [{
- type: 'element',
- tagName: 'span',
- attrs: [{name: 'id', value: 'bb4'}, {name: 'class', value: 'bb4'}, {name: 'data-index', value: '1'}],
- unary: false,
- children: [{type: 'text', content: '1'}],
- }, {
- type: 'element',
- tagName: 'span',
- attrs: [{name: 'class', value: 'bb4'}, {name: 'data-index', value: '2'}],
- unary: false,
- children: [{type: 'text', content: '2'}],
- }, {
- type: 'element',
- tagName: 'span',
- attrs: [{name: 'class', value: 'bb4'}, {name: 'data-index', value: '3'}],
- unary: false,
- children: [{type: 'text', content: '3'}],
- }],
- }, {
- type: 'element',
- tagName: 'div',
- attrs: [],
- unary: false,
- children: [{type: 'text', content: 'tail'}],
- }],
- }],
- }]);
-});
diff --git a/packages/miniapp-render/__tests__/tree/query-selector.test.js b/packages/miniapp-render/__tests__/tree/query-selector.test.js
deleted file mode 100644
index 5de2715008..0000000000
--- a/packages/miniapp-render/__tests__/tree/query-selector.test.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import QuerySelector from '../../src/tree/query-selector';
-
-const querySelector = new QuerySelector();
-
-function toArray(list) {
- return Array.prototype.slice.apply(list);
-}
-
-function getExtra(document) {
- return {
- idMap: {
- bb: document.getElementById('bb'),
- bb4: document.getElementById('bb4'),
- },
- tagMap: {
- DIV: toArray(document.getElementsByTagName('div')),
- SPAN: toArray(document.getElementsByTagName('span')),
- HEADER: toArray(document.getElementsByTagName('header')),
- FOOTER: toArray(document.getElementsByTagName('footer')),
- },
- classMap: {
- aa: toArray(document.getElementsByClassName('aa')),
- bb: toArray(document.getElementsByClassName('bb')),
- bb1: toArray(document.getElementsByClassName('bb1')),
- bb2: toArray(document.getElementsByClassName('bb2')),
- bb3: toArray(document.getElementsByClassName('bb3')),
- bb4: toArray(document.getElementsByClassName('bb4')),
- },
- };
-}
-
-test('query-selector: parse selector', () => {
- // 标签选择器
- expect(querySelector.parse('tag')).toEqual([{tag: 'tag'}]);
-
- // id 选择器
- expect(querySelector.parse('#id')).toEqual([{tag: '*', id: 'id'}]);
-
- // 类选择器
- expect(querySelector.parse('.class')).toEqual([{tag: '*', class: ['class']}]);
- expect(querySelector.parse('.class1.class2')).toEqual([{tag: '*', class: ['class1', 'class2']}]);
-
- // 亲属选择器
- expect(querySelector.parse('a b')).toEqual([{tag: 'a', kinship: ' '}, {tag: 'b'}]);
- expect(querySelector.parse('a > b')).toEqual([{tag: 'a', kinship: '>'}, {tag: 'b'}]);
- expect(querySelector.parse('a + b')).toEqual([{tag: 'a', kinship: '+'}, {tag: 'b'}]);
-
- // 基本组合
- expect(querySelector.parse('tag #id .class')).toEqual([
- {tag: 'tag', kinship: ' '},
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class']},
- ]);
- expect(querySelector.parse('tag#id.class1.class2')).toEqual([{tag: 'tag', id: 'id', class: ['class1', 'class2']}]);
-
- // 伪类选择器
- expect(querySelector.parse('#id .class:pseudo-class')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'pseudo-class'}]}
- ]);
- expect(querySelector.parse('#id .class:pseudo-class(1)')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'pseudo-class', param: '1'}]}
- ]);
- expect(querySelector.parse('#id .class:first-child')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'first-child'}]}
- ]);
- expect(querySelector.parse('#id .class:last-child')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'last-child'}]}
- ]);
- expect(querySelector.parse('#id .class:nth-child(3)')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'nth-child', param: {a: 0, b: 3}}]}
- ]);
- expect(querySelector.parse('#id .class:nth-child(2n+1)')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'nth-child', param: {a: 2, b: 1}}]}
- ]);
- expect(querySelector.parse('#id .class:nth-child(2n-1)')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], pseudo: [{name: 'nth-child', param: {a: 2, b: -1}}]}
- ]);
-
- // 属性选择器
- expect(querySelector.parse('#id .class[name=value]')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], attr: [{name: 'name', opr: '=', val: 'value'}]}
- ]);
- expect(querySelector.parse('#id .class[name^=value]')).toEqual([
- {tag: '*', id: 'id', kinship: ' '},
- {tag: '*', class: ['class'], attr: [{name: 'name', opr: '^=', val: 'value'}]}
- ]);
-});
diff --git a/packages/miniapp-render/__tests__/util/tool.test.js b/packages/miniapp-render/__tests__/util/tool.test.js
index 48f9311a88..61ae23dfff 100644
--- a/packages/miniapp-render/__tests__/util/tool.test.js
+++ b/packages/miniapp-render/__tests__/util/tool.test.js
@@ -12,9 +12,9 @@ test('tool: toCamel', () => {
});
test('tool: getId', () => {
- expect(tool.getId().toString()).toEqual(expect.stringMatching(/^\d{13}$/));
- expect(tool.getId().toString()).toEqual(expect.stringMatching(/^\d{13}$/));
- expect(tool.getId().toString()).toEqual(expect.stringMatching(/^\d{13}$/));
+ expect(tool.getId().toString()).toEqual('0');
+ expect(tool.getId().toString()).toEqual('1');
+ expect(tool.getId().toString()).toEqual('2');
});
test('tool: throttle/flushThrottleCache', async() => {
@@ -33,13 +33,3 @@ test('tool: throttle/flushThrottleCache', async() => {
await mock.sleep(10);
expect(count).toBe(2);
});
-
-test('tool: decodeContent', () => {
- expect(tool.decodeContent('asdc s d weq<>s sw"wwee"w'w&')).toBe('asdc\u00A0s \u2002d \u2003 weq<>s sw"wwee"w\'w&');
-});
-
-test('tool: isTagNameSupport', () => {
- expect(tool.isTagNameSupport('DIV')).toBe(true);
- expect(tool.isTagNameSupport('IFRAME')).toBe(false);
- expect(tool.isTagNameSupport('SPAN')).toBe(true);
-});
diff --git a/packages/miniapp-render/package.json b/packages/miniapp-render/package.json
index 77727faa2a..0b6754f950 100644
--- a/packages/miniapp-render/package.json
+++ b/packages/miniapp-render/package.json
@@ -1,6 +1,6 @@
{
"name": "miniapp-render",
- "version": "1.2.2",
+ "version": "1.2.3",
"description": "DOM simulator for MiniApp",
"files": [
"dist"
diff --git a/packages/miniapp-render/renderMock.js b/packages/miniapp-render/renderMock.js
index 5b920cc638..bdc15b9129 100644
--- a/packages/miniapp-render/renderMock.js
+++ b/packages/miniapp-render/renderMock.js
@@ -13,7 +13,71 @@ const config = {
}
};
-const html = `
+function generateDOM(document) {
+ const root = document.body;
+
+ const aa = document.createElement('div');
+ aa.setAttribute('class', 'aa');
+
+ const bb = document.createElement('div');
+ bb.id = 'bb';
+ bb.setAttribute('class', 'bb');
+
+ const header = document.createElement('header');
+
+ const footer = document.createElement('footer');
+
+ const bb1 = document.createElement('div');
+ bb1.setAttribute('class', 'bb1');
+ bb1.textContent = '123';
+
+ const bb2 = document.createElement('div');
+ bb2.setAttribute('class', 'bb2');
+ bb2.setAttribute('data-a', '123');
+ bb2.textContent = '321';
+
+ const bb3 = document.createElement('div');
+ bb3.setAttribute('class', 'bb3');
+ bb2.textContent = 'middle';
+
+ const bb4 = document.createElement('span');
+ bb4.id = 'bb4';
+ bb4.setAttribute('class', 'bb4');
+ bb2.setAttribute('data-index', '1');
+ bb2.textContent = '1';
+
+ const bb42 = document.createElement('span');
+ bb42.setAttribute('class', 'bb4');
+ bb42.setAttribute('data-index', '2');
+ bb42.textContent = '2';
+
+ const bb43 = document.createElement('span');
+ bb43.setAttribute('class', 'bb4');
+ bb43.setAttribute('data-index', '3');
+ bb43.textContent = '3';
+
+ const tail = document.createElement('div');
+ tail.textContent = 'tail';
+
+ footer.appendChild(bb4);
+ footer.appendChild(bb42);
+ footer.appendChild(bb43);
+
+ header.appendChild(bb1);
+ header.appendChild(bb2);
+
+ bb.appendChild(header);
+ bb.appendChild(bb3);
+ bb.appendChild(footer);
+ bb.appendChild(tail);
+
+ aa.appendChild(bb);
+
+ root.appendChild(aa);
+}
+
+const html = `
+
123
@@ -61,7 +125,8 @@ export default {
const pageId = '/pages/home/index-1';
const window = createWindow();
const document = createDocument(pageId);
- document.body.innerHTML = html;
+ generateDOM(document);
+ // document.body.innerHTML = html;
document._internal = {
data: {
pageId
@@ -70,7 +135,8 @@ export default {
setTimeout(() => {
callback();
}, 0);
- }
+ },
+ firstRenderCallback: () => {}
};
window.__pageId = pageId;
cache.setWindow(window);
diff --git a/packages/miniapp-render/src/bridge/events/callEvent.js b/packages/miniapp-render/src/bridge/events/callEvent.js
index db6781df29..c81ad65ff5 100644
--- a/packages/miniapp-render/src/bridge/events/callEvent.js
+++ b/packages/miniapp-render/src/bridge/events/callEvent.js
@@ -1,9 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isWeChatMiniProgram } from 'universal-env';
import EventTarget from '../../event/event-target';
import cache from '../../utils/cache';
-import findParentNode from '../../utils/findParentNode';
-import checkEventAccessDomNode from '../../utils/checkEventAccessDomNode';
export default function(eventName, evt, extra, pageId, nodeId) {
const originNode = cache.getNode(pageId, nodeId);
@@ -13,154 +9,6 @@ export default function(eventName, evt, extra, pageId, nodeId) {
originNode,
eventName,
evt,
- extra,
- (domNode, evt, isCapture) => {
- if (isWeChatMiniProgram) {
- setTimeout(() => {
- if (evt.cancelable) return;
- const window = cache.getWindow();
-
- if (
- domNode.tagName === 'LABEL' &&
- evt.type === 'click' &&
- !isCapture
- ) {
- const forValue = domNode.getAttribute('for');
- let targetDomNode;
- if (forValue) {
- targetDomNode = window.document.getElementById(forValue);
- } else {
- targetDomNode = domNode.querySelector('input');
-
- if (!targetDomNode)
- targetDomNode = domNode.querySelector(
- 'builtIn-component[_behavior=switch]'
- );
- }
-
- if (!targetDomNode || !!targetDomNode.getAttribute('disabled'))
- return;
-
- if (targetDomNode.tagName === 'INPUT') {
- if (checkEventAccessDomNode(evt, targetDomNode, domNode)) return;
- targetDomNode.focus();
- } else if (targetDomNode.tagName === 'BUILTIN-COMPONENT') {
- if (checkEventAccessDomNode(evt, targetDomNode, domNode)) return;
-
- const behavior = targetDomNode._behavior;
- if (behavior === 'switch') {
- const checked = !targetDomNode.getAttribute('checked');
- targetDomNode.setAttribute('checked', checked);
- this.callSimpleEvent(
- 'change',
- { detail: { value: checked } },
- targetDomNode
- );
- }
- }
- } else if (
- (domNode.tagName === 'BUTTON' ||
- domNode.tagName === 'BUILTIN-COMPONENT' &&
- domNode._behavior === 'button') &&
- evt.type === 'click' &&
- !isCapture
- ) {
- const type =
- domNode.tagName === 'BUTTON'
- ? domNode.getAttribute('type')
- : domNode.getAttribute('form-type');
- const formAttr = domNode.getAttribute('form');
- const form = formAttr
- ? window.document.getElementById(formAttr)
- : findParentNode(domNode, 'FORM');
-
- if (!form) return;
- if (type !== 'submit' && type !== 'reset') return;
-
- const inputList = form.querySelectorAll(
- 'input[name]'
- );
- const textareaList = form.querySelectorAll(
- 'textarea[name]'
- );
- const switchList = form
- .querySelectorAll('builtin-component[_behavior=switch]')
- .filter((item) => !!item.getAttribute('name'));
- const sliderList = form
- .querySelectorAll('builtin-component[_behavior=slider]')
- .filter((item) => !!item.getAttribute('name'));
- const pickerList = form
- .querySelectorAll('builtin-component[_behavior=picker]')
- .filter((item) => !!item.getAttribute('name'));
-
- if (type === 'submit') {
- const formData = {};
- if (inputList.length) {
- inputList.forEach((item) => {
- formData[item.name] = item.value;
- });
- }
- if (textareaList.length)
- textareaList.forEach(
- (item) => formData[item.name] = item.value
- );
- if (switchList.length)
- switchList.forEach(
- (item) =>
- formData[item.getAttribute('name')] = !!item.getAttribute(
- 'checked'
- )
- );
- if (sliderList.length)
- sliderList.forEach(
- (item) =>
- formData[item.getAttribute('name')] =
- +item.getAttribute('value') || 0
- );
- if (pickerList.length)
- pickerList.forEach(
- (item) =>
- formData[item.getAttribute('name')] = item.getAttribute(
- 'value'
- )
- );
-
- const detail = { value: formData };
- if (form._formId) {
- detail.formId = form._formId;
- form._formId = null;
- }
- this.callSimpleEvent(
- 'submit',
- { detail, extra: { $$from: 'button' } },
- form
- );
- } else if (type === 'reset') {
- if (inputList.length) {
- inputList.forEach((item) => {
- item.setAttribute('value', '');
- });
- }
- if (textareaList.length)
- textareaList.forEach((item) => item.setAttribute('value', ''));
- if (switchList.length)
- switchList.forEach((item) =>
- item.setAttribute('checked', undefined)
- );
- if (sliderList.length)
- sliderList.forEach((item) =>
- item.setAttribute('value', undefined)
- );
- if (pickerList.length)
- pickerList.forEach((item) =>
- item.setAttribute('value', undefined)
- );
-
- this.callSimpleEvent('reset', { extra: { $$from: 'button' } }, form);
- }
- }
- }, 0);
- }
- }
+ extra
);
}
diff --git a/packages/miniapp-render/src/builtInComponents/button.js b/packages/miniapp-render/src/builtInComponents/button.js
index ba22c0fbe0..002706486b 100644
--- a/packages/miniapp-render/src/builtInComponents/button.js
+++ b/packages/miniapp-render/src/builtInComponents/button.js
@@ -1,108 +1,5 @@
export default {
name: 'button',
- props: [{
- name: 'size',
- get(domNode) {
- return domNode.getAttribute('size') || 'default';
- },
- }, {
- name: 'type',
- get(domNode) {
- return domNode.getAttribute('type') || 'default';
- },
- }, {
- name: 'plain',
- get(domNode) {
- return !!domNode.getAttribute('plain');
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return !!domNode.getAttribute('disabled');
- },
- }, {
- name: 'loading',
- get(domNode) {
- return !!domNode.getAttribute('loading');
- },
- }, {
- name: 'form-type',
- get(domNode) {
- return domNode.getAttribute('form-type') || '';
- },
- }, {
- name: 'open-type',
- get(domNode) {
- return domNode.getAttribute('open-type') || '';
- },
- }, {
- name: 'hover-class',
- get(domNode) {
- return domNode.getAttribute('hover-class') || 'button-hover';
- },
- }, {
- name: 'hover-stop-propagation',
- get(domNode) {
- return !!domNode.getAttribute('hover-stop-propagation');
- },
- }, {
- name: 'hover-start-time',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('hover-start-time'), 10);
- return !isNaN(value) ? value : 20;
- },
- }, {
- name: 'hover-stay-time',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('hover-stay-time'), 10);
- return !isNaN(value) ? value : 70;
- },
- }, {
- name: 'lang',
- get(domNode) {
- return domNode.getAttribute('lang') || 'en';
- },
- }, {
- name: 'session-from',
- get(domNode) {
- return domNode.getAttribute('session-from') || '';
- },
- }, {
- name: 'send-message-title',
- get(domNode) {
- return domNode.getAttribute('send-message-title') || '';
- },
- }, {
- name: 'send-message-path',
- get(domNode) {
- return domNode.getAttribute('send-message-path') || '';
- },
- }, {
- name: 'send-message-img',
- get(domNode) {
- return domNode.getAttribute('send-message-img') || '';
- },
- }, {
- name: 'app-parameter',
- get(domNode) {
- return domNode.getAttribute('app-parameter') || '';
- },
- }, {
- name: 'show-message-card',
- get(domNode) {
- return !!domNode.getAttribute('show-message-card');
- },
- }, {
- name: 'business-id',
- get(domNode) {
- return domNode.getAttribute('business-id') || '';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onButtonGetUserInfo',
eventName: 'getuserinfo'
diff --git a/packages/miniapp-render/src/builtInComponents/camera.js b/packages/miniapp-render/src/builtInComponents/camera.js
index 27ab2c8e04..1abe62368f 100644
--- a/packages/miniapp-render/src/builtInComponents/camera.js
+++ b/packages/miniapp-render/src/builtInComponents/camera.js
@@ -1,32 +1,12 @@
-export default {
- name: 'camera',
- props: [{
- name: 'mode',
- get(domNode) {
- return domNode.getAttribute('mode') || 'normal';
- },
- }, {
- name: 'device-position',
- get(domNode) {
- return domNode.getAttribute('device-position') || 'back';
- },
- }, {
- name: 'flash',
- get(domNode) {
- return domNode.getAttribute('flash') || 'auto';
- },
- }, {
- name: 'frame-size',
- get(domNode) {
- return domNode.getAttribute('frame-size') || 'medium';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
- singleEvents: [{
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { isWeChatMiniProgram } from 'universal-env';
+
+const camera = {
+ name: 'camera'
+};
+
+if (isWeChatMiniProgram) {
+ camera.singleEvents = [{
name: 'onCameraStop',
eventName: 'stop'
},
@@ -41,5 +21,7 @@ export default {
{
name: 'onCameraScanCode',
eventName: 'scancode'
- }]
-};
+ }];
+}
+
+export default camera;
diff --git a/packages/miniapp-render/src/builtInComponents/canvas.js b/packages/miniapp-render/src/builtInComponents/canvas.js
index f25da96a93..9beb0e3e7e 100644
--- a/packages/miniapp-render/src/builtInComponents/canvas.js
+++ b/packages/miniapp-render/src/builtInComponents/canvas.js
@@ -1,29 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isWeChatMiniProgram, isMiniApp } from 'universal-env';
-
const canvas = {
name: 'canvas',
- props: [{
- name: 'type',
- get(domNode) {
- return domNode.getAttribute('type') || '';
- },
- }, {
- name: 'canvas-id',
- get(domNode) {
- return domNode.getAttribute(isWeChatMiniProgram ? 'canvas-id' : 'id') || '';
- },
- }, {
- name: 'disable-scroll',
- get(domNode) {
- return !!domNode.getAttribute('disable-scroll');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onCanvasTouchStart',
eventName: 'canvastouchstart'
@@ -50,20 +26,4 @@ const canvas = {
}]
};
-if (isMiniApp) {
- canvas.props = canvas.props.concat([
- {
- name: 'width',
- get(domNode) {
- return domNode.getAttribute('width') || '';
- },
- }, {
- name: 'height',
- get(domNode) {
- return domNode.getAttribute('height') || '';
- },
- }
- ]);
-}
-
export default canvas;
diff --git a/packages/miniapp-render/src/builtInComponents/checkbox-group.js b/packages/miniapp-render/src/builtInComponents/checkbox-group.js
index 889e2b4630..ff5f131700 100644
--- a/packages/miniapp-render/src/builtInComponents/checkbox-group.js
+++ b/packages/miniapp-render/src/builtInComponents/checkbox-group.js
@@ -1,11 +1,5 @@
export default {
name: 'checkbox-group',
- props: [{
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }],
singleEvents: [{
name: 'onCheckboxChange',
eventName: 'change'
diff --git a/packages/miniapp-render/src/builtInComponents/checkbox.js b/packages/miniapp-render/src/builtInComponents/checkbox.js
index 85a79b3aac..5fa68d0354 100644
--- a/packages/miniapp-render/src/builtInComponents/checkbox.js
+++ b/packages/miniapp-render/src/builtInComponents/checkbox.js
@@ -1,31 +1,5 @@
export default {
name: 'checkbox',
- props: [{
- name: 'value',
- get(domNode) {
- return domNode.getAttribute('value') || '';
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'checked',
- get(domNode) {
- return domNode.getAttribute('checked') || false;
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return domNode.getAttribute('disabled') || false;
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '';
- },
- }],
singleEvents: [{
name: 'onCheckboxItemChange',
eventName: 'change'
diff --git a/packages/miniapp-render/src/builtInComponents/cover-image.js b/packages/miniapp-render/src/builtInComponents/cover-image.js
index 83cbfb323b..a7a9e39a5c 100644
--- a/packages/miniapp-render/src/builtInComponents/cover-image.js
+++ b/packages/miniapp-render/src/builtInComponents/cover-image.js
@@ -1,16 +1,5 @@
export default {
name: 'cover-image',
- props: [{
- name: 'src',
- get(domNode) {
- return domNode.src;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onCoverImageLoad',
eventName: 'load'
diff --git a/packages/miniapp-render/src/builtInComponents/cover-view.js b/packages/miniapp-render/src/builtInComponents/cover-view.js
index 7f047bffd2..967dbf8fc1 100644
--- a/packages/miniapp-render/src/builtInComponents/cover-view.js
+++ b/packages/miniapp-render/src/builtInComponents/cover-view.js
@@ -1,15 +1,3 @@
export default {
- name: 'cover-view',
- props: [{
- name: 'scroll-top',
- get(domNode) {
- const value = domNode.getAttribute('scroll-top');
- return value !== undefined && !isNaN(+value) ? +value : '';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'cover-view'
};
diff --git a/packages/miniapp-render/src/builtInComponents/editor.js b/packages/miniapp-render/src/builtInComponents/editor.js
index 234b32549e..f96b793f74 100644
--- a/packages/miniapp-render/src/builtInComponents/editor.js
+++ b/packages/miniapp-render/src/builtInComponents/editor.js
@@ -1,36 +1,5 @@
export default {
name: 'editor',
- props: [{
- name: 'read-only',
- get(domNode) {
- return !!domNode.getAttribute('read-only');
- },
- }, {
- name: 'placeholder',
- get(domNode) {
- return domNode.getAttribute('placeholder') || '';
- },
- }, {
- name: 'show-img-size',
- get(domNode) {
- return !!domNode.getAttribute('show-img-size');
- },
- }, {
- name: 'show-img-toolbar',
- get(domNode) {
- return !!domNode.getAttribute('show-img-toolbar');
- },
- }, {
- name: 'show-img-resize',
- get(domNode) {
- return !!domNode.getAttribute('show-img-resize');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onEditorReady',
eventName: 'ready'
diff --git a/packages/miniapp-render/src/builtInComponents/form.js b/packages/miniapp-render/src/builtInComponents/form.js
index 0487753c16..ce46b68cc0 100644
--- a/packages/miniapp-render/src/builtInComponents/form.js
+++ b/packages/miniapp-render/src/builtInComponents/form.js
@@ -1,21 +1,5 @@
export default {
name: 'form',
- props: [{
- name: 'report-submit',
- get(domNode) {
- return !!domNode.getAttribute('report-submit');
- },
- }, {
- name: 'report-submit-timeout',
- get(domNode) {
- return +domNode.getAttribute('report-submit-timeout') || 0;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onFormSubmit',
eventName: 'submit'
diff --git a/packages/miniapp-render/src/builtInComponents/icon.js b/packages/miniapp-render/src/builtInComponents/icon.js
index df9a96227b..4b0b72166d 100644
--- a/packages/miniapp-render/src/builtInComponents/icon.js
+++ b/packages/miniapp-render/src/builtInComponents/icon.js
@@ -1,24 +1,3 @@
export default {
- name: 'icon',
- props: [{
- name: 'type',
- get(domNode) {
- return domNode.getAttribute('type') || '';
- },
- }, {
- name: 'size',
- get(domNode) {
- return domNode.getAttribute('size') || '23';
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'icon'
};
diff --git a/packages/miniapp-render/src/builtInComponents/image.js b/packages/miniapp-render/src/builtInComponents/image.js
index 87d97bd620..b84e477a2e 100644
--- a/packages/miniapp-render/src/builtInComponents/image.js
+++ b/packages/miniapp-render/src/builtInComponents/image.js
@@ -1,56 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isMiniApp, isWeChatMiniProgram } from 'universal-env';
-
-let props = [{
- name: 'src',
- get(domNode) {
- return domNode.src;
- },
-}, {
- name: 'mode',
- get(domNode) {
- return domNode.getAttribute('mode') || 'scaleToFill';
- },
-}, {
- name: 'lazy-load',
- get(domNode) {
- return !!domNode.getAttribute('lazy-load');
- },
-}, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
-}];
-
-if (isWeChatMiniProgram) {
- props = props.concat([
- {
- name: 'show-menu-by-longpress',
- get(domNode) {
- return !!domNode.getAttribute('show-menu-by-longpress');
- }
- },
- {
- name: 'webp',
- get(domNode) {
- return !!domNode.getAttribute('webp');
- }
- },
- ]);
-}
-if (isMiniApp) {
- props.push({
- name: 'default-source',
- get(domNode) {
- return !!domNode.getAttribute('default-source');
- },
- });
-}
-
export default {
name: 'image',
- props,
singleEvents: [{
name: 'onImageLoad',
eventName: 'load'
diff --git a/packages/miniapp-render/src/builtInComponents/index.js b/packages/miniapp-render/src/builtInComponents/index.js
index 5ab8119527..01ead07358 100644
--- a/packages/miniapp-render/src/builtInComponents/index.js
+++ b/packages/miniapp-render/src/builtInComponents/index.js
@@ -73,7 +73,6 @@ const components = [
pickerViewColumn,
];
-const propsMap = {};
const handlesMap = {
simpleEvents: [],
singleEvents: [],
@@ -83,14 +82,11 @@ const handlesMap = {
components.forEach(
({
- name,
- props,
simpleEvents,
singleEvents,
functionalSingleEvents,
complexEvents,
}) => {
- propsMap[name] = props;
if (simpleEvents) {
handlesMap.simpleEvents = handlesMap.simpleEvents.concat(simpleEvents);
}
@@ -108,15 +104,4 @@ components.forEach(
}
);
-// Tags below will be mapped to miniapp builtinComponent, others will be mapped to view
-const WEB_TAG_MAP = {
- IMG: 'image',
- INPUT: 'input',
- TEXTAREA: 'textarea',
- VIDEO: 'video'
-};
-Object.keys(WEB_TAG_MAP).forEach(TAG_NAME => {
- propsMap[TAG_NAME] = propsMap[WEB_TAG_MAP[TAG_NAME]];
-});
-
-export { propsMap, handlesMap };
+export { handlesMap };
diff --git a/packages/miniapp-render/src/builtInComponents/input.js b/packages/miniapp-render/src/builtInComponents/input.js
index 7e9bb94102..199dce314f 100644
--- a/packages/miniapp-render/src/builtInComponents/input.js
+++ b/packages/miniapp-render/src/builtInComponents/input.js
@@ -1,116 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isMiniApp } from 'universal-env';
-
const input = {
name: 'input',
- props: [{
- name: 'value',
- get(domNode) {
- return domNode.value || '';
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'type',
- get(domNode) {
- const value = domNode.type || 'text';
- return value !== 'password' ? value : 'text';
- },
- }, {
- name: 'password',
- get(domNode) {
- return domNode.type !== 'password' ? !!domNode.getAttribute('password') : true;
- },
- }, {
- name: 'placeholder',
- get(domNode) {
- return domNode.placeholder;
- },
- }, {
- name: 'placeholder-style',
- get(domNode) {
- let style = domNode.getAttribute('placeholder-style') || '';
- // Compatible with placeholderColor attribute of rax-textinput
- const color = domNode.getAttribute('placeholderColor');
- if (color) {
- style = 'color:' + color + ';' + style;
- }
- return style;
- }
- }, {
- name: 'placeholder-class',
- get(domNode) {
- return domNode.getAttribute('placeholder-class');
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return domNode.disabled || domNode.readOnly;
- },
- }, {
- name: 'maxlength',
- get(domNode) {
- const value = parseInt(domNode.maxlength, 10);
- return !isNaN(value) ? value : 140;
- },
- }, {
- name: 'cursor-spacing',
- get(domNode) {
- return +domNode.getAttribute('cursor-spacing') || 0;
- },
- }, {
- name: 'confirm-type',
- get(domNode) {
- return domNode.getAttribute('confirm-type') || 'done';
- },
- }, {
- name: 'confirm-hold',
- get(domNode) {
- return !!domNode.getAttribute('confirm-hold');
- },
- }, {
- name: 'cursor',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('cursor'), 10);
- return !isNaN(value) ? value : -1;
- },
- }, {
- name: 'selection-start',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('selection-start'), 10);
- return !isNaN(value) ? value : -1;
- },
- }, {
- name: 'selection-end',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('selection-end'), 10);
- return !isNaN(value) ? value : -1;
- },
- }, {
- name: 'adjust-position',
- get(domNode) {
- const value = domNode.getAttribute('adjust-position');
- return value !== undefined ? !!value : true;
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '#09BB07';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }, {
- name: 'focus-state',
- get(domNode) {
- return !!(domNode.getAttribute('autofocus') || domNode.getAttribute('focus-state'));
- },
- }],
simpleEvents: [{
name: 'onInputConfirm',
eventName: 'confirm'
@@ -124,7 +13,7 @@ const input = {
eventName: 'input',
middleware(evt, domNode, pageId, nodeId) {
const value = '' + evt.detail.value;
- domNode.__setAttributeWithoutUpdate('value', value);
+ domNode._setAttributeWithOutUpdate('value', value);
this.callEvent('input', evt, null, pageId, nodeId);
}
@@ -134,7 +23,7 @@ const input = {
eventName: 'focus',
middleware(evt, domNode, pageId, nodeId) {
domNode.__inputOldValue = domNode.value || '';
- domNode.__setAttributeWithoutUpdate('focus-state', true);
+ domNode._setAttributeWithOutUpdate('focus-state', true);
this.callSimpleEvent('focus', evt, domNode);
}
@@ -143,7 +32,7 @@ const input = {
name: 'onInputBlur',
eventName: 'blur',
middleware(evt, domNode, pageId, nodeId) {
- domNode.__setAttributeWithoutUpdate('focus-state', false);
+ domNode._setAttributeWithOutUpdate('focus-state', false);
if (domNode.__inputOldValue !== undefined && domNode.value !== domNode.__inputOldValue) {
domNode.__inputOldValue = undefined;
@@ -154,13 +43,4 @@ const input = {
}]
};
-if (!isMiniApp) {
- input.props.push({
- name: 'controlled',
- get(domNode) {
- return !!domNode.getAttribute('controlled');
- },
- });
-}
-
export default input;
diff --git a/packages/miniapp-render/src/builtInComponents/label.js b/packages/miniapp-render/src/builtInComponents/label.js
index 551902bc40..1bbda9ac11 100644
--- a/packages/miniapp-render/src/builtInComponents/label.js
+++ b/packages/miniapp-render/src/builtInComponents/label.js
@@ -1,9 +1,3 @@
export default {
- name: 'label',
- props: [{
- name: 'for',
- get(domNode) {
- return domNode.getAttribute('for') || '';
- },
- }]
+ name: 'label'
};
diff --git a/packages/miniapp-render/src/builtInComponents/map.js b/packages/miniapp-render/src/builtInComponents/map.js
index 5d794dfac0..1b0e739050 100644
--- a/packages/miniapp-render/src/builtInComponents/map.js
+++ b/packages/miniapp-render/src/builtInComponents/map.js
@@ -1,133 +1,5 @@
export default {
name: 'map',
- props: [{
- name: 'longitude',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('longitude'), 10);
- return !isNaN(value) ? value : 39.92;
- },
- }, {
- name: 'latitude',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('latitude'), 10);
- return !isNaN(value) ? value : 116.46;
- },
- }, {
- name: 'scale',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('scale'), 10);
- return !isNaN(value) ? value : 16;
- },
- }, {
- name: 'markers',
- get(domNode) {
- const value = domNode.getAttribute('markers');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'polyline',
- get(domNode) {
- const value = domNode.getAttribute('polyline');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'circles',
- get(domNode) {
- const value = domNode.getAttribute('circles');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'controls',
- get(domNode) {
- const value = domNode.getAttribute('controls');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'include-points',
- get(domNode) {
- const value = domNode.getAttribute('include-points');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'show-location',
- get(domNode) {
- return !!domNode.getAttribute('show-location');
- },
- }, {
- name: 'polygons',
- get(domNode) {
- const value = domNode.getAttribute('polygons');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'subkey',
- get(domNode) {
- return domNode.getAttribute('subkey') || '';
- },
- }, {
- name: 'layer-style',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('layer-style'), 10);
- return !isNaN(value) ? value : 1;
- },
- }, {
- name: 'rotate',
- get(domNode) {
- return +domNode.getAttribute('rotate') || 0;
- },
- }, {
- name: 'skew',
- get(domNode) {
- return +domNode.getAttribute('skew') || 0;
- },
- }, {
- name: 'enable-3D',
- get(domNode) {
- return !!domNode.getAttribute('enable-3D');
- },
- }, {
- name: 'show-compass',
- get(domNode) {
- return !!domNode.getAttribute('show-compass');
- },
- }, {
- name: 'enable-overlooking',
- get(domNode) {
- return !!domNode.getAttribute('enable-overlooking');
- },
- }, {
- name: 'enable-zoom',
- get(domNode) {
- const value = domNode.getAttribute('enable-zoom');
- return value !== undefined ? !!value : true;
- },
- }, {
- name: 'enable-scroll',
- get(domNode) {
- const value = domNode.getAttribute('enable-scroll');
- return value !== undefined ? !!value : true;
- },
- }, {
- name: 'enable-rotate',
- get(domNode) {
- return !!domNode.getAttribute('enable-rotate');
- },
- }, {
- name: 'enable-satellite',
- get(domNode) {
- return !!domNode.getAttribute('enable-satellite');
- },
- }, {
- name: 'enable-traffic',
- get(domNode) {
- return !!domNode.getAttribute('enable-traffic');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onMapTap',
eventName: 'tap'
diff --git a/packages/miniapp-render/src/builtInComponents/movable-area.js b/packages/miniapp-render/src/builtInComponents/movable-area.js
index f84f485432..1f5cf3d59d 100644
--- a/packages/miniapp-render/src/builtInComponents/movable-area.js
+++ b/packages/miniapp-render/src/builtInComponents/movable-area.js
@@ -1,14 +1,3 @@
export default {
- name: 'movable-area',
- props: [{
- name: 'scaleArea',
- get(domNode) {
- return !!domNode.getAttribute('scale-area');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'movable-area'
};
diff --git a/packages/miniapp-render/src/builtInComponents/movable-view.js b/packages/miniapp-render/src/builtInComponents/movable-view.js
index d8ae413123..bd4df4b8c5 100644
--- a/packages/miniapp-render/src/builtInComponents/movable-view.js
+++ b/packages/miniapp-render/src/builtInComponents/movable-view.js
@@ -1,82 +1,5 @@
export default {
name: 'movable-view',
- props: [{
- name: 'direction',
- get(domNode) {
- return domNode.getAttribute('direction') || 'none';
- },
- }, {
- name: 'inertia',
- get(domNode) {
- return !!domNode.getAttribute('inertia');
- },
- }, {
- name: 'outOfBounds',
- get(domNode) {
- return !!domNode.getAttribute('out-of-bounds');
- },
- }, {
- name: 'x',
- get(domNode) {
- return +domNode.getAttribute('x') || 0;
- },
- }, {
- name: 'y',
- get(domNode) {
- return +domNode.getAttribute('y') || 0;
- },
- }, {
- name: 'damping',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('damping'), 10);
- return !isNaN(value) ? value : 20;
- },
- }, {
- name: 'friction',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('friction'), 10);
- return !isNaN(value) ? value : 2;
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return !!domNode.getAttribute('disabled');
- },
- }, {
- name: 'scale',
- get(domNode) {
- return !!domNode.getAttribute('scale');
- },
- }, {
- name: 'scaleMin',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('scale-min'), 10);
- return !isNaN(value) ? value : 0.5;
- },
- }, {
- name: 'scaleMax',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('scale-max'), 10);
- return !isNaN(value) ? value : 10;
- },
- }, {
- name: 'scaleValue',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('scale-value'), 10);
- return !isNaN(value) ? value : 1;
- },
- }, {
- name: 'animation',
- get(domNode) {
- const value = domNode.getAttribute('animation');
- return value !== undefined ? !!value : true;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onMovableViewHtouchmove',
eventName: 'htouchmove'
@@ -90,17 +13,17 @@ export default {
name: 'onMovableViewChange',
eventName: 'change',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('x', evt.detail.x);
- domNode.__setAttributeWithoutUpdate('y', evt.detail.y);
+ domNode._setAttributeWithOutUpdate('x', evt.detail.x);
+ domNode._setAttributeWithOutUpdate('y', evt.detail.y);
}
},
{
name: 'onMovableViewScale',
eventName: 'scale',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('x', evt.detail.x);
- domNode.__setAttributeWithoutUpdate('y', evt.detail.y);
- domNode.__setAttributeWithoutUpdate('scale-value', evt.detail.scale);
+ domNode._setAttributeWithOutUpdate('x', evt.detail.x);
+ domNode._setAttributeWithOutUpdate('y', evt.detail.y);
+ domNode._setAttributeWithOutUpdate('scale-value', evt.detail.scale);
}
}
]
diff --git a/packages/miniapp-render/src/builtInComponents/navigator.js b/packages/miniapp-render/src/builtInComponents/navigator.js
index 0b7eb560fa..4547de2fb6 100644
--- a/packages/miniapp-render/src/builtInComponents/navigator.js
+++ b/packages/miniapp-render/src/builtInComponents/navigator.js
@@ -1,82 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isWeChatMiniProgram } from 'universal-env';
-
-let props = [{
- name: 'open-type',
- get(domNode) {
- return domNode.getAttribute('open-type') || 'navigate';
- },
-}, {
- name: 'hover-class',
- get(domNode) {
- return domNode.getAttribute('hover-class') || 'none';
- },
-}, {
- name: 'hover-start-time',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('hover-start-time'), 10);
- return !isNaN(value) ? value : 50;
- },
-}, {
- name: 'hover-stay-time',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('hover-stay-time'), 10);
- return !isNaN(value) ? value : 600;
- },
-}, {
- name: 'url',
- get(domNode) {
- return domNode.getAttribute('url') || '';
- },
-}, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
-}];
-if (isWeChatMiniProgram) {
- props = props.concat([{
- name: 'target',
- get(domNode) {
- return domNode.getAttribute('target') || 'self';
- },
- }, {
- name: 'delta',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('delta'), 10);
- return !isNaN(value) ? value : 1;
- },
- }, {
- name: 'app-id',
- get(domNode) {
- return domNode.getAttribute('app-id') || '';
- },
- }, {
- name: 'path',
- get(domNode) {
- return domNode.getAttribute('path') || '';
- },
- }, {
- name: 'extra-data',
- get(domNode) {
- return domNode.getAttribute('extra-data') || {};
- },
- }, {
- name: 'version',
- get(domNode) {
- return domNode.getAttribute('version') || 'release';
- },
- }, {
- name: 'hover-stop-propagation',
- get(domNode) {
- return !!domNode.getAttribute('hover-stop-propagation');
- },
- }]);
-}
-
export default {
name: 'navigator',
- props,
singleEvents: [{
name: 'onNavigatorSuccess',
eventName: 'success'
diff --git a/packages/miniapp-render/src/builtInComponents/picker-view-column.js b/packages/miniapp-render/src/builtInComponents/picker-view-column.js
index e05e95f5d9..0461c77f37 100644
--- a/packages/miniapp-render/src/builtInComponents/picker-view-column.js
+++ b/packages/miniapp-render/src/builtInComponents/picker-view-column.js
@@ -1,9 +1,3 @@
export default {
- name: 'picker-view-column',
- props: [{
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'picker-view-column'
};
diff --git a/packages/miniapp-render/src/builtInComponents/picker-view.js b/packages/miniapp-render/src/builtInComponents/picker-view.js
index 0a172f43a0..844ee356c6 100644
--- a/packages/miniapp-render/src/builtInComponents/picker-view.js
+++ b/packages/miniapp-render/src/builtInComponents/picker-view.js
@@ -1,39 +1,5 @@
export default {
name: 'picker-view',
- props: [{
- name: 'value',
- get(domNode) {
- let value = domNode.getAttribute('value');
- if (typeof value === 'string') value = value.split(',').map(item => parseInt(item, 10));
-
- return value !== undefined ? value : [];
- },
- }, {
- name: 'indicator-style',
- get(domNode) {
- return domNode.getAttribute('indicator-style') || '';
- },
- }, {
- name: 'indicator-class',
- get(domNode) {
- return domNode.getAttribute('indicator-class') || '';
- },
- }, {
- name: 'mask-style',
- get(domNode) {
- return domNode.getAttribute('mask-style') || '';
- },
- }, {
- name: 'mask-class',
- get(domNode) {
- return domNode.getAttribute('mask-class') || '';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onPickerViewPickstart',
eventName: 'pickstart'
@@ -47,7 +13,7 @@ export default {
name: 'onPickerViewChange',
eventName: 'change',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('value', evt.detail.value);
+ domNode._setAttributeWithOutUpdate('value', evt.detail.value);
}
}
]
diff --git a/packages/miniapp-render/src/builtInComponents/picker.js b/packages/miniapp-render/src/builtInComponents/picker.js
index c4e245b0d7..eec60ab8f2 100644
--- a/packages/miniapp-render/src/builtInComponents/picker.js
+++ b/packages/miniapp-render/src/builtInComponents/picker.js
@@ -3,52 +3,6 @@ import { isWeChatMiniProgram } from 'universal-env';
const picker = {
name: 'picker',
- props: [
- {
- name: 'disabled',
- get(domNode) {
- return !!domNode.getAttribute('disabled');
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'range',
- get(domNode) {
- const value = domNode.getAttribute('range');
- return value !== undefined ? value : [];
- },
- }, {
- name: 'range-key',
- get(domNode) {
- return domNode.getAttribute('range-key') || '';
- },
- }, {
- name: 'value',
- get(domNode) {
- const mode = domNode.getAttribute('mode') || 'selector';
- const value = domNode.getAttribute('value');
- if (mode === 'selector' || mode === 'multiSelector') {
- return +value || 0;
- } else if (mode === 'time') {
- return value || '';
- } else if (mode === 'date') {
- return value || '0';
- } else if (mode === 'region') {
- return value || [];
- }
-
- return value;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }
- ],
singleEvents: [{
name: 'onPickerCancel',
eventName: 'cancel'
@@ -58,41 +12,13 @@ const picker = {
name: 'onPickerChange',
eventName: 'change',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('value', evt.detail.value);
+ domNode._setAttributeWithOutUpdate('value', evt.detail.value);
}
}
]
};
if (isWeChatMiniProgram) {
- picker.props = picker.props.concat([
- {
- name: 'mode',
- get(domNode) {
- return domNode.getAttribute('mode') || 'selector';
- },
- }, {
- name: 'start',
- get(domNode) {
- return domNode.getAttribute('start') || '';
- },
- }, {
- name: 'end',
- get(domNode) {
- return domNode.getAttribute('end') || '';
- },
- }, {
- name: 'fields',
- get(domNode) {
- return domNode.getAttribute('fields') || 'day';
- },
- }, {
- name: 'customItem',
- get(domNode) {
- return domNode.getAttribute('custom-item') || '';
- }
- }
- ]);
picker.singleEvents.push({
name: 'onPickerColumnChange',
eventName: 'columnchange'
diff --git a/packages/miniapp-render/src/builtInComponents/progress.js b/packages/miniapp-render/src/builtInComponents/progress.js
index ec973579d1..a88e797a1a 100644
--- a/packages/miniapp-render/src/builtInComponents/progress.js
+++ b/packages/miniapp-render/src/builtInComponents/progress.js
@@ -1,61 +1,5 @@
export default {
name: 'progress',
- props: [{
- name: 'percent',
- get(domNode) {
- return +domNode.getAttribute('percent') || 0;
- },
- }, {
- name: 'showInfo',
- get(domNode) {
- return !!domNode.getAttribute('show-info');
- },
- }, {
- name: 'border-radius',
- get(domNode) {
- return domNode.getAttribute('border-radius') || '0';
- },
- }, {
- name: 'font-size',
- get(domNode) {
- return domNode.getAttribute('font-size') || '16';
- },
- }, {
- name: 'stroke-width',
- get(domNode) {
- return domNode.getAttribute('stroke-width') || '6';
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '#09BB07';
- },
- }, {
- name: 'active-color',
- get(domNode) {
- return domNode.getAttribute('active-color') || '#09BB07';
- },
- }, {
- name: 'background-color',
- get(domNode) {
- return domNode.getAttribute('background-color') || '#EBEBEB';
- },
- }, {
- name: 'active',
- get(domNode) {
- return !!domNode.getAttribute('active');
- },
- }, {
- name: 'active-mode',
- get(domNode) {
- return domNode.getAttribute('active-mode') || 'backwards';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onProgressActiveEnd',
eventName: 'activeend'
diff --git a/packages/miniapp-render/src/builtInComponents/radio-group.js b/packages/miniapp-render/src/builtInComponents/radio-group.js
index 9ef60035d4..f6c00d206e 100644
--- a/packages/miniapp-render/src/builtInComponents/radio-group.js
+++ b/packages/miniapp-render/src/builtInComponents/radio-group.js
@@ -1,11 +1,5 @@
export default {
name: 'radio-group',
- props: [{
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }],
singleEvents: [{
name: 'onRadioChange',
eventName: 'change'
diff --git a/packages/miniapp-render/src/builtInComponents/radio.js b/packages/miniapp-render/src/builtInComponents/radio.js
index 794b3c1db4..7405830723 100644
--- a/packages/miniapp-render/src/builtInComponents/radio.js
+++ b/packages/miniapp-render/src/builtInComponents/radio.js
@@ -1,31 +1,5 @@
export default {
name: 'radio',
- props: [{
- name: 'value',
- get(domNode) {
- return domNode.getAttribute('value') || '';
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'checked',
- get(domNode) {
- return domNode.getAttribute('checked') || false;
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return domNode.getAttribute('disabled') || false;
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '';
- },
- }],
singleEvents: [{
name: 'onRadioChange',
eventName: 'change'
diff --git a/packages/miniapp-render/src/builtInComponents/rich-text.js b/packages/miniapp-render/src/builtInComponents/rich-text.js
index 327f994ac1..61201a3ce3 100644
--- a/packages/miniapp-render/src/builtInComponents/rich-text.js
+++ b/packages/miniapp-render/src/builtInComponents/rich-text.js
@@ -1,22 +1,3 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isWeChatMiniProgram } from 'universal-env';
-
-const props = [{
- name: 'nodes',
- get(domNode) {
- return domNode.getAttribute('nodes') || [];
- },
-}];
-if (isWeChatMiniProgram) {
- props.push({
- name: 'space',
- get(domNode) {
- return domNode.getAttribute('space') || '';
- },
- });
-}
-
export default {
- name: 'rich-text',
- props
+ name: 'rich-text'
};
diff --git a/packages/miniapp-render/src/builtInComponents/scroll-view.js b/packages/miniapp-render/src/builtInComponents/scroll-view.js
index aae1b878eb..e9c7e6ead1 100644
--- a/packages/miniapp-render/src/builtInComponents/scroll-view.js
+++ b/packages/miniapp-render/src/builtInComponents/scroll-view.js
@@ -1,76 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isWeChatMiniProgram } from 'universal-env';
-
const ScrollView = {
name: 'scroll-view',
- props: [{
- name: 'scroll-x',
- get(domNode) {
- return !!domNode.getAttribute('scroll-x');
- },
- }, {
- name: 'scroll-y',
- get(domNode) {
- return !!domNode.getAttribute('scroll-y');
- },
- }, {
- name: 'upper-threshold',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('upper-threshold'), 10);
- return !isNaN(value) ? value : 50;
- },
- }, {
- name: 'lower-threshold',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('lower-threshold'), 10);
- return !isNaN(value) ? value : 50;
- },
- }, {
- name: 'scroll-top',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('scroll-top'), 10);
- if (Boolean(domNode.__scrollViewScrollTop) == value) {
- return '';
- }
- domNode.__scrollViewScrollTop = value;
- return !isNaN(value) ? value : '';
- },
- }, {
- name: 'scroll-left',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('scroll-left'), 10);
- if (Boolean(domNode.__scrollViewScrollLeft) == value) {
- return '';
- }
- domNode.__scrollViewScrollLeft = value;
- return !isNaN(value) ? value : '';
- },
- }, {
- name: 'scroll-into-view',
- get(domNode) {
- return domNode.getAttribute('scroll-into-view') || '';
- },
- }, {
- name: 'scroll-with-animation',
- get(domNode) {
- return !!domNode.getAttribute('scroll-with-animation');
- },
- }, {
- name: 'scroll-animation-duration',
- get(domNode) {
- return domNode.getAttribute('scroll-animation-duration');
- },
- }, {
- name: 'enable-back-to-top',
- get(domNode) {
- return !!domNode.getAttribute('enable-back-to-top');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onScrollViewScrollToUpper',
eventName: 'scrolltoupper'
@@ -84,66 +13,12 @@ const ScrollView = {
name: 'onScrollViewScroll',
eventName: 'scroll',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('scroll-into-view', '');
- domNode.__setAttributeWithoutUpdate('scroll-top', evt.detail.scrollTop);
- domNode.__setAttributeWithoutUpdate('scroll-left', evt.detail.scrollLeft);
+ domNode._setAttributeWithOutUpdate('scroll-into-view', '');
+ domNode._setAttributeWithOutUpdate('scroll-top', evt.detail.scrollTop);
+ domNode._setAttributeWithOutUpdate('scroll-left', evt.detail.scrollLeft);
}
}
]
};
-if (isWeChatMiniProgram) {
- ScrollView.props = ScrollView.props.concat([,
- {
- name: 'scroll-anchoring',
- get(domNode) {
- return !!domNode.getAttribute('scroll-anchoring');
- },
- }, {
- name: 'refresher-enabled',
- get(domNode) {
- return !!domNode.getAttribute('refresher-enabled');
- },
- }, {
- name: 'refresher-threshold',
- get(domNode) {
- return domNode.getAttribute('refresher-threshold') || '45';
- },
- }, {
- name: 'refresher-defaultStyle',
- get(domNode) {
- return domNode.getAttribute('refresher-default-style') || 'black';
- },
- }, {
- name: 'refresher-background',
- get(domNode) {
- return domNode.getAttribute('refresher-background') || '#FFF';
- },
- }, {
- name: 'refresher-triggered',
- get(domNode) {
- return !!domNode.getAttribute('refresher-triggered');
- },
- }
- ]);
- ScrollView.singleEvents = ScrollView.singleEvents.concat([
- {
- name: 'onScrollViewRefresherPulling',
- eventName: 'refresherpulling'
- },
- {
- name: 'onScrollViewRefresherRefresh',
- eventName: 'refresherrefresh'
- },
- {
- name: 'onScrollViewRefresherRestore',
- eventName: 'refresherrestore'
- },
- {
- name: 'onScrollViewRefresherAbort',
- eventName: 'refresherabort'
- }
- ]);
-}
-
export default ScrollView;
diff --git a/packages/miniapp-render/src/builtInComponents/slider.js b/packages/miniapp-render/src/builtInComponents/slider.js
index c17f1f4af6..24b900cdde 100644
--- a/packages/miniapp-render/src/builtInComponents/slider.js
+++ b/packages/miniapp-render/src/builtInComponents/slider.js
@@ -1,80 +1,5 @@
export default {
name: 'slider',
- props: [{
- name: 'min',
- get(domNode) {
- return +domNode.getAttribute('min') || 0;
- },
- }, {
- name: 'max',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('max'), 10);
- return !isNaN(value) ? value : 100;
- },
- }, {
- name: 'step',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('step'), 10);
- return !isNaN(value) ? value : 1;
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return !!domNode.getAttribute('disabled');
- },
- }, {
- name: 'value',
- canBeUserChanged: true,
- get(domNode) {
- return +domNode.getAttribute('value') || 0;
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '#e9e9e9';
- },
- }, {
- name: 'selected-color',
- get(domNode) {
- return domNode.getAttribute('selected-color') || '#1aad19';
- },
- }, {
- name: 'active-color',
- get(domNode) {
- return domNode.getAttribute('active-color') || '#1aad19';
- },
- }, {
- name: 'background-color',
- get(domNode) {
- return domNode.getAttribute('background-color') || '#e9e9e9';
- },
- }, {
- name: 'block-size',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('block-size'), 10);
- return !isNaN(value) ? value : 28;
- },
- }, {
- name: 'block-color',
- get(domNode) {
- return domNode.getAttribute('block-color') || '#ffffff';
- },
- }, {
- name: 'show-value',
- get(domNode) {
- return !!domNode.getAttribute('show-value');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onSliderChanging',
eventName: 'changing'
@@ -84,7 +9,7 @@ export default {
name: 'onSliderChange',
eventName: 'change',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('value', evt.detail.value);
+ domNode._setAttributeWithOutUpdate('value', evt.detail.value);
domNode.__oldValues = domNode.__oldValues || {};
domNode.__oldValues.value = evt.detail.value;
}
diff --git a/packages/miniapp-render/src/builtInComponents/swiper-item.js b/packages/miniapp-render/src/builtInComponents/swiper-item.js
index 74a14773ad..3a13dfb5f5 100644
--- a/packages/miniapp-render/src/builtInComponents/swiper-item.js
+++ b/packages/miniapp-render/src/builtInComponents/swiper-item.js
@@ -1,14 +1,3 @@
export default {
- name: 'swiper-item',
- props: [{
- name: 'item-id',
- get(domNode) {
- return domNode.getAttribute('item-id') || '';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'swiper-item'
};
diff --git a/packages/miniapp-render/src/builtInComponents/swiper.js b/packages/miniapp-render/src/builtInComponents/swiper.js
index 6275ee5c73..a3ca219903 100644
--- a/packages/miniapp-render/src/builtInComponents/swiper.js
+++ b/packages/miniapp-render/src/builtInComponents/swiper.js
@@ -3,85 +3,6 @@ import { isMiniApp, isWeChatMiniProgram } from 'universal-env';
const swiper = {
name: 'swiper',
- props: [{
- name: 'indicator-dots',
- get(domNode) {
- return !!domNode.getAttribute('indicator-dots');
- },
- }, {
- name: 'indicator-color',
- get(domNode) {
- return domNode.getAttribute('indicator-color') || 'rgba(0, 0, 0, .3)';
- },
- }, {
- name: 'indicator-active-color',
- get(domNode) {
- return domNode.getAttribute('indicator-active-color') || '#000000';
- },
- }, {
- name: 'autoplay',
- get(domNode) {
- return !!domNode.getAttribute('autoplay');
- },
- }, {
- name: 'current',
- get(domNode) {
- return +domNode.getAttribute('current') || 0;
- },
- }, {
- name: 'interval',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('interval'), 10);
- return !isNaN(value) ? value : 5000;
- },
- }, {
- name: 'duration',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('duration'), 10);
- return !isNaN(value) ? value : 500;
- },
- }, {
- name: 'circular',
- get(domNode) {
- return !!domNode.getAttribute('circular');
- },
- }, {
- name: 'vertical',
- get(domNode) {
- return !!domNode.getAttribute('vertical');
- },
- }, {
- name: 'previous-margin',
- get(domNode) {
- return domNode.getAttribute('previous-margin') || '0px';
- },
- }, {
- name: 'next-margin',
- get(domNode) {
- return domNode.getAttribute('next-margin') || '0px';
- },
- }, {
- name: 'display-multiple-items',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('display-multiple-items'), 10);
- return !isNaN(value) ? value : 1;
- },
- }, {
- name: 'skip-hidden-item-layout',
- get(domNode) {
- return !!domNode.getAttribute('skip-hidden-item-layout');
- },
- }, {
- name: 'easing-function',
- get(domNode) {
- return domNode.getAttribute('easing-function') || 'default';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onSwiperTransition',
eventName: 'transition'
@@ -91,7 +12,7 @@ const swiper = {
name: 'onSwiperChange',
eventName: 'change',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('current', evt.detail.current);
+ domNode._setAttributeWithOutUpdate('current', evt.detail.current);
}
}
]
diff --git a/packages/miniapp-render/src/builtInComponents/switch.js b/packages/miniapp-render/src/builtInComponents/switch.js
index 5944a5cd98..645b01b245 100644
--- a/packages/miniapp-render/src/builtInComponents/switch.js
+++ b/packages/miniapp-render/src/builtInComponents/switch.js
@@ -1,42 +1,11 @@
export default {
name: 'switch',
- props: [{
- name: 'checked',
- get(domNode) {
- return !!domNode.getAttribute('checked');
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return !!domNode.getAttribute('disabled');
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'type',
- get(domNode) {
- return domNode.getAttribute('type') || 'switch';
- },
- }, {
- name: 'color',
- get(domNode) {
- return domNode.getAttribute('color') || '#04BE02';
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
functionalSingleEvents: [
{
name: 'onSwitchChange',
eventName: 'change',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('checked', evt.detail.value);
+ domNode._setAttributeWithOutUpdate('checked', evt.detail.value);
}
}
]
diff --git a/packages/miniapp-render/src/builtInComponents/text.js b/packages/miniapp-render/src/builtInComponents/text.js
index 12ac28f252..8fc091d6a5 100644
--- a/packages/miniapp-render/src/builtInComponents/text.js
+++ b/packages/miniapp-render/src/builtInComponents/text.js
@@ -1,38 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isMiniApp } from 'universal-env';
-
const text = {
- name: 'text',
- props: [{
- name: 'selectable',
- get(domNode) {
- return !!domNode.getAttribute('selectable');
- },
- }, {
- name: 'space',
- get(domNode) {
- return domNode.getAttribute('space') || '';
- },
- }, {
- name: 'decode',
- get(domNode) {
- return !!domNode.getAttribute('decode');
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'text'
};
-if (isMiniApp) {
- text.props.push({
- name: 'number-of-lines',
- get(domNode) {
- return domNode.getAttribute('number-of-lines');
- }
- });
-}
-
export default text;
diff --git a/packages/miniapp-render/src/builtInComponents/textarea.js b/packages/miniapp-render/src/builtInComponents/textarea.js
index b21b38a375..2c252af85a 100644
--- a/packages/miniapp-render/src/builtInComponents/textarea.js
+++ b/packages/miniapp-render/src/builtInComponents/textarea.js
@@ -1,113 +1,5 @@
export default {
name: 'textarea',
- props: [{
- name: 'value',
- get(domNode) {
- return domNode.value || '';
- },
- }, {
- name: 'name',
- get(domNode) {
- return domNode.getAttribute('name') || '';
- },
- }, {
- name: 'placeholder',
- get(domNode) {
- return domNode.placeholder;
- },
- }, {
- name: 'placeholder-style',
- get(domNode) {
- let style = domNode.getAttribute('placeholder-style') || '';
- // Compatible with placeholderColor attribute of rax-textinput
- const color = domNode.getAttribute('placeholderColor');
- if (color) {
- style = 'color:' + color + ';' + style;
- }
- return style;
- }
- }, {
- name: 'placeholder-class',
- get(domNode) {
- return domNode.getAttribute('placeholder-class');
- },
- }, {
- name: 'disabled',
- get(domNode) {
- return domNode.disabled || domNode.readOnly;
- },
- }, {
- name: 'maxlength',
- get(domNode) {
- const value = parseInt(domNode.maxlength, 10);
- return !isNaN(value) ? value : 140;
- }
- }, {
- name: 'focus-state',
- get(domNode) {
- return !!domNode.getAttribute('autofocus');
- },
- }, {
- name: 'focus-state',
- get(domNode) {
- return !!(domNode.getAttribute('autofocus') || domNode.getAttribute('focus-state'));
- },
- }, {
- name: 'auto-height',
- get(domNode) {
- return !!domNode.getAttribute('auto-height');
- },
- }, {
- name: 'fixed',
- get(domNode) {
- return !!domNode.getAttribute('fixed');
- },
- }, {
- name: 'cursor-spacing',
- get(domNode) {
- return +domNode.getAttribute('cursor-spacing') || 0;
- },
- }, {
- name: 'cursor',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('cursor'), 10);
- return !isNaN(value) ? value : -1;
- },
- }, {
- name: 'show-confirm-bar',
- get(domNode) {
- const value = domNode.getAttribute('show-confirm-bar');
- return value !== undefined ? !!value : true;
- },
- }, {
- name: 'selection-start',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('selection-start'), 10);
- return !isNaN(value) ? value : -1;
- },
- }, {
- name: 'selection-end',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('selection-end'), 10);
- return !isNaN(value) ? value : -1;
- },
- }, {
- name: 'adjust-position',
- get(domNode) {
- const value = domNode.getAttribute('adjust-position');
- return value !== undefined ? !!value : true;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }, {
- name: 'controlled',
- get(domNode) {
- return !!domNode.getAttribute('controlled');
- },
- }],
singleEvents: [{
name: 'keyboardheightchange',
eventName: 'keyboardheightchange'
@@ -121,7 +13,7 @@ export default {
eventName: 'input',
middleware(evt, domNode, pageId, nodeId) {
domNode.__textareaOldValue = domNode.value || '';
- domNode.__setAttributeWithoutUpdate('focus-state', true);
+ domNode._setAttributeWithOutUpdate('focus-state', true);
this.callSimpleEvent('focus', evt, domNode);
}
},
@@ -129,10 +21,10 @@ export default {
name: 'onTextareaBlur',
eventName: 'blur',
middleware(evt, domNode, pageId, nodeId) {
- domNode.__setAttributeWithoutUpdate('focus-state', false);
+ domNode._setAttributeWithOutUpdate('focus-state', false);
if (domNode.__textareaOldValue !== undefined && domNode.value !== domNode.__textareaOldValue) {
domNode.__textareaOldValue = undefined;
- this.callEvent('change', evt, pageId, nodeId);
+ this.callEvent('change', evt, null, pageId, nodeId);
}
this.callSimpleEvent('blur', evt, domNode);
}
@@ -142,7 +34,7 @@ export default {
eventName: 'input',
middleware(evt, domNode, pageId, nodeId) {
const value = '' + evt.detail.value;
- domNode.__setAttributeWithoutUpdate('value', value);
+ domNode._setAttributeWithOutUpdate('value', value);
this.callEvent('input', evt, null, pageId, nodeId);
}
diff --git a/packages/miniapp-render/src/builtInComponents/video.js b/packages/miniapp-render/src/builtInComponents/video.js
index fe6f55f84f..2781f9534f 100644
--- a/packages/miniapp-render/src/builtInComponents/video.js
+++ b/packages/miniapp-render/src/builtInComponents/video.js
@@ -1,174 +1,5 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isMiniApp } from 'universal-env';
-
-let props = [{
- name: 'src',
- get(domNode) {
- return domNode.src;
- },
-}, {
- name: 'duration',
- get(domNode) {
- return +domNode.getAttribute('duration') || 0;
- },
-}, {
- name: 'controls',
- get(domNode) {
- return domNode.controls;
- },
-}, {
- name: 'danmu-list',
- get(domNode) {
- const value = domNode.getAttribute('danmu-list');
- return value !== undefined ? value : [];
- },
-}, {
- name: 'danmu-btn',
- get(domNode) {
- return !!domNode.getAttribute('danmu-btn');
- },
-}, {
- name: 'enable-danmu',
- get(domNode) {
- return !!domNode.getAttribute('enable-danmu');
- },
-}, {
- name: 'autoplay',
- get(domNode) {
- return domNode.autoplay;
- },
-}, {
- name: 'loop',
- get(domNode) {
- return domNode.loop;
- },
-}, {
- name: 'muted',
- get(domNode) {
- return domNode.muted;
- },
-}, {
- name: 'initial-time',
- get(domNode) {
- return +domNode.getAttribute('initial-time') || 0;
- },
-}, {
- name: 'direction',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('direction'), 10);
- return !isNaN(value) ? value : -1;
- },
-}, {
- name: 'show-progress',
- get(domNode) {
- const value = domNode.getAttribute('show-progress');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'show-fullscreen-btn',
- get(domNode) {
- const value = domNode.getAttribute('show-fullscreen-btn');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'show-play-btn',
- get(domNode) {
- const value = domNode.getAttribute('show-play-btn');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'show-center-play-btn',
- get(domNode) {
- const value = domNode.getAttribute('show-center-play-btn');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'enable-progress-gesture',
- get(domNode) {
- const value = domNode.getAttribute('enable-progress-gesture');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'object-fit',
- get(domNode) {
- return domNode.getAttribute('object-fit') || 'contain';
- },
-}, {
- name: 'poster',
- get(domNode) {
- return domNode.poster;
- },
-}, {
- name: 'show-mute-btn',
- get(domNode) {
- return !!domNode.getAttribute('show-mute-btn');
- },
-}, {
- name: 'title',
- get(domNode) {
- return domNode.getAttribute('title') || '';
- },
-}, {
- name: 'play-btn-position',
- get(domNode) {
- return domNode.getAttribute('play-btn-position') || 'bottom';
- },
-}, {
- name: 'enable-play-gesture',
- get(domNode) {
- return !!domNode.getAttribute('enable-play-gesture');
- },
-}, {
- name: 'auto-pause-if-navigate',
- get(domNode) {
- const value = domNode.getAttribute('auto-pause-if-navigate');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'auto-pause-if-open-native',
- get(domNode) {
- const value = domNode.getAttribute('auto-pause-if-open-native');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'vslide-gesture',
- get(domNode) {
- return !!domNode.getAttribute('vslide-gesture');
- },
-}, {
- name: 'vslide-gesture-in-fullscreen',
- get(domNode) {
- const value = domNode.getAttribute('vslide-gesture-in-fullscreen');
- return value !== undefined ? !!value : true;
- },
-}, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
-}];
-
-if (isMiniApp) {
- props = props.concat([{
- name: 'enableNative',
- get(domNode) {
- return !!domNode.getAttribute('enableNative');
- }
- }, {
- name: 'playsinline',
- get(domNode) {
- return !!domNode.getAttribute('playsinline');
- }
- }, {
- name: 'rawControls',
- get(domNode) {
- return !!domNode.getAttribute('rawControls');
- }
- }]);
-}
export default {
name: 'video',
- props,
singleEvents: [{
name: 'onVideoPlay',
eventName: 'play'
@@ -198,14 +29,14 @@ export default {
name: 'onVideoTimeUpdate',
eventName: 'timeupdate',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('currentTime', evt.detail.currentTime);
+ domNode._setAttributeWithOutUpdate('currentTime', evt.detail.currentTime);
}
},
{
name: 'onVideoProgress',
eventName: 'progress',
middleware(evt, domNode) {
- domNode.__setAttributeWithoutUpdate('buffered', evt.detail.buffered);
+ domNode._setAttributeWithOutUpdate('buffered', evt.detail.buffered);
}
}
]
diff --git a/packages/miniapp-render/src/builtInComponents/view.js b/packages/miniapp-render/src/builtInComponents/view.js
index 0ca56fd87e..40b3812ba9 100644
--- a/packages/miniapp-render/src/builtInComponents/view.js
+++ b/packages/miniapp-render/src/builtInComponents/view.js
@@ -2,44 +2,10 @@
import { isMiniApp } from 'universal-env';
const view = {
- name: 'view',
- props: [{
- name: 'hover-class',
- get(domNode) {
- return domNode.getAttribute('hover-class') || 'none';
- },
- }, {
- name: 'hover-stop-propagation',
- get(domNode) {
- return !!domNode.getAttribute('hover-stop-propagation');
- },
- }, {
- name: 'hover-start-time',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('hover-start-time'), 10);
- return !isNaN(value) ? value : 50;
- },
- }, {
- name: 'hover-stay-time',
- get(domNode) {
- const value = parseInt(domNode.getAttribute('hover-stay-time'), 10);
- return !isNaN(value) ? value : 400;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }]
+ name: 'view'
};
if (isMiniApp) {
- view.props.push({
- name: 'disable-scroll',
- get(domNode) {
- return !!domNode.getAttribute('disable-scroll');
- },
- });
view.simpleEvents = [{
name: 'onViewAppear',
eventName: 'appear'
diff --git a/packages/miniapp-render/src/builtInComponents/web-view.js b/packages/miniapp-render/src/builtInComponents/web-view.js
index 4a7191be43..67123ea3ef 100644
--- a/packages/miniapp-render/src/builtInComponents/web-view.js
+++ b/packages/miniapp-render/src/builtInComponents/web-view.js
@@ -1,16 +1,5 @@
export default {
name: 'web-view',
- props: [{
- name: 'src',
- get(domNode) {
- return domNode.src;
- },
- }, {
- name: 'animation',
- get(domNode) {
- return domNode.getAttribute('animation');
- }
- }],
singleEvents: [{
name: 'onWebviewMessage',
eventName: 'message'
diff --git a/packages/miniapp-render/src/constants.js b/packages/miniapp-render/src/constants.js
index 16dc2157d6..ba1b3bce48 100644
--- a/packages/miniapp-render/src/constants.js
+++ b/packages/miniapp-render/src/constants.js
@@ -10,3 +10,16 @@ export const NATIVE_EVENTS_LIST = [
'beforeTabItemTap',
'onResize'
];
+
+export const BUILTIN_COMPONENT_LIST = new Set([
+ 'movable-view', 'cover-image', 'cover-view', 'movable-area', 'scroll-view', 'swiper', 'swiper-item', 'view',
+ 'icon', 'progress', 'rich-text', 'text',
+ 'button', 'checkbox', 'checkbox-group', 'editor', 'form', 'input', 'label', 'picker', 'picker-view', 'picker-view-column', 'radio', 'radio-group', 'slider', 'switch', 'textarea',
+ 'functional-page-navigator', 'navigator',
+ 'audio', 'camera', 'image', 'live-player', 'live-pusher', 'video',
+ 'map',
+ 'canvas',
+ 'ad', 'official-account', 'open-data', 'web-view'
+]);
+
+export const BODY_NODE_ID = 'e-body';
diff --git a/packages/miniapp-render/src/createConfig/element.js b/packages/miniapp-render/src/createConfig/element.js
index c6564ca76d..4cfd3611c1 100644
--- a/packages/miniapp-render/src/createConfig/element.js
+++ b/packages/miniapp-render/src/createConfig/element.js
@@ -26,12 +26,16 @@ export default function() {
}
},
options: {
- styleIsolation: 'shared'
+ styleIsolation: 'shared',
+ virtualHost: true
},
methods: createEventProxy(),
...getComponentLifeCycle({
mount() {
cache.setElementInstance(this);
+ const window = cache.getWindow();
+ const node = cache.getNode(window.__pageId, this.properties.r.nodeId);
+ node._internal = this;
}
})
};
diff --git a/packages/miniapp-render/src/createConfig/page.js b/packages/miniapp-render/src/createConfig/page.js
index 51dd9405d7..d942267378 100644
--- a/packages/miniapp-render/src/createConfig/page.js
+++ b/packages/miniapp-render/src/createConfig/page.js
@@ -5,6 +5,7 @@ import perf from '../utils/perf';
import createDocument from '../document';
// eslint-disable-next-line import/no-extraneous-dependencies
import { isMiniApp } from 'universal-env';
+import { BODY_NODE_ID } from '../constants';
export function getBaseLifeCycles(route) {
return {
@@ -44,43 +45,6 @@ export function getBaseLifeCycles(route) {
}
this.renderInfo.setDocument(this.document);
this.renderInfo.render();
- // Handle update of body
- this.document.body.addEventListener('render', (...tasks) => {
- if (tasks.length > 0) {
- if (this.$batchedUpdates) {
- let callback;
- this.$batchedUpdates(() => {
- tasks.forEach((task, index) => {
- if (index === tasks.length - 1) {
- callback = () => {
- if (process.env.NODE_ENV === 'development') {
- perf.stop('setData');
- }
- };
- this.firstRenderCallback();
- }
- if (task.type === 'children') {
- const spliceArgs = [task.start, task.deleteCount];
- this.$spliceData({
- [task.path]: task.item ? spliceArgs.concat(task.item) : spliceArgs
- }, callback);
- } else {
- this.setData({
- [task.path]: task.value
- }, callback);
- }
- });
- });
- } else {
- this.firstRenderCallback(tasks[0]);
- this.setData(tasks[0], () => {
- if (process.env.NODE_ENV === 'development') {
- perf.stop('setData');
- }
- });
- }
- }
- });
this.window.$$trigger('DOMContentLoaded');
},
@@ -108,7 +72,7 @@ export function getBaseLifeCycles(route) {
this.window.$$trigger('pageunload');
this.document.__unmount && this.document.__unmount(); // Manually unmount component instance
- this.document.body.$$recycle(); // Recycle DOM node
+ this.document.body.$$destroy();
cache.destroy(this.pageId);
@@ -125,6 +89,8 @@ export default function(route, lifeCycles = []) {
firstRender: true,
data: {
root: {
+ nodeId: BODY_NODE_ID,
+ nodeType: 'h-element',
children: []
}
},
diff --git a/packages/miniapp-render/src/document.js b/packages/miniapp-render/src/document.js
index b8a70d5c38..a733de0ad9 100755
--- a/packages/miniapp-render/src/document.js
+++ b/packages/miniapp-render/src/document.js
@@ -1,98 +1,43 @@
import EventTarget from './event/event-target';
-import Tree from './tree/tree';
import Node from './node/node';
import Element from './node/element';
import TextNode from './node/text-node';
import Comment from './node/comment';
-import tool from './utils/tool';
import cache from './utils/cache';
import Image from './node/element/image';
import Input from './node/element/input';
import Textarea from './node/element/textarea';
import Video from './node/element/video';
-import BuiltInComponent from './node/element/builtin-component';
import CustomComponent from './node/element/custom-component';
+import RootElement from './node/root';
+import { BODY_NODE_ID } from './constants';
-const CONSTRUCTOR_MAP = {
- IMG: Image,
- INPUT: Input,
- TEXTAREA: Textarea,
- VIDEO: Video,
- 'BUILTIN-COMPONENT': BuiltInComponent,
-};
-const BUILTIN_COMPONENT_LIST = [
- 'movable-view', 'cover-image', 'cover-view', 'movable-area', 'scroll-view', 'swiper', 'swiper-item', 'view',
- 'icon', 'progress', 'rich-text', 'text',
- 'button', 'checkbox', 'checkbox-group', 'editor', 'form', 'input', 'label', 'picker', 'picker-view', 'picker-view-column', 'radio', 'radio-group', 'slider', 'switch', 'textarea',
- 'functional-page-navigator', 'navigator',
- 'audio', 'camera', 'image', 'live-player', 'live-pusher', 'video',
- 'map',
- 'canvas',
- 'ad', 'official-account', 'open-data', 'web-view'
-];
-
-/**
- * Check this component is builtIn component
- * @param {string} tagName - component tag name
- * @return {boolean}
- */
-function checkIsBuiltInComponent(tagName) {
- return BUILTIN_COMPONENT_LIST.indexOf(tagName) > -1;
-}
+const CONSTRUCTOR_MAP = new Map([['img', Image], ['input', Input], ['textarea', Textarea], ['video', Video]]);
class Document extends EventTarget {
- constructor(pageId, nodeIdMap) {
+ constructor(pageId) {
super();
const { usingComponents = {}, usingPlugins = {} } = cache.getConfig();
this.usingComponents = usingComponents;
this.usingPlugins = usingPlugins;
- this.__pageId = pageId;
-
- // Used to encapsulate special tag and corresponding constructors
- const that = this;
- this.$_imageConstructor = function HTMLImageElement(width, height) {
- return Image.$$create({
- tagName: 'img',
- nodeId: `b-${tool.getId()}`,
- attrs: {},
- width,
- height,
- }, that.$_tree);
- };
+ this.__nodeIdMap = new Map();
+ this.__idMap = new Map();
this.__pageId = pageId;
- this.$_tree = new Tree(pageId, {
+
+ this.__root = new RootElement({
type: 'element',
tagName: 'body',
attrs: {},
- unary: false,
- nodeId: 'e-body',
children: [],
- }, nodeIdMap, this);
- this.$_config = null;
-
- // documentElement
- this.$_node = this.$$createElement({
- tagName: 'html',
- attrs: {},
- nodeId: `a-${tool.getId()}`,
- type: Node.DOCUMENT_NODE,
+ document: this,
});
- // documentElement's parentNode is document
- this.$_node.$$updateParent(this);
- this.$_node.scrollTop = 0;
- // head
- this.$_head = this.createElement('head');
+ this.__nodeIdMap.set(BODY_NODE_ID, this.__root);
// update body's parentNode
- this.$_tree.root.$$updateParent(this.$_node);
- }
-
- // Image constructor
- get $$imageConstructor() {
- return this.$_imageConstructor;
+ this.__root.parentNode = this;
}
// Event trigger
@@ -100,47 +45,30 @@ class Document extends EventTarget {
this.documentElement.$$trigger(eventName, options);
}
- $$createElement(options, tree) {
- const originTagName = options.tagName;
- const tagName = originTagName.toUpperCase();
- const componentName = checkIsBuiltInComponent(originTagName) ? originTagName : null;
- tree = tree || this.$_tree;
-
- const constructorClass = CONSTRUCTOR_MAP[tagName];
- if (constructorClass) {
- return constructorClass.$$create(options, tree);
- } else if (componentName) {
- // Transform to builtin-component
- options.tagName = 'builtin-component';
- options.attrs = options.attrs || {};
- options.attrs._behavior = componentName;
- return BuiltInComponent.$$create(options, tree);
- } else if (this.usingComponents[originTagName]) {
- // Transform to custom-component
- options.tagName = 'custom-component';
- options.attrs = options.attrs || {};
- options.componentName = originTagName;
- return CustomComponent.$$create(options, tree);
- } else if (this.usingPlugins[originTagName]) {
- options.tagName = 'miniapp-plugin';
- options.attrs = options.attrs || {};
- options.componentName = originTagName;
- return CustomComponent.$$create(options, tree);
- } if (!tool.isTagNameSupport(tagName)) {
- throw new Error(`${tagName} is not supported.`);
- } else {
- return Element.$$create(options, tree);
- }
+ _isRendered() {
+ return true;
}
- // Create text node
- $$createTextNode(options, tree) {
- return TextNode.$$create(options, tree || this.$_tree);
- }
+ _createElement(options) {
+ const ConstructorClass = CONSTRUCTOR_MAP.get(options.tagName);
+ if (ConstructorClass) {
+ return new ConstructorClass(options);
+ }
- // Create comment node
- $$createComment(options, tree) {
- return Comment.$$create(options, tree || this.$_tree);
+ options.attrs = options.attrs || {};
+
+ if (options.attrs.__native) {
+ if (this.usingComponents[options.tagName]) {
+ // Transform to custom-component
+ options.nativeType = 'customComponent';
+ return new CustomComponent(options);
+ } else if (this.usingPlugins[options.tagName]) {
+ options.nativeType = 'miniappPlugin';
+ return new CustomComponent(options);
+ }
+ } else {
+ return new Element(options);
+ }
}
// Node type
@@ -149,21 +77,17 @@ class Document extends EventTarget {
}
get documentElement() {
- return this.$_node;
+ return this.body;
}
get body() {
- return this.$_tree.root;
+ return this.__root;
}
get nodeName() {
return '#document';
}
- get head() {
- return this.$_head;
- }
-
get defaultView() {
return cache.getWindow() || null;
}
@@ -171,42 +95,71 @@ class Document extends EventTarget {
getElementById(id) {
if (typeof id !== 'string') return;
- return this.$_tree.getById(id) || null;
+ const element = this.__idMap.get(id);
+ if (element && element._isRendered()) {
+ return element;
+ }
+ return null;
}
getElementsByTagName(tagName) {
if (typeof tagName !== 'string') return [];
- return this.$_tree.getByTagName(tagName);
+ const elements = [];
+ this.__nodeIdMap.forEach((element, nodeId) => {
+ if (element && element.__tagName === tagName && element._isRendered()) {
+ elements.push(element);
+ }
+ });
+ return elements;
}
getElementsByClassName(className) {
if (typeof className !== 'string') return [];
- return this.$_tree.getByClassName(className);
+ const elements = [];
+ this.__nodeIdMap.forEach((element, nodeId) => {
+ const classNames = className.trim().split(/\s+/);
+ if (element && classNames.every(c => element.classList && element.classList.contains(c))) {
+ elements.push(element);
+ }
+ });
+ return elements;
}
querySelector(selector) {
if (typeof selector !== 'string') return;
- return this.$_tree.query(selector)[0] || null;
+ if (selector[0] === '.') {
+ const elements = this.getElementsByClassName(selector.slice(1));
+ return elements.length > 0 ? elements[0] : null;
+ } else if (selector[0] === '#') {
+ return this.getElementById(selector.slice(1));
+ } else if (/^[a-zA-Z]/.test(selector)) {
+ const elements = this.getElementsByTagName(selector);
+ return elements.length > 0 ? elements[0] : null;
+ }
+ return null;
}
querySelectorAll(selector) {
if (typeof selector !== 'string') return [];
- return this.$_tree.query(selector);
+ if (selector[0] === '.') {
+ return this.getElementsByClassName(selector.slice(1));
+ } else if (selector[0] === '#') {
+ const element = this.getElementById(selector.slice(1));
+ return element ? [element] : [];
+ } else if (/^[a-zA-Z]/.test(selector)) {
+ return this.getElementsByTagName(selector);
+ }
+ return null;
}
createElement(tagName) {
- if (typeof tagName !== 'string') return;
-
- tagName = tagName.trim();
- if (!tagName) return;
-
- return this.$$createElement({
- tagName,
- nodeId: `b-${tool.getId()}`,
+ return this._createElement({
+ document: this,
+ tagName
});
}
@@ -218,25 +171,25 @@ class Document extends EventTarget {
createTextNode(content) {
content = '' + content;
- return this.$$createTextNode({
+ return new TextNode({
content,
- nodeId: `b-${tool.getId()}`,
+ document: this
});
}
- createComment() {
- // Ignore the incoming comment content
- return this.$$createComment({
- nodeId: `b-${tool.getId()}`,
+ createComment(data) {
+ return new Comment({
+ document: this,
+ data
});
}
createDocumentFragment() {
- return Element.$$create({
+ return new Element({
tagName: 'documentfragment',
- nodeId: `b-${tool.getId()}`,
nodeType: Node.DOCUMENT_FRAGMENT_NODE,
- }, this.$_tree);
+ document: this
+ });
}
createEvent() {
@@ -259,12 +212,10 @@ class Document extends EventTarget {
}
export default function createDocument(pageId) {
- const nodeIdMap = {};
- const document = new Document(pageId, nodeIdMap);
+ const document = new Document(pageId);
cache.init(pageId, {
- document,
- nodeIdMap
+ document
});
return document;
diff --git a/packages/miniapp-render/src/event/event-target.js b/packages/miniapp-render/src/event/event-target.js
index 7a9384662c..f168a16c54 100755
--- a/packages/miniapp-render/src/event/event-target.js
+++ b/packages/miniapp-render/src/event/event-target.js
@@ -71,10 +71,6 @@ function compareEventInWechat(last, now) {
class EventTarget {
constructor(...args) {
- this.$$init(...args);
- }
-
- $$init() {
// Supplement the instance's properties for the 'XXX' in XXX judgment
this.ontouchstart = null;
this.ontouchmove = null;
@@ -87,7 +83,7 @@ class EventTarget {
// Logs the triggered miniapp events
this.$_miniappEvent = null;
- this.$_eventHandlerMap = null;
+ this.__eventHandlerMap = new Map();
}
// Destroy instance
@@ -101,16 +97,7 @@ class EventTarget {
});
this.$_miniappEvent = null;
- this.$_eventHandlerMap = null;
- }
-
- set $_eventHandlerMap(value) {
- this.$__eventHandlerMap = value;
- }
-
- get $_eventHandlerMap() {
- if (!this.$__eventHandlerMap) this.$__eventHandlerMap = Object.create(null);
- return this.$__eventHandlerMap;
+ this.__eventHandlerMap = null;
}
// Trigger event capture, bubble flow
@@ -128,16 +115,11 @@ class EventTarget {
const path = [target];
let parentNode = target.parentNode;
- while (parentNode && parentNode.tagName !== 'HTML') {
+ while (parentNode && parentNode.ownerDocument) {
path.push(parentNode);
parentNode = parentNode.parentNode;
}
- if (path[path.length - 1].tagName === 'BODY') {
- // If the last node is document.body, the document.documentelement is appended
- path.push(parentNode);
- }
-
if (!event) {
// Special handling here, not directly return the applet's event object
event = new Event({
@@ -216,20 +198,22 @@ class EventTarget {
// Get handlers
__getHandles(eventName, isCapture, isInit) {
- const handlerMap = this.$_eventHandlerMap;
const pageId = this.__pageId || 'app';
- if (!handlerMap[pageId]) {
- handlerMap[pageId] = {};
+ if (!this.__eventHandlerMap.get(pageId)) {
+ this.__eventHandlerMap.set(pageId, new Map());
}
if (isInit) {
- const handlerObj = handlerMap[pageId][eventName] = handlerMap[pageId][eventName] || {};
+ let handlerObj = this.__eventHandlerMap.get(pageId).get(eventName);
+ if (!handlerObj) {
+ this.__eventHandlerMap.get(pageId).set(eventName, handlerObj = {});
+ }
handlerObj.capture = handlerObj.capture || [];
handlerObj.bubble = handlerObj.bubble || [];
return isCapture ? handlerObj.capture : handlerObj.bubble;
} else {
- const handlerObj = handlerMap[pageId][eventName];
+ const handlerObj = this.__eventHandlerMap.get(pageId).get(eventName);
if (!handlerObj) return null;
diff --git a/packages/miniapp-render/src/node/attribute.js b/packages/miniapp-render/src/node/attribute.js
index c4041291a8..988a6fcc97 100755
--- a/packages/miniapp-render/src/node/attribute.js
+++ b/packages/miniapp-render/src/node/attribute.js
@@ -1,165 +1,90 @@
import tool from '../utils/tool';
class Attribute {
- constructor(element, onUpdate) {
- this.$$init(element, onUpdate);
+ constructor(element) {
+ this.__element = element;
+ this.__value = {};
}
- static $$create(element, onUpdate) {
- return new Attribute(element, onUpdate);
- }
-
- $$init(element, onUpdate) {
- this.$_element = element;
- this.$_doUpdate = onUpdate;
- this.$_map = {};
- this.$_list = [];
-
- this.triggerUpdate();
- }
-
- $$destroy() {
- this.$_element = null;
- this.$_doUpdate = null;
- this.$_map = null;
- this.$_list = null;
- }
-
- $$recycle() {
- this.$$destroy();
- }
-
- get list() {
- return this.$_list;
+ _setWithOutUpdate(name, value) {
+ this.__value[name] = value;
+ if (name === 'style') {
+ this.__element.style.cssText = value;
+ } else if (name.indexOf('data-') === 0) {
+ const datasetName = tool.toCamel(name.substr(5));
+ this.__element.dataset[datasetName] = value;
+ }
}
set(name, value, immediate = true) {
- const element = this.$_element;
- const map = this.$_map;
+ const element = this.__element;
+ this.__value[name] = value;
- if (name === 'id') {
- map.id = value;
- } else if (name === 'class' || element.tagName === 'BUILTIN-COMPONENT' && name === 'className') {
- element.className = value;
- } else if (name === 'style') {
+ if (name === 'style') {
element.style.cssText = value;
} else if (name.indexOf('data-') === 0) {
const datasetName = tool.toCamel(name.substr(5));
element.dataset[datasetName] = value;
} else {
- map[name] = value;
-
const payload = {
- path: `${this.$_element._path}.${name}`,
+ path: `${element._path}.${name}`,
value: value
};
- this.$_doUpdate(payload, immediate);
+ element._triggerUpdate(payload, immediate);
}
-
- this.triggerUpdate();
}
get(name) {
- const element = this.$_element;
- const map = this.$_map;
-
- if (name === 'id') {
- return map.id || '';
- } if (name === 'class') {
- return element.className;
- } else if (name === 'style') {
- return element.style.cssText;
+ const element = this.__element;
+ if (name === 'style') {
+ return element.style.cssText || null;
} else if (name.indexOf('data-') === 0) {
const datasetName = tool.toCamel(name.substr(5));
- if (!element.$__dataset) return undefined;
return element.dataset[datasetName];
- } else {
- return map[name];
}
+ return this.__value[name] || null;
}
- has(name) {
- const element = this.$_element;
- const map = this.$_map;
-
- if (name === 'id') {
- return !!element.id;
- } else if (name === 'class') {
- return !!element.className;
- } else if (name === 'style') {
- return !!element.style.cssText;
- } else if (name.indexOf('data-') === 0) {
- const datasetName = tool.toCamel(name.substr(5));
- if (!element.$__dataset) return false;
- return Object.prototype.hasOwnProperty.call(element.dataset, datasetName);
- } else {
- return Object.prototype.hasOwnProperty.call(map, name);
- }
+ get style() {
+ return this.__element.style.cssText || undefined;
}
- remove(name) {
- const element = this.$_element;
- const map = this.$_map;
-
- if (name === 'id') {
- element.id = '';
- } else if (name === 'class' || name === 'style') {
- this.set(name, '');
- } else if (name.indexOf('data-') === 0) {
- const datasetName = tool.toCamel(name.substr(5));
- if (element.$__dataset) delete element.dataset[datasetName];
- } else {
- // The Settings for the other fields need to trigger the parent component to update
- delete map[name];
- const payload = {
- path: `${this.$_element._path}.${name}`,
- value: ''
- };
- this.$_doUpdate(payload);
- }
+ get class() {
+ return this.__value.class || undefined;
+ }
- this.triggerUpdate();
+ get id() {
+ return this.__value.id || undefined;
}
- triggerUpdate() {
- const map = this.$_map;
- const list = this.$_list;
+ get src() {
+ return this.__value.src || undefined;
+ }
- // Empty the old list
- list.forEach(item => {
- delete list[item.name];
- });
- delete list.class;
- delete list.style;
- list.length = 0;
+ has(name) {
+ return Object.prototype.hasOwnProperty.call(this.__value, name);
+ }
- // Add a new list
- Object.keys(map).forEach(name => {
- if (name !== 'id') {
- const item = {name, value: map[name]};
+ remove(name) {
+ const element = this.__element;
+ delete this.__value[name];
+ delete this[name];
- list.push(item);
- list[name] = item;
+ if (name === 'style') {
+ element.style.cssText = '';
+ } else if (name === 'id') {
+ element.id = '';
+ } else {
+ if (name.indexOf('data-') === 0) {
+ const datasetName = tool.toCamel(name.substr(5));
+ delete element.dataset[datasetName];
+ } else {
+ const payload = {
+ path: `${element._path}.${name}`,
+ value: ''
+ };
+ element._triggerUpdate(payload);
}
- });
-
- const idValue = this.get('id');
- const classValue = this.get('class');
- const styleValue = this.get('style');
- if (idValue) {
- const item = {name: 'id', value: idValue};
- list.push(item);
- list.id = item;
- }
- if (classValue) {
- const item = {name: 'class', value: classValue};
- list.push(item);
- list.class = item;
- }
- if (styleValue) {
- const item = {name: 'style', value: styleValue};
- list.push(item);
- list.style = item;
}
}
}
diff --git a/packages/miniapp-render/src/node/class-list.js b/packages/miniapp-render/src/node/class-list.js
index 96fa2e3403..72ad738023 100755
--- a/packages/miniapp-render/src/node/class-list.js
+++ b/packages/miniapp-render/src/node/class-list.js
@@ -1,127 +1,73 @@
-function ClassList(element, onUpdate) {
- this.$$init(element, onUpdate);
-}
-
-ClassList.$$create = function(element, onUpdate) {
- return new ClassList(element, onUpdate);
-};
-
-ClassList.prototype = Object.assign([], {
- $$init(element, onUpdate) {
- this.$_element = element;
- this.$_doUpdate = onUpdate;
- },
-
- $$destroy() {
- this.$_element = null;
- this.$_doUpdate = null;
- this.length = 0;
- },
-
- $$recycle() {
- this.$$destroy();
- },
-
- $$parse(className = '') {
- this.length = 0;
-
- className = className.trim();
- className = className ? className.split(/\s+/) : [];
-
- for (const item of className) {
- this.push(item);
- }
-
- const payload = {
- path: `${this.$_element._path}.className`,
- value: this.slice().join(' ')
- };
-
- this.$_doUpdate(payload);
- },
-
- item(index) {
- return this[index];
- },
-
- contains(className) {
- if (typeof className !== 'string') return false;
-
- return this.indexOf(className) !== -1;
- },
-
- add(...args) {
- let isUpdate = false;
-
- for (let className of args) {
- if (typeof className !== 'string') continue;
-
- className = className.trim();
-
- if (className && this.indexOf(className) === -1) {
- this.push(className);
- isUpdate = true;
- }
+export default class ClassList extends Set {
+ static _create(className, element) {
+ const instance = new Set();
+ instance.__proto__ = ClassList.prototype;
+ instance.__element = element;
+ className.trim().split(/\s+/).forEach((s) => s !== '' && instance.add(s));
+ return instance;
+ }
+
+ get value() {
+ const classArray = [];
+ this.forEach(item => classArray.push(item));
+ return classArray.join(' ');
+ }
+ add(s) {
+ if (typeof s === 'string' && s !== '') {
+ super.add(s);
+ this._update();
}
- if (isUpdate) {
- const payload = {
- path: `${this.$_element._path}.className`,
- value: this.slice().join(' ')
- };
- this.$_doUpdate(payload);
- }
- },
+ return this;
+ }
- remove(...args) {
- let isUpdate = false;
+ remove(s) {
+ super.delete(s);
+ this._update();
+ }
- for (let className of args) {
- if (typeof className !== 'string') continue;
+ replace(s1, s2) {
+ super.delete(s1);
+ super.add(s2);
- className = className.trim();
+ this._update();
+ }
- if (!className) continue;
+ contains(s) {
+ return this.has(s);
+ }
- const index = this.indexOf(className);
- if (index >= 0) {
- this.splice(index, 1);
- isUpdate = true;
+ item(index) {
+ let count = 0;
+ for (let i of this) {
+ if (count === index) {
+ return i;
}
+ count ++;
}
+ return undefined;
+ }
- if (isUpdate) {
- const payload = {
- path: `${this.$_element._path}.className`,
- value: this.slice().join(' ')
- };
- this.$_doUpdate(payload);
+ toggle(token, force) {
+ if (force !== undefined) {
+ force === true ? this.add(token) : this.remove(token);
+ return force;
}
- },
-
- toggle(className, force) {
- if (typeof className !== 'string') return false;
-
- className = className.trim();
-
- if (!className) return false;
- const isNotContain = this.indexOf(className) === -1;
- let action = isNotContain ? 'add' : 'remove';
- action = force === true ? 'add' : force === false ? 'remove' : action;
-
- if (action === 'add') {
- this.add(className);
+ if (this.has(token)) {
+ this.remove(token);
+ return false;
} else {
- this.remove(className);
+ this.add(token);
+ return true;
}
-
- return force === true || force === false ? force : isNotContain;
- },
+ }
toString() {
- return this.join(' ');
- },
-});
+ return this.value;
+ }
-export default ClassList;
+ _update() {
+ this.__element.className = this.value;
+ }
+}
diff --git a/packages/miniapp-render/src/node/comment.js b/packages/miniapp-render/src/node/comment.js
index 4dc7217803..d3ab999657 100755
--- a/packages/miniapp-render/src/node/comment.js
+++ b/packages/miniapp-render/src/node/comment.js
@@ -1,26 +1,15 @@
-import tool from '../utils/tool';
import Node from './node';
class Comment extends Node {
- static $$create(options, tree) {
- return new Comment(options, tree);
- }
-
- $$init(options, tree) {
+ constructor(options) {
options.type = 'comment';
-
- super.$$init(options, tree);
- }
-
- $$recycle() {
- this.$$destroy();
+ super(options);
+ this.data = options.data;
}
- get $$domInfo() {
+ get _renderInfo() {
return {
- nodeId: this.$_nodeId,
- pageId: this.__pageId,
- nodeType: this.$_type,
+ nodeType: 'h-' + this.$_type,
};
}
@@ -33,8 +22,8 @@ class Comment extends Node {
}
cloneNode() {
- return this.ownerDocument.$$createComment({
- nodeId: `b-${tool.getId()}`,
+ return this.ownerDocument.createComment({
+ data: this.data
});
}
}
diff --git a/packages/miniapp-render/src/node/element.js b/packages/miniapp-render/src/node/element.js
index bb6c5b2e09..b64ea6e4a7 100755
--- a/packages/miniapp-render/src/node/element.js
+++ b/packages/miniapp-render/src/node/element.js
@@ -5,333 +5,103 @@ import Style from './style';
import Attribute from './attribute';
import cache from '../utils/cache';
import tool from '../utils/tool';
-import parser from '../tree/parser';
+import { simplifyDomTree, traverse } from '../utils/tree';
+import { BUILTIN_COMPONENT_LIST } from '../constants';
class Element extends Node {
- static $$create(options, tree) {
- return new Element(options, tree);
- }
-
- // Override the $$init method of the parent class
- $$init(options, tree) {
+ constructor(options) {
options.type = 'element';
- super.$$init(options, tree);
-
- this.$_tagName = options.tagName || '';
- this.$_children = [];
- this.$_nodeType = options.nodeType || Node.ELEMENT_NODE;
- this.$_unary = !!parser.voidMap[this.$_tagName.toLowerCase()];
- this.$_dataset = null;
- this.$_classList = null;
- this.$_style = null;
- this.$_attrs = null;
-
- this.$_initAttrs(options.attrs);
+ super(options);
+
+ this.__tagName = options.tagName || '';
+ this.__isBuiltinComponent = BUILTIN_COMPONENT_LIST.has(this.__tagName);
+ this.__tmplName = this.__isBuiltinComponent ? this.__tagName : 'h-element';
+ this.childNodes = [];
+ this.__nodeType = options.nodeType || Node.ELEMENT_NODE;
+ this.style = new Style(this);
+ this.__attrs = new Attribute(this);
+ cache.setNode(this.__pageId, this.__nodeId, this);
+ this.dataset = {};
+ this.ownerDocument.__nodeIdMap.set(this.__nodeId, this);
+ if (this.id) {
+ this.ownerDocument.__idMap.set(this.id, this);
+ }
- this.onclick = null;
- this.ontouchstart = null;
- this.ontouchmove = null;
- this.ontouchend = null;
- this.ontouchcancel = null;
- this.onload = null;
- this.onerror = null;
+ this._initAttributes(options.attrs);
}
// Override the $$destroy method of the parent class
$$destroy() {
+ this.childNodes.forEach(child => child.$$destroy());
+ cache.setNode(this.__pageId, this.__nodeId, null);
+ this.ownerDocument.__nodeIdMap.set(this.__nodeId, null);
+ this.ownerDocument.__idMap.set(this.id, null);
super.$$destroy();
-
- this.$_tagName = '';
- this.$_children.length = 0;
- this.$_nodeType = Node.ELEMENT_NODE;
- this.$_unary = null;
- this.$_dataset = null;
- this.$_classList = null;
- this.$_style = null;
- this.$_attrs = null;
- }
-
- // Recycling instance
- $$recycle() {
- this.$_children.forEach(child => child.$$recycle());
- this.$$destroy();
- }
-
- set $_dataset(value) {
- this.$__dataset = value;
- }
-
- get $_dataset() {
- if (!this.$__dataset) this.$__dataset = Object.create(null);
- return this.$__dataset;
- }
-
- set $_classList(value) {
- if (!value && this.$__classList) this.$__classList.$$recycle();
- this.$__classList = value;
- }
-
- get $_classList() {
- if (!this.$__classList) this.$__classList = ClassList.$$create(this, this.$_onClassOrStyleUpdate.bind(this));
- return this.$__classList;
- }
-
- set $_style(value) {
- if (!value && this.$__style) this.$__style.$$recycle();
- this.$__style = value;
- }
-
- get $_style() {
- if (!this.$__style) this.$__style = Style.$$create(this, this.$_onClassOrStyleUpdate.bind(this));
- return this.$__style;
- }
-
- set $_attrs(value) {
- if (!value && this.$__attrs) this.$__attrs.$$recycle();
- this.$__attrs = value;
- }
-
- get $_attrs() {
- if (!this.$__attrs) this.$__attrs = Attribute.$$create(this, this._triggerUpdate.bind(this));
- return this.$__attrs;
+ this.__tagName = '';
+ this.childNodes.length = 0;
+ this.__nodeType = Node.ELEMENT_NODE;
+ this.__attrs = null;
}
// Init attribute
- $_initAttrs(attrs = {}) {
- // Avoid create $_attrs when component init
- const attrKeys = Object.keys(attrs);
- if (!attrKeys.length) return;
-
- attrKeys.forEach(name => {
- if (name.indexOf('data-') === 0) {
- // dataset
- const datasetName = tool.toCamel(name.substr(5));
- this.$_dataset[datasetName] = attrs[name];
- } else {
- // Other attributes
- this.__setAttributeWithoutUpdate(name, attrs[name]);
- }
+ _initAttributes(attrs = {}) {
+ Object.keys(attrs).forEach(name => {
+ this._setAttributeWithOutUpdate(name, attrs[name]);
});
}
- // Listen for class or style attribute values to change
- $_onClassOrStyleUpdate(payload) {
- if (this.$__attrs) this.$_attrs.triggerUpdate();
- this._triggerUpdate(payload);
- }
-
_triggerUpdate(payload, immediate = true) {
- if (!this.__notTriggerUpdate) {
+ if (immediate) {
this.enqueueRender(payload);
- } else if (!immediate && this._root) {
- this._root.renderStacks.push(payload);
- }
- }
-
- _traverseNodeMap(node, isRemove) {
- let queue = [];
- queue.push(node);
- while (queue.length) {
- let curNode = queue.shift();
- this._updateNodeMap(curNode, isRemove);
- if (curNode.childNodes && curNode.childNodes.length) {
- queue = queue.concat(curNode.childNodes);
- }
- }
- }
- // Changes to the mapping table caused by changes to update child nodes
- _updateNodeMap(node, isRemove) {
- const id = node.id;
-
- // Update nodeId - dom map
- if (isRemove) {
- cache.setNode(this.__pageId, node.$$nodeId, null);
} else {
- cache.setNode(this.__pageId, node.$$nodeId, node);
- }
-
- // Update id - dom map
- if (id) {
- if (isRemove) {
- this.$_tree.updateIdMap(id, null);
- } else {
- this.$_tree.updateIdMap(id, node);
- }
- }
- }
-
- // Traverse the dom tree to generate the HTML
- $_generateHtml(node) {
- if (node.nodeType === Node.TEXT_NODE) {
- // Text node
- return node.textContent;
- } else if (node.nodeType === Node.ELEMENT_NODE) {
- // Element
- const tagName = node.tagName.toLowerCase();
- let html = `<${tagName}`;
-
- // Attribute
- if (node.id) html += ` id="${node.id}"`;
- if (node.className) html += ` class="${node.className}"`;
-
- const styleText = node.style.cssText;
- if (styleText) html += ` style="${styleText}"`;
-
- const src = node.src;
- if (src) html += ` src=${src}`;
-
- const animation = node.animation;
- if (node.animation) html += `animation=${animation}`;
-
- const dataset = node.dataset;
- Object.keys(dataset).forEach(name => {
- html += ` data-${tool.toDash(name)}="${dataset[name]}"`;
- });
-
- html = this.$$dealWithAttrsForGenerateHtml(html, node);
-
- if (node.$$isUnary) {
- // Empty tag
- return `${html} />`;
- } else {
- const childrenHtml = node.childNodes.map(child => this.$_generateHtml(child)).join('');
- return `${html}>${childrenHtml}${tagName}>`;
- }
- }
- }
-
- // Traverse the ast to generate the dom tree
- $_generateDomTree(node) {
- const {
- type,
- tagName = '',
- attrs = [],
- children = [],
- content = '',
- } = node;
-
- // generated at runtime, using the b- prefix
- const nodeId = `b-${tool.getId()}`;
-
- if (type === 'element') {
- // Element
- const attrsMap = {};
-
- // The property list is converted to a map
- for (const attr of attrs) {
- const name = attr.name;
- let value = attr.value;
-
- if (name === 'style') value = value && value.replace('"', '\'') || '';
-
- attrsMap[name] = value;
- }
-
- const element = this.ownerDocument.$$createElement({
- tagName, attrs: attrsMap, nodeId
- });
-
- for (let child of children) {
- child = this.$_generateDomTree(child);
-
- if (child) element.appendChild(child);
- }
-
- return element;
- } else if (type === 'text') {
- // Text node
- return this.ownerDocument.$$createTextNode({
- content: tool.decodeContent(content), nodeId
- });
+ this._root.renderStacks.push(payload);
}
}
- // Dom info
- get $$domInfo() {
+ get _renderInfo() {
return {
- nodeId: this.$$nodeId,
+ nodeId: this.__nodeId,
pageId: this.__pageId,
- nodeType: this.$_type,
- tagName: this.$_tagName,
- id: this.id,
- className: this.className,
- style: this.$__style ? this.style.cssText : '',
- animation: this.$__attrs ? this.$__attrs.get('animation') : {},
- slot: this.$__attrs ? this.$__attrs.get('slot') : null,
+ nodeType: this.__tmplName,
+ ...this.__attrs.__value,
+ style: this.style.cssText,
+ class: this.__isBuiltinComponent ? this.className : `h5-${this.__tagName} ${this.className}`,
};
}
- // Check Empty tag
- get $$isUnary() {
- return this.$_unary;
- }
-
- // The $_generateHtml interface is called to handle additional attributes
- $$dealWithAttrsForGenerateHtml(html) {
- // The concrete implementation logic is implemented by subclasses
- return html;
- }
-
- // The setter for outerHTML is called to handle the extra properties
- $$dealWithAttrsForOuterHTML() {
- }
-
// The cloneNode interface is called to process additional properties
- $$dealWithAttrsForCloneNode() {
+ _dealWithAttrsForCloneNode() {
return {};
}
// Sets properties, but does not trigger updates
- __setAttributeWithoutUpdate(name, value) {
- this.__notTriggerUpdate = true;
- this.setAttribute(name, value, false);
- this.__notTriggerUpdate = false;
+ _setAttributeWithOutUpdate(name, value) {
+ this.__attrs._setWithOutUpdate(name, value);
}
get id() {
- if (!this.$__attrs) return '';
-
- return this.$_attrs.get('id');
+ return this.__attrs.get('id') || '';
}
set id(id) {
- if (typeof id !== 'string') return;
-
- id = id.trim();
- const oldId = this.$_attrs.get('id');
- this.$_attrs.set('id', id);
-
- if (id === oldId) return;
-
- // update tree
- if (this.$_tree.getById(oldId) === this) this.$_tree.updateIdMap(oldId, null);
- if (id) this.$_tree.updateIdMap(id, this);
- const payload = {
- path: `${this._path}.id`,
- value: id
- };
- this._triggerUpdate(payload);
+ this.setAttribute('id', id);
}
get tagName() {
- return this.$_tagName.toUpperCase();
+ return this.__tagName.toUpperCase();
}
get className() {
- if (!this.$__classList) return '';
-
- return this.$_classList.toString();
+ return this.getAttribute('class') || '';
}
set className(className) {
- if (typeof className !== 'string') return;
-
- this.$_classList.$$parse(className);
+ this.setAttribute('class', className);
}
get classList() {
- return this.$_classList;
+ return ClassList._create(this.className, this);
}
get nodeName() {
@@ -339,107 +109,19 @@ class Element extends Node {
}
get nodeType() {
- return this.$_nodeType;
- }
-
- get childNodes() {
- return this.$_children;
+ return this.__nodeType;
}
get children() {
- return this.$_children.filter(child => child.nodeType === Node.ELEMENT_NODE);
+ return this.childNodes.filter(child => child.nodeType === Node.ELEMENT_NODE);
}
get firstChild() {
- return this.$_children[0];
+ return this.childNodes[0];
}
get lastChild() {
- return this.$_children[this.$_children.length - 1];
- }
-
- get innerHTML() {
- return this.$_children.map(child => this.$_generateHtml(child)).join('');
- }
-
- set innerHTML(html) {
- if (typeof html !== 'string') return;
-
- // parse to ast
- let ast = null;
- try {
- ast = parser.parse(html);
- } catch (err) {
- console.error(err);
- }
-
- if (!ast) return;
-
- // Generate dom tree
- const newChildNodes = [];
- ast.forEach(item => {
- const node = this.$_generateDomTree(item);
- if (node) newChildNodes.push(node);
- });
-
- // Delete all child nodes
- this.$_children.forEach(node => {
- node.$$updateParent(null);
-
- // Update the mapping table
- this._traverseNodeMap(node, true);
- });
- this.$_children.length = 0;
-
- // Append the new child nodes
- for (let i = 0, j = newChildNodes.length; i < j; i++) {
- this.appendChild(newChildNodes[i]);
- }
- }
-
- get outerHTML() {
- return this.$_generateHtml(this);
- }
-
- set outerHTML(html) {
- if (typeof html !== 'string') return;
-
- // Resolve to ast, taking only the first as the current node
- let ast = null;
- try {
- ast = parser.parse(html)[0];
- } catch (err) {
- console.error(err);
- }
-
- if (ast) {
- // Generate dom tree
- const node = this.$_generateDomTree(ast);
-
- // Delete all child nodes
- this.$_children.forEach(node => {
- node.$$updateParent(null);
-
- // Update the mapping table
- this._traverseNodeMap(node, true);
- });
- this.$_children.length = 0;
-
- // Append new child nodes
- const children = [].concat(node.childNodes);
- for (const child of children) {
- this.appendChild(child);
- }
-
- this.$_tagName = node.tagName.toLowerCase();
- this.id = node.id || '';
- this.className = node.className || '';
- this.style.cssText = node.style.cssText || '';
- this.src = node.src || '';
- this.$_dataset = Object.assign({}, node.dataset);
-
- this.$$dealWithAttrsForOuterHTML(node);
- }
+ return this.childNodes[this.childNodes.length - 1];
}
get innerText() {
@@ -452,75 +134,52 @@ class Element extends Node {
}
get textContent() {
- return this.$_children.map(child => child.textContent).join('');
+ return this.childNodes.map(child => child.textContent).join('');
}
set textContent(text) {
text = '' + text;
- // Delete all child nodes
- this.$_children.forEach(node => {
- node.$$updateParent(null);
-
- // Update mapping table
- this._traverseNodeMap(node, true);
- });
-
// An empty string does not add a textNode node
if (!text) {
const payload = {
type: 'children',
path: `${this._path}.children`,
start: 0,
- deleteCount: this.$_children.length
+ deleteCount: this.childNodes.length
};
- this.$_children.length = 0;
+ this.childNodes.length = 0;
this._triggerUpdate(payload);
} else {
- this.$_children.length = 0;
- // Generated at run time, using the b- prefix
- const nodeId = `b-${tool.getId()}`;
- const child = this.ownerDocument.$$createTextNode({content: text, nodeId});
+ this.childNodes.length = 0;
+ const child = this.ownerDocument.createTextNode(text);
this.appendChild(child);
}
}
- get style() {
- return this.$_style;
- }
-
- set style(value) {
- this.$_style.cssText = value;
- }
-
- get dataset() {
- return this.$_dataset;
- }
-
get attributes() {
- return this.$_attrs.list;
+ return this.__attrs;
}
get src() {
- if (!this.$__attrs) return '';
+ if (!this.__attrs) return '';
- return this.$_attrs.get('src');
+ return this.__attrs.get('src') || undefined;
}
set src(value) {
value = '' + value;
- this.$_attrs.set('src', value);
+ this.__attrs.set('src', value);
}
cloneNode(deep) {
const dataset = {};
- Object.keys(this.$_dataset).forEach(name => {
- dataset[`data-${tool.toDash(name)}`] = this.$_dataset[name];
+ Object.keys(this.dataset).forEach(name => {
+ dataset[`data-${tool.toDash(name)}`] = this.dataset[name];
});
-
- const newNode = this.ownerDocument.$$createElement({
- tagName: this.$_tagName,
+ const newNode = this.ownerDocument._createElement({
+ tagName: this.__tagName,
attrs: {
id: this.id,
class: this.className,
@@ -528,15 +187,15 @@ class Element extends Node {
src: this.src,
...dataset,
- ...this.$$dealWithAttrsForCloneNode(),
+ ...this._dealWithAttrsForCloneNode(),
},
- nodeType: this.$_nodeType,
- nodeId: `b-${tool.getId()}`,
+ document: this.ownerDocument,
+ nodeType: this.__nodeType
});
if (deep) {
// Deep clone
- for (const child of this.$_children) {
+ for (const child of this.childNodes) {
newNode.appendChild(child.cloneNode(deep));
}
}
@@ -545,27 +204,25 @@ class Element extends Node {
}
appendChild(node) {
- if (!(node instanceof Node)) return;
-
if (node === this) return;
if (node.parentNode) node.parentNode.removeChild(node);
- this.$_children.push(node);
+ this.childNodes.push(node);
// Set parentNode
- node.$$updateParent(this);
-
- // Update map
- this._traverseNodeMap(node);
-
- // Trigger update
- const payload = {
- type: 'children',
- path: `${this._path}.children`,
- start: this.$_children.length - 1,
- deleteCount: 0,
- item: node
- };
- this._triggerUpdate(payload);
+ node.parentNode = this;
+
+ if (this._isRendered()) {
+ node.__rendered = true;
+ // Trigger update
+ const payload = {
+ type: 'children',
+ path: `${this._path}.children`,
+ start: this.childNodes.length - 1,
+ deleteCount: 0,
+ item: simplifyDomTree(node)
+ };
+ this._triggerUpdate(payload);
+ }
return this;
}
@@ -573,25 +230,25 @@ class Element extends Node {
removeChild(node) {
if (!(node instanceof Node)) return;
- const index = this.$_children.indexOf(node);
+ const index = this.childNodes.indexOf(node);
if (index >= 0) {
// Inserted, need to delete
- this.$_children.splice(index, 1);
-
- node.$$updateParent(null);
-
- // Update map
- this._traverseNodeMap(node, true);
-
- // Trigger update
- const payload = {
- type: 'children',
- path: `${this._path}.children`,
- start: index,
- deleteCount: 1
- };
- this._triggerUpdate(payload);
+ this.childNodes.splice(index, 1);
+ node.parentNode = null;
+ node.__rendered = false;
+
+ if (this._isRendered()) {
+ node.__rendered = false;
+ // Trigger update
+ const payload = {
+ type: 'children',
+ path: `${this._path}.children`,
+ start: index,
+ deleteCount: 1
+ };
+ this._triggerUpdate(payload);
+ }
}
return node;
@@ -604,29 +261,29 @@ class Element extends Node {
if (node === this) return;
if (node.parentNode) node.parentNode.removeChild(node);
- const insertIndex = ref ? this.$_children.indexOf(ref) : -1;
- const payload = {
- type: 'children',
- path: `${this._path}.children`,
- deleteCount: 0,
- item: node
- };
+ // Set parentNode
+ node.parentNode = this;
+ const insertIndex = ref ? this.childNodes.indexOf(ref) : -1;
if (insertIndex === -1) {
// Insert to the end
- this.$_children.push(node);
- payload.start = this.$_children.length - 1;
+ this.childNodes.push(node);
} else {
// Inserted before ref
- this.$_children.splice(insertIndex, 0, node);
- payload.start = insertIndex;
+ this.childNodes.splice(insertIndex, 0, node);
}
- // Set parentNode
- node.$$updateParent(this);
+ if (this._isRendered()) {
+ node.__rendered = true;
+ const payload = {
+ type: 'children',
+ path: `${this._path}.children`,
+ deleteCount: 0,
+ item: simplifyDomTree(node),
+ start: insertIndex === -1 ? this.childNodes.length - 1 : insertIndex
+ };
- // Update the mapping table
- this._traverseNodeMap(node);
- // Trigger update
- this._triggerUpdate(payload);
+ // Trigger update
+ this._triggerUpdate(payload);
+ }
return node;
}
@@ -634,99 +291,115 @@ class Element extends Node {
replaceChild(node, old) {
if (!(node instanceof Node) || !(old instanceof Node)) return;
- const replaceIndex = this.$_children.indexOf(old);
- if (replaceIndex !== -1) this.$_children.splice(replaceIndex, 1);
+ const replaceIndex = this.childNodes.indexOf(old);
+ if (replaceIndex !== -1) this.childNodes.splice(replaceIndex, 1);
if (node === this) return;
if (node.parentNode) node.parentNode.removeChild(node);
if (replaceIndex === -1) {
// Insert to the end
- this.$_children.push(node);
+ this.childNodes.push(node);
} else {
// Replace to old
- this.$_children.splice(replaceIndex, 0, node);
+ this.childNodes.splice(replaceIndex, 0, node);
}
// Set parentNode
- node.$$updateParent(this);
- // Update the mapping table
- this._traverseNodeMap(node);
- this._traverseNodeMap(old, true);
-
- // Trigger update
- const payload = {
- type: 'children',
- path: `${this._path}.children`,
- start: replaceIndex === -1 ? this.$_children.length - 1 : replaceIndex,
- deleteCount: replaceIndex === -1 ? 0 : 1,
- item: node
- };
- this._triggerUpdate(payload);
+ node.parentNode = this;
+
+ if (this._isRendered()) {
+ node.__rendered = true;
+ // Trigger update
+ const payload = {
+ type: 'children',
+ path: `${this._path}.children`,
+ start: replaceIndex === -1 ? this.childNodes.length - 1 : replaceIndex,
+ deleteCount: replaceIndex === -1 ? 0 : 1,
+ item: simplifyDomTree(node)
+ };
+ this._triggerUpdate(payload);
+ }
return old;
}
hasChildNodes() {
- return this.$_children.length > 0;
+ return this.childNodes.length > 0;
}
getElementsByTagName(tagName) {
if (typeof tagName !== 'string') return [];
-
- return this.$_tree.getByTagName(tagName, this);
+ const elements = [];
+ traverse(this, element => {
+ if (element !== this && element && element.__tagName === tagName) {
+ elements.push(element);
+ }
+ return {};
+ });
+ return elements;
}
getElementsByClassName(className) {
if (typeof className !== 'string') return [];
-
- return this.$_tree.getByClassName(className, this);
+ const elements = [];
+ traverse(this, element => {
+ const classNames = className.trim().split(/\s+/);
+ if (element !== this && element && classNames.every(c => element.classList && element.classList.contains(c))) {
+ elements.push(element);
+ }
+ return {};
+ });
+ return elements;
}
querySelector(selector) {
- if (typeof selector !== 'string') return;
-
- return this.$_tree.query(selector, this)[0] || null;
+ if (selector[0] === '.') {
+ const elements = this.getElementsByClassName(selector.slice(1));
+ return elements.length > 0 ? elements[0] : null;
+ } else if (selector[0] === '#') {
+ return this.ownerDocument.getElementById(selector.slice(1));
+ } else if (/^[a-zA-Z]/.test(selector)) {
+ const elements = this.getElementsByTagName(selector);
+ return elements.length > 0 ? elements[0] : null;
+ }
+ return null;
}
querySelectorAll(selector) {
if (typeof selector !== 'string') return [];
- return this.$_tree.query(selector, this);
+ if (selector[0] === '.') {
+ return this.getElementsByClassName(selector.slice(1));
+ } else if (selector[0] === '#') {
+ const element = this.ownerDocument.getElementById(selector.slice(1));
+ return element ? [element] : [];
+ } else if (/^[a-zA-Z]/.test(selector)) {
+ return this.getElementsByTagName(selector);
+ }
+ return null;
}
setAttribute(name, value, immediate = true) {
- if (typeof name !== 'string') return;
-
- // preserve the original contents of the object/Array/boolean/undefined to facilitate the use of the built-in components of miniapp
- const valueType = typeof value;
- if (valueType !== 'object' && valueType !== 'boolean' && value !== undefined && !Array.isArray(value)) value = '' + value;
-
- if (name === 'id') {
- // id to be handled here in advance
- this.id = value;
- } else {
- this.$_attrs.set(name, value, immediate);
+ if (name === 'id' && value !== this.id) {
+ this.ownerDocument.__idMap.delete(this.id);
+ this.ownerDocument.__idMap.set(value, this);
}
+ this.__attrs.set(name, value, immediate);
}
getAttribute(name) {
- if (typeof name !== 'string') return '';
- if (!this.$__attrs) return name === 'id' || name === 'style' || name === 'class' ? '' : undefined;
-
- return this.$_attrs.get(name);
+ return this.__attrs.get(name);
}
hasAttribute(name) {
- if (typeof name !== 'string') return false;
- if (!this.$__attrs) return false;
-
- return this.$_attrs.has(name);
+ if (name === 'style' || name === 'id') {
+ return !!this.getAttribute(name);
+ }
+ return this.__attrs.has(name);
}
removeAttribute(name) {
- if (typeof name !== 'string') return false;
-
- return this.$_attrs.remove(name);
+ return this.__attrs.remove(name);
}
contains(otherElement) {
@@ -746,9 +419,6 @@ class Element extends Node {
}
enqueueRender(payload) {
- if (this._root === null) {
- return;
- }
this._root.enqueueRender(payload);
}
diff --git a/packages/miniapp-render/src/node/element/builtin-component.js b/packages/miniapp-render/src/node/element/builtin-component.js
deleted file mode 100755
index 6a3e42b0d6..0000000000
--- a/packages/miniapp-render/src/node/element/builtin-component.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import Element from '../element';
-import cache from '../../utils/cache';
-
-class BuiltInComponent extends Element {
- // Create instance
- static $$create(options, tree) {
- return new BuiltInComponent(options, tree);
- }
-
- // Override the parent class's recovery instance method
- $$recycle() {
- this.$$destroy();
- }
-
- get _behavior() {
- return this.$_attrs.get('_behavior') || '';
- }
-
- set _behavior(value) {
- if (typeof value !== 'string') return;
-
- this.$_attrs.set('_behavior', value);
- }
-
-
- get scrollTop() {
- return this.$_attrs.get('scroll-top') || 0;
- }
-
- set scrollTop(value) {
- value = parseInt(value, 10);
-
- if (!isNaN(value)) {
- this.$_attrs.set('scroll-top', value);
- }
- }
-
- get scrollLeft() {
- return this.$_attrs.get('scroll-left') || 0;
- }
-
- set scrollLeft(value) {
- value = parseInt(value, 10);
-
- if (!isNaN(value)) {
- this.$_attrs.set('scroll-left', value);
- }
- }
-}
-
-export default BuiltInComponent;
diff --git a/packages/miniapp-render/src/node/element/custom-component.js b/packages/miniapp-render/src/node/element/custom-component.js
index dbbe6ebb7a..c2b6456624 100755
--- a/packages/miniapp-render/src/node/element/custom-component.js
+++ b/packages/miniapp-render/src/node/element/custom-component.js
@@ -3,78 +3,45 @@ import cache from '../../utils/cache';
import tool from '../../utils/tool';
class CustomComponent extends Element {
- // Create instance
- static $$create(options, tree) {
- return new CustomComponent(options, tree);
- }
-
- $$init(options, tree) {
- this.__behavior = options.componentName;
- this.__nativeType = options.tagName === 'custom-component' ? 'customComponent' : 'miniappPlugin';
- super.$$init(options, tree);
+ constructor(options) {
+ super(options);
+ this.__nativeType = options.nativeType;
}
$$destroy() {
super.$$destroy();
- this.__behavior = null;
- }
-
- $$recycle() {
- this.$$destroy();
- }
-
- get _behavior() {
- return this.__behavior;
+ this.__nativeType = null;
}
- get $$domInfo() {
- const domInfo = {
- nodeId: this.$$nodeId,
+ get _renderInfo() {
+ const renderInfo = {
+ nodeId: this.__nodeId,
pageId: this.__pageId,
- nodeType: this.$_type,
- tagName: this.$_tagName,
- id: this.id,
- className: this.className,
- style: this.$__style ? this.style.cssText : '',
- animation: this.$__attrs ? this.$__attrs.get('animation') : {}
+ nodeType: this.__tagName,
+ style: this.style.cssText,
+ class: this.className,
+ ...this.__attrs.__value
};
const config = cache.getConfig();
let nativeInfo = null;
if (this.__nativeType === 'customComponent') {
- domInfo.customComponentName = this.__behavior;
- nativeInfo = config.usingComponents[this.__behavior];
+ nativeInfo = config.usingComponents[this.__tagName];
} else if (this.__nativeType === 'miniappPlugin') {
- domInfo.miniappPluginName = this.__behavior;
- nativeInfo = config.usingPlugins[this.__behavior];
+ nativeInfo = config.usingPlugins[this.__tagName];
}
if (nativeInfo) {
- // Inject props scanned by babel plugin into domInfo
- nativeInfo.props.forEach(prop => {
- domInfo[prop] = domInfo[prop] || this.$_attrs && this.$__attrs.get(prop);
- });
// Bind methods to every element which is used recursively to generate dom tree
nativeInfo.events.forEach(event => {
- const eventName = `${this.__behavior}_${event}_${tool.getId()}`;
- domInfo[event] = eventName;
+ const eventName = `${this.__tagName}_${event}_${tool.getId()}`;
+ renderInfo[event] = eventName;
cache.setElementMethods(eventName, (...args) => {
this.$$trigger(event, { args });
});
});
}
- return domInfo;
- }
-
- setAttribute(name, value, immediate = true) {
- if (typeof name !== 'string') return;
-
- if (name === 'id') {
- // id to be handled here in advance
- this.id = value;
- } else {
- this.$_attrs.set(name, value, immediate);
- }
+ return renderInfo;
}
}
diff --git a/packages/miniapp-render/src/node/element/image.js b/packages/miniapp-render/src/node/element/image.js
index 870e6883af..45d81f041a 100755
--- a/packages/miniapp-render/src/node/element/image.js
+++ b/packages/miniapp-render/src/node/element/image.js
@@ -3,20 +3,14 @@ import Element from '../element';
import Event from '../../event/event';
class Image extends Element {
- // Create instance
- static $$create(options, tree) {
- return new Image(options, tree);
- }
-
- // Override the parent class's $$init instance method
- $$init(options, tree) {
+ constructor(options) {
const width = options.width;
const height = options.height;
if (typeof width === 'number' && width >= 0) options.attrs.width = width;
if (typeof height === 'number' && height >= 0) options.attrs.height = height;
- super.$$init(options, tree);
+ super(options);
this.$_naturalWidth = 0;
this.$_naturalHeight = 0;
@@ -32,24 +26,13 @@ class Image extends Element {
this.$_naturalHeight = null;
}
- // Override the parent class's recovery instance method
- $$recycle() {
- this.$$destroy();
- }
-
- // Update parent
- $_triggerParentUpdate(payload) {
- this.$_initRect();
- super.$_triggerParentUpdate(payload);
- }
-
// Init length
$_initRect() {
- const width = parseInt(this.$_attrs.get('width'), 10);
- const height = parseInt(this.$_attrs.get('height'), 10);
+ const width = parseInt(this.__attrs.get('width'), 10);
+ const height = parseInt(this.__attrs.get('height'), 10);
- if (typeof width === 'number' && width >= 0) this.$_style.width = `${width}px`;
- if (typeof height === 'number' && height >= 0) this.$_style.height = `${height}px`;
+ if (typeof width === 'number' && width >= 0) this.style.width = `${width}px`;
+ if (typeof height === 'number' && height >= 0) this.style.height = `${height}px`;
}
// Reset width & height
@@ -60,14 +43,25 @@ class Image extends Element {
this.$_initRect();
}
+ get _renderInfo() {
+ return {
+ nodeId: this.__nodeId,
+ pageId: this.__pageId,
+ nodeType: 'image',
+ ...this.__attrs.__value,
+ style: this.style.cssText,
+ class: 'h5-img ' + this.className,
+ };
+ }
+
get src() {
- return this.$_attrs.get('src') || '';
+ return this.__attrs.get('src') || '';
}
set src(value) {
if (!value || typeof value !== 'string') return;
- this.$_attrs.set('src', value);
+ this.__attrs.set('src', value);
setTimeout(() => {
if (this.src.indexOf('data:image') !== 0) {
@@ -107,24 +101,24 @@ class Image extends Element {
}
get width() {
- return +this.$_attrs.get('width') || 0;
+ return +this.__attrs.get('width') || 0;
}
set width(value) {
if (typeof value !== 'number' || !isFinite(value) || value < 0) return;
- this.$_attrs.set('width', value);
+ this.__attrs.set('width', value);
this.$_initRect();
}
get height() {
- return +this.$_attrs.get('height') || 0;
+ return +this.__attrs.get('height') || 0;
}
set height(value) {
if (typeof value !== 'number' || !isFinite(value) || value < 0) return;
- this.$_attrs.set('height', value);
+ this.__attrs.set('height', value);
this.$_initRect();
}
diff --git a/packages/miniapp-render/src/node/element/input.js b/packages/miniapp-render/src/node/element/input.js
index a630ccccc4..f5782d83d6 100755
--- a/packages/miniapp-render/src/node/element/input.js
+++ b/packages/miniapp-render/src/node/element/input.js
@@ -1,53 +1,14 @@
import Element from '../element';
class HTMLInputElement extends Element {
- // Create instance
- static $$create(options, tree) {
- return new HTMLInputElement(options, tree);
- }
-
- // Override parent class recycle method
- $$recycle() {
- this.$$destroy();
- }
-
- // $_generateHtml handle other attributes
- $$dealWithAttrsForGenerateHtml(html, node) {
- const type = node.type;
- if (type) html += ` type="${type}"`;
-
- const value = node.value;
- if (value) html += ` value="${value}"`;
-
- const disabled = node.disabled;
- if (disabled) html += ' disabled';
-
- const maxlength = node.maxlength;
- if (maxlength) html += ` maxlength="${maxlength}"`;
-
- const placeholder = node.placeholder;
- if (placeholder)
- html += ` placeholder="${placeholder.replace(/"/g, '\\"')}"`;
-
- return html;
- }
-
- // outerHtml
- $$dealWithAttrsForOuterHTML(node) {
- this.type = node.type || '';
- this.value = node.value || '';
- this.disabled = node.disabled || '';
- this.maxlength = node.maxlength;
- this.placeholder = node.placeholder || '';
-
- // Special attr
- this.mpplaceholderclass = node.mpplaceholderclass || '';
+ constructor(options) {
+ super(options);
}
/**
* The cloneNode interface is invoked to handle additional properties
*/
- $$dealWithAttrsForCloneNode() {
+ _dealWithAttrsForCloneNode() {
return {
type: this.type,
value: this.value,
@@ -60,30 +21,66 @@ class HTMLInputElement extends Element {
};
}
+ setAttribute(name, value, immediate = true) {
+ if (name === 'focus' || name === 'autofocus' || name === 'autoFocus') {
+ // autoFocus is passed by rax-textinput
+ name = 'focus-state';
+ }
+ super.setAttribute(name, value, immediate);
+ }
+
+ // Sets properties, but does not trigger updates
+ _setAttributeWithOutUpdate(name, value) {
+ if (name === 'focus' || name === 'autofocus' || name === 'autoFocus') {
+ // autoFocus is passed by rax-textinput
+ name = 'focus-state';
+ }
+ super._setAttributeWithOutUpdate(name, value);
+ }
+
+ getAttribute(name) {
+ if (name === 'focus' || name === 'autofocus' || name === 'autoFocus') {
+ // autoFocus is passed by rax-textinput
+ name = 'focus-state';
+ }
+ return this.__attrs.get(name);
+ }
+
+ get _renderInfo() {
+ return {
+ nodeId: this.__nodeId,
+ pageId: this.__pageId,
+ nodeType: 'input',
+ ...this.__attrs.__value,
+ style: this.style.cssText,
+ class: 'h5-input ' + this.className,
+ };
+ }
+
// Attribute
get name() {
- return this.$_attrs.get('name');
+ return this.__attrs.get('name');
}
set name(value) {
value = '' + value;
- this.$_attrs.set('name', value);
+ this.__attrs.set('name', value);
}
get type() {
- return this.$_attrs.get('type') || 'text';
+ return this.__attrs.get('type') || 'text';
}
set type(value) {
value = '' + value;
- this.$_attrs.set('type', value);
+ this.__attrs.set('type', value);
}
get value() {
- const type = this.$_attrs.get('type');
- let value = this.$_attrs.get('value');
+ const type = this.__attrs.get('type');
+ let value = this.__attrs.get('value');
if (!value && !this.changed) {
- value = this.$_attrs.get('defaultValue');
+ value = this.__attrs.get('defaultValue');
}
return value || '';
}
@@ -91,66 +88,57 @@ class HTMLInputElement extends Element {
set value(value) {
this.changed = true;
value = '' + value;
- this.$_attrs.set('value', value);
+ this.__attrs.set('value', value);
}
get readOnly() {
- return !!this.$_attrs.get('readOnly');
+ return !!this.__attrs.get('readOnly');
}
set readOnly(value) {
- this.$_attrs.set('readOnly', !!value);
+ this.__attrs.set('readOnly', !!value);
}
get disabled() {
- return !!this.$_attrs.get('disabled');
+ return !!this.__attrs.get('disabled');
}
set disabled(value) {
value = !!value;
- this.$_attrs.set('disabled', value);
+ this.__attrs.set('disabled', value);
}
get maxlength() {
- return this.$_attrs.get('maxlength');
+ return this.__attrs.get('maxlength');
}
set maxlength(value) {
- this.$_attrs.set('maxlength', value);
+ this.__attrs.set('maxlength', value);
}
get placeholder() {
- return this.$_attrs.get('placeholder') || '';
+ return this.__attrs.get('placeholder') || '';
}
set placeholder(value) {
value = '' + value;
- this.$_attrs.set('placeholder', value);
- }
-
- get autofocus() {
- return !!this.$_attrs.get('autofocus');
- }
-
- set autofocus(value) {
- value = !!value;
- this.$_attrs.set('autofocus', value);
+ this.__attrs.set('placeholder', value);
}
set checked(value) {
- this.$_attrs.set('checked', value);
+ this.__attrs.set('checked', value);
}
get checked() {
- return this.$_attrs.get('checked') || '';
+ return this.__attrs.get('checked') || '';
}
blur() {
- this.$_attrs.set('focus', false);
+ this.setAttribute('focus', false);
}
focus() {
- this.$_attrs.set('autofocus', true);
+ this.setAttribute('focus', true);
}
}
diff --git a/packages/miniapp-render/src/node/element/textarea.js b/packages/miniapp-render/src/node/element/textarea.js
index 8977c776a5..7faff1d233 100644
--- a/packages/miniapp-render/src/node/element/textarea.js
+++ b/packages/miniapp-render/src/node/element/textarea.js
@@ -2,57 +2,14 @@ import Element from '../element';
import cache from '../../utils/cache';
class HTMLTextAreaElement extends Element {
- /**
- * Create instance
- */
- static $$create(options, tree) {
- return new HTMLTextAreaElement(options, tree);
- }
-
- // Override the parent class's recovery instance method
- $$recycle() {
- this.$$destroy();
- }
-
- /**
- * $_generateHtml handle other attributes
- */
- $$dealWithAttrsForGenerateHtml(html, node) {
- const type = node.type;
- if (type) html += ` type="${type}"`;
-
- const value = node.value;
- if (value) html += ` value="${value}"`;
-
- const disabled = node.disabled;
- if (disabled) html += ' disabled';
-
- const maxlength = node.maxlength;
- if (maxlength) html += ` maxlength="${maxlength}"`;
-
- const placeholder = node.placeholder;
- if (placeholder)
- html += ` placeholder="${placeholder.replace(/"/g, '\\"')}"`;
-
- return html;
- }
-
- // outerHtml
- $$dealWithAttrsForOuterHTML(node) {
- this.type = node.type || '';
- this.value = node.value || '';
- this.disabled = node.disabled || '';
- this.maxlength = node.maxlength;
- this.placeholder = node.placeholder || '';
-
- // Special field
- this.mpplaceholderclass = node.mpplaceholderclass || '';
+ constructor(options) {
+ super(options);
}
/**
* The cloneNode interface is invoked to handle additional properties
*/
- $$dealWithAttrsForCloneNode() {
+ _dealWithAttrsForCloneNode() {
return {
type: this.type,
value: this.value,
@@ -65,30 +22,66 @@ class HTMLTextAreaElement extends Element {
};
}
+ setAttribute(name, value, immediate = true) {
+ if (name === 'focus' || name === 'autofocus' || name === 'autoFocus') {
+ // autoFocus is passed by rax-textinput
+ name = 'focus-state';
+ }
+ super.setAttribute(name, value, immediate);
+ }
+
+ // Sets properties, but does not trigger updates
+ _setAttributeWithOutUpdate(name, value) {
+ if (name === 'focus' || name === 'autofocus' || name === 'autoFocus') {
+ // autoFocus is passed by rax-textinput
+ name = 'focus-state';
+ }
+ super._setAttributeWithOutUpdate(name, value);
+ }
+
+ getAttribute(name) {
+ if (name === 'focus' || name === 'autofocus' || name === 'autoFocus') {
+ // autoFocus is passed by rax-textinput
+ name = 'focus-state';
+ }
+ return this.__attrs.get(name);
+ }
+
+ get _renderInfo() {
+ return {
+ nodeId: this.__nodeId,
+ pageId: this.__pageId,
+ nodeType: 'textarea',
+ ...this.__attrs.__value,
+ style: this.style.cssText,
+ class: 'h5-textarea ' + this.className,
+ };
+ }
+
// Attribute
get name() {
- return this.$_attrs.get('name');
+ return this.__attrs.get('name');
}
set name(value) {
value = '' + value;
- this.$_attrs.set('name', value);
+ this.__attrs.set('name', value);
}
// Attribute
get type() {
- return this.$_attrs.get('type') || 'textarea';
+ return this.__attrs.get('type') || 'textarea';
}
set type(value) {
value = '' + value;
- this.$_attrs.set('type', value);
+ this.__attrs.set('type', value);
}
get value() {
- let value = this.$_attrs.get('value');
+ let value = this.__attrs.get('value');
if (!value && !this.changed) {
- value = this.$_attrs.get('defaultValue');
+ value = this.__attrs.get('defaultValue');
}
return value || '';
}
@@ -96,81 +89,67 @@ class HTMLTextAreaElement extends Element {
set value(value) {
this.changed = true;
value = '' + value;
- this.$_attrs.set('value', value);
+ this.__attrs.set('value', value);
}
get readOnly() {
- return !!this.$_attrs.get('readOnly');
+ return !!this.__attrs.get('readOnly');
}
set readOnly(value) {
- this.$_attrs.set('readOnly', !!value);
+ this.__attrs.set('readOnly', !!value);
}
get disabled() {
- return !!this.$_attrs.get('disabled');
+ return !!this.__attrs.get('disabled');
}
set disabled(value) {
value = !!value;
- this.$_attrs.set('disabled', value);
+ this.__attrs.set('disabled', value);
}
get maxlength() {
- return this.$_attrs.get('maxlength');
+ return this.__attrs.get('maxlength');
}
set maxlength(value) {
- this.$_attrs.set('maxlength', value);
+ this.__attrs.set('maxlength', value);
}
get placeholder() {
- return this.$_attrs.get('placeholder') || '';
+ return this.__attrs.get('placeholder') || '';
}
set placeholder(value) {
value = '' + value;
- this.$_attrs.set('placeholder', value);
- }
-
- get autofocus() {
- return !!this.$_attrs.get('autofocus');
- }
-
- set autofocus(value) {
- value = !!value;
- this.$_attrs.set('autofocus', value);
+ this.__attrs.set('placeholder', value);
}
get selectionStart() {
- const value = +this.$_attrs.get('selection-start');
+ const value = +this.__attrs.get('selection-start');
return value !== undefined ? value : -1;
}
set selectionStart(value) {
- this.$_attrs.set('selection-start', value);
+ this.__attrs.set('selection-start', value);
}
get selectionEnd() {
- const value = +this.$_attrs.get('selection-end');
+ const value = +this.__attrs.get('selection-end');
return value !== undefined ? value : -1;
}
set selectionEnd(value) {
- this.$_attrs.set('selection-end', value);
+ this.__attrs.set('selection-end', value);
}
- get focus() {
- return !!this.$_attrs.get('focus');
- }
-
- set focus(value) {
- value = !!value;
- this.$_attrs.set('focus', value);
+ blur() {
+ this.setAttribute('focus', false);
}
- blur() {
- this.$_attrs.set('focus', false);
+ focus() {
+ this.setAttribute('focus', true);
}
}
diff --git a/packages/miniapp-render/src/node/element/video.js b/packages/miniapp-render/src/node/element/video.js
index ace0f47467..cccc699dfc 100755
--- a/packages/miniapp-render/src/node/element/video.js
+++ b/packages/miniapp-render/src/node/element/video.js
@@ -1,123 +1,121 @@
import Element from '../element';
class HTMLVideoElement extends Element {
- static $$create(options, tree) {
- return new HTMLVideoElement(options, tree);
- }
-
- $$init(options, tree) {
+ constructor(options) {
const width = options.width;
const height = options.height;
if (typeof width === 'number' && width >= 0) options.attrs.width = width;
if (typeof height === 'number' && height >= 0) options.attrs.height = height;
- super.$$init(options, tree);
+ super(options);
this.$_initRect();
}
- $$recycle() {
- this.$$destroy();
- }
-
- $_triggerParentUpdate(payload) {
- this.$_initRect();
- super.$_triggerParentUpdate(payload);
- }
-
$_initRect() {
- const width = parseInt(this.$_attrs.get('width'), 10);
- const height = parseInt(this.$_attrs.get('height'), 10);
+ const width = parseInt(this.__attrs.get('width'), 10);
+ const height = parseInt(this.__attrs.get('height'), 10);
if (typeof width === 'number' && width >= 0) this.$_style.width = `${width}px`;
if (typeof height === 'number' && height >= 0) this.$_style.height = `${height}px`;
}
+ get _renderInfo() {
+ return {
+ nodeId: this.__nodeId,
+ pageId: this.__pageId,
+ nodeType: 'video',
+ ...this.__attrs.__value,
+ style: this.style.cssText,
+ class: 'h5-video ' + this.className,
+ };
+ }
+
get src() {
- return this.$_attrs.get('src') || '';
+ return this.__attrs.get('src') || '';
}
set src(value) {
if (!value || typeof value !== 'string') return;
- this.$_attrs.set('src', value);
+ this.__attrs.set('src', value);
}
get width() {
- return +this.$_attrs.get('width') || 0;
+ return +this.__attrs.get('width') || 0;
}
set width(value) {
if (typeof value !== 'number' || !isFinite(value) || value < 0) return;
- this.$_attrs.set('width', value);
+ this.__attrs.set('width', value);
this.$_initRect();
}
get height() {
- return +this.$_attrs.get('height') || 0;
+ return +this.__attrs.get('height') || 0;
}
set height(value) {
if (typeof value !== 'number' || !isFinite(value) || value < 0) return;
- this.$_attrs.set('height', value);
+ this.__attrs.set('height', value);
this.$_initRect();
}
get autoplay() {
- return !!this.$_attrs.get('autoplay');
+ return !!this.__attrs.get('autoplay');
}
set autoplay(value) {
value = !!value;
- this.$_attrs.set('autoplay', value);
+ this.__attrs.set('autoplay', value);
}
get loop() {
- return !!this.$_attrs.get('loop');
+ return !!this.__attrs.get('loop');
}
set loop(value) {
value = !!value;
- this.$_attrs.set('loop', value);
+ this.__attrs.set('loop', value);
}
get muted() {
- return !!this.$_attrs.get('muted');
+ return !!this.__attrs.get('muted');
}
set muted(value) {
value = !!value;
- this.$_attrs.set('muted', value);
+ this.__attrs.set('muted', value);
}
get controls() {
- const value = this.$_attrs.get('controls');
+ const value = this.__attrs.get('controls');
return value !== undefined ? !!value : true;
}
set controls(value) {
- this.$_attrs.set('controls', value);
+ this.__attrs.set('controls', value);
}
get poster() {
- return this.$_attrs.get('poster');
+ return this.__attrs.get('poster');
}
set poster(value) {
if (!value || typeof value !== 'string') return;
- this.$_attrs.set('poster', value);
+ this.__attrs.set('poster', value);
}
get currentTime() {
- return +this.$_attrs.get('currentTime') || 0;
+ return +this.__attrs.get('currentTime') || 0;
}
get buffered() {
- return this.$_attrs.get('buffered');
+ return this.__attrs.get('buffered');
}
}
diff --git a/packages/miniapp-render/src/node/node.js b/packages/miniapp-render/src/node/node.js
index f67e2acace..dd2d2f5fd4 100755
--- a/packages/miniapp-render/src/node/node.js
+++ b/packages/miniapp-render/src/node/node.js
@@ -1,18 +1,18 @@
import EventTarget from '../event/event-target';
+import tool from '../utils/tool';
import cache from '../utils/cache';
+import { BODY_NODE_ID } from '../constants';
class Node extends EventTarget {
- /**
- * Override parent class $$init method
- */
- $$init(options, tree) {
- super.$$init();
+ constructor(options) {
+ super();
- this.$_nodeId = options.nodeId; // unique
+ // unique node id
+ this.__nodeId = `n_${tool.getId()}`;
this.$_type = options.type;
- this.$_parentNode = null;
- this.$_tree = tree;
- this.__pageId = tree.pageId;
+ this.parentNode = null;
+ this.ownerDocument = options.document;
+ this.__pageId = this.ownerDocument.__pageId;
}
/**
@@ -21,30 +21,16 @@ class Node extends EventTarget {
$$destroy() {
super.$$destroy();
- this.$_nodeId = null;
+ this.__nodeId = null;
this.$_type = null;
- this.$_parentNode = null;
- this.$_tree = null;
+ this.parentNode = null;
this.__pageId = null;
- }
-
- /**
- * private nodeId
- */
- get $$nodeId() {
- return this.$_nodeId;
- }
-
- /**
- * update parent node
- */
- $$updateParent(parentNode = null) {
- this.$_parentNode = parentNode;
+ this.__rendered = false;
}
get _path() {
- if (this.$_parentNode !== null) {
- const index = '[' + this.$_parentNode.childNodes.indexOf(this) + ']';
+ if (this.parentNode !== null) {
+ const index = '[' + this.parentNode.childNodes.indexOf(this) + ']';
return `${this.parentNode._path}.children.${index}`;
}
@@ -53,15 +39,15 @@ class Node extends EventTarget {
}
get _root() {
- if (this.$_parentNode !== null) {
- return this.$_parentNode._root;
- }
-
- return null;
+ return cache.getNode(this.__pageId, BODY_NODE_ID);
}
- get parentNode() {
- return this.$_parentNode;
+ _isRendered() {
+ if (this.__rendered) return true;
+ if (this.parentNode) {
+ this.__rendered = this.parentNode._isRendered();
+ }
+ return this.__rendered;
}
get nodeValue() {
@@ -116,10 +102,6 @@ class Node extends EventTarget {
return null;
}
- get ownerDocument() {
- return cache.getDocument(this.__pageId) || null;
- }
-
hasChildNodes() {
return false;
}
diff --git a/packages/miniapp-render/src/node/root.js b/packages/miniapp-render/src/node/root.js
index d9884baa24..466afe3b45 100644
--- a/packages/miniapp-render/src/node/root.js
+++ b/packages/miniapp-render/src/node/root.js
@@ -1,67 +1,16 @@
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { isMiniApp } from 'universal-env';
import Element from './element';
import cache from '../utils/cache';
import perf from '../utils/perf';
import getProperty from '../utils/getProperty';
-import { propsMap } from '../builtInComponents';
-
-function simplify(node) {
- const domInfo = node.$$domInfo;
- const simpleNode = {};
- for (let attr in domInfo) {
- simpleNode[attr] = domInfo[attr];
- }
-
- let componentType;
- if (node._behavior) {
- componentType = simpleNode.behavior = node._behavior;
- } else {
- componentType = node.tagName;
- }
-
- // Get specific props
- const specificProps = propsMap[componentType] || [];
- specificProps.forEach(prop => {
- simpleNode[prop.name] = prop.get(node);
- });
-
- return simpleNode;
-}
-
-function traverseTree(node, action) {
- if (!node) {
- return;
- }
- let copiedNode;
- let queue = [];
- queue.push(node);
- while (queue.length) {
- let curNode = queue.shift();
- const result = action(curNode);
- if (!copiedNode) {
- copiedNode = result;
- copiedNode.children = [];
- } else {
- curNode.__parent.children = curNode.__parent.children || [];
- curNode.__parent.children.push(result);
- }
- if (curNode.$_children && curNode.$_children.length) {
- curNode.$_children.forEach(n => n.__parent = result);
- queue = queue.concat(curNode.$_children);
- }
- if (!result.children) {
- result.children = [];
- }
- }
- return copiedNode;
-}
+import { BODY_NODE_ID } from '../constants';
class RootElement extends Element {
- $$init(options, tree) {
- super.$$init(options, tree);
+ constructor(options) {
+ super(options);
+ this.__nodeId = BODY_NODE_ID;
this.allowRender = true;
this.renderStacks = [];
+ this.__renderCallbacks = [];
}
$$destroy() {
@@ -94,44 +43,75 @@ class RootElement extends Element {
}
// type 1: { path, start, deleteCount, item? } => need to simplify item
// type 2: { path, value }
- const renderObject = {};
- const renderStacks = [];
- const pathCache = [];
+
const internal = cache.getDocument(this.__pageId)._internal;
- for (let i = 0, j = this.renderStacks.length; i < j; i++) {
- const renderTask = this.renderStacks[i];
- const path = renderTask.path;
- const taskInfo = getProperty(internal.data, path, pathCache);
- if (!taskInfo.parentRendered || internal.firstRender && path !== 'root.children') break;
- if (renderTask.type === 'children') {
- const ElementNode = renderTask.item;
- const simplifiedNode = traverseTree(ElementNode, simplify);
- renderTask.item = simplifiedNode;
- // path cache should save lastest taskInfo value
- pathCache.push({
- path: renderTask.path,
- value: taskInfo.value
- });
- }
- if (!internal.$batchedUpdates) {
+ if (internal.$batchedUpdates) {
+ let callback;
+ internal.$batchedUpdates(() => {
+ this.renderStacks.forEach((task, index) => {
+ if (index === this.renderStacks.length - 1) {
+ callback = () => {
+ if (process.env.NODE_ENV === 'development') {
+ perf.stop('setData');
+ }
+ let fn;
+ while (fn = this.__renderCallbacks.pop()) {
+ fn();
+ }
+ };
+ internal.firstRenderCallback();
+ }
+ if (task.type === 'children') {
+ const spliceArgs = [task.start, task.deleteCount];
+ internal.$spliceData({
+ [task.path]: task.item ? spliceArgs.concat(task.item) : spliceArgs
+ }, callback);
+ } else {
+ internal.setData({
+ [task.path]: task.value
+ }, callback);
+ }
+ });
+ });
+ } else {
+ const renderObject = {};
+ const pathCache = [];
+ this.renderStacks.forEach(task => {
+ const path = task.path;
// there is no need to aggregate arrays if $batchedUpdate and $spliceData exist
- if (renderTask.type === 'children') {
- renderObject[path] = renderObject[path] || taskInfo.value || [];
- if (renderTask.item) {
- renderObject[path].splice(renderTask.start, renderTask.deleteCount, renderTask.item);
+ if (task.type === 'children') {
+ const taskInfo = getProperty(internal.data, path, pathCache);
+ // path cache should save lastest taskInfo value
+ pathCache.push({
+ path: task.path,
+ value: taskInfo.value
+ });
+
+ if (!renderObject[path]) {
+ renderObject[path] = taskInfo.value ? [...taskInfo.value] : [];
+ }
+ if (task.item) {
+ renderObject[path].splice(task.start, task.deleteCount, task.item);
} else {
- renderObject[path].splice(renderTask.start, renderTask.deleteCount);
+ renderObject[path].splice(task.start, task.deleteCount);
}
} else {
- renderObject[path] = renderTask.value;
+ renderObject[path] = task.value;
+ }
+ });
+ internal.firstRenderCallback(renderObject);
+ internal.setData(renderObject, () => {
+ let fn;
+ while (fn = this.__renderCallbacks.pop()) {
+ fn();
+ }
+ if (process.env.NODE_ENV === 'development') {
+ perf.stop('setData');
}
- } else {
- renderStacks.push(renderTask);
- }
+ });
}
- this.$$trigger('render', { args: internal.$batchedUpdates ? renderStacks : renderObject });
this.renderStacks = [];
}
}
diff --git a/packages/miniapp-render/src/node/style-list.js b/packages/miniapp-render/src/node/style-list.js
index 81356a4ac7..695a785285 100755
--- a/packages/miniapp-render/src/node/style-list.js
+++ b/packages/miniapp-render/src/node/style-list.js
@@ -1,27 +1,139 @@
/**
* A list of supported style properties that by default contain only commonly used style properties
*/
+export default {
+ position: 'position',
+ top: 'top',
+ bottom: 'bottom',
+ right: 'right',
+ left: 'left',
+ float: 'float',
+ clear: 'clear',
+ display: 'display',
+ width: 'width',
+ height: 'height',
+ maxHeight: 'max-height',
+ maxWidth: 'max-width',
+ minHeight: 'min-height',
+ minWidth: 'min-width',
+ flex: 'flex',
+ flexBasis: 'flex-basis',
+ flexGrow: 'flex-grow',
+ flexShrink: 'flex-shrink',
+ flexDirection: 'flex-direction',
+ flexWrap: 'flex-wrap',
+ justifyContent: 'justify-content',
+ alignItems: 'align-items',
+ padding: 'padding',
+ paddingBottom: 'padding-bottom',
+ paddingLeft: 'padding-left',
+ paddingRight: 'padding-right',
+ paddingTop: 'padding-top',
+ margin: 'margin',
+ marginBottom: 'margin-bottom',
+ marginLeft: 'margin-left',
+ marginRight: 'margin-right',
+ marginTop: 'margin-top',
-export default [
- 'position', 'top', 'bottom', 'right', 'left', 'float', 'clear',
- 'display', 'width', 'height', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'flex', 'flexBasis', 'flexGrow', 'flexShrink', 'flexDirection', 'flexWrap', 'justifyContent', 'alignItems',
- 'padding', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop',
- 'margin', 'marginBottom', 'marginLeft', 'marginRight', 'marginTop',
+ background: 'background',
+ backgroundClip: 'background-clip',
+ backgroundColor: 'background-color',
+ backgroundImage: 'background-image',
+ backgroundOrigin: 'background-origin',
+ backgroundPosition: 'background-position',
+ backgroundRepeat: 'background-repeat',
+ backgroundSize: 'background-size',
+ border: 'border',
+ borderRadius: 'border-radius',
+ borderBottomColor: 'border-bottom-color',
+ borderBottomLeftRadius: 'border-bottom-left-radius',
+ borderBottomRightRadius: 'border-bottom-right-radius',
+ borderBottomStyle: 'border-bottom-style',
+ borderBottomWidth: 'border-bottom-width',
+ borderCollapse: 'border-collapse',
+ borderImageOutset: 'border-image-outset',
+ borderImageRepeat: 'border-image-repeat',
+ borderImageSlice: 'border-image-slice',
+ borderImageSource: 'border-image-source',
+ borderImageWidth: 'border-image-width',
+ borderLeftColor: 'border-left-color',
+ borderLeftStyle: 'border-left-style',
+ borderLeftWidth: 'border-left-width',
+ borderRightColor: 'border-right-color',
+ borderRightStyle: 'border-right-style',
+ borderRightWidth: 'border-right-width',
+ borderTopColor: 'border-top-color',
+ borderTopLeftRadius: 'border-top-left-radius',
+ borderTopRightRadius: 'border-top-right-radius',
+ borderTopStyle: 'border-top-style',
+ borderTopWidth: 'border-top-width',
+ outline: 'outline',
+ borderWidth: 'border-width',
+ borderStyle: 'border-style',
+ borderColor: 'border-color',
- 'background', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPosition', 'backgroundRepeat', 'backgroundSize',
- 'border', 'borderRadius', 'borderBottomColor', 'borderBottomLeftRadius', 'borderBottomRightRadius', 'borderBottomStyle', 'borderBottomWidth', 'borderCollapse', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopLeftRadius', 'borderTopRightRadius', 'borderTopStyle', 'borderTopWidth',
- 'outline', 'borderWidth', 'borderStyle', 'borderColor',
+ animation: 'animation',
+ animationDelay: 'animation-delay',
+ animationDirection: 'animation-direction',
+ animationDuration: 'animation-duration',
+ animationFillMode: 'animation-fill-mode',
+ animationIterationCount: 'animation-iteration-count',
+ animationName: 'animation-name',
+ animationPlayState: 'animation-play-state',
+ animationTimingFunction: 'animation-timing-function',
+ transition: 'transition',
+ transitionDelay: 'transition-delay',
+ transitionDuration: 'transition-duration',
+ transitionProperty: 'transition-property',
+ transitionTimingFunction: 'transition-timing-function',
+ transform: 'transform',
+ transformOrigin: 'transform-origin',
+ perspective: 'perspective',
+ perspectiveOrigin: 'perspective-origin',
+ backfaceVisibility: 'backface-visibility',
- 'animation', 'animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction',
- 'transition', 'transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction',
- 'transform', 'transformOrigin', 'perspective', 'perspectiveOrigin', 'backfaceVisibility',
+ font: 'font',
+ fontFamily: 'font-family',
+ fontSize: 'font-size',
+ fontStyle: 'font-style',
+ fontWeight: 'font-weight',
+ color: 'color',
+ textAlign: 'text-align',
+ textDecoration: 'text-decoration',
+ textIndent: 'text-indent',
+ textRendering: 'text-rendering',
+ textShadow: 'text-shadow',
+ textOverflow: 'text-overflow',
+ textTransform: 'text-transform',
+ wordBreak: 'word-break',
+ wordSpacing: 'word-spacing',
+ wordWrap: 'word-wrap',
+ lineHeight: 'line-height',
+ letterSpacing: 'letter-spacing',
+ whiteSpace: 'white-space',
+ userSelect: 'user-select',
- 'font', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight',
- 'color', 'textAlign', 'textDecoration', 'textIndent', 'textRendering', 'textShadow', 'textOverflow', 'textTransform',
- 'wordBreak', 'wordSpacing', 'wordWrap', 'lineHeight', 'letterSpacing', 'whiteSpace', 'userSelect',
+ visibility: 'visibility',
+ opacity: 'opacity',
+ zIndex: 'z-index',
+ zoom: 'zoom',
+ overflow: 'overflow',
+ overflowX: 'overflow-x',
+ overflowY: 'overflow-y',
+ boxShadow: 'box-shadow',
+ boxSizing: 'box-sizing',
+ content: 'content',
+ cursor: 'cursor',
+ direction: 'direction',
+ listStyle: 'list-style',
+ objectFit: 'object-fit',
+ pointerEvents: 'pointer-events',
+ resize: 'resize',
+ verticalAlign: 'vertical-align',
+ willChange: 'will-change',
+ clip: 'clip',
+ clipPath: 'clip-path',
+ fill: 'fill',
- 'visibility', 'opacity', 'zIndex', 'zoom', 'overflow', 'overflowX', 'overflowY',
- 'boxShadow', 'boxSizing', 'content', 'cursor', 'direction', 'listStyle', 'objectFit', 'pointerEvents', 'resize', 'verticalAlign', 'willChange', 'clip', 'clipPath', 'fill',
-
- 'touchAction'
-];
+ touchAction: 'touch-action',
+};
diff --git a/packages/miniapp-render/src/node/style.js b/packages/miniapp-render/src/node/style.js
index 2ec08a8c05..e988af947f 100644
--- a/packages/miniapp-render/src/node/style.js
+++ b/packages/miniapp-render/src/node/style.js
@@ -1,103 +1,108 @@
import styleList from './style-list';
-import tool from '../utils/tool';
-
-/**
- * Parse style string
- */
-function parse(styleText) {
- const rules = {};
-
- if (styleText) {
- styleText = tool.decodeContent(styleText);
- // deal with the semicolon in the value first
- styleText = styleText.replace(/url\([^)]+\)/ig, all => all.replace(/;/ig, ':#||#:'));
- styleText.split(';').forEach(rule => {
- rule = rule.trim();
- if (!rule) return;
-
- const split = rule.indexOf(':');
- if (split === -1) return;
-
- const name = tool.toCamel(rule.substr(0, split).trim());
- rules[name] = rule.substr(split + 1).replace(/:#\|\|#:/ig, ';').trim();
- });
- }
-
- return rules;
-}
class Style {
- constructor(element, onUpdate) {
- this.__settedStyle = {};
- this.$$init(element, onUpdate);
+ constructor(element) {
+ this.__settedStyle = new Set();
+ this.__value = new Map();
+ this.__element = element;
}
- static $$create(element, onUpdate) {
- return new Style(element, onUpdate);
+ setStyle(val, styleKey) {
+ const old = this[styleKey];
+ if (val) {
+ this.__settedStyle.add(styleKey);
+ }
+ this.__value.set(styleKey, val);
+ if (old !== val && this.__element._isRendered()) {
+ const payload = {
+ path: `${this.__element._path}.style`,
+ value: this.cssText
+ };
+ this.__element._triggerUpdate(payload);
+ }
}
- // Init instance
- $$init(element, onUpdate) {
- this.$_element = element;
- this.$_doUpdate = onUpdate || (() => {});
- // Whether checking for updates is disabled
- this.$_disableCheckUpdate = false;
+ get cssText() {
+ let cssText = '';
+ this.__settedStyle.forEach(key => {
+ const val = this[key];
+ if (!val) return;
+ cssText += `${styleMap.get(key)}: ${val};`;
+ });
+ return cssText;
}
- $$destroy() {
- this.$_element = null;
- this.$_doUpdate = null;
- this.$_disableCheckUpdate = false;
-
- styleList.forEach(name => {
- this.__settedStyle[name] = undefined;
+ set cssText(styleText = '') {
+ this.__settedStyle.forEach(prop => {
+ this.removeProperty(prop);
});
- }
- $$recycle() {
- this.$$destroy();
- }
+ if (styleText === '') {
+ return;
+ }
- $_checkUpdate() {
- if (!this.$_disableCheckUpdate) {
- const payload = {
- path: `${this.$_element._path}.style`,
- value: this.cssText
- };
- this.$_doUpdate(payload);
+ const rules = styleText.split(';');
+
+ for (let i = 0; i < rules.length; i++) {
+ const rule = rules[i].trim();
+ if (rule === '') {
+ continue;
+ }
+
+ const [propName, val] = rule.split(':');
+ if (typeof val === undefined) {
+ continue;
+ }
+ this.setProperty(propName.trim(), val.trim());
}
}
- get cssText() {
- return Object.keys(this.__settedStyle).reduce((cssText, name) => {
- if (this.__settedStyle[name]) {
- return cssText + `${tool.toDash(name)}:${this.__settedStyle[name].trim()};`;
+ setCssVariables(styleKey) {
+ this.hasOwnProperty(styleKey) || Object.defineProperty(this, styleKey, {
+ enumerable: true,
+ configurable: true,
+ get: () => {
+ return this.__value.get(styleKey) || '';
+ },
+ set: (val) => {
+ this.setStyle(val, styleKey);
}
- return cssText;
- }, '');
+ });
}
- set cssText(styleText) {
- if (typeof styleText !== 'string') return;
-
- styleText = styleText.replace(/"/g, '\'');
+ setProperty(name, value) {
+ if (name[0] === '-') {
+ this.setCssVariables(name);
+ } else {
+ name = styleMap.get(name);
+ }
+ if (typeof value === undefined) {
+ return;
+ }
- // Parse style
- const rules = parse(styleText);
+ if (!value) {
+ this.removeProperty(name);
+ } else {
+ this[name] = value;
+ }
+ }
- // Merge the Settings for each rule into an update
- this.$_disableCheckUpdate = true;
- for (const name of styleList) {
- this[name] = rules[name];
+ removeProperty(name) {
+ name = styleMap.get(name);
+ if (!this.__settedStyle.has(name)) {
+ return '';
}
- this.$_disableCheckUpdate = false;
- // this.$_checkUpdate();
+
+ const value = this[name];
+ this[name] = '';
+ this.__settedStyle.delete(name);
+ return value;
}
getPropertyValue(name) {
if (typeof name !== 'string') return '';
- name = tool.toCamel(name);
+ name = styleMap.get(name);
return this[name] || '';
}
}
@@ -106,22 +111,20 @@ class Style {
* Set the getters and setters for each property
*/
const properties = {};
-styleList.forEach(name => {
+const styleMap = new Map();
+Object.keys(styleList).forEach(name => {
+ styleMap.set(name, styleList[name]);
+ styleMap.set(styleList[name], name);
properties[name] = {
get() {
- return this.__settedStyle[name] || '';
+ return this.__value.get(name) || '';
},
set(value) {
- const oldValue = this.__settedStyle[name];
- value = value !== undefined ? '' + value : undefined;
-
- this.__settedStyle[name] = value;
- if (oldValue !== value) {
- this.$_checkUpdate();
- }
+ this.setStyle(value, name);
},
};
});
+
Object.defineProperties(Style.prototype, properties);
export default Style;
diff --git a/packages/miniapp-render/src/node/text-node.js b/packages/miniapp-render/src/node/text-node.js
index 706b676f46..429603cab2 100755
--- a/packages/miniapp-render/src/node/text-node.js
+++ b/packages/miniapp-render/src/node/text-node.js
@@ -2,14 +2,10 @@ import tool from '../utils/tool';
import Node from '../node/node';
class TextNode extends Node {
- static $$create(options, tree) {
- return new TextNode(options, tree);
- }
-
- $$init(options, tree) {
+ constructor(options) {
options.type = 'text';
- super.$$init(options, tree);
+ super(options);
this.$_content = options.content || '';
}
@@ -20,19 +16,13 @@ class TextNode extends Node {
this.$_content = '';
}
- $$recycle() {
- this.$$destroy();
- }
-
_triggerUpdate(payload) {
- this._root && this._root.enqueueRender(payload);
+ this._root.enqueueRender(payload);
}
- get $$domInfo() {
+ get _renderInfo() {
return {
- nodeId: this.$_nodeId,
- pageId: this.__pageId,
- nodeType: this.$_type,
+ nodeType: `h-${this.$_type}`,
content: this.$_content,
};
}
@@ -61,11 +51,13 @@ class TextNode extends Node {
value += '';
this.$_content = value;
- const payload = {
- path: `${this._path}.content`,
- value
- };
- this._triggerUpdate(payload);
+ if (this._isRendered()) {
+ const payload = {
+ path: `${this._path}.content`,
+ value
+ };
+ this._triggerUpdate(payload);
+ }
}
get data() {
@@ -77,10 +69,7 @@ class TextNode extends Node {
}
cloneNode() {
- return this.ownerDocument.$$createTextNode({
- content: this.$_content,
- nodeId: `b-${tool.getId()}`,
- });
+ return this.ownerDocument.createTextNode(this.$_content);
}
}
diff --git a/packages/miniapp-render/src/tree/parser.js b/packages/miniapp-render/src/tree/parser.js
deleted file mode 100755
index e79ac76106..0000000000
--- a/packages/miniapp-render/src/tree/parser.js
+++ /dev/null
@@ -1,246 +0,0 @@
-/**
- * https://johnresig.com/files/htmlparser.js
- */
-
-// Reg
-const doctypeReg = /^\s]+))?)*)\s*(\/?)>/i;
-const startTagReg = /^<([-A-Za-z0-9_]+)((?:\s+[-A-Za-z0-9_:@.]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/i;
-const endTagReg = /^<\/([-A-Za-z0-9_]+)[^>]*>/i;
-const attrReg = /([-A-Za-z0-9_:@.]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
-
-// Empty element - https://www.w3.org/TR/html/syntax.html#void-elements
-const voidMap = {};
-['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'].forEach(n => voidMap[n] = true);
-
-// Block element - https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements#Elements
-const blockMap = {};
-['address', 'article', 'aside', 'blockquote', 'canvas', 'dd', 'div', 'dl', 'dt', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'main', 'nav', 'noscript', 'ol', 'output', 'p', 'pre', 'section', 'table', 'tfoot', 'ul', 'video'].forEach(n => blockMap[n] = true);
-
-// Inline element - https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements#Elements
-const inlineMap = {};
-['a', 'abbr', 'acronym', 'b', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'dfn', 'em', 'i', 'img', 'input', 'kbd', 'label', 'map', 'object', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong', 'sub', 'sup', 'textarea', 'time', 'tt', 'var'].forEach(n => inlineMap[n] = true);
-
-// An element that may contain arbitrary content- https://www.w3.org/TR/html/syntax.html#raw-text
-const rawTextMap = {};
-['script', 'style'].forEach(n => rawTextMap[n] = true);
-
-const longAttributeCache = {};
-let seed = 0;
-
-function tokenize(content, handler) {
- const stack = [];
- let last = content;
-
- stack.last = function() {
- return this[this.length - 1];
- };
-
- while (content) {
- let isText = true;
-
- if (!stack.last() || !rawTextMap[stack.last()]) {
- if (content.indexOf('');
-
- if (index >= 0) {
- content = content.substring(index + 3);
- isText = false;
- }
- } else if (content.indexOf('') === 0) {
- // end tag
- const match = content.match(endTagReg);
-
- if (match) {
- content = content.substring(match[0].length);
- match[0].replace(endTagReg, parseEndTag);
- isText = false;
- }
- } else if (content.indexOf('<') === 0) {
- // start tag
- let match = content.match(startTagReg);
-
- if (match) {
- content = content.substring(match[0].length);
- match[0].replace(startTagReg, parseStartTag);
- isText = false;
- } else {
- // 检测 doctype
- match = content.match(doctypeReg);
-
- if (match) {
- content = content.substring(match[0].length);
- isText = false;
- }
- }
- }
-
- if (isText) {
- const index = content.indexOf('<');
-
- const text = index < 0 ? content : content.substring(0, index);
- content = index < 0 ? '' : content.substring(index);
-
- if (handler.text) handler.text(text);
- }
- } else {
- const execRes = new RegExp(`${stack.last()}[^>]*>`).exec(content);
-
- if (execRes) {
- const text = content.substring(0, execRes.index);
- content = content.substring(execRes.index + execRes[0].length);
-
- text.replace(//g, '');
- if (text && handler.text) handler.text(text);
- }
-
- parseEndTag('', stack.last());
- }
-
- if (content === last) throw new Error(`parse error: ${content}`);
- last = content;
- }
-
- // Close the label in the stack
- parseEndTag();
-
- function parseStartTag(tag, tagName, rest, unary) {
- tagName = tagName.toLowerCase();
- unary = !!unary;
-
- unary = voidMap[tagName] || !!unary;
-
- if (!unary) stack.push(tagName);
-
- if (handler.start) {
- const attrs = [];
-
- try {
- rest.replace(attrReg, (all, $1, $2, $3, $4) => {
- const value = $2 || $3 || $4;
-
- attrs.push({
- name: $1,
- value,
- });
- });
- } catch (err) {
- // Some android will kneel down when performing a property regex on a string that is too long (mainly base 64)
- rest = rest.replace(/url\([^)]+\)/ig, all => {
- const id = `url(:#|${++seed}|#:)`;
- longAttributeCache[id] = all;
- return id;
- });
- rest.replace(attrReg, (all, $1, $2, $3, $4) => {
- const value = $2 || $3 || $4;
-
- attrs.push({
- name: $1,
- value: value.replace(/url\(:#\|\d+\|#:\)/ig, all => longAttributeCache[all] || 'url()'),
- });
- });
- }
-
- handler.start(tagName, attrs, unary);
- }
- }
-
- function parseEndTag(tag, tagName) {
- let pos;
-
- if (!tagName) {
- pos = 0;
- } else {
- // Find the start tag with the same name
- tagName = tagName.toLowerCase();
-
- for (pos = stack.length - 1; pos >= 0; pos--) {
- if (stack[pos] === tagName) break;
- }
- }
-
- if (pos >= 0) {
- // Close all tags in the start and end tags
- for (let i = stack.length - 1; i >= pos; i--) {
- if (handler.end) handler.end(stack[i]);
- }
-
- stack.length = pos;
- }
- }
-}
-
-function parse(html) {
- const r = {
- children: [],
- };
- const stack = [r];
-
- stack.last = function() {
- return this[this.length - 1];
- };
-
- tokenize(html, {
- start(tagName, attrs, unary) {
- const node = {
- type: 'element',
- tagName,
- attrs,
- unary,
- children: [],
- };
-
- stack.last().children.push(node);
-
- if (!unary) {
- stack.push(node);
- }
- },
- // eslint-disable-next-line no-unused-vars
- end(tagName) {
- const node = stack.pop();
-
- if (node.tagName === 'table') {
- // Supplement insert tbody
- let hasTbody = false;
-
- for (const child of node.children) {
- if (child.tagName === 'tbody') {
- hasTbody = true;
- break;
- }
- }
-
- if (!hasTbody) {
- node.children = [{
- type: 'element',
- tagName: 'tbody',
- attrs: [],
- unary: false,
- children: node.children,
- }];
- }
- }
- },
- text(content) {
- content = content.trim();
- if (!content) return;
-
- stack.last().children.push({
- type: 'text',
- content,
- });
- },
- });
-
- return r.children;
-}
-
-export default {
- tokenize,
- parse,
- voidMap,
- blockMap,
- inlineMap,
- rawTextMap,
-};
diff --git a/packages/miniapp-render/src/tree/query-selector.js b/packages/miniapp-render/src/tree/query-selector.js
deleted file mode 100755
index 01495cb74d..0000000000
--- a/packages/miniapp-render/src/tree/query-selector.js
+++ /dev/null
@@ -1,370 +0,0 @@
-/**
- * Thanks sizzle:https://github.com/jquery/sizzle/tree/master
- */
-
-const PSEUDO_CHECK = {
- checked: node => node.checked || node.selected,
- disabled: node => node.disabled,
- enabled: node => !node.disabled,
- 'first-child': node => node.parentNode.children[0] === node,
- 'last-child': node => node.parentNode.children[node.parentNode.children.length - 1] === node,
- 'nth-child': (node, param) => {
- const children = node.parentNode.children;
- const {a, b} = param;
- const index = children.indexOf(node) + 1;
-
- if (a) {
- return (index - b) % a === 0;
- } else {
- return index === b;
- }
- },
-};
-
-const ATTR_CHECK = {
- '=': (nodeVal, val) => nodeVal === val,
- '~=': (nodeVal, val) => nodeVal.split(/\s+/).indexOf(val) !== -1,
- '|=': (nodeVal, val) => nodeVal === val || nodeVal.indexOf(val + '-') === 0,
- '^=': (nodeVal, val) => nodeVal.indexOf(val) === 0,
- '$=': (nodeVal, val) => nodeVal.substr(nodeVal.length - val.length) === val,
- '*=': (nodeVal, val) => nodeVal.indexOf(val) !== -1,
-};
-
-const KINSHIP_CHECK = {
- ' ': (node, kinshipRule) => {
- let kinshipNode = node.parentNode;
-
- while (kinshipNode) {
- if (checkHit(kinshipNode, kinshipRule)) return kinshipNode;
-
- kinshipNode = kinshipNode.parentNode;
- }
-
- return null;
- },
- '>': (node, kinshipRule) => {
- const kinshipNode = node.parentNode;
-
- return checkHit(kinshipNode, kinshipRule) ? kinshipNode : null;
- },
- '+': (node, kinshipRule) => {
- const children = node.parentNode;
-
- for (let i = 0, len = children.length; i < len; i++) {
- const child = children[i];
-
- if (child === node) {
- const kinshipNode = children[i - 1];
-
- return checkHit(kinshipNode, kinshipRule) ? kinshipNode : null;
- }
- }
-
- return null;
- },
- '~': (node, kinshipRule) => {
- const children = node.parentNode;
- let foundCurrent = false;
-
- for (let i = children.length - 1; i >= 0; i--) {
- const child = children[i];
-
- if (foundCurrent && checkHit(child, kinshipRule)) return child;
- if (child === node) foundCurrent = true;
- }
-
- return null;
- },
-};
-
-/**
- * Check if the node conforms to the rule
- */
-function checkHit(node, rule) {
- if (!node) return false;
-
- const {
- id, class: classList, tag, pseudo, attr
- } = rule;
-
- if (id) {
- if (node.id !== id) return false;
- }
-
- if (classList && classList.length) {
- for (const className of classList) {
- if (!node.classList || !node.classList.contains(className)) return false;
- }
- }
-
- if (tag && tag !== '*') {
- if (node.tagName !== tag.toUpperCase()) return false;
- }
-
- if (pseudo) {
- for (const {name, param} of pseudo) {
- const checkPseudo = PSEUDO_CHECK[name];
- if (!checkPseudo || !checkPseudo(node, param)) return false;
- }
- }
-
- if (attr) {
- for (const {name, opr, val} of attr) {
- const nodeVal = node[name] || node.getAttribute(name);
-
- if (nodeVal === undefined) return false;
- if (opr) {
- // Existence operator
- const checkAttr = ATTR_CHECK[opr];
- if (!checkAttr || !checkAttr(nodeVal, val)) return false;
- }
- }
- }
-
- return true;
-}
-
-function unique(list) {
- for (let i = 0; i < list.length; i++) {
- const a = list[i];
-
- for (let j = i + 1; j < list.length; j++) {
- const b = list[j];
- if (a === b) list.splice(j, 1);
- }
- }
-
- return list;
-}
-
-function sortNodes(list) {
- list.sort((a, b) => {
- const aList = [a];
- const bList = [b];
- let aParent = a.parentNode;
- let bParent = b.parentNode;
-
- if (aParent === bParent) {
- // Check the order
- const children = aParent.children;
- return children.indexOf(a) - children.indexOf(b);
- }
-
- // A to the root list
- while (aParent) {
- aList.unshift(aParent);
- aParent = aParent.parentNode;
- }
-
- // B to the root list
- while (bParent) {
- bList.unshift(bParent);
- bParent = bParent.parentNode;
- }
-
- // Find the closest common ancestor
- let i = 0;
- while (aList[i] === bList[i]) i++;
-
- // Check the order
- const children = aList[i - 1].children;
- return children.indexOf(aList[i]) - children.indexOf(bList[i]);
- });
-
- return list;
-}
-
-class QuerySelector {
- constructor() {
- this.parseCache = {};
- this.parseCacheKeys = [];
-
- const idReg = '#([\\\\\\w-]+)';
- const tagReg = '\\*|builtin-component|[a-zA-Z-]\\w*';
- const classReg = '\\.([\\\\\\w-]+)';
- const pseudoReg = ':([\\\\\\w-]+)(?:\\(([^\\(\\)]*|(?:\\([^\\)]+\\)|[^\\(\\)]*)+)\\))?';
- const attrReg = '\\[\\s*([\\\\\\w-]+)(?:([*^$|~!]?=)[\'"]?([^\'"\\[]+)[\'"]?)?\\s*\\]';
- const kinshipReg = '\\s*([>\\s+~](?!=))\\s*';
- this.regexp = new RegExp(`^(?:(${idReg})|(${tagReg})|(${classReg})|(${pseudoReg})|(${attrReg})|(${kinshipReg}))`);
- }
-
- setParseCache(key, value) {
- if (this.parseCacheKeys.length > 50) {
- delete this.parseCache[this.parseCacheKeys.shift()];
- }
-
- this.parseCacheKeys.push(key);
- this.parseCache[key] = value;
-
- return value;
- }
-
- getParseCache(key) {
- return this.parseCache[key];
- }
-
- parse(selector) {
- const segment = [{tag: '*'}];
- const regexp = this.regexp;
-
- const onProcess = (all, idAll, id, tagAll, classAll, className, pseudoAll, pseudoName, pseudoParam, attrAll, attrName, attrOpr, attrVal, kinshipAll, kinship) => {
- if (idAll) {
- segment[segment.length - 1].id = id;
- } else if (tagAll) {
- segment[segment.length - 1].tag = tagAll.toLowerCase();
- } else if (classAll) {
- const currentRule = segment[segment.length - 1];
- currentRule.class = currentRule.class || [];
-
- currentRule.class.push(className);
- } else if (pseudoAll) {
- const currentRule = segment[segment.length - 1];
- currentRule.pseudo = currentRule.pseudo || [];
- pseudoName = pseudoName.toLowerCase();
-
- const pseudo = {name: pseudoName};
-
- if (pseudoParam) pseudoParam = pseudoParam.trim();
- if (pseudoName === 'nth-child') {
- // Handle nth-child pseudo-class, parameter unified processing into the format of an + b
- pseudoParam = pseudoParam.replace(/\s+/g, '');
-
- if (pseudoParam === 'even') {
- // 偶数个
- pseudoParam = {a: 2, b: 2};
- } else if (pseudoParam === 'odd') {
- pseudoParam = {a: 2, b: 1};
- } else if (pseudoParam) {
- const nthParsed = pseudoParam.match(/^(?:(\d+)|(\d*)?n([+-]\d+)?)$/);
-
- if (!nthParsed) {
- pseudoParam = {a: 0, b: 1};
- } else if (nthParsed[1]) {
- pseudoParam = {a: 0, b: +nthParsed[1]};
- } else {
- pseudoParam = {
- a: nthParsed[2] ? +nthParsed[2] : 1,
- b: nthParsed[3] ? +nthParsed[3] : 0,
- };
- }
- } else {
- // Take the first by default
- pseudoParam = {a: 0, b: 1};
- }
- }
- if (pseudoParam) pseudo.param = pseudoParam;
-
- currentRule.pseudo.push(pseudo);
- } else if (attrAll) {
- const currentRule = segment[segment.length - 1];
-
- currentRule.attr = currentRule.attr || [];
- currentRule.attr.push({
- name: attrName,
- opr: attrOpr,
- val: attrVal
- });
- } else if (kinshipAll) {
- segment[segment.length - 1].kinship = kinship;
- segment.push({tag: '*'});
- }
-
- return '';
- };
-
- // Selector resolution
- let lastParse;
- selector = selector.replace(regexp, onProcess);
-
- while (lastParse !== selector) {
- lastParse = selector;
- selector = selector.replace(regexp, onProcess);
- }
-
- return selector ? '' : segment;
- }
-
- exec(selector, extra) {
- selector = selector.trim().replace(/\s+/g, ' ').replace(/\s*(,|[>\s+~](?!=)|[*^$|~!]?=)\s*/g, '$1');
- const {idMap, tagMap, classMap} = extra;
-
- let segment = this.getParseCache(selector);
-
- if (!segment) {
- segment = this.parse(selector);
-
- if (!segment) return [];
-
- this.setParseCache(selector, segment);
- }
-
- if (!segment[0]) return [];
-
- const lastRule = segment[segment.length - 1];
- const {id, class: classList, tag} = lastRule;
- let hitNodes = [];
-
- if (id) {
- const node = idMap[id];
- hitNodes = node ? [node] : [];
- } else if (classList && classList.length) {
- for (const className of classList) {
- const classNodes = classMap[className];
- if (classNodes) {
- for (const classNode of classNodes) {
- if (hitNodes.indexOf(classNode) === -1) hitNodes.push(classNode);
- }
- }
- }
- } else if (tag && tag !== '*') {
- const tagName = tag.toUpperCase();
- const tagNodes = tagMap[tagName];
- if (tagNodes) hitNodes = tagNodes;
- } else {
- Object.keys(tagMap).forEach(key => {
- const tagNodes = tagMap[key];
- if (tagNodes) {
- for (const tagNode of tagNodes) hitNodes.push(tagNode);
- }
- });
- }
-
- if (hitNodes.length && segment.length) {
- for (let i = hitNodes.length - 1; i >= 0; i--) {
- let checkNode = hitNodes[i];
- let isMatched = false;
-
- for (let j = segment.length - 1; j >= 0; j--) {
- const prevRule = segment[j - 1];
-
- if (j === segment.length - 1) isMatched = checkHit(checkNode, lastRule);
-
- if (isMatched && prevRule) {
- const kinship = prevRule.kinship;
- const checkKinship = KINSHIP_CHECK[kinship];
-
- if (checkKinship) checkNode = checkKinship(checkNode, prevRule);
-
- if (!checkNode) {
- isMatched = false;
- break;
- }
- } else {
- break;
- }
- }
-
- if (!isMatched) hitNodes.splice(i, 1);
- }
- }
-
- if (hitNodes.length) {
- hitNodes = unique(hitNodes);
- hitNodes = sortNodes(hitNodes);
- }
-
- return hitNodes;
- }
-}
-
-export default QuerySelector;
diff --git a/packages/miniapp-render/src/tree/tree.js b/packages/miniapp-render/src/tree/tree.js
deleted file mode 100755
index b8166fec17..0000000000
--- a/packages/miniapp-render/src/tree/tree.js
+++ /dev/null
@@ -1,110 +0,0 @@
-import RootElement from '../node/root';
-import QuerySelector from './query-selector';
-
-// Traverse the dom tree to collect a list of nodes corresponding to the class and label
-function walkDomTree(node, cache) {
- const tagMap = cache.tagMap = cache.tagMap || {};
- const classMap = cache.classMap = cache.classMap || {};
- const {tagName, classList} = node;
-
- tagMap[tagName] = tagMap[tagName] || [];
- tagMap[tagName].push(node);
-
- for (const className of classList) {
- classMap[className] = classMap[className] || [];
- classMap[className].push(node);
- }
-
- const children = node.children || [];
-
- for (const child of children) {
- walkDomTree(child, cache);
- }
-}
-
-class Tree {
- constructor(pageId, root, nodeIdMap, document) {
- this.pageId = pageId;
- this.root = new RootElement({
- type: 'element',
- tagName: 'body',
- attrs: {},
- unary: false,
- nodeId: 'e-body',
- children: [],
- }, this);
- this.nodeIdMap = nodeIdMap;
- this.idMap = {};
- this.document = document;
-
- this.querySelector = new QuerySelector();
- if (nodeIdMap) nodeIdMap[root.nodeId] = this.root;
-
- this.walk(root, this.root);
- }
-
- walk(ast, parentNode) {
- const children = ast.children;
- const idMap = this.idMap;
- const nodeIdMap = this.nodeIdMap;
- const document = this.document;
-
- if (!children || !children.length) return;
-
- for (const child of children) {
- let childNode;
-
- if (child.type === 'element') {
- childNode = document.$$createElement(child, this);
- } else if (child.type === 'text') {
- childNode = document.$$createTextNode(child, this);
- }
-
- const id = childNode.id;
- if (id && !idMap[id]) {
- idMap[id] = childNode;
- }
-
- if (nodeIdMap) nodeIdMap[child.nodeId] = childNode;
-
- parentNode.appendChild(childNode);
-
- this.walk(child, childNode);
- }
- }
-
- updateIdMap(id, node) {
- this.idMap[id] = node;
- }
-
- getById(id) {
- return this.idMap[id];
- }
-
- getByTagName(tagName, node) {
- const cache = {};
- walkDomTree(node || this.root, cache);
-
- return cache.tagMap[tagName.toUpperCase()] || [];
- }
-
- getByClassName(className, node) {
- const cache = {};
- walkDomTree(node || this.root, cache);
-
- return cache.classMap[className] || [];
- }
-
- query(selector, node) {
- const cache = {};
- walkDomTree(node || this.root, cache);
-
- return this.querySelector.exec(selector, {
- idMap: this.idMap,
- tagMap: cache.tagMap,
- classMap: cache.classMap,
- });
- }
-}
-
-export default Tree;
diff --git a/packages/miniapp-render/src/utils/cache.js b/packages/miniapp-render/src/utils/cache.js
index a1e5c6e4ee..0423c45b3e 100755
--- a/packages/miniapp-render/src/utils/cache.js
+++ b/packages/miniapp-render/src/utils/cache.js
@@ -1,5 +1,5 @@
-const pageMap = {};
-const routeMap = {};
+const pageMap = new Map();
+const routeMap = new Map();
let config = {};
let window;
@@ -8,22 +8,19 @@ const elementMethodsCache = new Map();
// Init
function init(pageId, options) {
- pageMap[pageId] = {
- document: options.document,
- nodeIdMap: options.nodeIdMap,
- };
+ pageMap.set(pageId, options.document);
}
// Destroy
function destroy(pageId) {
- delete pageMap[pageId];
+ pageMap.delete(pageId);
}
/**
* Get document
*/
function getDocument(pageId) {
- return pageMap[pageId] && pageMap[pageId].document;
+ return pageMap.get(pageId);
}
// Set window
@@ -42,24 +39,18 @@ function getWindow() {
* Save domNode map
*/
function setNode(pageId, nodeId, domNode = null) {
- const document = pageMap[pageId] && pageMap[pageId].document;
+ const document = pageMap.get(pageId);
// Call before run, do nothing
if (!document) return;
- if (!domNode) return pageMap[pageId].nodeIdMap[nodeId] = domNode;
- let parentNode = domNode.parentNode;
-
- while (parentNode && parentNode !== document.body) {
- parentNode = parentNode.parentNode;
- }
-
- pageMap[pageId].nodeIdMap[nodeId] = parentNode === document.body ? domNode : null;
+ document.__nodeIdMap.set(nodeId, domNode);
}
// Get the domNode by nodeId
function getNode(pageId, nodeId) {
- return pageMap[pageId] && pageMap[pageId].nodeIdMap[nodeId];
+ const document = pageMap.get(pageId);
+ return document && document.__nodeIdMap.get(nodeId);
}
// Store global config
@@ -73,11 +64,9 @@ function getConfig() {
}
function getRouteId(route) {
- if (!routeMap[route]) {
- return routeMap[route] = 1;
- } else {
- return ++routeMap[route];
- }
+ const routeId = routeMap.get(route) || 0;
+ routeMap.set(route, routeId + 1);
+ return routeId + 1;
}
function setElementInstance(instance) {
diff --git a/packages/miniapp-render/src/utils/checkEventAccessDomNode.js b/packages/miniapp-render/src/utils/checkEventAccessDomNode.js
deleted file mode 100644
index 21e4090d6a..0000000000
--- a/packages/miniapp-render/src/utils/checkEventAccessDomNode.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default function(evt, domNode, dest) {
- const targetNode = dest || domNode.ownerDocument.body;
- let target = evt.target;
-
- if (domNode === targetNode) return true;
-
- while (target && target !== dest) {
- if (target === domNode) return true;
- target = target.parentNode;
- }
-
- return false;
-}
diff --git a/packages/miniapp-render/src/utils/findParentNode.js b/packages/miniapp-render/src/utils/findParentNode.js
deleted file mode 100644
index 273cd454c6..0000000000
--- a/packages/miniapp-render/src/utils/findParentNode.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Find the closest parent node
-export default function findParentNode(domNode, tagName) {
- const checkParentNode = (parentNode, tagName) => {
- if (!parentNode) return false;
- if (parentNode.tagName === tagName) return true;
- if (parentNode.tagName === 'BUILTIN-COMPONENT' && parentNode._behavior === tagName.toLowerCase()) return true;
-
- return false;
- };
- let parentNode = domNode.parentNode;
-
- if (checkParentNode(parentNode, tagName)) return parentNode;
- while (parentNode && parentNode.tagName !== tagName) {
- parentNode = parentNode.parentNode;
- if (checkParentNode(parentNode, tagName)) return parentNode;
- }
-
- return null;
-}
diff --git a/packages/miniapp-render/src/utils/getProperty.js b/packages/miniapp-render/src/utils/getProperty.js
index ada109964a..df3ac7d586 100644
--- a/packages/miniapp-render/src/utils/getProperty.js
+++ b/packages/miniapp-render/src/utils/getProperty.js
@@ -16,7 +16,6 @@ export default function(obj, path, cache) {
return false;
});
-
let value = obj;
let parentRendered = true;
diff --git a/packages/miniapp-render/src/utils/tool.js b/packages/miniapp-render/src/utils/tool.js
index cfa527e1c9..48f7a8e22c 100755
--- a/packages/miniapp-render/src/utils/tool.js
+++ b/packages/miniapp-render/src/utils/tool.js
@@ -15,7 +15,7 @@ function toCamel(str) {
/**
* Get unique id
*/
-let seed = +new Date();
+let seed = 0;
function getId() {
return seed++;
}
@@ -49,35 +49,10 @@ function flushThrottleCache() {
waitFuncSet.clear();
}
-/**
- * Encode special character
- */
-function decodeContent(content) {
- return content
- .replace(/ /g, '\u00A0')
- .replace(/ /g, '\u2002')
- .replace(/ /g, '\u2003')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, '\'')
- .replace(/&/g, '&');
-}
-
-/**
- * Check tag wheather supported
- */
-const NOT_SUPPORT_TAG_NAME_LIST = ['IFRAME', 'A'];
-function isTagNameSupport(tagName) {
- return NOT_SUPPORT_TAG_NAME_LIST.indexOf(tagName) === -1;
-}
-
export default {
toDash,
toCamel,
getId,
throttle,
flushThrottleCache,
- decodeContent,
- isTagNameSupport,
};
diff --git a/packages/miniapp-render/src/utils/tree.js b/packages/miniapp-render/src/utils/tree.js
new file mode 100644
index 0000000000..e74c1fc000
--- /dev/null
+++ b/packages/miniapp-render/src/utils/tree.js
@@ -0,0 +1,35 @@
+function simplify(node) {
+ return node._renderInfo;
+}
+
+export function traverse(node, action) {
+ if (!node) {
+ return;
+ }
+ let copiedNode;
+ let queue = [];
+ queue.push(node);
+ while (queue.length) {
+ let curNode = queue.shift();
+ const result = action(curNode);
+ if (!copiedNode) {
+ copiedNode = result;
+ copiedNode.children = [];
+ } else {
+ curNode.__parent.children = curNode.__parent.children || [];
+ curNode.__parent.children.push(result);
+ }
+ if (curNode.childNodes && curNode.childNodes.length) {
+ curNode.childNodes.forEach(n => n.__parent = result);
+ queue = queue.concat(curNode.childNodes);
+ }
+ if (!result.children) {
+ result.children = [];
+ }
+ }
+ return copiedNode;
+}
+
+export function simplifyDomTree(node) {
+ return traverse(node, simplify);
+}
diff --git a/packages/miniapp-render/src/window.js b/packages/miniapp-render/src/window.js
index fbed45bc35..41ded66033 100755
--- a/packages/miniapp-render/src/window.js
+++ b/packages/miniapp-render/src/window.js
@@ -14,9 +14,6 @@ class Window extends EventTarget {
const timeOrigin = +new Date();
- this.$_elementConstructor = function HTMLElement(...args) {
- return Element.$$create(...args);
- };
this.$_customEventConstructor = class CustomEvent extends OriginalCustomEvent {
constructor(name = '', options = {}) {
options.timeStamp = +new Date() - timeOrigin;
@@ -39,7 +36,7 @@ class Window extends EventTarget {
}
addEventListener(eventName, handler, options) {
- if (this.__sharedEventNames.indexOf(eventName) > 0) {
+ if (this.__sharedEventNames.indexOf(eventName) > -1) {
this.__sharedHandlers.push({
eventName,
handler
@@ -87,7 +84,7 @@ class Window extends EventTarget {
}
}
- if (this.__sharedEventNames.indexOf(eventName) > 0) {
+ if (this.__sharedEventNames.indexOf(eventName) > -1) {
this.__sharedHandlers
.filter((handlerInfo) => handlerInfo.eventName === eventName)
.forEach(({ handler }) => {
@@ -134,7 +131,9 @@ class Window extends EventTarget {
}
get HTMLElement() {
- return this.$_elementConstructor;
+ return function(...args) {
+ return new Element(...args);
+ };
}
get Element() {