@dolphinweex/weex-harmony 0.1.66 → 0.1.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dolphinweex/weex-harmony",
3
- "version": "0.1.66",
3
+ "version": "0.1.68",
4
4
  "description": "weex harmony adapter",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -122,6 +122,9 @@ export default {
122
122
  return null;
123
123
  };
124
124
  this._wrapperEl = findWrapperFromParent(); // 保存容器引用
125
+ // 优化手势处理性能
126
+ this._rafId = null;
127
+ this._pendingGesture = null;
125
128
  this._onMessage = (event) => {
126
129
  if(event.data.type==='IFRAME_CONTENT_HEIGHT'){
127
130
  const h = Number(event.data.height) || 0;
@@ -136,6 +139,26 @@ export default {
136
139
  }else{
137
140
  document.getElementsByTagName('iframe')[0].height = event.data.height
138
141
  }
142
+ // 处理iframe手势跨窗口传递冒泡
143
+ if (event.data.type === 'IFRAME_GESTURE') {
144
+ const gestureData = event.data;
145
+
146
+ // touchmove 使用RAF节流,其他事件立即处理
147
+ if (gestureData.eventType === 'touchmove') {
148
+ this._pendingGesture = gestureData;
149
+ if (!this._rafId) {
150
+ this._rafId = requestAnimationFrame(() => {
151
+ if (this._pendingGesture) {
152
+ this.handleGestureBubble(this._pendingGesture);
153
+ this._pendingGesture = null;
154
+ }
155
+ this._rafId = null;
156
+ });
157
+ }
158
+ } else {
159
+ this.handleGestureBubble(gestureData);
160
+ }
161
+ }
139
162
  };
140
163
  window.addEventListener("message", this._onMessage, false);
141
164
  },
@@ -151,6 +174,60 @@ export default {
151
174
  );
152
175
  }
153
176
  },
177
+ handleGestureBubble(gestureData) {
178
+ const iframeEl = this.$refs.iframe;
179
+ if (!iframeEl) return;
180
+
181
+ const rect = iframeEl.getBoundingClientRect();
182
+ const offsetX = rect.left;
183
+ const offsetY = rect.top;
184
+ const pageOffsetX = offsetX + window.pageXOffset;
185
+ const pageOffsetY = offsetY + window.pageYOffset;
186
+
187
+ // 创建Touch对象并转换坐标
188
+ const createTouches = (touchesData) => touchesData.map(t => new Touch({
189
+ identifier: t.identifier,
190
+ target: iframeEl,
191
+ clientX: t.clientX + offsetX,
192
+ clientY: t.clientY + offsetY,
193
+ screenX: t.screenX,
194
+ screenY: t.screenY,
195
+ pageX: t.pageX + pageOffsetX,
196
+ pageY: t.pageY + pageOffsetY,
197
+ radiusX: t.radiusX || 0,
198
+ radiusY: t.radiusY || 0,
199
+ rotationAngle: t.rotationAngle || 0,
200
+ force: t.force || 0
201
+ }));
202
+
203
+ try {
204
+ iframeEl.dispatchEvent(new TouchEvent(gestureData.eventType, {
205
+ bubbles: true,
206
+ cancelable: true,
207
+ composed: true,
208
+ touches: createTouches(gestureData.touches),
209
+ targetTouches: createTouches(gestureData.targetTouches),
210
+ changedTouches: createTouches(gestureData.changedTouches),
211
+ ctrlKey: gestureData.ctrlKey,
212
+ shiftKey: gestureData.shiftKey,
213
+ altKey: gestureData.altKey,
214
+ metaKey: gestureData.metaKey
215
+ }));
216
+ } catch (e) {
217
+ console.warn('手势事件冒泡失败:', e);
218
+ }
219
+ },
220
+ },
221
+ beforeDestroy() {
222
+ // 清理RAF避免内存泄漏
223
+ if (this._rafId) {
224
+ cancelAnimationFrame(this._rafId);
225
+ this._rafId = null;
226
+ }
227
+ // 清理消息监听
228
+ if (this._onMessage) {
229
+ window.removeEventListener("message", this._onMessage, false);
230
+ }
154
231
  },
155
232
  };
156
233
  </script>
@@ -190,7 +190,25 @@ function getComponentLoc(name) {
190
190
  return getAbsPath(address)
191
191
  }
192
192
  }
193
+ //解决v-bind传的是 a.b.c这种 可能a是空导致报错
193
194
  function createComputedProperty(vBindValue, computedName) {
195
+ // 使用辅助函数创建成员表达式,支持嵌套属性路径
196
+ const valueExpression = createMemberExpressionFromPath(vBindValue);
197
+ const styleExpression = t.memberExpression(createMemberExpressionFromPath(vBindValue), t.identifier('style'));
198
+
199
+ // 为嵌套路径创建逐级空值检查(如 a.b.c 需要检查 a && a.b && a.b.c)
200
+ const parts = vBindValue.split('.');
201
+ const nullCheckConditions = [];
202
+ for (let i = 0; i < parts.length; i++) {
203
+ nullCheckConditions.push(createMemberExpressionFromPath(parts.slice(0, i + 1).join('.')));
204
+ }
205
+
206
+ // 构建逐级 && 检查表达式
207
+ let nullCheckExpression = nullCheckConditions[0];
208
+ for (let i = 1; i < nullCheckConditions.length; i++) {
209
+ nullCheckExpression = t.logicalExpression('&&', nullCheckExpression, nullCheckConditions[i]);
210
+ }
211
+
194
212
  return t.objectProperty(
195
213
  t.identifier('computed'), // 为对象添加 computed 属性
196
214
  t.objectExpression([ // 计算属性
@@ -200,31 +218,27 @@ function createComputedProperty(vBindValue, computedName) {
200
218
  null, //不需要传参
201
219
  [],
202
220
  t.blockStatement([ // 函数体是一个块语句,包含多个语句
203
- t.ifStatement(// if (this.scrollerWrapProps && this.scrollerWrapProps.style)
221
+ // 先判断对象本身是否存在(逐级检查),不存在直接返回空对象
222
+ t.ifStatement(
223
+ t.unaryExpression('!', nullCheckExpression),
224
+ t.blockStatement([
225
+ t.returnStatement(t.objectExpression([]))
226
+ ])
227
+ ),
228
+ t.ifStatement(// if (this.xxx && this.xxx.style)
204
229
  t.logicalExpression(
205
- '&&', // 使用逻辑“与”操作符
206
- t.memberExpression(t.thisExpression(), t.identifier(vBindValue)), // this.scrollerWrapProps
207
- t.memberExpression(
208
- t.memberExpression(t.thisExpression(), t.identifier(vBindValue)),
209
- t.identifier('style') // this.scrollerWrapProps.style
210
- )
230
+ '&&', // 使用逻辑"与"操作符
231
+ valueExpression,
232
+ styleExpression
211
233
  ),
212
- t.blockStatement([ // 如果条件符合妖气
234
+ t.blockStatement([ // 如果条件符合
213
235
  t.expressionStatement(
214
236
  t.assignmentExpression(
215
237
  '=', // 赋值操作
216
- t.memberExpression(
217
- t.memberExpression(t.thisExpression(), t.identifier(vBindValue)),
218
- t.identifier('style') // this.scrollerWrapProps.style
219
- ),
220
- t.callExpression(
221
- t.identifier('this._px2rem'), // weex._px2remFn 函数
222
- [//函数传参
223
- t.memberExpression(
224
- t.memberExpression(t.thisExpression(), t.identifier(vBindValue)),
225
- t.identifier('style')
226
- )
227
- ]
238
+ styleExpression,
239
+ t.callExpression(
240
+ t.memberExpression(t.thisExpression(), t.identifier('_px2rem')), // this._px2rem 函数
241
+ [styleExpression]
228
242
  )
229
243
  )
230
244
  )
@@ -237,7 +251,7 @@ function createComputedProperty(vBindValue, computedName) {
237
251
  t.memberExpression(t.identifier('Object'), t.identifier('assign')),
238
252
  [
239
253
  t.objectExpression([]),
240
- t.memberExpression(t.thisExpression(), t.identifier(vBindValue))
254
+ valueExpression
241
255
  ]
242
256
  )
243
257
  )
@@ -265,6 +279,20 @@ function getAbsPath(address){
265
279
  }
266
280
  }
267
281
 
282
+ /**
283
+ * 根据属性路径字符串(如 'a.b.c')创建 AST 成员表达式
284
+ * @param {*} propertyPath 属性路径字符串
285
+ * @returns AST 成员表达式节点
286
+ */
287
+ function createMemberExpressionFromPath(propertyPath) {
288
+ const parts = propertyPath.split('.');
289
+ let expression = t.memberExpression(t.thisExpression(), t.identifier(parts[0]));
290
+ for (let i = 1; i < parts.length; i++) {
291
+ expression = t.memberExpression(expression, t.identifier(parts[i]));
292
+ }
293
+ return expression;
294
+ }
295
+
268
296
  /**
269
297
  * 生产SFC代码
270
298
  * @param {*} moduleResoveRet