[ios] some fix
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXRichText.mm b/ios/sdk/WeexSDK/Sources/Component/WXRichText.mm
index d007d60..cfbbea6 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXRichText.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/WXRichText.mm
@@ -28,6 +28,7 @@
 #import "WXComponentManager.h"
 #import "WXLog.h"
 #import "WXDarkSchemeProtocol.h"
+#import "WXAssert.h"
 #include <pthread/pthread.h>
 
 @interface WXRichNode : NSObject
@@ -80,7 +81,6 @@
         self.accessibilityTraits |= UIAccessibilityTraitStaticText;
         self.opaque = NO;
         self.editable = NO;
-        self.selectable = YES;
         self.contentMode = UIViewContentModeRedraw;
         self.textContainerInset = UIEdgeInsetsZero;
         self.textContainer.lineFragmentPadding = 0.0f;
@@ -126,6 +126,7 @@
     pthread_mutex_t _attributedStringMutex;
     pthread_mutexattr_t _propertMutexAttr;
     CGFloat _lineHeight;
+    BOOL _selectable;
 }
 
 - (void)dealloc
@@ -140,6 +141,7 @@
         textView = [[WXRichTextView alloc]init];
         textView.delegate = self;
         textView.scrollEnabled = NO;
+        textView.selectable = _selectable;
     }
     return textView;
 }
@@ -162,6 +164,10 @@
         pthread_mutexattr_init(&(_propertMutexAttr));
         pthread_mutexattr_settype(&(_propertMutexAttr), PTHREAD_MUTEX_RECURSIVE);
         pthread_mutex_init(&(_attributedStringMutex), &(_propertMutexAttr));
+        _selectable = YES;
+        if (_attributes[@"selectable"]) {
+            _selectable = [WXConvert BOOL:_attributes[@"selectable"]];
+        }
     }
     return self;
 }
@@ -595,10 +601,24 @@
 }
 
 - (void)updateAttributes:(NSDictionary *)attributes {
+    WXAssertMainThread();
+
+    if (attributes[@"selectable"]) {
+        _selectable = [WXConvert BOOL:attributes[@"selectable"]];
+    }
+    [self textView].selectable = _selectable;
+
+    __weak WXRichText* weakSelf = self;
     WXPerformBlockOnComponentThread(^{
-        _attributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
-        [self syncTextStorageForView];
+        __strong WXRichText* strongSelf = weakSelf;
+        if (strongSelf == nil) {
+            return;
+        }
+        strongSelf->_attributes = [NSMutableDictionary dictionaryWithDictionary:attributes];
+        [strongSelf syncTextStorageForView];
     });
+
+
 }
 
 - (void)updateChildNodeAttributes:(NSDictionary *)attributes ref:(NSString*)ref parentRef:(NSString*)parentRef {
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.mm b/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.mm
index 27538dc..ac9f5a4 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.mm
+++ b/ios/sdk/WeexSDK/Sources/Component/WXTextComponent.mm
@@ -947,7 +947,7 @@
         attrs = attrs ? attrs.mutableCopy : [NSMutableDictionary new];
         CTFontRef font = (__bridge CTFontRef)(attrs[(id)kCTFontAttributeName]);
         CGFloat fontSize = font ? CTFontGetSize(font):32 * self.weexInstance.pixelScaleFactor;
-        UIFont * uiFont = [UIFont systemFontOfSize:fontSize];
+        UIFont *uiFont = [WXUtility fontWithSize:fontSize textWeight:_fontWeight textStyle:WXTextStyleNormal fontFamily:self.fontFamily scaleFactor:self.weexInstance.pixelScaleFactor useCoreText:[self useCoreText]];
         if (uiFont) {
             font = CTFontCreateWithFontDescriptor((__bridge CTFontDescriptorRef)uiFont.fontDescriptor, uiFont.pointSize, NULL);
         }
@@ -1079,6 +1079,8 @@
     CGFloat ascent = 0;
     CGFloat descent = 0;
     CGFloat leading = 0;
+    CGPoint lineOrigins[lineCount];
+    CTFrameGetLineOrigins(frameRef, CFRangeMake(0, 0), lineOrigins);
     
     // height = ascent + descent + lineCount*leading
     // ignore linespaing
@@ -1091,7 +1093,6 @@
         totalHeight += ascent + descent;
         actualLineCount ++;
     }
-    
     totalHeight = totalHeight + actualLineCount * leading;
     CFRelease(frameRef);
     
@@ -1102,6 +1103,18 @@
         }
         return CGSizeMake(aWidth, suggestSize.height);
     }
+    if (WX_SYS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"14.0")) {
+        if (lineCount <= 1) {
+            return CGSizeMake(aWidth, totalHeight);
+        }
+        if (_lines && lineCount > _lines) {
+            actualLineCount = _lines;
+        } else {
+            actualLineCount = lineCount;
+        }
+        CGFloat actualLineHeight = lineOrigins[0].y - lineOrigins[1].y;
+        return CGSizeMake(aWidth, actualLineCount * actualLineHeight);
+    }
     return CGSizeMake(aWidth, totalHeight);
 }
 
diff --git a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
index d7b594c..3177a7e 100644
--- a/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
+++ b/ios/sdk/WeexSDK/Sources/Events/WXComponent+Events.m
@@ -33,6 +33,8 @@
 #import <UIKit/UIGestureRecognizerSubclass.h>
 #import "WXComponent+PseudoClassManagement.h"
 #import "WXCoreBridge.h"
+#import "WXSDKEngine.h"
+#import "WXConfigCenterProtocol.h"
 
 #pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
 
@@ -575,9 +577,16 @@
 - (void)addPanGesture
 {
     if (!_panGesture) {
+        _enableScreenEdgePanGesture = YES;
         _panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPan:)];
+
         _panGesture.delegate = self;
         [self.view addGestureRecognizer:_panGesture];
+
+        id configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
+        if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
+            _enableScreenEdgePanGesture = [[configCenter configForKey:@"iOS_weex_ext_config.enableScreenEdgePanGesture" defaultValue:@(YES) isDefault:NULL] boolValue];
+        }
     }
 }
 
@@ -840,6 +849,12 @@
     if ([gestureRecognizer isKindOfClass:[WXTouchGestureRecognizer class]]) {
         return YES;
     }
+
+    if (_enableScreenEdgePanGesture && gestureRecognizer == _panGesture && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ![otherGestureRecognizer isKindOfClass:NSClassFromString(panGestureRecog)]) {
+        [gestureRecognizer requireGestureRecognizerToFail:otherGestureRecognizer];
+        return YES;
+    }
+
     // swipe and scroll
     if ([gestureRecognizer isKindOfClass:[UISwipeGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:NSClassFromString(panGestureRecog)]) {
         return YES;
diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXDatePickerManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXDatePickerManager.m
index 9c67181..0636fa4 100644
--- a/ios/sdk/WeexSDK/Sources/Manager/WXDatePickerManager.m
+++ b/ios/sdk/WeexSDK/Sources/Manager/WXDatePickerManager.m
@@ -22,6 +22,7 @@
 #import <UIKit/UIKit.h>
 #import "WXConvert.h"
 #import "WXUtility.h"
+#import "WXLegacyAdapter.h"
 
 #define WXPickerHeight 266
 
@@ -61,13 +62,12 @@
         {
             datePicker = [[UIDatePicker alloc]init];
         }
-        
-        datePicker.datePickerMode=UIDatePickerModeDate;
-#ifdef __IPHONE_13_4
+    #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130400)
         if (@available(iOS 13.4, *)) {
             datePicker.preferredDatePickerStyle = UIDatePickerStyleWheels;
         }
-#endif
+    #endif
+        datePicker.datePickerMode=UIDatePickerModeDate;
         CGRect pickerFrame = CGRectMake(0, 44, [UIScreen mainScreen].bounds.size.width, WXPickerHeight-44);
         datePicker.backgroundColor = [UIColor whiteColor];
         datePicker.frame = pickerFrame;
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m b/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m
index 6e6f353..4607e4a 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXModalUIModule.m
@@ -65,6 +65,8 @@
 
 @interface WXModalUIModule () <UIAlertViewDelegate>
 
+@property (nonatomic, assign) CGFloat maxWidth;
+
 @end
 
 @implementation WXModalUIModule
@@ -107,9 +109,52 @@
         duration = WXToastDefaultDuration;
     }
     
-    WXPerformBlockOnMainThread(^{
-        [self toast:message duration:duration];
-    });
+    _maxWidth = WXToastDefaultWidth;
+    if (param[@"maxWidth"]) {
+        double maxWidth = [param[@"maxWidth"] doubleValue];
+        if (maxWidth > 0) {
+            _maxWidth = maxWidth;
+        }
+    }
+    
+    double animationTime = [param[@"animationTime"] doubleValue];
+    if (animationTime > 0) {
+        WXPerformBlockOnMainThread(^{
+            [self toast:message duration:duration animationTime:animationTime];
+        });
+    } else {
+        WXPerformBlockOnMainThread(^{
+            [self toast:message duration:duration];
+        });
+    }
+}
+
+- (void)toast:(NSString *)message duration:(double)duration animationTime:(double)animationTime{
+    WXAssertMainThread();
+    UIView *superView = self.weexInstance.rootView.window;
+    if (!superView) {
+        superView =  self.weexInstance.rootView;
+    }
+    UIView *toastView = [self toastViewForMessage:message superView:superView];
+    
+    UIView* toastingView = [WXToastManager sharedManager].toastingView;
+    if (toastingView) {
+        [toastingView removeFromSuperview];
+        [WXToastManager sharedManager].toastingView = nil;
+    }
+    if (!toastView || !superView) {
+        return;
+    }
+    [WXToastManager sharedManager].toastingView = toastView;
+    [superView addSubview:toastView];
+    [UIView animateWithDuration:animationTime delay:duration options:UIViewAnimationOptionCurveEaseInOut animations:^{
+        toastView.alpha = 0;
+    } completion:^(BOOL finished) {
+        [toastView removeFromSuperview];
+        if ([WXToastManager sharedManager].toastingView == toastView) {
+            [WXToastManager sharedManager].toastingView = nil;
+        }
+    }];
 }
 
 - (void)toast:(NSString *)message duration:(double)duration
@@ -132,7 +177,7 @@
 - (UIView *)toastViewForMessage:(NSString *)message superView:(UIView *)superView
 {
     CGFloat padding = WXToastDefaultPadding;
-    UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(padding/2, padding/2, WXToastDefaultWidth, WXToastDefaultHeight)];
+    UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(padding/2, padding/2, _maxWidth, WXToastDefaultHeight)];
     messageLabel.numberOfLines =  0;
     messageLabel.textAlignment = NSTextAlignmentCenter;
     messageLabel.text = message;
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXPickerModule.m b/ios/sdk/WeexSDK/Sources/Module/WXPickerModule.m
index c5b57a3..0c4da1c 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXPickerModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXPickerModule.m
@@ -24,6 +24,7 @@
 #import <UIKit/UIPickerView.h>
 #import <UIKit/UIDatePicker.h>
 #import <UIKit/UIKit.h>
+#import "WXLegacyAdapter.h"
 
 #define WXPickerHeight 266
 #define WXPickerToolBarHeight 44
@@ -432,7 +433,7 @@
 {
     self.callback = callback;
     self.datePicker = [[UIDatePicker alloc]init];
-#ifdef __IPHONE_13_4
+#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130400)
     if (@available(iOS 13.4, *)) {
         self.datePicker.preferredDatePickerStyle = UIDatePickerStyleWheels;
     }
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m b/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m
index 72106b9..7c6e3fd 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXStreamModule.m
@@ -27,6 +27,7 @@
 #import "WXSDKEngine.h"
 #import "WXSDKInstance_performance.h"
 #import "WXMonitor.h"
+#import "WXConvert.h"
 
 @implementation WXStreamModule
 
@@ -141,9 +142,17 @@
     if (self.weexInstance && !weexInstance.isJSCreateFinish) {
         self.weexInstance.performance.fsReqNetNum++;
     }
-    
-    WXResourceRequest *request = [WXResourceRequest requestWithURL:[NSURL URLWithString:urlStr] resourceType:WXResourceTypeOthers referrer:nil cachePolicy:NSURLRequestUseProtocolCachePolicy];
-    
+    BOOL shouldSetReferer = NO;
+    if ([options objectForKey:@"referer"] ) {
+        shouldSetReferer = [WXConvert BOOL:[options objectForKey:@"referer"]];
+    }
+    NSRange range = [weexInstance.scriptURL.absoluteString rangeOfString:@"?"];
+    NSString *referer = nil;
+    if (range.length > 0 && shouldSetReferer) {
+        referer = [weexInstance.scriptURL.absoluteString substringToIndex:range.location];
+    }
+    WXResourceRequest *request = [WXResourceRequest requestWithURL:[NSURL URLWithString:urlStr] resourceType:WXResourceTypeOthers referrer:referer cachePolicy:NSURLRequestUseProtocolCachePolicy];
+
     // parse http method
     NSString *method = [options objectForKey:@"method"];
     if ([WXUtility isBlankString:method]) {
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXConvert.m b/ios/sdk/WeexSDK/Sources/Utility/WXConvert.m
index 85ab360..b749144 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXConvert.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXConvert.m
@@ -389,13 +389,22 @@
               unichar t =   [rgba characterAtIndex:3];
               rgba = [NSString stringWithFormat:@"#%C%C%C%C%C%C", f, f, s, s, t, t];
             }
-            
-            // 3. #rrggbb
-            uint32_t colorValue = 0;
-            sscanf(rgba.UTF8String, "#%x", &colorValue);
-            red     = ((colorValue & 0xFF0000) >> 16) / 255.0;
-            green   = ((colorValue & 0x00FF00) >> 8) / 255.0;
-            blue    = (colorValue & 0x0000FF) / 255.0;
+            // 2. #aarrggbb
+            if ([rgba length] == 9) {
+                uint32_t colorValue = 0;
+                sscanf(rgba.UTF8String, "#%x", &colorValue);
+                alpha = ((colorValue & 0xFF000000) >> 24) / 255.0;
+                red = ((colorValue & 0x00FF0000) >> 16) / 255.0;
+                green = ((colorValue & 0x0000FF00) >> 8) / 255.0;
+                blue = (colorValue & 0x000000FF) / 255.0;
+            } else {
+                // 3. #rrggbb
+                uint32_t colorValue = 0;
+                sscanf(rgba.UTF8String, "#%x", &colorValue);
+                red     = ((colorValue & 0xFF0000) >> 16) / 255.0;
+                green   = ((colorValue & 0x00FF00) >> 8) / 255.0;
+                blue    = (colorValue & 0x0000FF) / 255.0;
+            }
         } else if ([rgba hasPrefix:@"rgb("]) {
             // 4. rgb(r,g,b)
             int r,g,b;
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXLegacyAdapter.h b/ios/sdk/WeexSDK/Sources/Utility/WXLegacyAdapter.h
new file mode 100644
index 0000000..6c50ff0
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXLegacyAdapter.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#ifndef WXLegacyAdapter_h
+#define WXLegacyAdapter_h
+
+API_AVAILABLE(ios(13.4))
+@interface UIDatePicker (LegacyXcode)
+
+#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130400)
+@property (nonatomic, readwrite, assign) UIDatePickerStyle preferredDatePickerStyle;
+#endif
+
+@end
+
+
+#endif /* WXLegacyAdapter_h */
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
index 0112322..66d6ad8 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h
@@ -540,6 +540,8 @@
 
 + (long) getUnixFixTimeMillis;
 
++ (long)getIntervalTime;
+
 + (NSArray<NSString *> *_Nullable)extractPropertyNamesOfJSValueObject:(JSValue *_Nullable)jsvalue;
 
 @end
diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
index ebe1a8f..6caf13e 100644
--- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
+++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m
@@ -46,6 +46,7 @@
 static BOOL enableRTLLayoutDirection = YES;
 static BOOL isDarkSchemeSupportEnabled = YES;
 static BOOL enableAdaptiveLayout = NO;
+static long intervalTime = 0;
 
 void WXPerformBlockOnMainThread(void (^ _Nonnull block)(void))
 {
@@ -1115,10 +1116,15 @@
     
     dispatch_once(&unixTimeToken, ^{
         sInterval = [[NSDate date] timeIntervalSince1970] * 1000 - CACurrentMediaTime()*1000;
+        intervalTime = sInterval;
     });
     return sInterval+CACurrentMediaTime()*1000;
 }
 
++ (long)getIntervalTime {
+    return intervalTime;
+}
+
 + (NSArray<NSString *> *)extractPropertyNamesOfJSValueObject:(JSValue *)jsvalue
 {
     if (!jsvalue) {