http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java new file mode 100644 index 0000000..42ca263 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/flat/widget/WidgetGroup.java @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package com.taobao.weex.ui.flat.widget; + + +import android.graphics.Canvas; +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; +import android.support.annotation.RestrictTo.Scope; +import com.taobao.weex.ui.flat.FlatGUIContext; +import java.util.LinkedList; +import java.util.List; + +@RestrictTo(Scope.LIBRARY) +public class WidgetGroup extends BaseWidget { + + private List<Widget> mChildren = new LinkedList<>(); + + public WidgetGroup(@NonNull FlatGUIContext context) { + super(context); + } + + public void replaceAll(@NonNull List<Widget> widgets) { + mChildren = widgets; + invalidate(); + } + + public List<Widget> getChildren() { + return mChildren; + } + + @Override + public void onDraw(@NonNull Canvas canvas) { + for (Widget child : mChildren) { + child.draw(canvas); + } + } +}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java index caa28a6..ae0ed99 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/module/WXTimerModule.java @@ -27,6 +27,7 @@ import static com.taobao.weex.common.WXJSBridgeMsgType.MODULE_TIMEOUT; import android.os.Handler; import android.os.Message; +import android.support.annotation.FloatRange; import android.support.annotation.IntDef; import android.support.annotation.IntRange; import android.support.annotation.VisibleForTesting; @@ -63,16 +64,16 @@ public class WXTimerModule extends WXModule implements Destroyable, Handler.Call @JSMethod(uiThread = false) - public void setTimeout(@IntRange(from = 1) int funcId, @IntRange(from = 0) int delay) { + public void setTimeout(@IntRange(from = 1) int funcId, @FloatRange(from = 0) float delay) { if(mWXSDKInstance != null) { - postOrHoldMessage(MODULE_TIMEOUT, funcId, delay, Integer.parseInt(mWXSDKInstance.getInstanceId())); + postOrHoldMessage(MODULE_TIMEOUT, funcId, (int) delay, Integer.parseInt(mWXSDKInstance.getInstanceId())); } } @JSMethod(uiThread = false) - public void setInterval(@IntRange(from = 1) int funcId, @IntRange(from = 0) int interval) { + public void setInterval(@IntRange(from = 1) int funcId, @FloatRange(from = 0) float interval) { if(mWXSDKInstance != null) { - postOrHoldMessage(MODULE_INTERVAL, funcId, interval, Integer.parseInt(mWXSDKInstance.getInstanceId())); + postOrHoldMessage(MODULE_INTERVAL, funcId, (int) interval, Integer.parseInt(mWXSDKInstance.getInstanceId())); } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/WXBaseCircleIndicator.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXBaseCircleIndicator.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXBaseCircleIndicator.java index 1fdba29..5983f2d 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXBaseCircleIndicator.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXBaseCircleIndicator.java @@ -37,7 +37,6 @@ import com.taobao.weex.utils.WXViewUtils; public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeListener, WXGestureObservable { private final Paint mPaintPage = new Paint(); - private final Paint mPaintStroke = new Paint(); private final Paint mPaintFill = new Paint(); private WXGesture wxGesture; private WXCircleViewPager mCircleViewPager; @@ -53,38 +52,24 @@ public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeLi /** * Fill color of unselected circle */ - private int pageColor; + private int pageColor = Color.LTGRAY; /** * Fill color of the selected circle */ - private int fillColor; + private int fillColor = Color.DKGRAY; private int realCurrentItem; - private OnPageChangeListener mListener; public WXBaseCircleIndicator(Context context) { super(context); - getAttrs(context); init(); } - /** - * Get attribute of xml - */ - private void getAttrs(Context context) { + private void init() { radius = WXViewUtils.dip2px(5); circlePadding = WXViewUtils.dip2px(5); - pageColor = Color.parseColor("#ffffff"); - // strokeWidth= WAViewUtils.dip2px((float)1.5); - // strokeColor = Color.parseColor("#FFDDDDDD"); - fillColor = Color.parseColor("#ffd545"); - } - - private void init() { - mPaintStroke.setAntiAlias(true); - mPaintStroke.setStyle(Style.STROKE); - // mPaintStroke.setColor(strokeColor); - // mPaintStroke.setStrokeWidth(strokeWidth); + pageColor = Color.LTGRAY; + fillColor = Color.DKGRAY; mPaintFill.setStyle(Style.FILL); mPaintFill.setAntiAlias(true); @@ -102,21 +87,9 @@ public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeLi */ public WXBaseCircleIndicator(Context context, AttributeSet attrs) { super(context, attrs); - getAttrs(context); init(); } - public void setOnPageChangeListener(OnPageChangeListener listener) { - mListener = listener; - } - - /** - * @return the mCircleViewPager - */ - public WXCircleViewPager getCircleViewPager() { - return mCircleViewPager; - } - /** * @param mCircleViewPager the mCircleViewPager to set */ @@ -125,38 +98,27 @@ public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeLi if (this.mCircleViewPager != null) { this.mCircleViewPager.addOnPageChangeListener(this); this.realCurrentItem = mCircleViewPager.getRealCurrentItem(); + if (realCurrentItem < 0) { + realCurrentItem = 0; + } } requestLayout(); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - if (mListener != null) { - mListener.onPageScrolled(position, positionOffset, positionOffsetPixels); - } + } @Override public void onPageSelected(int position) { realCurrentItem = mCircleViewPager.getRealCurrentItem(); invalidate(); - if (mListener != null) { - mListener.onPageSelected(position); - } } @Override public void onPageScrollStateChanged(int state) { - if (mListener != null) { - mListener.onPageScrollStateChanged(state); - } - } - /** - * @return the radius - */ - public float getRadius() { - return radius; } /** @@ -167,27 +129,6 @@ public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeLi } /** - * @return the circlePadding - */ - public float getCirclePadding() { - return circlePadding; - } - - /** - * @param circlePadding the circlePadding to set - */ - public void setCirclePadding(float circlePadding) { - this.circlePadding = circlePadding; - } - - /** - * @return the fillColor - */ - public int getFillColor() { - return fillColor; - } - - /** * @param fillColor the fillColor to set */ public void setFillColor(int fillColor) { @@ -212,36 +153,9 @@ public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeLi */ public void setRealCurrentItem(int realCurrentItem) { this.realCurrentItem = realCurrentItem; + invalidate(); } - // /** - // * @return the strokeColor - // */ - // public int getStrokeColor() { - // return strokeColor; - // } - // - // /** - // * @param strokeColor the strokeColor to set - // */ - // public void setStrokeColor(int strokeColor) { - // this.strokeColor = strokeColor; - // } - // - // /** - // * @return the strokeWidth - // */ - // public float getStrokeWidth() { - // return strokeWidth; - // } - // - // /** - // * @param strokeWidth the strokeWidth to set - // */ - // public void setStrokeWidth(float strokeWidth) { - // this.strokeWidth = strokeWidth; - // } - @Override public void registerGestureListener(WXGesture wxGesture) { this.wxGesture = wxGesture; @@ -258,29 +172,22 @@ public class WXBaseCircleIndicator extends FrameLayout implements OnPageChangeLi @Override protected void onDraw(Canvas canvas) { - // TODO Auto-generated method stub super.onDraw(canvas); - float firstX = getWidth() / 2 + getPaddingLeft() - getCount() / 2.0f * (radius + circlePadding);// + radius; - float firstY = getHeight() / 2 + getPaddingTop();// + radius; + float dotWidth = (circlePadding + radius) * 2; - //draw stroked circles - for (int i = 0; i < getCount(); i++) { - float dx = firstX + circlePadding * i + radius * 2 * i; - float dy = firstY; - if (mPaintStroke.getStrokeWidth() > 0) { - canvas.drawCircle(dx, dy, radius, mPaintStroke); - } + float firstCenterX = getWidth() / 2 - (dotWidth * (getCount() - 1) / 2); + float firstCenterY = getHeight() / 2 + getPaddingTop(); - if (mPaintPage.getAlpha() > 0) { + for (int i = 0; i < getCount(); i++) { + float dx = firstCenterX + dotWidth * i; + float dy = firstCenterY; + if (i != realCurrentItem) { canvas.drawCircle(dx, dy, radius, mPaintPage); + } else { + canvas.drawCircle(dx, dy, radius, mPaintFill); } } - - //Draw the filled circle - float dx = firstX + realCurrentItem * circlePadding + radius * 2 * realCurrentItem; - float dy = firstY; - canvas.drawCircle(dx, dy, radius, mPaintFill); } @Override http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/WXFrameLayout.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXFrameLayout.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXFrameLayout.java index ec39462..28c7cef 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/WXFrameLayout.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/WXFrameLayout.java @@ -20,16 +20,19 @@ package com.taobao.weex.ui.view; import android.content.Context; import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.MotionEvent; import android.widget.FrameLayout; - import com.taobao.weex.ui.component.WXDiv; +import com.taobao.weex.ui.flat.widget.Widget; import com.taobao.weex.ui.view.gesture.WXGesture; import com.taobao.weex.ui.view.gesture.WXGestureObservable; +import com.taobao.weex.utils.WXLogUtils; import com.taobao.weex.utils.WXViewUtils; - import java.lang.ref.WeakReference; +import java.util.List; /** * FrameLayout wrapper @@ -41,6 +44,8 @@ public class WXFrameLayout extends FrameLayout implements WXGestureObservable,IR private WeakReference<WXDiv> mWeakReference; + private List<Widget> mWidgets; + public WXFrameLayout(Context context) { super(context); } @@ -60,12 +65,6 @@ public class WXFrameLayout extends FrameLayout implements WXGestureObservable,IR } @Override - protected void onDraw(Canvas canvas) { - WXViewUtils.clipCanvasWithinBorderBox(this, canvas); - super.onDraw(canvas); - } - - @Override public void holdComponent(WXDiv component) { mWeakReference = new WeakReference<WXDiv>(component); } @@ -75,4 +74,42 @@ public class WXFrameLayout extends FrameLayout implements WXGestureObservable,IR public WXDiv getComponent() { return null != mWeakReference ? mWeakReference.get() : null; } + + public void mountFlatGUI(List<Widget> widgets){ + this.mWidgets = widgets; + if (mWidgets != null) { + setWillNotDraw(true); + } + invalidate(); + } + + public void unmountFlatGUI(){ + mWidgets = null; + setWillNotDraw(false); + invalidate(); + } + + @Override + protected boolean verifyDrawable(@NonNull Drawable who) { + return mWidgets != null || super.verifyDrawable(who); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + try { + if (mWidgets != null) { + canvas.save(); + canvas.translate(getPaddingLeft(), getPaddingTop()); + for (Widget widget : mWidgets) { + widget.draw(canvas); + } + canvas.restore(); + } else { + WXViewUtils.clipCanvasWithinBorderBox(this, canvas); + super.dispatchDraw(canvas); + } + }catch (Throwable e){ + WXLogUtils.e("FlatGUI Crashed when dispatchDraw", WXLogUtils.getStackTrace(e)); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java index a396063..07ff38f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderCorner.java @@ -31,13 +31,15 @@ abstract class BorderCorner { private final float mPreBorderWidth; private final float mPostBorderWidth; private final RectF mBorderBox; + protected final float mAngleBisector; - BorderCorner(float cornerRadius, float preBorderWidth, float postBorderWidth, @NonNull RectF - borderBox) { + BorderCorner(float cornerRadius, float preBorderWidth, float postBorderWidth, + @NonNull RectF borderBox, float angleBisector) { mCornerRadius = cornerRadius; mPreBorderWidth = preBorderWidth; mPostBorderWidth = postBorderWidth; mBorderBox = borderBox; + mAngleBisector = angleBisector; } /** @@ -61,18 +63,26 @@ abstract class BorderCorner { return getOuterCornerRadius() > 0 && !FloatUtil.floatsEqual(0, getOuterCornerRadius()); } - protected float getPreBorderWidth() { + protected final float getPreBorderWidth() { return mPreBorderWidth; } - protected float getPostBorderWidth() { + protected final float getPostBorderWidth() { return mPostBorderWidth; } - protected float getOuterCornerRadius() { + protected final float getOuterCornerRadius() { return mCornerRadius; } + protected final float getAngleBisectorDegree(){ + return mAngleBisector; + } + + protected final RectF getBorderBox() { + return mBorderBox; + } + /** * Get the staring point of the corner. * @return the starting point of the corner. @@ -88,12 +98,6 @@ abstract class BorderCorner { return lineStart; } - @NonNull - abstract protected PointF getRoundCornerStart(); - - @NonNull - abstract protected PointF getSharpCornerVertex(); - /** * Get the ending point of the corner. * @return the ending point of the corner. @@ -110,9 +114,13 @@ abstract class BorderCorner { } @NonNull - abstract protected PointF getRoundCornerEnd(); + abstract protected PointF getRoundCornerStart(); + + @NonNull + abstract protected PointF getSharpCornerVertex(); - abstract protected float getAngleBisectorDegree(); + @NonNull + abstract protected PointF getRoundCornerEnd(); @NonNull abstract protected PointF getSharpCornerStart(); @@ -126,7 +134,4 @@ abstract class BorderCorner { @NonNull abstract protected RectF getOvalIfInnerCornerNotExist(); - protected RectF getBorderBox() { - return mBorderBox; - } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java index 4ce218e..b768eb5 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BorderUtil.java @@ -78,30 +78,4 @@ class BorderUtil { } } } - - static boolean areEdgesSame(float... numbers) { - if (numbers != null && numbers.length > 0) { - float init = numbers[0]; - for (float number : numbers) { - if (number != init) { - return false; - } - } - return true; - } - return false; - } - - static boolean areEdgesSame(int... numbers) { - if (numbers != null && numbers.length > 0) { - int init = numbers[0]; - for (int number : numbers) { - if (number != init) { - return false; - } - } - return true; - } - return false; - } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java index cf24477..3c01a76 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomLeftCorner.java @@ -25,12 +25,7 @@ import android.support.annotation.NonNull; class BottomLeftCorner extends BorderCorner { BottomLeftCorner(float cornerRadius, float preBorderWidth, float postBorderWidth, @NonNull RectF borderBox) { - super(cornerRadius, preBorderWidth, postBorderWidth, borderBox); - } - - @Override - protected float getAngleBisectorDegree() { - return 135; + super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 135); } @NonNull http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java index de444c1..2ed50a4 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/BottomRightCorner.java @@ -25,12 +25,7 @@ import android.support.annotation.NonNull; class BottomRightCorner extends BorderCorner { BottomRightCorner(float cornerRadius, float preBorderWidth, float postBorderWidth, @NonNull RectF borderBox) { - super(cornerRadius, preBorderWidth, postBorderWidth, borderBox); - } - - @Override - protected float getAngleBisectorDegree() { - return 45; + super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 45); } @NonNull http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java index ce63c4b..e83706f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopLeftCorner.java @@ -25,12 +25,7 @@ import android.support.annotation.NonNull; class TopLeftCorner extends BorderCorner { TopLeftCorner(float cornerRadius, float preBorderWidth, float postBorderWidth, @NonNull RectF borderBox) { - super(cornerRadius, preBorderWidth, postBorderWidth, borderBox); - } - - @Override - protected float getAngleBisectorDegree() { - return 225; + super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 225); } @NonNull http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopRightCorner.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopRightCorner.java b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopRightCorner.java index 77a513f..0ea4377 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopRightCorner.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/view/border/TopRightCorner.java @@ -25,12 +25,7 @@ import android.support.annotation.NonNull; class TopRightCorner extends BorderCorner { TopRightCorner(float cornerRadius, float preBorderWidth, float postBorderWidth, @NonNull RectF borderBox) { - super(cornerRadius, preBorderWidth, postBorderWidth, borderBox); - } - - @Override - protected float getAngleBisectorDegree() { - return 315; + super(cornerRadius, preBorderWidth, postBorderWidth, borderBox, 315); } @NonNull http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/utils/FunctionParser.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/FunctionParser.java b/android/sdk/src/main/java/com/taobao/weex/utils/FunctionParser.java index e138213..ba9103e 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/FunctionParser.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/FunctionParser.java @@ -227,12 +227,6 @@ public class FunctionParser<K, V> { return true; } - private void reset() { - pointer = 0; - value = null; - current = null; - } - private boolean isCharacterOrDigit(char letter) { return (ZERO <= letter && letter <= NINE) || (A_LOWER <= letter && letter <= Z_LOWER) || (A_UPPER <= letter && letter <= Z_UPPER); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/utils/LogLevel.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/LogLevel.java b/android/sdk/src/main/java/com/taobao/weex/utils/LogLevel.java index 95dfd8a..0e10fa1 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/LogLevel.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/LogLevel.java @@ -24,8 +24,8 @@ import android.util.Log; * Created by lixinke on 16/5/11. */ public enum LogLevel { - ERROR("error", 0, Log.ERROR), WARN("warn", 1,Log.WARN), INFO("info", 2,Log.INFO), - DEBUG("debug", 3,Log.DEBUG), VERBOSE("verbose", 4, Log.VERBOSE), ALL("debug", 5,Log.DEBUG),OFF("off",6,Log.DEBUG); + WTF("wtf", 0, Log.ASSERT), ERROR("error", 1, Log.ERROR), WARN("warn", 2,Log.WARN), INFO("info", 3,Log.INFO), + DEBUG("debug", 4,Log.DEBUG), VERBOSE("verbose", 5, Log.VERBOSE), ALL("debug", 6,Log.DEBUG),OFF("off",7,Log.DEBUG),; String name; int value; int priority; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/utils/OsVersion.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/OsVersion.java b/android/sdk/src/main/java/com/taobao/weex/utils/OsVersion.java index ef2f0c9..7c53095 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/OsVersion.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/OsVersion.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package com.taobao.weex.util; +package com.taobao.weex.utils; /** * Android OS version utilities. http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/utils/Trace.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/Trace.java b/android/sdk/src/main/java/com/taobao/weex/utils/Trace.java index 7506804..cfe307e 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/Trace.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/Trace.java @@ -21,8 +21,6 @@ package com.taobao.weex.utils; import android.annotation.TargetApi; import android.os.Build; -import com.taobao.weex.util.OsVersion; - /** * Hepler class for systrace. * @@ -82,7 +80,7 @@ public class Trace { /** * Writes a trace message to indicate that a given section of code has ended. - * This call must be preceeded by a corresponding call to {@link #beginSection()} + * This call must be preceeded by a corresponding call to {@link #beginSection(String)} * on the same thread. */ public static void endSection() { http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java index 43246ea..4f1b818 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXLogUtils.java @@ -105,6 +105,10 @@ public class WXLogUtils { d(tag,new String(msg)); } + public static void wtf(String msg){ + wtf(WEEX_TAG, msg); + } + public static void d(String tag, String msg) { if (WXEnvironment.isApkDebugable() && !TextUtils.isEmpty(msg) && WXEnvironment.sLogLevel.compare(LogLevel.DEBUG) >= 0) { Log.d(tag, msg); @@ -170,6 +174,10 @@ public class WXLogUtils { log(tag, msg,LogLevel.ERROR); } + public static void wtf(String tag, String msg){ + log(tag, msg, LogLevel.WTF); + } + /** * 'p' for 'Performance', use {@link #WEEX_PERF_TAG} * @param msg @@ -208,6 +216,12 @@ public class WXLogUtils { } } + public static void wtf(String prefix, Throwable e){ + if (WXEnvironment.isApkDebugable()) { + wtf(prefix + getStackTrace(e)); + } + } + /** * 'p' for 'Performance', use {@link #WEEX_PERF_TAG} */ http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java b/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java index fb9ab8b..7d11d5a 100644 --- a/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java +++ b/android/sdk/src/main/java/com/taobao/weex/utils/WXViewUtils.java @@ -40,6 +40,8 @@ import com.taobao.weex.WXSDKInstance; import com.taobao.weex.WXSDKManager; import com.taobao.weex.common.Constants; import com.taobao.weex.common.WXRuntimeException; +import com.taobao.weex.ui.flat.widget.Widget; +import com.taobao.weex.ui.flat.widget.WidgetGroup; import com.taobao.weex.ui.view.border.BorderDrawable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -389,6 +391,22 @@ public class WXViewUtils { } } + public static void clipCanvasWithinBorderBox(Widget widget, Canvas canvas) { + BorderDrawable borderDrawable; + if (clipCanvasDueToAndroidVersion(canvas) && + clipCanvasIfAnimationExist() && + (borderDrawable=widget.getBackgroundAndBorder())!=null ) { + if (borderDrawable.isRounded() && clipCanvasIfBackgroundImageExist(widget, borderDrawable)) { + Path path = borderDrawable.getContentPath( + new RectF(0, 0, widget.getBorderBox().width(), widget.getBorderBox().height())); + canvas.clipPath(path); + } + else { + canvas.clipRect(widget.getBorderBox()); + } + } + } + /** * According to https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported API 18 or higher supports clipPath to canvas based on hardware acceleration. @@ -436,4 +454,17 @@ public class WXViewUtils { } return true; } + + private static boolean clipCanvasIfBackgroundImageExist(@NonNull Widget widget, + @NonNull BorderDrawable borderDrawable) { + if (widget instanceof WidgetGroup) { + for (Widget child : ((WidgetGroup) widget).getChildren()) { + if (child.getBackgroundAndBorder().hasImage() && + Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + return false; + } + } + } + return true; + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/test/java/com/taobao/weex/ui/component/WXDivTest.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/test/java/com/taobao/weex/ui/component/WXDivTest.java b/android/sdk/src/test/java/com/taobao/weex/ui/component/WXDivTest.java index 53b52c3..480d5a6 100644 --- a/android/sdk/src/test/java/com/taobao/weex/ui/component/WXDivTest.java +++ b/android/sdk/src/test/java/com/taobao/weex/ui/component/WXDivTest.java @@ -18,6 +18,8 @@ */ package com.taobao.weex.ui.component; +import static org.junit.Assert.assertEquals; + import com.taobao.weappplus_sdk.BuildConfig; import com.taobao.weex.WXSDKInstance; import com.taobao.weex.WXSDKInstanceTest; @@ -25,21 +27,15 @@ import com.taobao.weex.dom.TestDomObject; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.dom.WXEvent; import com.taobao.weex.dom.flex.Spacing; - +import com.taobao.weex.ui.flat.FlatGUIContext; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import static org.junit.Assert.*; - /** * Created by gulin on 16/2/24. */ @@ -65,6 +61,7 @@ public class WXDivTest { public void setUp() throws Exception { WXSDKInstance instance = Mockito.mock(WXSDKInstance.class); Mockito.when(instance.getContext()).thenReturn(RuntimeEnvironment.application); + Mockito.when(instance.getFlatUIContext()).thenReturn(new FlatGUIContext()); WXDomObject divDom = new WXDomObject(); WXDomObject spy = Mockito.spy(divDom); @@ -80,6 +77,7 @@ public class WXDivTest { public void testAddChild(){ WXSDKInstance instance = Mockito.mock(WXSDKInstance.class); Mockito.when(instance.getContext()).thenReturn(RuntimeEnvironment.application); + Mockito.when(instance.getFlatUIContext()).thenReturn(new FlatGUIContext()); WXDomObject testDom = Mockito.mock(WXDomObject.class); Mockito.when(testDom.getPadding()).thenReturn(new Spacing()); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/test/java/com/taobao/weex/ui/component/WXTextTest.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/test/java/com/taobao/weex/ui/component/WXTextTest.java b/android/sdk/src/test/java/com/taobao/weex/ui/component/WXTextTest.java index 0181457..3b6700f 100644 --- a/android/sdk/src/test/java/com/taobao/weex/ui/component/WXTextTest.java +++ b/android/sdk/src/test/java/com/taobao/weex/ui/component/WXTextTest.java @@ -18,6 +18,11 @@ */ package com.taobao.weex.ui.component; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import com.taobao.weappplus_sdk.BuildConfig; import com.taobao.weex.WXEnvironment; import com.taobao.weex.WXSDKInstance; @@ -27,7 +32,9 @@ import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.dom.WXTextDomObject; import com.taobao.weex.dom.flex.Spacing; import com.taobao.weex.ui.SimpleComponentHolder; - +import com.taobao.weex.ui.flat.FlatGUIContext; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,14 +43,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - /** * Created by gulin on 16/2/4. */ @@ -60,6 +59,7 @@ public class WXTextTest { WXEnvironment.sApplication = RuntimeEnvironment.application; WXSDKInstance instance = Mockito.mock(WXSDKInstance.class); Mockito.when(instance.getContext()).thenReturn(RuntimeEnvironment.application); + Mockito.when(instance.getFlatUIContext()).thenReturn(new FlatGUIContext()); mParentDomObj = Mockito.spy(new WXDomObject()); Mockito.when(mParentDomObj.getPadding()).thenReturn(new Spacing()); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/android/sdk/src/test/java/com/taobao/weex/ui/module/WXTimerModuleTest.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/test/java/com/taobao/weex/ui/module/WXTimerModuleTest.java b/android/sdk/src/test/java/com/taobao/weex/ui/module/WXTimerModuleTest.java index 7fe508c..f4331b0 100644 --- a/android/sdk/src/test/java/com/taobao/weex/ui/module/WXTimerModuleTest.java +++ b/android/sdk/src/test/java/com/taobao/weex/ui/module/WXTimerModuleTest.java @@ -18,6 +18,8 @@ */ package com.taobao.weex.ui.module; +import static android.R.attr.end; +import static android.R.attr.start; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; @@ -61,6 +63,7 @@ public class WXTimerModuleTest { public final static int DELAY = 50; public final static int IMMEDIATELY = 0; public final static int INVALID_DELAY = -50; + public final static float FLOAT_DELAY = 20.6f; @Rule public PowerMockRule rule = new PowerMockRule(); @@ -84,7 +87,26 @@ public class WXTimerModuleTest { @Test public void testSetTimeoutDelay() throws Exception { module.setTimeout(VALID_FUNC_ID, DELAY); - mLooper.idle(DELAY); + long start, end, duration; + start = mLooper.getScheduler().getCurrentTime(); + mLooper.runOneTask(); + end = mLooper.getScheduler().getCurrentTime(); + duration = end - start; + + assertThat(duration, is((long) DELAY)); + Mockito.verify(module, times(1)).handleMessage(any(Message.class)); + } + + @Test + public void testSetTimeoutDelay2() throws Exception { + module.setTimeout(VALID_FUNC_ID, FLOAT_DELAY); + long start, end, duration; + start = mLooper.getScheduler().getCurrentTime(); + mLooper.runOneTask(); + end = mLooper.getScheduler().getCurrentTime(); + duration = end - start; + + assertThat(duration, is((long) FLOAT_DELAY)); Mockito.verify(module, times(1)).handleMessage(any(Message.class)); } @@ -164,6 +186,23 @@ public class WXTimerModuleTest { } @Test + public void testSetIntervalDelay2() { + long start, end, duration; + module.setInterval(VALID_FUNC_ID, FLOAT_DELAY); + + start = mLooper.getScheduler().getCurrentTime(); + mLooper.runOneTask(); + end = mLooper.getScheduler().getCurrentTime(); + duration = end - start; + + assertThat(duration, is((long) FLOAT_DELAY)); + + mLooper.runOneTask(); + mLooper.runOneTask(); + Mockito.verify(module, times(3)).handleMessage(any(Message.class)); + } + + @Test public void testClearTimeout() throws Exception { module.setTimeout(VALID_FUNC_ID, DELAY); module.clearTimeout(VALID_FUNC_ID); @@ -180,7 +219,7 @@ public class WXTimerModuleTest { } @Test - public void setClearTimeout2(){ + public void testClearTimeout2(){ module.setTimeout(NO_CACHING_FUNC_ID, DELAY); module.clearTimeout(NO_CACHING_FUNC_ID); mLooper.idle(DELAY, TimeUnit.MILLISECONDS); @@ -188,7 +227,7 @@ public class WXTimerModuleTest { } @Test - public void setClearInterval2(){ + public void testClearInterval2(){ module.setInterval(NO_CACHING_FUNC_ID, DELAY); module.clearInterval(NO_CACHING_FUNC_ID); mLooper.idle(DELAY, TimeUnit.MILLISECONDS); http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/dangerfile-android.js ---------------------------------------------------------------------- diff --git a/dangerfile-android.js b/dangerfile-android.js new file mode 100644 index 0000000..2e81f0a --- /dev/null +++ b/dangerfile-android.js @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// Removed import +import fs from "fs"; +import path from 'path'; +import GitHubApi from 'github'; +import parseDiff from 'parse-diff'; +import shell from "shelljs"; + +const type_unknown = 0; +const type_ios_sdk = 1; +const type_android_sdk = 2; +const type_ios_test = 3; +const type_android_test = 4; +const type_jsfm = 5; +const type_jsfm_test = 6; +const type_doc = 7; +const type_ui_test = 8; + +const getFileType = file => { + if (file.match(/WeexSDK\/Sources\/.+\.(m|h|mm)/)) { + return type_ios_sdk; + } else if (file.match(/WeexSDKTests\//)) { + return type_ios_test; + } else if (file.match(/android\/sdk\/src\/test\/.+\.java/)) { + return type_android_test; + } else if (file.match(/android\/sdk\/src\/main\/java\/.+\.java/)) { + return type_android_sdk; + } else if ( + file.match(/html5\/(shared|frameworks|render|runtime|services)\/.+\.js/) + ) { + return type_jsfm; + } else if (file.match(/html5\/test\/.+\.js/)) { + return type_jsfm_test; + } else if (file.match(/doc\/\.+\.md/)) { + return type_doc; + } else if(file.match(/test\/scripts\/.+\.js/) || file.match(/test\/pages\/.+\.vue/)){ + return type_ui_test + }else{ + return type_unknown + } +} + +function checkAndroidFile(file){ + var type = getFileType(file); + return type == type_android_test || type == type_android_sdk || type == type_jsfm; +} + +var hasAndroidFile = false; + +if (!hasAndroidFile && danger.git.created_files) { + danger.git.created_files.some(file => { + var f = checkAndroidFile(file); + if(f){ + hasAndroidFile =f; + } + return f; + }); +} +if (!hasAndroidFile && danger.git.modified_files) { + danger.git.modified_files.some(file => { + var f = checkAndroidFile(file); + if(f){ + hasAndroidFile =f; + } + return f; + }); +} +if (!hasAndroidFile && danger.git.deleted_files) { + danger.git.deleted_files.some(file => { + var f = checkAndroidFile(file); + if(f){ + hasAndroidFile =f; + } + return f; + }); +} + +if(hasAndroidFile){ + var runTestCmd='source ~/.bash_profile; ' + +'cd android; ' + +'./gradlew clean assembleDebug :weex_sdk:testDebugUnitTest --info -PdisableCov=true ' + +'-Dorg.gradle.daemon=true -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs="-Xmx512m ' + +'-XX:+HeapDumpOnOutOfMemoryError" -Dfile.encoding=UTF-8 ' + var runSuccess = shell.exec(runTestCmd,{ async: false, timeout: 8 * 60 * 1000 }).code == 0; + if(!runSuccess){ + fail("android platform run unit test failed!"); + } +}else{ + message('has no android file changed,skip test!'); +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/dangerfile-ios.js ---------------------------------------------------------------------- diff --git a/dangerfile-ios.js b/dangerfile-ios.js new file mode 100644 index 0000000..079e516 --- /dev/null +++ b/dangerfile-ios.js @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// Removed import +import fs from "fs"; +import path from 'path'; +import GitHubApi from 'github'; +import parseDiff from 'parse-diff'; +import shell from "shelljs"; + +const type_unknown = 0; +const type_ios_sdk = 1; +const type_android_sdk = 2; +const type_ios_test = 3; +const type_android_test = 4; +const type_jsfm = 5; +const type_jsfm_test = 6; +const type_doc = 7; +const type_ui_test = 8; + +const getFileType = file => { + if (file.match(/WeexSDK\/Sources\/.+\.(m|h|mm)/)) { + return type_ios_sdk; + } else if (file.match(/WeexSDKTests\//)) { + return type_ios_test; + } else if (file.match(/android\/sdk\/src\/test\/.+\.java/)) { + return type_android_test; + } else if (file.match(/android\/sdk\/src\/main\/java\/.+\.java/)) { + return type_android_sdk; + } else if ( + file.match(/html5\/(shared|frameworks|render|runtime|services)\/.+\.js/) + ) { + return type_jsfm; + } else if (file.match(/html5\/test\/.+\.js/)) { + return type_jsfm_test; + } else if (file.match(/doc\/\.+\.md/)) { + return type_doc; + } else if(file.match(/test\/scripts\/.+\.js/) || file.match(/test\/pages\/.+\.vue/)){ + return type_ui_test + }else{ + return type_unknown + } +} + +function checkIosFile(file){ + var type = getFileType(file); + return type == type_ios_sdk || type == type_ios_test || type == type_jsfm; +} + +var hasIosFile = false; + +if (!hasIosFile && danger.git.created_files) { + danger.git.created_files.some(file => { + var f = checkIosFile(file); + if(f){ + hasIosFile =f; + } + return f; + }); +} +if (!hasIosFile && danger.git.modified_files) { + danger.git.modified_files.some(file => { + var f = checkIosFile(file); + if(f){ + hasIosFile =f; + } + return f; + }); +} +if (!hasIosFile && danger.git.deleted_files) { + danger.git.deleted_files.some(file => { + var f = checkIosFile(file); + if(f){ + hasIosFile =f; + } + return f; + }); +} + +if(hasIosFile){ + var runTestCmd='source ~/.bash_profile; ' + +'xcodebuild -project ios/sdk/WeexSDK.xcodeproj test ' + +'-scheme WeexSDKTests CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ' + +'-destination "platform=iOS Simulator,name=iPhone 6"' + runSuccess = shell.exec(runTestCmd,{ async: false, timeout: 8 * 60 * 1000 }).code == 0; + if(!runSuccess){ + fail("ios platform run unit test failed!"); + } +}else{ + message('has no ios file changed,skip test!'); +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/dangerfile-jsfm.js ---------------------------------------------------------------------- diff --git a/dangerfile-jsfm.js b/dangerfile-jsfm.js new file mode 100644 index 0000000..64b72f4 --- /dev/null +++ b/dangerfile-jsfm.js @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// Removed import +import fs from "fs"; +import path from 'path'; +import GitHubApi from 'github'; +import parseDiff from 'parse-diff'; +import shell from "shelljs"; + +const type_unknown = 0; +const type_ios_sdk = 1; +const type_android_sdk = 2; +const type_ios_test = 3; +const type_android_test = 4; +const type_jsfm = 5; +const type_jsfm_test = 6; +const type_doc = 7; +const type_ui_test = 8; + +const getFileType = file => { + if (file.match(/WeexSDK\/Sources\/.+\.(m|h|mm)/)) { + return type_ios_sdk; + } else if (file.match(/WeexSDKTests\//)) { + return type_ios_test; + } else if (file.match(/android\/sdk\/src\/test\/.+\.java/)) { + return type_android_test; + } else if (file.match(/android\/sdk\/src\/main\/java\/.+\.java/)) { + return type_android_sdk; + } else if ( + file.match(/html5\/(shared|frameworks|render|runtime|services)\/.+\.js/) + ) { + return type_jsfm; + } else if (file.match(/html5\/test\/.+\.js/)) { + return type_jsfm_test; + } else if (file.match(/doc\/\.+\.md/)) { + return type_doc; + } else if(file.match(/test\/scripts\/.+\.js/) || file.match(/test\/pages\/.+\.vue/)){ + return type_ui_test + }else{ + return type_unknown + } +} + +function checkJsfmFile(file){ + var type = getFileType(file); + return type == type_jsfm || type == type_jsfm_test; +} + +var hasJsfmFile = false; + +if (!hasJsfmFile && danger.git.created_files) { + danger.git.created_files.some(file => { + var f = checkJsfmFile(file); + if(f){ + hasJsfmFile =f; + } + return f; + }); +} +if (!hasJsfmFile && danger.git.modified_files) { + danger.git.modified_files.some(file => { + var f = checkJsfmFile(file); + if(f){ + hasJsfmFile =f; + } + return f; + }); +} +if (!hasJsfmFile && danger.git.deleted_files) { + danger.git.deleted_files.some(file => { + var f = checkJsfmFile(file); + if(f){ + hasJsfmFile =f; + } + return f; + }); +} + +if(hasJsfmFile){ + var runTestCmd='source ~/.bash_profile; ' + + 'npm run build && npm run test' + var runSuccess = shell.exec(runTestCmd,{ async: false, timeout: 8 * 60 * 1000 }).code == 0; + if(!runSuccess){ + fail("jsfm run test failed!"); + } +}else{ + message('has no jsfm file changed,skip test!'); +} + http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj index d43ec0e..3802d0e 100644 --- a/ios/sdk/WeexSDK.xcodeproj/project.pbxproj +++ b/ios/sdk/WeexSDK.xcodeproj/project.pbxproj @@ -48,8 +48,6 @@ 591DD3321D23AD5800BE8709 /* WXErrorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 591DD3301D23AD5800BE8709 /* WXErrorView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 594C28921CF9E61A009793A4 /* WXAnimationModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 594C28901CF9E61A009793A4 /* WXAnimationModule.m */; }; 594C28931CF9E61A009793A4 /* WXAnimationModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 594C28911CF9E61A009793A4 /* WXAnimationModule.h */; }; - 59597F981D2A041700EE9317 /* WXDebugLoggerBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 59597F961D2A041700EE9317 /* WXDebugLoggerBridge.h */; }; - 59597F991D2A041700EE9317 /* WXDebugLoggerBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 59597F971D2A041700EE9317 /* WXDebugLoggerBridge.m */; }; 596FDD661D3F52700082CD5B /* WXAnimationModuleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 596FDD651D3F52700082CD5B /* WXAnimationModuleTests.m */; }; 596FDD691D3F9EFF0082CD5B /* TestSupportUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 596FDD681D3F9EFF0082CD5B /* TestSupportUtils.m */; }; 597334B11D4D9E7F00988789 /* WXSDKManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 597334B01D4D9E7F00988789 /* WXSDKManagerTests.m */; }; @@ -85,7 +83,6 @@ 740451EB1E14BB26004157CB /* WXServiceFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 740451E91E14BB26004157CB /* WXServiceFactory.m */; }; 7408C48E1CFB345D000BCCD0 /* WXComponent+Events.h in Headers */ = {isa = PBXBuildFile; fileRef = 7408C48C1CFB345D000BCCD0 /* WXComponent+Events.h */; }; 7408C48F1CFB345D000BCCD0 /* WXComponent+Events.m in Sources */ = {isa = PBXBuildFile; fileRef = 7408C48D1CFB345D000BCCD0 /* WXComponent+Events.m */; }; - 740938EC1D3D075700DBB801 /* SRWebSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A27E7D81C3E360B00D7A552 /* SRWebSocket.m */; }; 740938EE1D3D079100DBB801 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 740938ED1D3D079100DBB801 /* JavaScriptCore.framework */; }; 740938EF1D3D083900DBB801 /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 7469869B1C4DEAC20054A57E /* libicucore.tbd */; }; 740938F31D3D0D9300DBB801 /* WXComponentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 740938EA1D3D026600DBB801 /* WXComponentTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; @@ -243,8 +240,6 @@ C42E8FAB1F3C7C09001EBE9D /* WXExtendCallNativeProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = C4424E591F24DA3D009F52E2 /* WXExtendCallNativeProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; C42E8FAC1F3C7C3B001EBE9D /* WXExtendCallNativeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C47B78CD1F2998EE001D3B0C /* WXExtendCallNativeManager.m */; }; C42E8FAD1F3C7C3F001EBE9D /* WXExtendCallNativeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C47B78CC1F2998EE001D3B0C /* WXExtendCallNativeManager.h */; }; - C42E8FAE1F3C7C49001EBE9D /* WXRecyclerDragController.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7764911F3C2CA300B5727E /* WXRecyclerDragController.m */; }; - C42E8FAF1F3C7C4B001EBE9D /* WXRecyclerDragController.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7764921F3C2CA300B5727E /* WXRecyclerDragController.h */; }; C43C03E81EC8ACA40044C7FF /* WXPrerenderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C43C03E41EC8ACA40044C7FF /* WXPrerenderManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; C43C03E91EC8ACA40044C7FF /* WXPrerenderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C43C03E51EC8ACA40044C7FF /* WXPrerenderManager.m */; }; C4424E5B1F24DA3D009F52E2 /* WXExtendCallNativeProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = C4424E591F24DA3D009F52E2 /* WXExtendCallNativeProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -264,10 +259,6 @@ C4E375381E5FCBD3009B2D9C /* WXComponent+BoxShadow.h in Headers */ = {isa = PBXBuildFile; fileRef = C4E375361E5FCBD3009B2D9C /* WXComponent+BoxShadow.h */; }; C4E97D331F1EF46D00ABC314 /* WXTracingManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C4E97D311F1EF46D00ABC314 /* WXTracingManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; C4E97D341F1EF46D00ABC314 /* WXTracingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C4E97D321F1EF46D00ABC314 /* WXTracingManager.m */; }; - C4F012791E1502A6003378D0 /* SRWebSocket+Weex.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F012721E1502A6003378D0 /* SRWebSocket+Weex.h */; }; - C4F0127A1E1502A6003378D0 /* SRWebSocket+Weex.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F012731E1502A6003378D0 /* SRWebSocket+Weex.m */; }; - C4F0127B1E1502A6003378D0 /* WXWebSocketDefaultImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F012741E1502A6003378D0 /* WXWebSocketDefaultImpl.h */; }; - C4F0127C1E1502A6003378D0 /* WXWebSocketDefaultImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F012751E1502A6003378D0 /* WXWebSocketDefaultImpl.m */; }; C4F0127D1E1502A6003378D0 /* WXWebSocketHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F012761E1502A6003378D0 /* WXWebSocketHandler.h */; }; C4F012821E1502E9003378D0 /* WXWebSocketModule.h in Headers */ = {isa = PBXBuildFile; fileRef = C4F012801E1502E9003378D0 /* WXWebSocketModule.h */; }; C4F012831E1502E9003378D0 /* WXWebSocketModule.m in Sources */ = {isa = PBXBuildFile; fileRef = C4F012811E1502E9003378D0 /* WXWebSocketModule.m */; }; @@ -588,8 +579,6 @@ 1D3000F01D40B9AB004F3B4F /* WXClipboardModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXClipboardModule.m; sourceTree = "<group>"; }; 2A1F57B51C75C6A600B58017 /* WXTextInputComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXTextInputComponent.h; sourceTree = "<group>"; }; 2A1F57B61C75C6A600B58017 /* WXTextInputComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXTextInputComponent.m; sourceTree = "<group>"; }; - 2A27E7D71C3E360B00D7A552 /* SRWebSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRWebSocket.h; path = dependency/SRWebSocket.h; sourceTree = "<group>"; }; - 2A27E7D81C3E360B00D7A552 /* SRWebSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRWebSocket.m; path = dependency/SRWebSocket.m; sourceTree = "<group>"; }; 2A42AF851C23B33E00818EA6 /* libWeexSDK_MTL.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libWeexSDK_MTL.a; sourceTree = BUILT_PRODUCTS_DIR; }; 2A42AF871C23B33E00818EA6 /* WeexSDK_MTL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WeexSDK_MTL.h; sourceTree = "<group>"; }; 2A42AF891C23B33E00818EA6 /* WeexSDK_MTL.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WeexSDK_MTL.m; sourceTree = "<group>"; }; @@ -624,8 +613,6 @@ 591DD3301D23AD5800BE8709 /* WXErrorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXErrorView.h; sourceTree = "<group>"; }; 594C28901CF9E61A009793A4 /* WXAnimationModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXAnimationModule.m; sourceTree = "<group>"; }; 594C28911CF9E61A009793A4 /* WXAnimationModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXAnimationModule.h; sourceTree = "<group>"; }; - 59597F961D2A041700EE9317 /* WXDebugLoggerBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXDebugLoggerBridge.h; sourceTree = "<group>"; }; - 59597F971D2A041700EE9317 /* WXDebugLoggerBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXDebugLoggerBridge.m; sourceTree = "<group>"; }; 596FDD651D3F52700082CD5B /* WXAnimationModuleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXAnimationModuleTests.m; sourceTree = "<group>"; }; 596FDD671D3F9EFF0082CD5B /* TestSupportUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestSupportUtils.h; sourceTree = "<group>"; }; 596FDD681D3F9EFF0082CD5B /* TestSupportUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestSupportUtils.m; sourceTree = "<group>"; }; @@ -838,10 +825,6 @@ C4E375361E5FCBD3009B2D9C /* WXComponent+BoxShadow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WXComponent+BoxShadow.h"; sourceTree = "<group>"; }; C4E97D311F1EF46D00ABC314 /* WXTracingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXTracingManager.h; sourceTree = "<group>"; }; C4E97D321F1EF46D00ABC314 /* WXTracingManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXTracingManager.m; sourceTree = "<group>"; }; - C4F012721E1502A6003378D0 /* SRWebSocket+Weex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SRWebSocket+Weex.h"; sourceTree = "<group>"; }; - C4F012731E1502A6003378D0 /* SRWebSocket+Weex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SRWebSocket+Weex.m"; sourceTree = "<group>"; }; - C4F012741E1502A6003378D0 /* WXWebSocketDefaultImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXWebSocketDefaultImpl.h; sourceTree = "<group>"; }; - C4F012751E1502A6003378D0 /* WXWebSocketDefaultImpl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXWebSocketDefaultImpl.m; sourceTree = "<group>"; }; C4F012761E1502A6003378D0 /* WXWebSocketHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXWebSocketHandler.h; sourceTree = "<group>"; }; C4F012801E1502E9003378D0 /* WXWebSocketModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXWebSocketModule.h; sourceTree = "<group>"; }; C4F012811E1502E9003378D0 /* WXWebSocketModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXWebSocketModule.m; sourceTree = "<group>"; }; @@ -929,15 +912,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 2A27E7D61C3E360400D7A552 /* dependency */ = { - isa = PBXGroup; - children = ( - 2A27E7D71C3E360B00D7A552 /* SRWebSocket.h */, - 2A27E7D81C3E360B00D7A552 /* SRWebSocket.m */, - ); - name = dependency; - sourceTree = "<group>"; - }; 2A42AF861C23B33E00818EA6 /* WeexSDK_MTL */ = { isa = PBXGroup; children = ( @@ -1166,7 +1140,6 @@ 77D160FF1C02DBE70010B15B /* WeexSDK */ = { isa = PBXGroup; children = ( - 2A27E7D61C3E360400D7A552 /* dependency */, 77D161171C02DCB90010B15B /* Resources */, 77D161181C02DCB90010B15B /* Sources */, ); @@ -1221,8 +1194,6 @@ 74862F801E03A24500B7A041 /* WXComponentMethod.m */, 74D2051E1E091B8000128F44 /* WXCallJSMethod.h */, 74D2051F1E091B8000128F44 /* WXCallJSMethod.m */, - 59597F961D2A041700EE9317 /* WXDebugLoggerBridge.h */, - 59597F971D2A041700EE9317 /* WXDebugLoggerBridge.m */, 59A582FA1CF5B17B0081FD3E /* WXBridgeContext.h */, 59A582FB1CF5B17B0081FD3E /* WXBridgeContext.m */, 77D1613A1C02DEA60010B15B /* WXJSCoreBridge.h */, @@ -1476,10 +1447,6 @@ C4F012711E1502A6003378D0 /* WebSocket */ = { isa = PBXGroup; children = ( - C4F012721E1502A6003378D0 /* SRWebSocket+Weex.h */, - C4F012731E1502A6003378D0 /* SRWebSocket+Weex.m */, - C4F012741E1502A6003378D0 /* WXWebSocketDefaultImpl.h */, - C4F012751E1502A6003378D0 /* WXWebSocketDefaultImpl.m */, C4F012761E1502A6003378D0 /* WXWebSocketHandler.h */, ); path = WebSocket; @@ -1531,7 +1498,6 @@ 1D3000F11D40B9AC004F3B4F /* WXClipboardModule.h in Headers */, 59A583081CF5B2FD0081FD3E /* WXNavigationDefaultImpl.h in Headers */, 775BEE4E1C16F993008D1629 /* WXDefine.h in Headers */, - 59597F981D2A041700EE9317 /* WXDebugLoggerBridge.h in Headers */, 77D161241C02DDD10010B15B /* WXSDKInstance.h in Headers */, DC6836E61EBB12B200AD2D84 /* WXConfigCenterProtocol.h in Headers */, DC7764941F3C2CA300B5727E /* WXRecyclerDragController.h in Headers */, @@ -1575,7 +1541,6 @@ 744D61141E4AF23E00B624B3 /* WXDiffUtil.h in Headers */, 74862F791E02B88D00B7A041 /* JSValue+Weex.h in Headers */, 2A1F57B71C75C6A600B58017 /* WXTextInputComponent.h in Headers */, - C4F012791E1502A6003378D0 /* SRWebSocket+Weex.h in Headers */, 74A4BA9A1CB3BAA100195969 /* WXThreadSafeMutableDictionary.h in Headers */, 74A4BA9E1CB3C0A100195969 /* WXHandlerFactory.h in Headers */, 741DFE021DDD7D18009B020F /* WXRoundedRect.h in Headers */, @@ -1604,7 +1569,6 @@ 77E65A0D1C155E99008B8775 /* WXDivComponent.h in Headers */, C41E1A971DC1FD15009C7F90 /* WXDatePickerManager.h in Headers */, 333D9A271F41507A007CED39 /* WXTransition.h in Headers */, - C4F0127B1E1502A6003378D0 /* WXWebSocketDefaultImpl.h in Headers */, 7461F8901CFB373100F62D44 /* WXDisplayQueue.h in Headers */, DCC77C141D770AE300CE7288 /* WXSliderNeighborComponent.h in Headers */, 747DF6821E31AEE4005C53A8 /* WXLength.h in Headers */, @@ -1674,7 +1638,6 @@ 333D9A281F41507A007CED39 /* WXTransition.h in Headers */, DCA445A51EFA571600D0CFA8 /* WXSDKError.h in Headers */, DCA445AD1EFA575100D0CFA8 /* WXNavigationProtocol.h in Headers */, - C42E8FAF1F3C7C4B001EBE9D /* WXRecyclerDragController.h in Headers */, DCA445B01EFA576200D0CFA8 /* WXModalUIModule.h in Headers */, DCA445A61EFA571E00D0CFA8 /* WXSDKEngine.h in Headers */, DCA445AA1EFA573900D0CFA8 /* WXResourceRequest.h in Headers */, @@ -2019,7 +1982,6 @@ DC9F46831D61AC8800A88239 /* WXStreamModuleTests.m in Sources */, 1C1A2BED1D91172800539AA1 /* WXConvertTests.m in Sources */, 74EF31C31DE6935600667A07 /* WXURLRewriteTests.m in Sources */, - 740938EC1D3D075700DBB801 /* SRWebSocket.m in Sources */, 740938F31D3D0D9300DBB801 /* WXComponentTests.m in Sources */, 596FDD661D3F52700082CD5B /* WXAnimationModuleTests.m in Sources */, 591324A31D49B7F1004E89ED /* WXTimerModuleTests.m in Sources */, @@ -2043,7 +2005,6 @@ 74B8BEFF1DC47B72004A6027 /* WXRootView.m in Sources */, 742AD7321DF98C45007DC46C /* WXResourceRequestHandlerDefaultImpl.m in Sources */, 747DF6831E31AEE4005C53A8 /* WXLength.m in Sources */, - C4F0127C1E1502A6003378D0 /* WXWebSocketDefaultImpl.m in Sources */, 77E65A0E1C155E99008B8775 /* WXDivComponent.m in Sources */, 2A60CE9D1C91733E00857B9F /* WXSwitchComponent.m in Sources */, 744D61111E49979000B624B3 /* WXFooterComponent.m in Sources */, @@ -2093,7 +2054,6 @@ 746319031C60AFC100EFEBD4 /* WXThreadSafeCounter.m in Sources */, 74A4BAA71CB4F98300195969 /* WXStreamModule.m in Sources */, 744D610D1E49978200B624B3 /* WXHeaderComponent.m in Sources */, - 59597F991D2A041700EE9317 /* WXDebugLoggerBridge.m in Sources */, 77E659F21C0C3612008B8775 /* WXModuleFactory.m in Sources */, DCF343681E49CAEE00A2FB34 /* WXJSExceptionInfo.m in Sources */, 59CE27E91CC387DB000BE37A /* WXEmbedComponent.m in Sources */, @@ -2152,7 +2112,6 @@ 77D1614C1C02E3790010B15B /* WXConvert.m in Sources */, 749DC27C1D40827B009E1C91 /* WXMonitor.m in Sources */, C4B834271DE69B09007AD27E /* WXPickerModule.m in Sources */, - C4F0127A1E1502A6003378D0 /* SRWebSocket+Weex.m in Sources */, 745B2D691E5A8E1E0092D38A /* WXMultiColumnLayout.m in Sources */, 77D161391C02DE940010B15B /* WXBridgeManager.m in Sources */, ); @@ -2243,7 +2202,6 @@ DCA4457A1EFA55B300D0CFA8 /* WXSimulatorShortcutManager.m in Sources */, DCA4457B1EFA55B300D0CFA8 /* WXAssert.m in Sources */, DCA4457C1EFA55B300D0CFA8 /* WXAppConfiguration.m in Sources */, - C42E8FAE1F3C7C49001EBE9D /* WXRecyclerDragController.m in Sources */, DCA4457D1EFA55B300D0CFA8 /* WXThreadSafeMutableDictionary.m in Sources */, DCA4457E1EFA55B300D0CFA8 /* WXThreadSafeMutableArray.m in Sources */, DCA4457F1EFA55B300D0CFA8 /* NSObject+WXSwizzle.m in Sources */, http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.h b/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.h deleted file mode 100644 index c86b12e..0000000 --- a/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#import "WXBridgeProtocol.h" - -@interface WXDebugLoggerBridge : NSObject <WXBridgeProtocol> - -- (instancetype)initWithURL:(NSURL *) URL; - -@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m b/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m deleted file mode 100644 index fcc4cb3..0000000 --- a/ios/sdk/WeexSDK/Sources/Bridge/WXDebugLoggerBridge.m +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#import "WXDebugLoggerBridge.h" -#import "SRWebSocket.h" -#import "WXSDKManager.h" -#import "WXUtility.h" -#import "WXLog.h" - -@interface WXDebugLoggerBridge()<SRWebSocketDelegate> - -@end - -@implementation WXDebugLoggerBridge -{ - BOOL _isConnect; - SRWebSocket *_webSocket; - NSMutableArray *_msgAry; - WXJSCallNative _nativeCallBlock; - NSThread *_curThread; -} - -- (void)dealloc -{ - _nativeCallBlock = nil; - [self _disconnect]; -} - -- (instancetype)initWithURL:(NSURL *) URL -{ - self = [super init]; - - _isConnect = NO; - _curThread = [NSThread currentThread]; - - [self _connect:URL]; - - return self; -} - -- (void)_initEnvironment -{ - [self callJSMethod:@"setEnvironment" args:@[[WXUtility getEnvironment]]]; -} - -- (void)_disconnect -{ - _msgAry = nil; - _isConnect = NO; - _webSocket.delegate = nil; - [_webSocket close]; - _webSocket = nil; -} - -- (void)_connect:(NSURL *)URL -{ - _msgAry = nil; - _msgAry = [NSMutableArray array]; - _webSocket.delegate = nil; - [_webSocket close]; - - _webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:URL]]; - _webSocket.delegate = self; - - [_webSocket open]; -} - --(void)_executionMsgAry -{ - if (!_isConnect) return; - - NSArray *templateContainers = [NSArray arrayWithArray:_msgAry]; - for (NSString *msg in templateContainers) { - [_webSocket send:msg]; - } - [_msgAry removeAllObjects]; -} - --(void)_evaluateNative:(NSString *)data -{ - NSDictionary *dict = [WXUtility objectFromJSON:data]; - NSString *method = [dict objectForKey:@"method"]; - NSArray *args = [dict objectForKey:@"arguments"]; - - if ([method isEqualToString:@"callNative"]) { - // call native - NSString *instanceId = args[0]; - NSArray *methods = args[1]; - NSString *callbackId = args[2]; - - // params parse - if(!methods || methods.count <= 0){ - return; - } - //call native - WXLogDebug(@"Calling native... instanceId:%@, methods:%@, callbackId:%@", instanceId, [WXUtility JSONString:methods], callbackId); - _nativeCallBlock(instanceId, methods, callbackId); - } else if ([method isEqualToString:@"setLogLevel"]) { - NSString *levelString = [args firstObject]; - [WXLog setLogLevelString:levelString]; - } -} - -#pragma mark - WXBridgeProtocol - -- (void)executeJavascript:(NSString *)script -{ - [self callJSMethod:@"evalFramework" args:@[script]]; -} - -- (void)executeJSFramework:(NSString *)frameworkScript -{ - [self callJSMethod:@"evalFramework" args:@[frameworkScript]]; -} - -- (JSValue *)callJSMethod:(NSString *)method args:(NSArray *)args -{ - if (![method isEqualToString:@"__logger"]) { - // prevent recursion - WXLogDebug(@"Calling JS... method:%@, args:%@", method, [WXUtility JSONString:args]); - } - - NSMutableDictionary *dict = [NSMutableDictionary dictionary]; - [dict setObject:method forKey:@"method"]; - [dict setObject:args forKey:@"arguments"]; - - [_msgAry addObject:[WXUtility JSONString:dict]]; - [self _executionMsgAry]; - - return nil; -} - -- (void)registerCallNative:(WXJSCallNative)callNative -{ - _nativeCallBlock = callNative; -} - -- (JSValue*) exception -{ - return nil; -} - -- (void)resetEnvironment -{ - [self _initEnvironment]; -} - -- (void)garbageCollect -{ - -} - -- (void)executeBridgeThead:(dispatch_block_t)block -{ - if([NSThread currentThread] == _curThread){ - block(); - } else { - [self performSelector:@selector(executeBridgeThead:) - onThread:_curThread - withObject:[block copy] - waitUntilDone:NO]; - } -} - -#pragma mark - SRWebSocketDelegate - -- (void)webSocketDidOpen:(SRWebSocket *)webSocket; -{ - WXLogWarning(@"Websocket Connected:%@", webSocket.url); - _isConnect = YES; - [self _initEnvironment]; - __weak typeof(self) weakSelf = self; - [self executeBridgeThead:^() { - [weakSelf _executionMsgAry]; - }]; -} - -- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error; -{ - WXLogError(@":( Websocket Failed With Error %@", error); -} - -- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message; -{ - __weak typeof(self) weakSelf = self; - [self executeBridgeThead:^() { - [weakSelf _evaluateNative:message]; - }]; -} - -- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean -{ - WXLogInfo(@"Websocket closed with code: %ld, reason:%@, wasClean: %d", (long)code, reason, wasClean); - _isConnect = NO; -} - -@end http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m index dd776a9..fb07935 100644 --- a/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m +++ b/ios/sdk/WeexSDK/Sources/Bridge/WXJSCoreBridge.m @@ -46,6 +46,8 @@ @property (nonatomic, strong) JSContext *jsContext; @property (nonatomic, strong) NSMutableArray *timers; +@property (nonatomic, strong) NSMutableDictionary *intervaltimers; +@property (nonatomic) long long intervalTimerId; @property (nonatomic, strong) NSMutableDictionary *callbacks; @end @@ -63,7 +65,9 @@ } _timers = [NSMutableArray new]; _callbacks = [NSMutableDictionary new]; - + _intervalTimerId = 0; + _intervaltimers = [NSMutableDictionary new]; + __weak typeof(self) weakSelf = self; NSDictionary *data = [WXUtility getEnvironment]; @@ -76,16 +80,19 @@ } afterDelay:[timeout toDouble] / 1000]; }; - _jsContext[@"setTimeoutWeex"] = ^(JSValue *appid, JSValue *ret,JSValue *arg ) { - [weakSelf triggerTimeout:[appid toString] ret:[ret toString] arg:[arg toString]]; + _jsContext[@"setTimeoutWeex"] = ^(JSValue *appId, JSValue *ret,JSValue *arg ) { + [weakSelf triggerTimeout:[appId toString] ret:[ret toString] arg:[arg toString]]; }; - _jsContext[@"setIntervalWeex"] = ^(JSValue *appid, JSValue *ret,JSValue *arg) { - [weakSelf triggerInterval:[appid toString] ret:[ret toString] arg:[arg toString]]; + _jsContext[@"setIntervalWeex"] = ^(JSValue *appId, JSValue *function,JSValue *arg) { + return [weakSelf triggerInterval:[appId toString] function:^() { + [function callWithArguments:@[]]; + } arg:[arg toString]]; }; - _jsContext[@"clearIntervalWeex"] = ^(JSValue *appid, JSValue *ret,JSValue *arg) { - [weakSelf triggerClearInterval:[appid toString] ret:[ret toString] arg:[arg toString]]; + _jsContext[@"clearIntervalWeex"] = ^(JSValue *appId, JSValue *ret,JSValue *arg) { + + [weakSelf triggerClearInterval:[appId toString] ret:[[ret toNumber] longLongValue]]; }; _jsContext[@"clearTimeoutWeex"] = ^(JSValue *ret) { @@ -411,6 +418,7 @@ #pragma mark - Public -(void)removeTimers:(NSString *)instance { + // remove timers if([_callbacks objectForKey:instance]){ NSMutableArray *arr = [_callbacks objectForKey:instance]; if(arr && [arr count]>0){ @@ -421,6 +429,10 @@ } } } + // remove intervaltimers + if(_intervaltimers && [_intervaltimers objectForKey:instance]){ + [_intervaltimers removeObjectForKey:instance]; + } } #pragma mark - Private @@ -451,20 +463,25 @@ - (void)callBack:(NSDictionary *)dic { if([dic objectForKey:@"ret"] && [_timers containsObject:[dic objectForKey:@"ret"]]) { - [[WXSDKManager bridgeMgr] callBack:[dic objectForKey:@"appid"] funcId:[dic objectForKey:@"ret"] params:[dic objectForKey:@"arg"] keepAlive:NO]; + [[WXSDKManager bridgeMgr] callBack:[dic objectForKey:@"appId"] funcId:[dic objectForKey:@"ret"] params:[dic objectForKey:@"arg"] keepAlive:NO]; } + } -- (void)callBackInterval:(NSDictionary *)dic +- (void)callBackInterval:(NSDictionary *)dic functon:(void(^)())block { - if([dic objectForKey:@"ret"] && [_timers containsObject:[dic objectForKey:@"ret"]]) { - [[WXSDKManager bridgeMgr] callBack:[dic objectForKey:@"appid"] funcId:[dic objectForKey:@"ret"] params:nil keepAlive:YES]; - [self triggerInterval:[dic objectForKey:@"appid"] ret:[dic objectForKey:@"ret"] arg:[dic objectForKey:@"arg"]]; + if([dic objectForKey:@"appId"] && [_intervaltimers objectForKey:[dic objectForKey:@"appId"]]){ + NSMutableArray *timers = [_intervaltimers objectForKey:[dic objectForKey:@"appId"]]; + if([timers containsObject:[dic objectForKey:@"timerId"]]){ + block(); + [self executeInterval:[dic objectForKey:@"appId"] function:block arg:[dic objectForKey:@"arg"] timerId:[[dic objectForKey:@"timerId"] longLongValue]]; + } } } -- (void)triggerTimeout:(NSString *)appid ret:(NSString *)ret arg:(NSString *)arg + +- (void)triggerTimeout:(NSString *)appId ret:(NSString *)ret arg:(NSString *)arg { double interval = [arg doubleValue]/1000.0f; @@ -473,42 +490,60 @@ } if(![_timers containsObject:ret]){ [_timers addObject:ret]; - [self addInstance:appid callback:ret]; + [self addInstance:appId callback:ret]; } + __weak typeof(self) weakSelf = self; dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, interval*NSEC_PER_SEC); dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSMutableDictionary *dic = [NSMutableDictionary new]; - [dic setObject:appid forKey:@"appid"]; + [dic setObject:appId forKey:@"appId"]; [dic setObject:ret forKey:@"ret"]; [dic setObject:arg forKey:@"arg"]; - [self performSelector:@selector(callBack:) withObject:dic ]; + [weakSelf performSelector:@selector(callBack:) withObject:dic ]; }); } -- (void)triggerInterval:(NSString *)appid ret:(NSString *)ret arg:(NSString *)arg +- (long long)triggerInterval:(NSString *)appId function:(void(^)())block arg:(NSString *)arg { double interval = [arg doubleValue]/1000.0f; + long long timerId = _intervalTimerId + 1; if(WXFloatEqual(interval,0)) { - return; + return timerId; } - if(![_timers containsObject:ret]){ - [_timers addObject:ret]; - [self addInstance:appid callback:ret]; + if([_intervaltimers objectForKey:appId]){ + NSMutableArray *timers = [[_intervaltimers objectForKey:appId] mutableCopy]; + [timers addObject:@(timerId)]; + [_intervaltimers setObject:timers forKey:appId]; + }else { + NSMutableArray *timers = [NSMutableArray new]; + [timers addObject:@(timerId)]; + [_intervaltimers setObject:timers forKey:appId]; } + [self executeInterval:appId function:block arg:arg timerId:timerId]; + return timerId; +} + +-(void)executeInterval:(NSString *)appId function:(void(^)())block arg:(NSString *)arg timerId:(long long)timerId +{ + double interval = [arg doubleValue]/1000.0f; dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, interval*NSEC_PER_SEC); + __weak typeof(self) weakSelf = self; dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSMutableDictionary *dic = [NSMutableDictionary new]; - [dic setObject:appid forKey:@"appid"]; - [dic setObject:ret forKey:@"ret"]; + [dic setObject:appId forKey:@"appId"]; [dic setObject:arg forKey:@"arg"]; - [self performSelector:@selector(callBackInterval:) withObject:dic ]; + [dic setObject:@(timerId) forKey:@"timerId"]; + [weakSelf performSelector:@selector(callBackInterval:functon:) withObject:dic withObject:block]; }); } -- (void)triggerClearInterval:(NSString *)appid ret:(NSString *)ret arg:(NSString *)arg +- (void)triggerClearInterval:(NSString *)appId ret:(long long)ret { - if([_timers containsObject:ret]){ - [_timers removeObject:ret]; + if(_intervaltimers && [_intervaltimers objectForKey:@"appId"]){ + NSMutableArray *timers = [_intervaltimers objectForKey:@"appId"]; + if(timers && [timers containsObject:@(ret)]){ + [timers removeObject:@(ret)]; + } } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Component/Recycler/WXMultiColumnLayout.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/Recycler/WXMultiColumnLayout.m b/ios/sdk/WeexSDK/Sources/Component/Recycler/WXMultiColumnLayout.m index e99e88f..8622ef8 100644 --- a/ios/sdk/WeexSDK/Sources/Component/Recycler/WXMultiColumnLayout.m +++ b/ios/sdk/WeexSDK/Sources/Component/Recycler/WXMultiColumnLayout.m @@ -182,19 +182,29 @@ NSString * const kMultiColumnLayoutCell = @"WXMultiColumnLayoutCell"; } // cells - for (NSInteger item = 0; item < [self.collectionView numberOfItemsInSection:section]; item++) { - NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; - CGFloat itemHeight = [self.delegate collectionView:self.collectionView layout:self heightForItemAtIndexPath:indexPath]; - UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; - NSUInteger column = [self _minHeightColumnForAllColumns]; - CGFloat x = insets.left + (columnWidth + columnGap) * column; - CGFloat y = [self.columnsMaxHeights[column] floatValue]; - itemAttributes.frame = CGRectMake(x, y, columnWidth, itemHeight); - cellAttributes[indexPath] = itemAttributes; - - self.columnsMaxHeights[column] = @(CGRectGetMaxY(itemAttributes.frame)); + + @try { + for (NSInteger item = 0; item < [self.collectionView numberOfItemsInSection:section]; item++) { + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + CGFloat itemHeight = [self.delegate collectionView:self.collectionView layout:self heightForItemAtIndexPath:indexPath]; + UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; + NSUInteger column = [self _minHeightColumnForAllColumns]; + CGFloat x = insets.left + (columnWidth + columnGap) * column; + if (column >= [self.columnsMaxHeights count]) { + return; + } + CGFloat y = [self.columnsMaxHeights[column] floatValue]; + itemAttributes.frame = CGRectMake(x, y, columnWidth, itemHeight); + cellAttributes[indexPath] = itemAttributes; + + self.columnsMaxHeights[column] = @(CGRectGetMaxY(itemAttributes.frame)); + } + } @catch (NSException *exception) { + WXLog(@"%@", exception); + } @finally { } + currentHeight = [self _maxHeightForAllColumns]; [self _columnsReachToHeight:currentHeight]; } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h index 685ec07..0316321 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h +++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h @@ -64,7 +64,7 @@ /** * accessibility support */ - UIAccessibilityTraits _role; //accessibility + NSString * _roles; //accessibility NSString * _ariaLabel; //accessibilityLabel NSString * _ariaHidden; // accessibilityElementsHidden NSString * _accessible; // accessible http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m index b7027b1..bd31e97 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m +++ b/ios/sdk/WeexSDK/Sources/Component/WXImageComponent.m @@ -29,6 +29,7 @@ #import "UIBezierPath+Weex.h" #import "WXSDKEngine.h" #import "WXUtility.h" +#import <pthread/pthread.h> @interface WXImageView : UIImageView @@ -46,8 +47,12 @@ static dispatch_queue_t WXImageUpdateQueue; @interface WXImageComponent () +{ + NSString * _imageSrc; + pthread_mutex_t _imageSrcMutex; + pthread_mutexattr_t _propertMutexAttr; +} -@property (nonatomic, strong) NSString *imageSrc; @property (nonatomic, strong) NSString *placeholdSrc; @property (nonatomic, assign) CGFloat blurRadius; @property (nonatomic, assign) UIViewContentMode resizeMode; @@ -72,8 +77,15 @@ WX_EXPORT_METHOD(@selector(save:)) if (!WXImageUpdateQueue) { WXImageUpdateQueue = dispatch_queue_create("com.taobao.weex.ImageUpdateQueue", DISPATCH_QUEUE_SERIAL); } + + pthread_mutexattr_init(&(_propertMutexAttr)); + pthread_mutexattr_settype(&(_propertMutexAttr), PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&(_imageSrcMutex), &(_propertMutexAttr)); + if (attributes[@"src"]) { + pthread_mutex_lock(&(_imageSrcMutex)); _imageSrc = [[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + pthread_mutex_unlock(&(_imageSrcMutex)); } else { WXLogWarning(@"image src is nil"); } @@ -223,13 +235,14 @@ WX_EXPORT_METHOD(@selector(save:)) - (void)dealloc { [self cancelImage]; + pthread_mutex_destroy(&(_imageSrcMutex)); + pthread_mutexattr_destroy(&_propertMutexAttr); } - (void)updateAttributes:(NSDictionary *)attributes { if (attributes[@"src"]) { - _imageSrc = [[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - [self updateImage]; + [self setImageSrc:[[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]]; } if (attributes[@"quality"]) { _imageQuality = [WXConvert WXImageQuality:attributes[@"quality"]]; @@ -308,13 +321,24 @@ WX_EXPORT_METHOD(@selector(save:)) } } +- (NSString *)imageSrc +{ + pthread_mutex_lock(&(_imageSrcMutex)); + NSString * imageSrcCpy = [_imageSrc copy]; + pthread_mutex_unlock(&(_imageSrcMutex)); + + return imageSrcCpy; +} + - (void)setImageSrc:(NSString*)src { + pthread_mutex_lock(&(_imageSrcMutex)); if (![src isEqualToString:_imageSrc]) { _imageSrc = src; _imageDownloadFinish = NO; [self updateImage]; } + pthread_mutex_unlock(&(_imageSrcMutex)); } - (void)updateImage @@ -348,7 +372,6 @@ WX_EXPORT_METHOD(@selector(save:)) NSString *placeholderSrc = self.placeholdSrc; if ([WXUtility isBlankString:placeholderSrc]) { -// WXLogError(@"image placeholder src is empty"); return; } @@ -387,8 +410,7 @@ WX_EXPORT_METHOD(@selector(save:)) - (void)updateContentImageWithFailedBlock:(void(^)(NSString *, NSError *))downloadFailedBlock { - NSString *imageSrc = self.imageSrc; - + NSString *imageSrc = [NSString stringWithFormat:@"%@", self.imageSrc?:@""]; if ([WXUtility isBlankString:imageSrc]) { WXLogError(@"image src is empty"); return; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/b0e072a4/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m ---------------------------------------------------------------------- diff --git a/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m b/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m index 664b0e8..7556074 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m +++ b/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.m @@ -362,12 +362,14 @@ do {\ - (NSAttributedString *)ctAttributedString { + NSAttributedString * attributedString = nil; pthread_mutex_lock(&(_ctAttributedStringMutex)); if (!_ctAttributedString) { - _ctAttributedString = [[self buildCTAttributeString] copy]; + _ctAttributedString = [self buildCTAttributeString]; } + attributedString = [_ctAttributedString copy]; pthread_mutex_unlock(&(_ctAttributedStringMutex)); - return [_ctAttributedString copy]; + return attributedString; } - (void)repaintText:(NSNotification *)notification