diff options
Diffstat (limited to 'iPhone/CordovaLib/Classes/CDVViewController.m')
| -rwxr-xr-x | iPhone/CordovaLib/Classes/CDVViewController.m | 172 | 
1 files changed, 137 insertions, 35 deletions
| diff --git a/iPhone/CordovaLib/Classes/CDVViewController.m b/iPhone/CordovaLib/Classes/CDVViewController.m index bec716d..94f4552 100755 --- a/iPhone/CordovaLib/Classes/CDVViewController.m +++ b/iPhone/CordovaLib/Classes/CDVViewController.m @@ -19,7 +19,6 @@  #import <objc/message.h>  #import "CDV.h" -#import "CDVCommandQueue.h"  #import "CDVCommandDelegateImpl.h"  #import "CDVConfigParser.h"  #import "CDVUserAgentUtil.h" @@ -103,6 +102,48 @@      return self;  } +- (void)viewWillAppear:(BOOL)animated +{ +    [super viewWillAppear:animated]; + +    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; +    [nc addObserver:self +           selector:@selector(keyboardWillShowOrHide:) +               name:UIKeyboardWillShowNotification +             object:nil]; +    [nc addObserver:self +           selector:@selector(keyboardWillShowOrHide:) +               name:UIKeyboardWillHideNotification +             object:nil]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ +    [super viewWillDisappear:animated]; + +    NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; +    [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil]; +    [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil]; +} + +- (void)keyboardWillShowOrHide:(NSNotification*)notif +{ +    if (![@"true" isEqualToString : self.settings[@"KeyboardShrinksView"]]) { +        return; +    } +    BOOL showEvent = [notif.name isEqualToString:UIKeyboardWillShowNotification]; + +    CGRect keyboardFrame = [notif.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; +    keyboardFrame = [self.view convertRect:keyboardFrame fromView:nil]; + +    CGRect newFrame = self.view.bounds; +    if (showEvent) { +        newFrame.size.height -= keyboardFrame.size.height; +    } +    self.webView.frame = newFrame; +    self.webView.scrollView.contentInset = UIEdgeInsetsMake(0, 0, -keyboardFrame.size.height, 0); +} +  - (void)printDeprecationNotice  {      if (!IsAtLeastiOSVersion(@"5.0")) { @@ -208,9 +249,6 @@      id backupWebStorage = self.settings[@"BackupWebStorage"];      if ([backupWebStorage isKindOfClass:[NSString class]]) {          backupWebStorageType = backupWebStorage; -    } else if ([backupWebStorage isKindOfClass:[NSNumber class]]) { -        NSLog(@"Deprecated: BackupWebStorage boolean property is a string property now (none, local, cloud). A boolean value of 'true' will be mapped to 'cloud'. Consult the docs: http://docs.cordova.io/en/edge/guide_project-settings_ios_index.md.html#Project%%20Settings%%20for%%20iOS"); -        backupWebStorageType = [(NSNumber*) backupWebStorage boolValue] ? @"cloud" : @"none";      }      self.settings[@"BackupWebStorage"] = backupWebStorageType; @@ -231,6 +269,10 @@      if ([self.settings objectForKey:@"MediaPlaybackRequiresUserAction"]) {          mediaPlaybackRequiresUserAction = [(NSNumber*)[settings objectForKey:@"MediaPlaybackRequiresUserAction"] boolValue];      } +    BOOL hideKeyboardFormAccessoryBar = NO;  // default value +    if ([self.settings objectForKey:@"HideKeyboardFormAccessoryBar"]) { +        hideKeyboardFormAccessoryBar = [(NSNumber*)[settings objectForKey:@"HideKeyboardFormAccessoryBar"] boolValue]; +    }      self.webView.scalesPageToFit = [enableViewportScale boolValue]; @@ -239,14 +281,26 @@       */      if ([enableLocation boolValue]) { +        NSLog(@"Deprecated: The 'EnableLocation' boolean property is deprecated in 2.5.0, and will be removed in 3.0.0. Use the 'onload' boolean attribute (of the CDVLocation plugin.");          [[self.commandDelegate getCommandInstance:@"Geolocation"] getLocation:[CDVInvokedUrlCommand new]];      } +    if (hideKeyboardFormAccessoryBar) { +        __weak CDVViewController* weakSelf = self; +        [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification +                                                          object:nil +                                                           queue:[NSOperationQueue mainQueue] +                                                      usingBlock:^(NSNotification* notification) { +            // we can't hide it here because the accessory bar hasn't been created yet, so we delay on the queue +            [weakSelf performSelector:@selector(hideKeyboardFormAccessoryBar) withObject:nil afterDelay:0]; +        }]; +    } +      /*       * Fire up CDVLocalStorage to work-around WebKit storage limitations: on all iOS 5.1+ versions for local-only backups, but only needed on iOS 5.1 for cloud backup.       */      if (IsAtLeastiOSVersion(@"5.1") && (([backupWebStorageType isEqualToString:@"local"]) || -            ([backupWebStorageType isEqualToString:@"cloud"] && !IsAtLeastiOSVersion(@"6.0")))) { +        ([backupWebStorageType isEqualToString:@"cloud"] && !IsAtLeastiOSVersion(@"6.0")))) {          [self registerPlugin:[[CDVLocalStorage alloc] initWithWebView:self.webView] withClassName:NSStringFromClass([CDVLocalStorage class])];      } @@ -260,12 +314,19 @@          self.webView.mediaPlaybackRequiresUserAction = NO;      } -    // UIWebViewBounce property - defaults to true -    NSNumber* bouncePreference = [self.settings objectForKey:@"UIWebViewBounce"]; -    BOOL bounceAllowed = (bouncePreference == nil || [bouncePreference boolValue]); +    // By default, overscroll bouncing is allowed. +    // UIWebViewBounce has been renamed to DisallowOverscroll, but both are checked. +    BOOL bounceAllowed = YES; +    NSNumber* disallowOverscroll = [self.settings objectForKey:@"DisallowOverscroll"]; +    if (disallowOverscroll == nil) { +        NSNumber* bouncePreference = [self.settings objectForKey:@"UIWebViewBounce"]; +        bounceAllowed = (bouncePreference == nil || [bouncePreference boolValue]); +    } else { +        bounceAllowed = ![disallowOverscroll boolValue]; +    }      // prevent webView from bouncing -    // based on UIWebViewBounce key in config.xml +    // based on the DisallowOverscroll/UIWebViewBounce key in config.xml      if (!bounceAllowed) {          if ([self.webView respondsToSelector:@selector(scrollView)]) {              ((UIScrollView*)[self.webView scrollView]).bounces = NO; @@ -307,8 +368,16 @@          }      } -    for (NSString* pluginName in self.startupPluginNames) { -        [self getCommandInstance:pluginName]; +    if ([self.startupPluginNames count] > 0) { +        [CDVTimer start:@"TotalPluginStartup"]; + +        for (NSString* pluginName in self.startupPluginNames) { +            [CDVTimer start:pluginName]; +            [self getCommandInstance:pluginName]; +            [CDVTimer stop:pluginName]; +        } + +        [CDVTimer stop:@"TotalPluginStartup"];      }      // TODO: Remove this explicit instantiation once we move to cordova-CLI. @@ -318,16 +387,44 @@      // /////////////////      [CDVUserAgentUtil acquireLock:^(NSInteger lockToken) { -            _userAgentLockToken = lockToken; -            [CDVUserAgentUtil setUserAgent:self.userAgent lockToken:lockToken]; -            if (!loadErr) { -                NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0]; -                [self.webView loadRequest:appReq]; -            } else { -                NSString* html = [NSString stringWithFormat:@"<html><body> %@ </body></html>", loadErr]; -                [self.webView loadHTMLString:html baseURL:nil]; +        _userAgentLockToken = lockToken; +        [CDVUserAgentUtil setUserAgent:self.userAgent lockToken:lockToken]; +        if (!loadErr) { +            NSURLRequest* appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0]; +            [self.webView loadRequest:appReq]; +        } else { +            NSString* html = [NSString stringWithFormat:@"<html><body> %@ </body></html>", loadErr]; +            [self.webView loadHTMLString:html baseURL:nil]; +        } +    }]; +} + +- (void)hideKeyboardFormAccessoryBar +{ +    NSArray* windows = [[UIApplication sharedApplication] windows]; + +    for (UIWindow* window in windows) { +        for (UIView* view in window.subviews) { +            if ([[view description] hasPrefix:@"<UIPeripheralHostView"]) { +                for (UIView* peripheralView in view.subviews) { +                    // hides the accessory bar +                    if ([[peripheralView description] hasPrefix:@"<UIWebFormAccessory"]) { +                        // remove the extra scroll space for the form accessory bar +                        CGRect newFrame = self.webView.scrollView.frame; +                        newFrame.size.height += peripheralView.frame.size.height; +                        self.webView.scrollView.frame = newFrame; + +                        // remove the form accessory bar +                        [peripheralView removeFromSuperview]; +                    } +                    // hides the thin grey line used to adorn the bar (iOS 6) +                    if ([[peripheralView description] hasPrefix:@"<UIImageView"]) { +                        [[peripheralView layer] setOpacity:0.0]; +                    } +                }              } -        }]; +        } +    }  }  - (NSArray*)parseInterfaceOrientations:(NSArray*)orientations @@ -518,12 +615,6 @@      // It's safe to release the lock even if this is just a sub-frame that's finished loading.      [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; -    // The .onNativeReady().fire() will work when cordova.js is already loaded. -    // The _nativeReady = true; is used when this is run before cordova.js is loaded. -    NSString* nativeReady = @"try{cordova.require('cordova/channel').onNativeReady.fire();}catch(e){window._nativeReady = true;}"; -    // Don't use [commandDelegate evalJs] here since it relies on cordova.js being loaded already. -    [self.webView stringByEvaluatingJavaScriptFromString:nativeReady]; -      /*       * Hide the Top Activity THROBBER in the Battery Bar       */ @@ -531,7 +622,7 @@      [self processOpenUrl]; -    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:nil]]; +    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:self.webView]];  }  - (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error @@ -660,6 +751,22 @@      [plugin pluginInitialize];  } +- (void)registerPlugin:(CDVPlugin*)plugin withPluginName:(NSString*)pluginName +{ +    if ([plugin respondsToSelector:@selector(setViewController:)]) { +        [plugin setViewController:self]; +    } + +    if ([plugin respondsToSelector:@selector(setCommandDelegate:)]) { +        [plugin setCommandDelegate:_commandDelegate]; +    } + +    NSString* className = NSStringFromClass([plugin class]); +    [self.pluginObjects setObject:plugin forKey:className]; +    [self.pluginsMap setValue:className forKey:[pluginName lowercaseString]]; +    [plugin pluginInitialize]; +} +  /**   Returns an instance of a CordovaCommand object, based on its name.  If one exists already, it is returned.   */ @@ -678,7 +785,7 @@      id obj = [self.pluginObjects objectForKey:className];      if (!obj) { -        obj = [[NSClassFromString (className)alloc] initWithWebView:webView]; +        obj = [[NSClassFromString(className)alloc] initWithWebView:webView];          if (obj != nil) {              [self registerPlugin:obj withClassName:className]; @@ -814,13 +921,8 @@  - (void)dealloc  {      [CDVURLProtocol unregisterViewController:self]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillTerminateNotification object:nil]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; -    [[NSNotificationCenter defaultCenter] removeObserver:self name:CDVPluginHandleOpenURLNotification object:nil]; +    [[NSNotificationCenter defaultCenter] removeObserver:self]; +      self.webView.delegate = nil;      self.webView = nil;      [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; | 
