adapt new protocol
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/26091f5b Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/26091f5b Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/26091f5b Branch: refs/heads/0.16-dev Commit: 26091f5b5be4ce8cf13d40bd66d0fd703ed64e06 Parents: 11b5b7f Author: jianbai.gbj <jianbai....@alibaba-inc.com> Authored: Mon Sep 18 22:05:28 2017 +0800 Committer: jianbai.gbj <jianbai....@alibaba-inc.com> Committed: Mon Sep 18 22:05:28 2017 +0800 ---------------------------------------------------------------------- .../java/com/taobao/weex/common/Constants.java | 4 +- .../main/java/com/taobao/weex/dom/WXAttr.java | 5 + .../com/taobao/weex/dom/binding/ELUtils.java | 19 +++- .../taobao/weex/dom/binding/WXStatement.java | 2 +- .../weex/ui/component/binding/Statements.java | 100 ++++++++++++++----- .../list/template/TemplateStickyHelper.java | 2 +- .../list/template/WXRecyclerTemplateList.java | 71 +++++++++++-- .../java/com/taobao/weex/el/ParserTest.java | 7 +- 8 files changed, 170 insertions(+), 40 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/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 6a96a08..1e1ad86 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 @@ -184,13 +184,15 @@ public class Constants { interface Recycler{ String LIST_DATA = "listData"; - String LIST_DATA_ITEM ="item"; + 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 CELL_INDEX = "cellIndex"; String TYPE_INDEX = "typeIndex"; + String APPEND = "append"; + String UPDATE_CELL = "updateCell"; } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/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 edf83b1..3434fe3 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 @@ -18,6 +18,7 @@ */ package com.taobao.weex.dom; +import static com.taobao.weex.dom.binding.ELUtils.COMPONENT_PROPS; import static java.lang.Boolean.parseBoolean; import android.support.annotation.NonNull; @@ -471,6 +472,10 @@ public class WXAttr implements Map<String, Object>,Cloneable { * filter dynamic attrs and statements * */ private boolean filterBindingStatement(String key, Object value) { + if(COMPONENT_PROPS.equals(key)){ + ELUtils.bindingBlock(value); + return false; + } if(ELUtils.isBinding(value)){ if(mBindingAttrs == null){ mBindingAttrs = new ArrayMap<String, Object>(); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/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 d4b9c9e..329fb99 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 @@ -25,6 +25,8 @@ import com.taobao.weex.el.parse.Block; import com.taobao.weex.el.parse.Parser; import com.taobao.weex.utils.WXLogUtils; +import java.util.Set; + /** * util's for binding and statment * Created by jianbai.gbj on 2017/8/17. @@ -32,8 +34,12 @@ import com.taobao.weex.utils.WXLogUtils; public class ELUtils { public static final String BINDING = "@binding"; + /** + * sub template + * */ + public static final String IS_COMPONENT_ROOT = "@isComponentRoot"; - public static final String SCOPE = "scope"; + public static final String COMPONENT_PROPS = "@componentProps"; /** * @param value check object is binding expression @@ -67,6 +73,17 @@ public class ELUtils { object.put(BINDING, Parser.parse(binding.toString())); } } + Set<String> keys = object.keySet(); + for(Object propsKey : keys){ + if(object.get(propsKey) instanceof JSONObject + && ((JSONObject)object.get(propsKey)).containsKey(BINDING)){ + JSONObject propsValue = (JSONObject) object.get(propsKey); + Object binding = propsValue.get(BINDING); + if(!(binding instanceof Block)){ + propsValue.put(BINDING, Parser.parse(binding.toString())); + } + } + } }else if(value instanceof JSONArray){ JSONArray array = (JSONArray) value; for(int i=0; i<array.size(); i++){ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/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 8b2dc8e..c11aaec 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 @@ -51,7 +51,7 @@ public class WXStatement implements Map<String, Object>,Cloneable { * */ public static final String WX_FOR = "[[repeat]]"; public static final String WX_FOR_INDEX = "@index"; - public static final String WX_FOR_ITEM = "@label"; + public static final String WX_FOR_ITEM = "@alias"; public static final String WX_FOR_LIST = "@expression"; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/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 5b5c730..bb75ea0 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 @@ -35,8 +35,10 @@ 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; +import com.taobao.weex.utils.WXUtils; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -133,15 +135,42 @@ public class Statements { if(listBlock != null) { data = listBlock.execute(context); } - if(data instanceof List - && !TextUtils.isEmpty(indexKey) - && !TextUtils.isEmpty(itemKey)){ - List list = (List) data; + if((data instanceof List || data instanceof Map)){ + + Collection collection = null; + Map map = null; + if(data instanceof List){ + collection = (List)data; + }else{ + map = (Map)data; + collection = map.keySet(); + } Map<String, Object> loop = new HashMap<>(); - context.push(loop); - for(int i=0; i<list.size(); i++){ - loop.put(indexKey, i); - loop.put(itemKey, list.get(i)); + int index = 0; + for(Object item : collection){ + Object key = null; + Object value = item; + if(map == null){ + key = index; + value = item; + }else{ + key = item; + value = map.get(item); + } + if(indexKey != null){ + loop.put(indexKey, key); + } + + if(itemKey != null){ + loop.put(itemKey, value); + }else{ + context.push(value); + } + if(loop.size() > 0){ + context.push(loop); + } + + if(vif != null){ if(!Operators.isTrue(vif.execute(context))){ continue; @@ -169,8 +198,13 @@ public class Statements { } doBindingAttrsEventAndRenderChildNode(renderNode, domObject, context); renderIndex++; + if(loop.size() > 0){ + context.push(loop); + } + if(itemKey == null) { + context.pop(); + } } - context.pop(); } //after v-for execute, remove component created pre v-for. for(;renderIndex<parent.getChildCount(); renderIndex++){ @@ -199,7 +233,19 @@ public class Statements { * bind attrs and doRender component child * */ private static void doBindingAttrsEventAndRenderChildNode(WXComponent component, WXDomObject domObject, ArrayStack context){ - int stackSize = context.size(); + WXAttr attr = component.getDomObject().getAttrs(); + /** + * sub component supported, sub component new 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); + } + } doRenderBindingAttrsAndEvent(component, domObject, context); if(component instanceof WXVContainer){ WXVContainer container = (WXVContainer) component; @@ -208,9 +254,6 @@ public class Statements { k += doRenderComponent(next, context); } } - while (context.size() > stackSize){ - context.pop(); - } } @@ -234,17 +277,6 @@ public class Statements { ArrayMap<String, Object> bindAttrs = domObject.getAttrs().getBindingAttrs(); Map<String, Object> dynamic = renderBindingAttrs(bindAttrs, context); Set<Map.Entry<String, Object>> entries = dynamic.entrySet(); - - /** - * scope supported - * */ - if(attr.get(ELUtils.SCOPE) != null){ - String alias = attr.get(ELUtils.SCOPE).toString(); - Map map = new ArrayMap(4); - map.put(alias, dynamic.get(alias)); - context.push(map); - } - /** * diff attrs, see attrs has update, remove none update attrs * */ @@ -325,6 +357,26 @@ public class Statements { return dynamic; } + + public static Map<String, Object> renderProps(JSONObject props, ArrayStack context){ + Set<Map.Entry<String, Object>> entrySet = props.entrySet(); + Map<String, Object> renderProps = new ArrayMap<>(4); + for(Map.Entry<String, Object> entry : entrySet){ + Object value = entry.getValue(); + String key = entry.getKey(); + if(value instanceof JSONObject + && (((JSONObject) value).get(ELUtils.BINDING) instanceof Block)){ + JSONObject binding = (JSONObject) value; + Block block = (Block) (binding.get(ELUtils.BINDING)); + Object blockValue = block.execute(context); + renderProps.put(key, blockValue); + }else{ + renderProps.put(key, value); + } + } + return renderProps; + } + public static List<Object> getBindingEventArgs(ArrayStack context, Object bindings){ List<Object> params = new ArrayList<>(4); if(bindings instanceof JSONArray){ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateStickyHelper.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateStickyHelper.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateStickyHelper.java index 8d228bc..328276f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateStickyHelper.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/TemplateStickyHelper.java @@ -32,7 +32,7 @@ import java.util.ArrayList; import java.util.List; /** - * mStickyHelper + * StickyHelper For Template List * Created by furture on 2017/8/24. */ public class TemplateStickyHelper { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/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 118007c..865754e 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 @@ -126,8 +126,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp private JSONArray listData; private String listDataKey = Constants.Name.Recycler.LIST_DATA; - private String listDataItemKey = Constants.Name.Recycler.LIST_DATA_ITEM; - private String listDataIndexKey = Constants.Name.Recycler.LIST_DATA_ITEM_INDEX; + private String listDataItemKey = null; + private String listDataIndexKey = null; private ArrayMap<String, Integer> mTemplateViewTypes; private Map<String, WXCell> mTemplates; private String listDataTemplateKey = Constants.Name.Recycler.SLOT_TEMPLATE_TYPE; @@ -422,8 +422,8 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp WXLogUtils.e("Float parseFloat error :"+e.getMessage()); } } - position = WXUtils.getNumberInt(options.get(Constants.Name.Recycler.CELL_INDEX), position); - typeIndex = WXUtils.getNumberInt(options.get(Constants.Name.Recycler.TYPE_INDEX), position); + position = WXUtils.getNumberInt(options.get(Constants.Name.Recycler.CELL_INDEX), -1); + typeIndex = WXUtils.getNumberInt(options.get(Constants.Name.Recycler.TYPE_INDEX), -1); } WXCell cell = findCell(component); if(typeIndex >= 0){ @@ -598,6 +598,14 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp setListData(param); } return true; + case Constants.Name.Recycler.APPEND:{ + append(param); + } + return true; + case Constants.Name.Recycler.UPDATE_CELL:{ + updateCell(param); + } + return true; case Constants.Name.Recycler.LIST_DATA_ITEM: listDataItemKey = WXUtils.getString(param, listDataItemKey); return true; @@ -720,6 +728,46 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp inner.setScrollable(scrollable); } + @WXComponentProp(name = Constants.Name.Recycler.APPEND) + public void append(Object arrayObject){ + if(listData == null){ + listData = new JSONArray(); + } + if(arrayObject instanceof JSONObject){ + listData.add(arrayObject); + } + if(arrayObject instanceof JSONArray){ + listData.addAll((JSONArray)arrayObject); + } + notifyUpdateList(); + } + + @WXComponentProp(name = Constants.Name.Recycler.UPDATE_CELL) + public void updateCell(Object data){ + if(!(data instanceof JSONObject)){ + return; + } + if(listData == null){ + return; + } + JSONObject cellData = (JSONObject)data; + if(cellData.get(Constants.Name.Recycler.LIST_DATA_ITEM) == null){ + return; + } + Integer cellIndex = cellData.getInteger(Constants.Name.Recycler.CELL_INDEX); + if(cellIndex == null){ + return; + } + if(cellIndex >= listData.size()){ + return; + } + listData.set(cellIndex, cellData.get(Constants.Name.Recycler.LIST_DATA_ITEM)); + if(getHostView() != null && getHostView().getRecyclerViewBaseAdapter() != null){ + getHostView().getRecyclerViewBaseAdapter().notifyItemChanged(cellIndex); + } + } + + @Override public void updateProperties(Map<String, Object> props) { super.updateProperties(props); @@ -936,7 +984,6 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp @Override public TemplateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - long start = System.currentTimeMillis(); String template = mTemplateViewTypes.keyAt(viewType); WXCell source = mTemplates.get(template); if(source == null){ @@ -951,6 +998,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp domObject.setRecyclerDomObject((WXRecyclerDomObject) getDomObject()); } component.lazy(false); + long start = System.currentTimeMillis(); component.createView(); if(WXEnvironment.isApkDebugable()){ WXLogUtils.d(TAG, template + " onCreateViewHolder view used " + (System.currentTimeMillis() - start)); @@ -996,11 +1044,16 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp if(listData != null){ stack.push(listData); stack.push(map); - Object item = listData.get(position); - stack.push(item); - map.put(listDataIndexKey, position); - map.put(listDataItemKey, item); map.put(listDataKey, listData); + Object item = listData.get(position); + if(!TextUtils.isEmpty(listDataIndexKey)) { + map.put(listDataIndexKey, position); + } + if(!TextUtils.isEmpty(listDataItemKey)) { + map.put(listDataItemKey, item); + }else{ + stack.push(item); + } } return stack; } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/26091f5b/android/sdk/src/test/java/com/taobao/weex/el/ParserTest.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/test/java/com/taobao/weex/el/ParserTest.java b/android/sdk/src/test/java/com/taobao/weex/el/ParserTest.java index 8a6fd7e..08f2dcf 100644 --- a/android/sdk/src/test/java/com/taobao/weex/el/ParserTest.java +++ b/android/sdk/src/test/java/com/taobao/weex/el/ParserTest.java @@ -170,9 +170,10 @@ public class ParserTest extends TestCase { System.out.println(block.getTokens().size()); - int count = 10; - for (int i = 0; i < count; ++i) { - System.out.println("i=" + i); + + String[] values = {null, null}; + for (Object value : values) { + System.out.println(value + "ddd"); } }