Daniel Zlotin 7 years ago
parent
commit
06875c0c39
24 changed files with 342 additions and 223 deletions
  1. 1
    1
      android/app/src/main/java/com/reactnativenavigation/bridge/NavigationReactModule.java
  2. 1
    6
      android/app/src/main/java/com/reactnativenavigation/events/ScreenChangedEvent.java
  3. 9
    4
      android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java
  4. 3
    0
      android/app/src/main/java/com/reactnativenavigation/layouts/Layout.java
  5. 9
    4
      android/app/src/main/java/com/reactnativenavigation/layouts/SingleScreenLayout.java
  6. 4
    0
      android/app/src/main/java/com/reactnativenavigation/params/BaseScreenParams.java
  7. 1
    0
      android/app/src/main/java/com/reactnativenavigation/params/FabParams.java
  8. 4
    0
      android/app/src/main/java/com/reactnativenavigation/params/ScreenParams.java
  9. 2
    2
      android/app/src/main/java/com/reactnativenavigation/params/parsers/ButtonParser.java
  10. 2
    1
      android/app/src/main/java/com/reactnativenavigation/params/parsers/FabParamsParser.java
  11. 1
    1
      android/app/src/main/java/com/reactnativenavigation/params/parsers/ScreenParamsParser.java
  12. 3
    5
      android/app/src/main/java/com/reactnativenavigation/params/parsers/StyleParamsParser.java
  13. 1
    1
      android/app/src/main/java/com/reactnativenavigation/params/parsers/TopTabParamsParser.java
  14. 19
    0
      android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java
  15. 3
    0
      android/app/src/main/java/com/reactnativenavigation/views/FloatingActionButtonAnimator.java
  16. 16
    3
      android/app/src/main/java/com/reactnativenavigation/views/FloatingActionButtonCoordinator.java
  17. 7
    2
      android/app/src/main/java/com/reactnativenavigation/views/SnackbarAndFabContainer.java
  18. 1
    1
      ios/RCCNavigationController.h
  19. 14
    0
      ios/RCCNavigationController.m
  20. 1
    1
      ios/RCCTabBarController.h
  21. 27
    0
      ios/RCCTabBarController.m
  22. 159
    129
      ios/RCCViewController.m
  23. 1
    2
      src/deprecated/platformSpecificDeprecated.android.js
  24. 53
    60
      yarn.lock

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/bridge/NavigationReactModule.java View File

@@ -98,7 +98,7 @@ public class NavigationReactModule extends ReactContextBaseJavaModule {
98 98
     }
99 99
 
100 100
     private void setScreenFab(String screenInstanceId, String navigatorEventId, ReadableMap fab) {
101
-        FabParams fabParams = new FabParamsParser().parse(BundleConverter.toBundle(fab), navigatorEventId);
101
+        FabParams fabParams = new FabParamsParser().parse(BundleConverter.toBundle(fab), navigatorEventId, screenInstanceId);
102 102
         NavigationCommandsHandler.setScreenFab(screenInstanceId, navigatorEventId, fabParams);
103 103
     }
104 104
 

+ 1
- 6
android/app/src/main/java/com/reactnativenavigation/events/ScreenChangedEvent.java View File

@@ -2,18 +2,13 @@ package com.reactnativenavigation.events;
2 2
 
3 3
 import com.reactnativenavigation.params.BaseScreenParams;
4 4
 import com.reactnativenavigation.params.FabParams;
5
-import com.reactnativenavigation.params.PageParams;
6 5
 
7 6
 public class ScreenChangedEvent implements Event {
8 7
     public static final String TYPE = "ScreenChangedEvent";
9 8
     public FabParams fabParams;
10 9
 
11 10
     public ScreenChangedEvent(BaseScreenParams screenParams) {
12
-        this.fabParams = screenParams.fabParams;
13
-    }
14
-
15
-    public ScreenChangedEvent(PageParams topTabParams) {
16
-        this.fabParams = topTabParams.fabParams;
11
+        this.fabParams = screenParams.getFab();
17 12
     }
18 13
 
19 14
     @Override

+ 9
- 4
android/app/src/main/java/com/reactnativenavigation/layouts/BottomTabsLayout.java View File

@@ -21,6 +21,7 @@ import com.reactnativenavigation.params.SideMenuParams;
21 21
 import com.reactnativenavigation.params.SnackbarParams;
22 22
 import com.reactnativenavigation.params.TitleBarButtonParams;
23 23
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
24
+import com.reactnativenavigation.screens.Screen;
24 25
 import com.reactnativenavigation.screens.ScreenStack;
25 26
 import com.reactnativenavigation.views.BottomTabs;
26 27
 import com.reactnativenavigation.views.SideMenu;
@@ -110,7 +111,7 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
110 111
     }
111 112
 
112 113
     private void createSnackbarContainer() {
113
-        snackbarAndFabContainer = new SnackbarAndFabContainer(getContext());
114
+        snackbarAndFabContainer = new SnackbarAndFabContainer(getContext(), this);
114 115
         RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
115 116
         lp.addRule(ABOVE, bottomTabs.getId());
116 117
         getScreenStackParent().addView(snackbarAndFabContainer, lp);
@@ -229,6 +230,11 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
229 230
         getCurrentScreenStack().peek().dismissContextualMenu();
230 231
     }
231 232
 
233
+    @Override
234
+    public Screen getCurrentScreen() {
235
+        return getCurrentScreenStack().peek();
236
+    }
237
+
232 238
     public void selectBottomTabByTabIndex(Integer index) {
233 239
         bottomTabs.setCurrentItem(index);
234 240
     }
@@ -382,11 +388,10 @@ public class BottomTabsLayout extends RelativeLayout implements Layout, AHBottom
382 388
 
383 389
     @Override
384 390
     public void onSideMenuButtonClick() {
391
+        final String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
392
+        NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);
385 393
         if (sideMenu != null) {
386 394
             sideMenu.openDrawer(Side.Left);
387
-        } else {
388
-            final String navigatorEventId = getCurrentScreenStack().peek().getNavigatorEventId();
389
-            NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);
390 395
         }
391 396
     }
392 397
 }

+ 3
- 0
android/app/src/main/java/com/reactnativenavigation/layouts/Layout.java View File

@@ -8,6 +8,7 @@ import com.reactnativenavigation.params.FabParams;
8 8
 import com.reactnativenavigation.params.SnackbarParams;
9 9
 import com.reactnativenavigation.params.TitleBarButtonParams;
10 10
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
11
+import com.reactnativenavigation.screens.Screen;
11 12
 import com.reactnativenavigation.views.SideMenu.Side;
12 13
 
13 14
 import java.util.List;
@@ -42,4 +43,6 @@ public interface Layout extends ScreenStackContainer {
42 43
     void showContextualMenu(String screenInstanceId, ContextualMenuParams params, Callback onButtonClicked);
43 44
 
44 45
     void dismissContextualMenu(String screenInstanceId);
46
+
47
+    Screen getCurrentScreen();
45 48
 }

+ 9
- 4
android/app/src/main/java/com/reactnativenavigation/layouts/SingleScreenLayout.java View File

@@ -16,6 +16,7 @@ import com.reactnativenavigation.params.SideMenuParams;
16 16
 import com.reactnativenavigation.params.SnackbarParams;
17 17
 import com.reactnativenavigation.params.TitleBarButtonParams;
18 18
 import com.reactnativenavigation.params.TitleBarLeftButtonParams;
19
+import com.reactnativenavigation.screens.Screen;
19 20
 import com.reactnativenavigation.screens.ScreenStack;
20 21
 import com.reactnativenavigation.views.LeftButtonOnClickListener;
21 22
 import com.reactnativenavigation.views.SideMenu;
@@ -92,7 +93,7 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
92 93
     }
93 94
 
94 95
     private void createFabAndSnackbarContainer() {
95
-        snackbarAndFabContainer = new SnackbarAndFabContainer(getContext());
96
+        snackbarAndFabContainer = new SnackbarAndFabContainer(getContext(), this);
96 97
         RelativeLayout.LayoutParams lp = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
97 98
         lp.addRule(ALIGN_PARENT_BOTTOM);
98 99
         snackbarAndFabContainer.setLayoutParams(lp);
@@ -231,6 +232,11 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
231 232
         stack.dismissContextualMenu(screenInstanceId);
232 233
     }
233 234
 
235
+    @Override
236
+    public Screen getCurrentScreen() {
237
+        return stack.peek();
238
+    }
239
+
234 240
     @Override
235 241
     public boolean onTitleBarBackButtonClick() {
236 242
         if (leftButtonOnClickListener != null) {
@@ -242,11 +248,10 @@ public class SingleScreenLayout extends RelativeLayout implements Layout {
242 248
 
243 249
     @Override
244 250
     public void onSideMenuButtonClick() {
251
+        final String navigatorEventId = stack.peek().getNavigatorEventId();
252
+        NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);
245 253
         if (sideMenu != null) {
246 254
             sideMenu.openDrawer(Side.Left);
247
-        } else {
248
-            final String navigatorEventId = stack.peek().getNavigatorEventId();
249
-            NavigationApplication.instance.getEventEmitter().sendNavigatorEvent("sideMenu", navigatorEventId);
250 255
         }
251 256
     }
252 257
 }

+ 4
- 0
android/app/src/main/java/com/reactnativenavigation/params/BaseScreenParams.java View File

@@ -38,4 +38,8 @@ public class BaseScreenParams {
38 38
     public boolean hasCollapsingTopBar() {
39 39
         return styleParams.collapsingTopBarParams != null;
40 40
     }
41
+
42
+    public FabParams getFab() {
43
+        return fabParams;
44
+    }
41 45
 }

+ 1
- 0
android/app/src/main/java/com/reactnativenavigation/params/FabParams.java View File

@@ -12,6 +12,7 @@ public class FabParams {
12 12
     public String expendedId;
13 13
     public String navigatorEventId;
14 14
     public List<FabActionParams> actions;
15
+    public String screenInstanceId;
15 16
 
16 17
     public boolean hasExpendedState() {
17 18
         return actions != null && actions.size() > 0;

+ 4
- 0
android/app/src/main/java/com/reactnativenavigation/params/ScreenParams.java View File

@@ -12,4 +12,8 @@ public class ScreenParams extends BaseScreenParams {
12 12
     public boolean hasTopTabs() {
13 13
         return topTabParams != null && !topTabParams.isEmpty();
14 14
     }
15
+
16
+    public FabParams getFab() {
17
+        return hasTopTabs() ? topTabParams.get(0).fabParams : fabParams;
18
+    }
15 19
 }

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/params/parsers/ButtonParser.java View File

@@ -35,10 +35,10 @@ public class ButtonParser extends Parser {
35 35
         return leftButton;
36 36
     }
37 37
 
38
-    public static FabParams parseFab(Bundle params, String navigatorEventId) {
38
+    public static FabParams parseFab(Bundle params, String navigatorEventId, String screenInstanceId) {
39 39
         FabParams fabParams = null;
40 40
         if (hasKey(params, KEY_FAB)) {
41
-            fabParams = new FabParamsParser().parse(params.getBundle(KEY_FAB), navigatorEventId);
41
+            fabParams = new FabParamsParser().parse(params.getBundle(KEY_FAB), navigatorEventId, screenInstanceId);
42 42
         }
43 43
         return fabParams;
44 44
     }

+ 2
- 1
android/app/src/main/java/com/reactnativenavigation/params/parsers/FabParamsParser.java View File

@@ -8,11 +8,12 @@ import com.reactnativenavigation.params.StyleParams;
8 8
 import com.reactnativenavigation.react.ImageLoader;
9 9
 
10 10
 public class FabParamsParser extends Parser {
11
-    public FabParams parse(Bundle params, final String navigatorEventId) {
11
+    public FabParams parse(Bundle params, final String navigatorEventId, String screenInstanceId) {
12 12
         FabParams fabParams = new FabParams();
13 13
         fabParams.collapsedId = params.getString("collapsedId");
14 14
         fabParams.expendedId = params.getString("expendedId");
15 15
         fabParams.navigatorEventId = navigatorEventId;
16
+        fabParams.screenInstanceId = screenInstanceId;
16 17
         fabParams.backgroundColor = getColor(params, "backgroundColor", new StyleParams.Color());
17 18
 
18 19
         if (hasKey(params, "collapsedIcon")) {

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/params/parsers/ScreenParamsParser.java View File

@@ -43,7 +43,7 @@ public class ScreenParamsParser extends Parser {
43 43
             result.fragmentCreatorPassProps = params.getBundle(FRAGMENT_CREATOR_PASS_PROPS);
44 44
         }
45 45
 
46
-        result.fabParams = ButtonParser.parseFab(params, result.navigationParams.navigatorEventId);
46
+        result.fabParams = ButtonParser.parseFab(params, result.navigationParams.navigatorEventId, result.navigationParams.screenInstanceId);
47 47
 
48 48
         result.tabLabel = getTabLabel(params);
49 49
         result.tabIcon = getTabIcon(params);

+ 3
- 5
android/app/src/main/java/com/reactnativenavigation/params/parsers/StyleParamsParser.java View File

@@ -53,7 +53,9 @@ public class StyleParamsParser {
53 53
         result.bottomTabsHidden = getBoolean("bottomTabsHidden", getDefaultBottomTabsHidden());
54 54
         result.drawScreenAboveBottomTabs = !result.bottomTabsHidden &&
55 55
                                            params.getBoolean("drawScreenAboveBottomTabs", getDefaultDrawScreenAboveBottomTabs());
56
-        result.drawScreenAboveBottomTabs = drawScreenUnderBottomTabsIfTitleBarIsHiddenOnScroll(result);
56
+        if (result.titleBarHideOnScroll) {
57
+            result.drawScreenAboveBottomTabs = false;
58
+        }
57 59
         result.bottomTabsHiddenOnScroll = getBoolean("bottomTabsHiddenOnScroll", getDefaultBottomTabsHiddenOnScroll());
58 60
         result.bottomTabsColor = getColor("bottomTabsColor", getDefaultBottomTabsColor());
59 61
         result.bottomTabsButtonColor = getColor("bottomTabsButtonColor", getDefaultBottomTabsButtonColor());
@@ -76,10 +78,6 @@ public class StyleParamsParser {
76 78
         return result;
77 79
     }
78 80
 
79
-    private boolean drawScreenUnderBottomTabsIfTitleBarIsHiddenOnScroll(StyleParams result) {
80
-        return !result.titleBarHideOnScroll;
81
-    }
82
-
83 81
     private StyleParams.Color getDefaultContextualMenuStatusBarColor() {
84 82
         return new StyleParams.Color(Color.parseColor("#7c7c7c"));
85 83
     }

+ 1
- 1
android/app/src/main/java/com/reactnativenavigation/params/parsers/TopTabParamsParser.java View File

@@ -31,7 +31,7 @@ public class TopTabParamsParser extends Parser {
31 31
         result.navigationParams = new NavigationParams(params.getBundle(NAVIGATION_PARAMS));
32 32
         result.leftButton = ButtonParser.parseLeftButton(params);
33 33
         result.rightButtons = ButtonParser.parseRightButton(params);
34
-        result.fabParams = ButtonParser.parseFab(params, result.navigationParams.navigatorEventId);
34
+        result.fabParams = ButtonParser.parseFab(params, result.navigationParams.navigatorEventId, result.navigationParams.screenInstanceId);
35 35
         result.styleParams = new StyleParamsParser(params.getBundle("styleParams")).parse();
36 36
         return result;
37 37
     }

+ 19
- 0
android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java View File

@@ -9,11 +9,13 @@ import android.support.annotation.Nullable;
9 9
 import android.util.DisplayMetrics;
10 10
 import android.view.View;
11 11
 import android.view.ViewGroup;
12
+import android.view.ViewParent;
12 13
 import android.view.ViewTreeObserver;
13 14
 import android.view.WindowManager;
14 15
 
15 16
 import com.reactnativenavigation.NavigationApplication;
16 17
 import com.reactnativenavigation.params.AppStyle;
18
+import com.reactnativenavigation.screens.Screen;
17 19
 
18 20
 import java.util.concurrent.atomic.AtomicInteger;
19 21
 
@@ -115,5 +117,22 @@ public class ViewUtils {
115 117
     public interface PerformOnViewTask {
116 118
         void runOnView(View view);
117 119
     }
120
+
121
+    public static void performOnParentScreen(View child, Task<Screen> task) {
122
+        Screen parentScreen = findParentScreen(child.getParent());
123
+        if (parentScreen != null) {
124
+            task.run(parentScreen);
125
+        }
126
+    }
127
+
128
+    private static Screen findParentScreen(ViewParent parent) {
129
+        if (parent == null) {
130
+            return null;
131
+        }
132
+        if (parent instanceof Screen) {
133
+            return (Screen) parent;
134
+        }
135
+        return findParentScreen(parent.getParent());
136
+    }
118 137
 }
119 138
 

+ 3
- 0
android/app/src/main/java/com/reactnativenavigation/views/FloatingActionButtonAnimator.java View File

@@ -87,6 +87,9 @@ public class FloatingActionButtonAnimator {
87 87
     }
88 88
 
89 89
     void removeFabFromScreen(FloatingActionButton fab, final AnimatorListenerAdapter animationListener) {
90
+        if (fab == null) {
91
+            return;
92
+        }
90 93
         state = State.Removing;
91 94
         fab.animate()
92 95
                 .alpha(0)

+ 16
- 3
android/app/src/main/java/com/reactnativenavigation/views/FloatingActionButtonCoordinator.java View File

@@ -10,6 +10,7 @@ import android.support.annotation.NonNull;
10 10
 import android.support.annotation.Nullable;
11 11
 import android.support.design.widget.CoordinatorLayout;
12 12
 import android.support.design.widget.FloatingActionButton;
13
+import android.util.Log;
13 14
 import android.view.Gravity;
14 15
 import android.view.View;
15 16
 
@@ -23,7 +24,7 @@ import java.util.ArrayList;
23 24
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
24 25
 
25 26
 public class FloatingActionButtonCoordinator {
26
-
27
+    private static final String TAG = "FloatingActionButtonCoo";
27 28
     private static final int INITIAL_EXPENDED_FAB_ROTATION = -90;
28 29
     private CoordinatorLayout parent;
29 30
     private FabParams params;
@@ -42,7 +43,18 @@ public class FloatingActionButtonCoordinator {
42 43
         actionSize = (int) ViewUtils.convertDpToPixel(40);
43 44
     }
44 45
 
45
-    public void add(FabParams params) {
46
+    public void add(final FabParams params) {
47
+        Log.i(TAG, "add() called with: params = [" + params + "]");
48
+        if (parent.getChildCount() > 0) {
49
+            remove(new Runnable() {
50
+                @Override
51
+                public void run() {
52
+                    add(params);
53
+                }
54
+            });
55
+            return;
56
+        }
57
+
46 58
         this.params = params;
47 59
         if (!params.isValid()) {
48 60
             return;
@@ -55,7 +67,8 @@ public class FloatingActionButtonCoordinator {
55 67
     }
56 68
 
57 69
     public void remove(@Nullable final Runnable onComplete) {
58
-        if (parent.getChildCount() == 0 || fabAnimator.isAnimating()) {
70
+        Log.w(TAG, "remove: ");
71
+        if (parent.getChildCount() == 0) {
59 72
             if (onComplete != null) {
60 73
                 onComplete.run();
61 74
             }

+ 7
- 2
android/app/src/main/java/com/reactnativenavigation/views/SnackbarAndFabContainer.java View File

@@ -8,15 +8,18 @@ import com.reactnativenavigation.events.EventBus;
8 8
 import com.reactnativenavigation.events.FabSetEvent;
9 9
 import com.reactnativenavigation.events.ScreenChangedEvent;
10 10
 import com.reactnativenavigation.events.Subscriber;
11
+import com.reactnativenavigation.layouts.Layout;
11 12
 import com.reactnativenavigation.params.FabParams;
12 13
 import com.reactnativenavigation.params.SnackbarParams;
13 14
 
14 15
 public class SnackbarAndFabContainer extends CoordinatorLayout implements Snakbar.OnDismissListener, Subscriber{
15 16
     private Snakbar snakbar;
16 17
     private FloatingActionButtonCoordinator fabCoordinator;
18
+    private Layout layout;
17 19
 
18
-    public SnackbarAndFabContainer(Context context) {
20
+    public SnackbarAndFabContainer(Context context, Layout layout) {
19 21
         super(context);
22
+        this.layout = layout;
20 23
         fabCoordinator = new FloatingActionButtonCoordinator(this);
21 24
         EventBus.instance.register(this);
22 25
     }
@@ -64,7 +67,9 @@ public class SnackbarAndFabContainer extends CoordinatorLayout implements Snakba
64 67
             @Override
65 68
             public void run() {
66 69
                 if (fabParams != null) {
67
-                    fabCoordinator.add(fabParams);
70
+                    if (layout.getCurrentScreen().getScreenInstanceId().equals(fabParams.screenInstanceId)) {
71
+                        fabCoordinator.add(fabParams);
72
+                    }
68 73
                 }
69 74
             }
70 75
         });

+ 1
- 1
ios/RCCNavigationController.h View File

@@ -1,7 +1,7 @@
1 1
 #import <UIKit/UIKit.h>
2 2
 #import "RCTBridge.h"
3 3
 
4
-@interface RCCNavigationController : UINavigationController
4
+@interface RCCNavigationController : UINavigationController <UINavigationControllerDelegate>
5 5
 
6 6
 - (instancetype)initWithProps:(NSDictionary *)props children:(NSArray *)children globalProps:(NSDictionary*)globalProps bridge:(RCTBridge *)bridge;
7 7
 - (void)performAction:(NSString*)performAction actionParams:(NSDictionary*)actionParams bridge:(RCTBridge *)bridge;

+ 14
- 0
ios/RCCNavigationController.m View File

@@ -36,6 +36,7 @@ NSString const *CALLBACK_ASSOCIATED_ID = @"RCCNavigationController.CALLBACK_ASSO
36 36
   
37 37
   self = [super initWithRootViewController:viewController];
38 38
   if (!self) return nil;
39
+  self.delegate = self;
39 40
   
40 41
   self.navigationBar.translucent = NO; // default
41 42
   
@@ -76,6 +77,7 @@ NSString const *CALLBACK_ASSOCIATED_ID = @"RCCNavigationController.CALLBACK_ASSO
76 77
       [mergedStyle removeObjectForKey:@"navBarBlur"];
77 78
       [mergedStyle removeObjectForKey:@"navBarTranslucent"];
78 79
       [mergedStyle removeObjectForKey:@"statusBarHideWithNavBar"];
80
+      [mergedStyle removeObjectForKey:@"statusBarTextColorSchemeSingleScreen"];
79 81
       
80 82
       [mergedStyle addEntriesFromDictionary:navigatorStyle];
81 83
       navigatorStyle = mergedStyle;
@@ -294,5 +296,17 @@ NSString const *CALLBACK_ASSOCIATED_ID = @"RCCNavigationController.CALLBACK_ASSO
294 296
   
295 297
 }
296 298
 
299
+- (UIStatusBarStyle)preferredStatusBarStyle {
300
+  return [self.topViewController preferredStatusBarStyle];
301
+}
302
+
303
+
304
+#pragma mark - UINavigationControllerDelegate
305
+
306
+
307
+-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
308
+  [viewController setNeedsStatusBarAppearanceUpdate];
309
+}
310
+
297 311
 
298 312
 @end

+ 1
- 1
ios/RCCTabBarController.h View File

@@ -1,7 +1,7 @@
1 1
 #import <UIKit/UIKit.h>
2 2
 #import "RCTBridge.h"
3 3
 
4
-@interface RCCTabBarController : UITabBarController
4
+@interface RCCTabBarController : UITabBarController <UITabBarDelegate>
5 5
 
6 6
 - (instancetype)initWithProps:(NSDictionary *)props children:(NSArray *)children globalProps:(NSDictionary*)globalProps bridge:(RCTBridge *)bridge;
7 7
 - (void)performAction:(NSString*)performAction actionParams:(NSDictionary*)actionParams bridge:(RCTBridge *)bridge completion:(void (^)(void))completion;

+ 27
- 0
ios/RCCTabBarController.m View File

@@ -20,6 +20,8 @@
20 20
     [[[RCCManager sharedInstance].getBridge uiManager] configureNextLayoutAnimation:nil withCallback:^(NSArray* arr){} errorCallback:^(NSArray* arr){}];
21 21
   });
22 22
   
23
+  [RCCTabBarController sendScreenTabChangedEvent:viewController];
24
+  
23 25
   return YES;
24 26
 }
25 27
 
@@ -237,4 +239,29 @@
237 239
     }
238 240
 }
239 241
 
242
++(void)sendScreenTabChangedEvent:(UIViewController*)viewController {
243
+  if ([viewController.view isKindOfClass:[RCTRootView class]]){
244
+    RCTRootView *rootView = (RCTRootView *)viewController.view;
245
+    
246
+    if (rootView.appProperties && rootView.appProperties[@"navigatorEventID"]) {
247
+      NSString *navigatorID = rootView.appProperties[@"navigatorID"];
248
+      NSString *screenInstanceID = rootView.appProperties[@"screenInstanceID"];
249
+      
250
+      [[[RCCManager sharedInstance] getBridge].eventDispatcher sendAppEventWithName:rootView.appProperties[@"navigatorEventID"] body:@
251
+       {
252
+         @"id": @"bottomTabSelected",
253
+         @"navigatorID": navigatorID,
254
+         @"screenInstanceID": screenInstanceID
255
+       }];
256
+    }
257
+  }
258
+  
259
+  if ([viewController isKindOfClass:[UINavigationController class]]) {
260
+    UINavigationController *navigationController = (UINavigationController*)viewController;
261
+    UIViewController *topViewController = [navigationController topViewController];
262
+    [RCCTabBarController sendScreenTabChangedEvent:topViewController];
263
+  }
264
+}
265
+
266
+
240 267
 @end

+ 159
- 129
ios/RCCViewController.m View File

@@ -96,60 +96,60 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
96 96
 
97 97
 - (instancetype)initWithProps:(NSDictionary *)props children:(NSArray *)children globalProps:(NSDictionary *)globalProps bridge:(RCTBridge *)bridge
98 98
 {
99
-  NSString *component = props[@"component"];
100
-  if (!component) return nil;
101
-
102
-  NSDictionary *passProps = props[@"passProps"];
103
-  NSDictionary *navigatorStyle = props[@"style"];
104
-
105
-  NSMutableDictionary *mergedProps = [NSMutableDictionary dictionaryWithDictionary:globalProps];
106
-  [mergedProps addEntriesFromDictionary:passProps];
107
-  
108
-  RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:component initialProperties:mergedProps];
109
-  if (!reactView) return nil;
110
-
111
-  self = [super init];
112
-  if (!self) return nil;
113
-
114
-  [self commonInit:reactView navigatorStyle:navigatorStyle props:props];
115
-
116
-  return self;
99
+    NSString *component = props[@"component"];
100
+    if (!component) return nil;
101
+    
102
+    NSDictionary *passProps = props[@"passProps"];
103
+    NSDictionary *navigatorStyle = props[@"style"];
104
+    
105
+    NSMutableDictionary *mergedProps = [NSMutableDictionary dictionaryWithDictionary:globalProps];
106
+    [mergedProps addEntriesFromDictionary:passProps];
107
+    
108
+    RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:component initialProperties:mergedProps];
109
+    if (!reactView) return nil;
110
+    
111
+    self = [super init];
112
+    if (!self) return nil;
113
+    
114
+    [self commonInit:reactView navigatorStyle:navigatorStyle props:props];
115
+    
116
+    return self;
117 117
 }
118 118
 
119 119
 - (instancetype)initWithComponent:(NSString *)component passProps:(NSDictionary *)passProps navigatorStyle:(NSDictionary*)navigatorStyle globalProps:(NSDictionary *)globalProps bridge:(RCTBridge *)bridge
120 120
 {
121
-  NSMutableDictionary *mergedProps = [NSMutableDictionary dictionaryWithDictionary:globalProps];
122
-  [mergedProps addEntriesFromDictionary:passProps];
123
-  
124
-  RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:component initialProperties:mergedProps];
125
-  if (!reactView) return nil;
126
-
127
-  self = [super init];
128
-  if (!self) return nil;
129
-
130
-  [self commonInit:reactView navigatorStyle:navigatorStyle props:passProps];
131
-
132
-  return self;
121
+    NSMutableDictionary *mergedProps = [NSMutableDictionary dictionaryWithDictionary:globalProps];
122
+    [mergedProps addEntriesFromDictionary:passProps];
123
+    
124
+    RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:component initialProperties:mergedProps];
125
+    if (!reactView) return nil;
126
+    
127
+    self = [super init];
128
+    if (!self) return nil;
129
+    
130
+    [self commonInit:reactView navigatorStyle:navigatorStyle props:passProps];
131
+    
132
+    return self;
133 133
 }
134 134
 
135 135
 - (void)commonInit:(RCTRootView*)reactView navigatorStyle:(NSDictionary*)navigatorStyle props:(NSDictionary*)props
136 136
 {
137
-  self.view = reactView;
138
-  
139
-  self.edgesForExtendedLayout = UIRectEdgeNone; // default
140
-  self.automaticallyAdjustsScrollViewInsets = NO; // default
141
-  
142
-  self.navigatorStyle = [NSMutableDictionary dictionaryWithDictionary:navigatorStyle];
143
-  
144
-  [self setStyleOnInit];
145
-  
146
-  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onRNReload) name:RCTReloadNotification object:nil];
147
-  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onCancelReactTouches) name:RCCViewControllerCancelReactTouchesNotification object:nil];
148
-  
149
-  // In order to support 3rd party native ViewControllers, we support passing a class name as a prop mamed `ExternalNativeScreenClass`
150
-  // In this case, we create an instance and add it as a child ViewController which preserves the VC lifecycle.
151
-  // In case some props are necessary in the native ViewController, the ExternalNativeScreenProps can be used to pass them
152
-  [self addExternalVCIfNecessary:props];
137
+    self.view = reactView;
138
+    
139
+    self.edgesForExtendedLayout = UIRectEdgeNone; // default
140
+    self.automaticallyAdjustsScrollViewInsets = NO; // default
141
+    
142
+    self.navigatorStyle = [NSMutableDictionary dictionaryWithDictionary:navigatorStyle];
143
+    
144
+    [self setStyleOnInit];
145
+    
146
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onRNReload) name:RCTReloadNotification object:nil];
147
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onCancelReactTouches) name:RCCViewControllerCancelReactTouchesNotification object:nil];
148
+    
149
+    // In order to support 3rd party native ViewControllers, we support passing a class name as a prop mamed `ExternalNativeScreenClass`
150
+    // In this case, we create an instance and add it as a child ViewController which preserves the VC lifecycle.
151
+    // In case some props are necessary in the native ViewController, the ExternalNativeScreenProps can be used to pass them
152
+    [self addExternalVCIfNecessary:props];
153 153
 }
154 154
 
155 155
 - (void)dealloc
@@ -166,9 +166,9 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
166 166
 
167 167
 -(void)onCancelReactTouches
168 168
 {
169
-  if ([self.view isKindOfClass:[RCTRootView class]]){
170
-    [(RCTRootView*)self.view cancelTouches];
171
-  }
169
+    if ([self.view isKindOfClass:[RCTRootView class]]){
170
+        [(RCTRootView*)self.view cancelTouches];
171
+    }
172 172
 }
173 173
 
174 174
 - (void)viewWillAppear:(BOOL)animated
@@ -189,7 +189,7 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
189 189
 // we want to reset the style to what we expect (so we need to reset on every willAppear)
190 190
 - (void)setStyleOnAppear
191 191
 {
192
-  [self setStyleOnAppearForViewController:self];
192
+    [self setStyleOnAppearForViewController:self];
193 193
 }
194 194
 
195 195
 -(void)setStyleOnAppearForViewController:(UIViewController*)viewController
@@ -200,7 +200,7 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
200 200
         UIColor *color = screenBackgroundColor != (id)[NSNull null] ? [RCTConvert UIColor:screenBackgroundColor] : nil;
201 201
         self.view.backgroundColor = color;
202 202
     }
203
- 
203
+    
204 204
     NSString *navBarBackgroundColor = self.navigatorStyle[@"navBarBackgroundColor"];
205 205
     if (navBarBackgroundColor)
206 206
     {
@@ -233,19 +233,33 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
233 233
     {
234 234
         viewController.navigationController.navigationBar.tintColor = nil;
235 235
     }
236
-    
237
-    NSString *statusBarTextColorScheme = self.navigatorStyle[@"statusBarTextColorScheme"];
238
-    if (statusBarTextColorScheme && [statusBarTextColorScheme isEqualToString:@"light"])
236
+  
237
+    NSString *statusBarTextColorSchemeSingleScreen = self.navigatorStyle[@"statusBarTextColorSchemeSingleScreen"];
238
+    if (statusBarTextColorSchemeSingleScreen && [statusBarTextColorSchemeSingleScreen isEqualToString:@"light"])
239 239
     {
240
-        viewController.navigationController.navigationBar.barStyle = UIBarStyleBlack;
241
-        self._statusBarTextColorSchemeLight = YES;
240
+      self._statusBarTextColorSchemeLight = YES;
242 241
     }
243 242
     else
244 243
     {
245
-        viewController.navigationController.navigationBar.barStyle = UIBarStyleDefault;
246
-        self._statusBarTextColorSchemeLight = NO;
244
+      self._statusBarTextColorSchemeLight = NO;
247 245
     }
248
-    
246
+  
247
+    // incase statusBarTextColorSchemeSingleScreen exists ignore the statusBarTextColorScheme which more globaly
248
+    if (!statusBarTextColorSchemeSingleScreen) {
249
+      NSString *statusBarTextColorScheme = self.navigatorStyle[@"statusBarTextColorScheme"];
250
+      if (statusBarTextColorScheme && [statusBarTextColorScheme isEqualToString:@"light"] && !statusBarTextColorSchemeSingleScreen)
251
+      {
252
+          viewController.navigationController.navigationBar.barStyle = UIBarStyleBlack;
253
+          self._statusBarTextColorSchemeLight = YES;
254
+        
255
+      }
256
+      else
257
+      {
258
+          viewController.navigationController.navigationBar.barStyle = UIBarStyleDefault;
259
+          self._statusBarTextColorSchemeLight = NO;
260
+      }
261
+    }
262
+  
249 263
     NSNumber *navBarHidden = self.navigatorStyle[@"navBarHidden"];
250 264
     BOOL navBarHiddenBool = navBarHidden ? [navBarHidden boolValue] : NO;
251 265
     if (viewController.navigationController.navigationBarHidden != navBarHiddenBool)
@@ -309,29 +323,44 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
309 323
     
310 324
     NSNumber *navBarTransparent = self.navigatorStyle[@"navBarTransparent"];
311 325
     BOOL navBarTransparentBool = navBarTransparent ? [navBarTransparent boolValue] : NO;
312
-    if (navBarTransparentBool)
313
-    {
314
-        if (![viewController.navigationController.navigationBar viewWithTag:TRANSPARENT_NAVBAR_TAG])
326
+    
327
+    void (^action)() = ^ {
328
+        if (navBarTransparentBool)
315 329
         {
316
-            [self storeOriginalNavBarImages];
317
-            
318
-            [viewController.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
319
-            viewController.navigationController.navigationBar.shadowImage = [UIImage new];
320
-            UIView *transparentView = [[UIView alloc] initWithFrame:CGRectZero];
321
-            transparentView.tag = TRANSPARENT_NAVBAR_TAG;
322
-            [viewController.navigationController.navigationBar insertSubview:transparentView atIndex:0];
330
+            if (![viewController.navigationController.navigationBar viewWithTag:TRANSPARENT_NAVBAR_TAG])
331
+            {
332
+                [self storeOriginalNavBarImages];
333
+                
334
+                [viewController.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
335
+                viewController.navigationController.navigationBar.shadowImage = [UIImage new];
336
+                UIView *transparentView = [[UIView alloc] initWithFrame:CGRectZero];
337
+                transparentView.tag = TRANSPARENT_NAVBAR_TAG;
338
+                [viewController.navigationController.navigationBar insertSubview:transparentView atIndex:0];
339
+            }
323 340
         }
324
-    }
325
-    else
326
-    {
327
-        UIView *transparentView = [viewController.navigationController.navigationBar viewWithTag:TRANSPARENT_NAVBAR_TAG];
328
-        if (transparentView)
341
+        else
329 342
         {
330
-            [transparentView removeFromSuperview];
331
-            [viewController.navigationController.navigationBar setBackgroundImage:self.originalNavBarImages[@"bgImage"] forBarMetrics:UIBarMetricsDefault];
332
-            viewController.navigationController.navigationBar.shadowImage = self.originalNavBarImages[@"shadowImage"];
333
-            self.originalNavBarImages = nil;
343
+            UIView *transparentView = [viewController.navigationController.navigationBar viewWithTag:TRANSPARENT_NAVBAR_TAG];
344
+            if (transparentView)
345
+            {
346
+                [transparentView removeFromSuperview];
347
+                [viewController.navigationController.navigationBar setBackgroundImage:self.originalNavBarImages[@"bgImage"] forBarMetrics:UIBarMetricsDefault];
348
+                viewController.navigationController.navigationBar.shadowImage = self.originalNavBarImages[@"shadowImage"];
349
+                self.originalNavBarImages = nil;
350
+            }
334 351
         }
352
+    };
353
+    
354
+    if(self.transitionCoordinator.initiallyInteractive || !navBarTransparentBool) {
355
+        action();
356
+    } else {
357
+        UIView* backgroundView = [self.navigationController.navigationBar valueForKey:@"backgroundView"];
358
+        CGFloat originalAlpha = backgroundView.alpha;
359
+        backgroundView.alpha = navBarTransparentBool ? 0.0 : 1.0;
360
+        [self.transitionCoordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext>  _Nonnull context) {
361
+            action();
362
+            backgroundView.alpha = originalAlpha;
363
+        }];
335 364
     }
336 365
     
337 366
     NSNumber *navBarTranslucent = self.navigatorStyle[@"navBarTranslucent"];
@@ -377,18 +406,18 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
377 406
     {
378 407
         self.navBarHairlineImageView.hidden = NO;
379 408
     }
380
-  
409
+    
381 410
     //Bug fix: in case there is a interactivePopGestureRecognizer, it prevents react-native from getting touch events on the left screen area that the gesture handles
382 411
     //overriding the delegate of the gesture prevents this from happening while keeping the gesture intact (another option was to disable it completely by demand)
383 412
     self.originalInteractivePopGestureDelegate = nil;
384 413
     if (self.navigationController != nil && self.navigationController.interactivePopGestureRecognizer != nil)
385 414
     {
386
-      id <UIGestureRecognizerDelegate> interactivePopGestureRecognizer = self.navigationController.interactivePopGestureRecognizer.delegate;
387
-      if (interactivePopGestureRecognizer != nil)
388
-      {
389
-        self.originalInteractivePopGestureDelegate = interactivePopGestureRecognizer;
390
-        self.navigationController.interactivePopGestureRecognizer.delegate = self;
391
-      }
415
+        id <UIGestureRecognizerDelegate> interactivePopGestureRecognizer = self.navigationController.interactivePopGestureRecognizer.delegate;
416
+        if (interactivePopGestureRecognizer != nil)
417
+        {
418
+            self.originalInteractivePopGestureDelegate = interactivePopGestureRecognizer;
419
+            self.navigationController.interactivePopGestureRecognizer.delegate = self;
420
+        }
392 421
     }
393 422
 }
394 423
 
@@ -411,11 +440,11 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
411 440
 -(void)setStyleOnDisappear
412 441
 {
413 442
     self.navBarHairlineImageView.hidden = NO;
414
-  
443
+    
415 444
     if (self.navigationController != nil && self.navigationController.interactivePopGestureRecognizer != nil && self.originalInteractivePopGestureDelegate != nil)
416 445
     {
417
-      self.navigationController.interactivePopGestureRecognizer.delegate = self.originalInteractivePopGestureDelegate;
418
-      self.originalInteractivePopGestureDelegate = nil;
446
+        self.navigationController.interactivePopGestureRecognizer.delegate = self.originalInteractivePopGestureDelegate;
447
+        self.originalInteractivePopGestureDelegate = nil;
419 448
     }
420 449
 }
421 450
 
@@ -510,57 +539,58 @@ const NSInteger TRANSPARENT_NAVBAR_TAG = 78264803;
510 539
 
511 540
 -(void)addExternalVCIfNecessary:(NSDictionary*)props
512 541
 {
513
-  NSString *externalScreenClass = props[@"externalNativeScreenClass"];
514
-  if (externalScreenClass != nil)
515
-  {
516
-    Class class = NSClassFromString(externalScreenClass);
517
-    if (class != NULL)
518
-    {
519
-      id obj = [[class alloc] init];
520
-      if (obj != nil && [obj isKindOfClass:[UIViewController class]] && [obj conformsToProtocol:@protocol(RCCExternalViewControllerProtocol)])
521
-      {
522
-        ((id <RCCExternalViewControllerProtocol>)obj).controllerDelegate = self;
523
-        [obj setProps:props[@"externalNativeScreenProps"]];
524
-        
525
-        UIViewController *viewController = (UIViewController*)obj;
526
-        [self addChildViewController:viewController];
527
-        viewController.view.frame = self.view.bounds;
528
-        [self.view addSubview:viewController.view];
529
-        [viewController didMoveToParentViewController:self];
530
-      }
531
-      else
532
-      {
533
-        NSLog(@"addExternalVCIfNecessary: could not create instance. Make sure that your class is a UIViewController whihc confirms to RCCExternalViewControllerProtocol");
534
-      }
535
-    }
536
-    else
542
+    NSString *externalScreenClass = props[@"externalNativeScreenClass"];
543
+    if (externalScreenClass != nil)
537 544
     {
538
-      NSLog(@"addExternalVCIfNecessary: could not create class from string. Check that the proper class name wass passed in ExternalNativeScreenClass");
545
+        Class class = NSClassFromString(externalScreenClass);
546
+        if (class != NULL)
547
+        {
548
+            id obj = [[class alloc] init];
549
+            if (obj != nil && [obj isKindOfClass:[UIViewController class]] && [obj conformsToProtocol:@protocol(RCCExternalViewControllerProtocol)])
550
+            {
551
+                ((id <RCCExternalViewControllerProtocol>)obj).controllerDelegate = self;
552
+                [obj setProps:props[@"externalNativeScreenProps"]];
553
+                
554
+                UIViewController *viewController = (UIViewController*)obj;
555
+                [self addChildViewController:viewController];
556
+                viewController.view.frame = self.view.bounds;
557
+                [self.view addSubview:viewController.view];
558
+                [viewController didMoveToParentViewController:self];
559
+            }
560
+            else
561
+            {
562
+                NSLog(@"addExternalVCIfNecessary: could not create instance. Make sure that your class is a UIViewController whihc confirms to RCCExternalViewControllerProtocol");
563
+            }
564
+        }
565
+        else
566
+        {
567
+            NSLog(@"addExternalVCIfNecessary: could not create class from string. Check that the proper class name wass passed in ExternalNativeScreenClass");
568
+        }
539 569
     }
540
-  }
541 570
 }
542 571
 
543 572
 #pragma mark - NewRelic
544 573
 
545 574
 - (NSString*) customNewRelicInteractionName
546 575
 {
547
-  NSString *interactionName = nil;
548
-  
549
-  if (self.view != nil && [self.view isKindOfClass:[RCTRootView class]])
550
-  {
551
-    NSString *moduleName = ((RCTRootView*)self.view).moduleName;
552
-    if(moduleName != nil)
576
+    NSString *interactionName = nil;
577
+    
578
+    if (self.view != nil && [self.view isKindOfClass:[RCTRootView class]])
553 579
     {
554
-      interactionName = [NSString stringWithFormat:@"RCCViewController: %@", moduleName];
580
+        NSString *moduleName = ((RCTRootView*)self.view).moduleName;
581
+        if(moduleName != nil)
582
+        {
583
+            interactionName = [NSString stringWithFormat:@"RCCViewController: %@", moduleName];
584
+        }
555 585
     }
556
-  }
557
-  
558
-  if (interactionName == nil)
559
-  {
560
-    interactionName = [NSString stringWithFormat:@"RCCViewController with title: %@", self.title];
561
-  }
562
-  
563
-  return interactionName;
586
+    
587
+    if (interactionName == nil)
588
+    {
589
+        interactionName = [NSString stringWithFormat:@"RCCViewController with title: %@", self.title];
590
+    }
591
+    
592
+    return interactionName;
564 593
 }
565 594
 
595
+
566 596
 @end

+ 1
- 2
src/deprecated/platformSpecificDeprecated.android.js View File

@@ -36,6 +36,7 @@ function startSingleScreenApp(params) {
36 36
 }
37 37
 
38 38
 function adaptTopTabs(screen, navigatorID) {
39
+  screen.topTabs = _.cloneDeep(screen.topTabs);
39 40
   _.forEach(_.get(screen, 'topTabs'), (tab) => {
40 41
     addNavigatorParams(tab);
41 42
     if (navigatorID) {
@@ -279,8 +280,6 @@ function navigatorSetButtons(navigator, navigatorEventID, params) {
279 280
     }
280 281
   }
281 282
   const fab = getFab(params);
282
-  console.log('params: ', JSON.stringify(params));
283
-  console.log('fab: ', JSON.stringify(fab));
284 283
   newPlatformSpecific.setScreenButtons(navigator.screenInstanceID, navigatorEventID, params.rightButtons, leftButton, fab);
285 284
 }
286 285
 

+ 53
- 60
yarn.lock View File

@@ -60,8 +60,8 @@ acorn@^4.0.1:
60 60
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a"
61 61
 
62 62
 ajv-keywords@^1.0.0:
63
-  version "1.4.1"
64
-  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.4.1.tgz#f080e635e230baae26537ce727f260ae62b43802"
63
+  version "1.5.0"
64
+  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.0.tgz#c11e6859eafff83e0dafc416929472eca946aa2c"
65 65
 
66 66
 ajv@^4.7.0:
67 67
   version "4.10.3"
@@ -230,7 +230,7 @@ async@1.x, async@^1.4.0, async@^1.4.2:
230 230
   version "1.5.2"
231 231
   resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
232 232
 
233
-async@^2.0.1:
233
+async@^2.0.1, async@^2.1.4:
234 234
   version "2.1.4"
235 235
   resolved "https://registry.yarnpkg.com/async/-/async-2.1.4.tgz#2d2160c7788032e4dd6cbe2502f1f9a2c8f6cde4"
236 236
   dependencies:
@@ -1188,7 +1188,7 @@ clone@^0.2.0:
1188 1188
   version "0.2.0"
1189 1189
   resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f"
1190 1190
 
1191
-clone@^1.0.0, clone@^1.0.2:
1191
+clone@^1.0.0:
1192 1192
   version "1.0.2"
1193 1193
   resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149"
1194 1194
 
@@ -1478,6 +1478,10 @@ dateformat@^1.0.11:
1478 1478
     get-stdin "^4.0.1"
1479 1479
     meow "^3.3.0"
1480 1480
 
1481
+dateformat@^2.0.0:
1482
+  version "2.0.0"
1483
+  resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17"
1484
+
1481 1485
 debug@2.3.3:
1482 1486
   version "2.3.3"
1483 1487
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.3.tgz#40c453e67e6e13c901ddec317af8986cda9eff8c"
@@ -1485,8 +1489,8 @@ debug@2.3.3:
1485 1489
     ms "0.7.2"
1486 1490
 
1487 1491
 debug@^2.0.0, debug@^2.1.0, debug@^2.1.1, debug@^2.2.0:
1488
-  version "2.5.2"
1489
-  resolved "https://registry.yarnpkg.com/debug/-/debug-2.5.2.tgz#50c295a53dbf1657146e0c1b21307275e90d49cb"
1492
+  version "2.6.0"
1493
+  resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.0.tgz#bc596bcabe7617f11d9fa15361eded5608b8499b"
1490 1494
   dependencies:
1491 1495
     ms "0.7.2"
1492 1496
 
@@ -1637,8 +1641,8 @@ diff@^2.1.2:
1637 1641
   resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99"
1638 1642
 
1639 1643
 diff@^3.0.0:
1640
-  version "3.1.0"
1641
-  resolved "https://registry.yarnpkg.com/diff/-/diff-3.1.0.tgz#9406c73a401e6c2b3ba901c5e2c44eb6a60c5385"
1644
+  version "3.2.0"
1645
+  resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
1642 1646
 
1643 1647
 doctrine@^1.2.2:
1644 1648
   version "1.5.0"
@@ -1658,11 +1662,7 @@ dom-walk@^0.1.0:
1658 1662
   version "0.1.1"
1659 1663
   resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
1660 1664
 
1661
-domelementtype@1:
1662
-  version "1.3.0"
1663
-  resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
1664
-
1665
-domelementtype@~1.1.1:
1665
+domelementtype@1, domelementtype@~1.1.1:
1666 1666
   version "1.1.3"
1667 1667
   resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
1668 1668
 
@@ -2095,15 +2095,15 @@ extsprintf@1.0.2:
2095 2095
   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
2096 2096
 
2097 2097
 fancy-log@^1.1.0:
2098
-  version "1.2.0"
2099
-  resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.2.0.tgz#d5a51b53e9ab22ca07d558f2b67ae55fdb5fcbd8"
2098
+  version "1.3.0"
2099
+  resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948"
2100 2100
   dependencies:
2101 2101
     chalk "^1.1.1"
2102 2102
     time-stamp "^1.0.0"
2103 2103
 
2104 2104
 fast-levenshtein@~2.0.4:
2105
-  version "2.0.5"
2106
-  resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.5.tgz#bd33145744519ab1c36c3ee9f31f08e9079b67f2"
2105
+  version "2.0.6"
2106
+  resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
2107 2107
 
2108 2108
 fb-watchman@^1.8.0, fb-watchman@^1.9.0:
2109 2109
   version "1.9.0"
@@ -2176,12 +2176,12 @@ filenamify@^1.0.1:
2176 2176
     strip-outer "^1.0.0"
2177 2177
     trim-repeated "^1.0.0"
2178 2178
 
2179
-fileset@0.2.x:
2180
-  version "0.2.1"
2181
-  resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.2.1.tgz#588ef8973c6623b2a76df465105696b96aac8067"
2179
+fileset@^2.0.2:
2180
+  version "2.0.3"
2181
+  resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0"
2182 2182
   dependencies:
2183
-    glob "5.x"
2184
-    minimatch "2.x"
2183
+    glob "^7.0.3"
2184
+    minimatch "^3.0.3"
2185 2185
 
2186 2186
 fill-range@^2.1.0:
2187 2187
   version "2.2.3"
@@ -2404,7 +2404,7 @@ glob-stream@^5.3.2:
2404 2404
     to-absolute-glob "^0.1.1"
2405 2405
     unique-stream "^2.0.2"
2406 2406
 
2407
-glob@5.x, glob@^5.0.15, glob@^5.0.3, glob@^5.0.5:
2407
+glob@^5.0.15, glob@^5.0.3, glob@^5.0.5:
2408 2408
   version "5.0.15"
2409 2409
   resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
2410 2410
   dependencies:
@@ -2543,14 +2543,14 @@ gulp-sourcemaps@1.6.0:
2543 2543
     vinyl "^1.0.0"
2544 2544
 
2545 2545
 gulp-util@^3.0.1, gulp-util@^3.0.4:
2546
-  version "3.0.7"
2547
-  resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.7.tgz#78925c4b8f8b49005ac01a011c557e6218941cbb"
2546
+  version "3.0.8"
2547
+  resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f"
2548 2548
   dependencies:
2549 2549
     array-differ "^1.0.0"
2550 2550
     array-uniq "^1.0.2"
2551 2551
     beeper "^1.0.0"
2552 2552
     chalk "^1.0.0"
2553
-    dateformat "^1.0.11"
2553
+    dateformat "^2.0.0"
2554 2554
     fancy-log "^1.1.0"
2555 2555
     gulplog "^1.0.0"
2556 2556
     has-gulplog "^0.1.0"
@@ -2996,35 +2996,34 @@ isstream@~0.1.2:
2996 2996
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
2997 2997
 
2998 2998
 istanbul-api@^1.0.0-aplha.10:
2999
-  version "1.0.0-aplha.10"
3000
-  resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.0.0-aplha.10.tgz#902edf5cf5404e0eba7e00ef46408488a0d3e337"
2999
+  version "1.1.0"
3000
+  resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.0.tgz#fb3f62edd5bfc6ae09da09453ded6e10ae7e483b"
3001 3001
   dependencies:
3002
-    async "1.x"
3003
-    clone "^1.0.2"
3004
-    fileset "0.2.x"
3005
-    istanbul-lib-coverage "^1.0.0-alpha"
3006
-    istanbul-lib-hook "^1.0.0-alpha"
3007
-    istanbul-lib-instrument "^1.0.0-alpha"
3008
-    istanbul-lib-report "^1.0.0-alpha"
3009
-    istanbul-lib-source-maps "^1.0.0-alpha"
3010
-    istanbul-reports "^1.0.0-alpha"
3011
-    js-yaml "3.x"
3012
-    mkdirp "0.5.x"
3013
-    once "1.x"
3002
+    async "^2.1.4"
3003
+    fileset "^2.0.2"
3004
+    istanbul-lib-coverage "^1.0.0"
3005
+    istanbul-lib-hook "^1.0.0-alpha.4"
3006
+    istanbul-lib-instrument "^1.3.0"
3007
+    istanbul-lib-report "^1.0.0-alpha.3"
3008
+    istanbul-lib-source-maps "^1.1.0"
3009
+    istanbul-reports "^1.0.0"
3010
+    js-yaml "^3.7.0"
3011
+    mkdirp "^0.5.1"
3012
+    once "^1.4.0"
3014 3013
 
3015 3014
 istanbul-lib-coverage@^1.0.0, istanbul-lib-coverage@^1.0.0-alpha, istanbul-lib-coverage@^1.0.0-alpha.0:
3016 3015
   version "1.0.0"
3017 3016
   resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.0.tgz#c3f9b6d226da12424064cce87fce0fb57fdfa7a2"
3018 3017
 
3019
-istanbul-lib-hook@^1.0.0-alpha:
3018
+istanbul-lib-hook@^1.0.0-alpha.4:
3020 3019
   version "1.0.0-alpha.4"
3021 3020
   resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.0-alpha.4.tgz#8c5bb9f6fbd8526e0ae6cf639af28266906b938f"
3022 3021
   dependencies:
3023 3022
     append-transform "^0.3.0"
3024 3023
 
3025
-istanbul-lib-instrument@^1.0.0-alpha, istanbul-lib-instrument@^1.1.1, istanbul-lib-instrument@^1.1.4:
3026
-  version "1.3.0"
3027
-  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.3.0.tgz#19f0a973397454989b98330333063a5b56df0e58"
3024
+istanbul-lib-instrument@^1.1.1, istanbul-lib-instrument@^1.1.4, istanbul-lib-instrument@^1.3.0:
3025
+  version "1.3.1"
3026
+  resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.3.1.tgz#112c25a4f2f9bc361d13d14bbff992331b974e52"
3028 3027
   dependencies:
3029 3028
     babel-generator "^6.18.0"
3030 3029
     babel-template "^6.16.0"
@@ -3034,7 +3033,7 @@ istanbul-lib-instrument@^1.0.0-alpha, istanbul-lib-instrument@^1.1.1, istanbul-l
3034 3033
     istanbul-lib-coverage "^1.0.0"
3035 3034
     semver "^5.3.0"
3036 3035
 
3037
-istanbul-lib-report@^1.0.0-alpha:
3036
+istanbul-lib-report@^1.0.0-alpha.3:
3038 3037
   version "1.0.0-alpha.3"
3039 3038
   resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.0.0-alpha.3.tgz#32d5f6ec7f33ca3a602209e278b2e6ff143498af"
3040 3039
   dependencies:
@@ -3045,7 +3044,7 @@ istanbul-lib-report@^1.0.0-alpha:
3045 3044
     rimraf "^2.4.3"
3046 3045
     supports-color "^3.1.2"
3047 3046
 
3048
-istanbul-lib-source-maps@^1.0.0-alpha:
3047
+istanbul-lib-source-maps@^1.1.0:
3049 3048
   version "1.1.0"
3050 3049
   resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.1.0.tgz#9d429218f35b823560ea300a96ff0c3bbdab785f"
3051 3050
   dependencies:
@@ -3054,7 +3053,7 @@ istanbul-lib-source-maps@^1.0.0-alpha:
3054 3053
     rimraf "^2.4.4"
3055 3054
     source-map "^0.5.3"
3056 3055
 
3057
-istanbul-reports@^1.0.0-alpha:
3056
+istanbul-reports@^1.0.0:
3058 3057
   version "1.0.0"
3059 3058
   resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.0.0.tgz#24b4eb2b1d29d50f103b369bd422f6e640aa0777"
3060 3059
   dependencies:
@@ -3295,7 +3294,7 @@ js-tokens@^2.0.0:
3295 3294
   version "2.0.0"
3296 3295
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5"
3297 3296
 
3298
-js-yaml@3.x, js-yaml@^3.5.1:
3297
+js-yaml@3.x, js-yaml@^3.5.1, js-yaml@^3.7.0:
3299 3298
   version "3.7.0"
3300 3299
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
3301 3300
   dependencies:
@@ -3758,13 +3757,13 @@ mime-db@~1.23.0:
3758 3757
   version "1.23.0"
3759 3758
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659"
3760 3759
 
3761
-mime-types@2.1.11:
3760
+mime-types@2.1.11, mime-types@~2.1.9:
3762 3761
   version "2.1.11"
3763 3762
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c"
3764 3763
   dependencies:
3765 3764
     mime-db "~1.23.0"
3766 3765
 
3767
-mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.6, mime-types@~2.1.7, mime-types@~2.1.9:
3766
+mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.6, mime-types@~2.1.7:
3768 3767
   version "2.1.13"
3769 3768
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.13.tgz#e07aaa9c6c6b9a7ca3012c69003ad25a39e92a88"
3770 3769
   dependencies:
@@ -3780,18 +3779,12 @@ min-document@^2.19.0:
3780 3779
   dependencies:
3781 3780
     dom-walk "^0.1.0"
3782 3781
 
3783
-"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2:
3782
+"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3:
3784 3783
   version "3.0.3"
3785 3784
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
3786 3785
   dependencies:
3787 3786
     brace-expansion "^1.0.0"
3788 3787
 
3789
-minimatch@2.x:
3790
-  version "2.0.10"
3791
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
3792
-  dependencies:
3793
-    brace-expansion "^1.0.0"
3794
-
3795 3788
 minimist@0.0.8, minimist@~0.0.1:
3796 3789
   version "0.0.8"
3797 3790
   resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
@@ -4023,7 +4016,7 @@ on-headers@~1.0.0, on-headers@~1.0.1:
4023 4016
   version "1.0.1"
4024 4017
   resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7"
4025 4018
 
4026
-once@1.x, once@^1.3.0:
4019
+once@1.x, once@^1.3.0, once@^1.4.0:
4027 4020
   version "1.4.0"
4028 4021
   resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
4029 4022
   dependencies:
@@ -5181,8 +5174,8 @@ time-stamp@^1.0.0:
5181 5174
   resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.0.1.tgz#9f4bd23559c9365966f3302dbba2b07c6b99b151"
5182 5175
 
5183 5176
 timed-out@^3.0.0:
5184
-  version "3.1.0"
5185
-  resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.0.tgz#43b98b14bb712c9161c28f4dc1f3068d67a04ec2"
5177
+  version "3.1.3"
5178
+  resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217"
5186 5179
 
5187 5180
 tmpl@1.0.x:
5188 5181
   version "1.0.4"