Ejemplo n.º 1
0
  /**
   * Update the attributes according to the given attribute. Then creating a command object for
   * updating corresponding view and put the command object in the queue.
   *
   * @param ref Reference of the dom.
   * @param attrs the new style. This style is only a part of the full attribute set, and will be
   *     merged into attributes
   * @see #updateStyle(String, JSONObject)
   */
  void updateAttrs(String ref, final JSONObject attrs) {
    if (mDestroy) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    final WXDomObject domObject = mRegistry.get(ref);
    if (domObject == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_UPDATEATTRS);
      }
      return;
    }

    domObject.updateAttr(attrs);

    mNormalTasks.add(
        new IWXRenderTask() {

          @Override
          public void execute() {
            mWXRenderManager.updateAttrs(mInstanceId, domObject.getRef(), attrs);
          }

          @Override
          public String toString() {
            return "updateAttr";
          }
        });
    mDirty = true;

    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }
Ejemplo n.º 2
0
 /**
  * Clear the mapping relationship between Reference and {@link WXDomObject}. The mapping info is
  * stored in {@link #mRegistry}.
  *
  * @param domObject
  */
 private void clearRegistryForDom(WXDomObject domObject) {
   int count = domObject.childCount();
   mRegistry.remove(domObject.getRef());
   for (int i = count - 1; i >= 0; --i) {
     clearRegistryForDom(domObject.getChild(i));
   }
 }
Ejemplo n.º 3
0
  /**
   * Update styles according to the given style. Then creating a command object for updating
   * corresponding view and put the command object in the queue.
   *
   * @param ref Reference of the dom.
   * @param style the new style. This style is only a part of the full style, and will be merged
   *     into styles
   * @see #updateAttrs(String, JSONObject)
   */
  void updateStyle(String ref, JSONObject style) {
    if (mDestroy || style == null) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    WXDomObject domObject = mRegistry.get(ref);
    if (domObject == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_UPDATESTYLE);
      }
      return;
    }

    Map<String, Object> animationMap = WXDataStructureUtil.newHashMapWithExpectedSize(2);
    animationMap.put(WXDomObject.TRANSFORM, style.remove(WXDomObject.TRANSFORM));
    animationMap.put(WXDomObject.TRANSFORM_ORIGIN, style.remove(WXDomObject.TRANSFORM_ORIGIN));
    animations.add(new Pair<>(ref, animationMap));

    if (!style.isEmpty()) {
      domObject.updateStyle(style);
      transformStyle(domObject, false);
      updateStyle(domObject, style);
    }
    mDirty = true;

    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }
Ejemplo n.º 4
0
  /**
   * Create a command object for removing the event listener of the corresponding {@link
   * WXDomObject} and put the command event in the queue.
   *
   * @param ref Reference of the dom.
   * @param type the type of the event, this may be a plain event defined in {@link
   *     com.taobao.weex.common.Constants.Event} or a gesture defined in {@link com.taobao
   *     .weex.ui.view.gesture.WXGestureType}
   */
  void removeEvent(final String ref, final String type) {
    if (mDestroy) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    WXDomObject domObject = mRegistry.get(ref);
    if (domObject == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_REMOVEEVENT);
      }
      return;
    }
    domObject.removeEvent(type);
    mNormalTasks.add(
        new IWXRenderTask() {

          @Override
          public void execute() {
            mWXRenderManager.removeEvent(mInstanceId, ref, type);
          }

          @Override
          public String toString() {
            return "removeEvent";
          }
        });

    mDirty = true;
    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }
Ejemplo n.º 5
0
 private void layoutAfter(WXDomObject dom) {
   if (dom == null || !dom.hasUpdate() || mDestroy) {
     return;
   }
   dom.layoutAfter();
   int count = dom.childCount();
   for (int i = 0; i < count; ++i) {
     layoutAfter(dom.getChild(i));
   }
 }
Ejemplo n.º 6
0
  /**
   * Batch the execution of command objects and execute all the command objects created other
   * places, e.g. call {@link IWXRenderTask#execute()}. First, it will rebuild the dom tree and do
   * pre layout staff. Then call {@link
   * com.taobao.weex.dom.flex.CSSNode#calculateLayout(CSSLayoutContext)} to start calculate layout.
   * Next, call {@link #applyUpdate(WXDomObject)} to get changed dom and creating corresponding
   * command object. Finally, walk through the queue, e.g. call {@link IWXRenderTask#execute()} for
   * every task in the queue.
   */
  void batch() {
    long start0 = System.currentTimeMillis();

    if (!mDirty || mDestroy) {
      return;
    }

    WXDomObject rootDom = mRegistry.get(WXDomObject.ROOT);
    if (rootDom == null) {
      return;
    }

    rebuildingDomTree(rootDom);

    layoutBefore(rootDom);
    long start = System.currentTimeMillis();

    rootDom.calculateLayout(mLayoutContext);

    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    if (instance != null) {
      instance.cssLayoutTime(System.currentTimeMillis() - start);
    }

    layoutAfter(rootDom);

    start = System.currentTimeMillis();
    applyUpdate(rootDom);

    if (instance != null) {
      instance.applyUpdateTime(System.currentTimeMillis() - start);
    }

    start = System.currentTimeMillis();
    updateDomObj();
    if (instance != null) {
      instance.updateDomObjTime(System.currentTimeMillis() - start);
    }
    parseAnimation();

    int count = mNormalTasks.size();
    for (int i = 0; i < count && !mDestroy; ++i) {
      mWXRenderManager.runOnThread(mInstanceId, mNormalTasks.get(i));
    }
    mNormalTasks.clear();
    mAddDom.clear();
    animations.clear();
    mDirty = false;
    if (instance != null) {
      instance.batchTime(System.currentTimeMillis() - start0);
    }
  }
Ejemplo n.º 7
0
 /**
  * Rebuild the component tree. The purpose of this method is moving fixed components to the root
  * component. This method will be called when {@link #batch()} is executed.
  *
  * @param root root dom
  */
 void rebuildingDomTree(WXDomObject root) {
   if (root != null && root.getFixedStyleRefs() != null) {
     int size = root.getFixedStyleRefs().size();
     for (int i = 0; i < size; i++) {
       String fixedRef = root.getFixedStyleRefs().get(i);
       WXDomObject wxDomObject = mRegistry.get(fixedRef);
       if (wxDomObject != null && wxDomObject.parent != null) {
         wxDomObject.parent.remove(wxDomObject);
         root.add(wxDomObject, -1);
       }
     }
   }
 }
Ejemplo n.º 8
0
  /**
   * Creating the mapping between Reference to {@link WXDomObject} and store the mapping in {@link
   * #mRegistry}. Then, parse and copy style from DOM to {@link com.taobao.weex.dom.flex.CSSNode}.
   * Finally, DOM's children are also added to {@link com.taobao.weex.dom.flex.CSSNode#mChildren} if
   * added is true. The above procedure will be done recursively.
   *
   * @param dom the original DOM Object
   * @param isAdd true for adding children of {@link WXDomObject} {@link
   *     com.taobao.weex.dom.flex.CSSNode#mChildren} and parsing style, false for only parsing
   *     style.
   */
  private void transformStyle(WXDomObject dom, boolean isAdd) {
    if (dom == null) {
      return;
    }

    if (isAdd) {
      dom.young();
      mRegistry.put(dom.getRef(), dom);
    }

    WXStyle style = dom.getStyles();

    /** merge default styles * */
    Map<String, String> defaults = dom.getDefaultStyle();
    if (defaults != null) {
      Iterator<Map.Entry<String, String>> it = defaults.entrySet().iterator();
      while (it.hasNext()) {
        Map.Entry<String, String> entry = it.next();
        if (!style.containsKey(entry.getKey())) {
          style.put(entry.getKey(), entry.getValue());
        }
      }
    }

    if (dom.getStyles().size() > 0) {
      dom.applyStyleToNode();
    }

    int count = dom.childCount();
    WXDomObject child;
    for (int i = 0; i < count; ++i) {
      child = dom.getChild(i);
      transformStyle(child, isAdd);
    }
  }
Ejemplo n.º 9
0
 private WXAnimationBean createAnimationBean(String ref, String animation) {
   try {
     WXAnimationBean animationBean = JSONObject.parseObject(animation, WXAnimationBean.class);
     if (animationBean != null && animationBean.styles != null) {
       WXDomObject domObject = mRegistry.get(ref);
       int width = (int) domObject.getLayoutWidth();
       int height = (int) domObject.getLayoutHeight();
       animationBean.styles.init(
           animationBean.styles.transformOrigin, animationBean.styles.transform, width, height);
     }
     return animationBean;
   } catch (RuntimeException e) {
     WXLogUtils.e("", e);
     return null;
   }
 }
Ejemplo n.º 10
0
 /**
  * Update the specified component's dom and mark it as old.
  *
  * @param component the component to be updated
  */
 private void updateDomObj(WXComponent component) {
   if (component == null) {
     return;
   }
   WXDomObject domObject = mRegistry.get(component.getRef());
   if (domObject == null) {
     return;
   }
   domObject.old();
   component.updateDom(domObject.clone());
   if (component instanceof WXVContainer) {
     WXVContainer container = (WXVContainer) component;
     int count = container.childCount();
     for (int i = 0; i < count; ++i) {
       updateDomObj(container.getChild(i));
     }
   }
 }
Ejemplo n.º 11
0
  /**
   * Create a command object for removing the specified {@link WXDomObject}. If the domObject is
   * null or its parent is null, this method returns directly. Otherwise, put the command object in
   * the queue.
   *
   * @param ref Reference of the dom.
   */
  void removeDom(final String ref) {
    if (mDestroy) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    WXDomObject domObject = mRegistry.get(ref);
    if (domObject == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_REMOVEELEMENT);
      }
      return;
    }
    WXDomObject parent = domObject.parent;
    if (parent == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_REMOVEELEMENT);
      }
      return;
    }
    clearRegistryForDom(domObject);
    parent.remove(domObject);
    mRegistry.remove(ref);

    mNormalTasks.add(
        new IWXRenderTask() {

          @Override
          public void execute() {
            mWXRenderManager.removeComponent(mInstanceId, ref);
          }

          @Override
          public String toString() {
            return "removeDom";
          }
        });

    mDirty = true;
    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }
Ejemplo n.º 12
0
  /**
   * Create a command object for moving the specific {@link WXDomObject} to a new parent. If any of
   * the following situation is met,
   *
   * <ul>
   *   <li>dom to be moved is null
   *   <li>dom's parent is null
   *   <li>new parent is null
   *   <li>parent is under {@link CSSNode#hasNewLayout()}
   * </ul>
   *
   * this method will return. Otherwise, put the command object in the queue.
   *
   * @param ref Reference of the dom to be moved.
   * @param parentRef Reference of the new parent DOM node
   * @param index the index of the dom to be inserted in the new parent.
   */
  void moveDom(final String ref, final String parentRef, final int index) {
    if (mDestroy) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    WXDomObject domObject = mRegistry.get(ref);
    WXDomObject parentObject = mRegistry.get(parentRef);
    if (domObject == null
        || domObject.parent == null
        || parentObject == null
        || parentObject.hasNewLayout()) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_MOVEELEMENT);
      }
      return;
    }
    if (domObject.parent.equals(parentObject)) {
      return;
    }
    domObject.parent.remove(domObject);
    parentObject.add(domObject, index);

    mNormalTasks.add(
        new IWXRenderTask() {

          @Override
          public void execute() {
            mWXRenderManager.moveComponent(mInstanceId, ref, parentRef, index);
          }

          @Override
          public String toString() {
            return "moveDom";
          }
        });

    mDirty = true;
    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }
Ejemplo n.º 13
0
 private WXAnimationBean createAnimationBean(String ref, Map<String, Object> style) {
   if (style != null) {
     try {
       Object transform = style.get(WXDomObject.TRANSFORM);
       if (transform instanceof String && !TextUtils.isEmpty((String) transform)) {
         String transformOrigin = (String) style.get(WXDomObject.TRANSFORM_ORIGIN);
         WXAnimationBean animationBean = new WXAnimationBean();
         WXDomObject domObject = mRegistry.get(ref);
         int width = (int) domObject.getLayoutWidth();
         int height = (int) domObject.getLayoutHeight();
         animationBean.styles = new WXAnimationBean.Style();
         animationBean.styles.init(transformOrigin, (String) transform, width, height);
         return animationBean;
       }
     } catch (RuntimeException e) {
       WXLogUtils.e("", e);
       return null;
     }
   }
   return null;
 }
Ejemplo n.º 14
0
  /**
   * Parse the jsonObject to {@link WXDomObject} recursively
   *
   * @param map the original JSONObject
   * @return Dom Object corresponding to the JSONObject.
   */
  private @Nullable WXDomObject parseInner(JSONObject map) {
    if (map == null || map.size() <= 0) {
      return null;
    }

    String type = (String) map.get(TYPE);
    WXDomObject domObject = WXDomObjectFactory.newInstance(type);
    if (domObject == null) {
      return null;
    }
    domObject.parseFromJson(map);

    Object children = map.get(CHILDREN);
    if (children != null && children instanceof JSONArray) {
      JSONArray childrenArray = (JSONArray) children;
      int count = childrenArray.size();
      for (int i = 0; i < count; ++i) {
        domObject.add(parseInner(childrenArray.getJSONObject(i)), -1);
      }
    }

    return domObject;
  }
Ejemplo n.º 15
0
  /**
   * Walk through the dom tree and create command object of re-calculating {@link
   * android.view.ViewGroup.LayoutParams} for dom that is old.
   *
   * @param dom the root dom of the walk through.
   */
  private void applyUpdate(WXDomObject dom) {
    if (dom == null) {
      return;
    }
    if (dom.hasUpdate()) {
      dom.markUpdateSeen();
      if (!dom.isYoung()) {
        final WXDomObject copy = dom.clone();
        if (copy == null) {
          return;
        }
        mNormalTasks.add(
            new IWXRenderTask() {

              @Override
              public void execute() {
                mWXRenderManager.setLayout(mInstanceId, copy.getRef(), copy);
              }

              @Override
              public String toString() {
                return "setLayout";
              }
            });
        if (dom.getExtra() != null) {
          mNormalTasks.add(
              new IWXRenderTask() {

                @Override
                public void execute() {
                  mWXRenderManager.setExtra(mInstanceId, copy.getRef(), copy.getExtra());
                }

                @Override
                public String toString() {
                  return "setExtra";
                }
              });
        }
      }
    }
    int count = dom.childCount();
    for (int i = 0; i < count; ++i) {
      applyUpdate(dom.getChild(i));
    }
  }
Ejemplo n.º 16
0
  /**
   * Find fixed node and tell root dom
   *
   * @param obj
   */
  void findFixed(WXDomObject obj) {
    WXDomObject rootDom = mRegistry.get(WXDomObject.ROOT);
    if (rootDom == null) {
      return;
    }
    if (obj.isFixed()) {
      rootDom.add2FixedDomList(obj.getRef());
    }

    int childrenCount = obj.childCount();
    if (childrenCount > 0) {
      for (int i = 0; i < childrenCount; i++) {
        findFixed(obj.getChild(i));
      }
    }
  }
Ejemplo n.º 17
0
  /**
   * Create command object for creating body according to the JSONObject. And put the command object
   * in the queue.
   *
   * @param element the jsonObject according to which to create command object.
   */
  void createBody(JSONObject element) {
    if (mDestroy) {
      return;
    }
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
    if (element == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_CREATEBODY);
      }
      return;
    }

    WXDomObject domObject = parseInner(element);
    if (domObject == null) {
      return;
    }
    Map<String, Object> style = new HashMap<>(5);
    if (!domObject.getStyles().containsKey(Constants.Name.FLEX_DIRECTION)) {
      style.put(Constants.Name.FLEX_DIRECTION, "column");
    }
    if (!domObject.getStyles().containsKey(Constants.Name.BACKGROUND_COLOR)) {
      style.put(Constants.Name.BACKGROUND_COLOR, "#ffffff");
    }
    // If there is height or width in JS, then that value will override value here.
    if (!domObject.getStyles().containsKey(Constants.Name.WIDTH)) {
      style.put(
          Constants.Name.WIDTH, WXViewUtils.getWebPxByWidth(WXViewUtils.getWeexWidth(mInstanceId)));
      domObject.setModifyWidth(true);
    }
    if (!domObject.getStyles().containsKey(Constants.Name.HEIGHT)) {
      style.put(
          Constants.Name.HEIGHT,
          WXViewUtils.getWebPxByWidth(WXViewUtils.getWeexHeight(mInstanceId)));
      domObject.setModifyHeight(true);
    }
    WXDomObject.prepareRoot(domObject);
    domObject.updateStyle(style);
    transformStyle(domObject, true);

    try {
      final WXComponent component = mWXRenderManager.createBodyOnDomThread(mInstanceId, domObject);
      AddDomInfo addDomInfo = new AddDomInfo();
      addDomInfo.component = component;
      mAddDom.put(domObject.getRef(), addDomInfo);

      mNormalTasks.add(
          new IWXRenderTask() {

            @Override
            public void execute() {
              WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
              if (instance == null || instance.getContext() == null) {
                WXLogUtils.e("instance is null or instance is destroy!");
                return;
              }
              try {
                mWXRenderManager.createBody(mInstanceId, component);
              } catch (Exception e) {
                WXLogUtils.e("create body failed.", e);
              }
            }

            @Override
            public String toString() {
              return "createBody";
            }
          });
      animations.add(
          new Pair<String, Map<String, Object>>(domObject.getRef(), domObject.getStyles()));
      mDirty = true;

      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
      }
    } catch (Exception e) {

      WXLogUtils.e("create body in dom thread failed." + e.getMessage());
    }
  }
Ejemplo n.º 18
0
  /**
   * Create a command object for adding a dom node to its parent in a specific location. If dom's
   * parent doesn't exist or the dom has been added in current {@link WXSDKInstance}, this method
   * will return. If the above request is met, then put the command object in the queue.
   *
   * @param dom the dom object in the form of JSONObject
   * @param parentRef parent to which the dom is added.
   * @param index the location of which the dom is added.
   */
  void addDom(JSONObject dom, final String parentRef, final int index) {
    if (mDestroy) {
      return;
    }
    WXDomObject parent = mRegistry.get(parentRef);
    WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);

    if (parent == null) {
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_ADDELEMENT);
      }
      return;
    }
    WXDomObject domObject = parseInner(dom);

    if (domObject == null || mRegistry.containsKey(domObject.getRef())) {
      if (WXEnvironment.isApkDebugable()) {
        WXLogUtils.e("[WXDomStatement] addDom error!!");
      }
      if (instance != null) {
        instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_ERR_DOM_ADDELEMENT);
      }
      return;
    }

    findFixed(domObject);

    parent.add(domObject, index);

    transformStyle(domObject, true);

    // Create component in dom thread
    final WXComponent component =
        mWXRenderManager.createComponentOnDomThread(mInstanceId, domObject, parentRef, index);
    if (component == null) {
      // stop redner, some fatal happened.
      return;
    }
    AddDomInfo addDomInfo = new AddDomInfo();
    addDomInfo.component = component;
    mAddDom.put(domObject.getRef(), addDomInfo);

    mNormalTasks.add(
        new IWXRenderTask() {

          @Override
          public void execute() {
            WXSDKInstance instance = WXSDKManager.getInstance().getSDKInstance(mInstanceId);
            if (instance == null || instance.getContext() == null) {
              WXLogUtils.e("instance is null or instance is destroy!");
              return;
            }
            try {
              mWXRenderManager.addComponent(mInstanceId, component, parentRef, index);
            } catch (Exception e) {
              WXLogUtils.e("add component failed.", e);
            }
          }

          @Override
          public String toString() {
            return "AddDom";
          }
        });
    animations.add(
        new Pair<String, Map<String, Object>>(domObject.getRef(), domObject.getStyles()));
    mDirty = true;

    if (instance != null) {
      instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);
    }
  }