You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by mi...@apache.org on 2018/02/08 08:57:08 UTC

[1/7] incubator-weex git commit: #import ==> #import

Repository: incubator-weex
Updated Branches:
  refs/heads/master 6019278ea -> 7ab6e7b23


#import <coreText/CoreText.h>   ==>   #import <CoreText/CoreText.h>


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/20c293f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/20c293f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/20c293f4

Branch: refs/heads/master
Commit: 20c293f4a9c4c14daa0deee19b9d9b9a4b73693b
Parents: ce4b6bf
Author: Zz <zh...@gmail.com>
Authored: Mon Jan 22 17:43:54 2018 +0800
Committer: jianbai.gbj <ji...@alibaba-inc.com>
Committed: Tue Jan 23 15:33:32 2018 +0800

----------------------------------------------------------------------
 ios/sdk/WeexSDK/Sources/Utility/WXUtility.m | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/20c293f4/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
index a2e4bdd..64c6862 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
@@ -33,7 +33,7 @@
 #import <UIKit/UIScreen.h>
 #import <Security/Security.h>
 #import <CommonCrypto/CommonCrypto.h>
-#import <coreText/CoreText.h>
+#import <CoreText/CoreText.h>
 #import "WXAppMonitorProtocol.h"
 
 #import "WXTextComponent.h"


[2/7] incubator-weex git commit: [WEEX-174][android] TemplateList Support Lifecycle and statefull component

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
index 51a4874..d8200a2 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java
@@ -22,10 +22,8 @@ import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.PointF;
-import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Looper;
-import android.os.MessageQueue;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v4.util.ArrayMap;
@@ -60,6 +58,7 @@ import com.taobao.weex.dom.flex.CSSLayoutContext;
 import com.taobao.weex.dom.flex.Spacing;
 import com.taobao.weex.el.parse.ArrayStack;
 import com.taobao.weex.ui.component.AppearanceHelper;
+import com.taobao.weex.ui.component.ComponentUtils;
 import com.taobao.weex.ui.component.Scrollable;
 import com.taobao.weex.ui.component.WXBaseRefresh;
 import com.taobao.weex.ui.component.WXComponent;
@@ -84,12 +83,10 @@ import com.taobao.weex.utils.WXViewUtils;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
 
 import static com.taobao.weex.common.Constants.Name.LOADMOREOFFSET;
 
@@ -101,8 +98,15 @@ import static com.taobao.weex.common.Constants.Name.LOADMOREOFFSET;
 @Component(lazyload = false)
 public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> implements
         IRecyclerAdapterListener<TemplateViewHolder>, IOnLoadMoreListener, Scrollable {
+
+    /**
+     * trace log for template list
+     * */
+    public static final boolean ENABLE_TRACE_LOG = false;
+
     public static final String TAG = "WXRecyclerTemplateList";
 
+    private static final String EMPTY_HOLDER_TEMPLATE_KEY  = "";
     private static final String NAME_HAS_FIXED_SIZE = "hasFixedSize";
     private static final String NAME_ITEM_VIEW_CACHE_SIZE = "itemViewCacheSize";
     private static final String NAME_TEMPLATE_CACHE_SIZE = "templateCacheSize";
@@ -134,7 +138,9 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
     private Point mLastReport = new Point(-1, -1);
     private boolean mHasAddScrollEvent = false;
 
-    private JSONArray listData;
+
+    private CellDataManager cellDataManager;
+
     private String listDataKey = Constants.Name.Recycler.LIST_DATA;
     private String listDataItemKey = null;
     private String listDataIndexKey = null;
@@ -143,13 +149,19 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
 
     private Map<String, WXCell> mTemplateSources;
-    private String  listDataTemplateKey = Constants.Name.Recycler.SLOT_TEMPLATE_TYPE;
+    private String  listDataTemplateKey = Constants.Name.Recycler.SLOT_TEMPLATE_CASE;
     private Runnable listUpdateRunnable;
     private ConcurrentHashMap<String, TemplateCache> mTemplatesCache;
     private int templateCacheSize = 2;
 
 
     /**
+     * case default cell and key
+     * */
+    private WXCell defaultTemplateCell;
+    private String defaultTemplateKey = "@default_template_cell";
+
+    /**
      * scroll start and scroll end event
      * */
     private ScrollStartEndHelper mScrollStartEndHelper;
@@ -175,9 +187,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
      * */
     private ArrayMap<Integer, Map<String,Map<Integer, List<Object>>>> mDisAppearWatchList = new ArrayMap<>();
 
-    private ArrayStack bindIngStackContext = new ArrayStack();
-    private Map bindIngMapContext = new HashMap();
-
+    private CellRenderContext cellRenderContext = new CellRenderContext();
 
     public WXRecyclerTemplateList(WXSDKInstance instance, WXDomObject node, WXVContainer parent) {
         super(instance, node, parent);
@@ -192,18 +202,19 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
             updateRecyclerAttr();
         }
         mTemplateViewTypes = new ArrayMap<>();
-        mTemplateViewTypes.put("", 0); //empty view, when template was not sended
+        mTemplateViewTypes.put(EMPTY_HOLDER_TEMPLATE_KEY, 0); //empty view, when template was not sended
         mTemplateSources = new HashMap<>();
         mTemplatesCache = new ConcurrentHashMap<>();
         mStickyHelper = new TemplateStickyHelper(this);
         orientation = mDomObject.getOrientation();
-        listDataTemplateKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_TEMPLATE_KEY), Constants.Name.Recycler.SLOT_TEMPLATE_TYPE);
+        listDataTemplateKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_TEMPLATE_SWITCH_KEY), Constants.Name.Recycler.SLOT_TEMPLATE_CASE);
         listDataItemKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_ITEM), listDataItemKey);
         listDataIndexKey = WXUtils.getString(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA_ITEM_INDEX), listDataIndexKey);
-        if( getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA) instanceof  JSONArray) {
+        cellDataManager = new CellDataManager(this);
+        if(getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA) instanceof  JSONArray) {
             JSONArray array = (JSONArray)getDomObject().getAttrs().get(Constants.Name.Recycler.LIST_DATA);
             if(array.size() > 0) {
-                listData = array;
+                cellDataManager.listData = array;
             }
         }
         /**
@@ -211,23 +222,28 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
          * list has layout and can archive better user experience and better load time,
          * which reduce waste cell layout when list layout changes.
          * */
-        WXSDKManager.getInstance().getWXDomManager().post(new Runnable() {
-            @Override
-            public void run() {
-                if(isDestoryed()){
-                    return;
-                }
-                long start = System.currentTimeMillis();
-                if(mDomObject != null && mDomObject.getCellList() != null){
-                    for(int i=0; i<mDomObject.getCellList().size(); i++){
-                        addChild(DomTreeBuilder.buildTree(mDomObject.getCellList().get(i),  WXRecyclerTemplateList.this));
+        if(mDomObject != null
+                && mDomObject.getCellList() != null
+                && mDomObject.getCellList().size() > 0){
+            Runnable runnable =  new Runnable() {
+                // @Override
+                public void run() {
+                    if(isDestoryed()){
+                        return;
+                    }
+                    long start = System.currentTimeMillis();
+                    if(mDomObject != null && mDomObject.getCellList() != null){
+                        for(int i=0; i<mDomObject.getCellList().size(); i++){
+                            addChild(ComponentUtils.buildTree(mDomObject.getCellList().get(i),  WXRecyclerTemplateList.this));
+                        }
+                    }
+                    if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG){
+                        WXLogUtils.d(TAG, "TemplateList BuildDomTree Used " + (System.currentTimeMillis() - start));
                     }
                 }
-                if(WXEnvironment.isApkDebugable()){
-                    WXLogUtils.d(TAG, "TemplateList BuildDomTree Used " + (System.currentTimeMillis() - start));
-                }
-            }
-        });
+            };
+            WXSDKManager.getInstance().getWXDomManager().post(runnable);
+        }
     }
 
     @Override
@@ -331,15 +347,17 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                  * compute sticky position
                  * */
                 if(mStickyHelper != null){
-                    mStickyHelper.getStickyPositions().clear();
-                    if(listData != null){
-                        for(int i=0; i<listData.size(); i++){
-                            WXCell cell = getSourceTemplate(i);
-                            if(cell == null){
-                                continue;
-                            }
-                            if(cell.isSticky()){
-                                mStickyHelper.getStickyPositions().add(i);
+                    if(mStickyHelper.getStickyTypes().size() > 0){
+                        mStickyHelper.getStickyPositions().clear();
+                        if(cellDataManager.listData != null){
+                            for(int i = 0; i< cellDataManager.listData.size(); i++){
+                                WXCell cell = getSourceTemplate(i);
+                                if(cell == null){
+                                    continue;
+                                }
+                                if(cell.isSticky()){
+                                    mStickyHelper.getStickyPositions().add(i);
+                                }
                             }
                         }
                     }
@@ -347,7 +365,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                 if(getHostView() != null && getHostView().getRecyclerViewBaseAdapter() != null){
                     getHostView().getRecyclerViewBaseAdapter().notifyDataSetChanged();
                 }
-                if(WXEnvironment.isApkDebugable()){
+                if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG){
                     WXLogUtils.d(TAG, "WXTemplateList notifyDataSetChanged");
                 }
             }
@@ -390,7 +408,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         if(template == null){
             return;
         }
-        if(listData == null || mStickyHelper == null){
+        if(cellDataManager.listData == null || mStickyHelper == null){
             return;
         }
         if(!mStickyHelper.getStickyTypes().contains(template.getRef())){
@@ -403,7 +421,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
     public void unbindStickStyle(WXComponent component) {
         WXComponent  template = findParentType(component, WXCell.class);
         if(template == null
-                || listData == null
+                || cellDataManager.listData == null
                 || mStickyHelper == null){
             return;
         }
@@ -425,14 +443,14 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
     }
 
     private void setAppearanceWatch(WXComponent component, int event, boolean enable) {
-        if(listData == null
+        if(cellDataManager.listData == null
                 || mAppearHelpers == null
                 || TextUtils.isEmpty(component.getRef())){
             return;
         }
-        WXComponent cell = findCell(component);
-        int type = getCellItemType(cell);
-        if(type <= 0){
+        WXCell cell = findCell(component);
+        int type = getCellTemplateItemType(cell);
+        if(type < 0){
             return;
         }
         List<AppearanceHelper>  mAppearListeners = mAppearHelpers.get(type);
@@ -517,9 +535,9 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         }
         WXCell cell = findCell(component);
         if(typeIndex >= 0){
-            if(listData != null && component.getRef() != null){
+            if(cellDataManager.listData != null && component.getRef() != null){
                 int typePosition = 0;
-                for(int i=0; i<listData.size(); i++){
+                for(int i = 0; i< cellDataManager.listData.size(); i++){
                     WXCell template = getSourceTemplate(i);
                     if(template == null){
                         continue;
@@ -533,7 +551,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                     }
                 }
                 if(position < 0){
-                    position = listData.size() - 1;
+                    position = cellDataManager.listData.size() - 1;
                 }
             }
         }
@@ -585,6 +603,9 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
     @Override
     public void addChild(WXComponent child, int index) {
+        /**
+         *  dom object in component is not tree, build tree
+         * */
         if(!(child instanceof  WXCell)) {
             super.addChild(child, index);
         }
@@ -593,8 +614,30 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         }
         if(child instanceof WXCell){
             if(child.getDomObject() != null && child.getDomObject().getAttrs() != null){
-                Object templateId = child.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_TYPE);
+                Object templateId = child.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_CASE);
                 String key = WXUtils.getString(templateId, null);
+                if(getDomObject().getAttrs().containsKey(Constants.Name.Recycler.LIST_DATA_TEMPLATE_SWITCH_KEY)){
+                    if(defaultTemplateCell == null){
+                        defaultTemplateCell = (WXCell) child;
+                        if(!TextUtils.isEmpty(key)){
+                            defaultTemplateKey = key;
+                        }else{
+                            key = defaultTemplateKey;
+                            child.getDomObject().getAttrs().put(Constants.Name.Recycler.SLOT_TEMPLATE_CASE, key);
+                        }
+                    }
+                }else{
+                    if(defaultTemplateCell == null
+                            || child.getDomObject().getAttrs().containsKey(Constants.Name.Recycler.SLOT_TEMPLATE_DEFAULT)){
+                        defaultTemplateCell = (WXCell) child;
+                        if(!TextUtils.isEmpty(key)){
+                            defaultTemplateKey = key;
+                        }else{
+                            key = defaultTemplateKey;
+                            child.getDomObject().getAttrs().put(Constants.Name.Recycler.SLOT_TEMPLATE_CASE, key);
+                        }
+                    }
+                }
                 if(key != null){
                     if(child.getDomObject() instanceof  WXCellDomObject
                             && getDomObject() instanceof  WXRecyclerDomObject){
@@ -602,7 +645,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                         domObject.setRecyclerDomObject((WXRecyclerDomObject) getDomObject());
                     }
                     mTemplateSources.put(key, (WXCell) child);
-                    ensureSourceCellRenderWithData((WXCell)child);
+                    renderTemplateCellWithData((WXCell)child);
                     if(mTemplateViewTypes.get(key) == null){
                         mTemplateViewTypes.put(key, mTemplateViewTypes.size());
                     }
@@ -614,6 +657,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
 
 
+
+
     /**
      * RecyclerView manage its children in a way that different from {@link WXVContainer}. Therefore,
      * {@link WXVContainer#addSubView(View, int)} is an empty implementation in {@link
@@ -671,9 +716,9 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
             case Constants.Name.Recycler.LIST_DATA_ITEM_INDEX:
                 listDataIndexKey = WXUtils.getString(param, listDataIndexKey);
                 return true;
-            case Constants.Name.Recycler.LIST_DATA_TEMPLATE_KEY:
-            case Constants.Name.Recycler.SLOT_TEMPLATE_TYPE:
-                listDataTemplateKey = WXUtils.getString(param, Constants.Name.Recycler.SLOT_TEMPLATE_TYPE);
+            case Constants.Name.Recycler.LIST_DATA_TEMPLATE_SWITCH_KEY:
+            case Constants.Name.Recycler.SLOT_TEMPLATE_CASE:
+                listDataTemplateKey = WXUtils.getString(param, Constants.Name.Recycler.SLOT_TEMPLATE_CASE);
                 return true;
             case LOADMOREOFFSET:
                 return true;
@@ -761,68 +806,112 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
     @JSMethod
     public void setListData(Object param){
-        boolean update = listData != null &&  listData != param;
+        boolean update = cellDataManager.listData != param;
         if(param instanceof  JSONArray){
-            listData = (JSONArray) param;
-        }
-        if(update){
-            notifyUpdateList();
+            if(update){
+                cellDataManager.setListData((JSONArray) param);
+                notifyUpdateList();
+            }
         }
     }
 
     @JSMethod
-    public void  appendData(JSONArray arrayObject){
-        if(listData == null){
-            listData = new JSONArray();
+    public void  appendData(JSONArray data){
+        if(data == null || data.size() == 0){
+            return;
+        }
+        if(cellDataManager.listData == null){
+            cellDataManager.listData = new JSONArray();
+        }
+        int position = cellDataManager.listData.size();
+        if(position < 0){
+            position = 0;
         }
-        if(arrayObject instanceof  JSONArray){
-            listData.addAll(arrayObject);
+        if(data instanceof  JSONArray){
+            cellDataManager.listData.addAll(data);
         }
-        notifyUpdateList();
+        getHostView().getRecyclerViewBaseAdapter().notifyItemRangeInserted(position, data.size());
     }
 
     @JSMethod
-    public void  insertData(JSONObject data, int index){
+    public void  insertData(int index, Object data){
         if(data == null){
             return;
         }
-        if(listData == null || index >= listData.size()){
+
+        if(cellDataManager.listData == null || index > cellDataManager.listData.size()){
             return;
         }
-        listData.add(index, data);
-        notifyUpdateList();
+        boolean renderStateChanged = cellDataManager.insertData(index, data);
+        if(renderStateChanged){
+            notifyUpdateList();
+        }else{
+            getHostView().getRecyclerViewBaseAdapter().notifyItemInserted(index);
+        }
+    }
+
+    @JSMethod
+    public void  appendRange(int index, JSONArray data){
+         insertRange(index, data);
     }
 
+
+    /**
+     * when update data, list maybe contains sticky, may use position, when position changed should be rendered
+     * so use notifyUpdateList is better
+     * */
+
     @JSMethod
-    public void  updateData(JSONObject data, int index){
+    public void  insertRange(int index, JSONArray data){
+        if(data == null || data.size() == 0){
+            return;
+        }
+        if(cellDataManager.listData == null || index > cellDataManager.listData.size()){
+            return;
+        }
+        boolean renderStateChange = cellDataManager.insertRange(index, data);
+        if(renderStateChange){
+            notifyUpdateList();
+        }else{
+            getHostView().getRecyclerViewBaseAdapter().notifyItemRangeInserted(index, data.size());
+        }
+
+    }
+
+    @JSMethod
+    public void  updateData(int index, Object data){
         if(data == null){
             return;
         }
-        if(listData == null || index >= listData.size()){
+        if(cellDataManager.listData == null || index >= cellDataManager.listData.size()){
             return;
         }
-        listData.set(index, data);
-        notifyUpdateList();
+        boolean onlyDataChange = cellDataManager.updateData(data, index);
+        if(onlyDataChange) {
+            getHostView().getRecyclerViewBaseAdapter().notifyItemChanged(index, data);
+        }else{
+            notifyUpdateList();
+        }
     }
 
     @JSMethod
-    public void  removeData(List<Integer> array){
-        if(array == null || array.size() == 0){
+    public void  removeData(int index, int count){
+        if(cellDataManager.listData == null
+                || index >= cellDataManager.listData.size()){
             return;
         }
-        int offset = 0;
-        for(Integer index : array){
-            if(listData == null
-                    || index == null){
-                return;
-            }
-            index -= offset;
-            if(index < listData.size()){
-                listData.remove((int)index);
-                offset++;
-            }
+        if(count <= 0){
+            count = 1;
+        }
+        int removeCount = 0;
+        while (count > 0 && index < cellDataManager.listData.size()){
+            cellDataManager.removeData(index);
+            count--;
+            removeCount++;
+        }
+        if(removeCount > 0) {
+            notifyUpdateList();
         }
-        notifyUpdateList();
     }
 
 
@@ -1009,8 +1098,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                 getHostView().getInnerView().setAdapter(null);
             }
         }
-        if(listData != null){
-            listData = null;
+        if(cellDataManager.listData != null){
+            cellDataManager.setListData(null);
         }
         if(mStickyHelper != null){
             mStickyHelper = null;
@@ -1045,25 +1134,21 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
             return;
         }
         long start = System.currentTimeMillis();
-        boolean resuse = templateViewHolder.getHolderPosition() >= 0;
         templateViewHolder.setHolderPosition(position);
-        Object data = listData.get(position);
-        if(component.getRenderData() == data){
-            component.setHasLayout(true);
+        Object data = cellDataManager.listData.get(position);
+        CellRenderState cellRenderState = cellDataManager.getRenderState(position);
+        if(component.getRenderData() == data && (cellRenderState == null || !cellRenderState.isDirty())){
+            if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG){
+                WXLogUtils.d(TAG,  position + " position "+ getTemplateKey(position) + " onBindViewHolder none data update ");
+            }
+            return;  //none update just return
         }else{
-            List<WXComponent> updates = Statements.doRender(component, getStackContextForPosition(position, data));
+            List<WXComponent> updates = doRenderTemplate(component, position);
             Statements.doInitCompontent(updates);
             component.setRenderData(data);
-            if(WXEnvironment.isApkDebugable()){
-                WXLogUtils.d(TAG, position + getTemplateKey(position) + " onBindViewHolder render used " + (System.currentTimeMillis() - start));
-            }
-            if(component.isHasLayout()){
-                resuse = true;
-            }
             Layouts.doLayoutAsync(templateViewHolder, true);
-            component.setHasLayout(true);
-            if(WXEnvironment.isApkDebugable()){
-                WXLogUtils.d(TAG,  position + getTemplateKey(position) + " onBindViewHolder layout used " + (System.currentTimeMillis() - start) + resuse);
+            if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG){
+                WXLogUtils.d(TAG,  position + " position "+ getTemplateKey(position) + " onBindViewHolder used " + (System.currentTimeMillis() - start));
             }
         }
     }
@@ -1077,41 +1162,34 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
             view.setLayoutParams(new FrameLayout.LayoutParams(0, 0));
             return new TemplateViewHolder(view, viewType);
         }
-        TemplateCache cache = mTemplatesCache.get(template);
-        WXCell component =  null;
+        WXCell component =  getCellTemplateFromCache(template);
         boolean cacheHit = true;
-        if(cache != null && cache.cells != null && cache.cells.size() > 0){
-            component = cache.cells.poll();
-        }
-        if(cache == null ||  !cache.isLoadIng){
-            asyncLoadTemplateCache(template);
-        }
         if(component == null){
             cacheHit = false;
             if(!source.isSourceUsed()){
                 source.setSourceUsed(true);
-                ensureSourceCellRenderWithData(source);
+                renderTemplateCellWithData(source);
                 component = source;
-                if(WXEnvironment.isApkDebugable()) {
+                if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) {
                     WXLogUtils.d(TAG, template + " onCreateViewHolder source");
                 }
             }
         }
         if(component == null) {
             long start = System.currentTimeMillis();
-            component = (WXCell) copyCell(source);
-            if(WXEnvironment.isApkDebugable()) {
+            component = (WXCell) copyComponentFromSourceCell(source);
+            if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) {
                 WXLogUtils.d(TAG, template + " onCreateViewHolder copy used " + (System.currentTimeMillis() - start));
             }
         }
         if(component.isLazy()) {
-            doInitLazyCell(component, template, false);
-            if(WXEnvironment.isApkDebugable()) {
-                WXLogUtils.d(TAG, template + " onCreateViewHolder  cache hit " + cacheHit   + " idle init false ");
+            doCreateCellViewBindData(component, template, false);
+            if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) {
+                WXLogUtils.d(TAG, template + " onCreateViewHolder  cache hit " + cacheHit   + " view not idle init");
             }
         }else{
-            if(WXEnvironment.isApkDebugable()) {
-                WXLogUtils.d(TAG, template + " onCreateViewHolder  cache hit " + cacheHit + " idle init true");
+            if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) {
+                WXLogUtils.d(TAG, template + " onCreateViewHolder  cache hit " + cacheHit + " view idle init");
             }
         }
         TemplateViewHolder templateViewHolder = new TemplateViewHolder(component, viewType);
@@ -1123,8 +1201,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
      * copy cell component from source, init render data, and return source
      * if none data, return null
      * */
-    private WXComponent copyCell(WXCell cell){
-        ensureSourceCellRenderWithData(cell);
+    public WXComponent copyComponentFromSourceCell(WXCell cell){
+        renderTemplateCellWithData(cell);
         WXCell component = (WXCell) Statements.copyComponentTree(cell);
         if(component.getDomObject() instanceof  WXCellDomObject
                 && getDomObject() instanceof  WXRecyclerDomObject){
@@ -1135,15 +1213,20 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         return component;
     }
 
-    private void ensureSourceCellRenderWithData(WXCell cell){
+    /**
+     *  render  init with  cell with one data,
+     *  if template has already render with data, done nothing
+     *  @param  cell
+     * */
+    private synchronized void renderTemplateCellWithData(WXCell cell){
         if(cell.getRenderData() == null){
-            if(listData != null && listData.size() > 0){
+            if(cellDataManager.listData != null && cellDataManager.listData.size() > 0){
                 synchronized (this){
                     if(cell.getRenderData() == null){
-                        for(int i=0; i<listData.size(); i++){
+                        for(int i = 0; i< cellDataManager.listData.size(); i++){
                             if(cell == getSourceTemplate(i)){
-                                Object data = listData.get(i);
-                                Statements.doRender(cell, getStackContextForPosition(i, data));
+                                Object data = cellDataManager.listData.get(i);
+                                doRenderTemplate(cell, i);
                                 Layouts.doSafeLayout(cell, new CSSLayoutContext());
                                 cell.setRenderData(data);
                                 break;
@@ -1162,37 +1245,33 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
      * */
     @Override
     public int getItemViewType(int position) {
-        JSONObject data = safeGetListData(position);
-        String template = data.getString(listDataTemplateKey);
-        if(TextUtils.isEmpty(template)){
-            template = "";
-        }
+        String template = getTemplateKey(position);
         int type =  mTemplateViewTypes.indexOfKey(template);
         if(type < 0){
-            type = 0;
+            type = mTemplateViewTypes.indexOfKey(EMPTY_HOLDER_TEMPLATE_KEY);
         }
         return type;
     }
 
 
     /**
-     * return code context for render component
+     * create code context for render component and do render
      * */
-    private ArrayStack getStackContextForPosition(int position,  Object item){
-        if(!bindIngStackContext.isEmpty()){
-            bindIngStackContext.getList().clear();
-        }
-        if(!bindIngMapContext.isEmpty()){
-            bindIngMapContext.clear();
-        }
-        ArrayStack stack = bindIngStackContext;
-        Map map = bindIngMapContext;
-        if(listData != null){
-            stack.push(listData);
+    private List<WXComponent> doRenderTemplate(WXCell cell, int position){
+        this.cellRenderContext.clear();
+        Object item = cellDataManager.listData.get(position);
+        CellRenderState cellRenderState = cellDataManager.getRenderState(position);
+        cellRenderContext.renderState = cellRenderState;
+        cellRenderContext.templateList = this;
+        cellRenderContext.position = position;
+
+        ArrayStack stack = cellRenderContext.stack;
+        Map map = cellRenderContext.map;
+        if(cellDataManager.listData != null){
             stack.push(map);
-            map.put(listDataKey, listData);
+            map.put(listDataKey, cellDataManager.listData);
             if(!TextUtils.isEmpty(listDataIndexKey)) {
-                map.put(listDataIndexKey, position);
+                map.put(listDataIndexKey, new PositionRef(cellRenderState));
             }
             if(!TextUtils.isEmpty(listDataItemKey)) {
                 map.put(listDataItemKey, item);
@@ -1200,17 +1279,51 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
                 stack.push(item);
             }
         }
-        return stack;
+        if(cellRenderState.itemId <= 0){
+            getItemId(position);
+        }
+        List<WXComponent> updates = Statements.doRender(cell, this.cellRenderContext);
+        if(cellRenderState.isDirty()){
+            cellRenderState.resetDirty();
+        }
+        return  updates;
+    }
+
+    public ArrayStack  copyStack(CellRenderContext context, ArrayStack stack){
+        ArrayStack  onceStack = new ArrayStack();
+        for(int index=0;  index <  stack.size(); index++) {
+            Object value = stack.get(index);
+            if(value instanceof  Map){
+                value  = new HashMap((Map) value);
+            }
+            onceStack.push(value);
+        }
+        return onceStack;
     }
 
+
     /**
      * return tepmlate key for position
      * */
     public String getTemplateKey(int position){
-        JSONObject data =  safeGetListData(position);
-        String template = data.getString(listDataTemplateKey);
+        Object data =  safeGetListData(position);
+        return getTemplateKey(data);
+    }
+
+    /**
+     * return template key for position never be null
+     * */
+    public String getTemplateKey(Object data){
+        String template = null;
+        if(data instanceof  JSONObject) {
+            template = ((JSONObject)data).getString(listDataTemplateKey);
+        }
         if(TextUtils.isEmpty(template)){
-            template = "";
+            if(defaultTemplateCell != null){
+                template  = defaultTemplateKey;
+            }else {
+                template = "";
+            }
         }
         return  template;
     }
@@ -1226,17 +1339,17 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
 
     /**
-     * get template key from cell; 0  for default type
+     * get template key from cell; -1 for  cann't find  type
      * */
-    private int getCellItemType(WXComponent cell){
+    private int getCellTemplateItemType(WXCell cell){
         if(cell == null){
             return  -1;
         }
         if(cell.getDomObject() != null && cell.getDomObject().getAttrs() != null){
-            Object templateId = cell.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_TYPE);
+            Object templateId = cell.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_CASE);
             String template = WXUtils.getString(templateId, null);
-            if(template == null){
-                return  0;
+            if(cell == defaultTemplateCell){
+                template = defaultTemplateKey;
             }
             int type =  mTemplateViewTypes.indexOfKey(template);
             if(type < 0){
@@ -1249,7 +1362,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
     @Override
     public int getItemCount() {
-        if(listData == null){
+        if(cellDataManager.listData == null){
             return  0;
         }
         if(mTemplateViewTypes == null || mTemplateViewTypes.size() <= 1){
@@ -1258,7 +1371,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         if(mTemplateSources == null || mTemplateSources.size() == 0){
             return  0;
         }
-        return listData.size();
+        return cellDataManager.listData.size();
     }
 
     @Override
@@ -1274,18 +1387,22 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
      * */
     @Override
     public long getItemId(int position) {
-        if(getItemViewType(position) <= 0){
-            return RecyclerView.NO_ID;
-        }
-        JSONObject data = safeGetListData(position);
-        if(data.containsKey(Constants.Name.Recycler.LIST_DATA_ITEM_ID)) {
-            String itemKey = data.getString(Constants.Name.Recycler.LIST_DATA_ITEM_ID);
-            if(TextUtils.isEmpty(itemKey)){
-                return  position;
+        CellRenderState renderState = cellDataManager.getRenderState(position);
+        if(renderState.itemId <=  0){
+            String template = getTemplateKey(position);
+            if(TextUtils.isEmpty(template)){
+                return RecyclerView.NO_ID;
+            }
+            Object data = safeGetListData(position);
+            if(data instanceof  JSONObject && ((JSONObject)data).containsKey("keyItemId")){
+                renderState.itemId =  ((JSONObject)data).getLongValue("keyItemId");
+            }else{
+                long id = Math.abs(data.hashCode());
+                long itemId = (id<< 24) + position;
+                renderState.itemId = itemId;
             }
-            return  itemKey.hashCode();
         }
-        return position;
+        return renderState.itemId;
     }
 
     @Override
@@ -1305,16 +1422,16 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
             }
             float offsetParsed = WXViewUtils.getRealPxByWidth(Integer.parseInt(offset),getInstance().getInstanceViewPortWidth());
 
-            if (offScreenY <= offsetParsed && listData != null) {
-                if (mListCellCount != listData.size()
+            if (offScreenY <= offsetParsed && cellDataManager.listData != null) {
+                if (mListCellCount != cellDataManager.listData.size()
                         || mForceLoadmoreNextTime) {
                     fireEvent(Constants.Event.LOADMORE);
-                    mListCellCount = listData.size();
+                    mListCellCount = cellDataManager.listData.size();
                     mForceLoadmoreNextTime = false;
                 }
             }
         } catch (Exception e) {
-            WXLogUtils.d(TAG + "onLoadMore :", e);
+            WXLogUtils.d(TAG + " onLoadMore : ", e);
         }
     }
 
@@ -1432,13 +1549,13 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
     }
 
 
-    private JSONObject safeGetListData(int position){
+    private Object safeGetListData(int position){
         try{
-            return listData.getJSONObject(position);
+            return cellDataManager.listData.get(position);
         }catch (Exception e){return  JSONObject.parseObject("{}");}
     }
 
-    private void  notifyUpdateList(){
+    public void  notifyUpdateList(){
         if(getHostView() == null
                 || getHostView().getInnerView() == null
                 || listUpdateRunnable == null){
@@ -1454,10 +1571,10 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
 
     private int calcContentSize() {
         int totalHeight = 0;
-        if(listData == null){
+        if(cellDataManager.listData == null){
             return totalHeight;
         }
-        for (int i = 0; i < listData.size(); i++) {
+        for (int i = 0; i < cellDataManager.listData.size(); i++) {
             WXCell child = getSourceTemplate(i);
             if (child != null) {
                 totalHeight += child.getLayoutHeight();
@@ -1567,114 +1684,45 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
     }
 
 
+
     /**
-     * copy cell async and save to cache
+     * @param  template  template name
+     * get cell template component from cache, if cell component not load
+     * start load cell template
      * */
-    private void asyncLoadTemplateCache(final String template) {
-        if(Thread.currentThread() != Looper.getMainLooper().getThread()){
-            if(listData == null || listData.size() == 0){
-                return;
-            }
-            boolean firstScreenContains = false;
-            for(int i=0; i<listData.size(); i++){
-                if(template.equals(getTemplateKey(i))){
-                    firstScreenContains = true;
-                    break;
-                }
-            }
-            if(!firstScreenContains){
-                return;
-            }
-        }
-        final WXCell source = mTemplateSources.get(template);
-        if(source == null){
-            return;
-        }
-        TemplateCache cellCache = mTemplatesCache.get(template);
-        if(cellCache == null){
-            cellCache = new TemplateCache();
-            mTemplatesCache.put(template, cellCache);
-        }
-        if(cellCache.cells.size() > 0){
-            cellCache.isLoadIng = false;
-            return;
-        }
-        if(cellCache.isLoadIng){
-            return;
+    private WXCell getCellTemplateFromCache(final String template){
+        TemplateCache cache = mTemplatesCache.get(template);
+        WXCell component =  null;
+        if(cache != null && cache.cells != null && cache.cells.size() > 0){
+            component = cache.cells.poll();
         }
-        cellCache.isLoadIng = true;
-        AsyncTask<Void,Void, Void> preloadTask = new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                TemplateCache cellCache = mTemplatesCache.get(template);
-                if(cellCache == null || cellCache.cells == null){
-                    return null;
-                }
-                while (cellCache.cells.size() < templateCacheSize){
-                    WXCell component = (WXCell) copyCell(source);
-                    if(component == null){
-                        return null;
-                    }
-                    if(source.getInstance() == null || source.getInstance().isDestroy()){
-                        return null;
-                    }
-                    cellCache.cells.add(component);
-                }
-                return null;
+        if(cache == null ||  !cache.isLoadIng){
+            if(cache == null){
+                cache = new TemplateCache();
+                mTemplatesCache.put(template, cache);
             }
-            @Override
-            protected void onPostExecute(Void aVoid) {
-                if(source.getInstance() == null || source.getInstance().isDestroy()){
-                    return;
+            cache.isLoadIng = true;
+            WXCell source = mTemplateSources.get(template);
+            if(source != null){
+                boolean allowPreload = WXUtils.getBoolean(source.getDomObject().getAttrs().get("preload"), true);
+                if(allowPreload) {
+                    AsyncCellLoadTask asyncCellLoadTask = new AsyncCellLoadTask(template, source, this);
+                    asyncCellLoadTask.startTask();
                 }
-                final TemplateCache cellCache = mTemplatesCache.get(template);
-                if(cellCache == null){
-                    return;
-                }
-                if(cellCache.cells == null
-                        || cellCache.cells.size() == 0){
-                    cellCache.isLoadIng = false;
-                    return;
-                }
-                Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
-                    @Override
-                    public boolean queueIdle() {
-                        if(source.getInstance() == null || source.getInstance().isDestroy()){
-                            return false;
-                        }
-                        ConcurrentLinkedQueue<WXCell> queue =  cellCache.cells;
-                        Iterator<WXCell> iterator =  queue.iterator();
-                        while (iterator.hasNext()){
-                            WXCell  component =  iterator.next();
-                            if(component.isLazy()){
-                                doInitLazyCell(component, template, true);
-                                return iterator.hasNext();
-                            }
-                        }
-                        return false;
-                    }
-                });
-                cellCache.isLoadIng = false;
             }
-        };
-        preloadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+        }
+        return  component;
     }
 
-    private static void  doInitLazyCell(WXCell component, String template, boolean inPreload){
+    /**
+     * create view for lazy cell and bind data
+     * */
+    public static void doCreateCellViewBindData(WXCell component, String template, boolean inPreload){
         if(component.isLazy()){
             long start = System.currentTimeMillis();
-            component.lazy(false);
-            component.createView();
-            if(WXEnvironment.isApkDebugable()) {
-                WXLogUtils.d(TAG,  "doInitLazyCell idle" + inPreload + template +  " createView used " + (System.currentTimeMillis() - start));
-            }
-            component.applyLayoutAndEvent(component);
-            if(WXEnvironment.isApkDebugable()) {
-                WXLogUtils.d(TAG,  "doInitLazyCell idle" + inPreload  + template +  " apply layout used " + (System.currentTimeMillis() - start));
-            }
-            component.bindData(component);
-            if(WXEnvironment.isApkDebugable()) {
-                WXLogUtils.d(TAG, "doInitLazyCell idle" + inPreload + template + " bindData used " + (System.currentTimeMillis() - start));
+            ComponentUtils.initLazyComponent(component, null);
+            if(WXEnvironment.isOpenDebugLog() && ENABLE_TRACE_LOG) {
+                WXLogUtils.d(TAG, " doCreateCellViewBindData " + template + " in preload "+ inPreload + " used " + (System.currentTimeMillis() - start));
             }
         }
     }
@@ -1685,4 +1733,20 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
         }
         return mScrollStartEndHelper;
     }
+
+    public int getTemplateCacheSize() {
+        return templateCacheSize;
+    }
+
+    public ConcurrentHashMap<String, TemplateCache> getTemplatesCache() {
+        if(mTemplatesCache == null){
+            mTemplatesCache = new ConcurrentHashMap<>();
+        }
+        return mTemplatesCache;
+    }
+
+
+    public CellDataManager getCellDataManager() {
+        return cellDataManager;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/test/java/com/taobao/weex/el/FailedCaseTest.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/test/java/com/taobao/weex/el/FailedCaseTest.java b/android/sdk/src/test/java/com/taobao/weex/el/FailedCaseTest.java
new file mode 100644
index 0000000..f887dca
--- /dev/null
+++ b/android/sdk/src/test/java/com/taobao/weex/el/FailedCaseTest.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.el;
+
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.el.parse.ArrayStack;
+import com.taobao.weex.el.parse.Parser;
+import com.taobao.weex.el.parse.Token;
+
+import junit.framework.TestCase;
+
+/**
+ * Created by furture on 2018/1/25.
+ */
+
+public class FailedCaseTest extends TestCase {
+
+
+    public void testVElseIf0(){
+        JSONObject data = new JSONObject();
+        JSONObject item = new JSONObject();
+        item.put("number", 0.0);
+        data.put("item", item);
+        ArrayStack stack = new ArrayStack();
+        stack.push(data);
+
+        Token token = Parser.parse("!(item.number%3 === 0) && (item.number%3 === 1)");
+
+        System.out.println(token.toString() + "  " + token.execute(stack));
+
+        Token if2 = Parser.parse("!(!(item.number%3 === 0) && (item.number%3 === 1))");
+        System.out.println(if2 + "   " + if2.execute(stack));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/test/java/com/taobao/weex/ui/component/binding/StatementTest.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/test/java/com/taobao/weex/ui/component/binding/StatementTest.java b/android/sdk/src/test/java/com/taobao/weex/ui/component/binding/StatementTest.java
index 3924a3a..2233acc 100644
--- a/android/sdk/src/test/java/com/taobao/weex/ui/component/binding/StatementTest.java
+++ b/android/sdk/src/test/java/com/taobao/weex/ui/component/binding/StatementTest.java
@@ -37,6 +37,7 @@ import com.taobao.weex.ui.component.WXComponentFactory;
 import com.taobao.weex.ui.component.WXDiv;
 import com.taobao.weex.ui.component.WXText;
 import com.taobao.weex.ui.component.list.WXCell;
+import com.taobao.weex.ui.component.list.template.CellRenderContext;
 
 import junit.framework.Assert;
 
@@ -57,7 +58,6 @@ import org.robolectric.annotation.Config;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Stack;
 
 /**
  * Created by furture on 2017/8/18.
@@ -166,7 +166,7 @@ public class StatementTest {
         return cell;
     }
 
-    private ArrayStack createContext(int count){
+    private CellRenderContext createContext(int count){
         JSONObject data = new JSONObject();
         data.put("item", new JSONObject());
         data.getJSONObject("item").put("name", "hello world");
@@ -178,7 +178,9 @@ public class StatementTest {
         data.put("dataList", datas);
         ArrayStack context = new ArrayStack();
         context.push(data);
-        return context;
+        CellRenderContext cellRenderContext = new CellRenderContext();
+        cellRenderContext.stack = context;
+        return cellRenderContext;
     }
 
 }


[4/7] incubator-weex git commit: [WEEX-174][android] TemplateList Support Lifecycle and statefull component

Posted by mi...@apache.org.
[WEEX-174][android] TemplateList Support Lifecycle and statefull component


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/886d859a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/886d859a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/886d859a

Branch: refs/heads/master
Commit: 886d859ab75ef892aad50506dace5818c06b66d2
Parents: 20c293f
Author: jianbai.gbj <ji...@alibaba-inc.com>
Authored: Wed Dec 20 15:07:01 2017 +0800
Committer: jianbai.gbj <ji...@alibaba-inc.com>
Committed: Thu Feb 8 11:55:09 2018 +0800

----------------------------------------------------------------------
 .../java/com/alibaba/weex/WXApplication.java    |   6 +-
 .../weex/extend/module/WXWsonTestModule.java    |  58 ++
 .../java/com/taobao/weex/WXEnvironment.java     |  17 +-
 .../com/taobao/weex/bridge/WXBridgeManager.java | 112 +++-
 .../java/com/taobao/weex/common/Constants.java  |   7 +-
 .../main/java/com/taobao/weex/dom/WXAttr.java   |  19 +-
 .../java/com/taobao/weex/dom/WXDomModule.java   |   7 +-
 .../java/com/taobao/weex/dom/WXDomObject.java   |  29 +-
 .../main/java/com/taobao/weex/dom/WXEvent.java  |  91 +--
 .../main/java/com/taobao/weex/dom/WXStyle.java  |  54 ++
 .../dom/action/AbstractAddElementAction.java    |  15 +-
 .../com/taobao/weex/dom/action/Actions.java     |   6 +
 .../weex/dom/action/AddElementAction.java       |   8 +-
 .../weex/dom/action/UpdateAttributeAction.java  |   6 +-
 .../dom/action/UpdateComponentDataAction.java   |  69 +++
 .../com/taobao/weex/dom/binding/ELUtils.java    |   1 +
 .../taobao/weex/dom/binding/WXStatement.java    |   6 +
 .../java/com/taobao/weex/el/parse/Block.java    |   3 +-
 .../java/com/taobao/weex/el/parse/Operator.java |   3 +-
 .../com/taobao/weex/el/parse/Operators.java     |  11 +-
 .../java/com/taobao/weex/el/parse/Token.java    |   3 +-
 .../weex/ui/component/ComponentUtils.java       | 122 ++++
 .../taobao/weex/ui/component/WXComponent.java   | 110 +++-
 .../weex/ui/component/binding/Layouts.java      |  23 +-
 .../weex/ui/component/binding/Statements.java   | 224 +++++--
 .../taobao/weex/ui/component/list/WXCell.java   |  18 +-
 .../list/template/AsyncCellLoadTask.java        | 128 ++++
 .../list/template/CellDataManager.java          | 272 +++++++++
 .../list/template/CellRenderContext.java        |  79 +++
 .../list/template/CellRenderState.java          | 122 ++++
 .../component/list/template/DomTreeBuilder.java | 100 ---
 .../ui/component/list/template/PositionRef.java |  64 ++
 .../template/VirtualComponentLifecycle.java     |  45 ++
 .../list/template/WXRecyclerTemplateList.java   | 610 ++++++++++---------
 .../java/com/taobao/weex/el/FailedCaseTest.java |  50 ++
 .../ui/component/binding/StatementTest.java     |   8 +-
 36 files changed, 1940 insertions(+), 566 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
----------------------------------------------------------------------
diff --git a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java b/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
index 41ca4cb..0561043 100644
--- a/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
+++ b/android/playground/app/src/main/java/com/alibaba/weex/WXApplication.java
@@ -38,6 +38,7 @@ import com.alibaba.weex.extend.module.RenderModule;
 import com.alibaba.weex.extend.module.SyncTestModule;
 import com.alibaba.weex.extend.module.WXEventModule;
 import com.alibaba.weex.extend.module.WXTitleBar;
+import com.alibaba.weex.extend.module.WXWsonTestModule;
 import com.facebook.drawee.backends.pipeline.Fresco;
 import com.taobao.weex.InitConfig;
 import com.taobao.weex.WXEnvironment;
@@ -62,7 +63,8 @@ public class WXApplication extends Application {
      * Fresco.initialize(this,config);
      **/
 //    initDebugEnvironment(true, false, "DEBUG_SERVER_HOST");
-    WXBridgeManager.updateGlobalConfig("wson_off");
+    WXBridgeManager.updateGlobalConfig("wson_on");
+    WXEnvironment.setOpenDebugLog(true);
     WXEnvironment.setApkDebugable(true);
     WXSDKEngine.addCustomOptions("appName", "WXSample");
     WXSDKEngine.addCustomOptions("appGroup", "WXApp");
@@ -95,6 +97,8 @@ public class WXApplication extends Application {
       WXSDKEngine.registerModule("geolocation", GeolocationModule.class);
 
       WXSDKEngine.registerModule("titleBar", WXTitleBar.class);
+
+      WXSDKEngine.registerModule("wsonTest", WXWsonTestModule.class);
       /**
        * override default image tag
        * WXSDKEngine.registerComponent("image", FrescoImageComponent.class);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXWsonTestModule.java
----------------------------------------------------------------------
diff --git a/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXWsonTestModule.java b/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXWsonTestModule.java
new file mode 100644
index 0000000..b018678
--- /dev/null
+++ b/android/playground/app/src/main/java/com/alibaba/weex/extend/module/WXWsonTestModule.java
@@ -0,0 +1,58 @@
+package com.alibaba.weex.extend.module;
+
+import android.util.Log;
+
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.annotation.JSMethod;
+import com.taobao.weex.bridge.JSCallback;
+import com.taobao.weex.common.WXModule;
+import com.taobao.weex.wson.Wson;
+
+/**
+ * Created by furture on 2018/1/18.
+ */
+
+public class WXWsonTestModule extends WXModule {
+
+    @JSMethod(uiThread = false)
+    public boolean callPass(JSONObject params) {
+        if(params.get("refundId") != null){
+            if(params.get("refundId").getClass() != Long.class){
+                Log.e("Weex", "weex wson refundId failed case");
+                return false;
+            }
+            return  ((Long)params.get("refundId")) == 6419458776149741l;
+        }
+
+        if(params.get("refundId2") != null){
+            if(params.get("refundId2").getClass() != Long.class){
+                Log.e("Weex", "weex wson refundId failed case");
+                return false;
+            }
+            return ((Long)params.get("refundId2")) == 64194587761497416l;
+        }
+
+
+
+
+        return true;
+    }
+
+    @JSMethod(uiThread = false)
+    public Object back(JSONObject params) {
+        JSONObject back = new JSONObject(params);
+        back.put("longMax", Long.MAX_VALUE);
+        back.put("longMin", Long.MIN_VALUE);
+        back.put("javaJSON", back.toJSONString());
+        return back;
+    }
+
+    @JSMethod(uiThread = false)
+    public void  backAsync(JSONObject params, JSCallback callback) {
+        JSONObject back = new JSONObject(params);
+        back.put("longMax", Long.MAX_VALUE);
+        back.put("longMin", Long.MIN_VALUE);
+        back.put("javaJSON", back.toJSONString());
+        callback.invoke(back);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
index e19570f..e6084d9 100644
--- a/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
+++ b/android/sdk/src/main/java/com/taobao/weex/WXEnvironment.java
@@ -88,6 +88,8 @@ public class WXEnvironment {
   private static boolean isApkDebug = true;
   public static boolean isPerf = false;
 
+  private static boolean openDebugLog = false;
+
   private static String sGlobalFontFamily;
 
   private static Map<String, String> options = new HashMap<>();
@@ -305,9 +307,20 @@ public class WXEnvironment {
       }
     }
   }
-    
+
+  public static boolean isOpenDebugLog() {
+    return openDebugLog;
+  }
+
+  public static void setOpenDebugLog(boolean openDebugLog) {
+    WXEnvironment.openDebugLog = openDebugLog;
+  }
+
   public static void  setApkDebugable(boolean debugable){
-      isApkDebug  = debugable;
+    isApkDebug  = debugable;
+    if(!isApkDebug){
+       openDebugLog = false;
+    }
   }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
index 349b5f8..79e3127 100644
--- a/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
+++ b/android/sdk/src/main/java/com/taobao/weex/bridge/WXBridgeManager.java
@@ -78,6 +78,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Stack;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import static com.taobao.weex.bridge.WXModuleManager.getDomModule;
 import static com.taobao.weex.bridge.WXModuleManager.createDomModule;
@@ -115,6 +117,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   public static final String METHOD_REGISTER_COMPONENTS = "registerComponents";
   public static final String METHOD_FIRE_EVENT = "fireEvent";
   public static final String METHD_FIRE_EVENT_SYNC = "fireEventSync";
+  public static final String METHD_COMPONENT_HOOK_SYNC = "componentHook";
   public static final String METHOD_CALLBACK = "callback";
   public static final String METHOD_REFRESH_INSTANCE = "refreshInstance";
   public static final String METHOD_NOTIFY_TRIM_MEMORY = "notifyTrimMemory";
@@ -361,7 +364,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   public Object callNativeModule(String instanceId, String module, String method, JSONArray arguments, Object options) {
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callNativeModule >>>> instanceId:").append(instanceId)
           .append(", module:").append(module).append(", method:").append(method).append(", arguments:").append(arguments);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -389,7 +392,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   public Object callNativeModule(String instanceId, String module, String method, JSONArray arguments, JSONObject options) {
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callNativeModule >>>> instanceId:").append(instanceId)
           .append(", module:").append(module).append(", method:").append(method).append(", arguments:").append(arguments);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -420,7 +423,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   }
 
   public Object callNativeComponent(String instanceId, String componentRef, String method, JSONArray arguments, Object options) {
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callNativeComponent >>>> instanceId:").append(instanceId)
           .append(", componentRef:").append(componentRef).append(", method:").append(method).append(", arguments:").append(arguments);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -458,7 +461,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
       return IWXBridge.INSTANCE_RENDERING_ERROR;
     }
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
     mLodBuilder.append("[WXBridgeManager] callNative >>>> instanceId:").append(instanceId)
         .append(", tasks:").append(tasks).append(", callback:").append(callback);
     WXLogUtils.d(mLodBuilder.substring(0));
@@ -534,12 +537,12 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 	  return IWXBridge.INSTANCE_RENDERING_ERROR;
     }
 
-    // if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
     mLodBuilder.append("[WXBridgeManager] callCreateBody >>>> instanceId:").append(instanceId)
         .append(", tasks:").append(tasks).append(", callback:").append(callback);
     WXLogUtils.d(mLodBuilder.substring(0));
     mLodBuilder.setLength(0);
-    // }
+    }
 
 
     if (mDestroyedInstanceId != null && mDestroyedInstanceId.contains(instanceId)) {
@@ -581,7 +584,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   // callUpdateFinish
   public int callUpdateFinish(String instanceId, String callback) {
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callUpdateFinish >>>> instanceId:").append(instanceId)
           .append(", callback:").append(callback);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -615,12 +618,12 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   // callCreateFinish
   public int callCreateFinish(String instanceId, String callback) {
-    // if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
     mLodBuilder.append("[WXBridgeManager] callCreateFinish >>>> instanceId:").append(instanceId)
         .append(", callback:").append(callback);
     WXLogUtils.d(mLodBuilder.substring(0));
     mLodBuilder.setLength(0);
-    // }
+     }
 
     if (mDestroyedInstanceId != null && mDestroyedInstanceId.contains(instanceId)) {
       return IWXBridge.DESTROY_INSTANCE;
@@ -650,7 +653,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   // callRefreshFinish
   public int callRefreshFinish(String instanceId, String callback) {
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callRefreshFinish >>>> instanceId:").append(instanceId)
           .append(", callback:").append(callback);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -693,7 +696,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
       return IWXBridge.INSTANCE_RENDERING_ERROR;
     }
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callUpdateAttrs >>>> instanceId:").append(instanceId)
           .append(", ref:").append(ref)
           .append(", task:").append(task)
@@ -748,7 +751,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 			  "task is empty", null);
 	  return IWXBridge.INSTANCE_RENDERING_ERROR;
     }
-   if (WXEnvironment.isApkDebugable()) {
+   if (WXEnvironment.isOpenDebugLog()) {
     mLodBuilder.append("[WXBridgeManager] callUpdateStyle >>>> instanceId:").append(instanceId)
         .append(", ref:").append(ref)
         .append(", task:").append(task)
@@ -796,7 +799,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   // callUpdateStyle
   public int callRemoveElement(String instanceId, String ref, String callback) {
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callRemoveElement >>>> instanceId:").append(instanceId)
           .append(", ref:").append(ref);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -835,7 +838,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   // callMoveElement
   public int callMoveElement(String instanceId, String ref, String parentref, String index, String callback) {
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callMoveElement >>>> instanceId:").append(instanceId)
           .append(", parentref:").append(parentref)
           .append(", index:").append(index)
@@ -872,13 +875,13 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   public int callAddEvent(String instanceId, String ref, String event, String callback) {
 
-//    if (WXEnvironment.isApkDebugable()) {
+   if (WXEnvironment.isOpenDebugLog()) {
     mLodBuilder.append("[WXBridgeManager] callAddEvent >>>> instanceId:").append(instanceId)
         .append(", ref:").append(ref)
         .append(", event:").append(event);
     WXLogUtils.d(mLodBuilder.substring(0));
     mLodBuilder.setLength(0);
-//    }
+   }
 
     if (mDestroyedInstanceId != null && mDestroyedInstanceId.contains(instanceId)) {
       return IWXBridge.DESTROY_INSTANCE;
@@ -911,7 +914,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   public int callRemoveEvent(String instanceId, String ref, String event, String callback) {
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callRemoveEvent >>>> instanceId:").append(instanceId)
           .append(", ref:").append(ref)
           .append(", event:").append(event);
@@ -950,7 +953,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   public int callAddElement(String instanceId, String ref, JSONObject dom, String index, String callback) {
 
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("[WXBridgeManager] callNative::callAddElement >>>> instanceId:").append(instanceId)
           .append(", ref:").append(ref).append(", dom:").append(dom).append(", callback:").append(callback);
       WXLogUtils.d(mLodBuilder.substring(0));
@@ -1108,9 +1111,68 @@ public class WXBridgeManager implements Callback, BactchExecutor {
   }
 
 
+
   /**
-   * aync call js event and return result in eventResult callback
+   * ref, type, data, domChanges
    * */
+  public EventResult syncCallJSEventWithResult(final String method, final String instanceId, final List<Object> params, final Object... args) {
+    final CountDownLatch waitLatch = new CountDownLatch(1);
+    EventResult callback = new EventResult(){
+      @Override
+      public void onCallback(Object result) {
+        super.onCallback(result);
+        waitLatch.countDown();
+      }
+    };
+    try{
+      asyncCallJSEventWithResult(callback, method, instanceId, params, args);
+      waitLatch.await(100, TimeUnit.MILLISECONDS);
+      return  callback;
+    }catch (Exception e){
+      WXLogUtils.e("syncCallJSEventWithResult", e);
+      return  callback;
+    }
+  }
+
+  public void asyncCallJSEventVoidResult(final String method, final String instanceId, final List<Object> params, final Object... args) {
+    post(new Runnable() {
+      @Override
+      public void run() {
+        try{
+          if (args == null || args.length == 0) {
+            return;
+          }
+
+          ArrayList<Object> argsList = new ArrayList<>();
+          for (Object arg : args) {
+            argsList.add(arg);
+          }
+          if (params != null) {
+            ArrayMap map = new ArrayMap(4);
+            map.put(KEY_PARAMS, params);
+            argsList.add(map);
+          }
+
+          WXHashMap<String, Object> task = new WXHashMap<>();
+          task.put(KEY_METHOD, method);
+          task.put(KEY_ARGS, argsList);
+          Object[] tasks = {task};
+          WXJSObject[] jsArgs = {
+                  new WXJSObject(WXJSObject.String, instanceId),
+                  WXJsonUtils.wsonWXJSObject(tasks)};
+          invokeExecJS(String.valueOf(instanceId), null, METHOD_CALL_JS, jsArgs, true);
+          jsArgs[0] = null;
+          jsArgs = null;
+        }catch (Exception e){
+          WXLogUtils.e("asyncCallJSEventVoidResult" , e);
+        }
+      }
+    });
+  }
+
+    /**
+     * aync call js event and return result in eventResult callback
+     * */
   private void asyncCallJSEventWithResult(final EventResult eventCallback, final String method, final String instanceId, final List<Object> params, final Object... args) {
     post(new Runnable() {
       @Override
@@ -1153,7 +1215,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
           taskResult = null;
           jsArgs = null;
         }catch (Exception e){
-          WXLogUtils.e("asyncCallJSEventWithResult ");
+          WXLogUtils.e("asyncCallJSEventWithResult" , e);
         }
       }
     });
@@ -1363,7 +1425,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         return;
       }
       long start = System.currentTimeMillis();
-      if (WXEnvironment.isApkDebugable()) {
+      if (WXEnvironment.isOpenDebugLog()) {
         WXLogUtils.d("refreshInstance >>>> instanceId:" + instanceId
             + ", data:" + refreshData.data + ", isDirty:" + refreshData.isDirty);
       }
@@ -1524,7 +1586,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
         return;
       }
       try {
-        if (WXEnvironment.isApkDebugable()) {
+        if (WXEnvironment.isOpenDebugLog()) {
           WXLogUtils.d("createInstance >>>> instanceId:" + instance.getInstanceId()
               + ", options:"
               + WXJsonUtils.fromObjectToJSONString(options)
@@ -1584,7 +1646,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   private void invokeDestroyInstance(String instanceId) {
     try {
-      if (WXEnvironment.isApkDebugable()) {
+      if (WXEnvironment.isOpenDebugLog()) {
         WXLogUtils.d("destroyInstance >>>> instanceId:" + instanceId);
       }
       WXJSObject instanceIdObj = new WXJSObject(WXJSObject.String,
@@ -1642,7 +1704,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   public void invokeExecJS(String instanceId, String namespace, String function,
                            WXJSObject[] args, boolean logTaskDetail) {
-     if (WXEnvironment.isApkDebugable()) {
+     if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("callJS >>>> instanceId:").append(instanceId)
           .append("function:").append(function);
       if (logTaskDetail) {
@@ -1656,7 +1718,7 @@ public class WXBridgeManager implements Callback, BactchExecutor {
 
   private byte[] invokeExecJSWithResult(String instanceId, String namespace, String function,
                                        WXJSObject[] args,boolean logTaskDetail){
-    if (WXEnvironment.isApkDebugable()) {
+    if (WXEnvironment.isOpenDebugLog()) {
       mLodBuilder.append("callJS >>>> instanceId:").append(instanceId)
               .append("function:").append(function);
       if(logTaskDetail) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
index 66c4df0..c107ee8 100644
--- a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
+++ b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
@@ -207,10 +207,9 @@ public class Constants {
       String LIST_DATA = "listData";
       String LIST_DATA_ITEM  ="alias";
       String LIST_DATA_ITEM_INDEX = "index";
-      String LIST_DATA_TEMPLATE_KEY = "templateKey";
-
-      String SLOT_TEMPLATE_TYPE = "templateType";
-      String LIST_DATA_ITEM_ID = "itemId";
+      String LIST_DATA_TEMPLATE_SWITCH_KEY = "switch";
+      String SLOT_TEMPLATE_CASE = "case";
+      String SLOT_TEMPLATE_DEFAULT = "default";
       String CELL_INDEX = "cellIndex";
       String TYPE_INDEX = "typeIndex";
     }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/WXAttr.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXAttr.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXAttr.java
index b05d46d..1025584 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXAttr.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXAttr.java
@@ -455,7 +455,7 @@ public class WXAttr implements Map<String, Object>,Cloneable {
   /**
    * filter dynamic state ment
    * */
-  private Map<String, Object> filterBindingStatement(Map attrs) {
+  public Map<String, Object> filterBindingStatement(Map attrs) {
     if(attrs == null || attrs.size() == 0){
       return attrs;
     }
@@ -511,6 +511,13 @@ public class WXAttr implements Map<String, Object>,Cloneable {
               return  true;
            }
         }
+
+        if(WXStatement.WX_ONCE.equals(key)){
+          if(mStatement == null){
+             mStatement = new WXStatement();
+          }
+          mStatement.put(key, true);
+        }
         return  false;
   }
 
@@ -519,11 +526,15 @@ public class WXAttr implements Map<String, Object>,Cloneable {
   }
 
   @Override
-  protected WXAttr clone(){
+  protected WXAttr clone() {
     WXAttr wxAttr = new WXAttr();
     wxAttr.skipFilterPutAll(attr);
-    wxAttr.mBindingAttrs = mBindingAttrs;
-    wxAttr.mStatement = mStatement;
+    if (mBindingAttrs != null) {
+      wxAttr.mBindingAttrs = new ArrayMap<>(mBindingAttrs);
+    }
+    if (mStatement != null){
+       wxAttr.mStatement = new WXStatement(mStatement);
+     }
     return wxAttr;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
index 7ab97a9..b764630 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
@@ -61,6 +61,9 @@ public final class WXDomModule extends WXModule {
   public static final String UPDATE_FINISH = "updateFinish";
   public static final String SCROLL_TO_ELEMENT = "scrollToElement";
   public static final String ADD_RULE = "addRule";
+
+  public static final String UPDATE_COMPONENT_DATA = "updateComponentData";
+
   public static final String GET_COMPONENT_RECT = "getComponentRect";
 
   public static final String WXDOM = "dom";
@@ -97,7 +100,9 @@ public final class WXDomModule extends WXModule {
     try {
       Action action = Actions.get(method,args);
       if(action == null){
-        WXLogUtils.e("Unknown dom action.");
+         WXLogUtils.e("Unknown dom action "
+                 +  method + " "  + args.toJSONString());
+         return null;
       }
       if(action instanceof DOMAction){
         postAction((DOMAction)action, CREATE_BODY.equals(method) || ADD_RULE.equals(method));

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
index d062a8a..dde66dc 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
@@ -134,6 +134,27 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
     mDomThreadNanos += (System.nanoTime() - startNanos);
   }
 
+  /**
+   * diff with tranverse tree, only tranverse update tree
+   * */
+  public void traverseUpdateTree(Consumer...consumers){
+    if (consumers == null) {
+      return;
+    }
+    if(!hasUpdate()){
+      return;
+    }
+    for (Consumer consumer:consumers){
+      consumer.accept(this);
+    }
+    int count = childCount();
+    WXDomObject child;
+    for (int i = 0; i < count; ++i) {
+      child = getChild(i);
+      child.traverseTree(consumers);
+    }
+  }
+
 
   public int getViewPortWidth() {
     return mViewPortWidth;
@@ -230,15 +251,13 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
     this.mRef = (String) map.get("ref");
     Object style = map.get("style");
     if (style != null && style instanceof JSONObject) {
-      WXStyle styles = new WXStyle();
-      styles.putAll((JSONObject) style,false);
+      WXStyle styles = new WXStyle((JSONObject) style,false);
       this.mStyles = styles;
       this.transition = WXTransition.fromMap(styles, this);
     }
     Object attr = map.get("attr");
     if (attr != null && attr instanceof JSONObject) {
       WXAttr attrs = new WXAttr((JSONObject) attr);
-      //WXJsonUtils.putAll(attrs, (JSONObject) attr);
       this.mAttributes = attrs;
     }
     Object event = map.get("event");
@@ -470,7 +489,7 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
     if (mAttributes == null) {
       mAttributes = new WXAttr();
     }
-    mAttributes.putAll(updates);
+    mAttributes.skipFilterPutAll(updates);
     if(hasNewLayout()){
       markUpdateSeen();
     }
@@ -658,7 +677,7 @@ public class WXDomObject extends CSSNode implements Cloneable,ImmutableDomObject
     if (sDestroy.get()) {
       return null;
     }
-    if(cloneThis){
+    if(isCloneThis()){
       return  this;
     }
     WXDomObject dom = null;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/WXEvent.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXEvent.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXEvent.java
index fe7f8cf..3e99cfa 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXEvent.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXEvent.java
@@ -35,21 +35,29 @@ public class WXEvent extends ArrayList<String> implements Serializable, Cloneabl
 
   private static final long serialVersionUID = -8186587029452440107L;
 
+
+  /**
+   *  event data format
+   *  {
+   *  type: 'appear',
+   *  params: [
+   *  { '@binding': 'index' },
+   *   'static',
+   *   { '@binding': 'item.name' },
+   *  { '@binding': '$event' }
+   *  ]
+   *  }
+   * */
+  public static final String EVENT_KEY_TYPE = "type";
+  public static final String EVENT_KEY_ARGS = "params";
+
+
   /**
    * dynamic binding event args, can be null, only weex use
    * */
   private ArrayMap mEventBindingArgs;
   private ArrayMap<String, List<Object>> mEventBindingArgsValues;
 
-
-  @Override
-  public WXEvent clone() {
-    WXEvent event = (WXEvent) super.clone();
-    event.mEventBindingArgs = mEventBindingArgs;
-    event.mEventBindingArgsValues = mEventBindingArgsValues;
-    return  event;
-  }
-
   @Override
   public void clear() {
     if(mEventBindingArgs != null){
@@ -63,13 +71,13 @@ public class WXEvent extends ArrayList<String> implements Serializable, Cloneabl
 
 
   public boolean remove(String o) {
-     if(mEventBindingArgs != null){
-        mEventBindingArgs.remove(o);
-     }
-     if(mEventBindingArgsValues != null){
-        mEventBindingArgsValues.remove(o);
-     }
-     return super.remove(o);
+    if(mEventBindingArgs != null){
+      mEventBindingArgs.remove(o);
+    }
+    if(mEventBindingArgsValues != null){
+      mEventBindingArgsValues.remove(o);
+    }
+    return super.remove(o);
   }
 
   /**
@@ -89,14 +97,14 @@ public class WXEvent extends ArrayList<String> implements Serializable, Cloneabl
     if(event instanceof CharSequence){
       String eventName = event.toString();
       if(!contains(eventName)){
-          add(eventName);
+        add(eventName);
       }
     }else if(event instanceof JSONObject){
       JSONObject bindings = (JSONObject) event;
       String eventName = bindings.getString(WXEvent.EVENT_KEY_TYPE);
       Object args = bindings.get(WXEvent.EVENT_KEY_ARGS);
       if (eventName != null) {
-           putEventBindingArgs(eventName, args);
+        putEventBindingArgs(eventName, args);
       }
     }
   }
@@ -116,41 +124,40 @@ public class WXEvent extends ArrayList<String> implements Serializable, Cloneabl
   }
 
   public void putEventBindingArgs(String event, Object args){
-      if(!contains(event)){
-          add(event);
-      }
-      if(args != null){
-        if(mEventBindingArgs == null){
-          mEventBindingArgs = new ArrayMap();
-        }
-        mEventBindingArgs.put(event, ELUtils.bindingBlock(args));
+    if(!contains(event)){
+      add(event);
+    }
+    if(args != null){
+      if(mEventBindingArgs == null){
+        mEventBindingArgs = new ArrayMap();
       }
+      mEventBindingArgs.put(event, ELUtils.bindingBlock(args));
+    }
   }
 
   public void putEventBindingArgsValue(String event, List<Object> value){
     if(mEventBindingArgsValues == null){
-        mEventBindingArgsValues = new ArrayMap();
+      mEventBindingArgsValues = new ArrayMap();
     }
     if(value == null){
       mEventBindingArgsValues.remove(event);
     }else{
-       mEventBindingArgsValues.put(event, value);
+      mEventBindingArgsValues.put(event, value);
     }
   }
 
 
-  /**
-   *  event data format
-   *  {
-   *  type: 'appear',
-   *  params: [
-   *  { '@binding': 'index' },
-   *   'static',
-   *   { '@binding': 'item.name' },
-   *  { '@binding': '$event' }
-   *  ]
-   *  }
-   * */
-  public static final String EVENT_KEY_TYPE = "type";
-  public static final String EVENT_KEY_ARGS = "params";
+
+  @Override
+  public WXEvent clone() {
+    WXEvent event = new WXEvent();
+    event.addAll(this);
+    if(mEventBindingArgs != null) {
+      event.mEventBindingArgs = new ArrayMap(mEventBindingArgs);
+    }
+    event.mEventBindingArgsValues = null; //this should not be clone, it dynamic args
+    return  event;
+  }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
index 6dc444a..ff1842a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXStyle.java
@@ -26,11 +26,14 @@ import android.text.Layout;
 import android.text.TextUtils;
 
 import com.taobao.weex.common.Constants;
+import com.taobao.weex.dom.binding.ELUtils;
+import com.taobao.weex.dom.binding.WXStatement;
 import com.taobao.weex.dom.flex.CSSAlign;
 import com.taobao.weex.dom.flex.CSSFlexDirection;
 import com.taobao.weex.dom.flex.CSSJustify;
 import com.taobao.weex.dom.flex.CSSPositionType;
 import com.taobao.weex.dom.flex.CSSWrap;
+import com.taobao.weex.el.parse.Parser;
 import com.taobao.weex.ui.component.WXText;
 import com.taobao.weex.ui.component.WXTextDecoration;
 import com.taobao.weex.utils.WXUtils;
@@ -41,6 +44,9 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 
+import static com.taobao.weex.dom.binding.ELUtils.COMPONENT_PROPS;
+import static com.taobao.weex.dom.binding.ELUtils.EXCLUDES_BINDING;
+
 /**
  * Store value of component style
  *
@@ -54,11 +60,20 @@ public class WXStyle implements Map<String, Object>,Cloneable {
   private Map<String,Map<String,Object>> mPesudoStyleMap = new ArrayMap<>();// clz_group:{styleMap}
   private Map<String,Object> mPesudoResetStyleMap = new ArrayMap<>();
 
+  /**
+   * dynamic binding attrs, can be null, only weex use
+   * */
+  private ArrayMap<String, Object>  mBindingStyle;
 
   public WXStyle(){
     mStyles = new ArrayMap<>();
   }
 
+  public WXStyle(Map<String, Object> mStyles, boolean byPesudo) {
+    this();
+    this.putAll(filterBindingStyles(mStyles), byPesudo);
+  }
+
   @Nullable
   public String getBlur() {
     if(get(Constants.Name.FILTER) == null) {
@@ -749,6 +764,7 @@ public class WXStyle implements Map<String, Object>,Cloneable {
   protected WXStyle clone(){
     WXStyle style = new WXStyle();
     style.mStyles.putAll(this.mStyles);
+    style.mBindingStyle = mBindingStyle;
 
     for(Entry<String,Map<String,Object>> entry:this.mPesudoStyleMap.entrySet()){
       Map<String,Object> valueClone = new ArrayMap<>();
@@ -759,4 +775,42 @@ public class WXStyle implements Map<String, Object>,Cloneable {
     style.mPesudoResetStyleMap.putAll(this.mPesudoResetStyleMap);
     return style;
   }
+
+
+  /**
+   * filter dynamic state ment
+   * */
+  private Map<String, Object> filterBindingStyles(Map styles) {
+    if(styles == null || styles.size() == 0){
+      return styles;
+    }
+    Set<Map.Entry<String,Object>> entries = styles.entrySet();
+    Iterator<Entry<String,Object>> it =  entries.iterator();
+    while (it.hasNext()){
+      Map.Entry<String,Object> entry = it.next();
+      if(filterBindingStyle(entry.getKey(), entry.getValue())){
+        it.remove();
+      }
+    }
+    return styles;
+  }
+
+  /**
+   * filter dynamic attrs and statements
+   * */
+  private boolean filterBindingStyle(String key, Object value) {
+    if(ELUtils.isBinding(value)){
+        if(mBindingStyle == null){
+          mBindingStyle = new ArrayMap<String, Object>();
+        }
+        value = ELUtils.bindingBlock(value);
+        mBindingStyle.put(key, value);
+        return  true;
+    }
+    return  false;
+  }
+
+  public ArrayMap<String, Object> getBindingStyle() {
+    return mBindingStyle;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
index cbe5a53..b6a27fb 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AbstractAddElementAction.java
@@ -27,9 +27,11 @@ import com.taobao.weex.common.WXErrorCode;
 import com.taobao.weex.dom.DOMAction;
 import com.taobao.weex.dom.DOMActionContext;
 import com.taobao.weex.dom.RenderAction;
+import com.taobao.weex.dom.WXCellDomObject;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.tracing.Stopwatch;
 import com.taobao.weex.tracing.WXTracing;
+import com.taobao.weex.ui.component.WXBasicComponentType;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXComponentFactory;
 import com.taobao.weex.ui.component.WXVContainer;
@@ -132,8 +134,19 @@ public abstract class AbstractAddElementAction extends TraceableAction implement
     }
     Stopwatch.split("createComponent");
 
-    context.addDomInfo(domObject.getRef(), component);
+    boolean needAddDomInfo = true;
+    if(domObject.getType().equals(WXBasicComponentType.CELL_SLOT)
+            && domObject instanceof WXCellDomObject){
+       needAddDomInfo = false;
+    }
+
+    if(needAddDomInfo) {
+      context.addDomInfo(domObject.getRef(), component);
+    }
+
+
     context.postRenderTask(this);
+
     addAnimationForDomTree(context, domObject);
 
 //    instance.commitUTStab(IWXUserTrackAdapter.DOM_MODULE, WXErrorCode.WX_SUCCESS);

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
index c284997..9f60765 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/Actions.java
@@ -42,6 +42,7 @@ import static com.taobao.weex.dom.WXDomModule.REMOVE_ELEMENT;
 import static com.taobao.weex.dom.WXDomModule.REMOVE_EVENT;
 import static com.taobao.weex.dom.WXDomModule.SCROLL_TO_ELEMENT;
 import static com.taobao.weex.dom.WXDomModule.UPDATE_ATTRS;
+import static com.taobao.weex.dom.WXDomModule.UPDATE_COMPONENT_DATA;
 import static com.taobao.weex.dom.WXDomModule.UPDATE_FINISH;
 import static com.taobao.weex.dom.WXDomModule.UPDATE_STYLE;
 
@@ -121,6 +122,11 @@ public class Actions {
           return null;
         }
         return new InvokeMethodAction(args.getString(0),args.getString(1),args.getJSONArray(2));
+      case UPDATE_COMPONENT_DATA:
+        if(args == null || args.size() < 3){
+          return null;
+        }
+        return new UpdateComponentDataAction(args.getString(0), args.getJSONObject(1), args.getString(2));
     }
 
     return null;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
index 2958ea5..87f5d56 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/AddElementAction.java
@@ -20,13 +20,15 @@ package com.taobao.weex.dom.action;
 
 import com.alibaba.fastjson.JSONObject;
 import com.taobao.weex.WXSDKInstance;
-import com.taobao.weex.adapter.IWXUserTrackAdapter;
 import com.taobao.weex.common.WXErrorCode;
 import com.taobao.weex.dom.DOMActionContext;
 import com.taobao.weex.dom.RenderActionContext;
+import com.taobao.weex.dom.WXCellDomObject;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.tracing.Stopwatch;
 import com.taobao.weex.tracing.WXTracing;
+import com.taobao.weex.ui.component.ComponentUtils;
+import com.taobao.weex.ui.component.WXBasicComponentType;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.utils.WXLogUtils;
@@ -60,6 +62,10 @@ final class AddElementAction extends AbstractAddElementAction {
 			  .append("!(comp instanceof WXVContainer)");
       return null;
     }
+    if(domObject.getType().equals(WXBasicComponentType.CELL_SLOT)
+            && domObject instanceof WXCellDomObject){
+      return ComponentUtils.buildTree(domObject, (WXVContainer) comp);
+    }
     return generateComponentTree(context, domObject, (WXVContainer) comp);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
index bbeeea1..0591f73 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
@@ -60,9 +60,11 @@ class UpdateAttributeAction extends TraceableAction implements DOMAction, Render
       }
       return;
     }
-
+    domObject.getAttrs().filterBindingStatement(mData);
     domObject.updateAttr(mData);
-    context.postRenderTask(this);
+    if(mData.size() > 0) {
+       context.postRenderTask(this);
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateComponentDataAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateComponentDataAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateComponentDataAction.java
new file mode 100644
index 0000000..347c886
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateComponentDataAction.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.dom.action;
+
+import android.text.TextUtils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.bridge.SimpleJSCallback;
+import com.taobao.weex.dom.RenderAction;
+import com.taobao.weex.dom.RenderActionContext;
+import com.taobao.weex.ui.component.WXComponent;
+import com.taobao.weex.ui.component.list.template.CellDataManager;
+import com.taobao.weex.ui.component.list.template.WXRecyclerTemplateList;
+import com.taobao.weex.utils.WXLogUtils;
+
+
+/**
+ * Created by furture on 2018/1/23.
+ */
+
+public class UpdateComponentDataAction implements RenderAction {
+
+    private String virtualComponentId;
+    private JSONObject data;
+    private String callback;
+
+    public UpdateComponentDataAction(String virtualComponentId,
+                                     JSONObject data, String callback) {
+        this.virtualComponentId = virtualComponentId;
+        this.data = data;
+        this.callback = callback;
+    }
+
+    @Override
+    public void executeRender(RenderActionContext context) {
+        String ref = CellDataManager.getListRef(virtualComponentId);
+        if(TextUtils.isEmpty(ref)){
+            WXLogUtils.e("wrong virtualComponentId split error " + virtualComponentId);
+            return;
+        }
+        WXComponent component = context.getComponent(ref);
+        if(component instanceof  WXRecyclerTemplateList){
+            WXRecyclerTemplateList templateList = (WXRecyclerTemplateList) component;
+            templateList.getCellDataManager().updateVirtualComponentData(virtualComponentId, data);
+            templateList.notifyUpdateList();
+            SimpleJSCallback jsCallback = new SimpleJSCallback(component.getInstanceId(), callback);
+            jsCallback.invoke(true);
+        }else{
+            WXLogUtils.e("recycler-list wrong virtualComponentId " + virtualComponentId);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/binding/ELUtils.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/binding/ELUtils.java b/android/sdk/src/main/java/com/taobao/weex/dom/binding/ELUtils.java
index 8202a46..dac03b2 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/binding/ELUtils.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/binding/ELUtils.java
@@ -39,6 +39,7 @@ public class ELUtils {
      * */
     public static final String IS_COMPONENT_ROOT = "@isComponentRoot";
 
+
     public static final String COMPONENT_PROPS = "@componentProps";
 
     public static final  String[] EXCLUDES_BINDING = {"clickEventParams"};

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/dom/binding/WXStatement.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/binding/WXStatement.java b/android/sdk/src/main/java/com/taobao/weex/dom/binding/WXStatement.java
index ca20dca..6a760cb 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/binding/WXStatement.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/binding/WXStatement.java
@@ -63,6 +63,12 @@ public class WXStatement extends ArrayMap<String, Object> implements  Cloneable
      * */
     public static final String WX_IF = "[[match]]";
 
+
+    /**
+     * once statement
+     * */
+    public static final  String WX_ONCE = "[[once]]";
+
     public WXStatement() {
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/el/parse/Block.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/el/parse/Block.java b/android/sdk/src/main/java/com/taobao/weex/el/parse/Block.java
index 5d15220..6c3e29a 100644
--- a/android/sdk/src/main/java/com/taobao/weex/el/parse/Block.java
+++ b/android/sdk/src/main/java/com/taobao/weex/el/parse/Block.java
@@ -57,7 +57,6 @@ class Block extends Token {
         return token.execute(context);
     }
 
-    /**
     @Override
     public String toString() {
         if(getType() == TYPE_ARRAY){
@@ -68,5 +67,5 @@ class Block extends Token {
             }
             return "{" + tokens + '}';
         }
-    }*/
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operator.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operator.java b/android/sdk/src/main/java/com/taobao/weex/el/parse/Operator.java
index d592579..d597be8 100644
--- a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operator.java
+++ b/android/sdk/src/main/java/com/taobao/weex/el/parse/Operator.java
@@ -93,7 +93,6 @@ class Operator extends Token {
         }
     }
 
-    /**
     @Override
     public String toString() {
         if(Operators.AND_NOT.equals(getToken())){
@@ -103,5 +102,5 @@ class Operator extends Token {
             return "{" + first +  getToken() + second + "}";
         }
         return "{" + self + getToken() + first + ":" + second + "}";
-    }*/
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java b/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java
index b2e1c02..a8de759 100644
--- a/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java
+++ b/android/sdk/src/main/java/com/taobao/weex/el/parse/Operators.java
@@ -18,6 +18,9 @@
  */
 package com.taobao.weex.el.parse;
 
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.ui.component.list.template.CellRenderContext;
+
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -63,6 +66,12 @@ public class Operators {
         if(context == null){
             return  null;
         }
+        if(context instanceof CellRenderContext){
+            if(WXEnvironment.isApkDebugable()){
+                throw new IllegalArgumentException("rong context CellRenderContext, you should pass it's stack");
+            }
+            context = ((CellRenderContext) context).stack;
+        }
         if(context instanceof ArrayStack){
             ArrayStack stack = (ArrayStack) context;
             for(int index=stack.size()-1; index >= 0; index--){
@@ -257,7 +266,7 @@ public class Operators {
         }
         Object leftValue =  null;
         if(left != null){
-            leftValue  = left.execute(context);;
+            leftValue  = left.execute(context);
         }
         Object rightValue = null;
         if(right != null) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/el/parse/Token.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/el/parse/Token.java b/android/sdk/src/main/java/com/taobao/weex/el/parse/Token.java
index 88a6ff8..44f9135 100644
--- a/android/sdk/src/main/java/com/taobao/weex/el/parse/Token.java
+++ b/android/sdk/src/main/java/com/taobao/weex/el/parse/Token.java
@@ -74,11 +74,10 @@ public class Token {
         throw new IllegalArgumentException("unhandled token type " + type);
     }
 
-    /***
     @Override
     public String toString() {
         return "{" + token + "," + type + '}';
-    }*/
+    }
 
     public String getToken() {
         return token;

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/ComponentUtils.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/ComponentUtils.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/ComponentUtils.java
new file mode 100644
index 0000000..b28a94f
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/ComponentUtils.java
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component;
+
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.WXSDKManager;
+import com.taobao.weex.dom.DOMActionContext;
+import com.taobao.weex.dom.WXDomObject;
+import com.taobao.weex.dom.action.TraceableAction;
+import com.taobao.weex.utils.WXLogUtils;
+
+/**
+ * Created by furture on 2018/1/25.
+ */
+
+public class ComponentUtils {
+
+    private static final String TAG = "ComponentUtils";
+
+    /**
+     * init component  if component is lazy,
+     * if component is not lazy, do nothing
+     * */
+    public static void initLazyComponent(WXComponent component, WXVContainer mParent){
+        if(component.isLazy()){
+            component.lazy(false);
+            if(mParent != null){
+                int index = mParent.indexOf(component);
+                mParent.createChildViewAt(index);
+            }else {
+                component.createView();
+            }
+            component.applyLayoutAndEvent(component);
+            component.bindData(component);
+        }
+    }
+
+    /**
+     * build component tree and dom tree for template list
+     * */
+    public static synchronized final WXComponent buildTree(WXDomObject domObject, WXVContainer parent){
+        DOMActionContext domActionContext = WXSDKManager.getInstance().getWXDomManager().getDomContext(parent.getInstanceId());
+        if(domActionContext == null){
+            return null;
+        }
+        DomTreeBuilder builder = new DomTreeBuilder();
+        domObject.traverseTree(
+                domActionContext.getAddDOMConsumer(),
+                domActionContext.getApplyStyleConsumer()
+        );
+        return builder.buildComponentTree(domActionContext, domObject, parent);
+    }
+
+
+    /**
+     * dom tree build
+     * */
+    static class DomTreeBuilder extends TraceableAction {
+
+        private WXComponent buildComponentTree(DOMActionContext context, WXDomObject dom, WXVContainer parent) {
+            if (dom == null) {
+                return null;
+            }
+            long startNanos = System.nanoTime();
+            dom.setCloneThis(true);
+            WXComponent component = WXComponentFactory.newInstance(context.getInstance(), dom, parent);
+            if (component != null) {
+                component.mTraceInfo.domThreadStart = dom.mDomThreadTimestamp;
+                component.mTraceInfo.rootEventId = mTracingEventId;
+                component.mTraceInfo.domQueueTime = mDomQueueTime;
+            }
+            context.registerComponent(dom.getRef(), component);
+            if (component instanceof WXVContainer) {
+                WXVContainer container = (WXVContainer) component;
+                WXDomObject parentDom = (WXDomObject) container.getDomObject();
+                for (int i = 0; i < dom.childCount(); ++i) {
+                    WXDomObject child = dom.getChild(i);
+                    if (child != null) {
+                        WXComponent childComponent = buildComponentTree(context, child, container);
+                        container.addChild(childComponent);
+                        WXDomObject childDomObject = (WXDomObject) childComponent.getDomObject();
+                        if(childDomObject != child) {
+                            int index = parentDom.index(child);
+                            parentDom.add(childDomObject, index);
+                            if(index >= 0) {
+                                parentDom.remove(child);
+                                i--;
+                            }
+                            RuntimeException exception = new IllegalArgumentException(childDomObject.getClass().getName()
+                                    + " not support clone this");
+                            WXLogUtils.e("weex", exception);
+                            if(WXEnvironment.isApkDebugable()){
+                                throw  exception;
+                            }
+                        }
+                    }
+                }
+            }
+            dom.setCloneThis(false);
+            if (component != null) {
+                component.mTraceInfo.domThreadNanos = System.nanoTime() - startNanos;
+            }
+            return component;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
index 0aff8a5..2e234ba 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
@@ -79,6 +79,7 @@ import com.taobao.weex.tracing.Stopwatch;
 import com.taobao.weex.tracing.WXTracing;
 import com.taobao.weex.ui.IFComponentHolder;
 import com.taobao.weex.ui.animation.WXAnimationModule;
+import com.taobao.weex.ui.component.binding.Statements;
 import com.taobao.weex.ui.component.pesudo.OnActivePseudoListener;
 import com.taobao.weex.ui.component.pesudo.PesudoStatus;
 import com.taobao.weex.ui.component.pesudo.TouchActivePseudoListener;
@@ -124,7 +125,7 @@ public abstract class  WXComponent<T extends View> implements IWXObject, IWXActi
   public static final String PROP_FS_WRAP_CONTENT = "w";
 
   private int mFixedProp = 0;
-  public static int mComponentNum = 0;
+  public static volatile int mComponentNum = 0;
   /** package **/ T mHost;
 
   private volatile WXVContainer mParent;
@@ -158,6 +159,7 @@ public abstract class  WXComponent<T extends View> implements IWXObject, IWXActi
   private boolean mNeedLayoutOnAnimation = false;
   private String mLastBoxShadowId;
 
+
   public WXTracing.TraceInfo mTraceInfo = new WXTracing.TraceInfo();
 
   public static final int TYPE_COMMON = 0;
@@ -165,6 +167,7 @@ public abstract class  WXComponent<T extends View> implements IWXObject, IWXActi
 
   private boolean waste = false;
 
+
   //Holding the animation bean when component is uninitialized
   public void postAnimation(WXAnimationModule.AnimationHolder holder) {
     this.mAnimationHolder = holder;
@@ -348,6 +351,12 @@ public abstract class  WXComponent<T extends View> implements IWXObject, IWXActi
         if(mDomObj.getEvents() != null && mDomObj.getEvents().getEventBindingArgsValues() != null){
              eventArgsValues = mDomObj.getEvents().getEventBindingArgsValues().get(type);
         }
+        if(params != null){
+          String componentId = Statements.getComponentId(this);
+          if(componentId != null) {
+            params.put("componentId", componentId);
+          }
+        }
         mInstance.fireEvent(mCurrentRef, type, params,domChanges, eventArgsValues, callback);
     }
   }
@@ -371,6 +380,9 @@ public abstract class  WXComponent<T extends View> implements IWXObject, IWXActi
    * @return true for lazy
    */
   public boolean isLazy() {
+    if(mLazy){
+      return true;
+    }
     return mParent != null && mParent.isLazy();
   }
 
@@ -1974,51 +1986,85 @@ public abstract class  WXComponent<T extends View> implements IWXObject, IWXActi
     }
   }
 
+  protected boolean isRippleEnabled() {
+    try {
+      Object obj = getDomObject().getAttrs().get(Constants.Name.RIPPLE_ENABLED);
+      return WXUtils.getBoolean(obj, false);
+    } catch (Throwable t) {
+      //ignore
+    }
+    return false;
+  }
+
+
+
   public boolean isWaste() {
     return waste;
   }
 
+  /**
+   * mark node waste,
+   * if node is waster should hidden, and dom tree should allow not show
+   * */
   public void setWaste(boolean waste) {
     if(this.waste != waste){
       this.waste = waste;
       WXDomObject domObject = (WXDomObject) getDomObject();
       if(waste){
-          getDomObject().getStyles().put(Constants.Name.VISIBILITY, Constants.Value.HIDDEN);
-          if(domObject.getAttrs().getStatement() == null) {
-            domObject.setVisible(false);
-            if (getHostView() != null) {
-                getHostView().setVisibility(View.GONE);
-            }
-            return;
-          }
-          if(Constants.Value.VISIBLE.equals(domObject.getAttrs().get(Constants.Name.VIF_FALSE))){
-            domObject.setVisible(true);
-            if(getHostView() != null){
-               getHostView().setVisibility(View.VISIBLE);
-             }
-          }else{
-            domObject.setVisible(false);
-            if(getHostView() != null){
-              getHostView().setVisibility(View.GONE);
-            }
-          }
+          //update dom not show, and put style to hidden
+         domObject.setVisible(false);
+         domObject.getStyles().put(Constants.Name.VISIBILITY, Constants.Value.HIDDEN);
+         //if component not init, mark lazy init when use, reduce view count
+         if(getHostView() == null){
+           if(!mLazy){
+              lazy(true);
+           }
+         }else{
+           getHostView().setVisibility(View.GONE);
+         }
       }else{
-        domObject.setVisible(true);
-        if(getHostView() != null){
+         domObject.setVisible(true);
+         domObject.getStyles().put(Constants.Name.VISIBILITY, Constants.Value.VISIBLE);
+         if(getHostView() == null){
+             if(mLazy) { // when parent is lazy just mark node lazy false
+               if(mParent != null && mParent.isLazy()){
+                  lazy(false);
+               }else{
+                  ComponentUtils.initLazyComponent(this, mParent);
+               }
+             }
+         }else{
            getHostView().setVisibility(View.VISIBLE);
-        }
-        getDomObject().getStyles().put(Constants.Name.VISIBILITY, Constants.Value.VISIBLE);
+         }
       }
     }
   }
 
-  protected boolean isRippleEnabled() {
-    try {
-      Object obj = getDomObject().getAttrs().get(Constants.Name.RIPPLE_ENABLED);
-      return WXUtils.getBoolean(obj, false);
-    } catch (Throwable t) {
-      //ignore
-    }
-    return false;
+
+  /** component key id in native,
+   *  differ with ref, ref + position
+   *  */
+  public  String getViewTreeKey(){
+     if(mViewTreeKey == null){
+        if(getParent() == null){
+          mViewTreeKey = getRef();
+        }else{
+          mViewTreeKey = getRef() + "_" + getParent().indexOf(this);
+        }
+     }
+     return mViewTreeKey;
+  }
+
+  private String mViewTreeKey;
+
+
+  /**
+   * node is lazy
+   * */
+  private boolean mLazy = false;
+
+  /***/
+  public void lazy(boolean lazy) {
+    mLazy = lazy;
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
index 9dea0ff..3357882 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Layouts.java
@@ -21,14 +21,12 @@ package com.taobao.weex.ui.component.binding;
 
 
 import android.os.AsyncTask;
-import android.util.Log;
 
 import com.taobao.weex.WXEnvironment;
 import com.taobao.weex.WXSDKInstance;
 import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.dom.flex.CSSLayoutContext;
-import com.taobao.weex.dom.flex.CSSNode;
 import com.taobao.weex.ui.component.WXComponent;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.ui.component.list.template.TemplateViewHolder;
@@ -87,10 +85,14 @@ public class Layouts {
         try{
             long start = System.currentTimeMillis();
             doLayout(component, layoutContext);
-            if(WXEnvironment.isApkDebugable()){
+            if(WXEnvironment.isOpenDebugLog() && WXRecyclerTemplateList.ENABLE_TRACE_LOG) {
                 WXLogUtils.d(WXRecyclerTemplateList.TAG, "WXTemplateList doSafeLayout" +
-                        component.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_TYPE) + Thread.currentThread().getName() +  " doSafeLayout  used " +
-                                (System.currentTimeMillis() - start));
+                        component.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_CASE) + Thread.currentThread().getName() + " doSafeLayout  used " +
+                        (System.currentTimeMillis() - start));
+            }
+            if(!(component.getLayoutHeight() > 0)){
+                WXLogUtils.e(WXRecyclerTemplateList.TAG, " WXTemplateList doSafeLayout wrong template " +
+                        component.getDomObject().getAttrs().get(Constants.Name.Recycler.SLOT_TEMPLATE_CASE)  + " cell height " + component.getLayoutHeight());
             }
         }catch (Exception e){
             if(WXEnvironment.isApkDebugable()){
@@ -102,7 +104,7 @@ public class Layouts {
     private static void doLayout(WXComponent component, final  CSSLayoutContext layoutContext){
         WXDomObject domObject = (WXDomObject) component.getDomObject();
         final WXSDKInstance instance = component.getInstance();
-        domObject.traverseTree(new WXDomObject.Consumer() {
+        domObject.traverseUpdateTree(new WXDomObject.Consumer() {
             @Override
             public void accept(WXDomObject dom) {
                 if(instance == null || instance.isDestroy()){
@@ -111,18 +113,24 @@ public class Layouts {
                 if(!dom.hasUpdate()){
                     return;
                 }
+                if(!dom.isShow()){ //not show just skip
+                   return;
+                }
                 dom.layoutBefore();
             }
         });
         if(instance != null && !instance.isDestroy()){
             domObject.calculateLayout(layoutContext);
         }
-        domObject.traverseTree( new WXDomObject.Consumer() {
+        domObject.traverseUpdateTree( new WXDomObject.Consumer() {
             @Override
             public void accept(WXDomObject dom) {
                 if(instance == null || instance.isDestroy()){
                     return;
                 }
+                if(!dom.isShow()){
+                    return;
+                }
                 if (dom.hasUpdate()) {
                     dom.layoutAfter();
                 }
@@ -140,7 +148,6 @@ public class Layouts {
      * */
     public static final void setLayout(WXComponent component, boolean force){
         if(component.isWaste()){
-            setLayoutWaste(component, force);
             return;
         }
         WXDomObject domObject = (WXDomObject) component.getDomObject();


[5/7] incubator-weex git commit: Merge remote-tracking branch 'origin/master_apache' into release-0.17-template-list-second

Posted by mi...@apache.org.
Merge remote-tracking branch 'origin/master_apache' into release-0.17-template-list-second

# Conflicts:
#	android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/30ad3f6c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/30ad3f6c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/30ad3f6c

Branch: refs/heads/master
Commit: 30ad3f6c0c13c635c0acdeb40a80f3064330248a
Parents: 886d859 e36379a
Author: jianbai.gbj <ji...@alibaba-inc.com>
Authored: Thu Feb 8 12:01:44 2018 +0800
Committer: jianbai.gbj <ji...@alibaba-inc.com>
Committed: Thu Feb 8 12:01:44 2018 +0800

----------------------------------------------------------------------
 .gitignore                                      |   7 -
 android/sdk/libs/x86/libweexjsb.so              | Bin 0 -> 3212 bytes
 android/sdk/libs/x86/libweexjsc.so              | Bin 12126020 -> 649940 bytes
 android/sdk/libs/x86/libweexjss.so              | Bin 0 -> 10942128 bytes
 .../main/java/com/taobao/weex/WXSDKEngine.java  |   1 +
 .../java/com/taobao/weex/WXSDKInstance.java     |   4 +-
 .../taobao/weex/bridge/WXServiceManager.java    |  25 +-
 .../java/com/taobao/weex/dom/WXDomObject.java   |   7 +
 .../com/taobao/weex/dom/WXTextDomObject.java    |  67 ++
 .../weex/dom/action/UpdateAttributeAction.java  |   2 +-
 .../taobao/weex/ui/component/WXComponent.java   |   6 +-
 .../com/taobao/weex/ui/component/WXText.java    |  51 -
 .../ui/component/list/BasicListComponent.java   |   5 +
 .../taobao/weex/ui/view/gesture/WXGesture.java  |  14 +-
 .../com/taobao/weex/utils/ImageDrawable.java    |  13 +
 .../com/taobao/weex/utils/TypefaceUtil.java     |   2 +-
 build/build.js                                  |   6 +-
 build/config.js                                 |  37 +-
 dangerfile-android.js                           |   3 -
 dangerfile-ios.js                               |   3 -
 dangerfile-jsfm.js                              |   7 +-
 dangerfile.js                                   |  11 -
 doc/_config.yml                                 | 339 -------
 doc/_config_cn.yml                              | 337 -------
 doc/advanced/extend-to-android.md               | 175 ----
 doc/package.json                                |  28 -
 doc/scaffolds/draft.md                          |   4 -
 doc/scaffolds/page.md                           |   4 -
 doc/scaffolds/post.md                           |   5 -
 doc/source/_posts/arkit.md                      | 112 ---
 doc/source/_posts/coreml.md                     |  79 --
 doc/source/blog/index.md                        |   4 -
 doc/source/cn/download.ejs                      |   3 -
 doc/source/cn/faq.md                            | 223 -----
 doc/source/cn/guide/.gitkeep                    |   0
 doc/source/cn/guide/contributing.md             | 107 ---
 doc/source/cn/guide/images/flow.png             | Bin 57741 -> 0 bytes
 doc/source/cn/guide/images/tut-cli-qrcode.png   | Bin 45480 -> 0 bytes
 doc/source/cn/guide/images/tut-first.png        | Bin 51434 -> 0 bytes
 doc/source/cn/guide/images/tut-second.png       | Bin 78519 -> 0 bytes
 doc/source/cn/guide/images/tut1.jpg             | Bin 47442 -> 0 bytes
 doc/source/cn/guide/images/tut2.jpg             | Bin 52428 -> 0 bytes
 doc/source/cn/guide/images/tut3.png             | Bin 52198 -> 0 bytes
 doc/source/cn/guide/images/tut4.gif             | Bin 218245 -> 0 bytes
 doc/source/cn/guide/index.md                    |  59 --
 doc/source/cn/guide/integrate-to-your-app.md    | 323 -------
 doc/source/cn/guide/intro/app-architecture.md   |  61 --
 doc/source/cn/guide/intro/how-it-works.md       |  62 --
 doc/source/cn/guide/intro/index.md              |  15 -
 doc/source/cn/guide/intro/page-architecture.md  |  48 -
 doc/source/cn/guide/intro/using-vue.md          |  62 --
 doc/source/cn/guide/intro/web-dev-experience.md |  38 -
 doc/source/cn/guide/intro/write-once.md         |  25 -
 doc/source/cn/guide/set-up-env.md               | 132 ---
 doc/source/cn/guide/tools/index.md              |  11 -
 doc/source/cn/guide/tools/plugin.md             |  77 --
 doc/source/cn/guide/tools/toolkit.md            | 231 -----
 doc/source/cn/index.md                          |   4 -
 doc/source/cn/playground.ejs                    |   3 -
 .../cn/references/advanced/extend-jsfm.md       | 172 ----
 .../cn/references/advanced/extend-to-android.md | 218 -----
 .../cn/references/advanced/extend-to-html5.md   | 103 ---
 .../cn/references/advanced/extend-to-ios.md     | 325 -------
 doc/source/cn/references/advanced/index.md      |  15 -
 .../advanced/integrate-devtool-to-android.md    | 353 -------
 .../advanced/integrate-devtool-to-ios.md        | 229 -----
 doc/source/cn/references/android-apis.md        | 221 -----
 doc/source/cn/references/bubble.md              | 146 ---
 doc/source/cn/references/color-names.md         | 180 ----
 doc/source/cn/references/common-event.md        | 138 ---
 doc/source/cn/references/common-style.md        | 627 -------------
 doc/source/cn/references/components/a.md        |  85 --
 doc/source/cn/references/components/cell.md     | 108 ---
 doc/source/cn/references/components/div.md      | 116 ---
 doc/source/cn/references/components/image.md    | 185 ----
 doc/source/cn/references/components/index.md    |  24 -
 .../cn/references/components/indicator.md       | 136 ---
 doc/source/cn/references/components/input.md    | 344 -------
 doc/source/cn/references/components/list.md     | 172 ----
 doc/source/cn/references/components/loading.md  | 127 ---
 doc/source/cn/references/components/refresh.md  | 132 ---
 doc/source/cn/references/components/scroller.md | 199 ----
 doc/source/cn/references/components/slider.md   | 112 ---
 doc/source/cn/references/components/switch.md   | 133 ---
 doc/source/cn/references/components/text.md     | 136 ---
 doc/source/cn/references/components/textarea.md | 162 ----
 doc/source/cn/references/components/video.md    |  94 --
 .../cn/references/components/waterfall.md       |  64 --
 doc/source/cn/references/components/web.md      | 155 ----
 doc/source/cn/references/downgrade.md           |  11 -
 doc/source/cn/references/gesture.md             |  60 --
 doc/source/cn/references/html5-apis.md          |  10 -
 doc/source/cn/references/images/Artboard.jpg    | Bin 36223 -> 0 bytes
 .../cn/references/images/coding_weex_1.jpg      | Bin 56225 -> 0 bytes
 .../cn/references/images/css-boxmodel.png       | Bin 12581 -> 0 bytes
 .../cn/references/images/css-flexbox-align.jpg  | Bin 35005 -> 0 bytes
 .../references/images/css-flexbox-justify.svg   |  59 --
 .../cn/references/images/css-flexbox-sample.png | Bin 3210 -> 0 bytes
 doc/source/cn/references/images/div_1.jpg       | Bin 59561 -> 0 bytes
 doc/source/cn/references/images/div_2.jpg       | Bin 62574 -> 0 bytes
 doc/source/cn/references/images/div_3.jpg       | Bin 82345 -> 0 bytes
 doc/source/cn/references/images/div_4.jpg       | Bin 200642 -> 0 bytes
 doc/source/cn/references/images/image_1.jpg     | Bin 163705 -> 0 bytes
 doc/source/cn/references/images/image_2.jpg     | Bin 255560 -> 0 bytes
 doc/source/cn/references/images/list_2.jpg      | Bin 56635 -> 0 bytes
 doc/source/cn/references/images/list_3.jpg      | Bin 128082 -> 0 bytes
 doc/source/cn/references/images/list_4.jpg      | Bin 339799 -> 0 bytes
 doc/source/cn/references/images/nav.jpg         | Bin 124441 -> 0 bytes
 doc/source/cn/references/images/nav.png         | Bin 83497 -> 0 bytes
 doc/source/cn/references/images/scroller_1.jpg  | Bin 344783 -> 0 bytes
 doc/source/cn/references/images/style_1.jpg     | Bin 59366 -> 0 bytes
 doc/source/cn/references/images/style_2.jpg     | Bin 59696 -> 0 bytes
 doc/source/cn/references/index.md               |  19 -
 doc/source/cn/references/ios-apis.md            |  91 --
 doc/source/cn/references/js-service/index.md    | 118 ---
 doc/source/cn/references/jsfm-apis.md           |  66 --
 .../cn/references/migration/difference.md       | 249 -----
 doc/source/cn/references/migration/index.md     |  11 -
 .../references/migration/migration-from-weex.md | 116 ---
 doc/source/cn/references/modules/animation.md   | 100 --
 doc/source/cn/references/modules/clipboard.md   | 101 --
 doc/source/cn/references/modules/dom.md         | 281 ------
 doc/source/cn/references/modules/globalevent.md |  88 --
 doc/source/cn/references/modules/index.md       |  21 -
 doc/source/cn/references/modules/meta.md        |  96 --
 doc/source/cn/references/modules/modal.md       | 141 ---
 doc/source/cn/references/modules/navigator.md   |  90 --
 doc/source/cn/references/modules/picker.md      | 129 ---
 doc/source/cn/references/modules/storage.md     | 184 ----
 doc/source/cn/references/modules/stream.md      | 124 ---
 doc/source/cn/references/modules/timer.md       |  47 -
 doc/source/cn/references/modules/websocket.md   | 219 -----
 doc/source/cn/references/modules/webview.md     | 138 ---
 doc/source/cn/references/native-dom-api.md      | 223 -----
 doc/source/cn/references/path.md                |  43 -
 doc/source/cn/references/platform-difference.md |  70 --
 doc/source/cn/references/text-style.md          |  46 -
 doc/source/cn/references/unit.md                |  64 --
 .../cn/references/vue/difference-of-vuex.md     |  87 --
 .../cn/references/vue/difference-with-web.md    | 137 ---
 doc/source/cn/references/vue/index.md           |  12 -
 doc/source/cn/references/web-standards.md       | 584 ------------
 doc/source/cn/references/weex-variable.md       |  96 --
 doc/source/cn/releasenote.md                    | 353 -------
 .../cn/v-0.10/advanced/create-a-weex-project.md | 271 ------
 .../advanced/customize-a-native-component.md    | 168 ----
 .../cn/v-0.10/advanced/cuszomize-native-apis.md |  85 --
 .../cn/v-0.10/advanced/extend-to-android.md     | 170 ----
 .../cn/v-0.10/advanced/extend-to-html5.md       | 253 -----
 doc/source/cn/v-0.10/advanced/extend-to-ios.md  | 279 ------
 .../v-0.10/advanced/how-data-binding-works.md   |  39 -
 .../cn/v-0.10/advanced/images/how-arch.png      | Bin 62303 -> 0 bytes
 .../cn/v-0.10/advanced/images/how-render.png    | Bin 42957 -> 0 bytes
 doc/source/cn/v-0.10/advanced/index.md          | 146 ---
 .../advanced/integrate-devtools-to-android.md   | 272 ------
 .../advanced/integrate-devtools-to-ios.md       | 230 -----
 .../cn/v-0.10/advanced/integrate-to-android.md  | 201 ----
 .../cn/v-0.10/advanced/integrate-to-html5.md    |  69 --
 .../cn/v-0.10/advanced/integrate-to-ios.md      | 110 ---
 doc/source/cn/v-0.10/blog/index.md              |   4 -
 .../guide/develop-on-your-local-machine.md      | 175 ----
 .../cn/v-0.10/guide/how-to/debug-with-html5.md  |  47 -
 doc/source/cn/v-0.10/guide/how-to/index.md      | 185 ----
 .../guide/how-to/require-3rd-party-libs.md      |  57 --
 .../how-to/transform-code-into-js-bundle.md     | 112 ---
 doc/source/cn/v-0.10/guide/index.md             |  60 --
 doc/source/cn/v-0.10/guide/syntax/comm.md       | 134 ---
 .../v-0.10/guide/syntax/composed-component.md   | 158 ----
 .../cn/v-0.10/guide/syntax/config-n-data.md     |  72 --
 .../cn/v-0.10/guide/syntax/data-binding.md      | 332 -------
 .../cn/v-0.10/guide/syntax/display-logic.md     | 252 -----
 doc/source/cn/v-0.10/guide/syntax/events.md     | 103 ---
 doc/source/cn/v-0.10/guide/syntax/id.md         | 124 ---
 doc/source/cn/v-0.10/guide/syntax/index.md      | 134 ---
 .../cn/v-0.10/guide/syntax/render-logic.md      |  44 -
 .../cn/v-0.10/guide/syntax/style-n-class.md     | 117 ---
 doc/source/cn/v-0.10/index.md                   |   5 -
 doc/source/cn/v-0.10/references/api.md          |  67 --
 doc/source/cn/v-0.10/references/bubble.md       | 150 ---
 doc/source/cn/v-0.10/references/cheatsheet.md   | 114 ---
 doc/source/cn/v-0.10/references/color-names.md  | 180 ----
 doc/source/cn/v-0.10/references/common-attrs.md | 166 ----
 doc/source/cn/v-0.10/references/common-event.md | 492 ----------
 doc/source/cn/v-0.10/references/common-style.md | 322 -------
 .../cn/v-0.10/references/component-defs.md      | 126 ---
 doc/source/cn/v-0.10/references/components/a.md | 273 ------
 .../cn/v-0.10/references/components/cell.md     | 191 ----
 .../cn/v-0.10/references/components/div.md      | 245 -----
 .../cn/v-0.10/references/components/image.md    | 161 ----
 .../cn/v-0.10/references/components/index.md    |  24 -
 .../v-0.10/references/components/indicator.md   | 124 ---
 .../cn/v-0.10/references/components/input.md    | 309 -------
 .../cn/v-0.10/references/components/list.md     | 375 --------
 .../cn/v-0.10/references/components/loading.md  | 118 ---
 .../cn/v-0.10/references/components/refresh.md  | 204 ----
 .../cn/v-0.10/references/components/scroller.md | 324 -------
 .../cn/v-0.10/references/components/slider.md   | 121 ---
 .../cn/v-0.10/references/components/switch.md   |  98 --
 .../cn/v-0.10/references/components/text.md     | 116 ---
 .../cn/v-0.10/references/components/textarea.md | 115 ---
 .../cn/v-0.10/references/components/video.md    |  82 --
 .../cn/v-0.10/references/components/web.md      | 143 ---
 doc/source/cn/v-0.10/references/gesture.md      |  79 --
 .../cn/v-0.10/references/images/Artboard.jpg    | Bin 36223 -> 0 bytes
 .../v-0.10/references/images/coding_weex_1.jpg  | Bin 56225 -> 0 bytes
 .../v-0.10/references/images/css-boxmodel.png   | Bin 12581 -> 0 bytes
 .../references/images/css-flexbox-align.jpg     | Bin 35005 -> 0 bytes
 .../references/images/css-flexbox-justify.svg   |  59 --
 .../cn/v-0.10/references/images/div_1.jpg       | Bin 59561 -> 0 bytes
 .../cn/v-0.10/references/images/div_2.jpg       | Bin 62574 -> 0 bytes
 .../cn/v-0.10/references/images/div_3.jpg       | Bin 82345 -> 0 bytes
 .../cn/v-0.10/references/images/div_4.jpg       | Bin 200642 -> 0 bytes
 .../cn/v-0.10/references/images/image_1.jpg     | Bin 163705 -> 0 bytes
 .../cn/v-0.10/references/images/image_2.jpg     | Bin 255560 -> 0 bytes
 .../cn/v-0.10/references/images/list_2.jpg      | Bin 56635 -> 0 bytes
 .../cn/v-0.10/references/images/list_3.jpg      | Bin 128082 -> 0 bytes
 .../cn/v-0.10/references/images/list_4.jpg      | Bin 339799 -> 0 bytes
 doc/source/cn/v-0.10/references/images/nav.jpg  | Bin 124441 -> 0 bytes
 .../cn/v-0.10/references/images/scroller_1.jpg  | Bin 344783 -> 0 bytes
 .../cn/v-0.10/references/images/style_1.jpg     | Bin 59366 -> 0 bytes
 .../cn/v-0.10/references/images/style_2.jpg     | Bin 59696 -> 0 bytes
 doc/source/cn/v-0.10/references/index.md        |  46 -
 .../cn/v-0.10/references/modules/animation.md   |  90 --
 .../cn/v-0.10/references/modules/clipboard.md   | 112 ---
 doc/source/cn/v-0.10/references/modules/dom.md  |  79 --
 .../cn/v-0.10/references/modules/globalevent.md |  87 --
 .../cn/v-0.10/references/modules/index.md       |  20 -
 .../cn/v-0.10/references/modules/modal.md       | 196 ----
 .../cn/v-0.10/references/modules/navigator.md   | 110 ---
 .../cn/v-0.10/references/modules/storage.md     | 224 -----
 .../cn/v-0.10/references/modules/stream.md      | 220 -----
 .../cn/v-0.10/references/modules/webview.md     |  66 --
 doc/source/cn/v-0.10/references/replace.md      |  57 --
 .../cn/v-0.10/references/special-element.md     |  38 -
 doc/source/cn/v-0.10/references/specs/index.md  | 309 -------
 .../references/specs/js-framework-apis.md       | 190 ----
 .../v-0.10/references/specs/virtual-dom-apis.md | 148 ---
 doc/source/cn/v-0.10/references/text-style.md   |  40 -
 doc/source/cn/v-0.10/references/units.md        |  66 --
 doc/source/cn/v-0.10/references/wxc/index.md    |  44 -
 .../cn/v-0.10/references/wxc/wxc-navpage.md     | 192 ----
 .../cn/v-0.10/references/wxc/wxc-tabbar.md      | 176 ----
 doc/source/cn/v-0.10/tools/devtools-android.md  | 123 ---
 doc/source/cn/v-0.10/tools/devtools-ios.md      |  65 --
 doc/source/cn/v-0.10/tools/devtools.md          |  99 --
 doc/source/cn/v-0.10/tools/index.md             |  96 --
 doc/source/cn/v-0.10/tools/playground.md        |  22 -
 doc/source/cn/v-0.10/tools/transformer.md       |  38 -
 doc/source/download.ejs                         |   3 -
 doc/source/examples/a.md                        |  39 -
 doc/source/examples/animation.md                |  47 -
 doc/source/examples/clipboard.md                |  64 --
 doc/source/examples/div.md                      |  27 -
 doc/source/examples/dom-rect.md                 | 118 ---
 doc/source/examples/dom-scroll.md               |  93 --
 doc/source/examples/image.md                    |  58 --
 doc/source/examples/indicator.md                |  80 --
 doc/source/examples/input.md                    |  68 --
 doc/source/examples/list.md                     |  64 --
 doc/source/examples/modal.md                    |  81 --
 doc/source/examples/navigator.md                |  54 --
 doc/source/examples/refresh.md                  |  74 --
 doc/source/examples/scroller.md                 |  92 --
 doc/source/examples/slider.md                   |  53 --
 doc/source/examples/storage.md                  | 103 ---
 doc/source/examples/stream.md                   |  74 --
 doc/source/examples/switch.md                   |  69 --
 doc/source/examples/text.md                     |  44 -
 doc/source/examples/textarea.md                 |  68 --
 doc/source/examples/video.md                    |  55 --
 doc/source/examples/web.md                      |  97 --
 doc/source/faq.md                               | 207 -----
 doc/source/guide/.gitkeep                       |   0
 doc/source/guide/contributing.md                | 106 ---
 doc/source/guide/images/flow.png                | Bin 57741 -> 0 bytes
 doc/source/guide/images/tut-cli-qrcode.png      | Bin 45480 -> 0 bytes
 doc/source/guide/images/tut-first.png           | Bin 51434 -> 0 bytes
 doc/source/guide/images/tut-second.png          | Bin 78519 -> 0 bytes
 doc/source/guide/images/tut1.jpg                | Bin 47442 -> 0 bytes
 doc/source/guide/images/tut2.jpg                | Bin 52428 -> 0 bytes
 doc/source/guide/images/tut3.png                | Bin 52198 -> 0 bytes
 doc/source/guide/images/tut4.gif                | Bin 218245 -> 0 bytes
 doc/source/guide/index.md                       |  66 --
 doc/source/guide/integrate-to-your-app.md       | 281 ------
 doc/source/guide/intro/app-architecture.md      |  61 --
 doc/source/guide/intro/how-it-works.md          |  72 --
 doc/source/guide/intro/index.md                 |  17 -
 doc/source/guide/intro/page-architecture.md     |  48 -
 doc/source/guide/intro/using-vue.md             |  58 --
 doc/source/guide/intro/web-dev-experience.md    |  36 -
 doc/source/guide/intro/write-once.md            |  23 -
 doc/source/guide/set-up-env.md                  |  99 --
 doc/source/guide/tools/index.md                 |  11 -
 doc/source/guide/tools/plugin.md                |  68 --
 doc/source/guide/tools/toolkit.md               | 197 ----
 doc/source/index.md                             |   4 -
 doc/source/playground.ejs                       |   3 -
 doc/source/references/advanced/extend-jsfm.md   | 167 ----
 .../references/advanced/extend-to-android.md    | 219 -----
 .../references/advanced/extend-to-html5.md      |  96 --
 doc/source/references/advanced/extend-to-ios.md | 341 -------
 doc/source/references/advanced/index.md         |  15 -
 .../advanced/integrate-devtool-to-android.md    | 146 ---
 .../advanced/integrate-devtool-to-ios.md        | 192 ----
 doc/source/references/android-apis.md           | 219 -----
 doc/source/references/bubble.md                 | 146 ---
 doc/source/references/color-names.md            | 182 ----
 doc/source/references/common-event.md           | 129 ---
 doc/source/references/common-style.md           | 522 -----------
 doc/source/references/components/a.md           |  71 --
 doc/source/references/components/cell.md        |  44 -
 doc/source/references/components/div.md         |  64 --
 doc/source/references/components/image.md       | 126 ---
 doc/source/references/components/index.md       |  24 -
 doc/source/references/components/indicator.md   | 121 ---
 doc/source/references/components/input.md       | 322 -------
 doc/source/references/components/list.md        | 175 ----
 doc/source/references/components/refresh.md     | 221 -----
 doc/source/references/components/scroller.md    | 163 ----
 doc/source/references/components/slider.md      |  93 --
 doc/source/references/components/switch.md      | 115 ---
 doc/source/references/components/text.md        | 131 ---
 doc/source/references/components/textarea.md    | 140 ---
 doc/source/references/components/video.md       |  87 --
 doc/source/references/components/waterfall.md   |  55 --
 doc/source/references/components/web.md         | 148 ---
 doc/source/references/downgrade.md              |  11 -
 doc/source/references/gesture.md                |  56 --
 doc/source/references/html5-apis.md             |  10 -
 doc/source/references/images/css-boxmodel.png   | Bin 12581 -> 0 bytes
 .../references/images/css-flexbox-align.jpg     | Bin 35005 -> 0 bytes
 .../references/images/css-flexbox-justify.svg   |  59 --
 .../references/images/css-flexbox-sample.png    | Bin 3210 -> 0 bytes
 doc/source/references/images/nav.png            | Bin 83497 -> 0 bytes
 doc/source/references/index.md                  |  19 -
 doc/source/references/ios-apis.md               |  76 --
 doc/source/references/js-service/index.md       | 114 ---
 doc/source/references/jsfm-apis.md              |  66 --
 doc/source/references/migration/difference.md   |  10 -
 doc/source/references/migration/index.md        |  11 -
 .../references/migration/migration-from-weex.md |  10 -
 doc/source/references/modules/animation.md      | 107 ---
 doc/source/references/modules/clipboard.md      |  98 --
 doc/source/references/modules/dom.md            | 276 ------
 doc/source/references/modules/globalevent.md    |  89 --
 doc/source/references/modules/index.md          |  20 -
 doc/source/references/modules/meta.md           |  97 --
 doc/source/references/modules/modal.md          | 146 ---
 doc/source/references/modules/navigator.md      |  89 --
 doc/source/references/modules/picker.md         | 129 ---
 doc/source/references/modules/storage.md        | 172 ----
 doc/source/references/modules/stream.md         | 131 ---
 doc/source/references/modules/timer.md          |  58 --
 doc/source/references/modules/websocket.md      | 218 -----
 doc/source/references/modules/webview.md        | 156 ----
 doc/source/references/native-dom-api.md         | 212 -----
 doc/source/references/path.md                   |  37 -
 doc/source/references/platform-difference.md    |  11 -
 doc/source/references/text-style.md             |  50 -
 doc/source/references/unit.md                   |  11 -
 doc/source/references/vue/difference-of-vuex.md |  89 --
 .../references/vue/difference-with-web.md       | 149 ---
 doc/source/references/vue/index.md              |  11 -
 doc/source/references/web-standards.md          | 584 ------------
 doc/source/references/weex-variable.md          |  96 --
 doc/source/releasenote.md                       | 354 -------
 doc/source/v-0.10/advanced/extend-to-android.md | 189 ----
 doc/source/v-0.10/advanced/extend-to-html5.md   | 258 ------
 doc/source/v-0.10/advanced/extend-to-ios.md     | 311 -------
 .../v-0.10/advanced/how-data-binding-works.md   |  39 -
 doc/source/v-0.10/advanced/images/how-arch.png  | Bin 62303 -> 0 bytes
 .../v-0.10/advanced/images/how-render.png       | Bin 42957 -> 0 bytes
 doc/source/v-0.10/advanced/index.md             | 148 ---
 .../v-0.10/advanced/integrate-to-android.md     | 204 ----
 .../v-0.10/advanced/integrate-to-html5.md       |  77 --
 doc/source/v-0.10/advanced/integrate-to-ios.md  | 118 ---
 doc/source/v-0.10/guide/.gitkeep                |   0
 .../how-to/customize-a-native-component.md      |  58 --
 .../guide/how-to/cuszomize-native-apis.md       |  80 --
 .../v-0.10/guide/how-to/debug-with-html5.md     |  47 -
 doc/source/v-0.10/guide/how-to/index.md         |  40 -
 .../guide/how-to/preview-in-playground-app.md   |  20 -
 .../guide/how-to/require-3rd-party-libs.md      |  56 --
 .../how-to/transform-code-into-js-bundle.md     | 110 ---
 .../v-0.10/guide/images/tut-cli-qrcode.png      | Bin 45480 -> 0 bytes
 doc/source/v-0.10/guide/images/tut-first.png    | Bin 51434 -> 0 bytes
 doc/source/v-0.10/guide/images/tut-second.png   | Bin 78519 -> 0 bytes
 doc/source/v-0.10/guide/images/tut1.jpg         | Bin 47442 -> 0 bytes
 doc/source/v-0.10/guide/images/tut2.jpg         | Bin 52428 -> 0 bytes
 doc/source/v-0.10/guide/images/tut3.png         | Bin 52198 -> 0 bytes
 doc/source/v-0.10/guide/images/tut4.gif         | Bin 218245 -> 0 bytes
 doc/source/v-0.10/guide/index.md                | 211 -----
 doc/source/v-0.10/guide/syntax/comm.md          | 228 -----
 .../v-0.10/guide/syntax/composed-component.md   | 114 ---
 doc/source/v-0.10/guide/syntax/config-n-data.md |  61 --
 doc/source/v-0.10/guide/syntax/data-binding.md  | 248 -----
 doc/source/v-0.10/guide/syntax/display-logic.md | 173 ----
 doc/source/v-0.10/guide/syntax/events.md        |  59 --
 doc/source/v-0.10/guide/syntax/id.md            |  65 --
 doc/source/v-0.10/guide/syntax/index.md         | 122 ---
 doc/source/v-0.10/guide/syntax/render-logic.md  |  35 -
 doc/source/v-0.10/guide/syntax/style-n-class.md | 118 ---
 doc/source/v-0.10/references/api.md             |  84 --
 doc/source/v-0.10/references/bubble.md          | 150 ---
 doc/source/v-0.10/references/cheatsheet.md      | 102 --
 doc/source/v-0.10/references/color-names.md     | 182 ----
 doc/source/v-0.10/references/common-attrs.md    |  78 --
 doc/source/v-0.10/references/common-event.md    | 120 ---
 doc/source/v-0.10/references/common-style.md    | 208 -----
 doc/source/v-0.10/references/component-defs.md  | 131 ---
 doc/source/v-0.10/references/components/a.md    |  50 -
 doc/source/v-0.10/references/components/cell.md |  42 -
 doc/source/v-0.10/references/components/div.md  |  48 -
 .../v-0.10/references/components/image.md       |  55 --
 .../v-0.10/references/components/index.md       |  24 -
 .../v-0.10/references/components/indicator.md   |  98 --
 .../v-0.10/references/components/input.md       | 124 ---
 doc/source/v-0.10/references/components/list.md | 292 ------
 .../references/components/refresh-loading.md    | 297 ------
 .../v-0.10/references/components/scroller.md    | 136 ---
 .../v-0.10/references/components/slider.md      | 107 ---
 .../v-0.10/references/components/switch.md      |  81 --
 doc/source/v-0.10/references/components/text.md |  94 --
 .../v-0.10/references/components/textarea.md    |  81 --
 .../v-0.10/references/components/video.md       |  75 --
 doc/source/v-0.10/references/components/web.md  | 152 ---
 .../v-0.10/references/components/wxc-navpage.md |  74 --
 .../v-0.10/references/components/wxc-tabbar.md  |  94 --
 doc/source/v-0.10/references/gesture.md         |  74 --
 .../v-0.10/references/images/css-boxmodel.png   | Bin 12581 -> 0 bytes
 .../references/images/css-flexbox-align.jpg     | Bin 35005 -> 0 bytes
 .../references/images/css-flexbox-justify.svg   |  59 --
 .../references/images/css-flexbox-sample.png    | Bin 3210 -> 0 bytes
 doc/source/v-0.10/references/images/nav.png     | Bin 83497 -> 0 bytes
 doc/source/v-0.10/references/index.md           |  49 -
 .../v-0.10/references/modules/animation.md      |  63 --
 .../v-0.10/references/modules/clipboard.md      |  53 --
 doc/source/v-0.10/references/modules/dom.md     | 114 ---
 .../v-0.10/references/modules/globalevent.md    |  89 --
 doc/source/v-0.10/references/modules/index.md   |  28 -
 doc/source/v-0.10/references/modules/modal.md   | 192 ----
 .../v-0.10/references/modules/navigator.md      | 198 ----
 doc/source/v-0.10/references/modules/storage.md | 111 ---
 doc/source/v-0.10/references/modules/stream.md  |  86 --
 doc/source/v-0.10/references/modules/timer.md   |  60 --
 doc/source/v-0.10/references/modules/webview.md | 160 ----
 doc/source/v-0.10/references/special-element.md |  36 -
 doc/source/v-0.10/references/specs/index.md     | 309 -------
 .../v-0.10/references/specs/js-bundle-format.md | 307 ------
 .../references/specs/js-framework-apis.md       | 191 ----
 .../v-0.10/references/specs/virtual-dom-apis.md | 147 ---
 doc/source/v-0.10/references/text-style.md      |  43 -
 doc/source/v-0.10/tools/devtools-android.md     | 123 ---
 doc/source/v-0.10/tools/devtools-ios.md         |  76 --
 doc/source/v-0.10/tools/devtools.md             | 102 --
 doc/source/v-0.10/tools/index.md                |  97 --
 doc/source/v-0.10/tools/playground.md           |  24 -
 doc/source/v-0.10/tools/transformer.md          |  38 -
 doc/themes/weex/_config.yml                     |  42 -
 doc/themes/weex/languages/cn.yml                | 117 ---
 doc/themes/weex/languages/en.yml                | 117 ---
 .../weex/layout/_partial/after-footer.ejs       |  13 -
 .../weex/layout/_partial/archive-post.ejs       |  11 -
 doc/themes/weex/layout/_partial/archive.ejs     |  19 -
 doc/themes/weex/layout/_partial/article.ejs     |  13 -
 doc/themes/weex/layout/_partial/footer.ejs      |  30 -
 doc/themes/weex/layout/_partial/head.ejs        |  39 -
 doc/themes/weex/layout/_partial/header.ejs      |  77 --
 .../weex/layout/_partial/post/category.ejs      |  10 -
 doc/themes/weex/layout/_partial/post/nav.ejs    |   8 -
 .../weex/layout/_partial/post/summary.ejs       |  55 --
 doc/themes/weex/layout/_partial/post/title.ejs  |  18 -
 doc/themes/weex/layout/_partial/search-form.ejs |   8 -
 doc/themes/weex/layout/_partial/sidebar.ejs     |  58 --
 doc/themes/weex/layout/_partial/slider.ejs      |  17 -
 doc/themes/weex/layout/archive.ejs              |   3 -
 doc/themes/weex/layout/blog.ejs                 |   3 -
 doc/themes/weex/layout/category.ejs             |   1 -
 doc/themes/weex/layout/download.ejs             |  20 -
 doc/themes/weex/layout/example.ejs              |  40 -
 doc/themes/weex/layout/index.ejs                | 269 ------
 doc/themes/weex/layout/layout.ejs               |  30 -
 doc/themes/weex/layout/page.ejs                 |   7 -
 doc/themes/weex/layout/playground.ejs           |  30 -
 doc/themes/weex/layout/post.ejs                 |   3 -
 doc/themes/weex/layout/tag.ejs                  |   1 -
 doc/themes/weex/scripts/helper.js               |  56 --
 doc/themes/weex/source/css/animation.scss       | 250 -----
 doc/themes/weex/source/css/atom-one-dark.scss   |  96 --
 doc/themes/weex/source/css/blog.scss            |  39 -
 doc/themes/weex/source/css/common.scss          | 256 -----
 doc/themes/weex/source/css/docsearch.min.css    |   2 -
 doc/themes/weex/source/css/example.scss         | 103 ---
 doc/themes/weex/source/css/index.scss           | 581 ------------
 doc/themes/weex/source/css/media-queries.scss   | 194 ----
 .../weex/source/css/partial/article-title.scss  |  28 -
 doc/themes/weex/source/css/partial/article.scss |  72 --
 doc/themes/weex/source/css/partial/footer.scss  |  74 --
 doc/themes/weex/source/css/partial/header.scss  | 128 ---
 .../weex/source/css/partial/highlight.scss      | 109 ---
 .../weex/source/css/partial/search-form.scss    | 113 ---
 doc/themes/weex/source/css/partial/sidebar.scss |  75 --
 doc/themes/weex/source/css/partial/summary.scss |  54 --
 doc/themes/weex/source/css/playground.scss      |  50 -
 doc/themes/weex/source/css/post.scss            |  95 --
 doc/themes/weex/source/css/style.scss           |  28 -
 doc/themes/weex/source/css/swiper.min.css       |  15 -
 doc/themes/weex/source/css/variable.scss        |  40 -
 doc/themes/weex/source/images/_slide1.png       | Bin 381001 -> 0 bytes
 .../weex/source/images/ali-open-source.png      | Bin 2193 -> 0 bytes
 doc/themes/weex/source/images/alibaba.png       | Bin 2107 -> 0 bytes
 doc/themes/weex/source/images/aliyun.png        | Bin 1292 -> 0 bytes
 doc/themes/weex/source/images/android.png       | Bin 5973 -> 0 bytes
 doc/themes/weex/source/images/avatar.png        | Bin 32736 -> 0 bytes
 doc/themes/weex/source/images/cainiao.png       | Bin 3353 -> 0 bytes
 doc/themes/weex/source/images/ding.png          | Bin 5929 -> 0 bytes
 doc/themes/weex/source/images/extendable.svg    |  51 -
 doc/themes/weex/source/images/feature.png       | Bin 1090905 -> 0 bytes
 doc/themes/weex/source/images/feizhu.jpg        | Bin 5988 -> 0 bytes
 doc/themes/weex/source/images/fliggy.png        | Bin 19329 -> 0 bytes
 doc/themes/weex/source/images/flow.png          | Bin 14440 -> 0 bytes
 doc/themes/weex/source/images/galaxy_1.svg      |  53 --
 doc/themes/weex/source/images/galaxy_2.svg      |  53 --
 doc/themes/weex/source/images/ios.png           | Bin 6272 -> 0 bytes
 doc/themes/weex/source/images/juhuasuan.png     | Bin 46340 -> 0 bytes
 doc/themes/weex/source/images/level1.png        | Bin 14951 -> 0 bytes
 doc/themes/weex/source/images/level2.png        | Bin 101449 -> 0 bytes
 doc/themes/weex/source/images/level3.png        | Bin 101212 -> 0 bytes
 doc/themes/weex/source/images/level4.png        | Bin 339831 -> 0 bytes
 doc/themes/weex/source/images/lightweight.svg   |  31 -
 doc/themes/weex/source/images/logo.png          | Bin 5398 -> 0 bytes
 doc/themes/weex/source/images/logo.svg          |  29 -
 doc/themes/weex/source/images/performance.svg   |  29 -
 doc/themes/weex/source/images/playground.png    | Bin 12659 -> 0 bytes
 doc/themes/weex/source/images/qianniu.png       | Bin 19852 -> 0 bytes
 doc/themes/weex/source/images/qr.png            | Bin 1801 -> 0 bytes
 doc/themes/weex/source/images/slide1.png        | Bin 226303 -> 0 bytes
 doc/themes/weex/source/images/taobao.png        | Bin 3074 -> 0 bytes
 doc/themes/weex/source/images/taopiaopiao.png   | Bin 12460 -> 0 bytes
 doc/themes/weex/source/images/tmall.png         | Bin 8562 -> 0 bytes
 doc/themes/weex/source/images/vue-logo.png      | Bin 5346 -> 0 bytes
 doc/themes/weex/source/images/vue.png           | Bin 16582 -> 0 bytes
 doc/themes/weex/source/images/web.png           | Bin 9297 -> 0 bytes
 doc/themes/weex/source/images/xiami.png         | Bin 2615 -> 0 bytes
 doc/themes/weex/source/images/youku.png         | Bin 2178 -> 0 bytes
 doc/themes/weex/source/js/common.js             | 643 -------------
 doc/themes/weex/source/js/docsearch.min.js      |   7 -
 doc/themes/weex/source/js/example.js            |  37 -
 doc/themes/weex/source/js/examples/a.web.js     | 528 -----------
 doc/themes/weex/source/js/examples/a.weex.js    | 198 ----
 .../weex/source/js/examples/animation.web.js    | 569 ------------
 .../weex/source/js/examples/animation.weex.js   | 224 -----
 .../weex/source/js/examples/clipboard.web.js    | 583 ------------
 .../weex/source/js/examples/clipboard.weex.js   | 249 -----
 doc/themes/weex/source/js/examples/div.web.js   | 523 -----------
 doc/themes/weex/source/js/examples/div.weex.js  | 183 ----
 .../weex/source/js/examples/dom-rect.web.js     | 589 ------------
 .../weex/source/js/examples/dom-rect.weex.js    | 254 -----
 .../weex/source/js/examples/dom-scroll.web.js   | 598 ------------
 .../weex/source/js/examples/dom-scroll.weex.js  | 288 ------
 doc/themes/weex/source/js/examples/image.web.js | 542 -----------
 .../weex/source/js/examples/image.weex.js       | 225 -----
 .../weex/source/js/examples/indicator.web.js    | 618 -------------
 .../weex/source/js/examples/indicator.weex.js   | 307 ------
 doc/themes/weex/source/js/examples/input.web.js | 586 ------------
 .../weex/source/js/examples/input.weex.js       | 251 -----
 doc/themes/weex/source/js/examples/list.web.js  | 584 ------------
 doc/themes/weex/source/js/examples/list.weex.js | 252 -----
 doc/themes/weex/source/js/examples/modal.web.js | 604 ------------
 .../weex/source/js/examples/modal.weex.js       | 272 ------
 .../weex/source/js/examples/navigator.web.js    | 562 -----------
 .../weex/source/js/examples/navigator.weex.js   | 230 -----
 .../weex/source/js/examples/refresh.web.js      | 594 ------------
 .../weex/source/js/examples/refresh.weex.js     | 267 ------
 .../weex/source/js/examples/scroller.web.js     | 598 ------------
 .../weex/source/js/examples/scroller.weex.js    | 288 ------
 .../weex/source/js/examples/slider.web.js       | 587 ------------
 .../weex/source/js/examples/slider.weex.js      | 255 -----
 .../weex/source/js/examples/storage.web.js      | 634 -------------
 .../weex/source/js/examples/storage.weex.js     | 317 -------
 .../weex/source/js/examples/stream.web.js       | 590 ------------
 .../weex/source/js/examples/stream.weex.js      | 259 ------
 .../weex/source/js/examples/switch.web.js       | 605 ------------
 .../weex/source/js/examples/switch.weex.js      | 280 ------
 doc/themes/weex/source/js/examples/text.web.js  | 535 -----------
 doc/themes/weex/source/js/examples/text.weex.js | 208 -----
 .../weex/source/js/examples/textarea.web.js     | 582 ------------
 .../weex/source/js/examples/textarea.weex.js    | 247 -----
 doc/themes/weex/source/js/examples/video.web.js | 593 ------------
 .../weex/source/js/examples/video.weex.js       | 254 -----
 doc/themes/weex/source/js/examples/web.web.js   | 923 -------------------
 doc/themes/weex/source/js/examples/web.weex.js  | 600 ------------
 doc/themes/weex/source/js/highlight.pack.js     |   2 -
 doc/themes/weex/source/js/mobile-detect.js      |   3 -
 doc/themes/weex/source/js/qrcode.min.js         |   1 -
 doc/themes/weex/source/js/reqwest.js            |   7 -
 doc/themes/weex/source/js/swiper.min.js         |  18 -
 doc/themes/weex/source/js/velocity.js           |   5 -
 .../WeexDemo/Scanner/WXScannerHistoryVC.m       |   1 +
 ios/playground/WeexDemo/Scanner/WXScannerVC.m   |   5 +-
 .../Recycler/WXRecyclerUpdateController.m       |   4 +-
 .../Sources/Component/WXScrollerComponent.m     |  22 +-
 .../WeexSDK/Sources/Component/WXTextComponent.m |   3 +
 ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m   |  14 +-
 .../Sources/Model/WXSDKInstance_private.h       |   3 +-
 .../Utility/WXThreadSafeMutableDictionary.m     |   5 +-
 ios/sdk/WeexSDK/Sources/Utility/WXUtility.m     |   2 +-
 package.json                                    |   9 +-
 runtime/api/WeexInstance.js                     |  26 +-
 runtime/api/init.js                             |  11 +
 runtime/bridge/CallbackManager.js               |   8 +-
 runtime/bridge/receiver.js                      |   4 +-
 runtime/entries/env.js                          |  27 +
 runtime/entries/index.js                        |   2 +
 runtime/entries/legacy.js                       |  23 +
 runtime/entries/setup.js                        |   3 -
 runtime/frameworks/legacy/app/ctrl/init.js      |   5 +-
 runtime/frameworks/legacy/app/ctrl/misc.js      |   6 +-
 runtime/shared/index.js                         |  20 +-
 scripts/commit-msg.sh                           |  28 -
 scripts/install-hooks.sh                        |  23 -
 scripts/pre-commit.sh                           |  27 -
 scripts/pre-push.sh                             |  28 -
 623 files changed, 298 insertions(+), 68193 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/30ad3f6c/android/sdk/src/main/java/com/taobao/weex/dom/WXDomObject.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/30ad3f6c/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
----------------------------------------------------------------------
diff --cc android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
index 0591f73,222a577..78022f1
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
@@@ -60,10 -60,10 +60,10 @@@ class UpdateAttributeAction extends Tra
        }
        return;
      }
 -
 +    domObject.getAttrs().filterBindingStatement(mData);
      domObject.updateAttr(mData);
      if(mData.size() > 0) {
-        context.postRenderTask(this);
+       context.postRenderTask(this);
      }
    }
  

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/30ad3f6c/android/sdk/src/main/java/com/taobao/weex/ui/component/WXComponent.java
----------------------------------------------------------------------



[6/7] incubator-weex git commit: [WEEX-174][android] TemplateList Support Lifecycle and statefull component

Posted by mi...@apache.org.
[WEEX-174][android] TemplateList Support Lifecycle and statefull component


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/d6af2aae
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/d6af2aae
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/d6af2aae

Branch: refs/heads/master
Commit: d6af2aae2143bb0198a3df6201cad81bcf6e1ee1
Parents: 30ad3f6
Author: jianbai.gbj <ji...@alibaba-inc.com>
Authored: Thu Feb 8 15:13:25 2018 +0800
Committer: jianbai.gbj <ji...@alibaba-inc.com>
Committed: Thu Feb 8 15:13:25 2018 +0800

----------------------------------------------------------------------
 .../weex/commons/adapter/ImageAdapter.java      | 49 +++++++++++---------
 .../java/com/taobao/weex/dom/WXDomModule.java   |  2 +-
 .../weex/dom/action/UpdateAttributeAction.java  |  4 ++
 .../weex/ui/component/binding/Statements.java   |  6 ++-
 4 files changed, 36 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/d6af2aae/android/commons/src/main/java/com/alibaba/weex/commons/adapter/ImageAdapter.java
----------------------------------------------------------------------
diff --git a/android/commons/src/main/java/com/alibaba/weex/commons/adapter/ImageAdapter.java b/android/commons/src/main/java/com/alibaba/weex/commons/adapter/ImageAdapter.java
index 63625f8..5a7a311 100644
--- a/android/commons/src/main/java/com/alibaba/weex/commons/adapter/ImageAdapter.java
+++ b/android/commons/src/main/java/com/alibaba/weex/commons/adapter/ImageAdapter.java
@@ -19,6 +19,7 @@
 package com.alibaba.weex.commons.adapter;
 
 import android.net.Uri;
+import android.os.Looper;
 import android.text.TextUtils;
 import android.widget.ImageView;
 
@@ -38,8 +39,7 @@ public class ImageAdapter implements IWXImgLoaderAdapter {
   @Override
   public void setImage(final String url, final ImageView view,
                        WXImageQuality quality, final WXImageStrategy strategy) {
-
-    WXSDKManager.getInstance().postOnUiThread(new Runnable() {
+    Runnable runnable = new Runnable() {
 
       @Override
       public void run() {
@@ -68,28 +68,33 @@ public class ImageAdapter implements IWXImgLoaderAdapter {
         }
 
         Picasso.with(WXEnvironment.getApplication())
-            .load(temp)
-            .transform(new BlurTransformation(strategy.blurRadius))
-            .into(view, new Callback() {
-              @Override
-              public void onSuccess() {
-                if(strategy.getImageListener()!=null){
-                  strategy.getImageListener().onImageFinish(url,view,true,null);
-                }
+                .load(temp)
+                .transform(new BlurTransformation(strategy.blurRadius))
+                .into(view, new Callback() {
+                  @Override
+                  public void onSuccess() {
+                    if(strategy.getImageListener()!=null){
+                      strategy.getImageListener().onImageFinish(url,view,true,null);
+                    }
 
-                if(!TextUtils.isEmpty(strategy.placeHolder)){
-                  ((Picasso) view.getTag(strategy.placeHolder.hashCode())).cancelRequest(view);
-                }
-              }
+                    if(!TextUtils.isEmpty(strategy.placeHolder)){
+                      ((Picasso) view.getTag(strategy.placeHolder.hashCode())).cancelRequest(view);
+                    }
+                  }
 
-              @Override
-              public void onError() {
-                if(strategy.getImageListener()!=null){
-                  strategy.getImageListener().onImageFinish(url,view,false,null);
-                }
-              }
-            });
+                  @Override
+                  public void onError() {
+                    if(strategy.getImageListener()!=null){
+                      strategy.getImageListener().onImageFinish(url,view,false,null);
+                    }
+                  }
+                });
       }
-    },0);
+    };
+    if(Thread.currentThread() == Looper.getMainLooper().getThread()){
+      runnable.run();
+    }else {
+      WXSDKManager.getInstance().postOnUiThread(runnable, 0);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/d6af2aae/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
index b764630..b9bbefd 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/WXDomModule.java
@@ -101,7 +101,7 @@ public final class WXDomModule extends WXModule {
       Action action = Actions.get(method,args);
       if(action == null){
          WXLogUtils.e("Unknown dom action "
-                 +  method + " "  + args.toJSONString());
+                 +  method + " args "  + (args == null ? " null" : args.toJSONString()));
          return null;
       }
       if(action instanceof DOMAction){

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/d6af2aae/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
index 78022f1..ac6ca5d 100644
--- a/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
+++ b/android/sdk/src/main/java/com/taobao/weex/dom/action/UpdateAttributeAction.java
@@ -49,6 +49,10 @@ class UpdateAttributeAction extends TraceableAction implements DOMAction, Render
     if (context.isDestory()) {
       return;
     }
+    if(mData == null){
+      return;
+    }
+
     WXSDKInstance instance = context.getInstance();
     final WXDomObject domObject = context.getDomByRef(mRef);
     if (domObject == null) {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/d6af2aae/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
index b0b383e..f0ddf03 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
@@ -234,8 +234,10 @@ public class Statements {
                                 renderNode = copyComponentTree(component, parent);
                                 renderNode.setWaste(false);
                                 WXDomObject renderNodeDomObject = (WXDomObject) renderNode.getDomObject();
-                                renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_FOR);
-                                renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_IF); //FIXME  clear node's statement
+                                if(renderNodeDomObject.getAttrs().getStatement() != null) {
+                                    renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_FOR);
+                                    renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_IF); //clear node's statement
+                                }
                                 parentDomObject.add(renderNodeDomObject, renderIndex);
                                 parent.addChild(renderNode, renderIndex);
                                 updates.add(renderNode);


[3/7] incubator-weex git commit: [WEEX-174][android] TemplateList Support Lifecycle and statefull component

Posted by mi...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
index 2ed3fae..b0b383e 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/binding/Statements.java
@@ -21,19 +21,19 @@ package com.taobao.weex.ui.component.binding;
 import android.os.Looper;
 import android.support.v4.util.ArrayMap;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.annotation.Component;
+import com.taobao.weex.bridge.EventResult;
+import com.taobao.weex.bridge.WXBridgeManager;
 import com.taobao.weex.common.Constants;
 import com.taobao.weex.dom.WXAttr;
 import com.taobao.weex.dom.WXDomObject;
 import com.taobao.weex.dom.WXEvent;
+import com.taobao.weex.dom.WXStyle;
 import com.taobao.weex.dom.binding.ELUtils;
 import com.taobao.weex.dom.binding.WXStatement;
-import com.taobao.weex.dom.flex.CSSLayoutContext;
 import com.taobao.weex.el.parse.ArrayStack;
 import com.taobao.weex.el.parse.Operators;
 import com.taobao.weex.el.parse.Token;
@@ -42,6 +42,9 @@ import com.taobao.weex.ui.component.WXComponentFactory;
 import com.taobao.weex.ui.component.WXImage;
 import com.taobao.weex.ui.component.WXVContainer;
 import com.taobao.weex.ui.component.list.WXCell;
+import com.taobao.weex.ui.component.list.template.CellRenderContext;
+import com.taobao.weex.ui.component.list.template.CellDataManager;
+import com.taobao.weex.ui.component.list.template.VirtualComponentLifecycle;
 import com.taobao.weex.ui.component.list.template.WXRecyclerTemplateList;
 import com.taobao.weex.utils.WXLogUtils;
 import com.taobao.weex.utils.WXUtils;
@@ -63,11 +66,7 @@ public class Statements {
      * recursive copy component, none parent connect
      * */
     public static WXComponent copyComponentTree(WXComponent component){
-        long start = System.currentTimeMillis();
         WXComponent copy =  copyComponentTree(component, component.getParent());
-        if(WXEnvironment.isApkDebugable()){
-            WXLogUtils.d(WXRecyclerTemplateList.TAG, Thread.currentThread() + component.getRef() + "copyComponentTree " + "used " + (System.currentTimeMillis() - start));
-        }
         return copy;
     }
 
@@ -91,6 +90,10 @@ public class Statements {
                 }
             }
         }
+        //copy info need be sync
+        if(source.isWaste()){
+            component.setWaste(true);
+        }
         return  component;
     }
 
@@ -104,7 +107,7 @@ public class Statements {
      *  may be next render it can be used.
      *  after statement has executed, render component's binding attrs in context and bind it to component.
      * */
-    public static final List<WXComponent> doRender(WXComponent component, ArrayStack stack){
+    public static final List<WXComponent> doRender(WXComponent component, CellRenderContext stack){
         List<WXComponent> updates = new ArrayList<>(4);
         try{
             doRenderComponent(component, stack, updates);
@@ -143,7 +146,7 @@ public class Statements {
          *  may be next render it can be used.
          *  after statement has executed, render component's binding attrs in context and bind it to component.
          * */
-    private static final int doRenderComponent(WXComponent component, ArrayStack context,
+    private static final int doRenderComponent(WXComponent component, CellRenderContext context,
                                        List<WXComponent> updates){
         WXVContainer parent = component.getParent();
         WXDomObject domObject = (WXDomObject) component.getDomObject();
@@ -168,7 +171,7 @@ public class Statements {
                     String itemKey = vfor.getString(WXStatement.WX_FOR_ITEM);
                     Object data = null;
                     if(listBlock != null) {
-                        data = listBlock.execute(context);
+                        data = listBlock.execute(context.stack);
                     }
                     if((data instanceof List || data instanceof  Map)){
 
@@ -199,15 +202,15 @@ public class Statements {
                             if(itemKey != null){
                                 loop.put(itemKey, value);
                             }else{
-                                context.push(value);
+                                context.stack.push(value);
                             }
                             if(loop.size() > 0){
-                                context.push(loop);
+                                context.stack.push(loop);
                             }
 
 
                             if(vif != null){
-                                if(!Operators.isTrue(vif.execute(context))){
+                                if(!Operators.isTrue(vif.execute(context.stack))){
                                     continue;
                                 }
                             }
@@ -229,8 +232,10 @@ public class Statements {
                             if(renderNode == null){
                                 long start = System.currentTimeMillis();
                                 renderNode = copyComponentTree(component, parent);
+                                renderNode.setWaste(false);
                                 WXDomObject renderNodeDomObject = (WXDomObject) renderNode.getDomObject();
-                                renderNodeDomObject.getAttrs().setStatement(null); // clear node's statement
+                                renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_FOR);
+                                renderNodeDomObject.getAttrs().getStatement().remove(WXStatement.WX_IF); //FIXME  clear node's statement
                                 parentDomObject.add(renderNodeDomObject, renderIndex);
                                 parent.addChild(renderNode, renderIndex);
                                 updates.add(renderNode);
@@ -238,13 +243,13 @@ public class Statements {
                                     WXLogUtils.d(WXRecyclerTemplateList.TAG, Thread.currentThread().getName() +  renderNode.getRef() + renderNode.getDomObject().getType() + "statements copy component tree used " + (System.currentTimeMillis() - start));
                                 }
                             }
-                            doBindingAttrsEventAndRenderChildNode(renderNode, domObject, context, updates);
+                            doBindingAttrsEventAndRenderChildNode(renderNode, (WXDomObject) renderNode.getDomObject(), context, updates);
                             renderIndex++;
                             if(loop.size() > 0){
-                                context.push(loop);
+                                context.stack.push(loop);
                             }
                             if(itemKey == null) {
-                                context.pop();
+                                context.stack.pop();
                             }
                         }
                     }
@@ -264,45 +269,112 @@ public class Statements {
 
             //execute v-if context
             if(vif != null){
-                if(!Operators.isTrue(vif.execute(context))){
+                if(!Operators.isTrue(vif.execute(context.stack))){
                     component.setWaste(true);
-                    if(Thread.currentThread() == Looper.getMainLooper().getThread()) {
-                        return 1;
-                    }
+                    return 1;
                 }else{
                     component.setWaste(false);
                 }
+
             }
         }
         doBindingAttrsEventAndRenderChildNode(component, domObject, context, updates);
         return  1;
     }
 
+
     /**
      * bind attrs and doRender component child
      * */
-    private static void doBindingAttrsEventAndRenderChildNode(WXComponent component, WXDomObject domObject, ArrayStack context,
+    private static void doBindingAttrsEventAndRenderChildNode(WXComponent component, WXDomObject domObject, CellRenderContext context,
                                                               List<WXComponent> updates){
-       WXAttr attr = component.getDomObject().getAttrs();
+        WXAttr attr = component.getDomObject().getAttrs();
+
         /**
          * sub component supported, sub component new stack
          * */
+        ArrayStack stack = context.stack;
+
+
+
         if(attr.get(ELUtils.IS_COMPONENT_ROOT) != null
                 && WXUtils.getBoolean(attr.get(ELUtils.IS_COMPONENT_ROOT), false)){
             if(attr.get(ELUtils.COMPONENT_PROPS) != null
                     && attr.get(ELUtils.COMPONENT_PROPS) instanceof  JSONObject){
-                Map<String, Object>  props  = renderProps((JSONObject) attr.get(ELUtils.COMPONENT_PROPS), context);
-                context = new ArrayStack();
-                context.push(props);
+                 String compoentId = (String) attr.get(CellDataManager.SUB_COMPONENT_TEMPLATE_ID);
+                Object compoentData = null;
+                if(!TextUtils.isEmpty(compoentId)){
+                    String virtualComponentId =  context.getRenderState().getVirtualComponentIds().get(component.getViewTreeKey());
+                   if(virtualComponentId == null){ //none virtualComponentId, create and do attach
+                        virtualComponentId =  CellDataManager.createVirtualComponentId(context.templateList.getRef(),
+                                component.getViewTreeKey(), context.templateList.getItemId(context.position));
+                        Map<String, Object>  props  = renderProps((JSONObject) attr.get(ELUtils.COMPONENT_PROPS), context.stack);
+                        EventResult result = WXBridgeManager.getInstance().syncCallJSEventWithResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC, component.getInstanceId(), null, compoentId, VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.CREATE,  new Object[]{
+                                virtualComponentId,
+                                props
+                        }, null);
+                        if(result != null
+                                && result.getResult() != null
+                                && result.getResult() instanceof Map){
+                            props.putAll((Map<? extends String, ?>) result.getResult());
+                        }
+                        compoentData  =  props;
+                        context.getRenderState().getVirtualComponentIds().put(component.getViewTreeKey(), virtualComponentId);
+                        context.templateList.getCellDataManager().createVirtualComponentData(context.position, virtualComponentId, compoentData);
+                        //create virtual componentId
+                        WXBridgeManager.getInstance().asyncCallJSEventVoidResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC, component.getInstanceId(), null, virtualComponentId, VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.ATTACH, null);
+                     }else{ // get virtual component data check has dirty's update
+                       compoentData = context.getRenderState().getVirtualComponentDatas().get(virtualComponentId);
+                       if(context.getRenderState().isHasDataUpdate()){
+                           Map<String, Object>  props  = renderProps((JSONObject) attr.get(ELUtils.COMPONENT_PROPS), context.stack);
+                           EventResult result = WXBridgeManager.getInstance().syncCallJSEventWithResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC, component.getInstanceId(), null, virtualComponentId, VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.SYNSTATE,  new Object[]{
+                                   virtualComponentId,
+                                   props
+                           }, null);
+
+                           if(result != null
+                                   && result.getResult() != null
+                                   && result.getResult() instanceof Map){
+                               props.putAll((Map<? extends String, ?>) result.getResult());
+                               context.templateList.getCellDataManager().updateVirtualComponentData(virtualComponentId, props);
+                               compoentData = props;
+                           }
+                       }
+                    }
+                    component.getDomObject().getAttrs().put(CellDataManager.VIRTUAL_COMPONENT_ID, virtualComponentId);
+                }else{ //stateless component
+                    Map<String, Object>  props  = renderProps((JSONObject) attr.get(ELUtils.COMPONENT_PROPS), context.stack);
+                    compoentData = props;
+                }
+                //virtual component is new context
+                context.stack = new ArrayStack();
+                if(compoentData != null){
+                    context.stack.push(compoentData);
+                }
             }
         }
+
+        /**
+         * check node is render only once, if render once, and has rendered, just return
+         * */
+        Object vonce = null;
+        if(attr.getStatement() != null){
+            vonce = attr.getStatement().get(WXStatement.WX_ONCE);
+        }
+        if(vonce != null){
+            ArrayStack onceStack = context.getRenderState().getOnceComponentStates().get(component.getViewTreeKey());
+            if(onceStack == null){
+                onceStack = context.templateList.copyStack(context, stack);
+                context.getRenderState().getOnceComponentStates().put(component.getViewTreeKey(), onceStack);
+            }
+            context.stack = onceStack;
+        }
+
         doRenderBindingAttrsAndEvent(component, domObject, context);
         if(component instanceof WXVContainer){
             if(!domObject.isShow()){
                 if(!(component instanceof WXCell)){
-                    if(Thread.currentThread() == Looper.getMainLooper().getThread()){
-                        return;
-                    }
+                    return;
                 }
             }
             WXVContainer container = (WXVContainer) component;
@@ -311,6 +383,9 @@ public class Statements {
                 k += doRenderComponent(next, context, updates);
             }
         }
+        if(stack != context.stack){
+            context.stack = stack;
+        }
     }
 
 
@@ -325,14 +400,15 @@ public class Statements {
     /**
      * render dynamic binding attrs and bind them to component node.
      * */
-    private static void doRenderBindingAttrsAndEvent(WXComponent component, WXDomObject domObject, ArrayStack context){
+    private static void doRenderBindingAttrsAndEvent(WXComponent component, WXDomObject domObject, CellRenderContext context){
+        ArrayStack stack  = context.stack;
         component.setWaste(false);
         WXAttr attr = domObject.getAttrs();
         if(attr != null
                 && attr.getBindingAttrs() != null
                 && attr.getBindingAttrs().size() > 0){
             ArrayMap<String, Object> bindAttrs = domObject.getAttrs().getBindingAttrs();
-            Map<String, Object> dynamic =  renderBindingAttrs(bindAttrs, context);
+            Map<String, Object> dynamic =  renderBindingAttrs(bindAttrs, stack);
             Set<Map.Entry<String, Object>> entries = dynamic.entrySet();
             /**
              * diff attrs, see attrs has update, remove none update attrs
@@ -364,23 +440,60 @@ public class Statements {
                 }else {
                     domObject.updateAttr(dynamic); //dirty layout
                 }
-                if(Thread.currentThread() == Looper.getMainLooper().getThread()) {
+                if(isMainThread()) {
                     component.updateProperties(dynamic);
                 }
                 dynamic.clear();
             }
         }
+
+
+        WXStyle style = domObject.getStyles();
+        if(style != null && style.getBindingStyle() != null){
+            ArrayMap<String, Object> bindStyle = style.getBindingStyle();
+            Map<String, Object> dynamic =  renderBindingAttrs(bindStyle, stack);
+            Set<Map.Entry<String, Object>> entries = dynamic.entrySet();
+            /**
+             * diff attrs, see attrs has update, remove none update attrs
+             * */
+            Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
+            while (iterator.hasNext()){
+                Map.Entry<String, Object> entry = iterator.next();
+                String key = entry.getKey();
+                Object value = entry.getValue();
+                Object oldValue = style.get(key);
+                if(value == null){
+                    if(oldValue == null){
+                        iterator.remove();
+                        continue;
+                    }
+                }else{
+                    if(value.equals(oldValue)){
+                        iterator.remove();
+                    }
+                }
+            }
+            if(dynamic.size() > 0) {
+                 domObject.updateStyle(dynamic, false);
+                 domObject.applyStyle(dynamic);
+                 if(isMainThread()) {
+                    component.updateProperties(dynamic);
+                 }
+            }
+        }
+
         WXEvent event = domObject.getEvents();
         if(event == null || event.getEventBindingArgs() == null){
             return;
         }
         Set<Map.Entry<String, Object>> eventBindArgsEntrySet = event.getEventBindingArgs().entrySet();
         for(Map.Entry<String, Object> eventBindArgsEntry : eventBindArgsEntrySet){
-             List<Object> values = getBindingEventArgs(context, eventBindArgsEntry.getValue());
+             List<Object> values = getBindingEventArgs(stack, eventBindArgsEntry.getValue());
              if(values != null){
                  event.putEventBindingArgsValue(eventBindArgsEntry.getKey(), values);
              }
         }
+
     }
 
 
@@ -390,7 +503,7 @@ public class Statements {
      * return binding attrs rended value in context
      * */
     private static final  ThreadLocal<Map<String, Object>> dynamicLocal = new ThreadLocal<>();
-    public static Map<String, Object> renderBindingAttrs(ArrayMap bindAttrs, ArrayStack context){
+    public static Map<String, Object> renderBindingAttrs(ArrayMap bindAttrs, ArrayStack stack){
         Set<Map.Entry<String, Object>> entrySet = bindAttrs.entrySet();
         Map<String, Object> dynamic = dynamicLocal.get();
         if(dynamic == null) {
@@ -407,7 +520,7 @@ public class Statements {
                     && (((JSONObject) value).get(ELUtils.BINDING)  instanceof Token)){
                 JSONObject binding = (JSONObject) value;
                 Token block = (Token) (binding.get(ELUtils.BINDING));
-                Object blockValue = block.execute(context);
+                Object blockValue = block.execute(stack);
                 dynamic.put(key, blockValue);
             }else if(value instanceof JSONArray){
                 JSONArray array = (JSONArray) value;
@@ -422,7 +535,7 @@ public class Statements {
                             && (((JSONObject) element).get(ELUtils.BINDING) instanceof Token)){
                         JSONObject binding = (JSONObject) element;
                         Token block = (Token) (binding.get(ELUtils.BINDING));
-                        Object blockValue = block.execute(context);
+                        Object blockValue = block.execute(stack);
                         if(blockValue == null){
                             blockValue = "";
                         }
@@ -442,7 +555,7 @@ public class Statements {
     }
 
 
-    public static Map<String, Object> renderProps(JSONObject props, ArrayStack context){
+    public static Map<String, Object> renderProps(JSONObject props, ArrayStack stack){
         Set<Map.Entry<String, Object>> entrySet = props.entrySet();
         Map<String, Object> renderProps = new ArrayMap<>(4);
         for(Map.Entry<String, Object> entry : entrySet){
@@ -452,7 +565,7 @@ public class Statements {
                     && (((JSONObject) value).get(ELUtils.BINDING)  instanceof  Token)){
                 JSONObject binding = (JSONObject) value;
                 Token block = (Token) (binding.get(ELUtils.BINDING));
-                Object blockValue = block.execute(context);
+                Object blockValue = block.execute(stack);
                 renderProps.put(key, blockValue);
             }else{
                 renderProps.put(key, value);
@@ -461,7 +574,7 @@ public class Statements {
         return  renderProps;
     }
 
-    public static List<Object> getBindingEventArgs(ArrayStack context, Object bindings){
+    public static List<Object> getBindingEventArgs(ArrayStack stack, Object bindings){
           List<Object>  params = new ArrayList<>(4);
           if(bindings instanceof  JSONArray){
               JSONArray array = (JSONArray) bindings;
@@ -470,7 +583,7 @@ public class Statements {
                   if(value instanceof  JSONObject
                           && (((JSONObject) value).get(ELUtils.BINDING) instanceof  Token)){
                       Token block = (Token)(((JSONObject) value).get(ELUtils.BINDING));
-                      Object blockValue = block.execute(context);
+                      Object blockValue = block.execute(stack);
                       params.add(blockValue);
                   }else{
                       params.add(value);
@@ -480,7 +593,7 @@ public class Statements {
               JSONObject binding = (JSONObject) bindings;
                if(binding.get(ELUtils.BINDING) instanceof  Token){
                    Token block = (Token) binding.get(ELUtils.BINDING);
-                   Object blockValue = block.execute(context);
+                   Object blockValue = block.execute(stack);
                    params.add(blockValue);
                }else{
                    params.add(bindings.toString());
@@ -490,4 +603,33 @@ public class Statements {
           }
           return  params;
     }
+
+    private static volatile int componentIdNext = 0;
+
+
+    private static boolean isMainThread(){
+        return  Thread.currentThread() == Looper.getMainLooper().getThread();
+    }
+
+
+
+    public static String getComponentId(WXComponent component){
+        if(component instanceof  WXCell || component == null){
+            return  null;
+        }
+        WXDomObject domObject = (WXDomObject) component.getDomObject();
+        WXAttr attr = domObject.getAttrs();
+        if(attr.get(ELUtils.IS_COMPONENT_ROOT) != null
+                && WXUtils.getBoolean(attr.get(ELUtils.IS_COMPONENT_ROOT), false)){
+            if(attr.get(ELUtils.COMPONENT_PROPS) != null
+                    && attr.get(ELUtils.COMPONENT_PROPS) instanceof  JSONObject){
+                Object componentId = attr.get(CellDataManager.VIRTUAL_COMPONENT_ID);
+                if(componentId == null){
+                    return null;
+                }
+                return componentId.toString();
+            }
+        }
+        return getComponentId(component.getParent());
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
index 36909fa..935f7e6 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
@@ -52,7 +52,6 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
     private ViewGroup mRealView;
     private View mTempStickyView;
     private View mHeadView;
-    private boolean mLazy = true;
 
     /** used in list sticky detect **/
     private int mScrollPositon = -1;
@@ -63,16 +62,16 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
 
     private boolean isSourceUsed = false;
 
-    private boolean hasLayout = false;
-
 
     @Deprecated
     public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, boolean isLazy) {
         super(instance, dom, parent);
+        lazy(true);
     }
 
     public WXCell(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, boolean isLazy) {
         super(instance, dom, parent);
+        lazy(true);
         if(Build.VERSION.SDK_INT< VERSION_CODES.LOLLIPOP) {
             try {
                 //TODO a WTF is necessary if anyone try to change the flat flag during update attrs.
@@ -88,12 +87,10 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
 
     @Override
     public boolean isLazy() {
-        return mLazy && !isFixed();
+        return super.isLazy() && !isFixed();
     }
 
-    public void lazy(boolean lazy) {
-        mLazy = lazy;
-    }
+
 
     @Override
     @RestrictTo(Scope.LIBRARY)
@@ -236,11 +233,4 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
         isSourceUsed = sourceUsed;
     }
 
-    public boolean isHasLayout() {
-        return hasLayout;
-    }
-
-    public void setHasLayout(boolean hasLayout) {
-        this.hasLayout = hasLayout;
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
new file mode 100644
index 0000000..eb864bf
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/AsyncCellLoadTask.java
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component.list.template;
+
+import android.os.AsyncTask;
+import android.os.Looper;
+import android.os.MessageQueue;
+
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.ui.component.list.WXCell;
+import com.taobao.weex.utils.WXLogUtils;
+
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * Created by furture on 2018/1/25.
+ * async template cell component copy in background and init component when idle
+ */
+class AsyncCellLoadTask extends AsyncTask<Void,Void, Void> {
+
+    private String template;
+    private WXCell source;
+    private WXRecyclerTemplateList templateList;
+
+    public AsyncCellLoadTask(String template, WXCell source, WXRecyclerTemplateList templateList) {
+        this.template = template;
+        this.source = source;
+        this.templateList = templateList;
+    }
+
+    /**
+     * async template cell component copy in background
+     * */
+    @Override
+    protected Void doInBackground(Void... params) {
+        TemplateCache cellCache = templateList.getTemplatesCache().get(template);
+        if(cellCache == null || cellCache.cells == null){
+            return null;
+        }
+        while (cellCache.cells.size() < templateList.getTemplateCacheSize()){
+            long start = System.currentTimeMillis();
+            WXCell component = (WXCell) templateList.copyComponentFromSourceCell(source);
+            if(WXEnvironment.isOpenDebugLog() && WXRecyclerTemplateList.ENABLE_TRACE_LOG){
+                WXLogUtils.d(WXRecyclerTemplateList.TAG, " AsyncCellLoadTask load " + template
+                + " used " + (System.currentTimeMillis() - start));
+            }
+            if(component == null){
+                return null;
+            }
+            if(isDestory()){
+                return null;
+            }
+            cellCache.cells.add(component);
+        }
+        return null;
+    }
+
+    /**
+     * init component view when main thread idle
+     * */
+    @Override
+    protected void onPostExecute(Void aVoid) {
+        if(isDestory()){
+            return;
+        }
+        final TemplateCache cellCache = templateList.getTemplatesCache().get(template);
+        if(cellCache == null){
+            return;
+        }
+        if(cellCache.cells == null
+                || cellCache.cells.size() == 0){
+            cellCache.isLoadIng = false;
+            return;
+        }
+        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
+            @Override
+            public boolean queueIdle() {
+                if(isDestory()){
+                    return false;
+                }
+                ConcurrentLinkedQueue<WXCell> queue =  cellCache.cells;
+                Iterator<WXCell> iterator =  queue.iterator();
+                while (iterator.hasNext()){
+                    WXCell  component =  iterator.next();
+                    if(component.isLazy()){
+                        templateList.doCreateCellViewBindData(component, template, true);
+                        return iterator.hasNext();
+                    }
+                }
+                return false;
+            }
+        });
+        cellCache.isLoadIng = false;
+    }
+
+    private boolean isDestory(){
+        if(source.getInstance() == null
+                || source.getInstance().isDestroy()){
+            return true;
+        }
+        return templateList.isDestoryed();
+    }
+
+    /**
+     * start cell load task on THREAD_POOL_EXECUTOR
+     * */
+    public void startTask(){
+        executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
new file mode 100644
index 0000000..3982117
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellDataManager.java
@@ -0,0 +1,272 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component.list.template;
+
+
+import android.support.v4.util.ArrayMap;
+import android.text.TextUtils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.taobao.weex.WXEnvironment;
+import com.taobao.weex.bridge.WXBridgeManager;
+import com.taobao.weex.utils.WXUtils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by furture on 2018/1/23.
+ * template data manager, manage data and render state
+ */
+public class CellDataManager {
+
+    private static final String VIRTUAL_COMPONENT_SEPRATOR = "@";
+
+    public static final String SUB_COMPONENT_TEMPLATE_ID = "@templateId";
+
+    public static final String VIRTUAL_COMPONENT_ID = "@virtualComponentId";
+
+    /**
+     * template list data, update should vis data manager interface, this field is read only
+     * */
+    JSONArray listData;
+
+    /**
+     * current template list
+     * */
+    public final WXRecyclerTemplateList templateList;
+
+    /**
+     * data render state for position, itemId、dirty、and other info
+     * */
+    private Map<Integer, CellRenderState> renderStates = new ArrayMap<>();
+
+
+    /**
+     * list virtual component data, rendet state
+     * key virtual component id, value is cell render state.
+     * */
+    private Map<String, CellRenderState> virtualComponentRenderStates;
+
+
+
+    /**
+     * template list data manager
+     * */
+    public CellDataManager(WXRecyclerTemplateList templateList) {
+        this.templateList = templateList;
+    }
+
+    /**
+     * get current render state for current position, never return null.
+     * */
+    public CellRenderState getRenderState(int position){
+        CellRenderState renderState = renderStates.get(position);
+        if(renderState == null){
+            renderState = new CellRenderState();
+            renderState.position = position;
+            renderStates.put(position, renderState);
+        }
+        if(position != renderState.position) {
+            renderState.position = position;
+            renderState.hasPositionChange = true;
+        }
+        return renderState;
+    }
+
+    /**
+     * @param  virutalComponentId virutalComponentId
+     * @param  data   update    virutalComponent's data
+     * update virtual component data
+     * */
+    public void updateVirtualComponentData(String virutalComponentId, Object data){
+        if(virtualComponentRenderStates != null){
+            CellRenderState cellRenderState = virtualComponentRenderStates.get(virutalComponentId);
+            if(cellRenderState != null){
+                cellRenderState.getVirtualComponentDatas().put(virutalComponentId, data);
+                cellRenderState.hasVirtualCompoentUpdate = true;
+            }else{
+                if(WXEnvironment.isApkDebugable()) {
+                    throw new IllegalArgumentException("virtualComponentDatas illegal state empty render state" + virutalComponentId);
+                }
+            }
+        }else{
+            if(WXEnvironment.isApkDebugable()){
+                throw  new IllegalArgumentException("virtualComponentDatas illegal state " + virutalComponentId);
+            }
+        }
+    }
+
+    /**
+     * @param  position  current position virtual component
+     * @param  virutalComponentId virutalComponentId
+     * @param  data   update    virutalComponent's data
+     * create virtual component data
+     * */
+    public void createVirtualComponentData(int position, String virutalComponentId, Object data){
+        if(virtualComponentRenderStates == null){
+            virtualComponentRenderStates = new HashMap<>(8);
+        }
+        CellRenderState renderState = renderStates.get(position);
+        renderState.getVirtualComponentDatas().put(virutalComponentId, data);
+        virtualComponentRenderStates.put(virutalComponentId, renderState);
+
+    }
+
+
+
+
+    /**
+     * @param  listData setList data
+     * clear render state for current cell, and virtual component data
+     * */
+    public void setListData(JSONArray listData) {
+        if(this.listData != listData) {
+            if(this.listData != null){
+                if(WXUtils.getBoolean(templateList.getDomObject().getAttrs().get("exitDetach"), true)){
+                    for(int i=0; i<this.listData.size(); i++){
+                        cleanRenderState(renderStates.remove(i));
+                    }
+                }
+            }
+            this.listData = listData;
+            renderStates.clear();
+            if (virtualComponentRenderStates != null) {
+                virtualComponentRenderStates.clear();
+            }
+        }
+    }
+
+    /**
+     * @param index insert index
+     * @param  data  data object
+     * insert data at current index
+     * */
+    public boolean insertData(int index, Object data){
+        listData.add(index, data);
+        boolean renderStateChange = false;
+        for(int i=listData.size(); i>= index; i--){
+            CellRenderState state = renderStates.remove(i);
+            if(state != null){
+                renderStates.put(i + 1, state);
+                renderStateChange = true;
+            }
+        }
+        return renderStateChange;
+    }
+
+    /**
+     *
+     * @param index insert index
+     * @param  data  data object
+     * insert data at current index
+     * */
+    public boolean insertRange(int index, JSONArray data){
+        listData.addAll(index, data);
+        boolean renderStateChange = false;
+        for(int i = listData.size()-1; i >= index; i--){
+            CellRenderState state = renderStates.remove(i);
+            if(state != null){
+                renderStates.put(i + 1, state);
+                renderStateChange = true;
+            }
+        }
+        return renderStateChange;
+    }
+
+    /**
+     * @param  data  data object
+     * @param index insert index
+     * update data, reset new render state,
+     * return true if only data changed, false if viewType changed
+     * */
+    public boolean  updateData(Object data, int index){
+        boolean onlyDataChange = TextUtils.equals(templateList.getTemplateKey(index), templateList.getTemplateKey(data));
+        listData.set(index, data);
+        if(!onlyDataChange){
+            //structure changed, reset render state
+            cleanRenderState(renderStates.remove(index));
+        }else{
+            CellRenderState renderState = renderStates.get(index);
+            if(renderState != null){
+                renderState.hasDataUpdate = true;
+            }
+        }
+        return onlyDataChange;
+    }
+
+    /**
+     * @param index
+     * remove data, and its render state  and  virtual's data
+     * */
+    public void  removeData(Integer index){
+        listData.remove((int)index); //remove by index
+        cleanRenderState(renderStates.remove(index));
+        int count = listData.size() + 1;
+        for(int i=index + 1; i < count; i++){
+            CellRenderState state = renderStates.remove(i);
+            if(state != null){
+                renderStates.put(i-1, state);
+            }
+        }
+    }
+
+    /**
+     *  clean render state, if has virtual component, call virtual component detach lifecycle
+     * */
+    private void  cleanRenderState(CellRenderState renderState){
+        if(renderState == null){
+            return;
+        }
+        if(renderState.hasVirtualComponents()){
+            Collection<String> virtualComponentIds =  renderState.getVirtualComponentIds().values();
+            for(String virtualComponentId : virtualComponentIds){
+                if(virtualComponentRenderStates != null){
+                    virtualComponentRenderStates.remove(virtualComponentId);
+                }
+                WXBridgeManager.getInstance().asyncCallJSEventVoidResult(WXBridgeManager.METHD_COMPONENT_HOOK_SYNC,
+                        templateList.getInstanceId(),
+                        null,
+                        virtualComponentId, VirtualComponentLifecycle.LIFECYCLE, VirtualComponentLifecycle.DETACH, null);
+
+            }
+        }
+    }
+
+
+    /**
+     * create virtualComponentId
+     * */
+    public static String createVirtualComponentId(String listRef, String viewTreeKey, long itemId){
+        return  listRef + VIRTUAL_COMPONENT_SEPRATOR  + viewTreeKey + VIRTUAL_COMPONENT_SEPRATOR + itemId;
+    }
+
+    /**
+     * get list ref from virtualComponentId
+     * */
+    public static String getListRef(String virtualComponentId){
+        if(virtualComponentId == null){
+            return null;
+        }
+        return virtualComponentId.split(VIRTUAL_COMPONENT_SEPRATOR)[0];
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
new file mode 100644
index 0000000..7d59848
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderContext.java
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component.list.template;
+
+import com.taobao.weex.el.parse.ArrayStack;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by furture on 2018/1/23.
+ * render context for cell template
+ */
+public class CellRenderContext {
+    /**
+     * code execute stack
+     * */
+    public ArrayStack stack = new ArrayStack();
+    /**
+     * init context data
+     * */
+    public Map map = new HashMap(8);
+
+
+    /**
+     * component data context
+     * */
+    public CellRenderState renderState;
+
+    /**
+     * current position
+     * */
+    public int position;
+
+    /**
+     * current list component
+     * */
+    public WXRecyclerTemplateList templateList;
+
+
+    /**
+     * get current render state
+     * */
+    public CellRenderState getRenderState() {
+        if(renderState != null){
+            renderState =  templateList.getCellDataManager().getRenderState(position);
+        }
+        return renderState;
+    }
+
+
+    public void clear(){
+        if(stack.getList().size() > 0) {
+            stack.getList().clear();
+        }
+        if(map.size() > 0) {
+            map.clear();
+        }
+        renderState  = null;
+        position = 0;
+        templateList = null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
new file mode 100644
index 0000000..2f71a81
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/CellRenderState.java
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component.list.template;
+
+import android.support.v7.widget.RecyclerView;
+
+import com.taobao.weex.el.parse.ArrayStack;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by furture on 2018/1/24.
+ * render state for one cell, manage it's render state
+ */
+public class CellRenderState {
+
+    /**
+     * dirty for current position, for example virtual component has update
+     * */
+    boolean hasVirtualCompoentUpdate = false;
+
+    /**
+     * has date update
+     * */
+    boolean hasDataUpdate = false;
+
+    /**
+     * position changed
+     * */
+    boolean hasPositionChange = false;
+
+    /**
+     *  may use position, when position changed should be rendered
+     * */
+    int  position;
+
+    /**
+     * unique itemId for current position, generate via key core
+     * */
+    long itemId = RecyclerView.NO_ID;
+
+
+
+    /**
+     * virtualCompoentId for cell, key is viewTreeKey, value is virutalComponentId.
+     * lazy init,
+     * */
+    private Map<String, String> virtualComponentIds;
+    private Map<String, Object> virtualComponentDatas;
+
+
+    /**
+     * mark once statements has rendered
+     * */
+    private Map<String,ArrayStack> onceComponentStates;
+
+
+    public Map<String, String> getVirtualComponentIds() {
+        if(virtualComponentIds == null){
+            virtualComponentIds = new HashMap<>(8);
+        }
+        return virtualComponentIds;
+    }
+
+    /**
+     * return current cell has virtual component
+     * */
+    public boolean hasVirtualComponents(){
+        return virtualComponentIds != null && virtualComponentIds.size() > 0;
+    }
+
+    public Map<String, Object> getVirtualComponentDatas() {
+        if(virtualComponentDatas == null){
+            virtualComponentDatas = new HashMap<>(4);
+        }
+        return virtualComponentDatas;
+    }
+
+    public Map<String, ArrayStack> getOnceComponentStates() {
+        if(onceComponentStates == null){
+            onceComponentStates = new HashMap<>();
+        }
+        return onceComponentStates;
+    }
+
+    public boolean isDirty() {
+        return hasDataUpdate
+                || hasVirtualCompoentUpdate
+                || hasPositionChange;
+    }
+
+    public boolean isHasDataUpdate() {
+        return hasDataUpdate;
+    }
+
+
+
+    public void  resetDirty(){
+        hasDataUpdate = false;
+        hasVirtualCompoentUpdate = false;
+        hasPositionChange = false;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
deleted file mode 100644
index 0aa6cde..0000000
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/DomTreeBuilder.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.taobao.weex.ui.component.list.template;
-
-import com.taobao.weex.WXEnvironment;
-import com.taobao.weex.WXSDKManager;
-import com.taobao.weex.dom.DOMActionContext;
-import com.taobao.weex.dom.WXDomObject;
-import com.taobao.weex.dom.action.TraceableAction;
-import com.taobao.weex.ui.component.WXComponent;
-import com.taobao.weex.ui.component.WXComponentFactory;
-import com.taobao.weex.ui.component.WXVContainer;
-import com.taobao.weex.utils.WXLogUtils;
-
-/**
- * Created by furture on 2017/10/2.
- */
-
-class DomTreeBuilder extends TraceableAction {
-
-
-
-
-    public WXComponent generateComponentTree(DOMActionContext context, WXDomObject dom, WXVContainer parent) {
-        if (dom == null) {
-            return null;
-        }
-       long startNanos = System.nanoTime();
-        dom.setCloneThis(true);
-        WXComponent component = WXComponentFactory.newInstance(context.getInstance(), dom, parent);
-        if (component != null) {
-            component.mTraceInfo.domThreadStart = dom.mDomThreadTimestamp;
-            component.mTraceInfo.rootEventId = mTracingEventId;
-            component.mTraceInfo.domQueueTime = mDomQueueTime;
-        }
-        context.registerComponent(dom.getRef(), component);
-        if (component instanceof WXVContainer) {
-            WXVContainer container = (WXVContainer) component;
-            WXDomObject parentDom = (WXDomObject) container.getDomObject();
-            for (int i = 0; i < dom.childCount(); ++i) {
-                WXDomObject child = dom.getChild(i);
-                if (child != null) {
-                    WXComponent childComponent = generateComponentTree(context, child, container);
-                    container.addChild(childComponent);
-                    WXDomObject childDomObject = (WXDomObject) childComponent.getDomObject();
-                    if(childDomObject != child) {
-                        int index = parentDom.index(child);
-                        parentDom.add(childDomObject, index);
-                        if(index >= 0) {
-                            parentDom.remove(child);
-                            i--;
-                        }
-                        RuntimeException exception = new IllegalArgumentException(childDomObject.getClass().getName()
-                                + " not support clone this");
-                        WXLogUtils.e("weex", exception);
-                        if(WXEnvironment.isApkDebugable()){
-                            throw  exception;
-                        }
-                    }
-                }
-            }
-        }
-        dom.setCloneThis(false);
-        if (component != null) {
-            component.mTraceInfo.domThreadNanos = System.nanoTime() - startNanos;
-        }
-        return component;
-    }
-
-    public static final WXComponent buildTree(WXDomObject domObject, WXVContainer parent){
-        DOMActionContext domActionContext = WXSDKManager.getInstance().getWXDomManager().getDomContext(parent.getInstanceId());
-        if(domActionContext == null){
-            return null;
-        }
-        DomTreeBuilder builder = new DomTreeBuilder();
-        domObject.traverseTree(
-                domActionContext.getAddDOMConsumer(),
-                domActionContext.getApplyStyleConsumer()
-        );
-        return builder.generateComponentTree(domActionContext, domObject, parent);
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
new file mode 100644
index 0000000..f25c9a9
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/PositionRef.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component.list.template;
+
+/**
+ * position render state, when render state change, position changed
+ * Created by furture on 2018/2/2.
+ */
+public class PositionRef extends  Number{
+
+    private CellRenderState renderState;
+
+    public PositionRef(CellRenderState renderState) {
+        this.renderState = renderState;
+    }
+
+    @Override
+    public int intValue() {
+        return getPosition();
+    }
+
+    @Override
+    public long longValue() {
+        return getPosition();
+    }
+
+    @Override
+    public float floatValue() {
+        return getPosition();
+    }
+
+    @Override
+    public double doubleValue() {
+        return getPosition();
+    }
+
+    private int getPosition(){
+        if(renderState == null){
+            return  -1;
+        }
+        return renderState.position;
+    }
+
+    @Override
+    public String toString() {
+        return String.valueOf(getPosition());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/886d859a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
new file mode 100644
index 0000000..5466621
--- /dev/null
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/VirtualComponentLifecycle.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.taobao.weex.ui.component.list.template;
+
+
+/**
+ * Created by furture on 2018/2/1.
+ */
+
+public class VirtualComponentLifecycle {
+
+    /**
+     * lifecycle
+     * */
+    public static final  String LIFECYCLE = "lifecycle";
+
+
+    /**
+     * virtual component lifecycle
+     * */
+    public static final  String CREATE = "create";
+
+    public static final  String ATTACH = "attach";
+
+    public static final  String SYNSTATE = "syncState";
+
+    public static final  String DETACH = "detach";
+
+}


[7/7] incubator-weex git commit: Merge remote-tracking branch 'upstream/pr1019' into apache-master

Posted by mi...@apache.org.
Merge remote-tracking branch 'upstream/pr1019' into apache-master


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/7ab6e7b2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/7ab6e7b2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/7ab6e7b2

Branch: refs/heads/master
Commit: 7ab6e7b236ad78742df0fc0c986187fc8b183225
Parents: 6019278 d6af2aa
Author: misakuo <mi...@apache.org>
Authored: Thu Feb 8 16:56:56 2018 +0800
Committer: misakuo <mi...@apache.org>
Committed: Thu Feb 8 16:56:56 2018 +0800

----------------------------------------------------------------------
 .../weex/commons/adapter/ImageAdapter.java      |  49 +-
 .../java/com/alibaba/weex/WXApplication.java    |   6 +-
 .../weex/extend/module/WXWsonTestModule.java    |  58 ++
 .../java/com/taobao/weex/WXEnvironment.java     |  17 +-
 .../com/taobao/weex/bridge/WXBridgeManager.java | 112 +++-
 .../java/com/taobao/weex/common/Constants.java  |   7 +-
 .../main/java/com/taobao/weex/dom/WXAttr.java   |  19 +-
 .../java/com/taobao/weex/dom/WXDomModule.java   |   7 +-
 .../java/com/taobao/weex/dom/WXDomObject.java   |  29 +-
 .../main/java/com/taobao/weex/dom/WXEvent.java  |  91 +--
 .../main/java/com/taobao/weex/dom/WXStyle.java  |  54 ++
 .../dom/action/AbstractAddElementAction.java    |  15 +-
 .../com/taobao/weex/dom/action/Actions.java     |   6 +
 .../weex/dom/action/AddElementAction.java       |   8 +-
 .../weex/dom/action/UpdateAttributeAction.java  |   6 +-
 .../dom/action/UpdateComponentDataAction.java   |  69 +++
 .../com/taobao/weex/dom/binding/ELUtils.java    |   1 +
 .../taobao/weex/dom/binding/WXStatement.java    |   6 +
 .../java/com/taobao/weex/el/parse/Block.java    |   3 +-
 .../java/com/taobao/weex/el/parse/Operator.java |   3 +-
 .../com/taobao/weex/el/parse/Operators.java     |  11 +-
 .../java/com/taobao/weex/el/parse/Token.java    |   3 +-
 .../weex/ui/component/ComponentUtils.java       | 122 ++++
 .../taobao/weex/ui/component/WXComponent.java   | 110 +++-
 .../weex/ui/component/binding/Layouts.java      |  23 +-
 .../weex/ui/component/binding/Statements.java   | 226 +++++--
 .../taobao/weex/ui/component/list/WXCell.java   |  18 +-
 .../list/template/AsyncCellLoadTask.java        | 128 ++++
 .../list/template/CellDataManager.java          | 272 +++++++++
 .../list/template/CellRenderContext.java        |  79 +++
 .../list/template/CellRenderState.java          | 122 ++++
 .../component/list/template/DomTreeBuilder.java | 100 ---
 .../ui/component/list/template/PositionRef.java |  64 ++
 .../template/VirtualComponentLifecycle.java     |  45 ++
 .../list/template/WXRecyclerTemplateList.java   | 610 ++++++++++---------
 .../java/com/taobao/weex/el/FailedCaseTest.java |  50 ++
 .../ui/component/binding/StatementTest.java     |   8 +-
 37 files changed, 1970 insertions(+), 587 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/7ab6e7b2/android/sdk/src/main/java/com/taobao/weex/common/Constants.java
----------------------------------------------------------------------