You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ky...@apache.org on 2018/04/28 06:53:43 UTC

[15/48] incubator-weex git commit: * [android] Merge WeexCore-master to master.

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_move_element.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_move_element.h b/weex_core/Source/core/render/action/render_action_move_element.h
new file mode 100644
index 0000000..d365333
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_move_element.h
@@ -0,0 +1,24 @@
+#ifndef WEEX_PROJECT_RENDERACTIONMOVEELEMENT_H
+#define WEEX_PROJECT_RENDERACTIONMOVEELEMENT_H
+
+#include "render_action.h"
+
+namespace WeexCore {
+
+  class RenderActionMoveElement : public render_action {
+
+  public:
+    RenderActionMoveElement(const std::string &pageId, const std::string &ref,
+                            const std::string &parentRef, int index);
+
+    void ExecuteAction();
+
+  public:
+    std::string mPageId;
+    std::string mRef;
+    std::string mParentRef;
+    int mIndex;
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERACTIONMOVEELEMENT_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_remove_element.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_remove_element.cpp b/weex_core/Source/core/render/action/render_action_remove_element.cpp
new file mode 100644
index 0000000..be1663b
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_remove_element.cpp
@@ -0,0 +1,19 @@
+#include "render_action_remove_element.h"
+
+namespace WeexCore {
+
+  RenderActionRemoveElement::RenderActionRemoveElement(const std::string &pageId, const std::string &ref) {
+    this->mPageId = pageId;
+    this->mRef = ref;
+  }
+
+  void RenderActionRemoveElement::ExecuteAction() {
+    RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId);
+    if (page == nullptr)
+      return;
+
+    long long startTime = getCurrentTime();
+    Bridge_Impl_Android::getInstance()->callRemoveElement(mPageId.c_str(), mRef.c_str());
+    page->JniCallTime(getCurrentTime() - startTime);
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_remove_element.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_remove_element.h b/weex_core/Source/core/render/action/render_action_remove_element.h
new file mode 100644
index 0000000..eeaf4e2
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_remove_element.h
@@ -0,0 +1,20 @@
+#ifndef WEEX_PROJECT_RENDERACTIONREMOVEELEMENT_H
+#define WEEX_PROJECT_RENDERACTIONREMOVEELEMENT_H
+
+#include "render_action.h"
+
+namespace WeexCore {
+
+  class RenderActionRemoveElement : public render_action {
+  public:
+    RenderActionRemoveElement(const std::string &pageId, const std::string &ref);
+
+    void ExecuteAction();
+
+  public:
+    std::string mPageId;
+    std::string mRef;
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERACTIONREMOVEELEMENT_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_remove_event.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_remove_event.cpp b/weex_core/Source/core/render/action/render_action_remove_event.cpp
new file mode 100644
index 0000000..fdff2f5
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_remove_event.cpp
@@ -0,0 +1,24 @@
+#include "render_action_remove_event.h"
+
+namespace WeexCore {
+
+  RenderActionRemoveEvent::RenderActionRemoveEvent(const std::string &pageId, const std::string &ref, const std::string &event) {
+    this->mPageId = pageId;
+    this->mRef = ref;
+    this->mEvent = event;
+  }
+
+  void RenderActionRemoveEvent::ExecuteAction() {
+    RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId);
+    if (page == nullptr)
+      return;
+
+    long long startTime = getCurrentTime();
+
+    Bridge_Impl_Android::getInstance()->callRemoveEvent(mPageId.c_str(), mRef.c_str(), mEvent.c_str());
+
+    page->JniCallTime(getCurrentTime() - startTime);
+    page->RemoveEventActionJNITime(getCurrentTime() - startTime);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_remove_event.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_remove_event.h b/weex_core/Source/core/render/action/render_action_remove_event.h
new file mode 100644
index 0000000..8cc8c92
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_remove_event.h
@@ -0,0 +1,22 @@
+#ifndef WEEX_PROJECT_REMOVEEVENTACTION_H
+#define WEEX_PROJECT_REMOVEEVENTACTION_H
+
+#include "render_action.h"
+
+namespace WeexCore {
+
+  class RenderActionRemoveEvent : public render_action {
+
+  public:
+      RenderActionRemoveEvent(const std::string &pageId, const std::string &ref, const std::string &event);
+
+    void ExecuteAction();
+
+  public:
+    std::string mPageId;
+    std::string mRef;
+    std::string mEvent;
+  };
+}
+
+#endif //WEEX_PROJECT_REMOVEEVENTACTION_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_update_attr.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_update_attr.cpp b/weex_core/Source/core/render/action/render_action_update_attr.cpp
new file mode 100644
index 0000000..663bc31
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_update_attr.cpp
@@ -0,0 +1,22 @@
+#include "render_action_update_attr.h"
+
+namespace WeexCore {
+
+  RenderActionUpdateAttr::RenderActionUpdateAttr(const std::string &pageId, const std::string &ref,
+                                                 std::vector<std::pair<std::string, std::string>> *mAttrs) {
+    this->mPageId = pageId;
+    this->mRef = ref;
+    this->mAttrs = mAttrs;
+  }
+
+  void RenderActionUpdateAttr::ExecuteAction() {
+    RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId);
+    if (page == nullptr)
+      return;
+
+    long long startTime = getCurrentTime();
+    Bridge_Impl_Android::getInstance()->callUpdateAttr(mPageId.c_str(), mRef.c_str(), mAttrs);
+    if (page != nullptr)
+      page->JniCallTime(getCurrentTime() - startTime);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_update_attr.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_update_attr.h b/weex_core/Source/core/render/action/render_action_update_attr.h
new file mode 100644
index 0000000..ca0a1cf
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_update_attr.h
@@ -0,0 +1,23 @@
+#ifndef WEEX_PROJECT_UPDATEATTRACTION_H
+#define WEEX_PROJECT_UPDATEATTRACTION_H
+
+#include "render_action.h"
+
+namespace WeexCore {
+
+  class RenderActionUpdateAttr : public render_action {
+
+  public:
+    RenderActionUpdateAttr(const std::string &pageId, const std::string &ref,
+                           std::vector<std::pair<std::string, std::string>> *mAttrs);
+
+    void ExecuteAction();
+
+  public:
+    std::string mPageId;
+    std::string mRef;
+    std::vector<std::pair<std::string, std::string>> *mAttrs;
+  };
+}
+
+#endif //WEEX_PROJECT_UPDATEATTRACTION_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_update_style.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_update_style.cpp b/weex_core/Source/core/render/action/render_action_update_style.cpp
new file mode 100644
index 0000000..6e719bf
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_update_style.cpp
@@ -0,0 +1,29 @@
+#include "render_action_update_style.h"
+
+namespace WeexCore {
+
+  RenderActionUpdateStyle::RenderActionUpdateStyle(const std::string &pageId, const std::string &ref,
+                                                   std::vector<std::pair<std::string, std::string>> *style,
+                                                   std::vector<std::pair<std::string, std::string>> *margin,
+                                                   std::vector<std::pair<std::string, std::string>> *padding,
+                                                   std::vector<std::pair<std::string, std::string>> *border) {
+    this->mPageId = pageId;
+    this->mRef = ref;
+    this->mStyle = style;
+    this->mMargin = margin;
+    this->mPadding = padding;
+    this->mBorder = border;
+  }
+
+  void RenderActionUpdateStyle::ExecuteAction() {
+    RenderPage *page = RenderManager::GetInstance()->GetPage(mPageId);
+    if (page == nullptr)
+      return;
+
+    long long startTime = getCurrentTime();
+    Bridge_Impl_Android::getInstance()->callUpdateStyle(mPageId.c_str(), mRef.c_str(), mStyle, mMargin,
+                                                        mPadding, mBorder);
+    if (page != nullptr)
+      page->JniCallTime(getCurrentTime() - startTime);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/action/render_action_update_style.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/action/render_action_update_style.h b/weex_core/Source/core/render/action/render_action_update_style.h
new file mode 100644
index 0000000..dc40e61
--- /dev/null
+++ b/weex_core/Source/core/render/action/render_action_update_style.h
@@ -0,0 +1,30 @@
+#ifndef WEEX_PROJECT_UPDATESTYLEACTION_H
+#define WEEX_PROJECT_UPDATESTYLEACTION_H
+
+#include "render_action.h"
+
+namespace WeexCore {
+
+  class RenderActionUpdateStyle : public render_action {
+
+  public:
+
+    RenderActionUpdateStyle(const std::string &pageId, const std::string &ref,
+                            std::vector<std::pair<std::string, std::string>> *style,
+                            std::vector<std::pair<std::string, std::string>> *margin,
+                            std::vector<std::pair<std::string, std::string>> *padding,
+                            std::vector<std::pair<std::string, std::string>> *border);
+
+    void ExecuteAction();
+
+  public:
+    std::string mPageId;
+    std::string mRef;
+    std::vector<std::pair<std::string, std::string>> *mStyle;
+    std::vector<std::pair<std::string, std::string>> *mMargin;
+    std::vector<std::pair<std::string, std::string>> *mPadding;
+    std::vector<std::pair<std::string, std::string>> *mBorder;
+  };
+}
+
+#endif //WEEX_PROJECT_UPDATESTYLEACTION_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/manager/render_manager.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/manager/render_manager.cpp b/weex_core/Source/core/render/manager/render_manager.cpp
new file mode 100644
index 0000000..8b7de8b
--- /dev/null
+++ b/weex_core/Source/core/render/manager/render_manager.cpp
@@ -0,0 +1,196 @@
+#include <core/parser/dom_parser.h>
+#include <core/render/manager/render_manager.h>
+#include <core/render/page/render_page.h>
+#include <core/render/node/render_object.h>
+#include <base/TimeUtils.h>
+
+namespace WeexCore {
+
+  RenderManager *RenderManager::m_pInstance = nullptr;
+
+  bool RenderManager::CreatePage(std::string pageId, const std::string &data) {
+
+#if RENDER_LOG
+    LOGD("[RenderManager] CreatePage >>>> pageId: %s, dom data: %s", pageId.c_str(), data.c_str());
+#endif
+
+    RenderPage *page = new RenderPage(pageId);
+    mPages.insert(std::pair<std::string, RenderPage *>(pageId, page));
+    long long startTime = getCurrentTime();
+    char *c_data = (char *) data.data();
+    RenderObject *root = Json2RenderObject(c_data, pageId);
+    page->updateDirty(true);
+    page->ParseJsonTime(getCurrentTime() - startTime);
+    page->BuildRenderTreeTime(getCurrentTime() - startTime);
+    return page->CreateRootRender(root);
+  }
+
+  bool RenderManager::AddRenderObject(const std::string &pageId, const std::string &parentRef,
+                                      int index, const std::string &data) {
+
+    RenderPage *page = GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] AddRenderObject >>>> pageId: %s, parentRef: %s, index: %d, dom data: %s",
+         pageId.c_str(), parentRef.c_str(), index, data.c_str());
+#endif
+
+    long long startTime = getCurrentTime();
+    char *c_data = (char *) data.data();
+    RenderObject *child = Json2RenderObject(c_data, pageId);
+    page->ParseJsonTime(getCurrentTime() - startTime);
+    page->BuildRenderTreeTime(getCurrentTime() - startTime);
+    if (child == nullptr)
+      return false;
+
+    page->updateDirty(true);
+    return page->AddRenderObject(parentRef, index, child);
+  }
+
+  bool RenderManager::RemoveRenderObject(const std::string &pageId, const std::string &ref) {
+
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] RemoveRenderObject >>>> pageId: %s, ref: %s", pageId.c_str(),
+         ref.c_str());
+#endif
+
+    page->updateDirty(true);
+    return page->RemoveRenderObject(ref);
+  }
+
+  bool RenderManager::MoveRenderObject(const std::string &pageId, const std::string &ref,
+                                       const std::string &parentRef, int index) {
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] MoveRenderObject >>>> pageId: %s, ref: %s, parentRef: %s, index: %d",
+         pageId.c_str(), ref.c_str(), parentRef.c_str(), index);
+#endif
+
+    page->updateDirty(true);
+    return page->MoveRenderObject(ref, parentRef, index);
+  }
+
+  bool RenderManager::UpdateAttr(const std::string &pageId, const std::string &ref,
+                                 const std::string &data) {
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] UpdateAttr >>>> pageId: %s, ref: %s, data: %s",
+         pageId.c_str(), ref.c_str(), data.c_str());
+#endif
+
+    long long startTime = getCurrentTime();
+    char *c_data = (char *) data.data();
+    std::vector<std::pair<std::string, std::string>> *attrs = Json2Pairs(c_data);
+    page->updateDirty(true);
+    page->ParseJsonTime(getCurrentTime() - startTime);
+    page->BuildRenderTreeTime(getCurrentTime() - startTime);
+    return page->UpdateAttr(ref, attrs);
+  }
+
+  bool RenderManager::UpdateStyle(const std::string &pageId, const std::string &ref,
+                                  const std::string &data) {
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] UpdateStyle >>>> pageId: %s, ref: %s, data: %s",
+         pageId.c_str(), ref.c_str(), data.c_str());
+#endif
+
+    long long startTime = getCurrentTime();
+    char *c_data = (char *) data.data();
+    std::vector<std::pair<std::string, std::string>> *styles = Json2Pairs(c_data);
+    page->updateDirty(true);
+    page->ParseJsonTime(getCurrentTime() - startTime);
+    page->BuildRenderTreeTime(getCurrentTime() - startTime);
+    return page->UpdateStyle(ref, styles);
+  }
+
+  bool RenderManager::AddEvent(const std::string &pageId, const std::string &ref,
+                               const std::string &event) {
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] AddEvent >>>> pageId: %s, ref: %s, event: %s",
+         pageId.c_str(), ref.c_str(), event.c_str());
+#endif
+
+    page->updateDirty(true);
+    return page->AddEvent(ref, event);
+  }
+
+  bool RenderManager::RemoveEvent(const std::string &pageId, const std::string &ref,
+                                  const std::string &event) {
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] RemoveEvent >>>> pageId: %s, ref: %s, event: %s",
+         pageId.c_str(), ref.c_str(), event.c_str());
+#endif
+
+    page->updateDirty(true);
+    return page->RemoveEvent(ref, event);
+  }
+
+  bool RenderManager::CreateFinish(const std::string &pageId) {
+    RenderPage *page = GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] CreateFinish >>>> pageId: %s", pageId.c_str());
+#endif
+
+    page->updateDirty(true);
+    return page->CreateFinish();
+  }
+
+  RenderPage *RenderManager::GetPage(const std::string &id) {
+    std::map<std::string, RenderPage *>::iterator iter = mPages.find(id);
+    if (iter != mPages.end()) {
+      return iter->second;
+    } else {
+      return nullptr;
+    }
+  }
+
+  bool RenderManager::ClosePage(const std::string &pageId) {
+    RenderPage *page = GetPage(pageId);
+    if (page == nullptr)
+      return false;
+
+#if RENDER_LOG
+    LOGD("[RenderManager] ClosePage >>>> pageId: %s", pageId.c_str());
+#endif
+
+    mPages.erase(pageId);
+    delete page;
+    page = nullptr;
+  }
+
+  void RenderManager::Batch(const std::string &pageId) {
+    RenderPage *page = this->GetPage(pageId);
+    if (page == nullptr)
+      return;
+
+    page->Batch();
+  }
+
+} //namespace WeexCore

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/manager/render_manager.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/manager/render_manager.h b/weex_core/Source/core/render/manager/render_manager.h
new file mode 100644
index 0000000..35a014a
--- /dev/null
+++ b/weex_core/Source/core/render/manager/render_manager.h
@@ -0,0 +1,73 @@
+#ifndef RenderManager_h
+#define RenderManager_h
+
+#include <map>
+#include <string>
+
+namespace WeexCore {
+
+  class RenderPage;
+
+  class RenderManager {
+
+  private:
+    RenderManager() {}
+
+    ~RenderManager() {}
+
+    //just to release singleton object
+    class Garbo {
+    public:
+      ~Garbo() {
+        if (RenderManager::m_pInstance) {
+          delete RenderManager::m_pInstance;
+        }
+      }
+    };
+
+    static Garbo garbo;
+
+  public:
+
+    void Batch(const std::string &pageId);
+
+    // create root node
+    bool CreatePage(std::string pageId, const std::string &data);
+
+    bool AddRenderObject(const std::string &pageId, const std::string &parentRef, int index,
+                         const std::string &data);
+
+    bool RemoveRenderObject(const std::string &pageId, const std::string &ref);
+
+    bool
+    MoveRenderObject(const std::string &pageId, const std::string &ref,
+                     const std::string &parentRef, int index);
+
+    bool UpdateAttr(const std::string &pageId, const std::string &ref, const std::string &data);
+
+    bool UpdateStyle(const std::string &pageId, const std::string &ref, const std::string &data);
+
+    bool AddEvent(const std::string &pageId, const std::string &ref, const std::string &event);
+
+    bool RemoveEvent(const std::string &pageId, const std::string &ref, const std::string &event);
+
+    bool CreateFinish(const std::string &pageId);
+
+    RenderPage *GetPage(const std::string &id);
+
+    bool ClosePage(const std::string &pageId);
+
+    static RenderManager *GetInstance() {
+      if (!m_pInstance) {
+        m_pInstance = new RenderManager();
+      }
+      return m_pInstance;
+    }
+
+  private:
+    static RenderManager *m_pInstance;
+    std::map<std::string, RenderPage *> mPages;
+  };
+}
+
+#endif //RenderManager_h
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/i_render_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/i_render_factory.h b/weex_core/Source/core/render/node/factory/i_render_factory.h
new file mode 100644
index 0000000..7228c33
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/i_render_factory.h
@@ -0,0 +1,13 @@
+#ifndef WEEX_PROJECT_IRENDERFACTORY_H
+#define WEEX_PROJECT_IRENDERFACTORY_H
+
+#include "i_render_object.h"
+
+namespace WeexCore {
+  class IRenderFactory {
+  public:
+    virtual IRenderObject *CreateRender() = 0;
+  };
+}
+
+#endif //WEEX_PROJECT_IRENDERFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/i_render_object.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/i_render_object.h b/weex_core/Source/core/render/node/factory/i_render_object.h
new file mode 100644
index 0000000..f6bdcb8
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/i_render_object.h
@@ -0,0 +1,42 @@
+#ifndef WEEX_PROJECT_IRENDEROBJECT_H
+#define WEEX_PROJECT_IRENDEROBJECT_H
+
+#include <string>
+#include <core/layout/layout.h>
+
+namespace WeexCore {
+
+  class IRenderObject : public WXCoreLayoutNode {
+  public:
+    inline void SetRef(std::string ref) {
+      mRef = ref;
+    }
+
+    inline const std::string &Ref() const {
+      return mRef;
+    }
+
+    inline void SetPageId(std::string pageId) {
+      this->mPageId = pageId;
+    }
+
+    inline const std::string &PageId() const {
+      return mPageId;
+    }
+
+    inline void SetType(std::string type) {
+      mType = type;
+    }
+
+    inline const std::string &Type() const {
+      return mType;
+    }
+
+  private:
+    std::string mPageId = "";
+    std::string mRef = "";
+    std::string mType = "";
+  };
+}
+
+#endif //WEEX_PROJECT_IRENDEROBJECT_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_appbar_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_appbar_factory.h b/weex_core/Source/core/render/node/factory/render_appbar_factory.h
new file mode 100644
index 0000000..d1d1865
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_appbar_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERAPPBARFACTORY_H
+#define WEEX_PROJECT_RENDERAPPBARFACTORY_H
+
+#include <core/render/node/render_appbar.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderAppBarFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderAppBar();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERAPPBARFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_cell_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_cell_factory.h b/weex_core/Source/core/render/node/factory/render_cell_factory.h
new file mode 100644
index 0000000..f3bfe99
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_cell_factory.h
@@ -0,0 +1,17 @@
+#ifndef WEEX_PROJECT_RENDERCELLFACTORY_H
+#define WEEX_PROJECT_RENDERCELLFACTORY_H
+
+#include <core/render/node/render_cell.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderCellFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderCell();
+    }
+  };
+
+}
+#endif //WEEX_PROJECT_RENDERCELLFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_creator.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_creator.cpp b/weex_core/Source/core/render/node/factory/render_creator.cpp
new file mode 100644
index 0000000..849a539
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_creator.cpp
@@ -0,0 +1,53 @@
+#include "render_creator.h"
+#include "i_render_object.h"
+#include "i_render_factory.h"
+#include "render_text_factory.h"
+#include "simple_render_factory.h"
+#include "render_cell_factory.h"
+#include "render_type.h"
+#include "render_indicator_factory.h"
+#include "render_input_factory.h"
+#include "render_list_factory.h"
+#include "render_mask_factory.h"
+#include "render_scroller_factory.h"
+#include "render_switch_factory.h"
+#include "render_textarea_factory.h"
+#include "render_appbar_factory.h"
+
+namespace WeexCore {
+
+  RenderCreator *RenderCreator::m_pInstance = nullptr;
+
+  IRenderObject *RenderCreator::CreateRender(const std::string &type, const std::string &ref) {
+    IRenderFactory *factory;
+    if (type == kRenderText) {
+      factory = new RenderTextFactory();
+    } else if (type == kRenderCell || type == kRenderHeader) {
+      factory = new RenderCellFactory();
+    } else if (type == kRenderIndicator) {
+      factory = new RenderIndicatorFactory();
+    } else if (type == kRenderInput) {
+      factory = new RenderInputFactory();
+    } else if (type == kRenderList || type == kRenderWaterfall) {
+      factory = new RenderListFactory();
+    } else if (type == kRenderMask) {
+      factory = new RenderMaskFactory();
+    } else if (type == kRenderScroller) {
+      factory = new RenderScrollerFactory();
+    } else if (type == kRenderSwitch) {
+      factory = new RenderSwitchFactory();
+    } else if (type == kRenderTextArea) {
+      factory = new RenderTextAreaFactory();
+    } else if (type == kRenderAppBar) {
+      factory = new RenderAppBarFactory();
+    } else {
+      factory = new RenderCommonFactory();
+    }
+
+    IRenderObject *render = factory->CreateRender();
+    render->SetRef(ref);
+    render->SetType(type);
+    delete factory;
+    return render;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_creator.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_creator.h b/weex_core/Source/core/render/node/factory/render_creator.h
new file mode 100644
index 0000000..068ce60
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_creator.h
@@ -0,0 +1,45 @@
+#ifndef WEEX_PROJECT_RENDERCREATOR_H
+#define WEEX_PROJECT_RENDERCREATOR_H
+
+#include <string>
+
+namespace WeexCore {
+
+  class IRenderObject;
+
+  class RenderCreator {
+
+  private:
+    RenderCreator() {}
+
+    ~RenderCreator() {}
+
+    //just to release singleton object
+    class Garbo {
+    public:
+      ~Garbo() {
+        if (RenderCreator::m_pInstance) {
+          delete RenderCreator::m_pInstance;
+        }
+      }
+    };
+
+    static Garbo garbo;
+
+  public:
+
+    static RenderCreator *GetInstance() {
+      if (!m_pInstance) {
+        m_pInstance = new RenderCreator();
+      }
+      return m_pInstance;
+    }
+
+    IRenderObject *CreateRender(const std::string &type, const std::string &ref);
+
+  private:
+    static RenderCreator *m_pInstance;
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERCREATOR_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_indicator_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_indicator_factory.h b/weex_core/Source/core/render/node/factory/render_indicator_factory.h
new file mode 100644
index 0000000..8679ddf
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_indicator_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERINDICATORFACTORY_H
+#define WEEX_PROJECT_RENDERINDICATORFACTORY_H
+
+#include <core/render/node/render_indicator.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderIndicatorFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderIndicator();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERINDICATORFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_input_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_input_factory.h b/weex_core/Source/core/render/node/factory/render_input_factory.h
new file mode 100644
index 0000000..2a33f75
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_input_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERINPUTFACTORY_H
+#define WEEX_PROJECT_RENDERINPUTFACTORY_H
+
+#include <core/render/node/render_input.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderInputFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderInput();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERINPUTFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_list_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_list_factory.h b/weex_core/Source/core/render/node/factory/render_list_factory.h
new file mode 100644
index 0000000..f3cae57
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_list_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERLISTFACTORY_H
+#define WEEX_PROJECT_RENDERLISTFACTORY_H
+
+#include <core/render/node/render_list.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderListFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderList();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERLISTFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_mask_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_mask_factory.h b/weex_core/Source/core/render/node/factory/render_mask_factory.h
new file mode 100644
index 0000000..a000848
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_mask_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERMASKFACTORY_H
+#define WEEX_PROJECT_RENDERMASKFACTORY_H
+
+#include <core/render/node/render_mask.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderMaskFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderMask();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERMASKFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_scroller_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_scroller_factory.h b/weex_core/Source/core/render/node/factory/render_scroller_factory.h
new file mode 100644
index 0000000..cfa909c
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_scroller_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERSCROLLERFACTORY_H
+#define WEEX_PROJECT_RENDERSCROLLERFACTORY_H
+
+#include <core/render/node/render_scroller.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderScrollerFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderScroller();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERSCROLLERFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_switch_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_switch_factory.h b/weex_core/Source/core/render/node/factory/render_switch_factory.h
new file mode 100644
index 0000000..4babee8
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_switch_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERSWITCHFACTORY_H
+#define WEEX_PROJECT_RENDERSWITCHFACTORY_H
+
+#include <core/render/node/render_switch.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderSwitchFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderSwitch();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERSWITCHFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_text_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_text_factory.h b/weex_core/Source/core/render/node/factory/render_text_factory.h
new file mode 100644
index 0000000..04c3277
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_text_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERTEXTFACTORY_H
+#define WEEX_PROJECT_RENDERTEXTFACTORY_H
+
+#include <core/render/node/render_text.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderTextFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderText();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERTEXTFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_textarea_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_textarea_factory.h b/weex_core/Source/core/render/node/factory/render_textarea_factory.h
new file mode 100644
index 0000000..01cbedd
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_textarea_factory.h
@@ -0,0 +1,18 @@
+#ifndef WEEX_PROJECT_RENDERTEXTAREAFACTORY_H
+#define WEEX_PROJECT_RENDERTEXTAREAFACTORY_H
+
+#include <core/render/node/render_textarea.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderTextAreaFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderTextArea();
+    }
+  };
+
+}
+
+#endif //WEEX_PROJECT_RENDERTEXTAREAFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/render_type.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/render_type.h b/weex_core/Source/core/render/node/factory/render_type.h
new file mode 100644
index 0000000..3c57a49
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/render_type.h
@@ -0,0 +1,23 @@
+#ifndef WEEX_PROJECT_RENDERTYPE_H
+#define WEEX_PROJECT_RENDERTYPE_H
+
+#include <string>
+
+namespace WeexCore {
+  constexpr char kRenderCell[] = "cell";
+  constexpr char kRenderIndicator[] = "indicator";
+  constexpr char kRenderInput[] = "input";
+  constexpr char kRenderList[] = "list";
+  constexpr char kHList[] = "hlist";
+  constexpr char kRenderMask[] = "mask";
+  constexpr char kRenderScroller[] = "scroller";
+  constexpr char kRenderSwitch[] = "switch";
+  constexpr char kRenderText[] = "text";
+  constexpr char kRenderTextArea[] = "textarea";
+  constexpr char kRenderHeader[] = "header";
+  constexpr char kRenderFooter[] = "footer";
+  constexpr char kRenderWaterfall[] = "waterfall";
+  constexpr char kRenderAppBar[] = "appbar";
+}
+
+#endif //WEEX_PROJECT_RENDERTYPE_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/factory/simple_render_factory.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/factory/simple_render_factory.h b/weex_core/Source/core/render/node/factory/simple_render_factory.h
new file mode 100644
index 0000000..9cfb36b
--- /dev/null
+++ b/weex_core/Source/core/render/node/factory/simple_render_factory.h
@@ -0,0 +1,19 @@
+#ifndef WEEX_PROJECT_RENDERCOMMONFACTORY_H
+#define WEEX_PROJECT_RENDERCOMMONFACTORY_H
+
+#include <core/render/node/render_object.h>
+#include "i_render_factory.h"
+
+namespace WeexCore {
+
+  class RenderCommonFactory : public IRenderFactory {
+  public:
+    IRenderObject *CreateRender() {
+      return new RenderObject();
+    }
+  };
+
+}
+
+
+#endif //WEEX_PROJECT_RENDERCOMMONFACTORY_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_appbar.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_appbar.h b/weex_core/Source/core/render/node/render_appbar.h
new file mode 100644
index 0000000..f724dfd
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_appbar.h
@@ -0,0 +1,68 @@
+#ifndef WEEX_PROJECT_RENDERAPPBAR_H
+#define WEEX_PROJECT_RENDERAPPBAR_H
+
+#include <core/render/node/render_object.h>
+#include <string>
+#include <android/base/string/string_utils.h>
+
+namespace WeexCore {
+  class RenderAppBar : public RenderObject {
+
+  private:
+    float defaultNavWidth;
+    float defaultOverflowWidth;
+
+    std::map<std::string, std::string> *GetDefaultStyle() {
+      defaultNavWidth = getFloat(WXCoreEnvironment::getInstance()->GetOption("defaultNavWidth").c_str());
+
+      defaultOverflowWidth = getFloat(WXCoreEnvironment::getInstance()->GetOption("defaultOverflowWidth").c_str());
+
+      std::string appbar_color = WXCoreEnvironment::getInstance()->GetOption("appbar_color");
+      std::string appbar_background_color = WXCoreEnvironment::getInstance()->GetOption(
+          "appbar_background_color");
+
+      std::map<std::string, std::string> *style = new std::map<std::string, std::string>();
+      style->insert(std::pair<std::string, std::string>(PADDING_LEFT, "0"));
+      style->insert(std::pair<std::string, std::string>(PADDING_RIGHT, "0"));
+
+      if (!appbar_color.empty() && appbar_color != "")
+        style->insert(std::pair<std::string, std::string>(COLOR, appbar_color));
+      if (!appbar_background_color.empty() && appbar_background_color != "")
+        style->insert(std::pair<std::string, std::string>(BACKGROUND_COLOR, appbar_background_color));
+      return style;
+    }
+
+  public:
+
+    StyleType ApplyStyle(const std::string &key, const std::string &value, const bool updating) {
+      if (key == PADDING) {
+        UpdateStyle(key,
+                    value,
+                    0,
+                    [=](float foo) {
+                      setPadding(kPaddingLeft, foo + defaultNavWidth),
+                          setPadding(kPaddingRight, foo + defaultOverflowWidth),
+                          setPadding(kPaddingTop, foo),
+                          setPadding(kPaddingBottom, foo);
+                    });
+        return kTypePadding;
+      } else if (key == PADDING_LEFT) {
+        UpdateStyle(key,
+                    value,
+                    0,
+                    [=](float foo) { setPadding(kPaddingLeft, foo + defaultNavWidth); });
+        return kTypePadding;
+      } else if (key == PADDING_RIGHT) {
+        UpdateStyle(key,
+                    value,
+                    0,
+                    [=](float foo) { setPadding(kPaddingRight, foo + defaultOverflowWidth); });
+        return kTypePadding;
+      } else {
+        return RenderObject::ApplyStyle(key, value, updating);
+      }
+    }
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERAPPBAR_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_cell.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_cell.h b/weex_core/Source/core/render/node/render_cell.h
new file mode 100644
index 0000000..c46d8a7
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_cell.h
@@ -0,0 +1,12 @@
+#ifndef WEEX_PROJECT_RENDERCELL_H
+#define WEEX_PROJECT_RENDERCELL_H
+
+#include <core/render/node/render_object.h>
+
+namespace WeexCore {
+  class RenderCell : public RenderObject {
+
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERCELL_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_indicator.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_indicator.h b/weex_core/Source/core/render/node/render_indicator.h
new file mode 100644
index 0000000..b8733ad
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_indicator.h
@@ -0,0 +1,12 @@
+#ifndef WEEX_PROJECT_RENDERINDICATOR_H
+#define WEEX_PROJECT_RENDERINDICATOR_H
+
+#include <core/render/node/render_object.h>
+
+namespace WeexCore {
+  class RenderIndicator : public RenderObject {
+
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERINDICATOR_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_input.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_input.h b/weex_core/Source/core/render/node/render_input.h
new file mode 100644
index 0000000..fcdb1fd
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_input.h
@@ -0,0 +1,12 @@
+#ifndef WEEX_PROJECT_BASICRENDEREDITTEXT_H
+#define WEEX_PROJECT_BASICRENDEREDITTEXT_H
+
+#include <core/render/node/render_object.h>
+
+namespace WeexCore {
+  class RenderInput : public RenderObject {
+
+  };
+}
+
+#endif //WEEX_PROJECT_BASICRENDEREDITTEXT_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_list.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_list.h b/weex_core/Source/core/render/node/render_list.h
new file mode 100644
index 0000000..6634236
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_list.h
@@ -0,0 +1,217 @@
+#ifndef WEEX_PROJECT_RENDERLIST_H
+#define WEEX_PROJECT_RENDERLIST_H
+
+#include <core/css/constants_name.h>
+#include <core/render/node/render_object.h>
+#include <core/css/constants_value.h>
+#include <android/base/log_utils.h>
+#include <cmath>
+#include <base/ViewUtils.h>
+#include <core/render/node/factory/render_type.h>
+#include "render_object.h"
+
+namespace WeexCore {
+
+  class RenderList : public RenderObject {
+
+    bool mIsPreCalculateCellWidth = false;
+    int mColumnCount = COLUMN_COUNT_NORMAL;
+    float mColumnWidth = AUTO_VALUE;
+    float mAvailableWidth = 0;
+    float mColumnGap = COLUMN_GAP_NORMAL;
+    bool mIsSetFlex = false;
+
+    std::map<std::string, std::string> *GetDefaultStyle() {
+      std::map<std::string, std::string> *style = new std::map<std::string, std::string>();
+
+      bool isVertical = true;
+      RenderObject *parent = (RenderObject *) getParent();
+
+      if (parent != nullptr && !parent->Type().empty()) {
+          if (parent->Type() == kHList) {
+              isVertical = false;
+          } else if (getOrientation() == HORIZONTAL_VALUE) {
+              isVertical = false;
+          }
+      }
+
+      std::string prop = isVertical ? HEIGHT : WIDTH;
+
+      if (prop == HEIGHT && isnan(getStyleHeight()) && !mIsSetFlex) {
+        mIsSetFlex = true;
+        style->insert(std::pair<std::string, std::string>(FLEX, "1"));
+      } else if (prop == WIDTH && isnan(getStyleWidth()) && !mIsSetFlex) {
+        mIsSetFlex = true;
+        style->insert(std::pair<std::string, std::string>(FLEX, "1"));
+      }
+
+      return style;
+    }
+
+    inline void setFlex(const float flex) {
+        mIsSetFlex = true;
+        WXCoreLayoutNode::setFlex(flex);
+    }
+
+    float calcFreeSpaceAlongMainAxis(const float &width, const float &height, const float &currentLength) const override {
+      return NAN;
+    }
+
+    std::map<std::string, std::string> *GetDefaultAttr() {
+      if (!mIsPreCalculateCellWidth) {
+        return preCalculateCellWidth();
+      }
+      return nullptr;
+    }
+
+
+    std::map<std::string, std::string> *preCalculateCellWidth() {
+        std::map<std::string, std::string> *attrs = new std::map<std::string, std::string>();
+        if (Attributes() != nullptr) {
+            mColumnCount = getColumnCount();
+            mColumnWidth = getColumnWidth();
+            mColumnGap = getColumnGap();
+
+            mAvailableWidth = getStyleWidth()- getWebPxByWidth(getPaddingLeft(), GetRenderPage()->ViewPortWidth()) - getWebPxByWidth(getPaddingRight(), GetRenderPage()->ViewPortWidth());
+
+            if (AUTO_VALUE == mColumnCount && AUTO_VALUE == mColumnWidth) {
+                mColumnCount = COLUMN_COUNT_NORMAL;
+                mColumnWidth = (mAvailableWidth - ((mColumnCount - 1) * mColumnGap)) / mColumnCount;
+                mColumnWidth = mColumnWidth > 0 ? mColumnWidth :0;
+            } else if (AUTO_VALUE == mColumnWidth && AUTO_VALUE != mColumnCount) {
+                mColumnWidth = (mAvailableWidth - ((mColumnCount - 1) * mColumnGap)) / mColumnCount;
+                mColumnWidth = mColumnWidth > 0 ? mColumnWidth :0;
+            } else if (AUTO_VALUE != mColumnWidth && AUTO_VALUE == mColumnCount) {
+                mColumnCount = round((mAvailableWidth + mColumnGap) / (mColumnWidth + mColumnGap)-0.5f);
+                mColumnCount = mColumnCount > 0 ? mColumnCount :1;
+                if (mColumnCount <= 0) {
+                    mColumnCount = COLUMN_COUNT_NORMAL;
+                }
+                mColumnWidth =((mAvailableWidth + mColumnGap) / mColumnCount) - mColumnGap;
+
+            } else if(AUTO_VALUE != mColumnWidth && AUTO_VALUE != mColumnCount){
+                int columnCount = round((mAvailableWidth + mColumnGap) / (mColumnWidth + mColumnGap)-0.5f);
+                mColumnCount = columnCount > mColumnCount ? mColumnCount :columnCount;
+                if (mColumnCount <= 0) {
+                    mColumnCount = COLUMN_COUNT_NORMAL;
+                }
+                mColumnWidth= ((mAvailableWidth + mColumnGap) / mColumnCount) - mColumnGap;
+            }
+
+            mIsPreCalculateCellWidth = true;
+            attrs->insert(std::pair<std::string, std::string>(COLUMN_COUNT, std::to_string(mColumnCount)));
+            attrs->insert(std::pair<std::string, std::string>(COLUMN_WIDTH, std::to_string(mColumnWidth)));
+            attrs->insert(std::pair<std::string, std::string>(COLUMN_GAP, std::to_string(mColumnGap)));
+
+        }
+        return attrs;
+    }
+
+    float getStyleWidth() {
+      float width = getWebPxByWidth(getLayoutWidth(), GetRenderPage()->ViewPortWidth());
+      if (isnan(width) || width <= 0){
+        if(getParent() != nullptr){
+          width = getWebPxByWidth(getParent()->getLayoutWidth(), GetRenderPage()->ViewPortWidth());
+        }
+        if (isnan(width) || width <= 0){
+            width = getWebPxByWidth(RenderObject::getStyleWidth(), GetRenderPage()->ViewPortWidth());
+        }
+      }
+      if (isnan(width) || width <= 0){
+        width = GetViewPortWidth();
+      }
+      return width;
+    }
+
+
+    int AddRenderObject(int index, RenderObject *child) {
+      index = RenderObject::AddRenderObject(index, child);
+
+      if (!mIsPreCalculateCellWidth) {
+        preCalculateCellWidth();
+      }
+
+      if(mColumnWidth != 0 && !isnan(mColumnWidth)) {
+        //LOGE("listen child->ApplyStyle %s %s", child->Ref().c_str(), std::to_string(mColumnWidth).c_str());
+        AddRenderObjectWidth(child, false);
+      }
+      return index;
+    }
+
+    void AddRenderObjectWidth(RenderObject *child, const bool updating) {
+        if (Type() == kRenderWaterfall) {
+            if(child->Type() == kRenderHeader || child->Type() == kRenderFooter) {
+                child->ApplyStyle(WIDTH, std::to_string(mAvailableWidth), updating);
+            } else if (child->Type() == kRenderCell){
+                child->ApplyStyle(WIDTH, std::to_string(mColumnWidth), updating);
+            } else if (child->getStypePositionType() == kSticky) {
+                child->ApplyStyle(WIDTH, std::to_string(GetViewPortWidth()), updating);
+            }
+        }
+    }
+
+    void UpdateAttr(std::string key, std::string value) {
+      RenderObject::UpdateAttr(key, value);
+
+      if(!GetAttr(COLUMN_COUNT).empty() || !GetAttr(COLUMN_GAP).empty() || !GetAttr(COLUMN_WIDTH).empty()){
+        preCalculateCellWidth();
+
+        if(mColumnWidth == 0 && isnan(mColumnWidth)) {
+          return;
+        }
+
+        int count = getChildCount();
+        for (Index i = 0; i < count; i++) {
+          RenderObject *child = GetChild(i);
+          //LOGE("listen child->UpdateAttr %s %s", child->Ref().c_str(), std::to_string(mColumnWidth).c_str());
+          // ApplyStyle(WIDTH, std::to_string(mColumnWidth));
+          AddRenderObjectWidth(this, true);
+        }
+      }
+    }
+
+    float getColumnCount() {
+      std::string columnCount = GetAttr(COLUMN_COUNT);
+
+      if (columnCount.empty() || columnCount == AUTO) {
+        return AUTO_VALUE;
+      }
+
+      float columnCountValue = getFloat(columnCount.c_str());
+      return (columnCountValue > 0 && !isnan(columnCountValue)) ? columnCountValue : AUTO_VALUE;
+    }
+
+    float getColumnGap() {
+      std::string columnGap = GetAttr(COLUMN_GAP);
+
+      if (columnGap.empty() || columnGap == NORMAL) {
+        return COLUMN_GAP_NORMAL;
+      }
+
+      float columnGapValue = getFloat(columnGap.c_str());
+      return (columnGapValue > 0 && !isnan(columnGapValue)) ? columnGapValue : AUTO_VALUE;
+    }
+
+    float getColumnWidth() {
+      std::string columnWidth = GetAttr(COLUMN_WIDTH);
+
+      if (columnWidth.empty() || columnWidth == AUTO) {
+        return AUTO_VALUE;
+      }
+
+      float columnWidthValue = getFloat(columnWidth.c_str());
+      return (columnWidthValue > 0 && !isnan(columnWidthValue)) ? columnWidthValue : 0;
+    }
+
+    int getOrientation(){
+      std::string direction = GetAttr(SCROLL_DIRECTION);
+      if(HORIZONTAL == direction){
+        return HORIZONTAL_VALUE;
+      }
+      return VERTICAL_VALUE;
+    }
+
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERLIST_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_mask.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_mask.h b/weex_core/Source/core/render/node/render_mask.h
new file mode 100644
index 0000000..3ae41a1
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_mask.h
@@ -0,0 +1,37 @@
+#ifndef WEEX_PROJECT_RENDERMASK_H
+#define WEEX_PROJECT_RENDERMASK_H
+
+#include <core/render/node/render_object.h>
+#include <core/config/core_environment.h>
+#include <android/bridge/impl/bridge_impl_android.h>
+#include <base/ViewUtils.h>
+#include <cstdlib>
+
+namespace WeexCore {
+  class RenderMask : public RenderObject {
+    std::map<std::string, std::string> *GetDefaultStyle() {
+      std::map<std::string, std::string> *style = new std::map<std::string, std::string>();
+
+      int width = WXCoreEnvironment::getInstance()->DeviceWidth();
+      int height = WXCoreEnvironment::getInstance()->DeviceHeight();
+
+      if (WXCoreEnvironment::getInstance()->GetOption("screen_width_pixels") != "" &&
+          WXCoreEnvironment::getInstance()->GetOption("screen_height_pixels") != "") {
+        width = atoi(WXCoreEnvironment::getInstance()->GetOption("screen_width_pixels").c_str());
+        height = atoi(WXCoreEnvironment::getInstance()->GetOption("screen_height_pixels").c_str());
+      }
+
+      if (WXCoreEnvironment::getInstance()->GetOption("status_bar_height") != "") {
+        int statusBarHeight = atoi(WXCoreEnvironment::getInstance()->GetOption("status_bar_height").c_str());
+        height -= statusBarHeight;
+      }
+
+      style->insert(std::pair<std::string, std::string>(POSITION, "absolute"));
+      style->insert(std::pair<std::string, std::string>(WIDTH, std::to_string(getWebPxByWidth(width, GetViewPortWidth()))));
+      style->insert(std::pair<std::string, std::string>(HEIGHT, std::to_string(getWebPxByWidth(height, GetViewPortWidth()))));
+      style->insert(std::pair<std::string, std::string>(TOP, "0"));
+      return style;
+    }
+  };
+}
+#endif //WEEX_PROJECT_RENDERMASK_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_object.cpp
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_object.cpp b/weex_core/Source/core/render/node/render_object.cpp
new file mode 100644
index 0000000..3f4301d
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_object.cpp
@@ -0,0 +1,139 @@
+#include <core/render/node/render_object.h>
+#include <android/bridge/impl/content_box_measurement_impl_android.h>
+#include <android/bridge/impl/measure_mode_impl_android.h>
+#include <android/base/jni/scoped_java_ref.h>
+#include <android/bridge/impl/weexcore_impl_android.h>
+#include <android/base/string/string_utils.h>
+#include <string.h>
+
+using namespace std;
+namespace WeexCore {
+
+  RenderObject::RenderObject() {
+    mStyles = new StylesMap();
+    mAttributes = new AttributesMap();
+    mEvents = new EventsSet();
+    mMeasureFunc_Impl_Android = nullptr;
+    mIsRootRender = false;
+  }
+
+  RenderObject::~RenderObject() {
+
+    JNIEnv *env = getJNIEnv();
+
+    mParentRender = nullptr;
+
+    if (mStyles != nullptr) {
+      delete mStyles;
+      mStyles = nullptr;
+    }
+    if (mAttributes != nullptr) {
+      delete mAttributes;
+      mAttributes = nullptr;
+    }
+    if (mEvents != nullptr) {
+      delete mEvents;
+      mEvents = nullptr;
+    }
+
+    if (mMeasureFunc_Impl_Android != nullptr) {
+      env->DeleteGlobalRef(mMeasureFunc_Impl_Android);
+      mMeasureFunc_Impl_Android = nullptr;
+    }
+
+    for(auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
+      RenderObject* child = static_cast<RenderObject*>(*it);
+      if (child != nullptr) {
+        delete child;
+        child = nullptr;
+      }
+    }
+  }
+
+  void RenderObject::ApplyDefaultStyle() {
+    std::map<std::string, std::string> *style = GetDefaultStyle();
+
+    if (style == nullptr)
+      return;
+
+    for (auto iter = style->cbegin(); iter != style->cend(); iter++)
+      AddStyle(iter->first, iter->second);
+
+    if (style != nullptr) {
+      delete style;
+      style = nullptr;
+    }
+  }
+
+  void RenderObject::ApplyDefaultAttr() {
+    std::map<std::string, std::string> *attrs = GetDefaultAttr();
+
+    if (attrs == nullptr)
+      return;
+
+    for (auto iter = attrs->cbegin(); iter != attrs->cend(); iter++) {
+        UpdateAttr(iter->first, iter->second);
+    }
+
+    if (attrs != nullptr) {
+      delete attrs;
+      attrs = nullptr;
+    }
+  }
+
+  WXCoreSize measureFunc_Impl(WXCoreLayoutNode *node, float width, MeasureMode widthMeasureMode,
+                              float height, MeasureMode heightMeasureMode) {
+    JNIEnv *env = getJNIEnv();
+    WXCoreSize size;
+    size.height = 0;
+    size.width = 0;
+
+    jobject measureFunc = ((RenderObject *) node)->GetMeasureFuncImplAndroid();
+
+    if (node == nullptr || measureFunc == nullptr)
+      return size;
+
+    int widthMode = Unspecified(env);
+    int heightMode = Unspecified(env);
+    if (widthMeasureMode == kExactly)
+      widthMode = Exactly(env);
+    if (heightMeasureMode == kExactly)
+      heightMode = Exactly(env);
+    cumsmeasure_Imple_Android(env, measureFunc,
+                              width, height,
+                              widthMode, heightMode);
+    size.width = GetLayoutWidth(env, measureFunc);
+    size.height = GetLayoutHeight(env, measureFunc);
+
+    return size;
+  }
+
+  bool RenderObject::BindMeasureFuncImplAndroid(jobject measureFunc_impl_android) {
+    if (measureFunc_impl_android == nullptr)
+      return false;
+    this->mMeasureFunc_Impl_Android = getJNIEnv()->NewGlobalRef(measureFunc_impl_android);
+    setMeasureFunc(measureFunc_Impl);
+    return true;
+  }
+
+  bool RenderObject::BindMeasureFuncImplIOS(WXCoreMeasureFunc measureFunc_impl_ios) {
+    if (measureFunc_impl_ios == nullptr)
+      return false;
+    setMeasureFunc(measureFunc_impl_ios);
+    return true;
+  }
+
+  void RenderObject::onLayoutBefore() {
+    if (this->GetMeasureFuncImplAndroid() == nullptr)
+      return;
+    JNIEnv *env = getJNIEnv();
+    LayoutBeforeImplAndroid(env, this->GetMeasureFuncImplAndroid());
+  }
+
+  void RenderObject::onLayoutAfter(float width, float height) {
+    if (this->GetMeasureFuncImplAndroid() == nullptr)
+      return;
+    JNIEnv *env = getJNIEnv();
+    LayoutAfterImplAndroid(env, this->GetMeasureFuncImplAndroid(), width, height);
+  }
+} //end WeexCore

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_object.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_object.h b/weex_core/Source/core/render/node/render_object.h
new file mode 100644
index 0000000..0dc51a8
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_object.h
@@ -0,0 +1,394 @@
+#ifndef RenderObject_h
+#define RenderObject_h
+
+#include <string>
+#include <map>
+#include <set>
+#include <jni.h>
+#include <core/css/constants_name.h>
+#include <core/css/css_value_getter.h>
+#include <core/layout/layout.h>
+#include <core/render/manager/render_manager.h>
+#include <core/render/node/factory/i_render_object.h>
+#include <base/ViewUtils.h>
+#include <core/render/page/render_page.h>
+#include <core/css/constants_value.h>
+#include <android/base/log_utils.h>
+
+namespace WeexCore {
+
+  class RenderObject;
+
+  class RenderPage;
+
+  typedef enum StyleType {
+    kTypeStyle, kTypeLayout, kTypeMargin, kTypePadding, kTypeBorder
+  } StyleType;
+
+  typedef std::map<std::string, std::string>::const_iterator StylesIterator;
+  typedef std::map<std::string, std::string>::const_iterator AttributesIterator;
+  typedef std::set<std::string>::const_iterator EventsIterator;
+  typedef std::map<std::string, std::string> StylesMap;
+  typedef std::map<std::string, std::string> AttributesMap;
+  typedef std::set<std::string> EventsSet;
+
+  class RenderObject : public IRenderObject {
+
+    friend class RenderPage;
+
+
+  private:
+    inline void LayoutBefore() {
+      if (isDirty()) {
+        onLayoutBefore();
+      }
+
+      for(auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
+        RenderObject* child = static_cast<RenderObject*>(*it);
+        if (child != nullptr) {
+          child->LayoutBefore();
+        }
+      }
+    }
+
+    inline void LayoutAfter() {
+      if (hasNewLayout()) {
+        onLayoutAfter(getLayoutWidth(), getLayoutHeight());
+      }
+
+      for(auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
+        RenderObject* child = static_cast<RenderObject*>(*it);
+        if (child != nullptr) {
+          child->LayoutAfter();
+        }
+      }
+    }
+
+    inline bool ViewInit() {
+      return (!isnan(getStyleWidth()) && getStyleWidth() > 0) ||
+          (IsRootRender() && GetRenderPage() != nullptr && GetRenderPage()->GetRenderContainerWidthWrapContent());
+    }
+
+    virtual std::map<std::string, std::string> *GetDefaultStyle() {
+      return nullptr;
+    }
+
+    virtual std::map<std::string, std::string> *GetDefaultAttr() {
+      return nullptr;
+    }
+
+   protected:
+    bool UpdateStyle(const std::string key, const std::string value,
+                      float fallback, std::function<void(float)> functor){
+      bool ret = false;
+      if (value.empty()) {
+        functor(fallback);
+        ret = true;
+      } else {
+        float fvalue = getFloatByViewport(value, GetViewPortWidth());
+        if (!isnan(fvalue)) {
+          functor(fvalue);
+          ret = true;
+        }
+      }
+      return ret;
+    }
+
+  public:
+
+    RenderObject();
+
+    ~RenderObject();
+
+    bool BindMeasureFuncImplAndroid(jobject measureFunc_impl_android);
+
+    bool BindMeasureFuncImplIOS(WXCoreMeasureFunc measureFunc_impl_ios);
+
+    void onLayoutBefore();
+
+    void onLayoutAfter(float width, float height);
+
+    virtual StyleType ApplyStyle(const std::string &key, const std::string &value, const bool updating) {
+      if (key == ALIGN_ITEMS) {
+        setAlignItems(GetWXCoreAlignItem(value));
+        return kTypeLayout;
+      } else if (key == ALIGN_SELF) {
+        setAlignSelf(GetWXCoreAlignSelf(value));
+        return kTypeLayout;
+      } else if (key == FLEX) {
+        if (value.empty()) {
+          setFlex(0);
+        } else {
+          float ret = getFloat(value.c_str());
+          if (!isnan(ret)) {
+            setFlex(ret);
+          }
+        }
+        return kTypeLayout;
+      } else if (key == FLEX_DIRECTION) {
+        setFlexDirection(GetWXCoreFlexDirection(value), updating);
+        return kTypeLayout;
+      } else if (key == JUSTIFY_CONTENT) {
+        setJustifyContent(GetWXCoreJustifyContent(value));
+        return kTypeLayout;
+      } else if (key == FLEX_WRAP) {
+        setFlexWrap(GetWXCoreFlexWrap(value));
+        return kTypeLayout;
+      } else if (key == MIN_WIDTH) {
+        UpdateStyle(key, value, NAN, [=](float foo){setMinWidth(foo, updating);});
+        return kTypeLayout;
+      } else if (key == MIN_HEIGHT) {
+        UpdateStyle(key, value, NAN, [=](float foo){setMinHeight(foo);});
+        return kTypeLayout;
+      } else if (key == MAX_WIDTH) {
+        UpdateStyle(key, value, NAN, [=](float foo){setMaxWidth(foo, updating);});
+        return kTypeLayout;
+      } else if (key == MAX_HEIGHT) {
+        UpdateStyle(key, value, NAN, [=](float foo){setMaxHeight(foo);});
+        return kTypeLayout;
+      } else if (key == HEIGHT) {
+        if(UpdateStyle(key, value, NAN, [=](float foo){setStyleHeight(foo);})){
+          setStyleHeightLevel(CSS_STYLE);
+        }
+        return kTypeLayout;
+      } else if (key == WIDTH) {
+        if(UpdateStyle(key, value, NAN, [=](float foo){setStyleWidth(foo, updating);})){
+          setStyleWidthLevel(CSS_STYLE);
+        }
+        return kTypeLayout;
+      } else if (key == POSITION) {
+        setStylePositionType(GetWXCorePositionType(value));
+        mStyles->insert(std::pair<std::string, std::string>(key, value));
+        return kTypeStyle;
+      } else if (key == LEFT) {
+        UpdateStyle(key, value, NAN, [=](float foo){setStylePosition(kPositionEdgeLeft, foo);});
+        return kTypeLayout;
+      } else if (key == TOP) {
+        UpdateStyle(key, value, NAN, [=](float foo){setStylePosition(kPositionEdgeTop, foo);});
+        return kTypeLayout;
+      } else if (key == RIGHT) {
+        UpdateStyle(key, value, NAN, [=](float foo){setStylePosition(kPositionEdgeRight, foo);});
+        return kTypeLayout;
+      } else if (key == BOTTOM) {
+        UpdateStyle(key, value, NAN, [=](float foo){setStylePosition(kPositionEdgeBottom, foo);});
+        return kTypeLayout;
+      } else if (key == MARGIN) {
+        UpdateStyle(key, value, 0, [=](float foo){setMargin(kMarginALL, foo);});
+        return kTypeMargin;
+      } else if (key == MARGIN_LEFT) {
+        UpdateStyle(key, value, 0, [=](float foo){setMargin(kMarginLeft, foo);});
+        return kTypeMargin;
+      } else if (key == MARGIN_TOP) {
+        UpdateStyle(key, value, 0, [=](float foo){setMargin(kMarginTop, foo);});
+        return kTypeMargin;
+      } else if (key == MARGIN_RIGHT) {
+        UpdateStyle(key, value, 0, [=](float foo){setMargin(kMarginRight, foo);});
+        return kTypeMargin;
+      } else if (key == MARGIN_BOTTOM) {
+        UpdateStyle(key, value, 0, [=](float foo){setMargin(kMarginBottom, foo);});
+        return kTypeMargin;
+      } else if (key == BORDER_WIDTH) {
+        UpdateStyle(key, value, 0, [=](float foo){setBorderWidth(kBorderWidthALL, foo);});
+        return kTypeBorder;
+      } else if (key == BORDER_TOP_WIDTH) {
+        UpdateStyle(key, value, 0, [=](float foo){setBorderWidth(kBorderWidthTop, foo);});
+        return kTypeBorder;
+      } else if (key == BORDER_RIGHT_WIDTH) {
+        UpdateStyle(key, value, 0, [=](float foo){setBorderWidth(kBorderWidthRight, foo);});
+        return kTypeBorder;
+      } else if (key == BORDER_BOTTOM_WIDTH) {
+        UpdateStyle(key, value, 0, [=](float foo){setBorderWidth(kBorderWidthBottom, foo);});
+        return kTypeBorder;
+      } else if (key == BORDER_LEFT_WIDTH) {
+        UpdateStyle(key, value, 0, [=](float foo){setBorderWidth(kBorderWidthLeft, foo);});
+        return kTypeBorder;
+      } else if (key == PADDING) {
+        UpdateStyle(key, value, 0, [=](float foo){setPadding(kPaddingALL, foo);});
+        return kTypePadding;
+      } else if (key == PADDING_LEFT) {
+        UpdateStyle(key, value, 0, [=](float foo){setPadding(kPaddingLeft, foo);});
+        return kTypePadding;
+      } else if (key == PADDING_TOP) {
+        UpdateStyle(key, value, 0, [=](float foo){setPadding(kPaddingTop, foo);});
+        return kTypePadding;
+      } else if (key == PADDING_RIGHT) {
+        UpdateStyle(key, value, 0, [=](float foo){setPadding(kPaddingRight, foo);});
+        return kTypePadding;
+      } else if (key == PADDING_BOTTOM) {
+        UpdateStyle(key, value, 0, [=](float foo){setPadding(kPaddingBottom, foo);});
+        return kTypePadding;
+      } else {
+        mStyles->insert(std::pair<std::string, std::string>(key, value));
+        return kTypeStyle;
+      }
+    }
+
+    void ApplyDefaultStyle();
+
+    void ApplyDefaultAttr();
+
+    inline jobject GetMeasureFuncImplAndroid() {
+      return mMeasureFunc_Impl_Android;
+    }
+
+    inline RenderObject *GetChild(const Index &index) {
+      return static_cast<RenderObject*>(getChildAt(index));
+    }
+
+    inline Index IndexOf(const RenderObject *render) {
+      if (render == nullptr) {
+        return -1;
+      } else {
+        int i = 0;
+        for(auto it = ChildListIterBegin(); it != ChildListIterEnd(); it++) {
+          RenderObject* child = static_cast<RenderObject*>(*it);
+          if (child != nullptr) {
+            if (render->Ref() == child->Ref())
+              return i;
+          }
+          ++i;
+        }
+      }
+      return -1;
+    }
+
+    virtual int AddRenderObject(int index, RenderObject *child) {
+
+      if (child == nullptr || index < -1) {
+        return index;
+      }
+
+      Index count = getChildCount();
+      index = index >= count ? -1 : index;
+      if (index == -1) {
+        addChildAt(child, getChildCount());
+      } else {
+        addChildAt(child, index);
+      }
+
+      child->SetParentRender(this);
+
+      return index;
+    }
+
+    inline void RemoveRenderObject(RenderObject *child) {
+      removeChild(child);
+    }
+
+    inline void AddAttr(std::string key, std::string value) {
+      mAttributes->insert(std::pair<std::string, std::string>(key, value));
+    }
+
+    virtual void UpdateAttr(std::string key, std::string value) {
+      AddAttr(key, value);
+    }
+
+    virtual StyleType UpdateStyle(std::string key, std::string value) {
+      return ApplyStyle(key, value, true);
+    }
+
+    inline StyleType AddStyle(std::string key, std::string value) {
+      return ApplyStyle(key, value, false);
+    }
+
+    inline void AddEvent(std::string event) {
+      if (mEvents == nullptr || mEvents->empty()) {
+          mEvents = new EventsSet();
+      }
+      mEvents->insert(event);
+    }
+
+    inline void RemoveEvent(const std::string &event) {
+      mEvents->erase(event);
+    }
+
+    inline RenderPage *GetRenderPage() {
+      return RenderManager::GetInstance()->GetPage(PageId());
+    }
+
+    inline float GetViewPortWidth() {
+      if (mViewPortWidth >= 0)
+        return mViewPortWidth;
+
+      RenderPage *page = GetRenderPage();
+      if (page == nullptr)
+        return kDefaultViewPortWidth;
+
+      return page->ViewPortWidth();
+    }
+
+    inline void SetParentRender(RenderObject *render) {
+      mParentRender = render;
+    }
+
+    inline RenderObject *GetParentRender() {
+      return mParentRender;
+    }
+
+    inline StylesMap *Styles() const {
+      return mStyles;
+    }
+
+    inline AttributesMap * Attributes() const {
+      return mAttributes;
+    }
+
+    inline EventsSet *Events() const {
+      return mEvents;
+    }
+
+    inline StylesIterator StyleItBegin() {
+      return mStyles->begin();
+    }
+
+    inline StylesIterator StyleItEnd() {
+      return mStyles->end();
+    }
+
+    inline AttributesIterator AttrItBegin() {
+      return mAttributes->begin();
+    }
+
+    inline AttributesIterator AttrItEnd() {
+      return mAttributes->end();
+    }
+
+    inline EventsIterator EventItBegin() {
+      return mEvents->begin();
+    }
+
+    inline EventsIterator EventItEnd() {
+      return mEvents->end();
+    }
+
+    inline const std::string GetAttr(const std::string &key) {
+      if (mAttributes == nullptr)
+        return "";
+
+      std::map<std::string, std::string>::iterator iter = mAttributes->find(key);
+      if (iter != mAttributes->end()) {
+        return iter->second;
+      } else {
+        return "";
+      }
+    }
+
+    inline void MarkRootRender() {
+      mIsRootRender = true;
+    }
+
+    inline bool IsRootRender() {
+      return mIsRootRender;
+    }
+
+  private:
+    RenderObject *mParentRender;
+    StylesMap *mStyles;
+    AttributesMap *mAttributes;
+    EventsSet *mEvents;
+    jobject mMeasureFunc_Impl_Android;
+    float mViewPortWidth = -1;
+    bool mIsRootRender;
+  };
+} //end WeexCore
+#endif //RenderObject_h

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_scroller.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_scroller.h b/weex_core/Source/core/render/node/render_scroller.h
new file mode 100644
index 0000000..dc7890b
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_scroller.h
@@ -0,0 +1,47 @@
+#ifndef WEEX_PROJECT_RENDERSCROLLER_H
+#define WEEX_PROJECT_RENDERSCROLLER_H
+
+#include <android/bridge/impl/bridge_impl_android.h>
+#include <core/render/node/render_object.h>
+
+namespace WeexCore {
+  class RenderScroller : public RenderObject {
+
+    bool mIsSetFlex = false;
+
+    std::map<std::string, std::string> *GetDefaultStyle() {
+      std::map<std::string, std::string> *style = new std::map<std::string, std::string>();
+
+      bool isVertical = true;
+      RenderObject *parent = (RenderObject *) getParent();
+
+      if (parent != nullptr) {
+        if (parent->GetAttr(SCROLL_DIRECTION) == HORIZONTAL) {
+          isVertical = false;
+        }
+      }
+
+      std::string prop = isVertical ? HEIGHT : WIDTH;
+
+      if (prop == HEIGHT && isnan(getStyleHeight()) &&  !mIsSetFlex) {
+        style->insert(std::pair<std::string, std::string>(FLEX, "1"));
+      } else if (prop == WIDTH && isnan(getStyleWidth()) &&  !mIsSetFlex) {
+        style->insert(std::pair<std::string, std::string>(FLEX, "1"));
+      }
+
+      return style;
+    }
+
+    inline void setFlex(const float flex) {
+       mIsSetFlex = true;
+       WXCoreLayoutNode::setFlex(flex);
+    }
+
+
+      float calcFreeSpaceAlongMainAxis(const float &width, const float &height, const float &currentLength) const override {
+      return NAN;
+    }
+
+  };
+}
+#endif //WEEX_PROJECT_RENDERSCROLLER_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_switch.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_switch.h b/weex_core/Source/core/render/node/render_switch.h
new file mode 100644
index 0000000..69ccd82
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_switch.h
@@ -0,0 +1,12 @@
+#ifndef WEEX_PROJECT_RENDERSWITCH_H
+#define WEEX_PROJECT_RENDERSWITCH_H
+
+#include <core/render/node/render_object.h>
+
+namespace WeexCore {
+  class RenderSwitch : public RenderObject {
+    
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERSWITCH_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_text.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_text.h b/weex_core/Source/core/render/node/render_text.h
new file mode 100644
index 0000000..d3b67ec
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_text.h
@@ -0,0 +1,26 @@
+#ifndef WEEX_PROJECT_RENDERTEXT_H
+#define WEEX_PROJECT_RENDERTEXT_H
+
+#include <core/render/node/render_object.h>
+#include <core/render/page/render_page.h>
+
+namespace WeexCore {
+  class RenderText : public RenderObject {
+  private:
+    inline void UpdateAttr(std::string key, std::string value) {
+      RenderObject::UpdateAttr(key, value);
+      markDirty();
+      RenderPage* page = GetRenderPage();
+      if (page != nullptr)
+        GetRenderPage()->Batch();
+    }
+
+    inline StyleType UpdateStyle(std::string key, std::string value) {
+      StyleType resultType = RenderObject::ApplyStyle(key, value, true);
+      markDirty();
+      return resultType;
+    }
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERTEXT_H

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/2f8caedb/weex_core/Source/core/render/node/render_textarea.h
----------------------------------------------------------------------
diff --git a/weex_core/Source/core/render/node/render_textarea.h b/weex_core/Source/core/render/node/render_textarea.h
new file mode 100644
index 0000000..5595082
--- /dev/null
+++ b/weex_core/Source/core/render/node/render_textarea.h
@@ -0,0 +1,12 @@
+#ifndef WEEX_PROJECT_RENDERTEXTAREA_H
+#define WEEX_PROJECT_RENDERTEXTAREA_H
+
+#include <core/render/node/render_input.h>
+
+namespace WeexCore {
+  class RenderTextArea : public RenderInput {
+
+  };
+}
+
+#endif //WEEX_PROJECT_RENDERTEXTAREA_H