Commit 58f57589 by Sebastián Katzer

wip

parent 0b4653dc

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

...@@ -10,4 +10,8 @@ ...@@ -10,4 +10,8 @@
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<preference name="windows-target-version" value="10.0" /> <preference name="windows-target-version" value="10.0" />
<plugin name="cordova-plugin-device" spec="~1.1.6" />
<plugin name="cordova-plugin-x-toast" spec="~2.6.0" />
<engine name="ios" spec="latest" />
<plugin name="cordova-plugin-local-notifications" spec="~0.0.0" />
</widget> </widget>
* text eol=lf
# source code
*.php text
*.css text
*.sass text
*.scss text
*.less text
*.styl text
*.js text
*.coffee text
*.json text
*.htm text
*.html text
*.xml text
*.svg text
*.txt text
*.ini text
*.inc text
*.pl text
*.rb text
*.py text
*.scm text
*.sql text
*.sh text
*.bat text
# templates
*.ejs text
*.hbt text
*.jade text
*.haml text
*.hbs text
*.dot text
*.tmpl text
*.phtml text
# server config
.htaccess text
# git config
.gitattributes text
.gitignore text
.gitconfig text
# code analysis config
.jshintrc text
.jscsrc text
.jshintignore text
.csslintrc text
# misc config
*.yaml text
*.yml text
.editorconfig text
# build config
*.npmignore text
*.bowerrc text
# Heroku
Procfile text
.slugignore text
# Documentation
*.md text
LICENSE text
AUTHORS text
#
## These files are binary and should be left untouched
#
# (binary is a macro for -text -diff)
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.mov binary
*.mp4 binary
*.mp3 binary
*.flv binary
*.fla binary
*.swf binary
*.gz binary
*.zip binary
*.7z binary
*.ttf binary
*.eot binary
*.woff binary
*.pyc binary
*.pdf binary
<!--
Please make sure the checklist boxes are all checked before submitting the PR. The checklist
is intended as a quick reference, for complete details please see our Contributor Guidelines:
http://cordova.apache.org/contribute/contribute_guidelines.html
Thanks!
-->
### Platforms affected
### What does this PR do?
### What testing has been done on this change?
### Checklist
- [ ] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
- [ ] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
- [ ] Added automated test coverage as appropriate for this change.
instrumentation:
root: "bin/templates/scripts"
include-all-sources: true
reporting:
print: "detail"
bin/node_modules/*
bin/templates/project/*
tests/spec/unit/fixtures/*
...@@ -7,4 +7,5 @@ ...@@ -7,4 +7,5 @@
, "indent": 4 , "indent": 4
, "unused": "vars" , "unused": "vars"
, "latedef": "nofunc" , "latedef": "nofunc"
, "esversion": "6"
} }
.DS_Store
.*.sw?
.vscode
*.cso
tmp
*.mode1v3
*.pbxuser
xcuserdata
console.log
node_modules/jshint
node_modules/jasmine-node
node_modules/rewire
node_modules/istanbul
node_modules/.bin/cake
node_modules/.bin/codecov
node_modules/.bin/coffee
node_modules/.bin/color-support
node_modules/.bin/coveralls
node_modules/.bin/escodegen
node_modules/.bin/esgenerate
node_modules/.bin/esparse
node_modules/.bin/esvalidate
node_modules/.bin/handlebars
node_modules/.bin/har-validator
node_modules/.bin/istanbul
node_modules/.bin/jasmine-node
node_modules/.bin/js-yaml
node_modules/.bin/jshint
node_modules/.bin/mkdirp
node_modules/.bin/nodeunit
node_modules/.bin/nyc
node_modules/.bin/opener
node_modules/.bin/r.js
node_modules/.bin/r_js
node_modules/.bin/sshpk-conv
node_modules/.bin/sshpk-sign
node_modules/.bin/sshpk-verify
node_modules/.bin/strip-json-comments
node_modules/.bin/tap
node_modules/.bin/tap-mocha-reporter
node_modules/.bin/tap-parser
node_modules/.bin/tape
node_modules/.bin/uglifyjs
node_modules/.bin/uncrustify
node_modules/.bin/which
node_modules/align-text/
node_modules/amdefine/
node_modules/ansi-regex/
node_modules/ansi-styles/
node_modules/argparse/
node_modules/asn1/
node_modules/assert-plus/
node_modules/async/
node_modules/asynckit/
node_modules/aws-sign2/
node_modules/aws4/
node_modules/bcrypt-pbkdf/
node_modules/bl/
node_modules/bluebird/
node_modules/boom/
node_modules/buffer-shims/
node_modules/camelcase/
node_modules/caseless/
node_modules/center-align/
node_modules/chalk/
node_modules/clean-yaml-object/
node_modules/cli/
node_modules/cliui/
node_modules/codecov.io/
node_modules/coffee-script/
node_modules/color-support/
node_modules/combined-stream/
node_modules/commander/
node_modules/console-browserify/
node_modules/core-util-is/
node_modules/coveralls/
node_modules/cross-spawn/
node_modules/cryptiles/
node_modules/ctype/
node_modules/dashdash/
node_modules/date-now/
node_modules/debug/
node_modules/decamelize/
node_modules/deep-equal/
node_modules/deep-is/
node_modules/deeper/
node_modules/defined/
node_modules/delayed-stream/
node_modules/diff/
node_modules/dom-serializer/
node_modules/domelementtype/
node_modules/domhandler/
node_modules/domutils/
node_modules/duplexer/
node_modules/ecc-jsbn/
node_modules/entities/
node_modules/escape-string-regexp/
node_modules/escodegen/
node_modules/esprima/
node_modules/estraverse/
node_modules/esutils/
node_modules/events-to-array/
node_modules/exit/
node_modules/extend/
node_modules/extsprintf/
node_modules/fast-levenshtein/
node_modules/fileset/
node_modules/foreground-child/
node_modules/forever-agent/
node_modules/form-data/
node_modules/fs.realpath/
node_modules/gaze/
node_modules/generate-function/
node_modules/generate-object-property/
node_modules/getpass/
node_modules/graceful-readlink/
node_modules/growl/
node_modules/handlebars/
node_modules/har-validator/
node_modules/has-ansi/
node_modules/has-flag/
node_modules/hawk/
node_modules/hoek/
node_modules/htmlparser2/
node_modules/http-signature/
node_modules/is-buffer/
node_modules/is-my-json-valid/
node_modules/is-property/
node_modules/is-typedarray/
node_modules/isarray/
node_modules/isexe/
node_modules/isstream/
node_modules/jasmine-growl-reporter/
node_modules/jasmine-reporters/
node_modules/jodid25519/
node_modules/js-yaml/
node_modules/jsbn/
node_modules/json-schema/
node_modules/json-stringify-safe/
node_modules/jsonify/
node_modules/jsonpointer/
node_modules/jsprim/
node_modules/kind-of/
node_modules/lazy-cache/
node_modules/lcov-parse/
node_modules/levn/
node_modules/log-driver/
node_modules/longest/
node_modules/lru-cache/
node_modules/mime-db/
node_modules/mime-types/
node_modules/mime/
node_modules/minimist/
node_modules/mkdirp/
node_modules/ms/
node_modules/nodeunit/
node_modules/nyc/
node_modules/oauth-sign/
node_modules/only-shallow/
node_modules/opener/
node_modules/optimist/
node_modules/optional/
node_modules/optionator/
node_modules/pinkie-promise/
node_modules/pinkie/
node_modules/prelude-ls/
node_modules/process-nextick-args/
node_modules/pseudomap/
node_modules/punycode/
node_modules/qs/
node_modules/readable-stream/
node_modules/repeat-string/
node_modules/request/
node_modules/requirejs/
node_modules/resolve/
node_modules/resumer/
node_modules/right-align/
node_modules/sigmund/
node_modules/signal-exit/
node_modules/sntp/
node_modules/source-map/
node_modules/split/
node_modules/sprintf-js/
node_modules/sshpk/
node_modules/stack-utils/
node_modules/stream-combiner/
node_modules/string_decoder/
node_modules/stringstream/
node_modules/strip-ansi/
node_modules/strip-json-comments/
node_modules/supports-color/
node_modules/tap-mocha-reporter/
node_modules/tap-parser/
node_modules/tap/
node_modules/tape/
node_modules/through/
node_modules/tmatch/
node_modules/tough-cookie/
node_modules/tunnel-agent/
node_modules/tweetnacl/
node_modules/type-check/
node_modules/uglify-js/
node_modules/uglify-to-browserify/
node_modules/uncrustify/
node_modules/underscore.string/
node_modules/unicode-length/
node_modules/urlgrey/
node_modules/verror/
node_modules/walkdir/
node_modules/which/
node_modules/window-size/
node_modules/wordwrap/
node_modules/xtend/
node_modules/yallist/
node_modules/yargs/
coverage/
npm-debug.log
node_modules/.bin/color-support
node_modules/.bin/jasmine
node_modules/asynckit/
node_modules/aws4/
node_modules/bcrypt-pbkdf/
node_modules/color-support/
node_modules/fs.realpath/
node_modules/jasmine-core/
node_modules/jasmine/
# yes, not .gitignore
gitignore
# licenses for both below are in the cordova-ios LICENSE file
NSData+Base64.h
NSData+Base64.m
Contents.json
jasmine.json
fixtures
appveyor.yml
i386
language: objective-c
osx_image: xcode7.3
sudo: false
before_install:
- npm cache clean -f
- npm install -g n
- node --version
install:
- npm install
- npm install ios-deploy
- npm install -g codecov
script:
- npm run jshint
- npm run unit-tests
- npm run e2e-tests
- open -b com.apple.iphonesimulator
- npm run objc-tests
- npm run cover
after_script: codecov
<!--
#
# 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.
#
-->
# Contributing to Apache Cordova
Anyone can contribute to Cordova. And we need your contributions.
There are multiple ways to contribute: report bugs, improve the docs, and
contribute code.
For instructions on this, start with the
[contribution overview](http://cordova.apache.org/contribute/).
The details are explained there, but the important items are:
- Sign and submit an Apache ICLA (Contributor License Agreement).
- Have a Jira issue open that corresponds to your contribution.
- Run the tests so your patch doesn't break existing functionality.
We look forward to your contributions!
build/*
*.pbxuser
*.perspectivev3
*.mode1v3
javascripts/cordova-*.js
/*
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.
*/
#ifdef DEBUG
#define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define DLog(...)
#endif
#define ALog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
/*
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.
*/
@interface NSArray (CDVJSONSerializingPrivate)
- (NSString*)cdv_JSONString;
@end
@interface NSDictionary (CDVJSONSerializingPrivate)
- (NSString*)cdv_JSONString;
@end
@interface NSString (CDVJSONSerializingPrivate)
- (id)cdv_JSONObject;
- (id)cdv_JSONFragment;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVJSON_private.h"
#import <Foundation/NSJSONSerialization.h>
@implementation NSArray (CDVJSONSerializingPrivate)
- (NSString*)cdv_JSONString
{
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:self
options:0
error:&error];
if (error != nil) {
NSLog(@"NSArray JSONString error: %@", [error localizedDescription]);
return nil;
} else {
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
@end
@implementation NSDictionary (CDVJSONSerializingPrivate)
- (NSString*)cdv_JSONString
{
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:self
options:NSJSONWritingPrettyPrinted
error:&error];
if (error != nil) {
NSLog(@"NSDictionary JSONString error: %@", [error localizedDescription]);
return nil;
} else {
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
@end
@implementation NSString (CDVJSONSerializingPrivate)
- (id)cdv_JSONObject
{
NSError* error = nil;
id object = [NSJSONSerialization JSONObjectWithData:[self dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:&error];
if (error != nil) {
NSLog(@"NSString JSONObject error: %@", [error localizedDescription]);
}
return object;
}
- (id)cdv_JSONFragment
{
NSError* error = nil;
id object = [NSJSONSerialization JSONObjectWithData:[self dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingAllowFragments
error:&error];
if (error != nil) {
NSLog(@"NSString JSONObject error: %@", [error localizedDescription]);
}
return object;
}
@end
#!/usr/bin/env node
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at 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, http://www.apache.org/licenses/LICENSE-2.0
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.
*/
var emulator = require('./emulator'), Unless required by applicable law or agreed to in writing,
args = process.argv; 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.
*/
var install_target; @interface CDVPlugin (Private)
if(args.length > 2) {
if (args[2].substring(0, 9) == '--target=') {
install_target = args[2].substring(9, args[2].length);
} else {
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
process.exit(2);
}
}
emulator.start(install_target).done(null, function(err) { - (instancetype)initWithWebViewEngine:(id <CDVWebViewEngineProtocol>)theWebViewEngine;
console.error('ERROR: ' + err);
process.exit(2);
});
@end
#!/usr/bin/env node
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at 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.
*/
http://www.apache.org/licenses/LICENSE-2.0 #import "CDVPlugin.h"
Unless required by applicable law or agreed to in writing, @interface CDVGestureHandler : CDVPlugin
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.
*/
var emulators = require('./emulator'); @property (nonatomic, strong) UILongPressGestureRecognizer* lpgr;
// Usage support for when args are given @end
emulators.list_started().done(function(emulator_list) {
emulator_list && emulator_list.forEach(function(emu) {
console.log(emu);
});
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVGestureHandler.h"
@implementation CDVGestureHandler
- (void)pluginInitialize
{
[self applyLongPressFix];
}
- (void)applyLongPressFix
{
// You can't suppress 3D Touch and still have regular longpress,
// so if this is false, let's not consider the 3D Touch setting at all.
if (![self.commandDelegate.settings objectForKey:@"suppresseslongpressgesture"] ||
![[self.commandDelegate.settings objectForKey:@"suppresseslongpressgesture"] boolValue]) {
return;
}
self.lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGestures:)];
self.lpgr.minimumPressDuration = 0.45f;
self.lpgr.allowableMovement = 100.0f;
// 0.45 is ok for 'regular longpress', 0.05-0.08 is required for '3D Touch longpress',
// but since this will also kill onclick handlers (not ontouchend) it's optional.
if ([self.commandDelegate.settings objectForKey:@"suppresses3dtouchgesture"] &&
[[self.commandDelegate.settings objectForKey:@"suppresses3dtouchgesture"] boolValue]) {
self.lpgr.minimumPressDuration = 0.05f;
}
NSArray *views = self.webView.subviews;
if (views.count == 0) {
NSLog(@"No webview subviews found, not applying the longpress fix.");
return;
}
for (int i=0; i<views.count; i++) {
UIView *webViewScrollView = views[i];
if ([webViewScrollView isKindOfClass:[UIScrollView class]]) {
NSArray *webViewScrollViewSubViews = webViewScrollView.subviews;
UIView *browser = webViewScrollViewSubViews[0];
[browser addGestureRecognizer:self.lpgr];
break;
}
}
}
- (void)handleLongPressGestures:(UILongPressGestureRecognizer*)sender
{
if ([sender isEqual:self.lpgr]) {
if (sender.state == UIGestureRecognizerStateBegan) {
NSLog(@"Ignoring a longpress in order to suppress the magnifying glass.");
}
}
}
@end
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the KIND, either express or implied. See the License for the
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
*/
package org.apache.cordova;
/**
* Specifies interface for HTTP auth handler object which is used to handle auth requests and
* specifying user credentials.
*/ */
public interface ICordovaHttpAuthHandler {
/** #import "CDVPlugin.h"
* Instructs the WebView to cancel the authentication request.
*/ @interface CDVHandleOpenURL : CDVPlugin
public void cancel ();
@property (nonatomic, strong) NSURL* url;
/** @property (nonatomic, assign) BOOL pageLoaded;
* Instructs the WebView to proceed with the authentication with the given credentials.
* @end
* @param username The user name
* @param password The password
*/
public void proceed (String username, String password);
}
\ No newline at end of file
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVHandleOpenURL.h"
#import "CDV.h"
@implementation CDVHandleOpenURL
- (void)pluginInitialize
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationLaunchedWithUrl:) name:CDVPluginHandleOpenURLNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationPageDidLoad:) name:CDVPageDidLoadNotification object:nil];
}
- (void)applicationLaunchedWithUrl:(NSNotification*)notification
{
NSURL* url = [notification object];
self.url = url;
// warm-start handler
if (self.pageLoaded) {
[self processOpenUrl:self.url pageLoaded:YES];
self.url = nil;
}
}
- (void)applicationPageDidLoad:(NSNotification*)notification
{
// cold-start handler
self.pageLoaded = YES;
if (self.url) {
[self processOpenUrl:self.url pageLoaded:YES];
self.url = nil;
}
}
- (void)processOpenUrl:(NSURL*)url pageLoaded:(BOOL)pageLoaded
{
__weak __typeof(self) weakSelf = self;
dispatch_block_t handleOpenUrl = ^(void) {
// calls into javascript global function 'handleOpenURL'
NSString* jsString = [NSString stringWithFormat:@"document.addEventListener('deviceready',function(){if (typeof handleOpenURL === 'function') { handleOpenURL(\"%@\");}});", url.absoluteString];
[weakSelf.webViewEngine evaluateJavaScript:jsString completionHandler:nil];
};
if (!pageLoaded) {
NSString* jsString = @"document.readystate";
[self.webViewEngine evaluateJavaScript:jsString
completionHandler:^(id object, NSError* error) {
if ((error == nil) && [object isKindOfClass:[NSString class]]) {
NSString* readyState = (NSString*)object;
BOOL ready = [readyState isEqualToString:@"loaded"] || [readyState isEqualToString:@"complete"];
if (ready) {
handleOpenUrl();
} else {
self.url = url;
}
}
}];
} else {
handleOpenUrl();
}
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVPlugin.h"
#import "CDVWhitelist.h"
typedef NS_ENUM(NSInteger, CDVIntentAndNavigationFilterValue) {
CDVIntentAndNavigationFilterValueIntentAllowed,
CDVIntentAndNavigationFilterValueNavigationAllowed,
CDVIntentAndNavigationFilterValueNoneAllowed
};
@interface CDVIntentAndNavigationFilter : CDVPlugin <NSXMLParserDelegate>
+ (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url intentsWhitelist:(CDVWhitelist*)intentsWhitelist navigationsWhitelist:(CDVWhitelist*)navigationsWhitelist;
+ (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType filterValue:(CDVIntentAndNavigationFilterValue)filterValue;
+ (BOOL)shouldOpenURLRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVIntentAndNavigationFilter.h"
#import <Cordova/CDV.h>
@interface CDVIntentAndNavigationFilter ()
@property (nonatomic, readwrite) NSMutableArray* allowIntents;
@property (nonatomic, readwrite) NSMutableArray* allowNavigations;
@property (nonatomic, readwrite) CDVWhitelist* allowIntentsWhitelist;
@property (nonatomic, readwrite) CDVWhitelist* allowNavigationsWhitelist;
@end
@implementation CDVIntentAndNavigationFilter
#pragma mark NSXMLParserDelegate
- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName attributes:(NSDictionary*)attributeDict
{
if ([elementName isEqualToString:@"allow-navigation"]) {
[self.allowNavigations addObject:attributeDict[@"href"]];
}
if ([elementName isEqualToString:@"allow-intent"]) {
[self.allowIntents addObject:attributeDict[@"href"]];
}
}
- (void)parserDidStartDocument:(NSXMLParser*)parser
{
// file: url <allow-navigations> are added by default
self.allowNavigations = [[NSMutableArray alloc] initWithArray:@[ @"file://" ]];
// no intents are added by default
self.allowIntents = [[NSMutableArray alloc] init];
}
- (void)parserDidEndDocument:(NSXMLParser*)parser
{
self.allowIntentsWhitelist = [[CDVWhitelist alloc] initWithArray:self.allowIntents];
self.allowNavigationsWhitelist = [[CDVWhitelist alloc] initWithArray:self.allowNavigations];
}
- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError
{
NSAssert(NO, @"config.xml parse error line %ld col %ld", (long)[parser lineNumber], (long)[parser columnNumber]);
}
#pragma mark CDVPlugin
- (void)pluginInitialize
{
if ([self.viewController isKindOfClass:[CDVViewController class]]) {
[(CDVViewController*)self.viewController parseSettingsWithParser:self];
}
}
+ (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url intentsWhitelist:(CDVWhitelist*)intentsWhitelist navigationsWhitelist:(CDVWhitelist*)navigationsWhitelist
{
// a URL can only allow-intent OR allow-navigation, if both are specified,
// only allow-navigation is allowed
BOOL allowNavigationsPass = [navigationsWhitelist URLIsAllowed:url logFailure:NO];
BOOL allowIntentPass = [intentsWhitelist URLIsAllowed:url logFailure:NO];
if (allowNavigationsPass && allowIntentPass) {
return CDVIntentAndNavigationFilterValueNavigationAllowed;
} else if (allowNavigationsPass) {
return CDVIntentAndNavigationFilterValueNavigationAllowed;
} else if (allowIntentPass) {
return CDVIntentAndNavigationFilterValueIntentAllowed;
}
return CDVIntentAndNavigationFilterValueNoneAllowed;
}
- (CDVIntentAndNavigationFilterValue) filterUrl:(NSURL*)url
{
return [[self class] filterUrl:url intentsWhitelist:self.allowIntentsWhitelist navigationsWhitelist:self.allowNavigationsWhitelist];
}
+ (BOOL)shouldOpenURLRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
return (UIWebViewNavigationTypeLinkClicked == navigationType ||
(UIWebViewNavigationTypeOther == navigationType &&
[[request.mainDocumentURL absoluteString] isEqualToString:[request.URL absoluteString]]
)
);
}
+ (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType filterValue:(CDVIntentAndNavigationFilterValue)filterValue
{
NSString* allowIntents_whitelistRejectionFormatString = @"ERROR External navigation rejected - <allow-intent> not set for url='%@'";
NSString* allowNavigations_whitelistRejectionFormatString = @"ERROR Internal navigation rejected - <allow-navigation> not set for url='%@'";
NSURL* url = [request URL];
switch (filterValue) {
case CDVIntentAndNavigationFilterValueNavigationAllowed:
return YES;
case CDVIntentAndNavigationFilterValueIntentAllowed:
// only allow-intent if it's a UIWebViewNavigationTypeLinkClicked (anchor tag) OR
// it's a UIWebViewNavigationTypeOther, and it's an internal link
if ([[self class] shouldOpenURLRequest:request navigationType:navigationType]){
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
// CB-11895; openURL with a single parameter is deprecated in iOS 10
// see https://useyourloaf.com/blog/openurl-deprecated-in-ios10
if ([[UIApplication sharedApplication] respondsToSelector:@selector(openURL:options:completionHandler:)]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url];
}
#else
// fall back if on older SDK
[[UIApplication sharedApplication] openURL:url];
#endif
}
// consume the request (i.e. no error) if it wasn't handled above
return NO;
case CDVIntentAndNavigationFilterValueNoneAllowed:
// allow-navigation attempt failed for sure
NSLog(@"%@", [NSString stringWithFormat:allowNavigations_whitelistRejectionFormatString, [url absoluteString]]);
// anchor tag link means it was an allow-intent attempt that failed as well
if (UIWebViewNavigationTypeLinkClicked == navigationType) {
NSLog(@"%@", [NSString stringWithFormat:allowIntents_whitelistRejectionFormatString, [url absoluteString]]);
}
return NO;
}
}
- (BOOL)shouldOverrideLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
return [[self class] shouldOverrideLoadWithRequest:request navigationType:navigationType filterValue:[self filterUrl:request.URL]];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVPlugin.h"
#define kCDVLocalStorageErrorDomain @"kCDVLocalStorageErrorDomain"
#define kCDVLocalStorageFileOperationError 1
@interface CDVLocalStorage : CDVPlugin
@property (nonatomic, readonly, strong) NSMutableArray* backupInfo;
- (BOOL)shouldBackup;
- (BOOL)shouldRestore;
- (void)backup:(CDVInvokedUrlCommand*)command;
- (void)restore:(CDVInvokedUrlCommand*)command;
+ (void)__fixupDatabaseLocationsWithBackupType:(NSString*)backupType;
// Visible for testing.
+ (BOOL)__verifyAndFixDatabaseLocationsWithAppPlistDict:(NSMutableDictionary*)appPlistDict
bundlePath:(NSString*)bundlePath
fileManager:(NSFileManager*)fileManager;
@end
@interface CDVBackupInfo : NSObject
@property (nonatomic, copy) NSString* original;
@property (nonatomic, copy) NSString* backup;
@property (nonatomic, copy) NSString* label;
- (BOOL)shouldBackup;
- (BOOL)shouldRestore;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#import "CDVAvailability.h"
/**
* Distinguishes top-level navigations from sub-frame navigations.
* shouldStartLoadWithRequest is called for every request, but didStartLoad
* and didFinishLoad is called only for top-level navigations.
* Relevant bug: CB-2389
*/
@interface CDVUIWebViewDelegate : NSObject <UIWebViewDelegate>{
__weak NSObject <UIWebViewDelegate>* _delegate;
NSInteger _loadCount;
NSInteger _state;
NSInteger _curLoadToken;
NSInteger _loadStartPollCount;
}
- (id)initWithDelegate:(NSObject <UIWebViewDelegate>*)delegate;
- (BOOL)request:(NSURLRequest*)newRequest isEqualToRequestAfterStrippingFragments:(NSURLRequest*)originalRequest;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVPlugin.h"
#import "CDVWebViewEngineProtocol.h"
@interface CDVUIWebViewEngine : CDVPlugin <CDVWebViewEngineProtocol>
@property (nonatomic, strong, readonly) id <UIWebViewDelegate> uiWebViewDelegate;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVUIWebViewEngine.h"
#import "CDVUIWebViewDelegate.h"
#import "CDVUIWebViewNavigationDelegate.h"
#import "NSDictionary+CordovaPreferences.h"
#import <objc/message.h>
@interface CDVUIWebViewEngine ()
@property (nonatomic, strong, readwrite) UIView* engineWebView;
@property (nonatomic, strong, readwrite) id <UIWebViewDelegate> uiWebViewDelegate;
@property (nonatomic, strong, readwrite) CDVUIWebViewNavigationDelegate* navWebViewDelegate;
@end
@implementation CDVUIWebViewEngine
@synthesize engineWebView = _engineWebView;
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super init];
if (self) {
self.engineWebView = [[UIWebView alloc] initWithFrame:frame];
NSLog(@"Using UIWebView");
}
return self;
}
- (void)pluginInitialize
{
// viewController would be available now. we attempt to set all possible delegates to it, by default
UIWebView* uiWebView = (UIWebView*)_engineWebView;
if ([self.viewController conformsToProtocol:@protocol(UIWebViewDelegate)]) {
self.uiWebViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:(id <UIWebViewDelegate>)self.viewController];
uiWebView.delegate = self.uiWebViewDelegate;
} else {
self.navWebViewDelegate = [[CDVUIWebViewNavigationDelegate alloc] initWithEnginePlugin:self];
self.uiWebViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:self.navWebViewDelegate];
uiWebView.delegate = self.uiWebViewDelegate;
}
[self updateSettings:self.commandDelegate.settings];
}
- (void)evaluateJavaScript:(NSString*)javaScriptString completionHandler:(void (^)(id, NSError*))completionHandler
{
NSString* ret = [(UIWebView*)_engineWebView stringByEvaluatingJavaScriptFromString:javaScriptString];
if (completionHandler) {
completionHandler(ret, nil);
}
}
- (id)loadRequest:(NSURLRequest*)request
{
[(UIWebView*)_engineWebView loadRequest:request];
return nil;
}
- (id)loadHTMLString:(NSString*)string baseURL:(NSURL*)baseURL
{
[(UIWebView*)_engineWebView loadHTMLString:string baseURL:baseURL];
return nil;
}
- (NSURL*)URL
{
return [[(UIWebView*)_engineWebView request] URL];
}
- (BOOL) canLoadRequest:(NSURLRequest*)request
{
return (request != nil);
}
- (void)updateSettings:(NSDictionary*)settings
{
UIWebView* uiWebView = (UIWebView*)_engineWebView;
uiWebView.scalesPageToFit = [settings cordovaBoolSettingForKey:@"EnableViewportScale" defaultValue:NO];
uiWebView.allowsInlineMediaPlayback = [settings cordovaBoolSettingForKey:@"AllowInlineMediaPlayback" defaultValue:NO];
uiWebView.mediaPlaybackRequiresUserAction = [settings cordovaBoolSettingForKey:@"MediaPlaybackRequiresUserAction" defaultValue:YES];
uiWebView.mediaPlaybackAllowsAirPlay = [settings cordovaBoolSettingForKey:@"MediaPlaybackAllowsAirPlay" defaultValue:YES];
uiWebView.keyboardDisplayRequiresUserAction = [settings cordovaBoolSettingForKey:@"KeyboardDisplayRequiresUserAction" defaultValue:YES];
uiWebView.suppressesIncrementalRendering = [settings cordovaBoolSettingForKey:@"SuppressesIncrementalRendering" defaultValue:NO];
uiWebView.gapBetweenPages = [settings cordovaFloatSettingForKey:@"GapBetweenPages" defaultValue:0.0];
uiWebView.pageLength = [settings cordovaFloatSettingForKey:@"PageLength" defaultValue:0.0];
id prefObj = nil;
// By default, DisallowOverscroll is false (thus bounce is allowed)
BOOL bounceAllowed = !([settings cordovaBoolSettingForKey:@"DisallowOverscroll" defaultValue:NO]);
// prevent webView from bouncing
if (!bounceAllowed) {
if ([uiWebView respondsToSelector:@selector(scrollView)]) {
((UIScrollView*)[uiWebView scrollView]).bounces = NO;
} else {
for (id subview in self.webView.subviews) {
if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {
((UIScrollView*)subview).bounces = NO;
}
}
}
}
NSString* decelerationSetting = [settings cordovaSettingForKey:@"UIWebViewDecelerationSpeed"];
if (![@"fast" isEqualToString:decelerationSetting]) {
[uiWebView.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal];
}
NSInteger paginationBreakingMode = 0; // default - UIWebPaginationBreakingModePage
prefObj = [settings cordovaSettingForKey:@"PaginationBreakingMode"];
if (prefObj != nil) {
NSArray* validValues = @[@"page", @"column"];
NSString* prefValue = [validValues objectAtIndex:0];
if ([prefObj isKindOfClass:[NSString class]]) {
prefValue = prefObj;
}
paginationBreakingMode = [validValues indexOfObject:[prefValue lowercaseString]];
if (paginationBreakingMode == NSNotFound) {
paginationBreakingMode = 0;
}
}
uiWebView.paginationBreakingMode = paginationBreakingMode;
NSInteger paginationMode = 0; // default - UIWebPaginationModeUnpaginated
prefObj = [settings cordovaSettingForKey:@"PaginationMode"];
if (prefObj != nil) {
NSArray* validValues = @[@"unpaginated", @"lefttoright", @"toptobottom", @"bottomtotop", @"righttoleft"];
NSString* prefValue = [validValues objectAtIndex:0];
if ([prefObj isKindOfClass:[NSString class]]) {
prefValue = prefObj;
}
paginationMode = [validValues indexOfObject:[prefValue lowercaseString]];
if (paginationMode == NSNotFound) {
paginationMode = 0;
}
}
uiWebView.paginationMode = paginationMode;
}
- (void)updateWithInfo:(NSDictionary*)info
{
UIWebView* uiWebView = (UIWebView*)_engineWebView;
id <UIWebViewDelegate> uiWebViewDelegate = [info objectForKey:kCDVWebViewEngineUIWebViewDelegate];
NSDictionary* settings = [info objectForKey:kCDVWebViewEngineWebViewPreferences];
if (uiWebViewDelegate &&
[uiWebViewDelegate conformsToProtocol:@protocol(UIWebViewDelegate)]) {
self.uiWebViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:(id <UIWebViewDelegate>)self.viewController];
uiWebView.delegate = self.uiWebViewDelegate;
}
if (settings && [settings isKindOfClass:[NSDictionary class]]) {
[self updateSettings:settings];
}
}
// This forwards the methods that are in the header that are not implemented here.
// Both WKWebView and UIWebView implement the below:
// loadHTMLString:baseURL:
// loadRequest:
- (id)forwardingTargetForSelector:(SEL)aSelector
{
return _engineWebView;
}
- (UIView*)webView
{
return self.engineWebView;
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#import "CDVUIWebViewEngine.h"
@interface CDVUIWebViewNavigationDelegate : NSObject <UIWebViewDelegate>
@property (nonatomic, weak) CDVPlugin* enginePlugin;
- (instancetype)initWithEnginePlugin:(CDVPlugin*)enginePlugin;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVUIWebViewNavigationDelegate.h"
#import <Cordova/CDVViewController.h>
#import <Cordova/CDVCommandDelegateImpl.h>
#import <Cordova/CDVUserAgentUtil.h>
#import <objc/message.h>
@implementation CDVUIWebViewNavigationDelegate
- (instancetype)initWithEnginePlugin:(CDVPlugin*)theEnginePlugin
{
self = [super init];
if (self) {
self.enginePlugin = theEnginePlugin;
}
return self;
}
/**
When web application loads Add stuff to the DOM, mainly the user-defined settings from the Settings.plist file, and
the device's data such as device ID, platform version, etc.
*/
- (void)webViewDidStartLoad:(UIWebView*)theWebView
{
NSLog(@"Resetting plugins due to page load.");
CDVViewController* vc = (CDVViewController*)self.enginePlugin.viewController;
[vc.commandQueue resetRequestId];
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginResetNotification object:self.enginePlugin.webView]];
}
/**
Called when the webview finishes loading. This stops the activity view.
*/
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
NSLog(@"Finished load of: %@", theWebView.request.URL);
CDVViewController* vc = (CDVViewController*)self.enginePlugin.viewController;
// It's safe to release the lock even if this is just a sub-frame that's finished loading.
[CDVUserAgentUtil releaseLock:vc.userAgentLockToken];
/*
* Hide the Top Activity THROBBER in the Battery Bar
*/
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:self.enginePlugin.webView]];
}
- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
{
CDVViewController* vc = (CDVViewController*)self.enginePlugin.viewController;
[CDVUserAgentUtil releaseLock:vc.userAgentLockToken];
NSString* message = [NSString stringWithFormat:@"Failed to load webpage with error: %@", [error localizedDescription]];
NSLog(@"%@", message);
NSURL* errorUrl = vc.errorURL;
if (errorUrl) {
errorUrl = [NSURL URLWithString:[NSString stringWithFormat:@"?error=%@", [message stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLPathAllowedCharacterSet]] relativeToURL:errorUrl];
NSLog(@"%@", [errorUrl absoluteString]);
[theWebView loadRequest:[NSURLRequest requestWithURL:errorUrl]];
}
}
- (BOOL)defaultResourcePolicyForURL:(NSURL*)url
{
/*
* If a URL is being loaded that's a file url, just load it internally
*/
if ([url isFileURL]) {
return YES;
}
return NO;
}
- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL* url = [request URL];
CDVViewController* vc = (CDVViewController*)self.enginePlugin.viewController;
/*
* Execute any commands queued with cordova.exec() on the JS side.
* The part of the URL after gap:// is irrelevant.
*/
if ([[url scheme] isEqualToString:@"gap"]) {
[vc.commandQueue fetchCommandsFromJs];
// The delegate is called asynchronously in this case, so we don't have to use
// flushCommandQueueWithDelayedJs (setTimeout(0)) as we do with hash changes.
[vc.commandQueue executePending];
return NO;
}
/*
* Give plugins the chance to handle the url
*/
BOOL anyPluginsResponded = NO;
BOOL shouldAllowRequest = NO;
for (NSString* pluginName in vc.pluginObjects) {
CDVPlugin* plugin = [vc.pluginObjects objectForKey:pluginName];
SEL selector = NSSelectorFromString(@"shouldOverrideLoadWithRequest:navigationType:");
if ([plugin respondsToSelector:selector]) {
anyPluginsResponded = YES;
shouldAllowRequest = (((BOOL (*)(id, SEL, id, int))objc_msgSend)(plugin, selector, request, navigationType));
if (!shouldAllowRequest) {
break;
}
}
}
if (anyPluginsResponded) {
return shouldAllowRequest;
}
/*
* Handle all other types of urls (tel:, sms:), and requests to load a url in the main webview.
*/
BOOL shouldAllowNavigation = [self defaultResourcePolicyForURL:url];
if (shouldAllowNavigation) {
return YES;
} else {
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
}
return NO;
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVAvailability.h"
#import "CDVAvailabilityDeprecated.h"
#import "CDVAppDelegate.h"
#import "CDVPlugin.h"
#import "CDVPluginResult.h"
#import "CDVViewController.h"
#import "CDVCommandDelegate.h"
#import "CDVURLProtocol.h"
#import "CDVInvokedUrlCommand.h"
#import "CDVWhitelist.h"
#import "CDVScreenOrientationDelegate.h"
#import "CDVTimer.h"
#import "CDVUserAgentUtil.h"
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
#import "CDVViewController.h"
@interface CDVAppDelegate : NSObject <UIApplicationDelegate>{}
@property (nonatomic, strong) IBOutlet UIWindow* window;
@property (nonatomic, strong) IBOutlet CDVViewController* viewController;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVAppDelegate.h"
@implementation CDVAppDelegate
@synthesize window, viewController;
- (id)init
{
/** If you need to do any extra app-specific initialization, you can do it here
* -jm
**/
NSHTTPCookieStorage* cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
[cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
int cacheSizeMemory = 8 * 1024 * 1024; // 8MB
int cacheSizeDisk = 32 * 1024 * 1024; // 32MB
NSURLCache* sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
[NSURLCache setSharedURLCache:sharedCache];
self = [super init];
return self;
}
#pragma mark UIApplicationDelegate implementation
/**
* This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up)
*/
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
self.window = [[UIWindow alloc] initWithFrame:screenBounds];
self.window.autoresizesSubviews = YES;
// only set if not already set in subclass
if (self.viewController == nil) {
self.viewController = [[CDVViewController alloc] init];
}
// Set your app's start page by setting the <content src='foo.html' /> tag in config.xml.
// If necessary, uncomment the line below to override it.
// self.viewController.startPage = @"index.html";
// NOTE: To customize the view's frame size (which defaults to full screen), override
// [self.viewController viewWillAppear:] in your view controller.
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
// this happens while we are running ( in the background, or from within our own app )
// only valid if 40x-Info.plist specifies a protocol to handle
- (BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
{
if (!url) {
return NO;
}
// all plugins will get the notification, and their handlers will be called
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
return YES;
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
#else //CB-12098. Defaults to UIInterfaceOrientationMask for iOS 9+
- (UIInterfaceOrientationMask)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
#endif
{
// iPhone doesn't support upside down by default, while the iPad does. Override to allow all orientations always, and let the root view controller decide what's allowed (the supported orientations mask gets intersected).
NSUInteger supportedInterfaceOrientations = (1 << UIInterfaceOrientationPortrait) | (1 << UIInterfaceOrientationLandscapeLeft) | (1 << UIInterfaceOrientationLandscapeRight) | (1 << UIInterfaceOrientationPortraitUpsideDown);
return supportedInterfaceOrientations;
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication*)application
{
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVAvailabilityDeprecated.h"
#define __CORDOVA_IOS__
#define __CORDOVA_0_9_6 906
#define __CORDOVA_1_0_0 10000
#define __CORDOVA_1_1_0 10100
#define __CORDOVA_1_2_0 10200
#define __CORDOVA_1_3_0 10300
#define __CORDOVA_1_4_0 10400
#define __CORDOVA_1_4_1 10401
#define __CORDOVA_1_5_0 10500
#define __CORDOVA_1_6_0 10600
#define __CORDOVA_1_6_1 10601
#define __CORDOVA_1_7_0 10700
#define __CORDOVA_1_8_0 10800
#define __CORDOVA_1_8_1 10801
#define __CORDOVA_1_9_0 10900
#define __CORDOVA_2_0_0 20000
#define __CORDOVA_2_1_0 20100
#define __CORDOVA_2_2_0 20200
#define __CORDOVA_2_3_0 20300
#define __CORDOVA_2_4_0 20400
#define __CORDOVA_2_5_0 20500
#define __CORDOVA_2_6_0 20600
#define __CORDOVA_2_7_0 20700
#define __CORDOVA_2_8_0 20800
#define __CORDOVA_2_9_0 20900
#define __CORDOVA_3_0_0 30000
#define __CORDOVA_3_1_0 30100
#define __CORDOVA_3_2_0 30200
#define __CORDOVA_3_3_0 30300
#define __CORDOVA_3_4_0 30400
#define __CORDOVA_3_4_1 30401
#define __CORDOVA_3_5_0 30500
#define __CORDOVA_3_6_0 30600
#define __CORDOVA_3_7_0 30700
#define __CORDOVA_3_8_0 30800
#define __CORDOVA_3_9_0 30900
#define __CORDOVA_3_9_1 30901
#define __CORDOVA_3_9_2 30902
#define __CORDOVA_4_0_0 40000
#define __CORDOVA_4_0_1 40001
#define __CORDOVA_4_1_0 40100
#define __CORDOVA_4_1_1 40101
#define __CORDOVA_4_2_0 40200
#define __CORDOVA_4_2_1 40201
#define __CORDOVA_4_3_0 40300
#define __CORDOVA_4_3_1 40301
#define __CORDOVA_4_4_0 40400
/* coho:next-version,insert-before */
#define __CORDOVA_NA 99999 /* not available */
/*
#if CORDOVA_VERSION_MIN_REQUIRED >= __CORDOVA_4_0_0
// do something when its at least 4.0.0
#else
// do something else (non 4.0.0)
#endif
*/
#ifndef CORDOVA_VERSION_MIN_REQUIRED
/* coho:next-version-min-required,replace-after */
#define CORDOVA_VERSION_MIN_REQUIRED __CORDOVA_4_4_0
#endif
/*
Returns YES if it is at least version specified as NSString(X)
Usage:
if (IsAtLeastiOSVersion(@"5.1")) {
// do something for iOS 5.1 or greater
}
*/
#define IsAtLeastiOSVersion(X) ([[[UIDevice currentDevice] systemVersion] compare:X options:NSNumericSearch] != NSOrderedAscending)
/* Return the string version of the decimal version */
#define CDV_VERSION [NSString stringWithFormat:@"%d.%d.%d", \
(CORDOVA_VERSION_MIN_REQUIRED / 10000), \
(CORDOVA_VERSION_MIN_REQUIRED % 10000) / 100, \
(CORDOVA_VERSION_MIN_REQUIRED % 10000) % 100]
// Enable this to log all exec() calls.
#define CDV_ENABLE_EXEC_LOGGING 0
#if CDV_ENABLE_EXEC_LOGGING
#define CDV_EXEC_LOG NSLog
#else
#define CDV_EXEC_LOG(...) do { \
} while (NO)
#endif
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#ifdef __clang__
#define CDV_DEPRECATED(version, msg) __attribute__((deprecated("Deprecated in Cordova " #version ". " msg)))
#else
#define CDV_DEPRECATED(version, msg) __attribute__((deprecated()))
#endif
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVAvailability.h"
#import "CDVInvokedUrlCommand.h"
@class CDVPlugin;
@class CDVPluginResult;
@class CDVWhitelist;
typedef NSURL* (^ UrlTransformerBlock)(NSURL*);
@protocol CDVCommandDelegate <NSObject>
@property (nonatomic, readonly) NSDictionary* settings;
@property (nonatomic, copy) UrlTransformerBlock urlTransformer;
- (NSString*)pathForResource:(NSString*)resourcepath;
- (id)getCommandInstance:(NSString*)pluginName;
// Sends a plugin result to the JS. This is thread-safe.
- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId;
// Evaluates the given JS. This is thread-safe.
- (void)evalJs:(NSString*)js;
// Can be used to evaluate JS right away instead of scheduling it on the run-loop.
// This is required for dispatch resign and pause events, but should not be used
// without reason. Without the run-loop delay, alerts used in JS callbacks may result
// in dead-lock. This method must be called from the UI thread.
- (void)evalJs:(NSString*)js scheduledOnRunLoop:(BOOL)scheduledOnRunLoop;
// Runs the given block on a background thread using a shared thread-pool.
- (void)runInBackground:(void (^)())block;
// Returns the User-Agent of the associated UIWebView.
- (NSString*)userAgent;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#import "CDVCommandDelegate.h"
@class CDVViewController;
@class CDVCommandQueue;
@interface CDVCommandDelegateImpl : NSObject <CDVCommandDelegate>{
@private
__weak CDVViewController* _viewController;
NSRegularExpression* _callbackIdPattern;
@protected
__weak CDVCommandQueue* _commandQueue;
BOOL _delayResponses;
}
- (id)initWithViewController:(CDVViewController*)viewController;
- (void)flushCommandQueueWithDelayedJs;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVCommandDelegateImpl.h"
#import "CDVJSON_private.h"
#import "CDVCommandQueue.h"
#import "CDVPluginResult.h"
#import "CDVViewController.h"
@implementation CDVCommandDelegateImpl
@synthesize urlTransformer;
- (id)initWithViewController:(CDVViewController*)viewController
{
self = [super init];
if (self != nil) {
_viewController = viewController;
_commandQueue = _viewController.commandQueue;
NSError* err = nil;
_callbackIdPattern = [NSRegularExpression regularExpressionWithPattern:@"[^A-Za-z0-9._-]" options:0 error:&err];
if (err != nil) {
// Couldn't initialize Regex
NSLog(@"Error: Couldn't initialize regex");
_callbackIdPattern = nil;
}
}
return self;
}
- (NSString*)pathForResource:(NSString*)resourcepath
{
NSBundle* mainBundle = [NSBundle mainBundle];
NSMutableArray* directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]];
NSString* filename = [directoryParts lastObject];
[directoryParts removeLastObject];
NSString* directoryPartsJoined = [directoryParts componentsJoinedByString:@"/"];
NSString* directoryStr = _viewController.wwwFolderName;
if ([directoryPartsJoined length] > 0) {
directoryStr = [NSString stringWithFormat:@"%@/%@", _viewController.wwwFolderName, [directoryParts componentsJoinedByString:@"/"]];
}
return [mainBundle pathForResource:filename ofType:@"" inDirectory:directoryStr];
}
- (void)flushCommandQueueWithDelayedJs
{
_delayResponses = YES;
[_commandQueue executePending];
_delayResponses = NO;
}
- (void)evalJsHelper2:(NSString*)js
{
CDV_EXEC_LOG(@"Exec: evalling: %@", [js substringToIndex:MIN([js length], 160)]);
[_viewController.webViewEngine evaluateJavaScript:js completionHandler:^(id obj, NSError* error) {
// TODO: obj can be something other than string
if ([obj isKindOfClass:[NSString class]]) {
NSString* commandsJSON = (NSString*)obj;
if ([commandsJSON length] > 0) {
CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by chaining.");
}
[_commandQueue enqueueCommandBatch:commandsJSON];
[_commandQueue executePending];
}
}];
}
- (void)evalJsHelper:(NSString*)js
{
// Cycle the run-loop before executing the JS.
// For _delayResponses -
// This ensures that we don't eval JS during the middle of an existing JS
// function (possible since UIWebViewDelegate callbacks can be synchronous).
// For !isMainThread -
// It's a hard error to eval on the non-UI thread.
// For !_commandQueue.currentlyExecuting -
// This works around a bug where sometimes alerts() within callbacks can cause
// dead-lock.
// If the commandQueue is currently executing, then we know that it is safe to
// execute the callback immediately.
// Using (dispatch_get_main_queue()) does *not* fix deadlocks for some reason,
// but performSelectorOnMainThread: does.
if (_delayResponses || ![NSThread isMainThread] || !_commandQueue.currentlyExecuting) {
[self performSelectorOnMainThread:@selector(evalJsHelper2:) withObject:js waitUntilDone:NO];
} else {
[self evalJsHelper2:js];
}
}
- (BOOL)isValidCallbackId:(NSString*)callbackId
{
if ((callbackId == nil) || (_callbackIdPattern == nil)) {
return NO;
}
// Disallow if too long or if any invalid characters were found.
if (([callbackId length] > 100) || [_callbackIdPattern firstMatchInString:callbackId options:0 range:NSMakeRange(0, [callbackId length])]) {
return NO;
}
return YES;
}
- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId
{
CDV_EXEC_LOG(@"Exec(%@): Sending result. Status=%@", callbackId, result.status);
// This occurs when there is are no win/fail callbacks for the call.
if ([@"INVALID" isEqualToString:callbackId]) {
return;
}
// This occurs when the callback id is malformed.
if (![self isValidCallbackId:callbackId]) {
NSLog(@"Invalid callback id received by sendPluginResult");
return;
}
int status = [result.status intValue];
BOOL keepCallback = [result.keepCallback boolValue];
NSString* argumentsAsJSON = [result argumentsAsJSON];
BOOL debug = NO;
#ifdef DEBUG
debug = YES;
#endif
NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d, %d)", callbackId, status, argumentsAsJSON, keepCallback, debug];
[self evalJsHelper:js];
}
- (void)evalJs:(NSString*)js
{
[self evalJs:js scheduledOnRunLoop:YES];
}
- (void)evalJs:(NSString*)js scheduledOnRunLoop:(BOOL)scheduledOnRunLoop
{
js = [NSString stringWithFormat:@"try{cordova.require('cordova/exec').nativeEvalAndFetch(function(){%@})}catch(e){console.log('exception nativeEvalAndFetch : '+e);};", js];
if (scheduledOnRunLoop) {
[self evalJsHelper:js];
} else {
[self evalJsHelper2:js];
}
}
- (id)getCommandInstance:(NSString*)pluginName
{
return [_viewController getCommandInstance:pluginName];
}
- (void)runInBackground:(void (^)())block
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block);
}
- (NSString*)userAgent
{
return [_viewController userAgent];
}
- (NSDictionary*)settings
{
return _viewController.settings;
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
@class CDVInvokedUrlCommand;
@class CDVViewController;
@interface CDVCommandQueue : NSObject
@property (nonatomic, readonly) BOOL currentlyExecuting;
- (id)initWithViewController:(CDVViewController*)viewController;
- (void)dispose;
- (void)resetRequestId;
- (void)enqueueCommandBatch:(NSString*)batchJSON;
- (void)fetchCommandsFromJs;
- (void)executePending;
- (BOOL)execute:(CDVInvokedUrlCommand*)command;
@end
/*
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.
*/
#include <objc/message.h>
#import "CDVCommandQueue.h"
#import "CDVViewController.h"
#import "CDVCommandDelegateImpl.h"
#import "CDVJSON_private.h"
#import "CDVDebug.h"
// Parse JS on the main thread if it's shorter than this.
static const NSInteger JSON_SIZE_FOR_MAIN_THREAD = 4 * 1024; // Chosen arbitrarily.
// Execute multiple commands in one go until this many seconds have passed.
static const double MAX_EXECUTION_TIME = .008; // Half of a 60fps frame.
@interface CDVCommandQueue () {
NSInteger _lastCommandQueueFlushRequestId;
__weak CDVViewController* _viewController;
NSMutableArray* _queue;
NSTimeInterval _startExecutionTime;
}
@end
@implementation CDVCommandQueue
- (BOOL)currentlyExecuting
{
return _startExecutionTime > 0;
}
- (id)initWithViewController:(CDVViewController*)viewController
{
self = [super init];
if (self != nil) {
_viewController = viewController;
_queue = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dispose
{
// TODO(agrieve): Make this a zeroing weak ref once we drop support for 4.3.
_viewController = nil;
}
- (void)resetRequestId
{
_lastCommandQueueFlushRequestId = 0;
}
- (void)enqueueCommandBatch:(NSString*)batchJSON
{
if ([batchJSON length] > 0) {
NSMutableArray* commandBatchHolder = [[NSMutableArray alloc] init];
[_queue addObject:commandBatchHolder];
if ([batchJSON length] < JSON_SIZE_FOR_MAIN_THREAD) {
[commandBatchHolder addObject:[batchJSON cdv_JSONObject]];
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^() {
NSMutableArray* result = [batchJSON cdv_JSONObject];
@synchronized(commandBatchHolder) {
[commandBatchHolder addObject:result];
}
[self performSelectorOnMainThread:@selector(executePending) withObject:nil waitUntilDone:NO];
});
}
}
}
- (void)fetchCommandsFromJs
{
__weak CDVCommandQueue* weakSelf = self;
NSString* js = @"cordova.require('cordova/exec').nativeFetchMessages()";
[_viewController.webViewEngine evaluateJavaScript:js
completionHandler:^(id obj, NSError* error) {
if ((error == nil) && [obj isKindOfClass:[NSString class]]) {
NSString* queuedCommandsJSON = (NSString*)obj;
CDV_EXEC_LOG(@"Exec: Flushed JS->native queue (hadCommands=%d).", [queuedCommandsJSON length] > 0);
[weakSelf enqueueCommandBatch:queuedCommandsJSON];
// this has to be called here now, because fetchCommandsFromJs is now async (previously: synchronous)
[self executePending];
}
}];
}
- (void)executePending
{
// Make us re-entrant-safe.
if (_startExecutionTime > 0) {
return;
}
@try {
_startExecutionTime = [NSDate timeIntervalSinceReferenceDate];
while ([_queue count] > 0) {
NSMutableArray* commandBatchHolder = _queue[0];
NSMutableArray* commandBatch = nil;
@synchronized(commandBatchHolder) {
// If the next-up command is still being decoded, wait for it.
if ([commandBatchHolder count] == 0) {
break;
}
commandBatch = commandBatchHolder[0];
}
while ([commandBatch count] > 0) {
@autoreleasepool {
// Execute the commands one-at-a-time.
NSArray* jsonEntry = [commandBatch cdv_dequeue];
if ([commandBatch count] == 0) {
[_queue removeObjectAtIndex:0];
}
CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry];
CDV_EXEC_LOG(@"Exec(%@): Calling %@.%@", command.callbackId, command.className, command.methodName);
if (![self execute:command]) {
#ifdef DEBUG
NSString* commandJson = [jsonEntry cdv_JSONString];
static NSUInteger maxLogLength = 1024;
NSString* commandString = ([commandJson length] > maxLogLength) ?
[NSString stringWithFormat : @"%@[...]", [commandJson substringToIndex:maxLogLength]] :
commandJson;
DLog(@"FAILED pluginJSON = %@", commandString);
#endif
}
}
// Yield if we're taking too long.
if (([_queue count] > 0) && ([NSDate timeIntervalSinceReferenceDate] - _startExecutionTime > MAX_EXECUTION_TIME)) {
[self performSelector:@selector(executePending) withObject:nil afterDelay:0];
return;
}
}
}
} @finally
{
_startExecutionTime = 0;
}
}
- (BOOL)execute:(CDVInvokedUrlCommand*)command
{
if ((command.className == nil) || (command.methodName == nil)) {
NSLog(@"ERROR: Classname and/or methodName not found for command.");
return NO;
}
// Fetch an instance of this class
CDVPlugin* obj = [_viewController.commandDelegate getCommandInstance:command.className];
if (!([obj isKindOfClass:[CDVPlugin class]])) {
NSLog(@"ERROR: Plugin '%@' not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.", command.className);
return NO;
}
BOOL retVal = YES;
double started = [[NSDate date] timeIntervalSince1970] * 1000.0;
// Find the proper selector to call.
NSString* methodName = [NSString stringWithFormat:@"%@:", command.methodName];
SEL normalSelector = NSSelectorFromString(methodName);
if ([obj respondsToSelector:normalSelector]) {
// [obj performSelector:normalSelector withObject:command];
((void (*)(id, SEL, id))objc_msgSend)(obj, normalSelector, command);
} else {
// There's no method to call, so throw an error.
NSLog(@"ERROR: Method '%@' not defined in Plugin '%@'", methodName, command.className);
retVal = NO;
}
double elapsed = [[NSDate date] timeIntervalSince1970] * 1000.0 - started;
if (elapsed > 10) {
NSLog(@"THREAD WARNING: ['%@'] took '%f' ms. Plugin should use a background thread.", command.className, elapsed);
}
return retVal;
}
@end
/*
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.
*/
@interface CDVConfigParser : NSObject <NSXMLParserDelegate>
{
NSString* featureName;
}
@property (nonatomic, readonly, strong) NSMutableDictionary* pluginsDict;
@property (nonatomic, readonly, strong) NSMutableDictionary* settings;
@property (nonatomic, readonly, strong) NSMutableArray* startupPluginNames;
@property (nonatomic, readonly, strong) NSString* startPage;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVConfigParser.h"
@interface CDVConfigParser ()
@property (nonatomic, readwrite, strong) NSMutableDictionary* pluginsDict;
@property (nonatomic, readwrite, strong) NSMutableDictionary* settings;
@property (nonatomic, readwrite, strong) NSMutableArray* startupPluginNames;
@property (nonatomic, readwrite, strong) NSString* startPage;
@end
@implementation CDVConfigParser
@synthesize pluginsDict, settings, startPage, startupPluginNames;
- (id)init
{
self = [super init];
if (self != nil) {
self.pluginsDict = [[NSMutableDictionary alloc] initWithCapacity:30];
self.settings = [[NSMutableDictionary alloc] initWithCapacity:30];
self.startupPluginNames = [[NSMutableArray alloc] initWithCapacity:8];
featureName = nil;
}
return self;
}
- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName attributes:(NSDictionary*)attributeDict
{
if ([elementName isEqualToString:@"preference"]) {
settings[[attributeDict[@"name"] lowercaseString]] = attributeDict[@"value"];
} else if ([elementName isEqualToString:@"feature"]) { // store feature name to use with correct parameter set
featureName = [attributeDict[@"name"] lowercaseString];
} else if ((featureName != nil) && [elementName isEqualToString:@"param"]) {
NSString* paramName = [attributeDict[@"name"] lowercaseString];
id value = attributeDict[@"value"];
if ([paramName isEqualToString:@"ios-package"]) {
pluginsDict[featureName] = value;
}
BOOL paramIsOnload = ([paramName isEqualToString:@"onload"] && [@"true" isEqualToString : value]);
BOOL attribIsOnload = [@"true" isEqualToString :[attributeDict[@"onload"] lowercaseString]];
if (paramIsOnload || attribIsOnload) {
[self.startupPluginNames addObject:featureName];
}
} else if ([elementName isEqualToString:@"content"]) {
self.startPage = attributeDict[@"src"];
}
}
- (void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName
{
if ([elementName isEqualToString:@"feature"]) { // no longer handling a feature so release
featureName = nil;
}
}
- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError
{
NSAssert(NO, @"config.xml parse error line %ld col %ld", (long)[parser lineNumber], (long)[parser columnNumber]);
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
@interface CDVInvokedUrlCommand : NSObject {
NSString* _callbackId;
NSString* _className;
NSString* _methodName;
NSArray* _arguments;
}
@property (nonatomic, readonly) NSArray* arguments;
@property (nonatomic, readonly) NSString* callbackId;
@property (nonatomic, readonly) NSString* className;
@property (nonatomic, readonly) NSString* methodName;
+ (CDVInvokedUrlCommand*)commandFromJson:(NSArray*)jsonEntry;
- (id)initWithArguments:(NSArray*)arguments
callbackId:(NSString*)callbackId
className:(NSString*)className
methodName:(NSString*)methodName;
- (id)initFromJson:(NSArray*)jsonEntry;
// Returns the argument at the given index.
// If index >= the number of arguments, returns nil.
// If the argument at the given index is NSNull, returns nil.
- (id)argumentAtIndex:(NSUInteger)index;
// Same as above, but returns defaultValue instead of nil.
- (id)argumentAtIndex:(NSUInteger)index withDefault:(id)defaultValue;
// Same as above, but returns defaultValue instead of nil, and if the argument is not of the expected class, returns defaultValue
- (id)argumentAtIndex:(NSUInteger)index withDefault:(id)defaultValue andClass:(Class)aClass;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVInvokedUrlCommand.h"
#import "CDVJSON_private.h"
@implementation CDVInvokedUrlCommand
@synthesize arguments = _arguments;
@synthesize callbackId = _callbackId;
@synthesize className = _className;
@synthesize methodName = _methodName;
+ (CDVInvokedUrlCommand*)commandFromJson:(NSArray*)jsonEntry
{
return [[CDVInvokedUrlCommand alloc] initFromJson:jsonEntry];
}
- (id)initFromJson:(NSArray*)jsonEntry
{
id tmp = [jsonEntry objectAtIndex:0];
NSString* callbackId = tmp == [NSNull null] ? nil : tmp;
NSString* className = [jsonEntry objectAtIndex:1];
NSString* methodName = [jsonEntry objectAtIndex:2];
NSMutableArray* arguments = [jsonEntry objectAtIndex:3];
return [self initWithArguments:arguments
callbackId:callbackId
className:className
methodName:methodName];
}
- (id)initWithArguments:(NSArray*)arguments
callbackId:(NSString*)callbackId
className:(NSString*)className
methodName:(NSString*)methodName
{
self = [super init];
if (self != nil) {
_arguments = arguments;
_callbackId = callbackId;
_className = className;
_methodName = methodName;
}
[self massageArguments];
return self;
}
- (void)massageArguments
{
NSMutableArray* newArgs = nil;
for (NSUInteger i = 0, count = [_arguments count]; i < count; ++i) {
id arg = [_arguments objectAtIndex:i];
if (![arg isKindOfClass:[NSDictionary class]]) {
continue;
}
NSDictionary* dict = arg;
NSString* type = [dict objectForKey:@"CDVType"];
if (!type || ![type isEqualToString:@"ArrayBuffer"]) {
continue;
}
NSString* data = [dict objectForKey:@"data"];
if (!data) {
continue;
}
if (newArgs == nil) {
newArgs = [NSMutableArray arrayWithArray:_arguments];
_arguments = newArgs;
}
[newArgs replaceObjectAtIndex:i withObject:[[NSData alloc] initWithBase64EncodedString:data options:0]];
}
}
- (id)argumentAtIndex:(NSUInteger)index
{
return [self argumentAtIndex:index withDefault:nil];
}
- (id)argumentAtIndex:(NSUInteger)index withDefault:(id)defaultValue
{
return [self argumentAtIndex:index withDefault:defaultValue andClass:nil];
}
- (id)argumentAtIndex:(NSUInteger)index withDefault:(id)defaultValue andClass:(Class)aClass
{
if (index >= [_arguments count]) {
return defaultValue;
}
id ret = [_arguments objectAtIndex:index];
if (ret == [NSNull null]) {
ret = defaultValue;
}
if ((aClass != nil) && ![ret isKindOfClass:aClass]) {
ret = defaultValue;
}
return ret;
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#import "CDVPlugin.h"
@interface CDVPlugin (CDVPluginResources)
/*
This will return the localized string for a key in a .bundle that is named the same as your class
For example, if your plugin class was called Foo, and you have a Spanish localized strings file, it will
try to load the desired key from Foo.bundle/es.lproj/Localizable.strings
*/
- (NSString*)pluginLocalizedString:(NSString*)key;
/*
This will return the image for a name in a .bundle that is named the same as your class
For example, if your plugin class was called Foo, and you have an image called "bar",
it will try to load the image from Foo.bundle/bar.png (and appropriately named retina versions)
*/
- (UIImage*)pluginImageResource:(NSString*)name;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVPlugin+Resources.h"
@implementation CDVPlugin (CDVPluginResources)
- (NSString*)pluginLocalizedString:(NSString*)key
{
NSBundle* bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:NSStringFromClass([self class]) ofType:@"bundle"]];
return [bundle localizedStringForKey:(key) value:nil table:nil];
}
- (UIImage*)pluginImageResource:(NSString*)name
{
NSString* resourceIdentifier = [NSString stringWithFormat:@"%@.bundle/%@", NSStringFromClass([self class]), name];
return [UIImage imageNamed:resourceIdentifier];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "CDVPluginResult.h"
#import "NSMutableArray+QueueAdditions.h"
#import "CDVCommandDelegate.h"
#import "CDVWebViewEngineProtocol.h"
@interface UIView (org_apache_cordova_UIView_Extension)
@property (nonatomic, weak) UIScrollView* scrollView;
@end
extern NSString* const CDVPageDidLoadNotification;
extern NSString* const CDVPluginHandleOpenURLNotification;
extern NSString* const CDVPluginResetNotification;
extern NSString* const CDVViewWillAppearNotification;
extern NSString* const CDVViewDidAppearNotification;
extern NSString* const CDVViewWillDisappearNotification;
extern NSString* const CDVViewDidDisappearNotification;
extern NSString* const CDVViewWillLayoutSubviewsNotification;
extern NSString* const CDVViewDidLayoutSubviewsNotification;
extern NSString* const CDVViewWillTransitionToSizeNotification;
/*
* The local and remote push notification functionality has been removed from the core in cordova-ios 4.x,
* but these constants have unfortunately have not been removed, but will be removed in 5.x.
*
* To have the same functionality as 3.x, use a third-party plugin or the experimental
* https://github.com/apache/cordova-plugins/tree/master/notification-rebroadcast
*/
extern NSString* const CDVLocalNotification CDV_DEPRECATED(4.0, "Functionality removed in 4.0, constant will be removed in 5.0");
extern NSString* const CDVRemoteNotification CDV_DEPRECATED(4.0, "Functionality removed in 4.0, constant will be removed in 5.0");
extern NSString* const CDVRemoteNotificationError CDV_DEPRECATED(4.0, "Functionality removed in 4.0, constant will be removed in 5.0");
@interface CDVPlugin : NSObject {}
@property (nonatomic, readonly, weak) UIView* webView;
@property (nonatomic, readonly, weak) id <CDVWebViewEngineProtocol> webViewEngine;
@property (nonatomic, weak) UIViewController* viewController;
@property (nonatomic, weak) id <CDVCommandDelegate> commandDelegate;
@property (readonly, assign) BOOL hasPendingOperation;
- (void)pluginInitialize;
- (void)handleOpenURL:(NSNotification*)notification;
- (void)onAppTerminate;
- (void)onMemoryWarning;
- (void)onReset;
- (void)dispose;
/*
// see initWithWebView implementation
- (void) onPause {}
- (void) onResume {}
- (void) onOrientationWillChange {}
- (void) onOrientationDidChange {}
*/
- (id)appDelegate;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVPlugin.h"
#import "CDVPlugin+Private.h"
#import "CDVPlugin+Resources.h"
#import "CDVViewController.h"
#include <objc/message.h>
@implementation UIView (org_apache_cordova_UIView_Extension)
@dynamic scrollView;
- (UIScrollView*)scrollView
{
SEL scrollViewSelector = NSSelectorFromString(@"scrollView");
if ([self respondsToSelector:scrollViewSelector]) {
return ((id (*)(id, SEL))objc_msgSend)(self, scrollViewSelector);
}
return nil;
}
@end
NSString* const CDVPageDidLoadNotification = @"CDVPageDidLoadNotification";
NSString* const CDVPluginHandleOpenURLNotification = @"CDVPluginHandleOpenURLNotification";
NSString* const CDVPluginResetNotification = @"CDVPluginResetNotification";
NSString* const CDVLocalNotification = @"CDVLocalNotification";
NSString* const CDVRemoteNotification = @"CDVRemoteNotification";
NSString* const CDVRemoteNotificationError = @"CDVRemoteNotificationError";
NSString* const CDVViewWillAppearNotification = @"CDVViewWillAppearNotification";
NSString* const CDVViewDidAppearNotification = @"CDVViewDidAppearNotification";
NSString* const CDVViewWillDisappearNotification = @"CDVViewWillDisappearNotification";
NSString* const CDVViewDidDisappearNotification = @"CDVViewDidDisappearNotification";
NSString* const CDVViewWillLayoutSubviewsNotification = @"CDVViewWillLayoutSubviewsNotification";
NSString* const CDVViewDidLayoutSubviewsNotification = @"CDVViewDidLayoutSubviewsNotification";
NSString* const CDVViewWillTransitionToSizeNotification = @"CDVViewWillTransitionToSizeNotification";
@interface CDVPlugin ()
@property (readwrite, assign) BOOL hasPendingOperation;
@property (nonatomic, readwrite, weak) id <CDVWebViewEngineProtocol> webViewEngine;
@end
@implementation CDVPlugin
@synthesize webViewEngine, viewController, commandDelegate, hasPendingOperation;
@dynamic webView;
// Do not override these methods. Use pluginInitialize instead.
- (instancetype)initWithWebViewEngine:(id <CDVWebViewEngineProtocol>)theWebViewEngine
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppTerminate) name:UIApplicationWillTerminateNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOpenURL:) name:CDVPluginHandleOpenURLNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onReset) name:CDVPluginResetNotification object:theWebViewEngine.engineWebView];
self.webViewEngine = theWebViewEngine;
}
return self;
}
- (void)pluginInitialize
{
// You can listen to more app notifications, see:
// http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006728-CH3-DontLinkElementID_4
// NOTE: if you want to use these, make sure you uncomment the corresponding notification handler
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPause) name:UIApplicationDidEnterBackgroundNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:UIApplicationWillEnterForegroundNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOrientationWillChange) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onOrientationDidChange) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
// Added in 2.5.0
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad:) name:CDVPageDidLoadNotification object:self.webView];
//Added in 4.3.0
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewWillAppear:) name:CDVViewWillAppearNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidAppear:) name:CDVViewDidAppearNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewWillDisappear:) name:CDVViewWillDisappearNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidDisappear:) name:CDVViewDidDisappearNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewWillLayoutSubviews:) name:CDVViewWillLayoutSubviewsNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewDidLayoutSubviews:) name:CDVViewDidLayoutSubviewsNotification object:nil];
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewWillTransitionToSize:) name:CDVViewWillTransitionToSizeNotification object:nil];
}
- (void)dispose
{
viewController = nil;
commandDelegate = nil;
}
- (UIView*)webView
{
if (self.webViewEngine != nil) {
return self.webViewEngine.engineWebView;
}
return nil;
}
/*
// NOTE: for onPause and onResume, calls into JavaScript must not call or trigger any blocking UI, like alerts
- (void) onPause {}
- (void) onResume {}
- (void) onOrientationWillChange {}
- (void) onOrientationDidChange {}
*/
/* NOTE: calls into JavaScript must not call or trigger any blocking UI, like alerts */
- (void)handleOpenURL:(NSNotification*)notification
{
// override to handle urls sent to your app
// register your url schemes in your App-Info.plist
NSURL* url = [notification object];
if ([url isKindOfClass:[NSURL class]]) {
/* Do your thing! */
}
}
/* NOTE: calls into JavaScript must not call or trigger any blocking UI, like alerts */
- (void)onAppTerminate
{
// override this if you need to do any cleanup on app exit
}
- (void)onMemoryWarning
{
// override to remove caches, etc
}
- (void)onReset
{
// Override to cancel any long-running requests when the WebView navigates or refreshes.
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self]; // this will remove all notifications unless added using addObserverForName:object:queue:usingBlock:
}
- (id)appDelegate
{
return [[UIApplication sharedApplication] delegate];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
#import "CDVAvailability.h"
typedef enum {
CDVCommandStatus_NO_RESULT = 0,
CDVCommandStatus_OK,
CDVCommandStatus_CLASS_NOT_FOUND_EXCEPTION,
CDVCommandStatus_ILLEGAL_ACCESS_EXCEPTION,
CDVCommandStatus_INSTANTIATION_EXCEPTION,
CDVCommandStatus_MALFORMED_URL_EXCEPTION,
CDVCommandStatus_IO_EXCEPTION,
CDVCommandStatus_INVALID_ACTION,
CDVCommandStatus_JSON_EXCEPTION,
CDVCommandStatus_ERROR
} CDVCommandStatus;
@interface CDVPluginResult : NSObject {}
@property (nonatomic, strong, readonly) NSNumber* status;
@property (nonatomic, strong, readonly) id message;
@property (nonatomic, strong) NSNumber* keepCallback;
// This property can be used to scope the lifetime of another object. For example,
// Use it to store the associated NSData when `message` is created using initWithBytesNoCopy.
@property (nonatomic, strong) id associatedObject;
- (CDVPluginResult*)init;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsString:(NSString*)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsArray:(NSArray*)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsInt:(int)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsNSInteger:(NSInteger)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsNSUInteger:(NSUInteger)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsDouble:(double)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsBool:(BOOL)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsDictionary:(NSDictionary*)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsArrayBuffer:(NSData*)theMessage;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsMultipart:(NSArray*)theMessages;
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageToErrorObject:(int)errorCode;
+ (void)setVerbose:(BOOL)verbose;
+ (BOOL)isVerbose;
- (void)setKeepCallbackAsBool:(BOOL)bKeepCallback;
- (NSString*)argumentsAsJSON;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVPluginResult.h"
#import "CDVJSON_private.h"
#import "CDVDebug.h"
@interface CDVPluginResult ()
- (CDVPluginResult*)initWithStatus:(CDVCommandStatus)statusOrdinal message:(id)theMessage;
@end
@implementation CDVPluginResult
@synthesize status, message, keepCallback, associatedObject;
static NSArray* org_apache_cordova_CommandStatusMsgs;
id messageFromArrayBuffer(NSData* data)
{
return @{
@"CDVType" : @"ArrayBuffer",
@"data" :[data base64EncodedStringWithOptions:0]
};
}
id massageMessage(id message)
{
if ([message isKindOfClass:[NSData class]]) {
return messageFromArrayBuffer(message);
}
return message;
}
id messageFromMultipart(NSArray* theMessages)
{
NSMutableArray* messages = [NSMutableArray arrayWithArray:theMessages];
for (NSUInteger i = 0; i < messages.count; ++i) {
[messages replaceObjectAtIndex:i withObject:massageMessage([messages objectAtIndex:i])];
}
return @{
@"CDVType" : @"MultiPart",
@"messages" : messages
};
}
+ (void)initialize
{
org_apache_cordova_CommandStatusMsgs = [[NSArray alloc] initWithObjects:@"No result",
@"OK",
@"Class not found",
@"Illegal access",
@"Instantiation error",
@"Malformed url",
@"IO error",
@"Invalid action",
@"JSON error",
@"Error",
nil];
}
- (CDVPluginResult*)init
{
return [self initWithStatus:CDVCommandStatus_NO_RESULT message:nil];
}
- (CDVPluginResult*)initWithStatus:(CDVCommandStatus)statusOrdinal message:(id)theMessage
{
self = [super init];
if (self) {
status = [NSNumber numberWithInt:statusOrdinal];
message = theMessage;
keepCallback = [NSNumber numberWithBool:NO];
}
return self;
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal
{
return [[self alloc] initWithStatus:statusOrdinal message:nil];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsString:(NSString*)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:theMessage];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsArray:(NSArray*)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:theMessage];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsInt:(int)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:[NSNumber numberWithInt:theMessage]];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsNSInteger:(NSInteger)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:[NSNumber numberWithInteger:theMessage]];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsNSUInteger:(NSUInteger)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:[NSNumber numberWithUnsignedInteger:theMessage]];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsDouble:(double)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:[NSNumber numberWithDouble:theMessage]];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsBool:(BOOL)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:[NSNumber numberWithBool:theMessage]];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsDictionary:(NSDictionary*)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:theMessage];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsArrayBuffer:(NSData*)theMessage
{
return [[self alloc] initWithStatus:statusOrdinal message:messageFromArrayBuffer(theMessage)];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAsMultipart:(NSArray*)theMessages
{
return [[self alloc] initWithStatus:statusOrdinal message:messageFromMultipart(theMessages)];
}
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageToErrorObject:(int)errorCode
{
NSDictionary* errDict = @{@"code" :[NSNumber numberWithInt:errorCode]};
return [[self alloc] initWithStatus:statusOrdinal message:errDict];
}
- (void)setKeepCallbackAsBool:(BOOL)bKeepCallback
{
[self setKeepCallback:[NSNumber numberWithBool:bKeepCallback]];
}
- (NSString*)argumentsAsJSON
{
id arguments = (self.message == nil ? [NSNull null] : self.message);
NSArray* argumentsWrappedInArray = [NSArray arrayWithObject:arguments];
NSString* argumentsJSON = [argumentsWrappedInArray cdv_JSONString];
argumentsJSON = [argumentsJSON substringWithRange:NSMakeRange(1, [argumentsJSON length] - 2)];
return argumentsJSON;
}
static BOOL gIsVerbose = NO;
+ (void)setVerbose:(BOOL)verbose
{
gIsVerbose = verbose;
}
+ (BOOL)isVerbose
{
return gIsVerbose;
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
@protocol CDVScreenOrientationDelegate <NSObject>
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000
- (NSUInteger)supportedInterfaceOrientations;
#else
- (UIInterfaceOrientationMask)supportedInterfaceOrientations;
#endif
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;
- (BOOL)shouldAutorotate;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
@interface CDVTimer : NSObject
+ (void)start:(NSString*)name;
+ (void)stop:(NSString*)name;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVTimer.h"
#pragma mark CDVTimerItem
@interface CDVTimerItem : NSObject
@property (nonatomic, strong) NSString* name;
@property (nonatomic, strong) NSDate* started;
@property (nonatomic, strong) NSDate* ended;
- (void)log;
@end
@implementation CDVTimerItem
- (void)log
{
NSLog(@"[CDVTimer][%@] %fms", self.name, [self.ended timeIntervalSinceDate:self.started] * 1000.0);
}
@end
#pragma mark CDVTimer
@interface CDVTimer ()
@property (nonatomic, strong) NSMutableDictionary* items;
@end
@implementation CDVTimer
#pragma mark object methods
- (id)init
{
if (self = [super init]) {
self.items = [NSMutableDictionary dictionaryWithCapacity:6];
}
return self;
}
- (void)add:(NSString*)name
{
if ([self.items objectForKey:[name lowercaseString]] == nil) {
CDVTimerItem* item = [CDVTimerItem new];
item.name = name;
item.started = [NSDate new];
[self.items setObject:item forKey:[name lowercaseString]];
} else {
NSLog(@"Timer called '%@' already exists.", name);
}
}
- (void)remove:(NSString*)name
{
CDVTimerItem* item = [self.items objectForKey:[name lowercaseString]];
if (item != nil) {
item.ended = [NSDate new];
[item log];
[self.items removeObjectForKey:[name lowercaseString]];
} else {
NSLog(@"Timer called '%@' does not exist.", name);
}
}
- (void)removeAll
{
[self.items removeAllObjects];
}
#pragma mark class methods
+ (void)start:(NSString*)name
{
[[CDVTimer sharedInstance] add:name];
}
+ (void)stop:(NSString*)name
{
[[CDVTimer sharedInstance] remove:name];
}
+ (void)clearAll
{
[[CDVTimer sharedInstance] removeAll];
}
+ (CDVTimer*)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static CDVTimer* _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
#import "CDVAvailability.h"
@class CDVViewController;
@interface CDVURLProtocol : NSURLProtocol {}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <AssetsLibrary/ALAsset.h>
#import <AssetsLibrary/ALAssetRepresentation.h>
#import <AssetsLibrary/ALAssetsLibrary.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import "CDVURLProtocol.h"
#import "CDVCommandQueue.h"
#import "CDVViewController.h"
// Contains a set of NSNumbers of addresses of controllers. It doesn't store
// the actual pointer to avoid retaining.
static NSMutableSet* gRegisteredControllers = nil;
NSString* const kCDVAssetsLibraryPrefixes = @"assets-library://";
@implementation CDVURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest
{
NSURL* theUrl = [theRequest URL];
if ([[theUrl absoluteString] hasPrefix:kCDVAssetsLibraryPrefixes]) {
return YES;
}
return NO;
}
+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request
{
// NSLog(@"%@ received %@", self, NSStringFromSelector(_cmd));
return request;
}
- (void)startLoading
{
// NSLog(@"%@ received %@ - start", self, NSStringFromSelector(_cmd));
NSURL* url = [[self request] URL];
if ([[url absoluteString] hasPrefix:kCDVAssetsLibraryPrefixes]) {
ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
if (asset) {
// We have the asset! Get the data and send it along.
ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
Byte* buffer = (Byte*)malloc((unsigned long)[assetRepresentation size]);
NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:(NSUInteger)[assetRepresentation size] error:nil];
NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
[self sendResponseWithResponseCode:200 data:data mimeType:MIMEType];
} else {
// Retrieving the asset failed for some reason. Send an error.
[self sendResponseWithResponseCode:404 data:nil mimeType:nil];
}
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
// Retrieving the asset failed for some reason. Send an error.
[self sendResponseWithResponseCode:401 data:nil mimeType:nil];
};
ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary assetForURL:url resultBlock:resultBlock failureBlock:failureBlock];
return;
}
NSString* body = [NSString stringWithFormat:@"Access not allowed to URL: %@", url];
[self sendResponseWithResponseCode:401 data:[body dataUsingEncoding:NSASCIIStringEncoding] mimeType:nil];
}
- (void)stopLoading
{
// do any cleanup here
}
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*)requestA toRequest:(NSURLRequest*)requestB
{
return NO;
}
- (void)sendResponseWithResponseCode:(NSInteger)statusCode data:(NSData*)data mimeType:(NSString*)mimeType
{
if (mimeType == nil) {
mimeType = @"text/plain";
}
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc] initWithURL:[[self request] URL] statusCode:statusCode HTTPVersion:@"HTTP/1.1" headerFields:@{@"Content-Type" : mimeType}];
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
if (data != nil) {
[[self client] URLProtocol:self didLoadData:data];
}
[[self client] URLProtocolDidFinishLoading:self];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
@interface CDVUserAgentUtil : NSObject
+ (NSString*)originalUserAgent;
+ (void)acquireLock:(void (^)(NSInteger lockToken))block;
+ (void)releaseLock:(NSInteger*)lockToken;
+ (void)setUserAgent:(NSString*)value lockToken:(NSInteger)lockToken;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "CDVUserAgentUtil.h"
#import <UIKit/UIKit.h>
// #define VerboseLog NSLog
#define VerboseLog(...) do {} while (0)
static NSString* const kCdvUserAgentKey = @"Cordova-User-Agent";
static NSString* const kCdvUserAgentVersionKey = @"Cordova-User-Agent-Version";
static NSString* gOriginalUserAgent = nil;
static NSInteger gNextLockToken = 0;
static NSInteger gCurrentLockToken = 0;
static NSMutableArray* gPendingSetUserAgentBlocks = nil;
@implementation CDVUserAgentUtil
+ (NSString*)originalUserAgent
{
if (gOriginalUserAgent == nil) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppLocaleDidChange:)
name:NSCurrentLocaleDidChangeNotification object:nil];
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
NSString* systemVersion = [[UIDevice currentDevice] systemVersion];
NSString* localeStr = [[NSLocale currentLocale] localeIdentifier];
// Record the model since simulator can change it without re-install (CB-5420).
NSString* model = [UIDevice currentDevice].model;
// Record the version of the app so that we can bust the cache when it changes (CB-10078)
NSString* appVersion = [[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"];
NSString* systemAndLocale = [NSString stringWithFormat:@"%@ %@ %@ %@", appVersion, model, systemVersion, localeStr];
NSString* cordovaUserAgentVersion = [userDefaults stringForKey:kCdvUserAgentVersionKey];
gOriginalUserAgent = [userDefaults stringForKey:kCdvUserAgentKey];
BOOL cachedValueIsOld = ![systemAndLocale isEqualToString:cordovaUserAgentVersion];
if ((gOriginalUserAgent == nil) || cachedValueIsOld) {
UIWebView* sampleWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
gOriginalUserAgent = [sampleWebView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
[userDefaults setObject:gOriginalUserAgent forKey:kCdvUserAgentKey];
[userDefaults setObject:systemAndLocale forKey:kCdvUserAgentVersionKey];
[userDefaults synchronize];
}
}
return gOriginalUserAgent;
}
+ (void)onAppLocaleDidChange:(NSNotification*)notification
{
// TODO: We should figure out how to update the user-agent of existing UIWebViews when this happens.
// Maybe use the PDF bug (noted in setUserAgent:).
gOriginalUserAgent = nil;
}
+ (void)acquireLock:(void (^)(NSInteger lockToken))block
{
if (gCurrentLockToken == 0) {
gCurrentLockToken = ++gNextLockToken;
VerboseLog(@"Gave lock %d", gCurrentLockToken);
block(gCurrentLockToken);
} else {
if (gPendingSetUserAgentBlocks == nil) {
gPendingSetUserAgentBlocks = [[NSMutableArray alloc] initWithCapacity:4];
}
VerboseLog(@"Waiting for lock");
[gPendingSetUserAgentBlocks addObject:block];
}
}
+ (void)releaseLock:(NSInteger*)lockToken
{
if (lockToken == nil || *lockToken == 0) {
return;
}
NSAssert(gCurrentLockToken == *lockToken, @"Got token %ld, expected %ld", (long)*lockToken, (long)gCurrentLockToken);
VerboseLog(@"Released lock %d", *lockToken);
if ([gPendingSetUserAgentBlocks count] > 0) {
void (^block)() = [gPendingSetUserAgentBlocks objectAtIndex:0];
[gPendingSetUserAgentBlocks removeObjectAtIndex:0];
gCurrentLockToken = ++gNextLockToken;
NSLog(@"Gave lock %ld", (long)gCurrentLockToken);
block(gCurrentLockToken);
} else {
gCurrentLockToken = 0;
}
*lockToken = 0;
}
+ (void)setUserAgent:(NSString*)value lockToken:(NSInteger)lockToken
{
NSAssert(gCurrentLockToken == lockToken, @"Got token %ld, expected %ld", (long)lockToken, (long)gCurrentLockToken);
VerboseLog(@"User-Agent set to: %@", value);
// Setting the UserAgent must occur before a UIWebView is instantiated.
// It is read per instantiation, so it does not affect previously created views.
// Except! When a PDF is loaded, all currently active UIWebViews reload their
// User-Agent from the NSUserDefaults some time after the DidFinishLoad of the PDF bah!
NSDictionary* dict = [[NSDictionary alloc] initWithObjectsAndKeys:value, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#import <Foundation/NSJSONSerialization.h>
#import "CDVAvailability.h"
#import "CDVInvokedUrlCommand.h"
#import "CDVCommandDelegate.h"
#import "CDVCommandQueue.h"
#import "CDVScreenOrientationDelegate.h"
#import "CDVPlugin.h"
#import "CDVWebViewEngineProtocol.h"
@interface CDVViewController : UIViewController <CDVScreenOrientationDelegate>{
@protected
id <CDVWebViewEngineProtocol> _webViewEngine;
@protected
id <CDVCommandDelegate> _commandDelegate;
@protected
CDVCommandQueue* _commandQueue;
NSString* _userAgent;
}
@property (nonatomic, readonly, weak) IBOutlet UIView* webView;
@property (nonatomic, readonly, strong) NSMutableDictionary* pluginObjects;
@property (nonatomic, readonly, strong) NSDictionary* pluginsMap;
@property (nonatomic, readonly, strong) NSMutableDictionary* settings;
@property (nonatomic, readonly, strong) NSXMLParser* configParser;
@property (nonatomic, readwrite, copy) NSString* configFile;
@property (nonatomic, readwrite, copy) NSString* wwwFolderName;
@property (nonatomic, readwrite, copy) NSString* startPage;
@property (nonatomic, readonly, strong) CDVCommandQueue* commandQueue;
@property (nonatomic, readonly, strong) id <CDVWebViewEngineProtocol> webViewEngine;
@property (nonatomic, readonly, strong) id <CDVCommandDelegate> commandDelegate;
/**
The complete user agent that Cordova will use when sending web requests.
*/
@property (nonatomic, readonly) NSString* userAgent;
/**
The base user agent data that Cordova will use to build its user agent. If this
property isn't set, Cordova will use the standard web view user agent as its
base.
*/
@property (nonatomic, readwrite, copy) NSString* baseUserAgent;
/**
Takes/Gives an array of UIInterfaceOrientation (int) objects
ex. UIInterfaceOrientationPortrait
*/
@property (nonatomic, readwrite, strong) NSArray* supportedOrientations;
/**
The address of the lock token used for controlling access to setting the user-agent
*/
@property (nonatomic, readonly) NSInteger* userAgentLockToken;
- (UIView*)newCordovaViewWithFrame:(CGRect)bounds;
- (NSString*)appURLScheme;
- (NSURL*)errorURL;
- (UIColor*)colorFromColorString:(NSString*)colorString;
- (NSArray*)parseInterfaceOrientations:(NSArray*)orientations;
- (BOOL)supportsOrientation:(UIInterfaceOrientation)orientation;
- (id)getCommandInstance:(NSString*)pluginName;
- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className;
- (void)registerPlugin:(CDVPlugin*)plugin withPluginName:(NSString*)pluginName;
- (void)parseSettingsWithParser:(NSObject <NSXMLParserDelegate>*)delegate;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
#define kCDVWebViewEngineScriptMessageHandlers @"kCDVWebViewEngineScriptMessageHandlers"
#define kCDVWebViewEngineUIWebViewDelegate @"kCDVWebViewEngineUIWebViewDelegate"
#define kCDVWebViewEngineWKNavigationDelegate @"kCDVWebViewEngineWKNavigationDelegate"
#define kCDVWebViewEngineWKUIDelegate @"kCDVWebViewEngineWKUIDelegate"
#define kCDVWebViewEngineWebViewPreferences @"kCDVWebViewEngineWebViewPreferences"
@protocol CDVWebViewEngineProtocol <NSObject>
@property (nonatomic, strong, readonly) UIView* engineWebView;
- (id)loadRequest:(NSURLRequest*)request;
- (id)loadHTMLString:(NSString*)string baseURL:(NSURL*)baseURL;
- (void)evaluateJavaScript:(NSString*)javaScriptString completionHandler:(void (^)(id, NSError*))completionHandler;
- (NSURL*)URL;
- (BOOL)canLoadRequest:(NSURLRequest*)request;
- (instancetype)initWithFrame:(CGRect)frame;
- (void)updateWithInfo:(NSDictionary*)info;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
extern NSString* const kCDVDefaultWhitelistRejectionString;
@interface CDVWhitelist : NSObject
@property (nonatomic, copy) NSString* whitelistRejectionFormatString;
- (id)initWithArray:(NSArray*)array;
- (BOOL)schemeIsAllowed:(NSString*)scheme;
- (BOOL)URLIsAllowed:(NSURL*)url;
- (BOOL)URLIsAllowed:(NSURL*)url logFailure:(BOOL)logFailure;
- (NSString*)errorStringForURL:(NSURL*)url;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface NSDictionary (CordovaPreferences)
- (id)cordovaSettingForKey:(NSString*)key;
- (BOOL)cordovaBoolSettingForKey:(NSString*)key defaultValue:(BOOL)defaultValue;
- (CGFloat)cordovaFloatSettingForKey:(NSString*)key defaultValue:(CGFloat)defaultValue;
@end
@interface NSMutableDictionary (CordovaPreferences)
- (void)setCordovaSetting:(id)value forKey:(NSString*)key;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "NSDictionary+CordovaPreferences.h"
#import <Foundation/Foundation.h>
@implementation NSDictionary (CordovaPreferences)
- (id)cordovaSettingForKey:(NSString*)key
{
return [self objectForKey:[key lowercaseString]];
}
- (BOOL)cordovaBoolSettingForKey:(NSString*)key defaultValue:(BOOL)defaultValue
{
BOOL value = defaultValue;
id prefObj = [self cordovaSettingForKey:key];
if (prefObj != nil) {
value = [(NSNumber*)prefObj boolValue];
}
return value;
}
- (CGFloat)cordovaFloatSettingForKey:(NSString*)key defaultValue:(CGFloat)defaultValue
{
CGFloat value = defaultValue;
id prefObj = [self cordovaSettingForKey:key];
if (prefObj != nil) {
value = [prefObj floatValue];
}
return value;
}
@end
@implementation NSMutableDictionary (CordovaPreferences)
- (void)setCordovaSetting:(id)value forKey:(NSString*)key
{
[self setObject:value forKey:[key lowercaseString]];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <Foundation/Foundation.h>
@interface NSMutableArray (QueueAdditions)
- (id)cdv_pop;
- (id)cdv_queueHead;
- (id)cdv_dequeue;
- (void)cdv_enqueue:(id)obj;
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import "NSMutableArray+QueueAdditions.h"
@implementation NSMutableArray (QueueAdditions)
- (id)cdv_queueHead
{
if ([self count] == 0) {
return nil;
}
return [self objectAtIndex:0];
}
- (__autoreleasing id)cdv_dequeue
{
if ([self count] == 0) {
return nil;
}
id head = [self objectAtIndex:0];
if (head != nil) {
// [[head retain] autorelease]; ARC - the __autoreleasing on the return value should so the same thing
[self removeObjectAtIndex:0];
}
return head;
}
- (id)cdv_pop
{
return [self cdv_dequeue];
}
- (void)cdv_enqueue:(id)object
{
[self addObject:object];
}
@end
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
#import <UIKit/UIKit.h>
//! Project version number for Cordova.
FOUNDATION_EXPORT double CordovaVersionNumber;
//! Project version string for Cordova.
FOUNDATION_EXPORT const unsigned char CordovaVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <Cordova/PublicHeader.h>
#import <Cordova/CDV.h>
#import <Cordova/CDVCommandDelegateImpl.h>
#import <Cordova/CDVAvailability.h>
#import <Cordova/CDVAvailabilityDeprecated.h>
#import <Cordova/CDVAppDelegate.h>
#import <Cordova/CDVPlugin.h>
#import <Cordova/CDVPluginResult.h>
#import <Cordova/CDVViewController.h>
#import <Cordova/CDVCommandDelegate.h>
#import <Cordova/CDVCommandQueue.h>
#import <Cordova/CDVConfigParser.h>
#import <Cordova/CDVURLProtocol.h>
#import <Cordova/CDVInvokedUrlCommand.h>
#import <Cordova/CDVPlugin+Resources.h>
#import <Cordova/CDVWebViewEngineProtocol.h>
#import <Cordova/NSDictionary+CordovaPreferences.h>
#import <Cordova/NSMutableArray+QueueAdditions.h>
#import <Cordova/CDVUIWebViewDelegate.h>
#import <Cordova/CDVWhitelist.h>
#import <Cordova/CDVScreenOrientationDelegate.h>
#import <Cordova/CDVTimer.h>
#import <Cordova/CDVUserAgentUtil.h>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C0C01EB11E3911D50056E6CB"
BuildableName = "Cordova.framework"
BlueprintName = "Cordova"
ReferencedContainer = "container:CordovaLib.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C0C01EB11E3911D50056E6CB"
BuildableName = "Cordova.framework"
BlueprintName = "Cordova"
ReferencedContainer = "container:CordovaLib.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C0C01EB11E3911D50056E6CB"
BuildableName = "Cordova.framework"
BlueprintName = "Cordova"
ReferencedContainer = "container:CordovaLib.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
#!/usr/bin/env node
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the KIND, either express or implied. See the License for the
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
*/ */
var emulators = require('./emulator');
// Usage support for when args are given #ifdef __OBJC__
emulators.list_images().done(function(emulator_list) { #import <Foundation/Foundation.h>
emulator_list && emulator_list.forEach(function(emu) { #endif
console.log(emu.name);
});
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});
Apache Cordova
Copyright 2012 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
<!--
#
# 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.
#
-->
[![Build status](https://ci.appveyor.com/api/projects/status/github/apache/cordova-ios?branch=master)](https://ci.appveyor.com/project/Humbedooh/cordova-ios)
[![Build Status](https://travis-ci.org/apache/cordova-ios.svg?branch=master)](https://travis-ci.org/apache/cordova-ios)
[![codecov.io](https://codecov.io/github/apache/cordova-ios/coverage.svg?branch=master)](https://codecov.io/github/apache/cordova-ios?branch=master)
Cordova iOS
=============================================================
Cordova iOS is an iOS application library that allows for Cordova-based projects to be built for the iOS Platform. Cordova based applications are, at the core, applications written with web technology: HTML, CSS and JavaScript.
<a href="http://cordova.apache.org">Apache Cordova</a> is a project of <a href="http://apache.org">The Apache Software Foundation (ASF)</a>.
Requires:
* Xcode 8.x or greater. Download it at [http://developer.apple.com/downloads](http://developer.apple.com/downloads) or the [Mac App Store](http://itunes.apple.com/us/app/xcode/id497799835?mt=12).
* [node.js](https://nodejs.org)
:warning: Report issues on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22iOS%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)
Create a Cordova project
-------------------------------------------------------------
Follow the instructions in the [**Command-Line Usage** section](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface) of [http://docs.cordova.io](http://docs.cordova.io)
To use a **shared CordovaLib**, for example in development, link the appropriate cordova-ios platform folder path:
cordova platform add --link /path/to/cordova-ios
Updating a Cordova project
-------------------------------------------------------------
When you install a new cordova-cli version that comes with a new iOS platform version, from within your project:
cordova platform rm ios
cordova platform add ios
Tests
--------------------------------------------------------------------
1. Run `npm install`
2. Run `npm test`
Futher reading
-----
* [http://cordova.apache.org/](http://cordova.apache.org/)
* [http://wiki.apache.org/cordova/](http://wiki.apache.org/cordova/)
This source diff could not be displayed because it is too large. You can view the blob instead.
environment:
matrix:
- nodejs_version: "4"
- nodejs_version: "6"
install:
- ps: Install-Product node $env:nodejs_version
# Lines below required due to uncrustify installation failure on Windows
- npm install --prod
- npm install jshint jasmine rewire
build: off
test_script:
- node --version
- npm --version
- npm run jshint
- npm run unit-tests
#!/usr/bin/env node #!/usr/bin/env node
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the KIND, either express or implied. See the License for the
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
*/ */
var android_sdk_version = require('./lib/android_sdk_version'); var versions = require('./lib/versions.js');
android_sdk_version.run().done(null, function(err) { versions.get_apple_ios_version().done(null, function(err) {
console.log(err); console.log(err);
process.exit(2); process.exit(2);
}); });
:: Licensed to the Apache Software Foundation (ASF) under one :: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file :: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information :: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file :: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the :: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance :: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at :: with the License. You may obtain a copy of the License at
:: ::
:: http://www.apache.org/licenses/LICENSE-2.0 :: http://www.apache.org/licenses/LICENSE-2.0
:: ::
:: Unless required by applicable law or agreed to in writing, :: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an :: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY :: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the :: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations :: specific language governing permissions and limitations
:: under the License. :: under the License.
@ECHO OFF @ECHO OFF
SET script_path="%~dp0list-started-emulators" SET script="%~dp0apple_ios_version"
IF EXIST %script_path% ( IF EXIST %script% (
node "%script_path%" %* node %script% %*
) ELSE ( ) ELSE (
ECHO. ECHO.
ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2 ECHO ERROR: Could not find 'apple_ios_version' script in 'bin' folder, aborting...>&2
EXIT /B 1 EXIT /B 1
) )
\ No newline at end of file
#!/usr/bin/env node
/*
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.
*/
var versions = require('./lib/versions.js');
versions.get_apple_osx_version().done(null, function(err) {
console.log(err);
process.exit(2);
});
:: Licensed to the Apache Software Foundation (ASF) under one :: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file :: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information :: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file :: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the :: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance :: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at :: with the License. You may obtain a copy of the License at
:: ::
:: http://www.apache.org/licenses/LICENSE-2.0 :: http://www.apache.org/licenses/LICENSE-2.0
:: ::
:: Unless required by applicable law or agreed to in writing, :: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an :: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY :: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the :: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations :: specific language governing permissions and limitations
:: under the License. :: under the License.
@ECHO OFF @ECHO OFF
SET script_path="%~dp0start-emulator" SET script="%~dp0apple_osx_version"
IF EXIST %script_path% ( IF EXIST %script% (
node "%script_path%" %* node %script% %*
) ELSE ( ) ELSE (
ECHO. ECHO.
ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2 ECHO ERROR: Could not find 'apple_osx_version' script in 'bin' folder, aborting...>&2
EXIT /B 1 EXIT /B 1
) )
\ No newline at end of file
#!/usr/bin/env node #!/usr/bin/env node
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
distributed with this work for additional information distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the KIND, either express or implied. See the License for the
specific language governing permissions and limitations specific language governing permissions and limitations
under the License. under the License.
*/ */
var devices = require('./device'); var versions = require('./lib/versions.js');
// Usage support for when args are given versions.get_apple_xcode_version().done(function (version) {
devices.list().done(function(device_list) { console.log(version);
device_list && device_list.forEach(function(dev) {
console.log(dev);
});
}, function(err) { }, function(err) {
console.error('ERROR: ' + err); console.error(err);
process.exit(2); process.exit(2);
}); });
:: 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.
@ECHO OFF
SET script="%~dp0apple_xcode_version"
IF EXIST %script% (
node %script% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'apple_xcode_version' script in 'bin' folder, aborting...>&2
EXIT /B 1
)
#! /usr/bin/env node
#
# 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.
#
require('nodeunit').reporters.default.run(['bin/tests'])
...@@ -21,11 +21,12 @@ ...@@ -21,11 +21,12 @@
var check_reqs = require('./lib/check_reqs'); var check_reqs = require('./lib/check_reqs');
check_reqs.run().done( // check for help flag
function success() { if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) > -1) {
console.log('Looks like your environment fully supports cordova-android development!'); console.log('Usage: check_reqs or node check_reqs');
}, function fail(err) { } else {
console.log(err); check_reqs.run().done(null, function (err) {
process.exit(2); console.error('Failed to check requirements due to ' + err);
} process.exit(2);
); });
}
...@@ -13,8 +13,7 @@ ...@@ -13,8 +13,7 @@
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY :: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the :: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations :: specific language governing permissions and limitations
:: under the License. :: under the License
@ECHO OFF @ECHO OFF
SET script_path="%~dp0check_reqs" SET script_path="%~dp0check_reqs"
IF EXIST %script_path% ( IF EXIST %script_path% (
...@@ -23,4 +22,4 @@ IF EXIST %script_path% ( ...@@ -23,4 +22,4 @@ IF EXIST %script_path% (
ECHO. ECHO.
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2 ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
EXIT /B 1 EXIT /B 1
) )
\ No newline at end of file
#!/usr/bin/python
#
# 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.
#
"""
Converts a project's Cordova.plist file into a config.xml one. This conversion is required for Cordova 2.3.
Usage:
plist2xml.py path/to/project
"""
import StringIO
import fileinput
import plistlib
import os
import re
import sys
from xml.dom import minidom
from xml.etree import ElementTree
def Usage():
sys.stderr.write(__doc__)
sys.exit(1)
def ValueToElement(node_name, key, value):
if isinstance(value, bool):
value = str(value).lower()
return ElementTree.Element(node_name, attrib={'name':key, 'value':str(value)})
def AppendDict(d, node, name, ignore=()):
for key in sorted(d):
if key not in ignore:
node.append(ValueToElement(name, key, d[key]))
def FindProjectFile(path):
# Do an extra abspath here to strip off trailing / if present.
path = os.path.abspath(path)
if path.endswith('.pbxproj'):
return path
elif path.endswith('.xcodeproj'):
return os.path.join(path, 'project.pbxproj')
for f in os.listdir(path):
if f.endswith('.xcodeproj'):
return os.path.join(path, f, 'project.pbxproj')
raise Exception('Invalid project path. Please provide the path to your .xcodeproj directory')
def FindPlistFile(search_path):
for root, unused_dirnames, file_names in os.walk(search_path):
for file_name in file_names:
if file_name == 'Cordova.plist':
return os.path.join(root, file_name)
raise Exception('Could not find a file named "Cordova.plist" within ' + search_path)
def ConvertPlist(src_path, dst_path):
# Run it through plutil to ensure it's not a binary plist.
os.system("plutil -convert xml1 '%s'" % src_path)
plist = plistlib.readPlist(src_path)
root = ElementTree.Element('cordova')
AppendDict(plist, root, 'preference', ignore=('Plugins', 'ExternalHosts'))
plugins = ElementTree.Element('plugins')
root.append(plugins)
AppendDict(plist['Plugins'], plugins, 'plugin')
for value in sorted(plist['ExternalHosts']):
root.append(ElementTree.Element('access', attrib={'origin':value}))
tree = ElementTree.ElementTree(root)
s = StringIO.StringIO()
tree.write(s, encoding='UTF-8')
mini_dom = minidom.parseString(s.getvalue())
with open(dst_path, 'w') as out:
out.write(mini_dom.toprettyxml(encoding='UTF-8'))
def UpdateProjectFile(path):
file_handle = fileinput.input(path, inplace=1)
for line in file_handle:
if 'Cordova.plist' in line:
line = line.replace('Cordova.plist', 'config.xml')
line = line.replace('lastKnownFileType = text.plist.xml', 'lastKnownFileType = text.xml')
print line,
file_handle.close()
def main(argv):
if len(argv) != 1:
Usage();
project_file = FindProjectFile(argv[0])
plist_file = FindPlistFile(os.path.dirname(os.path.dirname(project_file)))
config_file = os.path.join(os.path.dirname(plist_file), 'config.xml')
sys.stdout.write('Converting %s to %s.\n' % (plist_file, config_file))
ConvertPlist(plist_file, config_file)
sys.stdout.write('Updating references in %s\n' % project_file)
UpdateProjectFile(project_file)
os.unlink(plist_file)
sys.stdout.write('Updates Complete.\n')
if __name__ == '__main__':
main(sys.argv[1:])
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment