diff --git a/packages/miniapp-element/package.json b/packages/miniapp-element/package.json
index b2acde447c..6bedff00f4 100644
--- a/packages/miniapp-element/package.json
+++ b/packages/miniapp-element/package.json
@@ -1,6 +1,6 @@
{
"name": "miniapp-element",
- "version": "0.1.14",
+ "version": "0.1.15",
"description": "Custom element for MiniApp",
"files": [
"dist"
diff --git a/packages/miniapp-element/scripts/adapter.js b/packages/miniapp-element/scripts/adapter.js
index 41b6b495c3..d9dc4596bc 100644
--- a/packages/miniapp-element/scripts/adapter.js
+++ b/packages/miniapp-element/scripts/adapter.js
@@ -16,6 +16,8 @@ export default {
touchCancel: 'onTouchCancel',
load: 'onLoad',
error: 'onError',
+ appear: 'onAppear',
+ disAppear: 'onDisappear',
supportComponentGenerics: false
},
wechat: {
diff --git a/packages/miniapp-element/scripts/genreateSubtree.js b/packages/miniapp-element/scripts/genreateSubtree.js
index 7b451156d2..fabcdd8135 100644
--- a/packages/miniapp-element/scripts/genreateSubtree.js
+++ b/packages/miniapp-element/scripts/genreateSubtree.js
@@ -13,17 +13,18 @@ function getSubtreeSimple(i, platform) {
const isFirst = i === 1;
const subContent = [
`{{${itemName}.content}}`,
- ``,
- `{{${itemName}.content}}${isLast ? '' : ''}`
+ ``,
+ ``,
+ `{{${itemName}.content}}${isLast ? '' : ''}`
];
// Recursion next
if (!isLast) {
- subContent.splice(3, 0, ...getSubtreeSimple(i + 1, platform));
+ subContent.splice(4, 0, ...getSubtreeSimple(i + 1, platform));
}
// Add custom element
- subContent.push(``);
+ subContent.push(``);
// Add head content & foot content
const outputContent = [
@@ -48,17 +49,18 @@ function getSubtreeCoverSimple(i, platform) {
const isLast = i === DOM_SUBTREE_LEVEL;
const isFirst = i === 1;
const subContent = [
- ``,
- `{{${itemName}.content}}${isLast ? '' : ''}`
+ ``,
+ ``,
+ `{{${itemName}.content}}${isLast ? '' : ''}`
];
// Recursion next
if (!isLast) {
- subContent.splice(2, 0, ...getSubtreeCoverSimple(i + 1, platform));
+ subContent.splice(3, 0, ...getSubtreeCoverSimple(i + 1, platform));
}
// Add custom element
- subContent.push(``);
+ subContent.push(``);
// Add head and foot
const outputContent = [
@@ -85,6 +87,9 @@ function createSubtreeTemplate(platform) {
'',
'\n'
];
+ if (platform !== 'ali') {
+ content.unshift(``);
+ }
return content.join('');
}
@@ -98,23 +103,34 @@ function createSubtreeCoverTemplate(platform) {
'',
'\n'
];
+ if (platform !== 'ali') {
+ content.unshift(``);
+ }
return content.join('');
}
-export default function(distPath, platform) {
+function createInnerComponentTemplate(templatesDir, platform) {
+ return fs.readFileSync(path.join(templatesDir, `inner-component.${adapter[platform].xml}`), 'utf8');
+}
+
+export default function(distPath, templatesDir, platform) {
switch (platform) {
case 'ali':
const subtreeAXMLTemplate = createSubtreeTemplate(platform);
const subtreeCoverAXMLTemplate = createSubtreeCoverTemplate(platform);
+ const innerComponentAXMLTemplate = createInnerComponentTemplate(templatesDir, platform);
const XMLPath = path.join(distPath, 'index.axml');
+ fs.appendFileSync(XMLPath, innerComponentAXMLTemplate);
fs.appendFileSync(XMLPath, subtreeAXMLTemplate);
fs.appendFileSync(XMLPath, subtreeCoverAXMLTemplate);
break;
case 'wechat':
const subtreeWXMLTemplate = createSubtreeTemplate(platform);
const subtreeCoverWXMLTemplate = createSubtreeCoverTemplate(platform);
+ const innerComponentWXMLTemplate = createInnerComponentTemplate(templatesDir, platform);
const templatePath = path.join(distPath, 'template');
fs.ensureDirSync(templatePath);
+ fs.writeFileSync(path.join(templatePath, `inner-component.${adapter[platform].xml}`), innerComponentWXMLTemplate, 'utf8');
fs.writeFileSync(path.join(templatePath, `subtree.${adapter[platform].xml}`), subtreeWXMLTemplate, 'utf8');
fs.writeFileSync(path.join(templatePath, `subtree-cover.${adapter[platform].xml}`), subtreeCoverWXMLTemplate, 'utf8');
break;
diff --git a/packages/miniapp-element/scripts/handleComponentFile.js b/packages/miniapp-element/scripts/handleComponentFile.js
index 01eb291a53..6e60759c3c 100644
--- a/packages/miniapp-element/scripts/handleComponentFile.js
+++ b/packages/miniapp-element/scripts/handleComponentFile.js
@@ -8,7 +8,8 @@ export default function(platform) {
fs.ensureDirSync(distPath);
// Copy index file
- const sourceIndexXMLFilePath = path.resolve('src', 'templates', `index.${adapter[platform].xml}`);
+ const templatesDir = path.resolve('src', 'templates');
+ const sourceIndexXMLFilePath = path.resolve(templatesDir, `index.${adapter[platform].xml}`);
const distIndexXMLFilePath = path.join(distPath, `index.${adapter[platform].xml}`);
const sourceIndexJSONFilePath = path.resolve('src', `index.${platform}.json`);
const distIndexJSONFilePath = path.join(distPath, 'index.json');
@@ -22,5 +23,5 @@ export default function(platform) {
fs.writeFileSync(path.join(customComponentPath, 'index.json'), '{ "component": true }');
fs.writeFileSync(path.join(customComponentPath, `index.${adapter[platform].xml}`), '');
- generateSubtree(distPath, platform);
+ generateSubtree(distPath, templatesDir, platform);
}
diff --git a/packages/miniapp-element/src/builtInComponents/ad.js b/packages/miniapp-element/src/builtInComponents/ad.js
index 43c55238b0..497d79b4b0 100644
--- a/packages/miniapp-element/src/builtInComponents/ad.js
+++ b/packages/miniapp-element/src/builtInComponents/ad.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'ad',
@@ -20,13 +20,13 @@ export default {
}],
handles: {
onAdLoad(evt) {
- callSimpleEvent('load', evt, this.domNode);
+ callSingleEvent('load', evt, this);
},
onAdError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
onAdClose(evt) {
- callSimpleEvent('close', evt, this.domNode);
+ callSingleEvent('close', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/button.js b/packages/miniapp-element/src/builtInComponents/button.js
index 02a2d73247..335e6ea710 100644
--- a/packages/miniapp-element/src/builtInComponents/button.js
+++ b/packages/miniapp-element/src/builtInComponents/button.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'button',
@@ -107,23 +107,22 @@ export default {
}],
handles: {
onButtonGetUserInfo(evt) {
- callSimpleEvent('getuserinfo', evt, this.domNode);
+ callSingleEvent('getuserinfo', evt, this);
},
onButtonContact(evt) {
- callSimpleEvent('contact', evt, this.domNode);
+ callSingleEvent('contact', evt, this);
},
onButtonGetPhoneNumber(evt) {
- callSimpleEvent('getphonenumber', evt, this.domNode);
+ callSingleEvent('getphonenumber', evt, this);
},
onButtonError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
onButtonOpenSetting(evt) {
- callSimpleEvent('opensetting', evt, this.domNode);
+ callSingleEvent('opensetting', evt, this);
},
onButtonLaunchApp(evt) {
- callSimpleEvent('launchapp', evt, this.domNode);
+ callSingleEvent('launchapp', evt, this);
},
-
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/camera.js b/packages/miniapp-element/src/builtInComponents/camera.js
index 23a773741b..837d70c0d0 100644
--- a/packages/miniapp-element/src/builtInComponents/camera.js
+++ b/packages/miniapp-element/src/builtInComponents/camera.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'camera',
@@ -30,16 +30,16 @@ export default {
}],
handles: {
onCameraStop(evt) {
- callSimpleEvent('stop', evt, this.domNode);
+ callSingleEvent('stop', evt, this);
},
onCameraError(evt) {
- callSimpleEvent('error', evt);
+ callSingleEvent('error', evt, this);
},
onCameraInitDone(evt) {
- callSimpleEvent('initdone', evt, this.domNode);
+ callSingleEvent('initdone', evt, this);
},
onCameraScanCode(evt) {
- callSimpleEvent('scancode', evt, this.domNode);
+ callSingleEvent('scancode', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/canvas.js b/packages/miniapp-element/src/builtInComponents/canvas.js
index 5a58abccf8..307266dbaf 100644
--- a/packages/miniapp-element/src/builtInComponents/canvas.js
+++ b/packages/miniapp-element/src/builtInComponents/canvas.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'canvas',
@@ -25,25 +25,25 @@ export default {
}],
handles: {
onCanvasTouchStart(evt) {
- this.callSimpleEvent('canvastouchstart', evt);
+ callSingleEvent('canvastouchstart', evt, this);
},
onCanvasTouchMove(evt) {
- this.callSimpleEvent('canvastouchmove', evt);
+ callSingleEvent('canvastouchmove', evt, this);
},
onCanvasTouchEnd(evt) {
- this.callSimpleEvent('canvastouchend', evt);
+ callSingleEvent('canvastouchend', evt, this);
},
onCanvasTouchCancel(evt) {
- this.callSimpleEvent('canvastouchcancel', evt);
+ callSingleEvent('canvastouchcancel', evt, this);
},
onCanvasLongTap(evt) {
- callSimpleEvent('longtap', evt, this.domNode);
+ callSingleEvent('longtap', evt, this);
},
onCanvasError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/checkbox-group.js b/packages/miniapp-element/src/builtInComponents/checkbox-group.js
index c4bf91b3c1..7ebcef34a0 100644
--- a/packages/miniapp-element/src/builtInComponents/checkbox-group.js
+++ b/packages/miniapp-element/src/builtInComponents/checkbox-group.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'checkbox-group',
@@ -10,7 +10,7 @@ export default {
}],
handles: {
onCheckboxChange(evt) {
- callSimpleEvent('change', evt, this.domNode);
+ callSingleEvent('change', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/checkbox.js b/packages/miniapp-element/src/builtInComponents/checkbox.js
index 034f9df29c..d31c8cf3c8 100644
--- a/packages/miniapp-element/src/builtInComponents/checkbox.js
+++ b/packages/miniapp-element/src/builtInComponents/checkbox.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'checkbox',
@@ -7,6 +7,11 @@ export default {
get(domNode) {
return domNode.getAttribute('value') || '';
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'checked',
get(domNode) {
@@ -25,7 +30,7 @@ export default {
}],
handles: {
onCheckboxItemChange(evt) {
- callSimpleEvent('change', evt, this.domNode);
+ callSingleEvent('change', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/cover-image.js b/packages/miniapp-element/src/builtInComponents/cover-image.js
index a88d3a8d9d..7e46d47f90 100644
--- a/packages/miniapp-element/src/builtInComponents/cover-image.js
+++ b/packages/miniapp-element/src/builtInComponents/cover-image.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'cover-image',
@@ -15,10 +15,10 @@ export default {
}],
handles: {
onCoverImageLoad(evt) {
- callSimpleEvent('load', evt, this.domNode);
+ callSingleEvent('load', evt, this);
},
onCoverImageError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/editor.js b/packages/miniapp-element/src/builtInComponents/editor.js
index f50c0d1317..5d4728d27e 100644
--- a/packages/miniapp-element/src/builtInComponents/editor.js
+++ b/packages/miniapp-element/src/builtInComponents/editor.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'editor',
@@ -35,19 +35,19 @@ export default {
}],
handles: {
onEditorReady(evt) {
- callSimpleEvent('ready', evt, this.domNode);
+ callSingleEvent('ready', evt, this);
},
onEditorFocus(evt) {
- callSimpleEvent('focus', evt, this.domNode);
+ callSingleEvent('focus', evt, this);
},
onEditorBlur(evt) {
- callSimpleEvent('blur', evt, this.domNode);
+ callSingleEvent('blur', evt, this);
},
onEditorInput(evt) {
- callSimpleEvent('input', evt, this.domNode);
+ callSingleEvent('input', evt, this);
},
onEditorStatusChange(evt) {
- callSimpleEvent('statuschange', evt, this.domNode);
+ callSingleEvent('statuschange', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/form.js b/packages/miniapp-element/src/builtInComponents/form.js
index 46ed7f64e2..b7cfaede3e 100644
--- a/packages/miniapp-element/src/builtInComponents/form.js
+++ b/packages/miniapp-element/src/builtInComponents/form.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'form',
@@ -20,10 +20,10 @@ export default {
}],
handles: {
onFormSubmit(evt) {
- callSimpleEvent('submit', evt, this.domNode);
+ callSingleEvent('submit', evt, this);
},
onFormReset(evt) {
- callSimpleEvent('reset', evt, this.domNode);
+ callSingleEvent('reset', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/image.js b/packages/miniapp-element/src/builtInComponents/image.js
index 3bc1a1dbd4..03d4d8e31e 100644
--- a/packages/miniapp-element/src/builtInComponents/image.js
+++ b/packages/miniapp-element/src/builtInComponents/image.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'image',
@@ -35,10 +35,10 @@ export default {
}],
handles: {
onImageLoad(evt) {
- callSimpleEvent('load', evt, this.domNode);
+ callSingleEvent('load', evt, this);
},
onImageError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/input.js b/packages/miniapp-element/src/builtInComponents/input.js
index 571c898c2e..8e159e8f3e 100644
--- a/packages/miniapp-element/src/builtInComponents/input.js
+++ b/packages/miniapp-element/src/builtInComponents/input.js
@@ -1,6 +1,7 @@
import render from 'miniapp-render';
import callEvent from '../events/callEvent';
import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
const { cache } = render.$$adapter;
@@ -8,9 +9,15 @@ export default {
name: 'input',
props: [{
name: 'value',
+ canBeUserChanged: true,
get(domNode) {
return domNode.value || '';
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'type',
get(domNode) {
@@ -65,6 +72,7 @@ export default {
},
}, {
name: 'focus',
+ canBeUserChanged: true,
get(domNode) {
return !!domNode.getAttribute('focus');
},
@@ -104,6 +112,7 @@ export default {
},
}, {
name: 'checked',
+ canBeUserChanged: true,
get(domNode) {
return !!domNode.getAttribute('checked');
},
@@ -117,45 +126,75 @@ export default {
get(domNode) {
return domNode.getAttribute('animation');
}
+ }, {
+ name: 'controlled',
+ get(domNode) {
+ return !!domNode.getAttribute('controlled');
+ },
}],
handles: {
onInputInput(evt) {
- if (!this.domNode) return;
- this._inputOldValue = this.domNode.value;
+ const domNode = this.getDomNodeFromEvt('input', evt);
+ if (!domNode) return;
+ const value = '' + evt.detail.value;
+ domNode.$$setAttributeWithoutUpdate('value', value);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.value = value;
+
callEvent('input', evt, null, this.pageId, this.nodeId);
},
onInputFocus(evt) {
- this._inputOldValue = this.domNode.value || '';
- callSimpleEvent('focus', evt, this.domNode);
+ const domNode = this.getDomNodeFromEvt('focus', evt);
+ if (!domNode) return;
+ domNode.__inputOldValue = domNode.value;
+ domNode.$$setAttributeWithoutUpdate('focus', true);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.focus = true;
+ callSimpleEvent('focus', evt, domNode);
},
onInputBlur(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('blur', evt);
+ if (!domNode) return;
+
+ domNode.$$setAttributeWithoutUpdate('focus', false);
- this.domNode.setAttribute('focus', false);
- if (this._inputOldValue !== undefined && this.domNode.value !== this._inputOldValue) {
- this._inputOldValue = undefined;
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.focus = false;
+ if (this.__inputOldValue !== undefined && domNode.value !== this.__inputOldValue) {
+ this.__inputOldValue = undefined;
callEvent('change', evt, null, this.pageId, this.nodeId);
}
- callSimpleEvent('blur', evt, this.domNode);
+ callSimpleEvent('blur', evt, domNode);
},
onInputConfirm(evt) {
- callSimpleEvent('confirm', evt, this.domNode);
+ const domNode = this.getDomNodeFromEvt('confirm', evt);
+ callSimpleEvent('confirm', evt, domNode);
},
onInputKeyBoardHeightChange(evt) {
- callSimpleEvent('keyboardheightchange', evt, this.domNode);
+ callSingleEvent('keyboardheightchange', evt, this);
},
onRadioChange(evt) {
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
const window = cache.getWindow();
- const domNode = this.domNode;
const value = evt.detail.value;
const name = domNode.name;
- const otherDomNodes = window.document.querySelectorAll(`input[name=${name}]`) || [];
if (value === domNode.value) {
- domNode.setAttribute('checked', true);
+ domNode.$$setAttributeWithoutUpdate('checked', true);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.checked = true;
+
+ const otherDomNodes = window.document.querySelectorAll(`input[name=${name}]`) || [];
for (const otherDomNode of otherDomNodes) {
if (otherDomNode.type === 'radio' && otherDomNode !== domNode) {
- otherDomNode.setAttribute('checked', false);
+ otherDomNode.$$setAttributeWithoutUpdate('checked', false);
+
+ otherDomNode.__oldValues = otherDomNode.__oldValues || {};
+ otherDomNode.__oldValues.checked = false;
}
}
}
@@ -163,17 +202,25 @@ export default {
callEvent('change', evt, null, this.pageId, this.nodeId);
},
onCheckboxChange(evt) {
- const domNode = this.domNode;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
const value = evt.detail.value || [];
if (value.indexOf(domNode.value) >= 0) {
- domNode.setAttribute('checked', true);
+ domNode.$$setAttributeWithoutUpdate('checked', true);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.checked = true;
} else {
- domNode.setAttribute('checked', false);
+ domNode.$$setAttributeWithoutUpdate('checked', false);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.checked = false;
}
callEvent('change', evt, null, this.pageId, this.nodeId);
},
onCheckboxItemChange(evt) {
- const domNode = this.domNode;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
const value = evt.detail.value || false;
domNode.setAttribute('checked', value);
callEvent('change', evt, null, this.pageId, this.nodeId);
diff --git a/packages/miniapp-element/src/builtInComponents/live-player.js b/packages/miniapp-element/src/builtInComponents/live-player.js
index f0506178a5..9a3f4f95ea 100644
--- a/packages/miniapp-element/src/builtInComponents/live-player.js
+++ b/packages/miniapp-element/src/builtInComponents/live-player.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'live-player',
@@ -74,13 +74,13 @@ export default {
}],
handles: {
onLivePlayerStateChange(evt) {
- callSimpleEvent('statechange', evt, this.domNode);
+ callSingleEvent('statechange', evt, this);
},
onLivePlayerFullScreenChange(evt) {
- callSimpleEvent('fullscreenchange', evt, this.domNode);
+ callSingleEvent('fullscreenchange', evt, this);
},
onLivePlayerNetStatus(evt) {
- callSimpleEvent('netstatus', evt, this.domNode);
+ callSingleEvent('netstatus', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/live-pusher.js b/packages/miniapp-element/src/builtInComponents/live-pusher.js
index cce8444a51..48d2295e77 100644
--- a/packages/miniapp-element/src/builtInComponents/live-pusher.js
+++ b/packages/miniapp-element/src/builtInComponents/live-pusher.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'live-pusher',
@@ -104,22 +104,22 @@ export default {
}],
handles: {
onLivePusherStateChange(evt) {
- callSimpleEvent('statechange', evt, this.domNode);
+ callSingleEvent('statechange', evt, this);
},
onLivePusherNetStatus(evt) {
- callSimpleEvent('netstatus', evt, this.domNode);
+ callSingleEvent('netstatus', evt, this);
},
onLivePusherError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
onLivePusherBgmStart(evt) {
- callSimpleEvent('bgmstart', evt, this.domNode);
+ callSingleEvent('bgmstart', evt, this);
},
onLivePusherBgmProgress(evt) {
- callSimpleEvent('bgmprogress', evt, this.domNode);
+ callSingleEvent('bgmprogress', evt, this);
},
onLivePusherBgmComplete(evt) {
- callSimpleEvent('bgmcomplete', evt, this.domNode);
+ callSingleEvent('bgmcomplete', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/map.js b/packages/miniapp-element/src/builtInComponents/map.js
index 633b0757cb..ade55c8cf4 100644
--- a/packages/miniapp-element/src/builtInComponents/map.js
+++ b/packages/miniapp-element/src/builtInComponents/map.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'map',
@@ -74,11 +74,13 @@ export default {
},
}, {
name: 'rotate',
+ canBeUserChanged: true,
get(domNode) {
return +domNode.getAttribute('rotate') || 0;
},
}, {
name: 'skew',
+ canBeUserChanged: true,
get(domNode) {
return +domNode.getAttribute('skew') || 0;
},
@@ -132,25 +134,35 @@ export default {
}],
handles: {
onMapTap(evt) {
- callSimpleEvent('tap', evt, this.domNode);
+ callSingleEvent('tap', evt, this);
},
onMapMarkerTap(evt) {
- callSimpleEvent('markertap', evt, this.domNode);
+ callSingleEvent('markertap', evt, this);
},
onMapControlTap(evt) {
- callSimpleEvent('controltap', evt, this.domNode);
+ callSingleEvent('controltap', evt, this);
},
onMapCalloutTap(evt) {
- callSimpleEvent('callouttap', evt, this.domNode);
+ callSingleEvent('callouttap', evt, this);
},
onMapUpdated(evt) {
- callSimpleEvent('updated', evt, this.domNode);
+ callSingleEvent('updated', evt, this);
},
onMapRegionChange(evt) {
- callSimpleEvent('regionchange', evt, this.domNode);
+ const domNode = this.getDomNodeFromEvt('regionchange', evt);
+ if (!domNode) return;
+
+ if (!evt.detail.causedBy) evt.detail.causedBy = evt.causedBy;
+ if (evt.type === 'end' || evt.detail.type === 'end') {
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.rotate = evt.detail.rotate;
+ domNode.__oldValues.skew = evt.detail.skew;
+ }
+
+ callSingleEvent('regionchange', evt, this);
},
onMapPoiTap(evt) {
- callSimpleEvent('poitap', evt, this.domNode);
+ callSingleEvent('poitap', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/movable-view.js b/packages/miniapp-element/src/builtInComponents/movable-view.js
index e60f01e340..9e921d3c6f 100644
--- a/packages/miniapp-element/src/builtInComponents/movable-view.js
+++ b/packages/miniapp-element/src/builtInComponents/movable-view.js
@@ -1,7 +1,4 @@
-import render from 'miniapp-render';
-import callSimpleEvent from '../events/callSimpleEvent';
-
-const { cache } = render.$$adapter;
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'movable-view',
@@ -22,11 +19,13 @@ export default {
},
}, {
name: 'x',
+ canBeUserChanged: true,
get(domNode) {
return +domNode.getAttribute('x') || 0;
},
}, {
name: 'y',
+ canBeUserChanged: true,
get(domNode) {
return +domNode.getAttribute('y') || 0;
},
@@ -49,6 +48,7 @@ export default {
},
}, {
name: 'scale',
+ canBeUserChanged: true,
get(domNode) {
return !!domNode.getAttribute('scale');
},
@@ -84,41 +84,33 @@ export default {
}],
handles: {
onMovableViewChange(evt) {
- const nodeId = evt.currentTarget.dataset.privateNodeId;
- const domNode = cache.getNode(this.pageId, nodeId);
+ const domNode = this.getDomNodeFromEvt('change', evt);
if (!domNode) return;
domNode.$$setAttributeWithoutUpdate('x', evt.detail.x);
domNode.$$setAttributeWithoutUpdate('y', evt.detail.y);
- callSimpleEvent('change', evt, domNode);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.x = evt.detail.x;
+ domNode.__oldValues.y = evt.detail.y;
+ callSingleEvent('change', evt, this);
},
onMovableViewScale(evt) {
- const nodeId = evt.currentTarget.dataset.privateNodeId;
- const domNode = cache.getNode(this.pageId, nodeId);
+ const domNode = this.getDomNodeFromEvt('scale', evt);
if (!domNode) return;
domNode.$$setAttributeWithoutUpdate('x', evt.detail.x);
domNode.$$setAttributeWithoutUpdate('y', evt.detail.y);
domNode.$$setAttributeWithoutUpdate('scale-value', evt.detail.scale);
- callSimpleEvent('scale', evt, domNode);
+ callSingleEvent('scale', evt, this);
},
onMovableViewHtouchmove(evt) {
- const nodeId = evt.currentTarget.dataset.privateNodeId;
- const domNode = cache.getNode(this.pageId, nodeId);
-
- if (!domNode) return;
-
- callSimpleEvent('htouchmove', evt, domNode);
+ callSingleEvent('htouchmove', evt, this);
},
onMovableViewVtouchmove(evt) {
- const nodeId = evt.currentTarget.dataset.privateNodeId;
- const domNode = cache.getNode(this.pageId, nodeId);
-
- if (!domNode) return;
-
- callSimpleEvent('vtouchmove', evt, domNode);
+ callSingleEvent('vtouchmove', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/navigator.js b/packages/miniapp-element/src/builtInComponents/navigator.js
index 74bc0bf0c1..794817d0b0 100644
--- a/packages/miniapp-element/src/builtInComponents/navigator.js
+++ b/packages/miniapp-element/src/builtInComponents/navigator.js
@@ -1,5 +1,5 @@
/* global isWeChatMiniProgram */
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
let props = [{
name: 'openType',
@@ -79,13 +79,13 @@ export default {
props,
handles: {
onNavigatorSuccess(evt) {
- callSimpleEvent('success', evt, this.domNode);
+ callSingleEvent('success', evt, this);
},
onNavigatorFail(evt) {
- callSimpleEvent('fail', evt, this.domNode);
+ callSingleEvent('fail', evt, this);
},
onNavigatorComplete(evt) {
- callSimpleEvent('complete', evt, this.domNode);
+ callSingleEvent('complete', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/official-account.js b/packages/miniapp-element/src/builtInComponents/official-account.js
index 8081d15e80..af8a000db7 100644
--- a/packages/miniapp-element/src/builtInComponents/official-account.js
+++ b/packages/miniapp-element/src/builtInComponents/official-account.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'official-account',
@@ -10,10 +10,10 @@ export default {
}],
handles: {
onOfficialAccountLoad(evt) {
- callSimpleEvent('load', evt, this.domNode);
+ callSingleEvent('load', evt, this);
},
onOfficialAccountError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/picker-view.js b/packages/miniapp-element/src/builtInComponents/picker-view.js
index 9d04451d43..2e21521092 100644
--- a/packages/miniapp-element/src/builtInComponents/picker-view.js
+++ b/packages/miniapp-element/src/builtInComponents/picker-view.js
@@ -1,9 +1,10 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'picker-view',
props: [{
name: 'value',
+ canBeUserChanged: true,
get(domNode) {
let value = domNode.getAttribute('value');
if (typeof value === 'string') value = value.split(',').map(item => parseInt(item, 10));
@@ -38,16 +39,20 @@ export default {
}],
handles: {
onPickerViewChange(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
- this.domNode.$$setAttributeWithoutUpdate('value', evt.detail.value);
- callSimpleEvent('change', evt, this.domNode);
+ domNode.$$setAttributeWithoutUpdate('value', evt.detail.value);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.value = evt.detail.value;
+ callSingleEvent('change', evt, this);
},
onPickerViewPickstart(evt) {
- callSimpleEvent('pickstart', evt, this.domNode);
+ callSingleEvent('pickstart', evt, this);
},
onPickerViewPickend(evt) {
- callSimpleEvent('pickend', evt, this.domNode);
+ callSingleEvent('pickend', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/picker.js b/packages/miniapp-element/src/builtInComponents/picker.js
index ad2826707d..c652149e79 100644
--- a/packages/miniapp-element/src/builtInComponents/picker.js
+++ b/packages/miniapp-element/src/builtInComponents/picker.js
@@ -1,6 +1,6 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { isWeChatMiniProgram } from 'universal-env';
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
const picker = {
name: 'picker',
@@ -10,6 +10,11 @@ const picker = {
get(domNode) {
return !!domNode.getAttribute('disabled');
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'range',
get(domNode) {
@@ -23,6 +28,7 @@ const picker = {
},
}, {
name: 'value',
+ canBeUserChanged: true,
get(domNode) {
const mode = domNode.getAttribute('mode') || 'selector';
const value = domNode.getAttribute('value');
@@ -47,13 +53,16 @@ const picker = {
],
handles: {
onPickerChange(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
- this.domNode.$$setAttributeWithoutUpdate('value', evt.detail.value);
- callSimpleEvent('change', evt, this.domNode);
+ domNode.$$setAttributeWithoutUpdate('value', evt.detail.value);
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.value = evt.detail.value;
+ callSingleEvent('change', evt, this);
},
onPickerCancel(evt) {
- callSimpleEvent('cancel', evt, this.domNode);
+ callSingleEvent('cancel', evt, this);
},
}
};
@@ -88,7 +97,7 @@ if (isWeChatMiniProgram) {
}
]);
picker.handles.onPickerColumnChange = function(evt) {
- callSimpleEvent('columnchange', evt, this.domNode);
+ callSingleEvent('columnchange', evt, this);
};
}
diff --git a/packages/miniapp-element/src/builtInComponents/progress.js b/packages/miniapp-element/src/builtInComponents/progress.js
index 13dc07aeac..b841a7d302 100644
--- a/packages/miniapp-element/src/builtInComponents/progress.js
+++ b/packages/miniapp-element/src/builtInComponents/progress.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'progress',
@@ -60,7 +60,7 @@ export default {
}],
handles: {
onProgressActiveEnd(evt) {
- callSimpleEvent('activeend', evt, this.domNode);
+ callSingleEvent('activeend', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/radio-group.js b/packages/miniapp-element/src/builtInComponents/radio-group.js
index 30157eaf5e..30aef5735f 100644
--- a/packages/miniapp-element/src/builtInComponents/radio-group.js
+++ b/packages/miniapp-element/src/builtInComponents/radio-group.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'radio-group',
@@ -10,7 +10,7 @@ export default {
}],
handles: {
onRadioChange(evt) {
- callSimpleEvent('change', evt, this.domNode);
+ callSingleEvent('change', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/radio.js b/packages/miniapp-element/src/builtInComponents/radio.js
index 7e2837e917..5ef1d1a62e 100644
--- a/packages/miniapp-element/src/builtInComponents/radio.js
+++ b/packages/miniapp-element/src/builtInComponents/radio.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'radio',
@@ -7,6 +7,11 @@ export default {
get(domNode) {
return domNode.getAttribute('value') || '';
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'checked',
get(domNode) {
@@ -25,7 +30,7 @@ export default {
}],
handles: {
onRadioChange(evt) {
- callSimpleEvent('change', evt, this.domNode);
+ callSingleEvent('change', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/scroll-view.js b/packages/miniapp-element/src/builtInComponents/scroll-view.js
index 3bdf8bedd2..3e93d56259 100644
--- a/packages/miniapp-element/src/builtInComponents/scroll-view.js
+++ b/packages/miniapp-element/src/builtInComponents/scroll-view.js
@@ -1,6 +1,8 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { isWeChatMiniProgram } from 'universal-env';
+import callSingleEvent from '../events/callSingleEvent';
-export default {
+const ScrollView = {
name: 'scroll-view',
props: [{
name: 'scrollX',
@@ -26,18 +28,21 @@ export default {
},
}, {
name: 'scrollTop',
+ canBeUserChanged: true,
get(domNode) {
const value = parseInt(domNode.getAttribute('scroll-top'), 10);
return !isNaN(value) ? value : '';
},
}, {
name: 'scrollLeft',
+ canBeUserChanged: true,
get(domNode) {
const value = parseInt(domNode.getAttribute('scroll-left'), 10);
return !isNaN(value) ? value : '';
},
}, {
name: 'scrollIntoView',
+ canBeUserChanged: true,
get(domNode) {
return domNode.getAttribute('scroll-into-view') || '';
},
@@ -68,14 +73,46 @@ export default {
}
}],
handles: {
- onScrollToUpper(evt) {
- callSimpleEvent('scrolltoupper', evt, this.domNode);
+ onScrollViewScrolltoupper(evt) {
+ callSingleEvent('scrolltoupper', evt, this);
},
- onScrollToLower(evt) {
- callSimpleEvent('scrolltolower', evt, this.domNode);
+ onScrollViewScrolltolower(evt) {
+ callSingleEvent('scrolltolower', evt, this);
},
- onScroll(evt) {
- callSimpleEvent('scroll', evt, this.domNode);
+ onScrollViewScroll(evt) {
+ const domNode = this.getDomNodeFromEvt('scroll', evt);
+ if (!domNode) return;
+ domNode.$$setAttributeWithoutUpdate('scroll-into-view', '');
+ domNode.$$setAttributeWithoutUpdate('scroll-top', evt.detail.scrollTop);
+ domNode.$$setAttributeWithoutUpdate('scroll-left', evt.detail.scrollLeft);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.scrollIntoView = '';
+ domNode.__oldValues.scrollTop = evt.detail.scrollTop;
+ domNode.__oldValues.scrollLeft = evt.detail.scrollLeft;
+ callSingleEvent('scroll', evt, this);
},
},
};
+
+if (isWeChatMiniProgram) {
+ Object.assign(ScrollView.handles, {
+ onScrollViewRefresherPulling(evt) {
+ callSingleEvent('refresherpulling', evt, this);
+ },
+
+ onScrollViewRefresherRefresh(evt) {
+ callSingleEvent('refresherrefresh', evt, this);
+ },
+
+ onScrollViewRefresherRestore(evt) {
+ callSingleEvent('refresherrestore', evt, this);
+ },
+
+ onScrollViewRefresherAbort(evt) {
+ callSingleEvent('refresherabort', evt, this);
+ },
+ });
+}
+
+export default ScrollView;
diff --git a/packages/miniapp-element/src/builtInComponents/slider.js b/packages/miniapp-element/src/builtInComponents/slider.js
index d0b751cd68..0700141144 100644
--- a/packages/miniapp-element/src/builtInComponents/slider.js
+++ b/packages/miniapp-element/src/builtInComponents/slider.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'slider',
@@ -26,9 +26,15 @@ export default {
},
}, {
name: 'value',
+ canBeUserChanged: true,
get(domNode) {
return +domNode.getAttribute('value') || 0;
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'color',
get(domNode) {
@@ -73,13 +79,16 @@ export default {
}],
handles: {
onSliderChange(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
- this.domNode.$$setAttributeWithoutUpdate('value', evt.detail.value);
- callSimpleEvent('change', evt, this.domNode);
+ domNode.$$setAttributeWithoutUpdate('value', evt.detail.value);
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.value = evt.detail.value;
+ callSingleEvent('change', evt, this);
},
onSliderChanging(evt) {
- callSimpleEvent('changing', evt, this.domNode);
+ callSingleEvent('changing', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/swiper.js b/packages/miniapp-element/src/builtInComponents/swiper.js
index d09cd747fc..febce6f140 100644
--- a/packages/miniapp-element/src/builtInComponents/swiper.js
+++ b/packages/miniapp-element/src/builtInComponents/swiper.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'swiper',
@@ -24,6 +24,7 @@ export default {
},
}, {
name: 'current',
+ canBeUserChanged: true,
get(domNode) {
return +domNode.getAttribute('current') || 0;
},
@@ -83,16 +84,19 @@ export default {
}],
handles: {
onSwiperChange(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
- this.domNode.$$setAttributeWithoutUpdate('current', evt.detail.current);
- callSimpleEvent('change', evt, this.domNode);
+ domNode.$$setAttributeWithoutUpdate('current', evt.detail.current);
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.current = evt.detail.current;
+ callSingleEvent('change', evt, this);
},
onSwiperTransition(evt) {
- callSimpleEvent('transition', evt, this.domNode);
+ callSingleEvent('transition', evt, this);
},
onSwiperAnimationfinish(evt) {
- callSimpleEvent('animationfinish', evt, this.domNode);
+ callSingleEvent('animationfinish', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/switch.js b/packages/miniapp-element/src/builtInComponents/switch.js
index 5360438564..95dc62cd36 100644
--- a/packages/miniapp-element/src/builtInComponents/switch.js
+++ b/packages/miniapp-element/src/builtInComponents/switch.js
@@ -1,9 +1,10 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'switch',
props: [{
name: 'checked',
+ canBeUserChanged: true,
get(domNode) {
return !!domNode.getAttribute('checked');
},
@@ -12,6 +13,11 @@ export default {
get(domNode) {
return !!domNode.getAttribute('disabled');
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'type',
get(domNode) {
@@ -30,10 +36,15 @@ export default {
}],
handles: {
onSwitchChange(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('change', evt);
+ if (!domNode) return;
+
+ domNode.$$setAttributeWithoutUpdate('checked', evt.detail.value);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.checked = evt.detail.value;
- this.domNode.setAttribute('checked', evt.detail.value);
- callSimpleEvent('change', evt, this.domNode);
+ callSingleEvent('change', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/textarea.js b/packages/miniapp-element/src/builtInComponents/textarea.js
index efb680a2f8..e7117384be 100644
--- a/packages/miniapp-element/src/builtInComponents/textarea.js
+++ b/packages/miniapp-element/src/builtInComponents/textarea.js
@@ -1,13 +1,20 @@
import callSimpleEvent from '../events/callSimpleEvent';
import callEvent from '../events/callEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'textarea',
props: [{
name: 'value',
+ canBeUserChanged: true,
get(domNode) {
return domNode.value || '';
},
+ }, {
+ name: 'name',
+ get(domNode) {
+ return domNode.getAttribute('name') || '';
+ },
}, {
name: 'placeholder',
get(domNode) {
@@ -99,37 +106,59 @@ export default {
get(domNode) {
return domNode.getAttribute('animation');
}
+ }, {
+ name: 'controlled',
+ get(domNode) {
+ return !!domNode.getAttribute('controlled');
+ },
}],
handles: {
onTextareaFocus(evt) {
- this._textareaOldValue = this.domNode.value;
- callSimpleEvent('focus', evt, this.domNode);
+ const domNode = this.getDomNodeFromEvt('focus', evt);
+ if (!domNode) return;
+ domNode.__textareaOldValue = domNode.value;
+ domNode.$$setAttributeWithoutUpdate('focus', true);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.focus = true;
+ callSimpleEvent('focus', evt, domNode);
},
onTextareaBlur(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('blur', evt);
+ if (!domNode) return;
+
+ domNode.$$setAttributeWithoutUpdate('focus', false);
- this.domNode.setAttribute('focus', false);
- if (this._textareaOldValue !== undefined && this.domNode.value !== this._textareaOldValue) {
- this._textareaOldValue = undefined;
- this.callEvent('change', evt);
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.focus = false;
+ if (this.__textareaOldValue !== undefined && domNode.value !== this.__textareaOldValue) {
+ this.__textareaOldValue = undefined;
+ callEvent('change', evt, this.pageId, this.nodeId);
}
- callSimpleEvent('blur', evt, this.domNode);
+ callSimpleEvent('blur', evt, domNode);
},
onTextareaLineChange(evt) {
- callSimpleEvent('linechange', evt, this.domNode);
+ const domNode = this.getDomNodeFromEvt('linechange', evt);
+ callSimpleEvent('linechange', evt, domNode);
},
onTextareaInput(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('blur', evt);
+ if (!domNode) return;
const value = '' + evt.detail.value;
- this.domNode.setAttribute('value', value);
+ domNode.$$setAttributeWithoutUpdate('value', value);
+
+ domNode.__oldValues = domNode.__oldValues || {};
+ domNode.__oldValues.value = value;
+
callEvent('input', evt, null, this.pageId, this.nodeId);
},
onTextareaConfirm(evt) {
- callSimpleEvent('confirm', evt, this.domNode);
+ const domNode = this.getDomNodeFromEvt('confirm', evt);
+ callSimpleEvent('confirm', evt, domNode);
},
onTextareaKeyBoardHeightChange(evt) {
- callSimpleEvent('keyboardheightchange', this.domNode);
+ callSingleEvent('keyboardheightchange', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/video.js b/packages/miniapp-element/src/builtInComponents/video.js
index eb17f7034b..7563ba997c 100644
--- a/packages/miniapp-element/src/builtInComponents/video.js
+++ b/packages/miniapp-element/src/builtInComponents/video.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'video',
@@ -150,34 +150,36 @@ export default {
}],
handles: {
onVideoPlay(evt) {
- callSimpleEvent('play', evt, this.domNode);
+ callSingleEvent('play', evt, this);
},
onVideoPause(evt) {
- callSimpleEvent('pause', evt, this.domNode);
+ callSingleEvent('pause', evt, this);
},
onVideoEnded(evt) {
- callSimpleEvent('ended', evt, this.domNode);
+ callSingleEvent('ended', evt, this);
},
onVideoTimeUpdate(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('timeupdate', evt);
+ if (!domNode) return;
- this.domNode.$$setAttributeWithoutUpdate('currentTime', evt.detail.currentTime);
- callSimpleEvent('timeupdate', evt, this.domNode);
+ domNode.$$setAttributeWithoutUpdate('currentTime', evt.detail.currentTime);
+ callSingleEvent('timeupdate', evt, this);
},
onVideoFullScreenChange(evt) {
- callSimpleEvent('fullscreenchange', evt, this.domNode);
+ callSingleEvent('fullscreenchange', evt, this);
},
onVideoWaiting(evt) {
- callSimpleEvent('waiting', evt, this.domNode);
+ callSingleEvent('waiting', evt, this);
},
onVideoError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
onVideoProgress(evt) {
- if (!this.domNode) return;
+ const domNode = this.getDomNodeFromEvt('progress', evt);
+ if (!domNode) return;
- this.domNode.$$setAttributeWithoutUpdate('buffered', evt.detail.buffered);
- callSimpleEvent('progress', evt, this.domNode);
+ domNode.$$setAttributeWithoutUpdate('buffered', evt.detail.buffered);
+ callSingleEvent('progress', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/builtInComponents/web-view.js b/packages/miniapp-element/src/builtInComponents/web-view.js
index 9d530fa9b5..bad28f7cf2 100644
--- a/packages/miniapp-element/src/builtInComponents/web-view.js
+++ b/packages/miniapp-element/src/builtInComponents/web-view.js
@@ -1,4 +1,4 @@
-import callSimpleEvent from '../events/callSimpleEvent';
+import callSingleEvent from '../events/callSingleEvent';
export default {
name: 'web-view',
@@ -15,13 +15,13 @@ export default {
}],
handles: {
onWebviewMessage(evt) {
- callSimpleEvent('message', evt, this.domNode);
+ callSingleEvent('message', evt, this);
},
onWebviewLoad(evt) {
- callSimpleEvent('load', evt, this.domNode);
+ callSingleEvent('load', evt, this);
},
onWebviewError(evt) {
- callSimpleEvent('error', evt, this.domNode);
+ callSingleEvent('error', evt, this);
},
},
};
diff --git a/packages/miniapp-element/src/constants.js b/packages/miniapp-element/src/constants.js
index 7ec47bb4f4..e7aed640d4 100644
--- a/packages/miniapp-element/src/constants.js
+++ b/packages/miniapp-element/src/constants.js
@@ -1,11 +1,78 @@
-export const ELEMENT_DIFF_KEYS = ['nodeId', 'pageId', 'tagName', 'compName', 'id',
- 'class', 'style', 'src', 'mode', 'lazyLoad', 'showMenuByLongpress',
- 'isImage', 'isLeaf', 'isSimple', 'content', 'extra', 'animation'];
+export const ELEMENT_DIFF_KEYS = [
+ 'nodeId',
+ 'pageId',
+ 'tagName',
+ 'compName',
+ 'id',
+ 'className',
+ 'style',
+ 'src',
+ 'mode',
+ 'lazyLoad',
+ 'showMenuByLongpress',
+ 'useTemplate',
+ 'isImage',
+ 'isLeaf',
+ 'isSimple',
+ 'content',
+ 'extra',
+ 'animation',
+];
export const TEXT_NODE_DIFF_KEYS = ['nodeId', 'pageId', 'content'];
-export const NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT = ['movable-view', 'swiper-item', 'picker-view-column'];
+export const NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT = [
+ 'movable-view',
+ 'swiper-item',
+ 'picker-view-column',
+];
+export const NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT_PARENT = [
+ 'swiper',
+ 'movable-area',
+];
export const NOT_SUPPORT = ['IFRAME', 'A'];
// The nodes that class and style need to be separated
-export const NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT = ['INPUT', 'TEXTAREA', 'VIDEO',
- 'CANVAS', 'BUILTIN-COMPONENT', 'CUSTOM-COMPONENT'];
+export const NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT = [
+ 'BUILTIN-COMPONENT',
+ 'CUSTOM-COMPONENT',
+];
+export const USE_TEMPLATE = [
+ 'cover-image',
+ 'movable-area',
+ 'movable-view',
+ 'swiper',
+ 'swiper-item',
+ 'icon',
+ 'progress',
+ 'rich-text',
+ 'button',
+ 'editor',
+ 'form',
+ 'INPUT',
+ 'picker',
+ 'slider',
+ 'switch',
+ 'TEXTAREA',
+ 'navigator',
+ 'camera',
+ 'image',
+ 'live-player',
+ 'live-pusher',
+ 'label',
+ 'radio',
+ 'radio-group',
+ 'checkbox',
+ 'checkbox-group',
+ 'VIDEO',
+ 'map',
+ 'CANVAS',
+ 'ad',
+ 'official-account',
+ 'open-data',
+ 'web-view',
+];
// The nodes that must be render as custom components
-export const NEET_RENDER_TO_CUSTOM_ELEMENT = [...NOT_SUPPORT, ...NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT];
+export const NEET_RENDER_TO_CUSTOM_ELEMENT = [
+ ...NOT_SUPPORT,
+ ...NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT,
+];
+
+export const IN_COVER = ['cover-view'];
diff --git a/packages/miniapp-element/src/events/callEvent.js b/packages/miniapp-element/src/events/callEvent.js
index cee339b950..1eadbdd0d2 100644
--- a/packages/miniapp-element/src/events/callEvent.js
+++ b/packages/miniapp-element/src/events/callEvent.js
@@ -1,3 +1,5 @@
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { isWeChatMiniProgram } from 'universal-env';
import render from 'miniapp-render';
import checkEventAccessDomNode from '../vdom/checkEventAccessDomNode';
import findParentNode from '../vdom/findParentNode';
@@ -6,8 +8,7 @@ import callSimpleEvent from './callSimpleEvent';
const { cache, EventTarget } = render.$$adapter;
export default function(eventName, evt, extra, pageId, nodeId) {
- const originNodeId =
- evt.currentTarget.dataset.privateNodeId || nodeId;
+ const originNodeId = evt.currentTarget.dataset.privateNodeId || nodeId;
const originNode = cache.getNode(pageId, originNodeId);
if (!originNode) return;
@@ -18,202 +19,152 @@ export default function(eventName, evt, extra, pageId, nodeId) {
evt,
extra,
(domNode, evt, isCapture) => {
- // Delay triggering the jump until all synchronous callback processing is complete
- setTimeout(() => {
- if (evt.cancelable) return;
- const window = cache.getWindow();
+ if (isWeChatMiniProgram) {
+ setTimeout(() => {
+ if (evt.cancelable) return;
+ const window = cache.getWindow();
- // Handle special node event
- if (
- domNode.tagName === 'LABEL' &&
- evt.type === 'click' &&
- !isCapture
- ) {
- // Handle label
- const forValue = domNode.getAttribute('for');
- let targetDomNode;
- if (forValue) {
- targetDomNode = window.document.getElementById(forValue);
- } else {
- targetDomNode = domNode.querySelector('input');
-
- // Find switch node
- if (!targetDomNode)
- targetDomNode = domNode.querySelector(
- 'builtin-component[behavior=switch]'
- );
- }
+ 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.getAttribute('disabled'))
- return;
+ if (!targetDomNode)
+ targetDomNode = domNode.querySelector(
+ 'builtIn-component[behavior=switch]'
+ );
+ }
- // Find target node
- if (targetDomNode.tagName === 'INPUT') {
- if (checkEventAccessDomNode(evt, targetDomNode, domNode))
+ if (!targetDomNode || !!targetDomNode.getAttribute('disabled'))
return;
- const type = targetDomNode.type;
- if (type === 'radio') {
- targetDomNode.setAttribute('checked', true);
- const name = targetDomNode.name;
- const otherDomNodes =
- window.document.querySelectorAll(`input[name=${name}]`) ||
- [];
- for (const otherDomNode of otherDomNodes) {
- if (
- otherDomNode.type === 'radio' &&
- otherDomNode !== targetDomNode
- ) {
- otherDomNode.setAttribute('checked', false);
- }
- }
- callSimpleEvent(
- 'change',
- { detail: { value: targetDomNode.value } },
- targetDomNode
- );
- } else if (type === 'checkbox') {
- targetDomNode.setAttribute('checked', !targetDomNode.checked);
- callSimpleEvent(
- 'change',
- {
- detail: {
- value: targetDomNode.checked
- ? [targetDomNode.value]
- : []
- }
- },
- targetDomNode
- );
- } else {
+ if (targetDomNode.tagName === 'INPUT') {
+ if (checkEventAccessDomNode(evt, targetDomNode, domNode)) return;
targetDomNode.focus();
- }
- } else if (targetDomNode.tagName === 'BUILTIN-COMPONENT') {
- if (checkEventAccessDomNode(evt, targetDomNode, domNode))
- return;
+ } 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);
- callSimpleEvent(
- 'change',
- { detail: { value: checked } },
- targetDomNode
- );
+ const behavior = targetDomNode.behavior;
+ if (behavior === 'switch') {
+ const checked = !targetDomNode.getAttribute('checked');
+ targetDomNode.setAttribute('checked', checked);
+ callSimpleEvent(
+ 'change',
+ { detail: { value: checked } },
+ targetDomNode
+ );
+ }
}
- }
- } else if (
- (domNode.tagName === 'BUTTON' ||
- domNode.tagName === 'BUILTIN-COMPONENT' &&
- domNode.behavior === 'button') &&
- evt.type === 'click' &&
- !isCapture
- ) {
- // Handle button click
- 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');
+ } 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;
+ 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'));
+ 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 => {
- if (item.type === 'radio') {
- if (item.checked) formData[item.name] = item.value;
- } else if (item.type === 'checkbox') {
- formData[item.name] = formData[item.name] || [];
- if (item.checked) formData[item.name].push(item.value);
- } else {
+ if (type === 'submit') {
+ const formData = {};
+ if (inputList.length) {
+ inputList.forEach((item) => {
formData[item.name] = item.value;
- }
- });
- }
- if (textareaList.length)
- textareaList.forEach(
- item => formData[item.getAttribute('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'
- )
- );
+ });
+ }
+ 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'
+ )
+ );
- callSimpleEvent(
- 'submit',
- { detail: { value: formData }, extra: { $$from: 'button' } },
- form
- );
- } else if (type === 'reset') {
- if (inputList.length) {
- inputList.forEach(item => {
- if (item.type === 'radio') {
- item.setAttribute('checked', false);
- } else if (item.type === 'checkbox') {
- item.setAttribute('checked', false);
- } else {
- 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)
+ const detail = { value: formData };
+ if (form._formId) {
+ detail.formId = form._formId;
+ form._formId = null;
+ }
+ 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)
+ );
- callSimpleEvent(
- 'reset',
- { extra: { $$from: 'button' } },
- form
- );
+ callSimpleEvent('reset', { extra: { $$from: 'button' } }, form);
+ }
}
- }
- }, 0);
+ }, 0);
+ }
}
);
}
diff --git a/packages/miniapp-element/src/events/callSingleEvent.js b/packages/miniapp-element/src/events/callSingleEvent.js
new file mode 100644
index 0000000000..7d47a5063c
--- /dev/null
+++ b/packages/miniapp-element/src/events/callSingleEvent.js
@@ -0,0 +1,22 @@
+import { $$adapter } from 'miniapp-render';
+
+const { Event } = $$adapter;
+
+export default function callSingleEvent(eventName, evt, nativeComponent) {
+ const domNode = nativeComponent.getDomNodeFromEvt(eventName, evt);
+ if (!domNode) return;
+
+ domNode.$$trigger(eventName, {
+ event: new Event({
+ timeStamp: evt && evt.timeStamp,
+ touches: evt && evt.touches,
+ changedTouches: evt && evt.changedTouches,
+ name: eventName,
+ target: domNode,
+ eventPhase: Event.AT_TARGET,
+ detail: evt && evt.detail,
+ $$extra: evt && evt.extra,
+ }),
+ currentTarget: domNode,
+ });
+}
diff --git a/packages/miniapp-element/src/index.js b/packages/miniapp-element/src/index.js
index ed6a677d96..a0c5b040cd 100755
--- a/packages/miniapp-element/src/index.js
+++ b/packages/miniapp-element/src/index.js
@@ -6,7 +6,7 @@ import checkComponentAttr from './vdom/checkComponentAttr';
import dealWithLeafAndSimple from './vdom/dealWithLeafAndSimple';
import init from './init';
import { componentNameMap, handlesMap } from './component';
-import { NOT_SUPPORT } from './constants';
+import { NOT_SUPPORT, IN_COVER } from './constants';
import getInitialProps from './adapter/getInitialProps';
import getId from './adapter/getId';
import getLifeCycle from './adapter/getLifeCycle';
@@ -23,7 +23,6 @@ const config = {
data: {
builtinComponentName: '', // the builtIn component name
customComponentName: '', // current render custom component name
- innerChildNodes: [], // BuiltIn component children
childNodes: []
},
...getInitialProps(),
@@ -37,45 +36,22 @@ const config = {
if (!this.pageId || !this.nodeId) return;
// child nodes update
- const childNodes = filterNodes(this.domNode, DOM_SUB_TREE_LEVEL - 1);
- const oldChildNodes =
- this.data.builtinComponentName || this.data.customComponentName
- ? this.data.innerChildNodes
- : this.data.childNodes;
- if (checkDiffChildNodes(childNodes, oldChildNodes)) {
- const dataChildNodes = dealWithLeafAndSimple(
- childNodes,
- this.onChildNodesUpdate
- );
- const newData = {};
- if (this.data.builtinComponentName || this.data.customComponentName) {
- // builtIn component/custom component
- newData.innerChildNodes = dataChildNodes;
- newData.childNodes = [];
- } else {
- // normal tag
- newData.innerChildNodes = [];
- newData.childNodes = dataChildNodes;
- }
- this.setData(newData);
+ const childNodes = filterNodes(this.domNode, DOM_SUB_TREE_LEVEL - 1, this);
+ if (checkDiffChildNodes(childNodes, this.data.childNodes)) {
+ this.setData({
+ childNodes: dealWithLeafAndSimple(childNodes, this.onChildNodesUpdate),
+ });
}
// dispatch child update
const childNodeStack = [].concat(childNodes);
let childNode = childNodeStack.pop();
while (childNode) {
- if (
- childNode.type === 'element' &&
- !childNode.isLeaf &&
- !childNode.isSimple
- ) {
+ if (childNode.type === 'element' && !childNode.isImage && !childNode.isLeaf && !childNode.isSimple && !childNode.useTemplate) {
childNode.domNode.$$trigger('$$childNodesUpdate');
}
- if (childNode.childNodes && childNode.childNodes.length)
- childNode.childNodes.forEach(subChildNode =>
- childNodeStack.push(subChildNode)
- );
+ if (childNode.childNodes && childNode.childNodes.length) childNode.childNodes.forEach(subChildNode => childNodeStack.push(subChildNode));
childNode = childNodeStack.pop();
}
},
@@ -117,12 +93,29 @@ const config = {
// Replaced html tag
const builtinComponentName = componentNameMap[tagName.toLowerCase()];
if (builtinComponentName)
- checkComponentAttr(this, builtinComponentName, newAttrData);
+ newData.builtinComponentName = builtinComponentName;
}
this.setData(newData);
},
+ onAppear(evt) {
+ const pageId = this.pageId;
+ const originNodeId =
+ evt.currentTarget.dataset.privateNodeId || this.nodeId;
+ const originNode = cache.getNode(pageId, originNodeId);
+
+ if (!originNode) return;
+ callSimpleEvent('appear', evt, originNode);
+ },
+ onDisappear(evt) {
+ const pageId = this.pageId;
+ const originNodeId =
+ evt.currentTarget.dataset.privateNodeId || this.nodeId;
+ const originNode = cache.getNode(pageId, originNodeId);
+ if (!originNode) return;
+ callSimpleEvent('disappear', evt, originNode);
+ },
// Dom event
onTouchStart(evt) {
if (this.document && this.document.$$checkEvent(evt)) {
@@ -169,6 +162,22 @@ const config = {
callSimpleEvent('error', evt, originNode);
},
+ getDomNodeFromEvt(eventName, evt) {
+ if (!evt) return;
+ const pageId = this.pageId;
+ let originNodeId = this.nodeId;
+ if (evt.currentTarget && evt.currentTarget.dataset.privateNodeId) {
+ originNodeId = evt.currentTarget.dataset.privateNodeId;
+ } else if (
+ eventName &&
+ eventName.indexOf('canvas') === 0 &&
+ evt.target &&
+ evt.target.dataset.privateNodeId
+ ) {
+ originNodeId = evt.target.dataset.privateNodeId;
+ }
+ return cache.getNode(pageId, originNodeId);
+ },
...handlesMap
}
};
@@ -193,11 +202,6 @@ const lifeCycles = getLifeCycle({
this.domNode = cache.getNode(pageId, nodeId);
if (!this.domNode) return;
- // TODO, for the sake of compatibility with a bug in the underlying library, is implemented as follows
- if (this.domNode.tagName === 'CANVAS') {
- this.domNode._builtInComponent = this;
- }
-
// Store document
this.document = cache.getDocument(pageId);
@@ -214,23 +218,16 @@ const lifeCycles = getLifeCycle({
// init
init(this, data);
+ if (IN_COVER.indexOf(data.builtinComponentName) !== -1) this.data.inCover = true;
// init child nodes
- const childNodes = filterNodes(this.domNode, DOM_SUB_TREE_LEVEL - 1);
- const dataChildNodes = dealWithLeafAndSimple(
+ const childNodes = filterNodes(this.domNode, DOM_SUB_TREE_LEVEL - 1, this);
+ data.childNodes = dealWithLeafAndSimple(
childNodes,
this.onChildNodesUpdate
);
- if (data.builtinComponentName || data.customComponentName) {
- // builtIn component/custom component
- data.innerChildNodes = dataChildNodes;
- data.childNodes = [];
- } else {
- // normal tag
- data.innerChildNodes = [];
- data.childNodes = dataChildNodes;
- }
- this.setData(data);
+
+ if (Object.keys(data).length) this.setData(data);
if (isMiniApp) {
if (this.domNode.tagName === 'CANVAS') {
this.domNode.$$trigger('canvasReady');
diff --git a/packages/miniapp-element/src/init.js b/packages/miniapp-element/src/init.js
index d7ec70c49d..7314f0de04 100644
--- a/packages/miniapp-element/src/init.js
+++ b/packages/miniapp-element/src/init.js
@@ -1,11 +1,13 @@
import { componentNameMap } from './component';
-import { NOT_SUPPORT } from './constants';
+import { NOT_SUPPORT, USE_TEMPLATE } from './constants';
import checkComponentAttr from './vdom/checkComponentAttr';
export default function(instance, data) {
const domNode = instance.domNode;
const tagName = domNode.tagName;
+ if (USE_TEMPLATE.indexOf(tagName) !== -1 || USE_TEMPLATE.indexOf(domNode.behavior) !== -1) return;
+
if (tagName === 'BUILTIN-COMPONENT') {
// BuildIn component
data.builtinComponentName = domNode.behavior;
@@ -24,6 +26,6 @@ export default function(instance, data) {
} else {
// Could be replaced html tag
const builtinComponentName = componentNameMap[tagName.toLowerCase()];
- if (builtinComponentName) checkComponentAttr(instance, builtinComponentName, data);
+ if (builtinComponentName) data.builtinComponentName = builtinComponentName;
}
}
diff --git a/packages/miniapp-element/src/templates/index.axml b/packages/miniapp-element/src/templates/index.axml
index 216b4ae160..bbe594e694 100644
--- a/packages/miniapp-element/src/templates/index.axml
+++ b/packages/miniapp-element/src/templates/index.axml
@@ -1,73 +1,16 @@
-
-
-
-
-
-
+>
-
-
-
-
+>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ onLongTap="onLongTap"
+ onTouchStart="onTouchStart"
+ onTouchEnd="onTouchEnd"
+ onTouchMove="onTouchEnd"
+ onTouchCancel="onTouchCancel"
+ onAppear="onAppear"
+ onDisAppear="onDisappear"
+>
+>
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ onTouchStart="onTouchStart"
+ onTouchEnd="onTouchEnd"
+ onTouchMove="onTouchEnd"
+ onTouchCancel="onTouchCancel"
+>
{{content}}
-
-
-
+>
+
+
+
+
diff --git a/packages/miniapp-element/src/templates/index.wxml b/packages/miniapp-element/src/templates/index.wxml
index d8b287a265..916592c72b 100644
--- a/packages/miniapp-element/src/templates/index.wxml
+++ b/packages/miniapp-element/src/templates/index.wxml
@@ -1,73 +1,17 @@
-
-
-
-
-
+>
-
-
-
-
+ scroll-anchoring="{{scrollAnchoring}}"
+ refresher-enabled="{{refresherEnabled}}"
+ refresher-threshold="{{refresherThreshold}}"
+ refresher-default-style="{{refresherDefaultStyle}}"
+ refresher-background="{{refresherBackground}}"
+ refresher-triggered="{{refresherTriggered}}"
+ bindscrolltoupper="onScrollViewScrolltoupper"
+ bindscrolltolower="onScrollViewScrolltolower"
+ bindscroll="onScrollViewScroll"
+ bindrefresherpulling="onScrollViewRefresherPulling"
+ bindrefresherrefresh="onScrollViewRefresherRefresh"
+ bindrefresherrestore="onScrollViewRefresherRestore"
+ bindrefresherabort="onScrollViewRefresherAbort"
+>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ bindtap="onTap"
+ onLongTap="onLongTap"
+ bindtouchstart="onTouchStart"
+ bindtouchend="onTouchEnd"
+ bindtouchmove="onTouchEnd"
+ bindtouchcancel="onTouchCancel"
+>
+>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ selectable="{{selectable}}"
+ space="{{space}}"
+ decode="{{decode}}"
+ bindtap="onTap"
+ bindtouchstart="onTouchStart"
+ bindtouchend="onTouchEnd"
+ bindtouchmove="onTouchEnd"
+ bindtouchcancel="onTouchCancel"
+>
{{content}}
-
-
-
+>
+
+
diff --git a/packages/miniapp-element/src/templates/inner-component.axml b/packages/miniapp-element/src/templates/inner-component.axml
new file mode 100644
index 0000000000..28366199f2
--- /dev/null
+++ b/packages/miniapp-element/src/templates/inner-component.axml
@@ -0,0 +1,635 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/miniapp-element/src/templates/inner-component.wxml b/packages/miniapp-element/src/templates/inner-component.wxml
new file mode 100644
index 0000000000..fac32e884b
--- /dev/null
+++ b/packages/miniapp-element/src/templates/inner-component.wxml
@@ -0,0 +1,778 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/miniapp-element/src/vdom/checkComponentAttr.js b/packages/miniapp-element/src/vdom/checkComponentAttr.js
index ba05c8306f..c992985825 100644
--- a/packages/miniapp-element/src/vdom/checkComponentAttr.js
+++ b/packages/miniapp-element/src/vdom/checkComponentAttr.js
@@ -1,7 +1,13 @@
import { propsMap } from '../component';
+import shallowEqual from './shallowEqual';
// Check component attribute
-export default function checkComponentAttr(instance, name, newData) {
+export default function checkComponentAttr(
+ instance,
+ name,
+ newData,
+ extraClass = ''
+) {
const oldData = instance.data;
const { domNode } = instance;
const attrs = propsMap[name];
@@ -9,21 +15,36 @@ export default function checkComponentAttr(instance, name, newData) {
newData.builtinComponentName = name;
if (attrs && attrs.length) {
- for (const {name, get} of attrs) {
+ for (const { name, get, canBeUserChanged = false } of attrs) {
const newValue = get(domNode);
- if (!oldData || oldData[name] !== newValue) newData[name] = newValue;
+ if (canBeUserChanged) {
+ const oldValues = domNode.__oldValues;
+ if (
+ !oldData ||
+ !shallowEqual(newValue, oldData[name]) ||
+ oldValues && !shallowEqual(newValue, oldValues[name])
+ ) {
+ newData[name] = newValue;
+ newData.forceUpdate = true;
+ }
+ } else if (!oldData || !shallowEqual(newValue, oldData[name])) {
+ newData[name] = newValue;
+ }
}
}
// Add id/class/style/hidden/animation
const newId = domNode.id;
if (!oldData || oldData.id !== newId) newData.id = newId;
- const newClass = `builtin-component-${name} node-${domNode.$$nodeId} ${domNode.className || ''}`;
- if (!oldData || oldData.class !== newClass) newData.class = newClass;
+ const newClass = `${extraClass} builtin-component-${name} node-${
+ domNode.$$nodeId
+ } ${domNode.className || ''}`;
+ if (!oldData || oldData.className !== newClass) newData.className = newClass;
const newStyle = domNode.style.cssText;
if (!oldData || oldData.style !== newStyle) newData.style = newStyle;
const newHidden = domNode.getAttribute('hidden') || false;
if (!oldData || oldData.hidden !== newHidden) newData.hidden = newHidden;
const newAnimation = domNode.getAttribute('animation');
- if (!oldData || oldData.animation !== newAnimation) newData.animation = newAnimation;
+ if (!oldData || oldData.animation !== newAnimation)
+ newData.animation = newAnimation;
}
diff --git a/packages/miniapp-element/src/vdom/checkDiffChildNodes.js b/packages/miniapp-element/src/vdom/checkDiffChildNodes.js
index 3fd7caeb6c..c7bbbe6343 100644
--- a/packages/miniapp-element/src/vdom/checkDiffChildNodes.js
+++ b/packages/miniapp-element/src/vdom/checkDiffChildNodes.js
@@ -1,4 +1,5 @@
import { ELEMENT_DIFF_KEYS, TEXT_NODE_DIFF_KEYS } from '../constants';
+import shallowEqual from './shallowEqual';
export default function checkDiffChildNodes(newChildNodes, oldChildNodes) {
if (newChildNodes.length !== oldChildNodes.length) return true;
@@ -14,16 +15,21 @@ export default function checkDiffChildNodes(newChildNodes, oldChildNodes) {
for (const key of keys) {
const newValue = newChild[key];
const oldValue = oldChild[key];
- if (typeof newValue === 'object') {
- // Diff object top level
+ if (typeof newValue === 'object' && !Array.isArray(newValue)) {
if (typeof oldValue !== 'object') return true;
+ if (key === 'extra' && newValue.forceUpdate) {
+ newValue.forceUpdate = false;
+ return true;
+ }
+
const objectKeys = Object.keys(newValue);
for (const objectKey of objectKeys) {
- if (newValue[objectKey] !== oldValue[objectKey]) return true;
+ if (!shallowEqual(newValue[objectKey], oldValue[objectKey])) return true;
}
+ } else if (!shallowEqual(newValue, oldValue)) {
+ return true;
}
- if (newValue !== oldValue) return true;
}
// Diff children
diff --git a/packages/miniapp-element/src/vdom/dealWithLeafAndSimple.js b/packages/miniapp-element/src/vdom/dealWithLeafAndSimple.js
index 50dc11e731..1cccad925c 100644
--- a/packages/miniapp-element/src/vdom/dealWithLeafAndSimple.js
+++ b/packages/miniapp-element/src/vdom/dealWithLeafAndSimple.js
@@ -4,7 +4,7 @@ export default function dealWithLeafAndSimple(childNodes, onChildNodesUpdate) {
childNodes = childNodes.map(originChildNode => {
const childNode = Object.assign({}, originChildNode);
- if (childNode.isLeaf || childNode.isSimple) {
+ if (childNode.isImage || childNode.isLeaf || childNode.isSimple || childNode.useTemplate) {
childNode.domNode.$$clearEvent('$$childNodesUpdate');
childNode.domNode.addEventListener('$$childNodesUpdate', onChildNodesUpdate);
}
diff --git a/packages/miniapp-element/src/vdom/filterNodes.js b/packages/miniapp-element/src/vdom/filterNodes.js
index e40cf9bdfa..4519e13251 100644
--- a/packages/miniapp-element/src/vdom/filterNodes.js
+++ b/packages/miniapp-element/src/vdom/filterNodes.js
@@ -1,84 +1,159 @@
-import render from 'miniapp-render';
-import { propsMap } from '../component';
+import { propsMap, componentNameMap } from '../component';
import {
- NOT_SUPPORT, NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT,
- NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT, NEET_RENDER_TO_CUSTOM_ELEMENT
+ NOT_SUPPORT,
+ NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT,
+ NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT,
+ NEET_RENDER_TO_CUSTOM_ELEMENT,
+ USE_TEMPLATE,
+ NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT_PARENT,
} from '../constants';
-
-const { cache, tool } = render.$$adapter;
+import checkComponentAttr from './checkComponentAttr';
// Filter nodes only reserve childs
-export default function filterNodes(domNode, level) {
+export default function filterNodes(domNode, level, component) {
const childNodes = domNode.childNodes || [];
if (!childNodes.map) return [];
// Tags are not supported and child nodes are not rendered
if (NOT_SUPPORT.indexOf(domNode.tagName) >= 0) return [];
- return childNodes.map(child => {
- const domInfo = child.$$domInfo;
+ return childNodes
+ .map((child) => {
+ const domInfo = child.$$domInfo;
- if (domInfo.type !== 'element' && domInfo.type !== 'text') return;
+ if (domInfo.type !== 'element' && domInfo.type !== 'text') return;
- // Add default class
- domInfo.class = `h5-${domInfo.tagName} node-${domInfo.nodeId} ${domInfo.class || ''}`;
- domInfo.domNode = child;
+ // Add default class
+ domInfo.className =
+ domInfo.type === 'element'
+ ? `h5-${domInfo.tagName} node-${domInfo.nodeId} ${
+ domInfo.className || ''
+ }`
+ : '';
+ domInfo.domNode = child;
- // Special node
- if (NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT.indexOf(child.tagName) >= 0) {
- if (domInfo.tagName === 'builtin-component' && NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT.indexOf(child.behavior) !== -1) {
- domInfo.compName = child.behavior;
- domInfo.extra = {
- hidden: child.getAttribute('hidden') || false,
- };
+ // Special node
+ if (
+ NEET_SPLIT_CLASS_STYLE_FROM_CUSTOM_ELEMENT.indexOf(child.tagName) >= 0
+ ) {
+ if (
+ domInfo.tagName === 'builtin-component' &&
+ NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT.indexOf(child.behavior) !== -1
+ ) {
+ domInfo.compName = child.behavior;
+ domInfo.extra = {
+ hidden: child.getAttribute('hidden') || false,
+ };
- // Add special component props
- const props = propsMap[child.behavior] || {};
- if (props && props.length) {
- props.forEach(({name, get}) => {
- domInfo.extra[name] = get(child);
- });
- }
+ // Add special component props
+ const props = propsMap[child.behavior] || {};
+ if (props && props.length) {
+ props.forEach(({ name, get }) => {
+ domInfo.extra[name] = get(child);
+ });
+ }
- if (child.children.length && level > 0) {
- domInfo.childNodes = filterNodes(child, level - 1);
+ if (child.children.length && level > 0) {
+ domInfo.childNodes = filterNodes(child, level - 1, component);
+ }
+ return domInfo;
}
- return domInfo;
+
+ // id and style are excluded
+ domInfo.className = `h5-${domInfo.tagName} ${
+ domInfo.tagName === 'builtin-component'
+ ? 'builtin-' + child.behavior
+ : ''
+ }`;
+ domInfo.id = '';
+ domInfo.style = '';
}
- // id and style are excluded
- domInfo.class = `h5-${domInfo.tagName} ${domInfo.tagName === 'builtin-component' ? 'builtin-' + child.behavior : ''}`;
- domInfo.id = '';
- domInfo.style = '';
- }
+ // Check image node
+ domInfo.isImage = domInfo.type === 'element' && domInfo.tagName === 'img';
+ if (domInfo.isImage) {
+ domInfo.src = child.src || '';
+ domInfo.mode = child.getAttribute('mode') || '';
+ domInfo.lazyLoad = !!child.getAttribute('lazy-load');
+ domInfo.showMenuByLongpress = !!child.getAttribute(
+ 'show-menu-by-longpress'
+ );
+ } else {
+ domInfo.src = '';
+ domInfo.mode = '';
+ domInfo.lazyLoad = false;
+ domInfo.showMenuByLongpress = false;
+ }
- // Check image node
- domInfo.isImage = domInfo.type === 'element' && domInfo.tagName === 'img';
- if (domInfo.isImage) {
- domInfo.src = child.src || '';
- domInfo.mode = child.getAttribute('mode') || '';
- domInfo.lazyLoad = !!child.getAttribute('lazy-load');
- domInfo.showMenuByLongpress = !!child.getAttribute('show-menu-by-longpress');
- } else {
- domInfo.src = '';
- domInfo.mode = '';
- domInfo.lazyLoad = false;
- domInfo.showMenuByLongpress = false;
- }
+ // Check wheather use template
+ const templateName =
+ domInfo.tagName === 'builtin-component'
+ ? child.behavior
+ : child.tagName;
+ domInfo.useTemplate =
+ !domInfo.isImage && USE_TEMPLATE.indexOf(templateName) !== -1;
+ if (domInfo.useTemplate) {
+ const compName = componentNameMap[templateName.toLowerCase()];
+ const extra = {};
+ if (compName)
+ checkComponentAttr(
+ domInfo,
+ compName,
+ extra,
+ `h5-${domInfo.tagName} ${
+ domInfo.tagName === 'builtin-component'
+ ? 'builtin-' + child.behavior
+ : ''
+ }`
+ );
+ extra.pageId = domInfo.pageId;
+ extra.nodeId = domInfo.nodeId;
+ extra.inCover = component.data.inCover;
+ extra.hasChildren = !!child.childNodes.length;
+ domInfo.extra = extra;
- // Check child nodes
- domInfo.isLeaf = !domInfo.isImage && domInfo.type === 'element' && !child.children.length && NEET_RENDER_TO_CUSTOM_ELEMENT.indexOf(child.tagName.toUpperCase()) === -1;
- if (domInfo.isLeaf) {
- domInfo.content = child.childNodes.map(childNode => childNode.$$domInfo.type === 'text' ? childNode.textContent : '').join('');
- }
+ if (
+ NEET_BEHAVIOR_NORMAL_CUSTOM_ELEMENT_PARENT.indexOf(templateName) !==
+ -1
+ ) {
+ const childNodes = filterNodes(child, 0, component) || [];
+ extra.childNodes = childNodes.map((childNode) => {
+ const copyChildNode = Object.assign({}, childNode);
+ delete copyChildNode.domNode;
+ return copyChildNode;
+ });
+ }
+ }
- // Check simple node that can be rendered as view
- domInfo.isSimple = !domInfo.isLeaf && domInfo.type === 'element' && NEET_RENDER_TO_CUSTOM_ELEMENT.indexOf(child.tagName.toUpperCase()) === -1 && level > 0;
- if (domInfo.isSimple) {
- domInfo.content = '';
- domInfo.childNodes = filterNodes(child, level - 1);
- }
+ // Check child nodes
+ domInfo.isLeaf =
+ !domInfo.isImage &&
+ domInfo.type === 'element' &&
+ !child.children.length &&
+ NEET_RENDER_TO_CUSTOM_ELEMENT.indexOf(child.tagName.toUpperCase()) ===
+ -1;
+ if (domInfo.isLeaf) {
+ domInfo.content = child.childNodes
+ .map((childNode) =>
+ childNode.$$domInfo.type === 'text' ? childNode.textContent : ''
+ )
+ .join('');
+ }
+
+ // Check simple node that can be rendered as view
+ domInfo.isSimple =
+ !domInfo.isImage &&
+ !domInfo.useTemplate &&
+ !domInfo.isLeaf &&
+ domInfo.type === 'element' &&
+ NEET_RENDER_TO_CUSTOM_ELEMENT.indexOf(child.tagName) === -1 &&
+ level > 0;
+ if (domInfo.isSimple) {
+ domInfo.content = '';
+ domInfo.childNodes = filterNodes(child, level - 1, component);
+ }
- return domInfo;
- }).filter(child => !!child);
+ return domInfo;
+ })
+ .filter((child) => !!child);
}
diff --git a/packages/miniapp-element/src/vdom/shallowEqual.js b/packages/miniapp-element/src/vdom/shallowEqual.js
new file mode 100644
index 0000000000..62e7bb4c11
--- /dev/null
+++ b/packages/miniapp-element/src/vdom/shallowEqual.js
@@ -0,0 +1,50 @@
+import { isNull, isObject, EMPTY_OBJECT } from './types';
+
+const hasOwnProperty = EMPTY_OBJECT.hasOwnProperty;
+
+/**
+ * inlined Object.is polyfill to avoid requiring consumers ship their own
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
+ */
+export function is(x, y) {
+ // SameValue algorithm
+ if (x === y) {
+ // Steps 1-5, 7-10
+ // Steps 6.b-6.e: +0 != -0
+ return x !== 0 || 1 / x === 1 / y;
+ } else {
+ // Step 6.a: NaN == NaN
+ return x !== x && y !== y; // eslint-disable-line no-self-compare
+ }
+}
+
+/**
+ * Performs equality by iterating through keys on an object and returning false
+ * when any key has values which are not strictly equal between the arguments.
+ * Returns true when the values of all keys are strictly equal.
+ */
+export default function shallowEqual(objA, objB) {
+ if (is(objA, objB)) {
+ return true;
+ }
+
+ if (!isObject(objA) || isNull(objA) || !isObject(objB) || isNull(objB)) {
+ return false;
+ }
+
+ let keysA = Object.keys(objA);
+ let keysB = Object.keys(objB);
+
+ if (keysA.length !== keysB.length) {
+ return false;
+ }
+
+ // Test for A's keys different from B.
+ for (let i = 0; i < keysA.length; i++) {
+ if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/packages/miniapp-element/src/vdom/types.js b/packages/miniapp-element/src/vdom/types.js
new file mode 100644
index 0000000000..7ab5ce61c8
--- /dev/null
+++ b/packages/miniapp-element/src/vdom/types.js
@@ -0,0 +1,41 @@
+export function isNull(obj) {
+ return obj === null;
+}
+
+export function isUndef(value) {
+ return value === undefined;
+}
+
+export function isFunction(obj) {
+ return typeof obj === 'function';
+}
+
+export function isObject(obj) {
+ return typeof obj === 'object';
+}
+
+export function isPlainObject(obj) {
+ return EMPTY_OBJECT.toString.call(obj) === '[object Object]';
+}
+
+export function isArray(array) {
+ return Array.isArray(array);
+}
+
+export function isString(string) {
+ return typeof string === 'string';
+}
+
+export function isNumber(string) {
+ return typeof string === 'number';
+}
+
+export function isEmptyObj(obj) {
+ for (let key in obj) {
+ return false;
+ }
+ return true;
+}
+
+export const NOOP = () => {};
+export const EMPTY_OBJECT = {};
diff --git a/packages/miniapp-render/package.json b/packages/miniapp-render/package.json
index 3cf68bae2a..77a3f9f604 100644
--- a/packages/miniapp-render/package.json
+++ b/packages/miniapp-render/package.json
@@ -1,6 +1,6 @@
{
"name": "miniapp-render",
- "version": "0.1.16",
+ "version": "0.1.17",
"description": "DOM simulator for MiniApp",
"files": [
"dist"
diff --git a/packages/miniapp-render/src/node/attribute.js b/packages/miniapp-render/src/node/attribute.js
index 3775e0ea32..2da807002e 100755
--- a/packages/miniapp-render/src/node/attribute.js
+++ b/packages/miniapp-render/src/node/attribute.js
@@ -70,7 +70,6 @@ class Attribute {
} else {
const config = cache.getConfig();
- // 判断 value 是否需要删减
if (typeof value === 'string' && config.optimization.attrValueReduce && value.length > config.optimization.attrValueReduce) {
console.warn(`property "${name}" will be deleted, because it's greater than ${config.optimization.attrValueReduce}`);
value = '';
diff --git a/packages/miniapp-render/src/node/element.js b/packages/miniapp-render/src/node/element.js
index 4e8d819421..4852511ddd 100755
--- a/packages/miniapp-render/src/node/element.js
+++ b/packages/miniapp-render/src/node/element.js
@@ -283,7 +283,7 @@ class Element extends Node {
type: this.$_type,
tagName: this.$_tagName,
id: this.id,
- class: this.className,
+ className: this.className,
style: this.$__style ? this.style.cssText : '',
animation: this.$__attrs ? this.$__attrs.get('animation') : {}
};
@@ -346,8 +346,10 @@ class Element extends Node {
// Sets properties, but does not trigger updates
$$setAttributeWithoutUpdate(name, value) {
+ if (typeof name !== 'string') return;
+
this.$_notTriggerUpdate = true;
- this.setAttribute(name, value);
+ this.$_attrs.set(name, value);
this.$_notTriggerUpdate = false;
}
@@ -725,6 +727,7 @@ class Element extends Node {
// Trigger the webview update
if (hasUpdate) this.$_triggerMeUpdate();
+
return node;
}
diff --git a/packages/miniapp-render/src/node/element/builtin-component.js b/packages/miniapp-render/src/node/element/builtin-component.js
index b921466674..c1db7e4327 100755
--- a/packages/miniapp-render/src/node/element/builtin-component.js
+++ b/packages/miniapp-render/src/node/element/builtin-component.js
@@ -43,6 +43,31 @@ class BuiltInComponent extends Element {
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 bcdcf39789..149ec101f3 100755
--- a/packages/miniapp-render/src/node/element/custom-component.js
+++ b/packages/miniapp-render/src/node/element/custom-component.js
@@ -10,7 +10,6 @@ class CustomComponent extends Element {
const config = cache.getConfig();
if (config.optimization.elementMultiplexing) {
- // 复用 element 节点
const instance = pool.get();
if (instance) {
@@ -22,34 +21,24 @@ class CustomComponent extends Element {
return new CustomComponent(options, tree);
}
- /**
- * 覆写父类的 $$init 方法
- */
$$init(options, tree) {
this.$_behavior = options.componentName;
super.$$init(options, tree);
}
- /**
- * 覆写父类的 $$destroy 方法
- */
$$destroy() {
super.$$destroy();
this.$_behavior = null;
}
- /**
- * 覆写父类的回收实例方法
- */
$$recycle() {
this.$$destroy();
const config = cache.getConfig();
if (config.optimization.elementMultiplexing) {
- // 复用 element 节点
pool.add(this);
}
}
diff --git a/packages/miniapp-render/src/node/element/input.js b/packages/miniapp-render/src/node/element/input.js
index 01ca429fde..baee0a97fd 100755
--- a/packages/miniapp-render/src/node/element/input.js
+++ b/packages/miniapp-render/src/node/element/input.js
@@ -90,7 +90,7 @@ class HTMLInputElement extends Element {
set name(value) {
value = '' + value;
- return this.$_attrs.set('name', value);
+ this.$_attrs.set('name', value);
}
get type() {
@@ -171,8 +171,13 @@ class HTMLInputElement extends Element {
return this.$_attrs.get('checked') || '';
}
- focus() {
- this.$_attrs.set('focus', true);
+ get focus() {
+ return !!this.$_attrs.get('focus');
+ }
+
+ set focus(value) {
+ value = !!value;
+ this.$_attrs.set('focus', value);
}
blur() {
diff --git a/packages/miniapp-render/src/node/element/textarea.js b/packages/miniapp-render/src/node/element/textarea.js
index 492c37a4cc..52385d0c36 100644
--- a/packages/miniapp-render/src/node/element/textarea.js
+++ b/packages/miniapp-render/src/node/element/textarea.js
@@ -87,6 +87,16 @@ class HTMLTextAreaElement extends Element {
};
}
+ // Attribute
+ get name() {
+ return this.$_attrs.get('name');
+ }
+
+ set name(value) {
+ value = '' + value;
+ this.$_attrs.set('name', value);
+ }
+
// Attribute
get type() {
return this.$_attrs.get('type') || 'textarea';
@@ -172,8 +182,13 @@ class HTMLTextAreaElement extends Element {
this.$_attrs.set('selection-end', value);
}
- focus() {
- this.$_attrs.set('focus', true);
+ get focus() {
+ return !!this.$_attrs.get('focus');
+ }
+
+ set focus(value) {
+ value = !!value;
+ this.$_attrs.set('focus', value);
}
blur() {
diff --git a/packages/miniapp-render/src/node/node.js b/packages/miniapp-render/src/node/node.js
index f55da27cdb..90d363cd88 100755
--- a/packages/miniapp-render/src/node/node.js
+++ b/packages/miniapp-render/src/node/node.js
@@ -105,6 +105,12 @@ class Node extends EventTarget {
hasChildNodes() {
return false;
}
+
+ remove() {
+ if (!this.parentNode || !this.parentNode.removeChild) return this;
+
+ return this.parentNode.removeChild(this);
+ }
}
// static props
diff --git a/packages/miniapp-render/src/tree/tree.js b/packages/miniapp-render/src/tree/tree.js
index 5c670a8711..89cbcf13f3 100755
--- a/packages/miniapp-render/src/tree/tree.js
+++ b/packages/miniapp-render/src/tree/tree.js
@@ -1,28 +1,22 @@
import QuerySelector from './query-selector';
-/**
- * 遍历 dom 树,收集类和标签对应的节点列表
- */
+// 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;
- const children = node.children || [];
-
- for (const child of children) {
- const {tagName, classList} = child;
+ tagMap[tagName] = tagMap[tagName] || [];
+ tagMap[tagName].push(node);
- // 标签
- tagMap[tagName] = tagMap[tagName] || [];
- tagMap[tagName].push(child);
+ for (const className of classList) {
+ classMap[className] = classMap[className] || [];
+ classMap[className].push(node);
+ }
- // 类
- for (const className of classList) {
- classMap[className] = classMap[className] || [];
- classMap[className].push(child);
- }
+ const children = node.children || [];
- // 递归遍历
+ for (const child of children) {
walkDomTree(child, cache);
}
}
@@ -41,9 +35,6 @@ class Tree {
this.walk(root, this.root);
}
- /**
- * 遍历 ast
- */
walk(ast, parentNode) {
const children = ast.children;
const idMap = this.idMap;
@@ -52,7 +43,6 @@ class Tree {
if (!children || !children.length) return;
- // 遍历子节点
for (const child of children) {
let childNode;
@@ -62,40 +52,27 @@ class Tree {
childNode = document.$$createTextNode(child, this);
}
- // 处理 id 缓存
const id = childNode.id;
if (id && !idMap[id]) {
idMap[id] = childNode;
}
- // 处理 nodeId 缓存
if (nodeIdMap) nodeIdMap[child.nodeId] = childNode;
- // 插入子节点
parentNode.appendChild(childNode);
- // 遍历子节点的 ast
this.walk(child, childNode);
}
}
- /**
- * 更新 idMap
- */
updateIdMap(id, node) {
this.idMap[id] = node;
}
- /**
- * 根据 id 获取节点
- */
getById(id) {
return this.idMap[id];
}
- /**
- * 根据标签名获取节点列表
- */
getByTagName(tagName, node) {
const cache = {};
walkDomTree(node || this.root, cache);
@@ -103,9 +80,6 @@ class Tree {
return cache.tagMap[tagName.toUpperCase()] || [];
}
- /**
- * 根据类名获取节点列表
- */
getByClassName(className, node) {
const cache = {};
walkDomTree(node || this.root, cache);
@@ -113,9 +87,6 @@ class Tree {
return cache.classMap[className] || [];
}
- /**
- * 查询符合条件的节点
- */
query(selector, node) {
const cache = {};
walkDomTree(node || this.root, cache);