Ios cordova app randomly got frozen after dismissing inappbrowser
Hi, During the recent testing of our ios cordova applications, we got an issue of the app’s main UIwebview UI freezing after dismissing the inappbrowser. Debugging shows somehow the UIWindow created by inappbrowser did not deallocated as expected after calling the close method to dismiss the inappbrowser. So although the inappbrowser’s UIWindows is invisiable, but it is still the keywindow and receive the user input. The xcode instrument shows there is only one reference on the inappbrowser’s UIWindow object , which is expected to be released after dismissing the inappbrowser viewcontroller. Although this part of logic is inside the Apple SDK, and not sure exactly when the UIWindow is released within the Apple SDK. Note this happens randomly, so it may be a timing related issue. Just wonder whether anyone else has seen the similar issue? Or have any idea about it. Both main webview and inappbrwoser webview use UIWebView to show the html content. WKWebview is not involved. For now, we added an if condition in the show method in dispatch_async block in our inappbrowser.m to work around the issue, but if others see the same thing, we will need to have a pull request for this change. - (void)show:(CDVInvokedUrlCommand*)command { … // Run later to avoid the "took a long time" log message. dispatch_async(dispatch_get_main_queue(), ^{ if (weakSelf.inAppBrowserViewController != nil) { if ([weakSelf.inAppBrowserViewController.webView isKindOfClass:[WKWebView class]]) { CGRect frame = [[UIScreen mainScreen] bounds]; UIWindow *tmpWindow = [[UIWindow alloc] initWithFrame:frame]; UIViewController *tmpController = [[UIViewController alloc] init]; [tmpWindow setRootViewController:tmpController]; [tmpWindow setWindowLevel:UIWindowLevelNormal]; [tmpWindow makeKeyAndVisible]; [tmpController presentViewController:nav animated:YES completion:nil]; } else { [weakSelf.viewController presentViewController:nav animated:YES completion:nil]; } } }); } Thanks Jonathan
Create hybrid app using iOS cordova with WKWebView
Hi, Recently we start to investigate the possibility to adopt WKWebView for building ios cordova hybrid apps. Currently those apps are built with UIWebView on ios cordova library. In our application, the main html content is loaded from remote web server at runtime, and local cordova js resource are then injected into html page to leverage the device native functions, such as camera, calendar, etc. As the html page is loaded from remote server using https connection, the wkwebview will not allow the local web resource (for example, cordova.js) to be injected into the html page by local file url (file:// url). We also tried to use the cordova localhost webserver plugin to inject the local web resource into the html page, but that does not work either as localhost web server plugin only supports http connection, and wkwebview does not allow to inject http content into the https html page. In addition, as https://localhost: is a different domain from the remote web page, so xhr request from https://localhost: will not be able to receive wkwebview’s didReceiveAuthenticationChallenge callback method to handle the challenge. Those limitations also apply even if injecting cordova web resource to a new iframe on the https html page. So, in order to solve the issue, I wonder whether it is possible to have an option in cordova to allow loading the js resource as javascript context so instead of loading the js file as url as shown below the javascript content will be loaded directly into the script element …raw plugin script content In this way, all the cordova script and remote https content can live in a single domain to avoid the cross domain limiation. The initial loading of codova.js and other preload plugin js files can be injected using wkwebview userContentController at WKUserScriptInjectionTimeAtDocumentEnd. For the on-demand loading of plugin js files, the cordova.js can let the require method to send a cordova bridge call and then use wkwebview’s evaluateJavaScript method to load those javascitp content in
Re: optimizing ios inappbrowser plugin's open and openInSystem method s
Hi, The problem with self.callbackId = command.callbackId; is it causes the current inappbrowser stopping work properly after user clicks a link to open mobile safari using window.open method from the current inappbrowser html page. In our application, the inappbrowser is opened in inappbrowser webivew controller, the open method will set self.callbackId to the related value. In the html page loaded in the inappbrowser, there is link using window.open with system target to open an external page in mobile safari. When user clicks this link, the inappbrowser open method will be called again, and set self.callbackid to a new vaule, as a result after the mobile safari is opened, the original inappbrowser’s callback will not work anymore as its callback id is replaced by the second open method. Theoretically, the first inappbrowser’s function should still not be affected if it opens another link in new system browser, as the callback id is not used by system browser For the issue of when to use SASafarirViewController, it seems SASafariViewController is more a replacement for mobile safari (for system target) instead of inappbrowser webviewcontroller (for blank target). As SFSafariViewController is designed to replace the function of mobile safari, so there are no backward compatible issues or losing functions by doing so, and application will not have any major behavior difference with this change. On the other hand, SASafariViewController does not provide all the functions provided by inappbrowser webviewcontroller, replacing inappbrowser webview controller with SASafariViewController will have more risks. Thanks Jonathan From: julio cesar sanchez <jcesarmob...@gmail.com> Date: Wednesday, September 7, 2016 at 3:25 AM To: "Li, Jonathan" <jonathan...@sap.com> Cc: "dev@cordova.apache.org" <dev@cordova.apache.org> Subject: Re: optimizing ios inappbrowser plugin's open and openInSystem method s What is the problem self.callbackId = command.callbackId; causes when used with _system option? I think _system option should open in safari app as it does now, and SFSafariViewController should replace the ViewController we use when _blank is used. 2016-09-07 6:41 GMT+02:00 Li, Jonathan <jonathan...@sap.com<mailto:jonathan...@sap.com>>: Hi, Currently there are two issues in iOS inappbrowser’s open and openInSystem methods. First, in the inappbrowser open method, it sets the instance variable at below self.callbackId = command.callbackId; this causes the problem when opening a _system targe from an inappbrowser viewController, even if the callbackID are not applicable to system browser. Second, the _system target will always be opened in external mobile safari browser, although SFSafariViewController for iOS 9 device provides a better user experience. The major benefit with SFSafariViewController is the application staying in foreground, so that the application does not need to handle the application life cycle events triggered by opening the mobile safari. The below code is a prototype handling the two issues. Just want to know your comment about this change, and if it is fine, a pull request will be submitted for it. - (void)open:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult; NSString* url = [command argumentAtIndex:0]; NSString* target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf]; NSString* options = [command argumentAtIndex:2 withDefault:@"" andClass:[NSString class]]; //**the below line causes trouble to open system url from inappbrowser //self.callbackId = command.callbackId; if (url != nil) { #ifdef __CORDOVA_4_0_0 NSURL* baseUrl = [self.webViewEngine URL]; #else NSURL* baseUrl = [self.webView.request URL]; #endif NSURL* absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL]; if ([self isSystemUrl:absoluteUrl]) { target = kInAppBrowserTargetSystem; } if ([target isEqualToString:kInAppBrowserTargetSelf]) { [self openInCordovaWebView:absoluteUrl withOptions:options]; } else if ([target isEqualToString:kInAppBrowserTargetSystem]) { [self openInSystem:absoluteUrl]; } else { // _blank or anything else [self openInInAppBrowser:absoluteUrl withOptions:options]; } pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; } else { pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"incorrect number of arguments"]; } //***new code if (![target isEqualToString:kInAppBrowserTargetSystem]) { [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; self.callbackId = command.callbackId; } [self.commandDelegate sendPluginResult:pluginResult
Re: Cordova bridge call exception console log does not include call stack information
Hi, The issue is created for the issue at https://issues.apache.org/jira/browse/CB-11786 Thanks Jonathan On 8/30/16, 5:20 PM, "julio cesar sanchez" <jcesarmob...@gmail.com> wrote: Hi. Can you create an issue on issues.cordova.io? El martes, 30 de agosto de 2016, Li, Jonathan <jonathan...@sap.com> escribió: > > Hi, > In cordova.js, callbackFromNative method, when handles the exception, it > only logs the callbackid and error message, but does not log the error > callstack. Usually the callstack is quite useful to find what causes the > exception, so just wonder what is the reason to not include it in the error > console log. > > If it is fine to include the call stack information in the console log, I > would like to submit a pull request for the change. > > > /** > * Called by native code when returning the result from an action. > */ > callbackFromNative: function(callbackId, isSuccess, status, args, > keepCallback) { > try { > var callback = cordova.callbacks[callbackId]; > if (callback) { > if (isSuccess && status == cordova.callbackStatus.OK) { > callback.success && callback.success.apply(null, args); > } else if (!isSuccess) { > callback.fail && callback.fail.apply(null, args); > } > /* > else > Note, this case is intentionally not caught. > this can happen if isSuccess is true, but > callbackStatus is NO_RESULT > which is used to remove a callback from the list > without calling the callbacks > typically keepCallback is false in this case > */ > // Clear callback if not expecting any more results > if (!keepCallback) { > delete cordova.callbacks[callbackId]; > } > } > } > catch (err) { > var msg = "Error in " + (isSuccess ? "Success" : "Error") + " > callbackId: " + callbackId + " : " + err; > console && console.log && console.log(msg); > cordova.fireWindowEvent("cordovacallbackerror", { 'message': > msg }); > throw err; > } > > Thanks > Jonathan > - To unsubscribe, e-mail: dev-unsubscr...@cordova.apache.org For additional commands, e-mail: dev-h...@cordova.apache.org
Re: Cordova bridge call exception console log does not include call stack information
Hi, In cordova.js, callbackFromNative method, when handles the exception, it only logs the callbackid and error message, but does not log the error callstack. Usually the callstack is quite useful to find what causes the exception, so just wonder what is the reason to not include it in the error console log. If it is fine to include the call stack information in the console log, I would like to submit a pull request for the change. /** * Called by native code when returning the result from an action. */ callbackFromNative: function(callbackId, isSuccess, status, args, keepCallback) { try { var callback = cordova.callbacks[callbackId]; if (callback) { if (isSuccess && status == cordova.callbackStatus.OK) { callback.success && callback.success.apply(null, args); } else if (!isSuccess) { callback.fail && callback.fail.apply(null, args); } /* else Note, this case is intentionally not caught. this can happen if isSuccess is true, but callbackStatus is NO_RESULT which is used to remove a callback from the list without calling the callbacks typically keepCallback is false in this case */ // Clear callback if not expecting any more results if (!keepCallback) { delete cordova.callbacks[callbackId]; } } } catch (err) { var msg = "Error in " + (isSuccess ? "Success" : "Error") + " callbackId: " + callbackId + " : " + err; console && console.log && console.log(msg); cordova.fireWindowEvent("cordovacallbackerror", { 'message': msg }); throw err; } Thanks Jonathan
introduction
Hi all, I'm getting myself set up as a contributor to Cordova. So far I've just been working on projects that use Cordova, but I hope to contribute back to Cordova in the future. The first change I plan to make is fixing bug CB-3071, so iOS cordova app does not need to use SDURLCache as a workaround for this issue. Few crashes have been reported in SDURLCache code, and it is better to fix the issue in cordova and get rid of SDURLCache from the project. Regards, Jonathan
Reopen iOS bug CB-3071
Hi, Due to bug https://issues.apache.org/jira/browse/CB-3071, the cached response gets invalidated after each time restarting the iOS cordova app, the suggested workaround is to use the open source SDURLCache project, however, SDURLCache is not a good candidate to replace the iOS default NSURLCache, as it does not follow the RFC 2616 specification very well, and cannot be used in many projects that requires serious cache functions. The testing shows the issue of CB-3071 is related to the iOS cordova useragaent logic. When each time the app restarts, the uiWebView will get a new address, and this address is appended to the UIWebView's user agent string, so the user agent is different for each running session. iOS will automatically invalidate the cached response if it detects the user agent has been changed, as user agent contains locale information, and if locale setting is changed, the same url may get the different response from server side. This can be verified by always appending a constant number to the user agent string, in that case, the cached response can be loaded after the app restarts It seems the issue can be fixed by changing the current NSMutableSet* gRegisteredControllers to NSMutalbleDictionary object, the dictionary object uses a incremental sequential id as key, and use the view controller’s address as value, then only appending the sequential id in the user agent string. This sequential id can be used to find the corresponding view controller from gRegisteredControllers collection. As most cordova app will only create a single CDVViewController, so the sequential id most likely is always 0. This will generate the same user agent string across app running sessions, and keep the cached response valid. Please let me know if the bug CB-3071 can be reopened and get fixed with this idea. Thanks Jonathan
Inconsistent behavior when opening inappbrowser window
When creating inappBrowser in cordova app, for iOS, only a single uiwebview instance is created for multiple window.open method calls, and it only shows the content of last window.open's url content. However, on Android client, each window.open method call will create a separate webview instance with its own url content. Just want to confirm is this an expected behavior? Is there any change planned to make the behavior more consistent across all client platforms? Sample code to call window.open multiple times: var windowRef = window.open( 'http://google.com', '_blank', 'location=yes'); var windowRef2 = window.open('http://apache.org', '_blank', 'location=yes'); Regards Jonathan
Get customized feature parameter value from config.xml
Hi, In the following sample plugin.xml and config.xml , the parameter enable-redirect can be configured by app developers when they add the plugin to cordova project. However, currently only ios-package and onload parameters are parsed and stored by config.xml's settings parser, other parameters (like enable-redirect) are ignored by the settings parser, so plugin developer has to parse the config.xml again by themselves in order to get the other parameters' value. Just wonder it maybe a good idea to parse all parameters under feature element, and return it as a param dictionary, so as to make it ready to use by developers within plugin's native code. Plugin.xml: platform name=ios config-file target=config.xml parent=/widget feature name=myplugin param name=ios-package value=myPlugin/ param name=onload value=true/ param name=enable-redirect value=$REDIRECT/ /feature /config-file source-file src=ios/libs/myPlugin.a framework=true/ /platform Config.xml feature name=myplugin param name=ios-package value=myplugin / param name=onload value=true / param name=enable-redirect value=true / /feature Thanks Jonathan
Re: Get customized feature parameter value from config.xml
Does preference can be set on per platform and plugin level? On 4/14/14 2:27 PM, Shazron shaz...@gmail.com wrote: Will a preference / tag not suffice? On Mon, Apr 14, 2014 at 11:23 AM, Li, Jonathan jonathan...@sap.com wrote: Hi, In the following sample plugin.xml and config.xml , the parameter enable-redirect can be configured by app developers when they add the plugin to cordova project. However, currently only ios-package and onload parameters are parsed and stored by config.xml's settings parser, other parameters (like enable-redirect) are ignored by the settings parser, so plugin developer has to parse the config.xml again by themselves in order to get the other parameters' value. Just wonder it maybe a good idea to parse all parameters under feature element, and return it as a param dictionary, so as to make it ready to use by developers within plugin's native code. Plugin.xml: platform name=ios config-file target=config.xml parent=/widget feature name=myplugin param name=ios-package value=myPlugin/ param name=onload value=true/ param name=enable-redirect value=$REDIRECT/ /feature /config-file source-file src=ios/libs/myPlugin.a framework=true/ /platform Config.xml feature name=myplugin param name=ios-package value=myplugin / param name=onload value=true / param name=enable-redirect value=true / /feature Thanks Jonathan
Re: Get customized feature parameter value from config.xml
Although the preference can be defined in plugin.xml on per platform and plugin level, but when the information is used to generate config.xml, the related preference element will be generated under the root widget element, and so shared by all plugins. This may cause conflict if the same preference name is used by multiple plugins. On 4/14/14 3:48 PM, Shazron shaz...@gmail.com wrote: per platform in the platform tag - yes. plugin level - yes. On Mon, Apr 14, 2014 at 11:34 AM, Li, Jonathan jonathan...@sap.com wrote: Does preference can be set on per platform and plugin level? On 4/14/14 2:27 PM, Shazron shaz...@gmail.com wrote: Will a preference / tag not suffice? On Mon, Apr 14, 2014 at 11:23 AM, Li, Jonathan jonathan...@sap.com wrote: Hi, In the following sample plugin.xml and config.xml , the parameter enable-redirect can be configured by app developers when they add the plugin to cordova project. However, currently only ios-package and onload parameters are parsed and stored by config.xml's settings parser, other parameters (like enable-redirect) are ignored by the settings parser, so plugin developer has to parse the config.xml again by themselves in order to get the other parameters' value. Just wonder it maybe a good idea to parse all parameters under feature element, and return it as a param dictionary, so as to make it ready to use by developers within plugin's native code. Plugin.xml: platform name=ios config-file target=config.xml parent=/widget feature name=myplugin param name=ios-package value=myPlugin/ param name=onload value=true/ param name=enable-redirect value=$REDIRECT/ /feature /config-file source-file src=ios/libs/myPlugin.a framework=true/ /platform Config.xml feature name=myplugin param name=ios-package value=myplugin / param name=onload value=true / param name=enable-redirect value=true / /feature Thanks Jonathan
Re: Get customized feature parameter value from config.xml
That works. Thanks. On 4/14/14 4:26 PM, Shazron shaz...@gmail.com wrote: Yes, that is the known limitation. My suggestion is to prefix the preference name with your plugin name, or whatever you prefer. On Mon, Apr 14, 2014 at 1:12 PM, Li, Jonathan jonathan...@sap.com wrote: Although the preference can be defined in plugin.xml on per platform and plugin level, but when the information is used to generate config.xml, the related preference element will be generated under the root widget element, and so shared by all plugins. This may cause conflict if the same preference name is used by multiple plugins. On 4/14/14 3:48 PM, Shazron shaz...@gmail.com wrote: per platform in the platform tag - yes. plugin level - yes. On Mon, Apr 14, 2014 at 11:34 AM, Li, Jonathan jonathan...@sap.com wrote: Does preference can be set on per platform and plugin level? On 4/14/14 2:27 PM, Shazron shaz...@gmail.com wrote: Will a preference / tag not suffice? On Mon, Apr 14, 2014 at 11:23 AM, Li, Jonathan jonathan...@sap.com wrote: Hi, In the following sample plugin.xml and config.xml , the parameter enable-redirect can be configured by app developers when they add the plugin to cordova project. However, currently only ios-package and onload parameters are parsed and stored by config.xml's settings parser, other parameters (like enable-redirect) are ignored by the settings parser, so plugin developer has to parse the config.xml again by themselves in order to get the other parameters' value. Just wonder it maybe a good idea to parse all parameters under feature element, and return it as a param dictionary, so as to make it ready to use by developers within plugin's native code. Plugin.xml: platform name=ios config-file target=config.xml parent=/widget feature name=myplugin param name=ios-package value=myPlugin/ param name=onload value=true/ param name=enable-redirect value=$REDIRECT/ /feature /config-file source-file src=ios/libs/myPlugin.a framework=true/ /platform Config.xml feature name=myplugin param name=ios-package value=myplugin / param name=onload value=true / param name=enable-redirect value=true / /feature Thanks Jonathan
Explicitly added plugin gets deleted as dependent of other plugin
When testing with cordova 3.4.0-0.1.3, if a plugin A is a dependent of plugin B, then running the following command will automatically delete plugin B from the project cordova plugin add PluginB cordova plugin add pluginA cordova plugin rm pluginB As pluginA is explicitly added into the project, unless it is explicated removed from project by using cordova plugin rm pluginA command, then it should not be deleted from the project when deleting pluginB. The test is done on iOS platform. Please let me know if this is a known issue, or whether I need to submit a bug for it Thanks Jonathan
Re: Explicitly added plugin gets deleted as dependent of other plugin
Created. https://issues.apache.org/jira/browse/CB-6237 On 3/12/14 12:58 PM, Shazron shaz...@gmail.com wrote: Just tested it with File and File-Transfer - looks like a bug. Please file it, thanks! On Wed, Mar 12, 2014 at 7:46 AM, Li, Jonathan jonathan...@sap.com wrote: When testing with cordova 3.4.0-0.1.3, if a plugin A is a dependent of plugin B, then running the following command will automatically delete plugin B from the project cordova plugin add PluginB cordova plugin add pluginA cordova plugin rm pluginB As pluginA is explicitly added into the project, unless it is explicated removed from project by using cordova plugin rm pluginA command, then it should not be deleted from the project when deleting pluginB. The test is done on iOS platform. Please let me know if this is a known issue, or whether I need to submit a bug for it Thanks Jonathan
Re: Explicitly added plugin gets deleted as dependent of other plugin
Only the parent pluginB (not the dependent pluginA) is removed. However, the dependent plugin (PluginA) also gets removed along with pluginB, even if pluginA has been explicitly added into the project. Jonathan On 3/12/14 1:41 PM, Michal Mocny mmo...@chromium.org wrote: If its dependant is removed, it will stop working anyway -- so why is it a bug to remove it? I think we should warn when this happens (if it happens silently, thats bad experience), or better yet prompt for input to confirm removal, but I'm not sure what it would mean to just leave pluginA installed when its dependant is removed, regardless of if each plugin was explicitly installed. -Michal On Wed, Mar 12, 2014 at 12:58 PM, Shazron shaz...@gmail.com wrote: Just tested it with File and File-Transfer - looks like a bug. Please file it, thanks! On Wed, Mar 12, 2014 at 7:46 AM, Li, Jonathan jonathan...@sap.com wrote: When testing with cordova 3.4.0-0.1.3, if a plugin A is a dependent of plugin B, then running the following command will automatically delete plugin B from the project cordova plugin add PluginB cordova plugin add pluginA cordova plugin rm pluginB As pluginA is explicitly added into the project, unless it is explicated removed from project by using cordova plugin rm pluginA command, then it should not be deleted from the project when deleting pluginB. The test is done on iOS platform. Please let me know if this is a known issue, or whether I need to submit a bug for it Thanks Jonathan
RE: Opinions Needed: Platform specific features and mobilespec tests
Probably call the test failure for the unimplemented feature as Unimplemented Failure, and show in jasmine using a different color. Those failure are like a warning, and means the feature is expected to be supported by the platform, but is just not yet implemented. Expected failure is little confusing, as if when expected failure happens, it means a success test case. Jonathan -Original Message- From: Ian Clelland [mailto:iclell...@google.com] Sent: Friday, June 21, 2013 8:35 AM To: dev@cordova.apache.org Subject: Re: Opinions Needed: Platform specific features and mobilespec tests For tests like this, I'd like to see something in Jasmine that is akin to the Expected Failure result in JUinit / python unittest. It means that we still run all of the tests, but a failure on a device that doesn't support the feature doesn't cause the whole test suite to turn red. On the other hand, if a test which is expected to fail actually succeeds, that is reported as unexpected success in the test output. We can then go and look at what has changed -- either the test is broken, or the issue was actually resolved. I don't think it's available as an idiom in Jasmine, but it's just JavaScript; it shouldn't be too hard to implement. Ian On 13-06-20 9:06 AM, Andrew Grieve agri...@chromium.org wrote: Definitely torn on this one. On one hand, if there are features implemented on some platforms that should be implemented on others than having them fail is a constant reminder that your platform needs to implement the missing functionality. OTOH, things like camera clean-up are meant to be platform specific, so it's nothing but an annoyance if that fails on other platforms. So, I think my take on it is: 1. Have them shared and failing if the API should eventually be implemented on all platforms 2. Wrap tests in if (platform.name == 'ios') {} if they are meant to only work on one platform. On Thu, Jun 20, 2013 at 8:44 AM, Lisa Seacat DeLuca ldel...@us.ibm.comwrote: One issue I ran with respects to the mobile spec is some tests are only applicable to certain device types. We have a couple options when it comes to those types of tests: 1. Not include them in the automated tests 2. Include them knowing that they *might* cause failures with certain device types (see example) 3. Add javascript logic to check for device type before performing the tests 4. OR we could create platform specific automated tests that should be ran in addition to the base automated test per device. ex. automatedAndroid, automatedIOS, etc. An example is: https://issues.apache.org/jira/browse/CB-3484 camera.cleanup is only supported on iOS. I added a test case to verify that the function existed. But it doesn't actually run camera.cleanup so there are no failure on other platforms. So really there shouldn't be any harm in keeping the test. What are everyone's opinions on a good approach to handle this type of situation? Lisa Seacat DeLuca - This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful.
inAppBrowser API issue
Not sure whether this is a right place for this issue, but the javascript interface for InAppBrowser does not make much sense. The below code is from cordova document: var ref = window.open('http://apache.org', '_blank', 'location=yes'); ref.addEventListener('loadstart', function() { alert(event.url); }); The event handler is added after the open method is returned, so it is possible the event gets fired before developer has a chance to add the event handler for the open operation. Although it is async operation, it is still a good design, and may cause timing or other issues depending on native side implementation. Just wonder whether this is a known issue, or could it be changed to a better interface design? Thanks Jonathan
RE: inAppBrowser API issue
It is a little bit different from window.open defined by w3c. As window.open, the onload, onerror events can be embedded in the html page, they will be automatically attached to DOM when parsing the page, there is no need to add the event handler by separate calls, so no event will be missed. In fact, if calling the similar code shown below on a regular page, the onload method will not be called. var ref = window.open('http://apache.org'); ref.addEventListener('loadstart', function() { alert(event.url); }); The design should not heavily depend on the current browser's javascript thread implementation. Besides it is not safe to always assume the event will only be fired asynchronously from native code. For example, if invalid parameters are passed to open method, the validator may need to call onError to report the error, it will not work if onError event handler cannot be added before the operation. Jonathan -Original Message- From: bra...@google.com [mailto:bra...@google.com] On Behalf Of Braden Shepherdson Sent: Tuesday, May 28, 2013 11:10 AM To: dev@cordova.apache.org Subject: Re: inAppBrowser API issue If the event really did fire before the event listener was added, the Javascript engine is broken. When the event is triggered (which may happen in another browser thread or something) it will be added to the event queue in the Javascript engine. That event will not be processed until the currently executing Javascript chunk is done - the next time the Javascript cedes control (setTimeout, returning from all functions, etc.). That won't happen until after the event handler is attached in the second line. We didn't design this API, it's the same window.open API is is used elsewhere. Cordova tends to use existing W3C specs where appropriate. Braden On Tue, May 28, 2013 at 10:47 AM, Li, Jonathan jonathan...@sap.com wrote: Not sure whether this is a right place for this issue, but the javascript interface for InAppBrowser does not make much sense. The below code is from cordova document: var ref = window.open('http://apache.org', '_blank', 'location=yes'); ref.addEventListener('loadstart', function() { alert(event.url); }); The event handler is added after the open method is returned, so it is possible the event gets fired before developer has a chance to add the event handler for the open operation. Although it is async operation, it is still a good design, and may cause timing or other issues depending on native side implementation. Just wonder whether this is a known issue, or could it be changed to a better interface design? Thanks Jonathan