/** * 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); } } } }
/** * 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); } }
/** * 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; }
/** * 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); } }