diff options
Diffstat (limited to 'plugins')
689 files changed, 0 insertions, 112012 deletions
diff --git a/plugins/android.json b/plugins/android.json deleted file mode 100644 index 95e0c7fd..00000000 --- a/plugins/android.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "prepare_queue": { - "installed": [], - "uninstalled": [] - }, - "config_munge": { - "files": { - "res/xml/config.xml": { - "parents": { - "/*": [ - { - "xml": "<feature name=\"Keyboard\"><param name=\"android-package\" value=\"com.ionic.keyboard.IonicKeyboard\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"OrientationLock\"><param name=\"android-package\" value=\"com.plugin.phonegap.OrientationLock\" /></feature>", - "count": 1 - }, - { - "xml": "<preference name=\"webView\" value=\"org.crosswalk.engine.XWalkWebViewEngine\" />", - "count": 1 - }, - { - "xml": "<preference default=\"14+\" name=\"xwalkVersion\" />", - "count": 1 - }, - { - "xml": "<preference default=\"--disable-pull-to-refresh-effect\" name=\"xwalkCommandLine\" />", - "count": 1 - }, - { - "xml": "<preference default=\"embedded\" name=\"xwalkMode\" />", - "count": 1 - }, - { - "xml": "<feature name=\"File\"><param name=\"android-package\" value=\"org.apache.cordova.file.FileUtils\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"InAppBrowser\"><param name=\"android-package\" value=\"org.apache.cordova.inappbrowser.InAppBrowser\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"SplashScreen\"><param name=\"android-package\" value=\"org.apache.cordova.splashscreen.SplashScreen\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"WebSocket\"><param name=\"android-package\" value=\"com.knowledgecode.cordova.websocket.WebSocket\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Whitelist\"><param name=\"android-package\" value=\"org.apache.cordova.whitelist.WhitelistPlugin\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Badge\"><param name=\"android-package\" value=\"de.appplant.cordova.plugin.badge.Badge\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"EmailComposer\"><param name=\"android-package\" value=\"de.appplant.cordova.emailcomposer.EmailComposer\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Device\"><param name=\"android-package\" value=\"org.apache.cordova.device.Device\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"LocalNotification\"><param name=\"android-package\" value=\"de.appplant.cordova.plugin.localnotification.LocalNotification\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"PinDialog\"><param name=\"android-package\" value=\"hu.dpal.phonegap.plugins.PinDialog\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Insomnia\"><param name=\"android-package\" value=\"nl.xservices.plugins.Insomnia\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"StatusBar\"><param name=\"android-package\" value=\"org.apache.cordova.statusbar.StatusBar\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Canvas2ImagePlugin\"><param name=\"android-package\" value=\"org.devgeeks.Canvas2ImagePlugin.Canvas2ImagePlugin\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"PushNotification\"><param name=\"android-package\" value=\"com.adobe.phonegap.push.PushPlugin\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"AppVersion\"><param name=\"android-package\" value=\"uk.co.whiteoctober.cordova.AppVersion\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Media\"><param name=\"android-package\" value=\"org.apache.cordova.media.AudioHandler\" /></feature>", - "count": 1 - } - ] - } - }, - "AndroidManifest.xml": { - "parents": { - "/*": [ - { - "xml": "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />", - "count": 2 - }, - { - "xml": "<uses-permission android:name=\"android.permission.INTERNET\" />", - "count": 1 - } - ], - "/manifest/application": [ - { - "xml": "<activity android:exported=\"false\" android:launchMode=\"singleInstance\" android:name=\"de.appplant.cordova.plugin.badge.LaunchActivity\" android:theme=\"@android:style/Theme.Black.NoTitleBar\" />", - "count": 1 - }, - { - "xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.localnotification.TriggerReceiver\" />", - "count": 1 - }, - { - "xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.localnotification.ClearReceiver\" />", - "count": 1 - }, - { - "xml": "<activity android:exported=\"false\" android:launchMode=\"singleInstance\" android:name=\"de.appplant.cordova.plugin.localnotification.ClickActivity\" android:theme=\"@android:style/Theme.NoDisplay\" />", - "count": 1 - }, - { - "xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.notification.TriggerReceiver\" />", - "count": 1 - }, - { - "xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.notification.ClearReceiver\" />", - "count": 1 - }, - { - "xml": "<receiver android:exported=\"false\" android:name=\"de.appplant.cordova.plugin.localnotification.RestoreReceiver\"><intent-filter><action android:name=\"android.intent.action.BOOT_COMPLETED\" /></intent-filter></receiver>", - "count": 1 - }, - { - "xml": "<activity android:exported=\"false\" android:launchMode=\"singleInstance\" android:name=\"de.appplant.cordova.plugin.notification.ClickActivity\" android:theme=\"@android:style/Theme.NoDisplay\" />", - "count": 1 - }, - { - "xml": "<activity android:exported=\"true\" android:name=\"com.adobe.phonegap.push.PushHandlerActivity\" />", - "count": 1 - }, - { - "xml": "<receiver android:name=\"com.adobe.phonegap.push.CordovaGCMBroadcastReceiver\" android:permission=\"com.google.android.c2dm.permission.SEND\"><intent-filter><action android:name=\"com.google.android.c2dm.intent.RECEIVE\" /><action android:name=\"com.google.android.c2dm.intent.REGISTRATION\" /><category android:name=\"com.pliablepixels.zmninja\" /></intent-filter></receiver>", - "count": 1 - }, - { - "xml": "<service android:name=\"com.adobe.phonegap.push.GCMIntentService\" />", - "count": 1 - } - ], - "/manifest": [ - { - "xml": "<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"android.permission.WAKE_LOCK\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"android.permission.VIBRATE\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"com.google.android.c2dm.permission.RECEIVE\" />", - "count": 1 - }, - { - "xml": "<permission android:name=\"com.pliablepixels.zmninja.permission.C2D_MESSAGE\" android:protectionLevel=\"signature\" />", - "count": 1 - }, - { - "xml": "<uses-permission android:name=\"com.pliablepixels.zmninja.permission.C2D_MESSAGE\" />", - "count": 1 - } - ] - } - } - } - }, - "installed_plugins": { - "com.ionic.keyboard": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "com.phonegap.plugins.OrientationLock": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-crosswalk-webview": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-file": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-inappbrowser": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-ios-longpress-fix": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-splashscreen": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-touchid": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-websocket": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-whitelist": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.common.registerusernotificationsettings": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.plugin.badge": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.plugin.email-composer": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.plugin.local-notification": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "hu.dpal.phonegap.plugins.PinDialog": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "nl.x-services.plugins.insomnia": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.apache.cordova.console": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.apache.cordova.statusbar": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.devgeeks.Canvas2ImagePlugin": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "phonegap-plugin-push": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "uk.co.whiteoctober.cordova.appversion": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.apache.cordova.media": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - } - }, - "dependent_plugins": { - "org.apache.cordova.device": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - } - } -}
\ No newline at end of file diff --git a/plugins/com.ionic.keyboard/LICENSE b/plugins/com.ionic.keyboard/LICENSE deleted file mode 100644 index d6f545b8..00000000 --- a/plugins/com.ionic.keyboard/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2014 Drifty Co. - - Licensed 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. diff --git a/plugins/com.ionic.keyboard/README.md b/plugins/com.ionic.keyboard/README.md deleted file mode 100644 index 63f70012..00000000 --- a/plugins/com.ionic.keyboard/README.md +++ /dev/null @@ -1,123 +0,0 @@ -Keyboard -====== - -The `cordova.plugins.Keyboard` object provides functions to make interacting with the keyboard easier, and fires events to indicate that the keyboard will hide/show. - - cordova plugin add com.ionic.keyboard - -Methods -------- - -- cordova.plugins.Keyboard.hideKeyboardAccessoryBar -- cordova.plugins.Keyboard.close -- cordova.plugins.Keyboard.disableScroll -- cordova.plugins.Keyboard.show - -Properties --------- - -- cordova.plugins.Keyboard.isVisible - -Events --------- - -These events are fired on the window. - -- native.keyboardshow - * A number `keyboardHeight` is given on the event object, which is the pixel height of the keyboard. -- native.keyboardhide - -Keyboard.hideKeyboardAccessoryBar -================= - -Hide the keyboard accessory bar with the next, previous and done buttons. - - cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); - cordova.plugins.Keyboard.hideKeyboardAccessoryBar(false); - -Supported Platforms -------------------- - -- iOS - - -Keyboard.close -================= - -Close the keyboard if it is open. - - cordova.plugins.Keyboard.close(); - -Supported Platforms -------------------- - -- iOS, Android, Blackberry 10 - - -Keyboard.disableScroll -================= - -Disable native scrolling, useful if you are using JavaScript to scroll - - cordova.plugins.Keyboard.disableScroll(true); - cordova.plugins.Keyboard.disableScroll(false); - -Supported Platforms -------------------- - -- iOS - -Keyboard.show -================= - -Force keyboard to be shown on Android. This typically helps if autofocus on a text element does not pop up the keyboard automatically - - cordova.plugins.Keyboard.show(); - -Supported Platforms - -- Android, Blackberry 10 - -native.keyboardshow -================= - -This event fires when the keyboard will be shown - - window.addEventListener('native.keyboardshow', keyboardShowHandler); - - function keyboardShowHandler(e){ - alert('Keyboard height is: ' + e.keyboardHeight); - } - -Properties ------------ - -keyboardHeight: the height of the keyboard in pixels - - -Supported Platforms -------------------- - -- iOS, Android, Blackberry 10 - - -native.keyboardhide -================= - -This event fires when the keyboard will hide - - window.addEventListener('native.keyboardhide', keyboardHideHandler); - - function keyboardHideHandler(e){ - alert('Goodnight, sweet prince'); - } - -Properties ------------ - -None - -Supported Platforms -------------------- - -- iOS, Android, Blackberry 10 diff --git a/plugins/com.ionic.keyboard/package.json b/plugins/com.ionic.keyboard/package.json deleted file mode 100644 index 4dd54150..00000000 --- a/plugins/com.ionic.keyboard/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "version": "1.0.4", - "name": "com.ionic.keyboard", - "cordova_name": "Keyboard", - "description": "Ionic Keyboard Plugin", - "license": "Apache 2.0", - "repo": "https://github.com/driftyco/ionic-plugins-keyboard.git", - "issue": "https://github.com/driftyco/ionic-plugins-keyboard/issues", - "keywords": [ - "Ionic", - "keyboard" - ], - "platforms": [ - "android", - "ios", - "blackberry10" - ], - "engines": [] -}
\ No newline at end of file diff --git a/plugins/com.ionic.keyboard/plugin.xml b/plugins/com.ionic.keyboard/plugin.xml deleted file mode 100644 index 06688915..00000000 --- a/plugins/com.ionic.keyboard/plugin.xml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="com.ionic.keyboard" - version="1.0.4"> - <name>Keyboard</name> - <description>Ionic Keyboard Plugin</description> - <license>Apache 2.0</license> - <keywords>Ionic,keyboard</keywords> - <repo>https://github.com/driftyco/ionic-plugins-keyboard.git</repo> - <issue>https://github.com/driftyco/ionic-plugins-keyboard/issues</issue> - - <js-module src="www/keyboard.js" name="keyboard"> - <clobbers target="cordova.plugins.Keyboard" /> - </js-module> - - <!-- android --> - <platform name="android"> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Keyboard"> - <param name="android-package" value="com.ionic.keyboard.IonicKeyboard" /> - <param name="onload" value="true" /> - </feature> - </config-file> - - <source-file src="src/android/IonicKeyboard.java" target-dir="src/com/ionic/keyboard" /> - </platform> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="Keyboard"> - <param name="ios-package" value="IonicKeyboard" onload="true" /> - </feature> - </config-file> - - <header-file src="src/ios/IonicKeyboard.h" /> - <source-file src="src/ios/IonicKeyboard.m" /> - <header-file src="src/ios/UIWebViewExtension.h" /> - <source-file src="src/ios/UIWebViewExtension.m" /> - </platform> - - <!-- blackberry10 --> - <platform name="blackberry10"> - <source-file src="src/blackberry10/index.js" target-dir='Keyboard' /> - <lib-file src="src/blackberry10/native/device/libKeyboard.so" arch="device"/> - <lib-file src="src/blackberry10/native/simulator/libKeyboard.so" arch="simulator"/> - <config-file target="www/config.xml" parent="/widget"> - <feature name="Keyboard" value="com.ionic.keyboard"/> - - </config-file> - </platform> - -</plugin> diff --git a/plugins/com.ionic.keyboard/src/android/IonicKeyboard.java b/plugins/com.ionic.keyboard/src/android/IonicKeyboard.java deleted file mode 100644 index deb914ab..00000000 --- a/plugins/com.ionic.keyboard/src/android/IonicKeyboard.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.ionic.keyboard; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.PluginResult.Status; -import org.json.JSONArray; -import org.json.JSONException; - -import android.content.Context; -import android.graphics.Rect; -import android.util.DisplayMetrics; -import android.view.View; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.view.inputmethod.InputMethodManager; - -public class IonicKeyboard extends CordovaPlugin{ - - public void initialize(CordovaInterface cordova, CordovaWebView webView) { - super.initialize(cordova, webView); - - //calculate density-independent pixels (dp) - //http://developer.android.com/guide/practices/screens_support.html - DisplayMetrics dm = new DisplayMetrics(); - cordova.getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); - final float density = dm.density; - - final CordovaWebView appView = webView; - - //http://stackoverflow.com/a/4737265/1091751 detect if keyboard is showing - final View rootView = cordova.getActivity().getWindow().getDecorView().findViewById(android.R.id.content).getRootView(); - OnGlobalLayoutListener list = new OnGlobalLayoutListener() { - int previousHeightDiff = 0; - @Override - public void onGlobalLayout() { - Rect r = new Rect(); - //r will be populated with the coordinates of your view that area still visible. - rootView.getWindowVisibleDisplayFrame(r); - - int heightDiff = rootView.getRootView().getHeight() - (r.bottom - r.top); - int pixelHeightDiff = (int)(heightDiff / density); - if (pixelHeightDiff > 100 && pixelHeightDiff != previousHeightDiff) { // if more than 100 pixels, its probably a keyboard... - appView.sendJavascript("cordova.plugins.Keyboard.isVisible = true"); - appView.sendJavascript("cordova.fireWindowEvent('native.keyboardshow', { 'keyboardHeight':" + Integer.toString(pixelHeightDiff)+"});"); - - //deprecated - appView.sendJavascript("cordova.fireWindowEvent('native.showkeyboard', { 'keyboardHeight':" + Integer.toString(pixelHeightDiff)+"});"); - } - else if ( pixelHeightDiff != previousHeightDiff && ( previousHeightDiff - pixelHeightDiff ) > 100 ){ - appView.sendJavascript("cordova.plugins.Keyboard.isVisible = false"); - appView.sendJavascript("cordova.fireWindowEvent('native.keyboardhide')"); - - //deprecated - appView.sendJavascript("cordova.fireWindowEvent('native.hidekeyboard')"); - } - previousHeightDiff = pixelHeightDiff; - } - }; - - rootView.getViewTreeObserver().addOnGlobalLayoutListener(list); - } - - public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { - if ("close".equals(action)) { - cordova.getThreadPool().execute(new Runnable() { - public void run() { - //http://stackoverflow.com/a/7696791/1091751 - InputMethodManager inputManager = (InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - View v = cordova.getActivity().getCurrentFocus(); - - if (v == null) { - callbackContext.error("No current focus"); - } else { - inputManager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); - callbackContext.success(); // Thread-safe. - } - } - }); - return true; - } - if ("show".equals(action)) { - cordova.getThreadPool().execute(new Runnable() { - public void run() { - ((InputMethodManager) cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); - callbackContext.success(); // Thread-safe. - } - }); - return true; - } - return false; // Returning false results in a "MethodNotFound" error. - } - - -} - diff --git a/plugins/com.ionic.keyboard/src/blackberry10/index.js b/plugins/com.ionic.keyboard/src/blackberry10/index.js deleted file mode 100644 index 40294158..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/index.js +++ /dev/null @@ -1,135 +0,0 @@ - - -var keyboard, - resultObjs = {}, - threadCallback = null, - _utils = require("../../lib/utils"); - _event = require("../../lib/event"); - _webview = require("../../lib/webview"); - - - - -module.exports = { - - // Code can be declared and used outside the module.exports object, - // but any functions to be called by client.js need to be declared - // here in this object. - - // These methods call into JNEXT.Keyboard which handles the - // communication through the JNEXT plugin to keyboard_js.cpp - startService: function (success, fail, args, env) { - var result = new PluginResult(args, env); - - result.ok(keyboard.getInstance().startService(), false); - }, - show: function (success, fail, args, env) { - var result = new PluginResult(args, env); - - result.ok(keyboard.getInstance().showKeyboard(), false); - }, - close: function (success, fail, args, env) { - var result = new PluginResult(args, env); - - result.ok(keyboard.getInstance().closeKeyboard(), false); - } -}; - -keyboardShow = function(a){ - _webview.executeJavascript("cordova.plugins.Keyboard.isVisible = true"); - _webview.executeJavascript("cordova.fireDocumentEvent('native.keyboardshow',"+a+")"); - -} -keyboardHide = function(){ - _webview.executeJavascript("cordova.plugins.Keyboard.isVisible = false"); - _webview.executeJavascript("cordova.fireDocumentEvent('native.keyboardhide','')"); - -} -onStart = function() { - _webview.executeJavascript("cordova.exec("+null+", "+null+", 'Keyboard', 'startService', '')"); - } - -setTimeout(onStart,2000); - -/////////////////////////////////////////////////////////////////// -// JavaScript wrapper for JNEXT plugin for connection -/////////////////////////////////////////////////////////////////// - -JNEXT.Keyboard = function () { - var self = this, - hasInstance = false; - - self.getId = function () { - return self.m_id; - }; - - self.init = function () { - if (!JNEXT.require("libKeyboard")) { - return false; - } - - self.m_id = JNEXT.createObject("libKeyboard.Keyboard_JS"); - - if (self.m_id === "") { - return false; - } - - JNEXT.registerEvents(self); - }; - - // ************************ - // Enter your methods here - // ************************ - - // calls into InvokeMethod(string command) in keyboard_js.cpp - self.startService = function () { - return JNEXT.invoke(self.m_id, "startService"); - }; - self.showKeyboard = function () { - return JNEXT.invoke(self.m_id, "showKeyboard"); - }; - self.closeKeyboard = function () { - return JNEXT.invoke(self.m_id, "closeKeyboard"); - }; - - self.onEvent = function (strData) { // Fired by the Event framework (used by asynchronous callbacks) - var arData = strData.split(" "), - strEventDesc = arData[0], - jsonData; - - if (strEventDesc === "native.keyboardshow") { - jsonData = arData.slice(1, arData.length).join(" "); - keyboardShow(jsonData); - - } - else if (strEventDesc === "native.keyboardhide") { - keyboardHide(); - } - - }; - - // Thread methods - self.keyboardStartThread = function (callbackId) { - return JNEXT.invoke(self.m_id, "keyboardStartThread " + callbackId); - }; - self.keyboardStopThread = function () { - return JNEXT.invoke(self.m_id, "keyboardStopThread"); - }; - - // ************************ - // End of methods to edit - // ************************ - self.m_id = ""; - - self.getInstance = function () { - if (!hasInstance) { - hasInstance = true; - self.init(); - } - return self; - }; - -}; - -keyboard = new JNEXT.Keyboard(); - diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/.cproject b/plugins/com.ionic.keyboard/src/blackberry10/native/.cproject deleted file mode 100644 index 7b118eec..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/.cproject +++ /dev/null @@ -1,222 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> - <storageModule moduleId="org.eclipse.cdt.core.settings"> - <cconfiguration id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567"> - <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567" moduleId="org.eclipse.cdt.core.settings" name="device"> - <externalSettings> - <externalSetting> - <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Cordova-Keyboard"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Cordova-Keyboard/device"/> - <entry flags="RESOLVED" kind="libraryFile" name="Cordova-Keyboard" srcPrefixMapping="" srcRootPath=""/> - </externalSetting> - </externalSettings> - <extensions> - <extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> - <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> - <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> - <extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/> - </extensions> - </storageModule> - <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567" name="device" parent="com.qnx.qcc.configuration.sharedLib.release"> - <folderInfo id="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567." name="/" resourcePath=""> - <toolChain id="com.qnx.qcc.toolChain.2215983" name="QNX QCC" superClass="com.qnx.qcc.toolChain"> - <option id="com.qnx.qcc.option.cpu.315540759" name="Target CPU:" superClass="com.qnx.qcc.option.cpu" value="com.qnx.qcc.option.gen.cpu.armle-v7" valueType="enumerated"/> - <targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.1359109141" osList="all" superClass="com.qnx.qcc.targetPlatform"/> - <builder buildPath="${workspace_loc:/Keyboard/Device-Release}" id="com.qnx.nto.938326560" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/> - <tool id="com.qnx.qcc.tool.compiler.242697771" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler"> - <option id="com.qnx.qcc.option.compiler.shared.553244928" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.compiler.optlevel.2070537906" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.2" valueType="enumerated"/> - <option id="com.qnx.qcc.option.compiler.includePath.1483355415" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath"> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/> - <listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/> - </option> - <option id="com.qnx.qcc.option.compiler.security.9625963" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.compiler.defines.872099896" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols"> - <listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/> - </option> - <option id="com.qnx.qcc.option.compiler.qccoptions.1015003128" name="QCC Options" superClass="com.qnx.qcc.option.compiler.qccoptions" valueType="stringList"> - <listOptionValue builtIn="false" value="-frecord-gcc-switches"/> - </option> - <inputType id="com.qnx.qcc.inputType.compiler.1443568066" superClass="com.qnx.qcc.inputType.compiler"/> - </tool> - <tool id="com.qnx.qcc.tool.assembler.1996828008" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler"> - <inputType id="com.qnx.qcc.inputType.assembler.116798417" superClass="com.qnx.qcc.inputType.assembler"/> - </tool> - <tool id="com.qnx.qcc.tool.linker.871546588" name="QCC Linker" superClass="com.qnx.qcc.tool.linker"> - <option id="com.qnx.qcc.option.linker.shared.915102752" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.linker.libraryPaths.1049529253" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths"> - <listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/${CPUVARDIR}/usr/lib"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/${CPUVARDIR}/usr/lib/qt4/lib"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/> - </option> - <option id="com.qnx.qcc.option.linker.security.1157664997" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.linker.libraries.1316432206" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs"> - <listOptionValue builtIn="false" value="slog2"/> - <listOptionValue builtIn="false" value="QtCore"/> - <listOptionValue builtIn="false" value="bb"/> - <listOptionValue builtIn="false" value="bps"/> - </option> - <inputType id="com.qnx.qcc.inputType.linker.1028572887" superClass="com.qnx.qcc.inputType.linker"> - <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> - <additionalInput kind="additionalinput" paths="$(LIBS)"/> - </inputType> - </tool> - <tool id="com.qnx.qcc.tool.archiver.1781914947" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/> - </toolChain> - </folderInfo> - <sourceEntries> - <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> - <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/> - </sourceEntries> - </configuration> - </storageModule> - <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> - </cconfiguration> - <cconfiguration id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091"> - <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091" moduleId="org.eclipse.cdt.core.settings" name="simulator"> - <externalSettings> - <externalSetting> - <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Cordova-Keyboard"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Cordova-Keyboard/simulator"/> - <entry flags="RESOLVED" kind="libraryFile" name="Cordova-Keyboard" srcPrefixMapping="" srcRootPath=""/> - </externalSetting> - </externalSettings> - <extensions> - <extension id="com.qnx.tools.ide.qde.core.QDELinkerErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> - <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> - <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> - <extension id="com.qnx.tools.ide.qde.core.QDEBynaryParser" point="org.eclipse.cdt.core.BinaryParser"/> - </extensions> - </storageModule> - <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" description="" id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091" name="simulator" parent="com.qnx.qcc.configuration.sharedLib.debug"> - <folderInfo id="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091." name="/" resourcePath=""> - <toolChain id="com.qnx.qcc.toolChain.688026907" name="QNX QCC" superClass="com.qnx.qcc.toolChain"> - <targetPlatform archList="all" binaryParser="com.qnx.tools.ide.qde.core.QDEBynaryParser" id="com.qnx.qcc.targetPlatform.469207190" osList="all" superClass="com.qnx.qcc.targetPlatform"/> - <builder buildPath="${workspace_loc:/Keyboard/Simulator-Debug}" id="com.qnx.nto.2029800497" keepEnvironmentInBuildfile="false" name="CDT Internal Builder" superClass="com.qnx.nto"/> - <tool id="com.qnx.qcc.tool.compiler.1028279123" name="QCC Compiler" superClass="com.qnx.qcc.tool.compiler"> - <option id="com.qnx.qcc.option.compiler.shared.235893159" name="Shared (-shared)" superClass="com.qnx.qcc.option.compiler.shared" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.compiler.optlevel.1164238904" name="Optimization Level" superClass="com.qnx.qcc.option.compiler.optlevel" value="com.qnx.qcc.option.compiler.optlevel.0" valueType="enumerated"/> - <option id="com.qnx.qcc.option.compile.debug.3716470" name="Debug (-g)" superClass="com.qnx.qcc.option.compile.debug" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.compiler.includePath.306305432" name="Include Directories (-I)" superClass="com.qnx.qcc.option.compiler.includePath" valueType="includePath"> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/bb"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4/QtCore"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/qt4"/> - <listOptionValue builtIn="false" value="${workspace_loc:/${ProjName}/public}"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/usr/include/freetype2"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/usr/include"/> - </option> - <option id="com.qnx.qcc.option.compiler.security.1730007887" name="Enhanced Security (-fstack-protector-strong)" superClass="com.qnx.qcc.option.compiler.security" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.compiler.defines.1526896965" name="Defines (-D)" superClass="com.qnx.qcc.option.compiler.defines" valueType="definedSymbols"> - <listOptionValue builtIn="false" value="_FORTIFY_SOURCE=2"/> - </option> - <inputType id="com.qnx.qcc.inputType.compiler.1881183122" superClass="com.qnx.qcc.inputType.compiler"/> - </tool> - <tool id="com.qnx.qcc.tool.assembler.312168125" name="QCC Assembler" superClass="com.qnx.qcc.tool.assembler"> - <option id="com.qnx.qcc.option.assembler.debug.416544277" name="Debug (-g)" superClass="com.qnx.qcc.option.assembler.debug" value="true" valueType="boolean"/> - <inputType id="com.qnx.qcc.inputType.assembler.1722778407" superClass="com.qnx.qcc.inputType.assembler"/> - </tool> - <tool id="com.qnx.qcc.tool.linker.2130364088" name="QCC Linker" superClass="com.qnx.qcc.tool.linker"> - <option id="com.qnx.qcc.option.linker.debug.1332880614" name="Debug (-g)" superClass="com.qnx.qcc.option.linker.debug" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.linker.shared.1633267255" name="Shared (-shared)" superClass="com.qnx.qcc.option.linker.shared" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.linker.libraryPaths.565794953" name="Library Paths (-L)" superClass="com.qnx.qcc.option.linker.libraryPaths" valueType="libPaths"> - <listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/lib"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/${CPUVARDIR}/usr/lib"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/${CPUVARDIR}/usr/lib/qt4/lib"/> - <listOptionValue builtIn="false" value="${QNX_TARGET}/../target-override/${CPUVARDIR}/usr/lib"/> - </option> - <option id="com.qnx.qcc.option.linker.security.9141791" name="Enhanced Security (-Wl,-z,relro -Wl,-z,now)" superClass="com.qnx.qcc.option.linker.security" value="true" valueType="boolean"/> - <option id="com.qnx.qcc.option.linker.libraries.220836649" name="Libraries (-l)" superClass="com.qnx.qcc.option.linker.libraries" valueType="libs"> - <listOptionValue builtIn="false" value="slog2"/> - <listOptionValue builtIn="false" value="QtCore"/> - <listOptionValue builtIn="false" value="bb"/> - <listOptionValue builtIn="false" value="bps"/> - </option> - <inputType id="com.qnx.qcc.inputType.linker.167117375" superClass="com.qnx.qcc.inputType.linker"> - <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> - <additionalInput kind="additionalinput" paths="$(LIBS)"/> - </inputType> - </tool> - <tool id="com.qnx.qcc.tool.archiver.489682882" name="QCC Archiver" superClass="com.qnx.qcc.tool.archiver"/> - </toolChain> - </folderInfo> - <sourceEntries> - <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> - <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="public"/> - </sourceEntries> - </configuration> - </storageModule> - <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> - </cconfiguration> - </storageModule> - <storageModule moduleId="cdtBuildSystem" version="4.0.0"> - <project id="Keyboard.null.138005006" name="Keyboard"/> - </storageModule> - <storageModule moduleId="refreshScope" versionNumber="2"> - <configuration configurationName="Simulator-Profile"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="simulator"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="Simulator-Coverage"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="Device-Profile"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="Device-Debug"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="Simulator-Debug"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="device"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="Device-Release"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - <configuration configurationName="Device-Coverage"> - <resource resourceType="PROJECT" workspacePath="/Keyboard"/> - </configuration> - </storageModule> - <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> - <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> - <storageModule moduleId="scannerConfiguration"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.profile.941124085"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.coverage.1806890017"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.release.608922875"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.profile.27502649"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.debug.193597202"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.coverage.537092296"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.debug.193597202.362186091"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.release.608922875.1009704567"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - <scannerConfigBuildInfo instanceId="com.qnx.qcc.configuration.sharedLib.debug.1877214659"> - <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.qnx.tools.ide.qde.managedbuilder.core.qccScannerInfo"/> - </scannerConfigBuildInfo> - </storageModule> -</cproject> diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/.project b/plugins/com.ionic.keyboard/src/blackberry10/native/.project deleted file mode 100644 index 8a39f221..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/.project +++ /dev/null @@ -1,76 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>Keyboard</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> - <triggers>clean,full,incremental,</triggers> - <arguments> - <dictionary> - <key>?name?</key> - <value></value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.append_environment</key> - <value>true</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.buildArguments</key> - <value></value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.buildCommand</key> - <value>make</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.buildLocation</key> - <value>${workspace_loc:/Keyboard/Device-Release}</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.contents</key> - <value>org.eclipse.cdt.make.core.activeConfigSettings</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.enableAutoBuild</key> - <value>false</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.enableCleanBuild</key> - <value>true</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.enableFullBuild</key> - <value>true</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.stopOnError</key> - <value>true</value> - </dictionary> - <dictionary> - <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key> - <value>true</value> - </dictionary> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> - <triggers>full,incremental,</triggers> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.cdt.core.cnature</nature> - <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> - <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> - <nature>com.qnx.tools.ide.bbt.core.bbtnature</nature> - </natures> -</projectDescription> diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_reader.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_reader.o Binary files differdeleted file mode 100644 index 6f78251c..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_reader.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_value.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_value.o Binary files differdeleted file mode 100644 index 310adeb4..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_value.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_writer.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_writer.o Binary files differdeleted file mode 100644 index b81c56b9..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/json_writer.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/plugin.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/plugin.o Binary files differdeleted file mode 100644 index 90f1590d..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/plugin.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/tokenizer.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/tokenizer.o Binary files differdeleted file mode 100644 index 4062f5f0..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/public/tokenizer.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/CallKeyboard.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/CallKeyboard.o Binary files differdeleted file mode 100644 index 3bb136b6..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/CallKeyboard.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/Logger.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/Logger.o Binary files differdeleted file mode 100644 index f677dc8e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/Logger.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/keyboard_js.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/keyboard_js.o Binary files differdeleted file mode 100644 index 6bcd769f..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/keyboard_js.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/keyboard_ndk.o b/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/keyboard_ndk.o Binary files differdeleted file mode 100644 index c5bc3b8e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/device/src/keyboard_ndk.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/autolink.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/autolink.h deleted file mode 100644 index 37c9258e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/autolink.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef JSON_AUTOLINK_H_INCLUDED -# define JSON_AUTOLINK_H_INCLUDED - -# include "config.h" - -# ifdef JSON_IN_CPPTL -# include <cpptl/cpptl_autolink.h> -# endif - -# if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && !defined(JSON_IN_CPPTL) -# define CPPTL_AUTOLINK_NAME "json" -# undef CPPTL_AUTOLINK_DLL -# ifdef JSON_DLL -# define CPPTL_AUTOLINK_DLL -# endif -# include "autolink.h" -# endif - -#endif // JSON_AUTOLINK_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/config.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/config.h deleted file mode 100644 index 5d334cbc..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/config.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef JSON_CONFIG_H_INCLUDED -# define JSON_CONFIG_H_INCLUDED - -/// If defined, indicates that json library is embedded in CppTL library. -//# define JSON_IN_CPPTL 1 - -/// If defined, indicates that json may leverage CppTL library -//# define JSON_USE_CPPTL 1 -/// If defined, indicates that cpptl vector based map should be used instead of std::map -/// as Value container. -//# define JSON_USE_CPPTL_SMALLMAP 1 -/// If defined, indicates that Json specific container should be used -/// (hash table & simple deque container with customizable allocator). -/// THIS FEATURE IS STILL EXPERIMENTAL! -//# define JSON_VALUE_USE_INTERNAL_MAP 1 -/// Force usage of standard new/malloc based allocator instead of memory pool based allocator. -/// The memory pools allocator used optimization (initializing Value and ValueInternalLink -/// as if it was a POD) that may cause some validation tool to report errors. -/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined. -//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 1 - -/// If defined, indicates that Json use exception to report invalid type manipulation -/// instead of C assert macro. -# define JSON_USE_EXCEPTION 1 - -# ifdef JSON_IN_CPPTL -# include <cpptl/config.h> -# ifndef JSON_USE_CPPTL -# define JSON_USE_CPPTL 1 -# endif -# endif - -# ifdef JSON_IN_CPPTL -# define JSON_API CPPTL_API -# elif defined(JSON_DLL_BUILD) -# define JSON_API __declspec(dllexport) -# elif defined(JSON_DLL) -# define JSON_API __declspec(dllimport) -# else -# define JSON_API -# endif - -#endif // JSON_CONFIG_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/features.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/features.h deleted file mode 100644 index 5a9adec1..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/features.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef CPPTL_JSON_FEATURES_H_INCLUDED -# define CPPTL_JSON_FEATURES_H_INCLUDED - -# include "forwards.h" - -namespace Json { - - /** \brief Configuration passed to reader and writer. - * This configuration object can be used to force the Reader or Writer - * to behave in a standard conforming way. - */ - class JSON_API Features - { - public: - /** \brief A configuration that allows all features and assumes all strings are UTF-8. - * - C & C++ comments are allowed - * - Root object can be any JSON value - * - Assumes Value strings are encoded in UTF-8 - */ - static Features all(); - - /** \brief A configuration that is strictly compatible with the JSON specification. - * - Comments are forbidden. - * - Root object must be either an array or an object value. - * - Assumes Value strings are encoded in UTF-8 - */ - static Features strictMode(); - - /** \brief Initialize the configuration like JsonConfig::allFeatures; - */ - Features(); - - /// \c true if comments are allowed. Default: \c true. - bool allowComments_; - - /// \c true if root must be either an array or an object value. Default: \c false. - bool strictRoot_; - }; - -} // namespace Json - -#endif // CPPTL_JSON_FEATURES_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/forwards.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/forwards.h deleted file mode 100644 index d0ce8300..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/forwards.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef JSON_FORWARDS_H_INCLUDED -# define JSON_FORWARDS_H_INCLUDED - -# include "config.h" - -namespace Json { - - // writer.h - class FastWriter; - class StyledWriter; - - // reader.h - class Reader; - - // features.h - class Features; - - // value.h - typedef int Int; - typedef unsigned int UInt; - class StaticString; - class Path; - class PathArgument; - class Value; - class ValueIteratorBase; - class ValueIterator; - class ValueConstIterator; -#ifdef JSON_VALUE_USE_INTERNAL_MAP - class ValueAllocator; - class ValueMapAllocator; - class ValueInternalLink; - class ValueInternalArray; - class ValueInternalMap; -#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP - -} // namespace Json - - -#endif // JSON_FORWARDS_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/json.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/json.h deleted file mode 100644 index c71ed65a..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/json.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef JSON_JSON_H_INCLUDED -# define JSON_JSON_H_INCLUDED - -# include "autolink.h" -# include "value.h" -# include "reader.h" -# include "writer.h" -# include "features.h" - -#endif // JSON_JSON_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/reader.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/reader.h deleted file mode 100644 index ee1d6a24..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/reader.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef CPPTL_JSON_READER_H_INCLUDED -# define CPPTL_JSON_READER_H_INCLUDED - -# include "features.h" -# include "value.h" -# include <deque> -# include <stack> -# include <string> -# include <iostream> - -namespace Json { - - /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a Value. - * - */ - class JSON_API Reader - { - public: - typedef char Char; - typedef const Char *Location; - - /** \brief Constructs a Reader allowing all features - * for parsing. - */ - Reader(); - - /** \brief Constructs a Reader allowing the specified feature set - * for parsing. - */ - Reader( const Features &features ); - - /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document. - * \param document UTF-8 encoded string containing the document to read. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param collectComments \c true to collect comment and allow writing them back during - * serialization, \c false to discard comments. - * This parameter is ignored if Features::allowComments_ - * is \c false. - * \return \c true if the document was successfully parsed, \c false if an error occurred. - */ - bool parse( const std::string &document, - Value &root, - bool collectComments = true ); - - /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a> document. - * \param document UTF-8 encoded string containing the document to read. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param collectComments \c true to collect comment and allow writing them back during - * serialization, \c false to discard comments. - * This parameter is ignored if Features::allowComments_ - * is \c false. - * \return \c true if the document was successfully parsed, \c false if an error occurred. - */ - bool parse( const char *beginDoc, const char *endDoc, - Value &root, - bool collectComments = true ); - - /// \brief Parse from input stream. - /// \see Json::operator>>(std::istream&, Json::Value&). - bool parse( std::istream &is, - Value &root, - bool collectComments = true ); - - /** \brief Returns a user friendly string that list errors in the parsed document. - * \return Formatted error message with the list of errors with their location in - * the parsed document. An empty string is returned if no error occurred - * during parsing. - */ - std::string getFormatedErrorMessages() const; - - private: - enum TokenType - { - tokenEndOfStream = 0, - tokenObjectBegin, - tokenObjectEnd, - tokenArrayBegin, - tokenArrayEnd, - tokenString, - tokenNumber, - tokenTrue, - tokenFalse, - tokenNull, - tokenArraySeparator, - tokenMemberSeparator, - tokenComment, - tokenError - }; - - class Token - { - public: - TokenType type_; - Location start_; - Location end_; - }; - - class ErrorInfo - { - public: - Token token_; - std::string message_; - Location extra_; - }; - - typedef std::deque<ErrorInfo> Errors; - - bool expectToken( TokenType type, Token &token, const char *message ); - bool readToken( Token &token ); - void skipSpaces(); - bool match( Location pattern, - int patternLength ); - bool readComment(); - bool readCStyleComment(); - bool readCppStyleComment(); - bool readString(); - void readNumber(); - bool readValue(); - bool readObject( Token &token ); - bool readArray( Token &token ); - bool decodeNumber( Token &token ); - bool decodeString( Token &token ); - bool decodeString( Token &token, std::string &decoded ); - bool decodeDouble( Token &token ); - bool decodeUnicodeCodePoint( Token &token, - Location ¤t, - Location end, - unsigned int &unicode ); - bool decodeUnicodeEscapeSequence( Token &token, - Location ¤t, - Location end, - unsigned int &unicode ); - bool addError( const std::string &message, - Token &token, - Location extra = 0 ); - bool recoverFromError( TokenType skipUntilToken ); - bool addErrorAndRecover( const std::string &message, - Token &token, - TokenType skipUntilToken ); - void skipUntilSpace(); - Value ¤tValue(); - Char getNextChar(); - void getLocationLineAndColumn( Location location, - int &line, - int &column ) const; - std::string getLocationLineAndColumn( Location location ) const; - void addComment( Location begin, - Location end, - CommentPlacement placement ); - void skipCommentTokens( Token &token ); - - typedef std::stack<Value *> Nodes; - Nodes nodes_; - Errors errors_; - std::string document_; - Location begin_; - Location end_; - Location current_; - Location lastValueEnd_; - Value *lastValue_; - std::string commentsBefore_; - Features features_; - bool collectComments_; - }; - - /** \brief Read from 'sin' into 'root'. - - Always keep comments from the input JSON. - - This can be used to read a file into a particular sub-object. - For example: - \code - Json::Value root; - cin >> root["dir"]["file"]; - cout << root; - \endcode - Result: - \verbatim - { - "dir": { - "file": { - // The input stream JSON would be nested here. - } - } - } - \endverbatim - \throw std::exception on parse error. - \see Json::operator<<() - */ - std::istream& operator>>( std::istream&, Value& ); - -} // namespace Json - -#endif // CPPTL_JSON_READER_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/value.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/value.h deleted file mode 100644 index 58bfd88e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/value.h +++ /dev/null @@ -1,1069 +0,0 @@ -#ifndef CPPTL_JSON_H_INCLUDED -# define CPPTL_JSON_H_INCLUDED - -# include "forwards.h" -# include <string> -# include <vector> - -# ifndef JSON_USE_CPPTL_SMALLMAP -# include <map> -# else -# include <cpptl/smallmap.h> -# endif -# ifdef JSON_USE_CPPTL -# include <cpptl/forwards.h> -# endif - -/** \brief JSON (JavaScript Object Notation). - */ -namespace Json { - - /** \brief Type of the value held by a Value object. - */ - enum ValueType - { - nullValue = 0, ///< 'null' value - intValue, ///< signed integer value - uintValue, ///< unsigned integer value - realValue, ///< double value - stringValue, ///< UTF-8 string value - booleanValue, ///< bool value - arrayValue, ///< array value (ordered list) - objectValue ///< object value (collection of name/value pairs). - }; - - enum CommentPlacement - { - commentBefore = 0, ///< a comment placed on the line before a value - commentAfterOnSameLine, ///< a comment just after a value on the same line - commentAfter, ///< a comment on the line after a value (only make sense for root value) - numberOfCommentPlacement - }; - -//# ifdef JSON_USE_CPPTL -// typedef CppTL::AnyEnumerator<const char *> EnumMemberNames; -// typedef CppTL::AnyEnumerator<const Value &> EnumValues; -//# endif - - /** \brief Lightweight wrapper to tag static string. - * - * Value constructor and objectValue member assignement takes advantage of the - * StaticString and avoid the cost of string duplication when storing the - * string or the member name. - * - * Example of usage: - * \code - * Json::Value aValue( StaticString("some text") ); - * Json::Value object; - * static const StaticString code("code"); - * object[code] = 1234; - * \endcode - */ - class JSON_API StaticString - { - public: - explicit StaticString( const char *czstring ) - : str_( czstring ) - { - } - - operator const char *() const - { - return str_; - } - - const char *c_str() const - { - return str_; - } - - private: - const char *str_; - }; - - /** \brief Represents a <a HREF="http://www.json.org">JSON</a> value. - * - * This class is a discriminated union wrapper that can represents a: - * - signed integer [range: Value::minInt - Value::maxInt] - * - unsigned integer (range: 0 - Value::maxUInt) - * - double - * - UTF-8 string - * - boolean - * - 'null' - * - an ordered list of Value - * - collection of name/value pairs (javascript object) - * - * The type of the held value is represented by a #ValueType and - * can be obtained using type(). - * - * values of an #objectValue or #arrayValue can be accessed using operator[]() methods. - * Non const methods will automatically create the a #nullValue element - * if it does not exist. - * The sequence of an #arrayValue will be automatically resize and initialized - * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue. - * - * The get() methods can be used to obtanis default value in the case the required element - * does not exist. - * - * It is possible to iterate over the list of a #objectValue values using - * the getMemberNames() method. - */ - class JSON_API Value - { - friend class ValueIteratorBase; -# ifdef JSON_VALUE_USE_INTERNAL_MAP - friend class ValueInternalLink; - friend class ValueInternalMap; -# endif - public: - typedef std::vector<std::string> Members; - typedef ValueIterator iterator; - typedef ValueConstIterator const_iterator; - typedef Json::UInt UInt; - typedef Json::Int Int; - typedef UInt ArrayIndex; - - static const Value null; - static const Int minInt; - static const Int maxInt; - static const UInt maxUInt; - - private: -#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION -# ifndef JSON_VALUE_USE_INTERNAL_MAP - class CZString - { - public: - enum DuplicationPolicy - { - noDuplication = 0, - duplicate, - duplicateOnCopy - }; - CZString( int index ); - CZString( const char *cstr, DuplicationPolicy allocate ); - CZString( const CZString &other ); - ~CZString(); - CZString &operator =( const CZString &other ); - bool operator<( const CZString &other ) const; - bool operator==( const CZString &other ) const; - int index() const; - const char *c_str() const; - bool isStaticString() const; - private: - void swap( CZString &other ); - const char *cstr_; - int index_; - }; - - public: -# ifndef JSON_USE_CPPTL_SMALLMAP - typedef std::map<CZString, Value> ObjectValues; -# else - typedef CppTL::SmallMap<CZString, Value> ObjectValues; -# endif // ifndef JSON_USE_CPPTL_SMALLMAP -# endif // ifndef JSON_VALUE_USE_INTERNAL_MAP -#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - - public: - /** \brief Create a default Value of the given type. - - This is a very useful constructor. - To create an empty array, pass arrayValue. - To create an empty object, pass objectValue. - Another Value can then be set to this one by assignment. - This is useful since clear() and resize() will not alter types. - - Examples: - \code - Json::Value null_value; // null - Json::Value arr_value(Json::arrayValue); // [] - Json::Value obj_value(Json::objectValue); // {} - \endcode - */ - Value( ValueType type = nullValue ); - Value( Int value ); - Value( UInt value ); - Value( double value ); - Value( const char *value ); - Value( const char *beginValue, const char *endValue ); - /** \brief Constructs a value from a static string. - - * Like other value string constructor but do not duplicate the string for - * internal storage. The given string must remain alive after the call to this - * constructor. - * Example of usage: - * \code - * Json::Value aValue( StaticString("some text") ); - * \endcode - */ - Value( const StaticString &value ); - Value( const std::string &value ); -# ifdef JSON_USE_CPPTL - Value( const CppTL::ConstString &value ); -# endif - Value( bool value ); - Value( const Value &other ); - ~Value(); - - Value &operator=( const Value &other ); - /// Swap values. - /// \note Currently, comments are intentionally not swapped, for - /// both logic and efficiency. - void swap( Value &other ); - - ValueType type() const; - - bool operator <( const Value &other ) const; - bool operator <=( const Value &other ) const; - bool operator >=( const Value &other ) const; - bool operator >( const Value &other ) const; - - bool operator ==( const Value &other ) const; - bool operator !=( const Value &other ) const; - - int compare( const Value &other ); - - const char *asCString() const; - std::string asString() const; -# ifdef JSON_USE_CPPTL - CppTL::ConstString asConstString() const; -# endif - Int asInt() const; - UInt asUInt() const; - double asDouble() const; - bool asBool() const; - - bool isNull() const; - bool isBool() const; - bool isInt() const; - bool isUInt() const; - bool isIntegral() const; - bool isDouble() const; - bool isNumeric() const; - bool isString() const; - bool isArray() const; - bool isObject() const; - - bool isConvertibleTo( ValueType other ) const; - - /// Number of values in array or object - UInt size() const; - - /// \brief Return true if empty array, empty object, or null; - /// otherwise, false. - bool empty() const; - - /// Return isNull() - bool operator!() const; - - /// Remove all object members and array elements. - /// \pre type() is arrayValue, objectValue, or nullValue - /// \post type() is unchanged - void clear(); - - /// Resize the array to size elements. - /// New elements are initialized to null. - /// May only be called on nullValue or arrayValue. - /// \pre type() is arrayValue or nullValue - /// \post type() is arrayValue - void resize( UInt size ); - - /// Access an array element (zero based index ). - /// If the array contains less than index element, then null value are inserted - /// in the array so that its size is index+1. - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) - Value &operator[]( UInt index ); - /// Access an array element (zero based index ) - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) - const Value &operator[]( UInt index ) const; - /// If the array contains at least index+1 elements, returns the element value, - /// otherwise returns defaultValue. - Value get( UInt index, - const Value &defaultValue ) const; - /// Return true if index < size(). - bool isValidIndex( UInt index ) const; - /// \brief Append value to array at the end. - /// - /// Equivalent to jsonvalue[jsonvalue.size()] = value; - Value &append( const Value &value ); - - /// Access an object value by name, create a null member if it does not exist. - Value &operator[]( const char *key ); - /// Access an object value by name, returns null if there is no member with that name. - const Value &operator[]( const char *key ) const; - /// Access an object value by name, create a null member if it does not exist. - Value &operator[]( const std::string &key ); - /// Access an object value by name, returns null if there is no member with that name. - const Value &operator[]( const std::string &key ) const; - /** \brief Access an object value by name, create a null member if it does not exist. - - * If the object as no entry for that name, then the member name used to store - * the new entry is not duplicated. - * Example of use: - * \code - * Json::Value object; - * static const StaticString code("code"); - * object[code] = 1234; - * \endcode - */ - Value &operator[]( const StaticString &key ); -# ifdef JSON_USE_CPPTL - /// Access an object value by name, create a null member if it does not exist. - Value &operator[]( const CppTL::ConstString &key ); - /// Access an object value by name, returns null if there is no member with that name. - const Value &operator[]( const CppTL::ConstString &key ) const; -# endif - /// Return the member named key if it exist, defaultValue otherwise. - Value get( const char *key, - const Value &defaultValue ) const; - /// Return the member named key if it exist, defaultValue otherwise. - Value get( const std::string &key, - const Value &defaultValue ) const; -# ifdef JSON_USE_CPPTL - /// Return the member named key if it exist, defaultValue otherwise. - Value get( const CppTL::ConstString &key, - const Value &defaultValue ) const; -# endif - /// \brief Remove and return the named member. - /// - /// Do nothing if it did not exist. - /// \return the removed Value, or null. - /// \pre type() is objectValue or nullValue - /// \post type() is unchanged - Value removeMember( const char* key ); - /// Same as removeMember(const char*) - Value removeMember( const std::string &key ); - - /// Return true if the object has a member named key. - bool isMember( const char *key ) const; - /// Return true if the object has a member named key. - bool isMember( const std::string &key ) const; -# ifdef JSON_USE_CPPTL - /// Return true if the object has a member named key. - bool isMember( const CppTL::ConstString &key ) const; -# endif - - /// \brief Return a list of the member names. - /// - /// If null, return an empty list. - /// \pre type() is objectValue or nullValue - /// \post if type() was nullValue, it remains nullValue - Members getMemberNames() const; - -//# ifdef JSON_USE_CPPTL -// EnumMemberNames enumMemberNames() const; -// EnumValues enumValues() const; -//# endif - - /// Comments must be //... or /* ... */ - void setComment( const char *comment, - CommentPlacement placement ); - /// Comments must be //... or /* ... */ - void setComment( const std::string &comment, - CommentPlacement placement ); - bool hasComment( CommentPlacement placement ) const; - /// Include delimiters and embedded newlines. - std::string getComment( CommentPlacement placement ) const; - - std::string toStyledString() const; - - const_iterator begin() const; - const_iterator end() const; - - iterator begin(); - iterator end(); - - private: - Value &resolveReference( const char *key, - bool isStatic ); - -# ifdef JSON_VALUE_USE_INTERNAL_MAP - inline bool isItemAvailable() const - { - return itemIsUsed_ == 0; - } - - inline void setItemUsed( bool isUsed = true ) - { - itemIsUsed_ = isUsed ? 1 : 0; - } - - inline bool isMemberNameStatic() const - { - return memberNameIsStatic_ == 0; - } - - inline void setMemberNameIsStatic( bool isStatic ) - { - memberNameIsStatic_ = isStatic ? 1 : 0; - } -# endif // # ifdef JSON_VALUE_USE_INTERNAL_MAP - - private: - struct CommentInfo - { - CommentInfo(); - ~CommentInfo(); - - void setComment( const char *text ); - - char *comment_; - }; - - //struct MemberNamesTransform - //{ - // typedef const char *result_type; - // const char *operator()( const CZString &name ) const - // { - // return name.c_str(); - // } - //}; - - union ValueHolder - { - Int int_; - UInt uint_; - double real_; - bool bool_; - char *string_; -# ifdef JSON_VALUE_USE_INTERNAL_MAP - ValueInternalArray *array_; - ValueInternalMap *map_; -#else - ObjectValues *map_; -# endif - } value_; - ValueType type_ : 8; - int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. -# ifdef JSON_VALUE_USE_INTERNAL_MAP - unsigned int itemIsUsed_ : 1; // used by the ValueInternalMap container. - int memberNameIsStatic_ : 1; // used by the ValueInternalMap container. -# endif - CommentInfo *comments_; - }; - - - /** \brief Experimental and untested: represents an element of the "path" to access a node. - */ - class PathArgument - { - public: - friend class Path; - - PathArgument(); - PathArgument( UInt index ); - PathArgument( const char *key ); - PathArgument( const std::string &key ); - - private: - enum Kind - { - kindNone = 0, - kindIndex, - kindKey - }; - std::string key_; - UInt index_; - Kind kind_; - }; - - /** \brief Experimental and untested: represents a "path" to access a node. - * - * Syntax: - * - "." => root node - * - ".[n]" => elements at index 'n' of root node (an array value) - * - ".name" => member named 'name' of root node (an object value) - * - ".name1.name2.name3" - * - ".[0][1][2].name1[3]" - * - ".%" => member name is provided as parameter - * - ".[%]" => index is provied as parameter - */ - class Path - { - public: - Path( const std::string &path, - const PathArgument &a1 = PathArgument(), - const PathArgument &a2 = PathArgument(), - const PathArgument &a3 = PathArgument(), - const PathArgument &a4 = PathArgument(), - const PathArgument &a5 = PathArgument() ); - - const Value &resolve( const Value &root ) const; - Value resolve( const Value &root, - const Value &defaultValue ) const; - /// Creates the "path" to access the specified node and returns a reference on the node. - Value &make( Value &root ) const; - - private: - typedef std::vector<const PathArgument *> InArgs; - typedef std::vector<PathArgument> Args; - - void makePath( const std::string &path, - const InArgs &in ); - void addPathInArg( const std::string &path, - const InArgs &in, - InArgs::const_iterator &itInArg, - PathArgument::Kind kind ); - void invalidPath( const std::string &path, - int location ); - - Args args_; - }; - - /** \brief Experimental do not use: Allocator to customize member name and string value memory management done by Value. - * - * - makeMemberName() and releaseMemberName() are called to respectively duplicate and - * free an Json::objectValue member name. - * - duplicateStringValue() and releaseStringValue() are called similarly to - * duplicate and free a Json::stringValue value. - */ - class ValueAllocator - { - public: - enum { unknown = (unsigned)-1 }; - - virtual ~ValueAllocator(); - - virtual char *makeMemberName( const char *memberName ) = 0; - virtual void releaseMemberName( char *memberName ) = 0; - virtual char *duplicateStringValue( const char *value, - unsigned int length = unknown ) = 0; - virtual void releaseStringValue( char *value ) = 0; - }; - -#ifdef JSON_VALUE_USE_INTERNAL_MAP - /** \brief Allocator to customize Value internal map. - * Below is an example of a simple implementation (default implementation actually - * use memory pool for speed). - * \code - class DefaultValueMapAllocator : public ValueMapAllocator - { - public: // overridden from ValueMapAllocator - virtual ValueInternalMap *newMap() - { - return new ValueInternalMap(); - } - - virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) - { - return new ValueInternalMap( other ); - } - - virtual void destructMap( ValueInternalMap *map ) - { - delete map; - } - - virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) - { - return new ValueInternalLink[size]; - } - - virtual void releaseMapBuckets( ValueInternalLink *links ) - { - delete [] links; - } - - virtual ValueInternalLink *allocateMapLink() - { - return new ValueInternalLink(); - } - - virtual void releaseMapLink( ValueInternalLink *link ) - { - delete link; - } - }; - * \endcode - */ - class JSON_API ValueMapAllocator - { - public: - virtual ~ValueMapAllocator(); - virtual ValueInternalMap *newMap() = 0; - virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) = 0; - virtual void destructMap( ValueInternalMap *map ) = 0; - virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) = 0; - virtual void releaseMapBuckets( ValueInternalLink *links ) = 0; - virtual ValueInternalLink *allocateMapLink() = 0; - virtual void releaseMapLink( ValueInternalLink *link ) = 0; - }; - - /** \brief ValueInternalMap hash-map bucket chain link (for internal use only). - * \internal previous_ & next_ allows for bidirectional traversal. - */ - class JSON_API ValueInternalLink - { - public: - enum { itemPerLink = 6 }; // sizeof(ValueInternalLink) = 128 on 32 bits architecture. - enum InternalFlags { - flagAvailable = 0, - flagUsed = 1 - }; - - ValueInternalLink(); - - ~ValueInternalLink(); - - Value items_[itemPerLink]; - char *keys_[itemPerLink]; - ValueInternalLink *previous_; - ValueInternalLink *next_; - }; - - - /** \brief A linked page based hash-table implementation used internally by Value. - * \internal ValueInternalMap is a tradional bucket based hash-table, with a linked - * list in each bucket to handle collision. There is an addional twist in that - * each node of the collision linked list is a page containing a fixed amount of - * value. This provides a better compromise between memory usage and speed. - * - * Each bucket is made up of a chained list of ValueInternalLink. The last - * link of a given bucket can be found in the 'previous_' field of the following bucket. - * The last link of the last bucket is stored in tailLink_ as it has no following bucket. - * Only the last link of a bucket may contains 'available' item. The last link always - * contains at least one element unless is it the bucket one very first link. - */ - class JSON_API ValueInternalMap - { - friend class ValueIteratorBase; - friend class Value; - public: - typedef unsigned int HashKey; - typedef unsigned int BucketIndex; - -# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - struct IteratorState - { - IteratorState() - : map_(0) - , link_(0) - , itemIndex_(0) - , bucketIndex_(0) - { - } - ValueInternalMap *map_; - ValueInternalLink *link_; - BucketIndex itemIndex_; - BucketIndex bucketIndex_; - }; -# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - - ValueInternalMap(); - ValueInternalMap( const ValueInternalMap &other ); - ValueInternalMap &operator =( const ValueInternalMap &other ); - ~ValueInternalMap(); - - void swap( ValueInternalMap &other ); - - BucketIndex size() const; - - void clear(); - - bool reserveDelta( BucketIndex growth ); - - bool reserve( BucketIndex newItemCount ); - - const Value *find( const char *key ) const; - - Value *find( const char *key ); - - Value &resolveReference( const char *key, - bool isStatic ); - - void remove( const char *key ); - - void doActualRemove( ValueInternalLink *link, - BucketIndex index, - BucketIndex bucketIndex ); - - ValueInternalLink *&getLastLinkInBucket( BucketIndex bucketIndex ); - - Value &setNewItem( const char *key, - bool isStatic, - ValueInternalLink *link, - BucketIndex index ); - - Value &unsafeAdd( const char *key, - bool isStatic, - HashKey hashedKey ); - - HashKey hash( const char *key ) const; - - int compare( const ValueInternalMap &other ) const; - - private: - void makeBeginIterator( IteratorState &it ) const; - void makeEndIterator( IteratorState &it ) const; - static bool equals( const IteratorState &x, const IteratorState &other ); - static void increment( IteratorState &iterator ); - static void incrementBucket( IteratorState &iterator ); - static void decrement( IteratorState &iterator ); - static const char *key( const IteratorState &iterator ); - static const char *key( const IteratorState &iterator, bool &isStatic ); - static Value &value( const IteratorState &iterator ); - static int distance( const IteratorState &x, const IteratorState &y ); - - private: - ValueInternalLink *buckets_; - ValueInternalLink *tailLink_; - BucketIndex bucketsSize_; - BucketIndex itemCount_; - }; - - /** \brief A simplified deque implementation used internally by Value. - * \internal - * It is based on a list of fixed "page", each page contains a fixed number of items. - * Instead of using a linked-list, a array of pointer is used for fast item look-up. - * Look-up for an element is as follow: - * - compute page index: pageIndex = itemIndex / itemsPerPage - * - look-up item in page: pages_[pageIndex][itemIndex % itemsPerPage] - * - * Insertion is amortized constant time (only the array containing the index of pointers - * need to be reallocated when items are appended). - */ - class JSON_API ValueInternalArray - { - friend class Value; - friend class ValueIteratorBase; - public: - enum { itemsPerPage = 8 }; // should be a power of 2 for fast divide and modulo. - typedef Value::ArrayIndex ArrayIndex; - typedef unsigned int PageIndex; - -# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - struct IteratorState // Must be a POD - { - IteratorState() - : array_(0) - , currentPageIndex_(0) - , currentItemIndex_(0) - { - } - ValueInternalArray *array_; - Value **currentPageIndex_; - unsigned int currentItemIndex_; - }; -# endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - - ValueInternalArray(); - ValueInternalArray( const ValueInternalArray &other ); - ValueInternalArray &operator =( const ValueInternalArray &other ); - ~ValueInternalArray(); - void swap( ValueInternalArray &other ); - - void clear(); - void resize( ArrayIndex newSize ); - - Value &resolveReference( ArrayIndex index ); - - Value *find( ArrayIndex index ) const; - - ArrayIndex size() const; - - int compare( const ValueInternalArray &other ) const; - - private: - static bool equals( const IteratorState &x, const IteratorState &other ); - static void increment( IteratorState &iterator ); - static void decrement( IteratorState &iterator ); - static Value &dereference( const IteratorState &iterator ); - static Value &unsafeDereference( const IteratorState &iterator ); - static int distance( const IteratorState &x, const IteratorState &y ); - static ArrayIndex indexOf( const IteratorState &iterator ); - void makeBeginIterator( IteratorState &it ) const; - void makeEndIterator( IteratorState &it ) const; - void makeIterator( IteratorState &it, ArrayIndex index ) const; - - void makeIndexValid( ArrayIndex index ); - - Value **pages_; - ArrayIndex size_; - PageIndex pageCount_; - }; - - /** \brief Experimental: do not use. Allocator to customize Value internal array. - * Below is an example of a simple implementation (actual implementation use - * memory pool). - \code -class DefaultValueArrayAllocator : public ValueArrayAllocator -{ -public: // overridden from ValueArrayAllocator - virtual ~DefaultValueArrayAllocator() - { - } - - virtual ValueInternalArray *newArray() - { - return new ValueInternalArray(); - } - - virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) - { - return new ValueInternalArray( other ); - } - - virtual void destruct( ValueInternalArray *array ) - { - delete array; - } - - virtual void reallocateArrayPageIndex( Value **&indexes, - ValueInternalArray::PageIndex &indexCount, - ValueInternalArray::PageIndex minNewIndexCount ) - { - ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; - if ( minNewIndexCount > newIndexCount ) - newIndexCount = minNewIndexCount; - void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); - if ( !newIndexes ) - throw std::bad_alloc(); - indexCount = newIndexCount; - indexes = static_cast<Value **>( newIndexes ); - } - virtual void releaseArrayPageIndex( Value **indexes, - ValueInternalArray::PageIndex indexCount ) - { - if ( indexes ) - free( indexes ); - } - - virtual Value *allocateArrayPage() - { - return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) ); - } - - virtual void releaseArrayPage( Value *value ) - { - if ( value ) - free( value ); - } -}; - \endcode - */ - class JSON_API ValueArrayAllocator - { - public: - virtual ~ValueArrayAllocator(); - virtual ValueInternalArray *newArray() = 0; - virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) = 0; - virtual void destructArray( ValueInternalArray *array ) = 0; - /** \brief Reallocate array page index. - * Reallocates an array of pointer on each page. - * \param indexes [input] pointer on the current index. May be \c NULL. - * [output] pointer on the new index of at least - * \a minNewIndexCount pages. - * \param indexCount [input] current number of pages in the index. - * [output] number of page the reallocated index can handle. - * \b MUST be >= \a minNewIndexCount. - * \param minNewIndexCount Minimum number of page the new index must be able to - * handle. - */ - virtual void reallocateArrayPageIndex( Value **&indexes, - ValueInternalArray::PageIndex &indexCount, - ValueInternalArray::PageIndex minNewIndexCount ) = 0; - virtual void releaseArrayPageIndex( Value **indexes, - ValueInternalArray::PageIndex indexCount ) = 0; - virtual Value *allocateArrayPage() = 0; - virtual void releaseArrayPage( Value *value ) = 0; - }; -#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP - - - /** \brief base class for Value iterators. - * - */ - class ValueIteratorBase - { - public: - typedef unsigned int size_t; - typedef int difference_type; - typedef ValueIteratorBase SelfType; - - ValueIteratorBase(); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - explicit ValueIteratorBase( const Value::ObjectValues::iterator ¤t ); -#else - ValueIteratorBase( const ValueInternalArray::IteratorState &state ); - ValueIteratorBase( const ValueInternalMap::IteratorState &state ); -#endif - - bool operator ==( const SelfType &other ) const - { - return isEqual( other ); - } - - bool operator !=( const SelfType &other ) const - { - return !isEqual( other ); - } - - difference_type operator -( const SelfType &other ) const - { - return computeDistance( other ); - } - - /// Return either the index or the member name of the referenced value as a Value. - Value key() const; - - /// Return the index of the referenced Value. -1 if it is not an arrayValue. - UInt index() const; - - /// Return the member name of the referenced Value. "" if it is not an objectValue. - const char *memberName() const; - - protected: - Value &deref() const; - - void increment(); - - void decrement(); - - difference_type computeDistance( const SelfType &other ) const; - - bool isEqual( const SelfType &other ) const; - - void copy( const SelfType &other ); - - private: -#ifndef JSON_VALUE_USE_INTERNAL_MAP - Value::ObjectValues::iterator current_; - // Indicates that iterator is for a null value. - bool isNull_; -#else - union - { - ValueInternalArray::IteratorState array_; - ValueInternalMap::IteratorState map_; - } iterator_; - bool isArray_; -#endif - }; - - /** \brief const iterator for object and array value. - * - */ - class ValueConstIterator : public ValueIteratorBase - { - friend class Value; - public: - typedef unsigned int size_t; - typedef int difference_type; - typedef const Value &reference; - typedef const Value *pointer; - typedef ValueConstIterator SelfType; - - ValueConstIterator(); - private: - /*! \internal Use by Value to create an iterator. - */ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - explicit ValueConstIterator( const Value::ObjectValues::iterator ¤t ); -#else - ValueConstIterator( const ValueInternalArray::IteratorState &state ); - ValueConstIterator( const ValueInternalMap::IteratorState &state ); -#endif - public: - SelfType &operator =( const ValueIteratorBase &other ); - - SelfType operator++( int ) - { - SelfType temp( *this ); - ++*this; - return temp; - } - - SelfType operator--( int ) - { - SelfType temp( *this ); - --*this; - return temp; - } - - SelfType &operator--() - { - decrement(); - return *this; - } - - SelfType &operator++() - { - increment(); - return *this; - } - - reference operator *() const - { - return deref(); - } - }; - - - /** \brief Iterator for object and array value. - */ - class ValueIterator : public ValueIteratorBase - { - friend class Value; - public: - typedef unsigned int size_t; - typedef int difference_type; - typedef Value &reference; - typedef Value *pointer; - typedef ValueIterator SelfType; - - ValueIterator(); - ValueIterator( const ValueConstIterator &other ); - ValueIterator( const ValueIterator &other ); - private: - /*! \internal Use by Value to create an iterator. - */ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - explicit ValueIterator( const Value::ObjectValues::iterator ¤t ); -#else - ValueIterator( const ValueInternalArray::IteratorState &state ); - ValueIterator( const ValueInternalMap::IteratorState &state ); -#endif - public: - - SelfType &operator =( const SelfType &other ); - - SelfType operator++( int ) - { - SelfType temp( *this ); - ++*this; - return temp; - } - - SelfType operator--( int ) - { - SelfType temp( *this ); - --*this; - return temp; - } - - SelfType &operator--() - { - decrement(); - return *this; - } - - SelfType &operator++() - { - increment(); - return *this; - } - - reference operator *() const - { - return deref(); - } - }; - - -} // namespace Json - - -#endif // CPPTL_JSON_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/writer.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/writer.h deleted file mode 100644 index 5f4b83be..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json/writer.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef JSON_WRITER_H_INCLUDED -# define JSON_WRITER_H_INCLUDED - -# include "value.h" -# include <vector> -# include <string> -# include <iostream> - -namespace Json { - - class Value; - - /** \brief Abstract class for writers. - */ - class JSON_API Writer - { - public: - virtual ~Writer(); - - virtual std::string write( const Value &root ) = 0; - }; - - /** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format without formatting (not human friendly). - * - * The JSON document is written in a single line. It is not intended for 'human' consumption, - * but may be usefull to support feature such as RPC where bandwith is limited. - * \sa Reader, Value - */ - class JSON_API FastWriter : public Writer - { - public: - FastWriter(); - virtual ~FastWriter(){} - - void enableYAMLCompatibility(); - - public: // overridden from Writer - virtual std::string write( const Value &root ); - - private: - void writeValue( const Value &value ); - - std::string document_; - bool yamlCompatiblityEnabled_; - }; - - /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way. - * - * The rules for line break and indent are as follow: - * - Object value: - * - if empty then print {} without indent and line break - * - if not empty the print '{', line break & indent, print one value per line - * and then unindent and line break and print '}'. - * - Array value: - * - if empty then print [] without indent and line break - * - if the array contains no object value, empty array or some other value types, - * and all the values fit on one lines, then print the array on a single line. - * - otherwise, it the values do not fit on one line, or the array contains - * object or non empty array, then print one value per line. - * - * If the Value have comments then they are outputed according to their #CommentPlacement. - * - * \sa Reader, Value, Value::setComment() - */ - class JSON_API StyledWriter: public Writer - { - public: - StyledWriter(); - virtual ~StyledWriter(){} - - public: // overridden from Writer - /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. - * \param root Value to serialize. - * \return String containing the JSON document that represents the root value. - */ - virtual std::string write( const Value &root ); - - private: - void writeValue( const Value &value ); - void writeArrayValue( const Value &value ); - bool isMultineArray( const Value &value ); - void pushValue( const std::string &value ); - void writeIndent(); - void writeWithIndent( const std::string &value ); - void indent(); - void unindent(); - void writeCommentBeforeValue( const Value &root ); - void writeCommentAfterValueOnSameLine( const Value &root ); - bool hasCommentForValue( const Value &value ); - static std::string normalizeEOL( const std::string &text ); - - typedef std::vector<std::string> ChildValues; - - ChildValues childValues_; - std::string document_; - std::string indentString_; - int rightMargin_; - int indentSize_; - bool addChildValues_; - }; - - /** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a human friendly way, - to a stream rather than to a string. - * - * The rules for line break and indent are as follow: - * - Object value: - * - if empty then print {} without indent and line break - * - if not empty the print '{', line break & indent, print one value per line - * and then unindent and line break and print '}'. - * - Array value: - * - if empty then print [] without indent and line break - * - if the array contains no object value, empty array or some other value types, - * and all the values fit on one lines, then print the array on a single line. - * - otherwise, it the values do not fit on one line, or the array contains - * object or non empty array, then print one value per line. - * - * If the Value have comments then they are outputed according to their #CommentPlacement. - * - * \param indentation Each level will be indented by this amount extra. - * \sa Reader, Value, Value::setComment() - */ - class JSON_API StyledStreamWriter - { - public: - StyledStreamWriter( std::string indentation="\t" ); - ~StyledStreamWriter(){} - - public: - /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format. - * \param out Stream to write to. (Can be ostringstream, e.g.) - * \param root Value to serialize. - * \note There is no point in deriving from Writer, since write() should not return a value. - */ - void write( std::ostream &out, const Value &root ); - - private: - void writeValue( const Value &value ); - void writeArrayValue( const Value &value ); - bool isMultineArray( const Value &value ); - void pushValue( const std::string &value ); - void writeIndent(); - void writeWithIndent( const std::string &value ); - void indent(); - void unindent(); - void writeCommentBeforeValue( const Value &root ); - void writeCommentAfterValueOnSameLine( const Value &root ); - bool hasCommentForValue( const Value &value ); - static std::string normalizeEOL( const std::string &text ); - - typedef std::vector<std::string> ChildValues; - - ChildValues childValues_; - std::ostream* document_; - std::string indentString_; - int rightMargin_; - std::string indentation_; - bool addChildValues_; - }; - - std::string JSON_API valueToString( Int value ); - std::string JSON_API valueToString( UInt value ); - std::string JSON_API valueToString( double value ); - std::string JSON_API valueToString( bool value ); - std::string JSON_API valueToQuotedString( const char *value ); - - /// \brief Output using the StyledStreamWriter. - /// \see Json::operator>>() - std::ostream& operator<<( std::ostream&, const Value &root ); - -} // namespace Json - - - -#endif // JSON_WRITER_H_INCLUDED diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_batchallocator.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_batchallocator.h deleted file mode 100644 index 87ea5ed8..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_batchallocator.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED -# define JSONCPP_BATCHALLOCATOR_H_INCLUDED - -# include <stdlib.h> -# include <assert.h> - -# ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION - -namespace Json { - -/* Fast memory allocator. - * - * This memory allocator allocates memory for a batch of object (specified by - * the page size, the number of object in each page). - * - * It does not allow the destruction of a single object. All the allocated objects - * can be destroyed at once. The memory can be either released or reused for future - * allocation. - * - * The in-place new operator must be used to construct the object using the pointer - * returned by allocate. - */ -template<typename AllocatedType - ,const unsigned int objectPerAllocation> -class BatchAllocator -{ -public: - typedef AllocatedType Type; - - BatchAllocator( unsigned int objectsPerPage = 255 ) - : freeHead_( 0 ) - , objectsPerPage_( objectsPerPage ) - { -// printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() ); - assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space. - assert( objectsPerPage >= 16 ); - batches_ = allocateBatch( 0 ); // allocated a dummy page - currentBatch_ = batches_; - } - - ~BatchAllocator() - { - for ( BatchInfo *batch = batches_; batch; ) - { - BatchInfo *nextBatch = batch->next_; - free( batch ); - batch = nextBatch; - } - } - - /// allocate space for an array of objectPerAllocation object. - /// @warning it is the responsability of the caller to call objects constructors. - AllocatedType *allocate() - { - if ( freeHead_ ) // returns node from free list. - { - AllocatedType *object = freeHead_; - freeHead_ = *(AllocatedType **)object; - return object; - } - if ( currentBatch_->used_ == currentBatch_->end_ ) - { - currentBatch_ = currentBatch_->next_; - while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ ) - currentBatch_ = currentBatch_->next_; - - if ( !currentBatch_ ) // no free batch found, allocate a new one - { - currentBatch_ = allocateBatch( objectsPerPage_ ); - currentBatch_->next_ = batches_; // insert at the head of the list - batches_ = currentBatch_; - } - } - AllocatedType *allocated = currentBatch_->used_; - currentBatch_->used_ += objectPerAllocation; - return allocated; - } - - /// Release the object. - /// @warning it is the responsability of the caller to actually destruct the object. - void release( AllocatedType *object ) - { - assert( object != 0 ); - *(AllocatedType **)object = freeHead_; - freeHead_ = object; - } - -private: - struct BatchInfo - { - BatchInfo *next_; - AllocatedType *used_; - AllocatedType *end_; - AllocatedType buffer_[objectPerAllocation]; - }; - - // disabled copy constructor and assignement operator. - BatchAllocator( const BatchAllocator & ); - void operator =( const BatchAllocator &); - - static BatchInfo *allocateBatch( unsigned int objectsPerPage ) - { - const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation - + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage; - BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) ); - batch->next_ = 0; - batch->used_ = batch->buffer_; - batch->end_ = batch->buffer_ + objectsPerPage; - return batch; - } - - BatchInfo *batches_; - BatchInfo *currentBatch_; - /// Head of a single linked list within the allocated space of freeed object - AllocatedType *freeHead_; - unsigned int objectsPerPage_; -}; - - -} // namespace Json - -# endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION - -#endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED - diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_internalarray.inl b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_internalarray.inl deleted file mode 100644 index 9b985d25..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_internalarray.inl +++ /dev/null @@ -1,448 +0,0 @@ -// included by json_value.cpp -// everything is within Json namespace - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueInternalArray -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueArrayAllocator::~ValueArrayAllocator() -{ -} - -// ////////////////////////////////////////////////////////////////// -// class DefaultValueArrayAllocator -// ////////////////////////////////////////////////////////////////// -#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -class DefaultValueArrayAllocator : public ValueArrayAllocator -{ -public: // overridden from ValueArrayAllocator - virtual ~DefaultValueArrayAllocator() - { - } - - virtual ValueInternalArray *newArray() - { - return new ValueInternalArray(); - } - - virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) - { - return new ValueInternalArray( other ); - } - - virtual void destructArray( ValueInternalArray *array ) - { - delete array; - } - - virtual void reallocateArrayPageIndex( Value **&indexes, - ValueInternalArray::PageIndex &indexCount, - ValueInternalArray::PageIndex minNewIndexCount ) - { - ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; - if ( minNewIndexCount > newIndexCount ) - newIndexCount = minNewIndexCount; - void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); - if ( !newIndexes ) - throw std::bad_alloc(); - indexCount = newIndexCount; - indexes = static_cast<Value **>( newIndexes ); - } - virtual void releaseArrayPageIndex( Value **indexes, - ValueInternalArray::PageIndex indexCount ) - { - if ( indexes ) - free( indexes ); - } - - virtual Value *allocateArrayPage() - { - return static_cast<Value *>( malloc( sizeof(Value) * ValueInternalArray::itemsPerPage ) ); - } - - virtual void releaseArrayPage( Value *value ) - { - if ( value ) - free( value ); - } -}; - -#else // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -/// @todo make this thread-safe (lock when accessign batch allocator) -class DefaultValueArrayAllocator : public ValueArrayAllocator -{ -public: // overridden from ValueArrayAllocator - virtual ~DefaultValueArrayAllocator() - { - } - - virtual ValueInternalArray *newArray() - { - ValueInternalArray *array = arraysAllocator_.allocate(); - new (array) ValueInternalArray(); // placement new - return array; - } - - virtual ValueInternalArray *newArrayCopy( const ValueInternalArray &other ) - { - ValueInternalArray *array = arraysAllocator_.allocate(); - new (array) ValueInternalArray( other ); // placement new - return array; - } - - virtual void destructArray( ValueInternalArray *array ) - { - if ( array ) - { - array->~ValueInternalArray(); - arraysAllocator_.release( array ); - } - } - - virtual void reallocateArrayPageIndex( Value **&indexes, - ValueInternalArray::PageIndex &indexCount, - ValueInternalArray::PageIndex minNewIndexCount ) - { - ValueInternalArray::PageIndex newIndexCount = (indexCount*3)/2 + 1; - if ( minNewIndexCount > newIndexCount ) - newIndexCount = minNewIndexCount; - void *newIndexes = realloc( indexes, sizeof(Value*) * newIndexCount ); - if ( !newIndexes ) - throw std::bad_alloc(); - indexCount = newIndexCount; - indexes = static_cast<Value **>( newIndexes ); - } - virtual void releaseArrayPageIndex( Value **indexes, - ValueInternalArray::PageIndex indexCount ) - { - if ( indexes ) - free( indexes ); - } - - virtual Value *allocateArrayPage() - { - return static_cast<Value *>( pagesAllocator_.allocate() ); - } - - virtual void releaseArrayPage( Value *value ) - { - if ( value ) - pagesAllocator_.release( value ); - } -private: - BatchAllocator<ValueInternalArray,1> arraysAllocator_; - BatchAllocator<Value,ValueInternalArray::itemsPerPage> pagesAllocator_; -}; -#endif // #ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR - -static ValueArrayAllocator *&arrayAllocator() -{ - static DefaultValueArrayAllocator defaultAllocator; - static ValueArrayAllocator *arrayAllocator = &defaultAllocator; - return arrayAllocator; -} - -static struct DummyArrayAllocatorInitializer { - DummyArrayAllocatorInitializer() - { - arrayAllocator(); // ensure arrayAllocator() statics are initialized before main(). - } -} dummyArrayAllocatorInitializer; - -// ////////////////////////////////////////////////////////////////// -// class ValueInternalArray -// ////////////////////////////////////////////////////////////////// -bool -ValueInternalArray::equals( const IteratorState &x, - const IteratorState &other ) -{ - return x.array_ == other.array_ - && x.currentItemIndex_ == other.currentItemIndex_ - && x.currentPageIndex_ == other.currentPageIndex_; -} - - -void -ValueInternalArray::increment( IteratorState &it ) -{ - JSON_ASSERT_MESSAGE( it.array_ && - (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ - != it.array_->size_, - "ValueInternalArray::increment(): moving iterator beyond end" ); - ++(it.currentItemIndex_); - if ( it.currentItemIndex_ == itemsPerPage ) - { - it.currentItemIndex_ = 0; - ++(it.currentPageIndex_); - } -} - - -void -ValueInternalArray::decrement( IteratorState &it ) -{ - JSON_ASSERT_MESSAGE( it.array_ && it.currentPageIndex_ == it.array_->pages_ - && it.currentItemIndex_ == 0, - "ValueInternalArray::decrement(): moving iterator beyond end" ); - if ( it.currentItemIndex_ == 0 ) - { - it.currentItemIndex_ = itemsPerPage-1; - --(it.currentPageIndex_); - } - else - { - --(it.currentItemIndex_); - } -} - - -Value & -ValueInternalArray::unsafeDereference( const IteratorState &it ) -{ - return (*(it.currentPageIndex_))[it.currentItemIndex_]; -} - - -Value & -ValueInternalArray::dereference( const IteratorState &it ) -{ - JSON_ASSERT_MESSAGE( it.array_ && - (it.currentPageIndex_ - it.array_->pages_)*itemsPerPage + it.currentItemIndex_ - < it.array_->size_, - "ValueInternalArray::dereference(): dereferencing invalid iterator" ); - return unsafeDereference( it ); -} - -void -ValueInternalArray::makeBeginIterator( IteratorState &it ) const -{ - it.array_ = const_cast<ValueInternalArray *>( this ); - it.currentItemIndex_ = 0; - it.currentPageIndex_ = pages_; -} - - -void -ValueInternalArray::makeIterator( IteratorState &it, ArrayIndex index ) const -{ - it.array_ = const_cast<ValueInternalArray *>( this ); - it.currentItemIndex_ = index % itemsPerPage; - it.currentPageIndex_ = pages_ + index / itemsPerPage; -} - - -void -ValueInternalArray::makeEndIterator( IteratorState &it ) const -{ - makeIterator( it, size_ ); -} - - -ValueInternalArray::ValueInternalArray() - : pages_( 0 ) - , size_( 0 ) - , pageCount_( 0 ) -{ -} - - -ValueInternalArray::ValueInternalArray( const ValueInternalArray &other ) - : pages_( 0 ) - , pageCount_( 0 ) - , size_( other.size_ ) -{ - PageIndex minNewPages = other.size_ / itemsPerPage; - arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); - JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, - "ValueInternalArray::reserve(): bad reallocation" ); - IteratorState itOther; - other.makeBeginIterator( itOther ); - Value *value; - for ( ArrayIndex index = 0; index < size_; ++index, increment(itOther) ) - { - if ( index % itemsPerPage == 0 ) - { - PageIndex pageIndex = index / itemsPerPage; - value = arrayAllocator()->allocateArrayPage(); - pages_[pageIndex] = value; - } - new (value) Value( dereference( itOther ) ); - } -} - - -ValueInternalArray & -ValueInternalArray::operator =( const ValueInternalArray &other ) -{ - ValueInternalArray temp( other ); - swap( temp ); - return *this; -} - - -ValueInternalArray::~ValueInternalArray() -{ - // destroy all constructed items - IteratorState it; - IteratorState itEnd; - makeBeginIterator( it); - makeEndIterator( itEnd ); - for ( ; !equals(it,itEnd); increment(it) ) - { - Value *value = &dereference(it); - value->~Value(); - } - // release all pages - PageIndex lastPageIndex = size_ / itemsPerPage; - for ( PageIndex pageIndex = 0; pageIndex < lastPageIndex; ++pageIndex ) - arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); - // release pages index - arrayAllocator()->releaseArrayPageIndex( pages_, pageCount_ ); -} - - -void -ValueInternalArray::swap( ValueInternalArray &other ) -{ - Value **tempPages = pages_; - pages_ = other.pages_; - other.pages_ = tempPages; - ArrayIndex tempSize = size_; - size_ = other.size_; - other.size_ = tempSize; - PageIndex tempPageCount = pageCount_; - pageCount_ = other.pageCount_; - other.pageCount_ = tempPageCount; -} - -void -ValueInternalArray::clear() -{ - ValueInternalArray dummy; - swap( dummy ); -} - - -void -ValueInternalArray::resize( ArrayIndex newSize ) -{ - if ( newSize == 0 ) - clear(); - else if ( newSize < size_ ) - { - IteratorState it; - IteratorState itEnd; - makeIterator( it, newSize ); - makeIterator( itEnd, size_ ); - for ( ; !equals(it,itEnd); increment(it) ) - { - Value *value = &dereference(it); - value->~Value(); - } - PageIndex pageIndex = (newSize + itemsPerPage - 1) / itemsPerPage; - PageIndex lastPageIndex = size_ / itemsPerPage; - for ( ; pageIndex < lastPageIndex; ++pageIndex ) - arrayAllocator()->releaseArrayPage( pages_[pageIndex] ); - size_ = newSize; - } - else if ( newSize > size_ ) - resolveReference( newSize ); -} - - -void -ValueInternalArray::makeIndexValid( ArrayIndex index ) -{ - // Need to enlarge page index ? - if ( index >= pageCount_ * itemsPerPage ) - { - PageIndex minNewPages = (index + 1) / itemsPerPage; - arrayAllocator()->reallocateArrayPageIndex( pages_, pageCount_, minNewPages ); - JSON_ASSERT_MESSAGE( pageCount_ >= minNewPages, "ValueInternalArray::reserve(): bad reallocation" ); - } - - // Need to allocate new pages ? - ArrayIndex nextPageIndex = - (size_ % itemsPerPage) != 0 ? size_ - (size_%itemsPerPage) + itemsPerPage - : size_; - if ( nextPageIndex <= index ) - { - PageIndex pageIndex = nextPageIndex / itemsPerPage; - PageIndex pageToAllocate = (index - nextPageIndex) / itemsPerPage + 1; - for ( ; pageToAllocate-- > 0; ++pageIndex ) - pages_[pageIndex] = arrayAllocator()->allocateArrayPage(); - } - - // Initialize all new entries - IteratorState it; - IteratorState itEnd; - makeIterator( it, size_ ); - size_ = index + 1; - makeIterator( itEnd, size_ ); - for ( ; !equals(it,itEnd); increment(it) ) - { - Value *value = &dereference(it); - new (value) Value(); // Construct a default value using placement new - } -} - -Value & -ValueInternalArray::resolveReference( ArrayIndex index ) -{ - if ( index >= size_ ) - makeIndexValid( index ); - return pages_[index/itemsPerPage][index%itemsPerPage]; -} - -Value * -ValueInternalArray::find( ArrayIndex index ) const -{ - if ( index >= size_ ) - return 0; - return &(pages_[index/itemsPerPage][index%itemsPerPage]); -} - -ValueInternalArray::ArrayIndex -ValueInternalArray::size() const -{ - return size_; -} - -int -ValueInternalArray::distance( const IteratorState &x, const IteratorState &y ) -{ - return indexOf(y) - indexOf(x); -} - - -ValueInternalArray::ArrayIndex -ValueInternalArray::indexOf( const IteratorState &iterator ) -{ - if ( !iterator.array_ ) - return ArrayIndex(-1); - return ArrayIndex( - (iterator.currentPageIndex_ - iterator.array_->pages_) * itemsPerPage - + iterator.currentItemIndex_ ); -} - - -int -ValueInternalArray::compare( const ValueInternalArray &other ) const -{ - int sizeDiff( size_ - other.size_ ); - if ( sizeDiff != 0 ) - return sizeDiff; - - for ( ArrayIndex index =0; index < size_; ++index ) - { - int diff = pages_[index/itemsPerPage][index%itemsPerPage].compare( - other.pages_[index/itemsPerPage][index%itemsPerPage] ); - if ( diff != 0 ) - return diff; - } - return 0; -} diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_internalmap.inl b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_internalmap.inl deleted file mode 100644 index 19771488..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_internalmap.inl +++ /dev/null @@ -1,607 +0,0 @@ -// included by json_value.cpp -// everything is within Json namespace - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueInternalMap -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -/** \internal MUST be safely initialized using memset( this, 0, sizeof(ValueInternalLink) ); - * This optimization is used by the fast allocator. - */ -ValueInternalLink::ValueInternalLink() - : previous_( 0 ) - , next_( 0 ) -{ -} - -ValueInternalLink::~ValueInternalLink() -{ - for ( int index =0; index < itemPerLink; ++index ) - { - if ( !items_[index].isItemAvailable() ) - { - if ( !items_[index].isMemberNameStatic() ) - free( keys_[index] ); - } - else - break; - } -} - - - -ValueMapAllocator::~ValueMapAllocator() -{ -} - -#ifdef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -class DefaultValueMapAllocator : public ValueMapAllocator -{ -public: // overridden from ValueMapAllocator - virtual ValueInternalMap *newMap() - { - return new ValueInternalMap(); - } - - virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) - { - return new ValueInternalMap( other ); - } - - virtual void destructMap( ValueInternalMap *map ) - { - delete map; - } - - virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) - { - return new ValueInternalLink[size]; - } - - virtual void releaseMapBuckets( ValueInternalLink *links ) - { - delete [] links; - } - - virtual ValueInternalLink *allocateMapLink() - { - return new ValueInternalLink(); - } - - virtual void releaseMapLink( ValueInternalLink *link ) - { - delete link; - } -}; -#else -/// @todo make this thread-safe (lock when accessign batch allocator) -class DefaultValueMapAllocator : public ValueMapAllocator -{ -public: // overridden from ValueMapAllocator - virtual ValueInternalMap *newMap() - { - ValueInternalMap *map = mapsAllocator_.allocate(); - new (map) ValueInternalMap(); // placement new - return map; - } - - virtual ValueInternalMap *newMapCopy( const ValueInternalMap &other ) - { - ValueInternalMap *map = mapsAllocator_.allocate(); - new (map) ValueInternalMap( other ); // placement new - return map; - } - - virtual void destructMap( ValueInternalMap *map ) - { - if ( map ) - { - map->~ValueInternalMap(); - mapsAllocator_.release( map ); - } - } - - virtual ValueInternalLink *allocateMapBuckets( unsigned int size ) - { - return new ValueInternalLink[size]; - } - - virtual void releaseMapBuckets( ValueInternalLink *links ) - { - delete [] links; - } - - virtual ValueInternalLink *allocateMapLink() - { - ValueInternalLink *link = linksAllocator_.allocate(); - memset( link, 0, sizeof(ValueInternalLink) ); - return link; - } - - virtual void releaseMapLink( ValueInternalLink *link ) - { - link->~ValueInternalLink(); - linksAllocator_.release( link ); - } -private: - BatchAllocator<ValueInternalMap,1> mapsAllocator_; - BatchAllocator<ValueInternalLink,1> linksAllocator_; -}; -#endif - -static ValueMapAllocator *&mapAllocator() -{ - static DefaultValueMapAllocator defaultAllocator; - static ValueMapAllocator *mapAllocator = &defaultAllocator; - return mapAllocator; -} - -static struct DummyMapAllocatorInitializer { - DummyMapAllocatorInitializer() - { - mapAllocator(); // ensure mapAllocator() statics are initialized before main(). - } -} dummyMapAllocatorInitializer; - - - -// h(K) = value * K >> w ; with w = 32 & K prime w.r.t. 2^32. - -/* -use linked list hash map. -buckets array is a container. -linked list element contains 6 key/values. (memory = (16+4) * 6 + 4 = 124) -value have extra state: valid, available, deleted -*/ - - -ValueInternalMap::ValueInternalMap() - : buckets_( 0 ) - , tailLink_( 0 ) - , bucketsSize_( 0 ) - , itemCount_( 0 ) -{ -} - - -ValueInternalMap::ValueInternalMap( const ValueInternalMap &other ) - : buckets_( 0 ) - , tailLink_( 0 ) - , bucketsSize_( 0 ) - , itemCount_( 0 ) -{ - reserve( other.itemCount_ ); - IteratorState it; - IteratorState itEnd; - other.makeBeginIterator( it ); - other.makeEndIterator( itEnd ); - for ( ; !equals(it,itEnd); increment(it) ) - { - bool isStatic; - const char *memberName = key( it, isStatic ); - const Value &aValue = value( it ); - resolveReference(memberName, isStatic) = aValue; - } -} - - -ValueInternalMap & -ValueInternalMap::operator =( const ValueInternalMap &other ) -{ - ValueInternalMap dummy( other ); - swap( dummy ); - return *this; -} - - -ValueInternalMap::~ValueInternalMap() -{ - if ( buckets_ ) - { - for ( BucketIndex bucketIndex =0; bucketIndex < bucketsSize_; ++bucketIndex ) - { - ValueInternalLink *link = buckets_[bucketIndex].next_; - while ( link ) - { - ValueInternalLink *linkToRelease = link; - link = link->next_; - mapAllocator()->releaseMapLink( linkToRelease ); - } - } - mapAllocator()->releaseMapBuckets( buckets_ ); - } -} - - -void -ValueInternalMap::swap( ValueInternalMap &other ) -{ - ValueInternalLink *tempBuckets = buckets_; - buckets_ = other.buckets_; - other.buckets_ = tempBuckets; - ValueInternalLink *tempTailLink = tailLink_; - tailLink_ = other.tailLink_; - other.tailLink_ = tempTailLink; - BucketIndex tempBucketsSize = bucketsSize_; - bucketsSize_ = other.bucketsSize_; - other.bucketsSize_ = tempBucketsSize; - BucketIndex tempItemCount = itemCount_; - itemCount_ = other.itemCount_; - other.itemCount_ = tempItemCount; -} - - -void -ValueInternalMap::clear() -{ - ValueInternalMap dummy; - swap( dummy ); -} - - -ValueInternalMap::BucketIndex -ValueInternalMap::size() const -{ - return itemCount_; -} - -bool -ValueInternalMap::reserveDelta( BucketIndex growth ) -{ - return reserve( itemCount_ + growth ); -} - -bool -ValueInternalMap::reserve( BucketIndex newItemCount ) -{ - if ( !buckets_ && newItemCount > 0 ) - { - buckets_ = mapAllocator()->allocateMapBuckets( 1 ); - bucketsSize_ = 1; - tailLink_ = &buckets_[0]; - } -// BucketIndex idealBucketCount = (newItemCount + ValueInternalLink::itemPerLink) / ValueInternalLink::itemPerLink; - return true; -} - - -const Value * -ValueInternalMap::find( const char *key ) const -{ - if ( !bucketsSize_ ) - return 0; - HashKey hashedKey = hash( key ); - BucketIndex bucketIndex = hashedKey % bucketsSize_; - for ( const ValueInternalLink *current = &buckets_[bucketIndex]; - current != 0; - current = current->next_ ) - { - for ( BucketIndex index=0; index < ValueInternalLink::itemPerLink; ++index ) - { - if ( current->items_[index].isItemAvailable() ) - return 0; - if ( strcmp( key, current->keys_[index] ) == 0 ) - return ¤t->items_[index]; - } - } - return 0; -} - - -Value * -ValueInternalMap::find( const char *key ) -{ - const ValueInternalMap *constThis = this; - return const_cast<Value *>( constThis->find( key ) ); -} - - -Value & -ValueInternalMap::resolveReference( const char *key, - bool isStatic ) -{ - HashKey hashedKey = hash( key ); - if ( bucketsSize_ ) - { - BucketIndex bucketIndex = hashedKey % bucketsSize_; - ValueInternalLink **previous = 0; - BucketIndex index; - for ( ValueInternalLink *current = &buckets_[bucketIndex]; - current != 0; - previous = ¤t->next_, current = current->next_ ) - { - for ( index=0; index < ValueInternalLink::itemPerLink; ++index ) - { - if ( current->items_[index].isItemAvailable() ) - return setNewItem( key, isStatic, current, index ); - if ( strcmp( key, current->keys_[index] ) == 0 ) - return current->items_[index]; - } - } - } - - reserveDelta( 1 ); - return unsafeAdd( key, isStatic, hashedKey ); -} - - -void -ValueInternalMap::remove( const char *key ) -{ - HashKey hashedKey = hash( key ); - if ( !bucketsSize_ ) - return; - BucketIndex bucketIndex = hashedKey % bucketsSize_; - for ( ValueInternalLink *link = &buckets_[bucketIndex]; - link != 0; - link = link->next_ ) - { - BucketIndex index; - for ( index =0; index < ValueInternalLink::itemPerLink; ++index ) - { - if ( link->items_[index].isItemAvailable() ) - return; - if ( strcmp( key, link->keys_[index] ) == 0 ) - { - doActualRemove( link, index, bucketIndex ); - return; - } - } - } -} - -void -ValueInternalMap::doActualRemove( ValueInternalLink *link, - BucketIndex index, - BucketIndex bucketIndex ) -{ - // find last item of the bucket and swap it with the 'removed' one. - // set removed items flags to 'available'. - // if last page only contains 'available' items, then desallocate it (it's empty) - ValueInternalLink *&lastLink = getLastLinkInBucket( index ); - BucketIndex lastItemIndex = 1; // a link can never be empty, so start at 1 - for ( ; - lastItemIndex < ValueInternalLink::itemPerLink; - ++lastItemIndex ) // may be optimized with dicotomic search - { - if ( lastLink->items_[lastItemIndex].isItemAvailable() ) - break; - } - - BucketIndex lastUsedIndex = lastItemIndex - 1; - Value *valueToDelete = &link->items_[index]; - Value *valueToPreserve = &lastLink->items_[lastUsedIndex]; - if ( valueToDelete != valueToPreserve ) - valueToDelete->swap( *valueToPreserve ); - if ( lastUsedIndex == 0 ) // page is now empty - { // remove it from bucket linked list and delete it. - ValueInternalLink *linkPreviousToLast = lastLink->previous_; - if ( linkPreviousToLast != 0 ) // can not deleted bucket link. - { - mapAllocator()->releaseMapLink( lastLink ); - linkPreviousToLast->next_ = 0; - lastLink = linkPreviousToLast; - } - } - else - { - Value dummy; - valueToPreserve->swap( dummy ); // restore deleted to default Value. - valueToPreserve->setItemUsed( false ); - } - --itemCount_; -} - - -ValueInternalLink *& -ValueInternalMap::getLastLinkInBucket( BucketIndex bucketIndex ) -{ - if ( bucketIndex == bucketsSize_ - 1 ) - return tailLink_; - ValueInternalLink *&previous = buckets_[bucketIndex+1].previous_; - if ( !previous ) - previous = &buckets_[bucketIndex]; - return previous; -} - - -Value & -ValueInternalMap::setNewItem( const char *key, - bool isStatic, - ValueInternalLink *link, - BucketIndex index ) -{ - char *duplicatedKey = valueAllocator()->makeMemberName( key ); - ++itemCount_; - link->keys_[index] = duplicatedKey; - link->items_[index].setItemUsed(); - link->items_[index].setMemberNameIsStatic( isStatic ); - return link->items_[index]; // items already default constructed. -} - - -Value & -ValueInternalMap::unsafeAdd( const char *key, - bool isStatic, - HashKey hashedKey ) -{ - JSON_ASSERT_MESSAGE( bucketsSize_ > 0, "ValueInternalMap::unsafeAdd(): internal logic error." ); - BucketIndex bucketIndex = hashedKey % bucketsSize_; - ValueInternalLink *&previousLink = getLastLinkInBucket( bucketIndex ); - ValueInternalLink *link = previousLink; - BucketIndex index; - for ( index =0; index < ValueInternalLink::itemPerLink; ++index ) - { - if ( link->items_[index].isItemAvailable() ) - break; - } - if ( index == ValueInternalLink::itemPerLink ) // need to add a new page - { - ValueInternalLink *newLink = mapAllocator()->allocateMapLink(); - index = 0; - link->next_ = newLink; - previousLink = newLink; - link = newLink; - } - return setNewItem( key, isStatic, link, index ); -} - - -ValueInternalMap::HashKey -ValueInternalMap::hash( const char *key ) const -{ - HashKey hash = 0; - while ( *key ) - hash += *key++ * 37; - return hash; -} - - -int -ValueInternalMap::compare( const ValueInternalMap &other ) const -{ - int sizeDiff( itemCount_ - other.itemCount_ ); - if ( sizeDiff != 0 ) - return sizeDiff; - // Strict order guaranty is required. Compare all keys FIRST, then compare values. - IteratorState it; - IteratorState itEnd; - makeBeginIterator( it ); - makeEndIterator( itEnd ); - for ( ; !equals(it,itEnd); increment(it) ) - { - if ( !other.find( key( it ) ) ) - return 1; - } - - // All keys are equals, let's compare values - makeBeginIterator( it ); - for ( ; !equals(it,itEnd); increment(it) ) - { - const Value *otherValue = other.find( key( it ) ); - int valueDiff = value(it).compare( *otherValue ); - if ( valueDiff != 0 ) - return valueDiff; - } - return 0; -} - - -void -ValueInternalMap::makeBeginIterator( IteratorState &it ) const -{ - it.map_ = const_cast<ValueInternalMap *>( this ); - it.bucketIndex_ = 0; - it.itemIndex_ = 0; - it.link_ = buckets_; -} - - -void -ValueInternalMap::makeEndIterator( IteratorState &it ) const -{ - it.map_ = const_cast<ValueInternalMap *>( this ); - it.bucketIndex_ = bucketsSize_; - it.itemIndex_ = 0; - it.link_ = 0; -} - - -bool -ValueInternalMap::equals( const IteratorState &x, const IteratorState &other ) -{ - return x.map_ == other.map_ - && x.bucketIndex_ == other.bucketIndex_ - && x.link_ == other.link_ - && x.itemIndex_ == other.itemIndex_; -} - - -void -ValueInternalMap::incrementBucket( IteratorState &iterator ) -{ - ++iterator.bucketIndex_; - JSON_ASSERT_MESSAGE( iterator.bucketIndex_ <= iterator.map_->bucketsSize_, - "ValueInternalMap::increment(): attempting to iterate beyond end." ); - if ( iterator.bucketIndex_ == iterator.map_->bucketsSize_ ) - iterator.link_ = 0; - else - iterator.link_ = &(iterator.map_->buckets_[iterator.bucketIndex_]); - iterator.itemIndex_ = 0; -} - - -void -ValueInternalMap::increment( IteratorState &iterator ) -{ - JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterator using invalid iterator." ); - ++iterator.itemIndex_; - if ( iterator.itemIndex_ == ValueInternalLink::itemPerLink ) - { - JSON_ASSERT_MESSAGE( iterator.link_ != 0, - "ValueInternalMap::increment(): attempting to iterate beyond end." ); - iterator.link_ = iterator.link_->next_; - if ( iterator.link_ == 0 ) - incrementBucket( iterator ); - } - else if ( iterator.link_->items_[iterator.itemIndex_].isItemAvailable() ) - { - incrementBucket( iterator ); - } -} - - -void -ValueInternalMap::decrement( IteratorState &iterator ) -{ - if ( iterator.itemIndex_ == 0 ) - { - JSON_ASSERT_MESSAGE( iterator.map_, "Attempting to iterate using invalid iterator." ); - if ( iterator.link_ == &iterator.map_->buckets_[iterator.bucketIndex_] ) - { - JSON_ASSERT_MESSAGE( iterator.bucketIndex_ > 0, "Attempting to iterate beyond beginning." ); - --(iterator.bucketIndex_); - } - iterator.link_ = iterator.link_->previous_; - iterator.itemIndex_ = ValueInternalLink::itemPerLink - 1; - } -} - - -const char * -ValueInternalMap::key( const IteratorState &iterator ) -{ - JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); - return iterator.link_->keys_[iterator.itemIndex_]; -} - -const char * -ValueInternalMap::key( const IteratorState &iterator, bool &isStatic ) -{ - JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); - isStatic = iterator.link_->items_[iterator.itemIndex_].isMemberNameStatic(); - return iterator.link_->keys_[iterator.itemIndex_]; -} - - -Value & -ValueInternalMap::value( const IteratorState &iterator ) -{ - JSON_ASSERT_MESSAGE( iterator.link_, "Attempting to iterate using invalid iterator." ); - return iterator.link_->items_[iterator.itemIndex_]; -} - - -int -ValueInternalMap::distance( const IteratorState &x, const IteratorState &y ) -{ - int offset = 0; - IteratorState it = x; - while ( !equals( it, y ) ) - increment( it ); - return offset; -} diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_reader.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_reader.cpp deleted file mode 100644 index 5af16c8d..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_reader.cpp +++ /dev/null @@ -1,892 +0,0 @@ -#include <json/reader.h> -#include <json/value.h> -#include <utility> -#include <cstdio> -#include <cassert> -#include <cstring> -#include <iostream> -#include <stdexcept> - -#if _MSC_VER >= 1400 // VC++ 8.0 -#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. -#endif - -namespace Json { - -// QNX is strict about declaring C symbols in the std namespace. -#ifdef __QNXNTO__ -using std::memcpy; -using std::sprintf; -using std::sscanf; -#endif - -// Implementation of class Features -// //////////////////////////////// - -Features::Features() - : allowComments_( true ) - , strictRoot_( false ) -{ -} - - -Features -Features::all() -{ - return Features(); -} - - -Features -Features::strictMode() -{ - Features features; - features.allowComments_ = false; - features.strictRoot_ = true; - return features; -} - -// Implementation of class Reader -// //////////////////////////////// - - -static inline bool -in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4 ) -{ - return c == c1 || c == c2 || c == c3 || c == c4; -} - -static inline bool -in( Reader::Char c, Reader::Char c1, Reader::Char c2, Reader::Char c3, Reader::Char c4, Reader::Char c5 ) -{ - return c == c1 || c == c2 || c == c3 || c == c4 || c == c5; -} - - -static bool -containsNewLine( Reader::Location begin, - Reader::Location end ) -{ - for ( ;begin < end; ++begin ) - if ( *begin == '\n' || *begin == '\r' ) - return true; - return false; -} - -static std::string codePointToUTF8(unsigned int cp) -{ - std::string result; - - // based on description from http://en.wikipedia.org/wiki/UTF-8 - - if (cp <= 0x7f) - { - result.resize(1); - result[0] = static_cast<char>(cp); - } - else if (cp <= 0x7FF) - { - result.resize(2); - result[1] = static_cast<char>(0x80 | (0x3f & cp)); - result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6))); - } - else if (cp <= 0xFFFF) - { - result.resize(3); - result[2] = static_cast<char>(0x80 | (0x3f & cp)); - result[1] = 0x80 | static_cast<char>((0x3f & (cp >> 6))); - result[0] = 0xE0 | static_cast<char>((0xf & (cp >> 12))); - } - else if (cp <= 0x10FFFF) - { - result.resize(4); - result[3] = static_cast<char>(0x80 | (0x3f & cp)); - result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6))); - result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12))); - result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18))); - } - - return result; -} - - -// Class Reader -// ////////////////////////////////////////////////////////////////// - -Reader::Reader() - : features_( Features::all() ) -{ -} - - -Reader::Reader( const Features &features ) - : features_( features ) -{ -} - - -bool -Reader::parse( const std::string &document, - Value &root, - bool collectComments ) -{ - document_ = document; - const char *begin = document_.c_str(); - const char *end = begin + document_.length(); - return parse( begin, end, root, collectComments ); -} - - -bool -Reader::parse( std::istream& sin, - Value &root, - bool collectComments ) -{ - //std::istream_iterator<char> begin(sin); - //std::istream_iterator<char> end; - // Those would allow streamed input from a file, if parse() were a - // template function. - - // Since std::string is reference-counted, this at least does not - // create an extra copy. - std::string doc; - std::getline(sin, doc, (char)EOF); - return parse( doc, root, collectComments ); -} - -bool -Reader::parse( const char *beginDoc, const char *endDoc, - Value &root, - bool collectComments ) -{ - if ( !features_.allowComments_ ) - { - collectComments = false; - } - - begin_ = beginDoc; - end_ = endDoc; - collectComments_ = collectComments; - current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; - commentsBefore_ = ""; - errors_.clear(); - while ( !nodes_.empty() ) - nodes_.pop(); - nodes_.push( &root ); - - bool successful = readValue(); - Token token; - skipCommentTokens( token ); - if ( collectComments_ && !commentsBefore_.empty() ) - root.setComment( commentsBefore_, commentAfter ); - if ( features_.strictRoot_ ) - { - if ( !root.isArray() && !root.isObject() ) - { - // Set error location to start of doc, ideally should be first token found in doc - token.type_ = tokenError; - token.start_ = beginDoc; - token.end_ = endDoc; - addError( "A valid JSON document must be either an array or an object value.", - token ); - return false; - } - } - return successful; -} - - -bool -Reader::readValue() -{ - Token token; - skipCommentTokens( token ); - bool successful = true; - - if ( collectComments_ && !commentsBefore_.empty() ) - { - currentValue().setComment( commentsBefore_, commentBefore ); - commentsBefore_ = ""; - } - - - switch ( token.type_ ) - { - case tokenObjectBegin: - successful = readObject( token ); - break; - case tokenArrayBegin: - successful = readArray( token ); - break; - case tokenNumber: - successful = decodeNumber( token ); - break; - case tokenString: - successful = decodeString( token ); - break; - case tokenTrue: - currentValue() = true; - break; - case tokenFalse: - currentValue() = false; - break; - case tokenNull: - currentValue() = Value(); - break; - default: - return addError( "Syntax error: value, object or array expected.", token ); - } - - if ( collectComments_ ) - { - lastValueEnd_ = current_; - lastValue_ = ¤tValue(); - } - - return successful; -} - - -void -Reader::skipCommentTokens( Token &token ) -{ - if ( features_.allowComments_ ) - { - do - { - readToken( token ); - } - while ( token.type_ == tokenComment ); - } - else - { - readToken( token ); - } -} - - -bool -Reader::expectToken( TokenType type, Token &token, const char *message ) -{ - readToken( token ); - if ( token.type_ != type ) - return addError( message, token ); - return true; -} - - -bool -Reader::readToken( Token &token ) -{ - skipSpaces(); - token.start_ = current_; - Char c = getNextChar(); - bool ok = true; - switch ( c ) - { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = readString(); - break; - case '/': - token.type_ = tokenComment; - ok = readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - token.type_ = tokenNumber; - readNumber(); - break; - case 't': - token.type_ = tokenTrue; - ok = match( "rue", 3 ); - break; - case 'f': - token.type_ = tokenFalse; - ok = match( "alse", 4 ); - break; - case 'n': - token.type_ = tokenNull; - ok = match( "ull", 3 ); - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: - ok = false; - break; - } - if ( !ok ) - token.type_ = tokenError; - token.end_ = current_; - return true; -} - - -void -Reader::skipSpaces() -{ - while ( current_ != end_ ) - { - Char c = *current_; - if ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ) - ++current_; - else - break; - } -} - - -bool -Reader::match( Location pattern, - int patternLength ) -{ - if ( end_ - current_ < patternLength ) - return false; - int index = patternLength; - while ( index-- ) - if ( current_[index] != pattern[index] ) - return false; - current_ += patternLength; - return true; -} - - -bool -Reader::readComment() -{ - Location commentBegin = current_ - 1; - Char c = getNextChar(); - bool successful = false; - if ( c == '*' ) - successful = readCStyleComment(); - else if ( c == '/' ) - successful = readCppStyleComment(); - if ( !successful ) - return false; - - if ( collectComments_ ) - { - CommentPlacement placement = commentBefore; - if ( lastValueEnd_ && !containsNewLine( lastValueEnd_, commentBegin ) ) - { - if ( c != '*' || !containsNewLine( commentBegin, current_ ) ) - placement = commentAfterOnSameLine; - } - - addComment( commentBegin, current_, placement ); - } - return true; -} - - -void -Reader::addComment( Location begin, - Location end, - CommentPlacement placement ) -{ - assert( collectComments_ ); - if ( placement == commentAfterOnSameLine ) - { - assert( lastValue_ != 0 ); - lastValue_->setComment( std::string( begin, end ), placement ); - } - else - { - if ( !commentsBefore_.empty() ) - commentsBefore_ += "\n"; - commentsBefore_ += std::string( begin, end ); - } -} - - -bool -Reader::readCStyleComment() -{ - while ( current_ != end_ ) - { - Char c = getNextChar(); - if ( c == '*' && *current_ == '/' ) - break; - } - return getNextChar() == '/'; -} - - -bool -Reader::readCppStyleComment() -{ - while ( current_ != end_ ) - { - Char c = getNextChar(); - if ( c == '\r' || c == '\n' ) - break; - } - return true; -} - - -void -Reader::readNumber() -{ - while ( current_ != end_ ) - { - if ( !(*current_ >= '0' && *current_ <= '9') && - !in( *current_, '.', 'e', 'E', '+', '-' ) ) - break; - ++current_; - } -} - -bool -Reader::readString() -{ - Char c = 0; - while ( current_ != end_ ) - { - c = getNextChar(); - if ( c == '\\' ) - getNextChar(); - else if ( c == '"' ) - break; - } - return c == '"'; -} - - -bool -Reader::readObject( Token &tokenStart ) -{ - Token tokenName; - std::string name; - currentValue() = Value( objectValue ); - while ( readToken( tokenName ) ) - { - bool initialTokenOk = true; - while ( tokenName.type_ == tokenComment && initialTokenOk ) - initialTokenOk = readToken( tokenName ); - if ( !initialTokenOk ) - break; - if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object - return true; - if ( tokenName.type_ != tokenString ) - break; - - name = ""; - if ( !decodeString( tokenName, name ) ) - return recoverFromError( tokenObjectEnd ); - - Token colon; - if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator ) - { - return addErrorAndRecover( "Missing ':' after object member name", - colon, - tokenObjectEnd ); - } - Value &value = currentValue()[ name ]; - nodes_.push( &value ); - bool ok = readValue(); - nodes_.pop(); - if ( !ok ) // error already set - return recoverFromError( tokenObjectEnd ); - - Token comma; - if ( !readToken( comma ) - || ( comma.type_ != tokenObjectEnd && - comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment ) ) - { - return addErrorAndRecover( "Missing ',' or '}' in object declaration", - comma, - tokenObjectEnd ); - } - bool finalizeTokenOk = true; - while ( comma.type_ == tokenComment && - finalizeTokenOk ) - finalizeTokenOk = readToken( comma ); - if ( comma.type_ == tokenObjectEnd ) - return true; - } - return addErrorAndRecover( "Missing '}' or object member name", - tokenName, - tokenObjectEnd ); -} - - -bool -Reader::readArray( Token &tokenStart ) -{ - currentValue() = Value( arrayValue ); - skipSpaces(); - if ( *current_ == ']' ) // empty array - { - Token endArray; - readToken( endArray ); - return true; - } - int index = 0; - while ( true ) - { - Value &value = currentValue()[ index++ ]; - nodes_.push( &value ); - bool ok = readValue(); - nodes_.pop(); - if ( !ok ) // error already set - return recoverFromError( tokenArrayEnd ); - - Token token; - // Accept Comment after last item in the array. - ok = readToken( token ); - while ( token.type_ == tokenComment && ok ) - { - ok = readToken( token ); - } - bool badTokenType = ( token.type_ == tokenArraySeparator && - token.type_ == tokenArrayEnd ); - if ( !ok || badTokenType ) - { - return addErrorAndRecover( "Missing ',' or ']' in array declaration", - token, - tokenArrayEnd ); - } - if ( token.type_ == tokenArrayEnd ) - break; - } - return true; -} - - -bool -Reader::decodeNumber( Token &token ) -{ - bool isDouble = false; - for ( Location inspect = token.start_; inspect != token.end_; ++inspect ) - { - isDouble = isDouble - || in( *inspect, '.', 'e', 'E', '+' ) - || ( *inspect == '-' && inspect != token.start_ ); - } - if ( isDouble ) - return decodeDouble( token ); - Location current = token.start_; - bool isNegative = *current == '-'; - if ( isNegative ) - ++current; - Value::UInt threshold = (isNegative ? Value::UInt(-Value::minInt) - : Value::maxUInt) / 10; - Value::UInt value = 0; - while ( current < token.end_ ) - { - Char c = *current++; - if ( c < '0' || c > '9' ) - return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token ); - if ( value >= threshold ) - return decodeDouble( token ); - value = value * 10 + Value::UInt(c - '0'); - } - if ( isNegative ) - currentValue() = -Value::Int( value ); - else if ( value <= Value::UInt(Value::maxInt) ) - currentValue() = Value::Int( value ); - else - currentValue() = value; - return true; -} - - -bool -Reader::decodeDouble( Token &token ) -{ - double value = 0; - const int bufferSize = 32; - int count; - int length = int(token.end_ - token.start_); - if ( length <= bufferSize ) - { - Char buffer[bufferSize]; - memcpy( buffer, token.start_, length ); - buffer[length] = 0; - count = sscanf( buffer, "%lf", &value ); - } - else - { - std::string buffer( token.start_, token.end_ ); - count = sscanf( buffer.c_str(), "%lf", &value ); - } - - if ( count != 1 ) - return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token ); - currentValue() = value; - return true; -} - - -bool -Reader::decodeString( Token &token ) -{ - std::string decoded; - if ( !decodeString( token, decoded ) ) - return false; - currentValue() = decoded; - return true; -} - - -bool -Reader::decodeString( Token &token, std::string &decoded ) -{ - decoded.reserve( token.end_ - token.start_ - 2 ); - Location current = token.start_ + 1; // skip '"' - Location end = token.end_ - 1; // do not include '"' - while ( current != end ) - { - Char c = *current++; - if ( c == '"' ) - break; - else if ( c == '\\' ) - { - if ( current == end ) - return addError( "Empty escape sequence in string", token, current ); - Char escape = *current++; - switch ( escape ) - { - case '"': decoded += '"'; break; - case '/': decoded += '/'; break; - case '\\': decoded += '\\'; break; - case 'b': decoded += '\b'; break; - case 'f': decoded += '\f'; break; - case 'n': decoded += '\n'; break; - case 'r': decoded += '\r'; break; - case 't': decoded += '\t'; break; - case 'u': - { - unsigned int unicode; - if ( !decodeUnicodeCodePoint( token, current, end, unicode ) ) - return false; - decoded += codePointToUTF8(unicode); - } - break; - default: - return addError( "Bad escape sequence in string", token, current ); - } - } - else - { - decoded += c; - } - } - return true; -} - -bool -Reader::decodeUnicodeCodePoint( Token &token, - Location ¤t, - Location end, - unsigned int &unicode ) -{ - - if ( !decodeUnicodeEscapeSequence( token, current, end, unicode ) ) - return false; - if (unicode >= 0xD800 && unicode <= 0xDBFF) - { - // surrogate pairs - if (end - current < 6) - return addError( "additional six characters expected to parse unicode surrogate pair.", token, current ); - unsigned int surrogatePair; - if (*(current++) == '\\' && *(current++)== 'u') - { - if (decodeUnicodeEscapeSequence( token, current, end, surrogatePair )) - { - unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); - } - else - return false; - } - else - return addError( "expecting another \\u token to begin the second half of a unicode surrogate pair", token, current ); - } - return true; -} - -bool -Reader::decodeUnicodeEscapeSequence( Token &token, - Location ¤t, - Location end, - unsigned int &unicode ) -{ - if ( end - current < 4 ) - return addError( "Bad unicode escape sequence in string: four digits expected.", token, current ); - unicode = 0; - for ( int index =0; index < 4; ++index ) - { - Char c = *current++; - unicode *= 16; - if ( c >= '0' && c <= '9' ) - unicode += c - '0'; - else if ( c >= 'a' && c <= 'f' ) - unicode += c - 'a' + 10; - else if ( c >= 'A' && c <= 'F' ) - unicode += c - 'A' + 10; - else - return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", token, current ); - } - return true; -} - - -bool -Reader::addError( const std::string &message, - Token &token, - Location extra ) -{ - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = extra; - errors_.push_back( info ); - return false; -} - - -bool -Reader::recoverFromError( TokenType skipUntilToken ) -{ - int errorCount = int(errors_.size()); - Token skip; - while ( true ) - { - if ( !readToken(skip) ) - errors_.resize( errorCount ); // discard errors caused by recovery - if ( skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream ) - break; - } - errors_.resize( errorCount ); - return false; -} - - -bool -Reader::addErrorAndRecover( const std::string &message, - Token &token, - TokenType skipUntilToken ) -{ - addError( message, token ); - return recoverFromError( skipUntilToken ); -} - - -Value & -Reader::currentValue() -{ - return *(nodes_.top()); -} - - -Reader::Char -Reader::getNextChar() -{ - if ( current_ == end_ ) - return 0; - return *current_++; -} - - -void -Reader::getLocationLineAndColumn( Location location, - int &line, - int &column ) const -{ - Location current = begin_; - Location lastLineStart = current; - line = 0; - while ( current < location && current != end_ ) - { - Char c = *current++; - if ( c == '\r' ) - { - if ( *current == '\n' ) - ++current; - lastLineStart = current; - ++line; - } - else if ( c == '\n' ) - { - lastLineStart = current; - ++line; - } - } - // column & line start at 1 - column = int(location - lastLineStart) + 1; - ++line; -} - - -std::string -Reader::getLocationLineAndColumn( Location location ) const -{ - int line, column; - getLocationLineAndColumn( location, line, column ); - char buffer[18+16+16+1]; - sprintf( buffer, "Line %d, Column %d", line, column ); - return buffer; -} - - -std::string -Reader::getFormatedErrorMessages() const -{ - std::string formattedMessage; - for ( Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError ) - { - const ErrorInfo &error = *itError; - formattedMessage += "* " + getLocationLineAndColumn( error.token_.start_ ) + "\n"; - formattedMessage += " " + error.message_ + "\n"; - if ( error.extra_ ) - formattedMessage += "See " + getLocationLineAndColumn( error.extra_ ) + " for detail.\n"; - } - return formattedMessage; -} - - -std::istream& operator>>( std::istream &sin, Value &root ) -{ - Json::Reader reader; - bool ok = reader.parse(sin, root, true); - //JSON_ASSERT( ok ); - if (!ok) throw std::runtime_error(reader.getFormatedErrorMessages()); - return sin; -} - - -} // namespace Json diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_value.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_value.cpp deleted file mode 100644 index 6e5dcd3e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_value.cpp +++ /dev/null @@ -1,1726 +0,0 @@ -#include <iostream> -#include <json/value.h> -#include <json/writer.h> -#include <utility> -#include <stdexcept> -#include <cstring> -#include <cassert> -#ifdef JSON_USE_CPPTL -# include <cpptl/conststring.h> -#endif -#include <cstddef> // size_t -#ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR -# include "json_batchallocator.h" -#endif // #ifndef JSON_USE_SIMPLE_INTERNAL_ALLOCATOR - -#define JSON_ASSERT_UNREACHABLE assert( false ) -#define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw -#define JSON_ASSERT_MESSAGE( condition, message ) if (!( condition )) throw std::runtime_error( message ); - -namespace Json { - -// QNX is strict about declaring C symbols in the std namespace. -#ifdef __QNXNTO__ -using std::memcpy; -using std::strchr; -using std::strcmp; -using std::strlen; -#endif - -const Value Value::null; -const Int Value::minInt = Int( ~(UInt(-1)/2) ); -const Int Value::maxInt = Int( UInt(-1)/2 ); -const UInt Value::maxUInt = UInt(-1); - -// A "safe" implementation of strdup. Allow null pointer to be passed. -// Also avoid warning on msvc80. -// -//inline char *safeStringDup( const char *czstring ) -//{ -// if ( czstring ) -// { -// const size_t length = (unsigned int)( strlen(czstring) + 1 ); -// char *newString = static_cast<char *>( malloc( length ) ); -// memcpy( newString, czstring, length ); -// return newString; -// } -// return 0; -//} -// -//inline char *safeStringDup( const std::string &str ) -//{ -// if ( !str.empty() ) -// { -// const size_t length = str.length(); -// char *newString = static_cast<char *>( malloc( length + 1 ) ); -// memcpy( newString, str.c_str(), length ); -// newString[length] = 0; -// return newString; -// } -// return 0; -//} - -ValueAllocator::~ValueAllocator() -{ -} - -class DefaultValueAllocator : public ValueAllocator -{ -public: - virtual ~DefaultValueAllocator() - { - } - - virtual char *makeMemberName( const char *memberName ) - { - return duplicateStringValue( memberName ); - } - - virtual void releaseMemberName( char *memberName ) - { - releaseStringValue( memberName ); - } - - virtual char *duplicateStringValue( const char *value, - unsigned int length = unknown ) - { - //@todo invesgate this old optimization - //if ( !value || value[0] == 0 ) - // return 0; - - if ( length == unknown ) - length = (unsigned int)strlen(value); - char *newString = static_cast<char *>( malloc( length + 1 ) ); - memcpy( newString, value, length ); - newString[length] = 0; - return newString; - } - - virtual void releaseStringValue( char *value ) - { - if ( value ) - free( value ); - } -}; - -static ValueAllocator *&valueAllocator() -{ - static DefaultValueAllocator defaultAllocator; - static ValueAllocator *valueAllocator = &defaultAllocator; - return valueAllocator; -} - -static struct DummyValueAllocatorInitializer { - DummyValueAllocatorInitializer() - { - valueAllocator(); // ensure valueAllocator() statics are initialized before main(). - } -} dummyValueAllocatorInitializer; - - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ValueInternals... -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -#ifdef JSON_VALUE_USE_INTERNAL_MAP -# include "json_internalarray.inl" -# include "json_internalmap.inl" -#endif // JSON_VALUE_USE_INTERNAL_MAP - -# include "json_valueiterator.inl" - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::CommentInfo -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - - -Value::CommentInfo::CommentInfo() - : comment_( 0 ) -{ -} - -Value::CommentInfo::~CommentInfo() -{ - if ( comment_ ) - valueAllocator()->releaseStringValue( comment_ ); -} - - -void -Value::CommentInfo::setComment( const char *text ) -{ - if ( comment_ ) - valueAllocator()->releaseStringValue( comment_ ); - JSON_ASSERT( text ); - JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /"); - // It seems that /**/ style comments are acceptable as well. - comment_ = valueAllocator()->duplicateStringValue( text ); -} - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::CZString -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -# ifndef JSON_VALUE_USE_INTERNAL_MAP - -// Notes: index_ indicates if the string was allocated when -// a string is stored. - -Value::CZString::CZString( int index ) - : cstr_( 0 ) - , index_( index ) -{ -} - -Value::CZString::CZString( const char *cstr, DuplicationPolicy allocate ) - : cstr_( allocate == duplicate ? valueAllocator()->makeMemberName(cstr) - : cstr ) - , index_( allocate ) -{ -} - -Value::CZString::CZString( const CZString &other ) -: cstr_( other.index_ != noDuplication && other.cstr_ != 0 - ? valueAllocator()->makeMemberName( other.cstr_ ) - : other.cstr_ ) - , index_( other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate) - : other.index_ ) -{ -} - -Value::CZString::~CZString() -{ - if ( cstr_ && index_ == duplicate ) - valueAllocator()->releaseMemberName( const_cast<char *>( cstr_ ) ); -} - -void -Value::CZString::swap( CZString &other ) -{ - std::swap( cstr_, other.cstr_ ); - std::swap( index_, other.index_ ); -} - -Value::CZString & -Value::CZString::operator =( const CZString &other ) -{ - CZString temp( other ); - swap( temp ); - return *this; -} - -bool -Value::CZString::operator<( const CZString &other ) const -{ - if ( cstr_ ) - return strcmp( cstr_, other.cstr_ ) < 0; - return index_ < other.index_; -} - -bool -Value::CZString::operator==( const CZString &other ) const -{ - if ( cstr_ ) - return strcmp( cstr_, other.cstr_ ) == 0; - return index_ == other.index_; -} - - -int -Value::CZString::index() const -{ - return index_; -} - - -const char * -Value::CZString::c_str() const -{ - return cstr_; -} - -bool -Value::CZString::isStaticString() const -{ - return index_ == noDuplication; -} - -#endif // ifndef JSON_VALUE_USE_INTERNAL_MAP - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::Value -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -/*! \internal Default constructor initialization must be equivalent to: - * memset( this, 0, sizeof(Value) ) - * This optimization is used in ValueInternalMap fast allocator. - */ -Value::Value( ValueType type ) - : type_( type ) - , allocated_( 0 ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - switch ( type ) - { - case nullValue: - break; - case intValue: - case uintValue: - value_.int_ = 0; - break; - case realValue: - value_.real_ = 0.0; - break; - case stringValue: - value_.string_ = 0; - break; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(); - break; -#else - case arrayValue: - value_.array_ = arrayAllocator()->newArray(); - break; - case objectValue: - value_.map_ = mapAllocator()->newMap(); - break; -#endif - case booleanValue: - value_.bool_ = false; - break; - default: - JSON_ASSERT_UNREACHABLE; - } -} - - -Value::Value( Int value ) - : type_( intValue ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.int_ = value; -} - - -Value::Value( UInt value ) - : type_( uintValue ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.uint_ = value; -} - -Value::Value( double value ) - : type_( realValue ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.real_ = value; -} - -Value::Value( const char *value ) - : type_( stringValue ) - , allocated_( true ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.string_ = valueAllocator()->duplicateStringValue( value ); -} - - -Value::Value( const char *beginValue, - const char *endValue ) - : type_( stringValue ) - , allocated_( true ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.string_ = valueAllocator()->duplicateStringValue( beginValue, - UInt(endValue - beginValue) ); -} - - -Value::Value( const std::string &value ) - : type_( stringValue ) - , allocated_( true ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.string_ = valueAllocator()->duplicateStringValue( value.c_str(), - (unsigned int)value.length() ); - -} - -Value::Value( const StaticString &value ) - : type_( stringValue ) - , allocated_( false ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.string_ = const_cast<char *>( value.c_str() ); -} - - -# ifdef JSON_USE_CPPTL -Value::Value( const CppTL::ConstString &value ) - : type_( stringValue ) - , allocated_( true ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.string_ = valueAllocator()->duplicateStringValue( value, value.length() ); -} -# endif - -Value::Value( bool value ) - : type_( booleanValue ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - value_.bool_ = value; -} - - -Value::Value( const Value &other ) - : type_( other.type_ ) - , comments_( 0 ) -# ifdef JSON_VALUE_USE_INTERNAL_MAP - , itemIsUsed_( 0 ) -#endif -{ - switch ( type_ ) - { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - value_ = other.value_; - break; - case stringValue: - if ( other.value_.string_ ) - { - value_.string_ = valueAllocator()->duplicateStringValue( other.value_.string_ ); - allocated_ = true; - } - else - value_.string_ = 0; - break; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues( *other.value_.map_ ); - break; -#else - case arrayValue: - value_.array_ = arrayAllocator()->newArrayCopy( *other.value_.array_ ); - break; - case objectValue: - value_.map_ = mapAllocator()->newMapCopy( *other.value_.map_ ); - break; -#endif - default: - JSON_ASSERT_UNREACHABLE; - } - if ( other.comments_ ) - { - comments_ = new CommentInfo[numberOfCommentPlacement]; - for ( int comment =0; comment < numberOfCommentPlacement; ++comment ) - { - const CommentInfo &otherComment = other.comments_[comment]; - if ( otherComment.comment_ ) - comments_[comment].setComment( otherComment.comment_ ); - } - } -} - - -Value::~Value() -{ - switch ( type_ ) - { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - break; - case stringValue: - if ( allocated_ ) - valueAllocator()->releaseStringValue( value_.string_ ); - break; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - case objectValue: - delete value_.map_; - break; -#else - case arrayValue: - arrayAllocator()->destructArray( value_.array_ ); - break; - case objectValue: - mapAllocator()->destructMap( value_.map_ ); - break; -#endif - default: - JSON_ASSERT_UNREACHABLE; - } - - if ( comments_ ) - delete[] comments_; -} - -Value & -Value::operator=( const Value &other ) -{ - Value temp( other ); - swap( temp ); - return *this; -} - -void -Value::swap( Value &other ) -{ - ValueType temp = type_; - type_ = other.type_; - other.type_ = temp; - std::swap( value_, other.value_ ); - int temp2 = allocated_; - allocated_ = other.allocated_; - other.allocated_ = temp2; -} - -ValueType -Value::type() const -{ - return type_; -} - - -int -Value::compare( const Value &other ) -{ - /* - int typeDelta = other.type_ - type_; - switch ( type_ ) - { - case nullValue: - - return other.type_ == type_; - case intValue: - if ( other.type_.isNumeric() - case uintValue: - case realValue: - case booleanValue: - break; - case stringValue, - break; - case arrayValue: - delete value_.array_; - break; - case objectValue: - delete value_.map_; - default: - JSON_ASSERT_UNREACHABLE; - } - */ - return 0; // unreachable -} - -bool -Value::operator <( const Value &other ) const -{ - int typeDelta = type_ - other.type_; - if ( typeDelta ) - return typeDelta < 0 ? true : false; - switch ( type_ ) - { - case nullValue: - return false; - case intValue: - return value_.int_ < other.value_.int_; - case uintValue: - return value_.uint_ < other.value_.uint_; - case realValue: - return value_.real_ < other.value_.real_; - case booleanValue: - return value_.bool_ < other.value_.bool_; - case stringValue: - return ( value_.string_ == 0 && other.value_.string_ ) - || ( other.value_.string_ - && value_.string_ - && strcmp( value_.string_, other.value_.string_ ) < 0 ); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - case objectValue: - { - int delta = int( value_.map_->size() - other.value_.map_->size() ); - if ( delta ) - return delta < 0; - return (*value_.map_) < (*other.value_.map_); - } -#else - case arrayValue: - return value_.array_->compare( *(other.value_.array_) ) < 0; - case objectValue: - return value_.map_->compare( *(other.value_.map_) ) < 0; -#endif - default: - JSON_ASSERT_UNREACHABLE; - } - return 0; // unreachable -} - -bool -Value::operator <=( const Value &other ) const -{ - return !(other > *this); -} - -bool -Value::operator >=( const Value &other ) const -{ - return !(*this < other); -} - -bool -Value::operator >( const Value &other ) const -{ - return other < *this; -} - -bool -Value::operator ==( const Value &other ) const -{ - //if ( type_ != other.type_ ) - // GCC 2.95.3 says: - // attempt to take address of bit-field structure member `Json::Value::type_' - // Beats me, but a temp solves the problem. - int temp = other.type_; - if ( type_ != temp ) - return false; - switch ( type_ ) - { - case nullValue: - return true; - case intValue: - return value_.int_ == other.value_.int_; - case uintValue: - return value_.uint_ == other.value_.uint_; - case realValue: - return value_.real_ == other.value_.real_; - case booleanValue: - return value_.bool_ == other.value_.bool_; - case stringValue: - return ( value_.string_ == other.value_.string_ ) - || ( other.value_.string_ - && value_.string_ - && strcmp( value_.string_, other.value_.string_ ) == 0 ); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - case objectValue: - return value_.map_->size() == other.value_.map_->size() - && (*value_.map_) == (*other.value_.map_); -#else - case arrayValue: - return value_.array_->compare( *(other.value_.array_) ) == 0; - case objectValue: - return value_.map_->compare( *(other.value_.map_) ) == 0; -#endif - default: - JSON_ASSERT_UNREACHABLE; - } - return 0; // unreachable -} - -bool -Value::operator !=( const Value &other ) const -{ - return !( *this == other ); -} - -const char * -Value::asCString() const -{ - JSON_ASSERT( type_ == stringValue ); - return value_.string_; -} - - -std::string -Value::asString() const -{ - switch ( type_ ) - { - case nullValue: - return ""; - case stringValue: - return value_.string_ ? value_.string_ : ""; - case booleanValue: - return value_.bool_ ? "true" : "false"; - case intValue: - case uintValue: - case realValue: - case arrayValue: - case objectValue: - JSON_ASSERT_MESSAGE( false, "Type is not convertible to string" ); - default: - JSON_ASSERT_UNREACHABLE; - } - return ""; // unreachable -} - -# ifdef JSON_USE_CPPTL -CppTL::ConstString -Value::asConstString() const -{ - return CppTL::ConstString( asString().c_str() ); -} -# endif - -Value::Int -Value::asInt() const -{ - switch ( type_ ) - { - case nullValue: - return 0; - case intValue: - return value_.int_; - case uintValue: - JSON_ASSERT_MESSAGE( value_.uint_ < (unsigned)maxInt, "integer out of signed integer range" ); - return value_.uint_; - case realValue: - JSON_ASSERT_MESSAGE( value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range" ); - return Int( value_.real_ ); - case booleanValue: - return value_.bool_ ? 1 : 0; - case stringValue: - case arrayValue: - case objectValue: - JSON_ASSERT_MESSAGE( false, "Type is not convertible to int" ); - default: - JSON_ASSERT_UNREACHABLE; - } - return 0; // unreachable; -} - -Value::UInt -Value::asUInt() const -{ - switch ( type_ ) - { - case nullValue: - return 0; - case intValue: - JSON_ASSERT_MESSAGE( value_.int_ >= 0, "Negative integer can not be converted to unsigned integer" ); - return value_.int_; - case uintValue: - return value_.uint_; - case realValue: - JSON_ASSERT_MESSAGE( value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range" ); - return UInt( value_.real_ ); - case booleanValue: - return value_.bool_ ? 1 : 0; - case stringValue: - case arrayValue: - case objectValue: - JSON_ASSERT_MESSAGE( false, "Type is not convertible to uint" ); - default: - JSON_ASSERT_UNREACHABLE; - } - return 0; // unreachable; -} - -double -Value::asDouble() const -{ - switch ( type_ ) - { - case nullValue: - return 0.0; - case intValue: - return value_.int_; - case uintValue: - return value_.uint_; - case realValue: - return value_.real_; - case booleanValue: - return value_.bool_ ? 1.0 : 0.0; - case stringValue: - case arrayValue: - case objectValue: - JSON_ASSERT_MESSAGE( false, "Type is not convertible to double" ); - default: - JSON_ASSERT_UNREACHABLE; - } - return 0; // unreachable; -} - -bool -Value::asBool() const -{ - switch ( type_ ) - { - case nullValue: - return false; - case intValue: - case uintValue: - return value_.int_ != 0; - case realValue: - return value_.real_ != 0.0; - case booleanValue: - return value_.bool_; - case stringValue: - return value_.string_ && value_.string_[0] != 0; - case arrayValue: - case objectValue: - return value_.map_->size() != 0; - default: - JSON_ASSERT_UNREACHABLE; - } - return false; // unreachable; -} - - -bool -Value::isConvertibleTo( ValueType other ) const -{ - switch ( type_ ) - { - case nullValue: - return true; - case intValue: - return ( other == nullValue && value_.int_ == 0 ) - || other == intValue - || ( other == uintValue && value_.int_ >= 0 ) - || other == realValue - || other == stringValue - || other == booleanValue; - case uintValue: - return ( other == nullValue && value_.uint_ == 0 ) - || ( other == intValue && value_.uint_ <= (unsigned)maxInt ) - || other == uintValue - || other == realValue - || other == stringValue - || other == booleanValue; - case realValue: - return ( other == nullValue && value_.real_ == 0.0 ) - || ( other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt ) - || ( other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt ) - || other == realValue - || other == stringValue - || other == booleanValue; - case booleanValue: - return ( other == nullValue && value_.bool_ == false ) - || other == intValue - || other == uintValue - || other == realValue - || other == stringValue - || other == booleanValue; - case stringValue: - return other == stringValue - || ( other == nullValue && (!value_.string_ || value_.string_[0] == 0) ); - case arrayValue: - return other == arrayValue - || ( other == nullValue && value_.map_->size() == 0 ); - case objectValue: - return other == objectValue - || ( other == nullValue && value_.map_->size() == 0 ); - default: - JSON_ASSERT_UNREACHABLE; - } - return false; // unreachable; -} - - -/// Number of values in array or object -Value::UInt -Value::size() const -{ - switch ( type_ ) - { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - case stringValue: - return 0; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: // size of the array is highest index + 1 - if ( !value_.map_->empty() ) - { - ObjectValues::const_iterator itLast = value_.map_->end(); - --itLast; - return (*itLast).first.index()+1; - } - return 0; - case objectValue: - return Int( value_.map_->size() ); -#else - case arrayValue: - return Int( value_.array_->size() ); - case objectValue: - return Int( value_.map_->size() ); -#endif - default: - JSON_ASSERT_UNREACHABLE; - } - return 0; // unreachable; -} - - -bool -Value::empty() const -{ - if ( isNull() || isArray() || isObject() ) - return size() == 0u; - else - return false; -} - - -bool -Value::operator!() const -{ - return isNull(); -} - - -void -Value::clear() -{ - JSON_ASSERT( type_ == nullValue || type_ == arrayValue || type_ == objectValue ); - - switch ( type_ ) - { -#ifndef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - case objectValue: - value_.map_->clear(); - break; -#else - case arrayValue: - value_.array_->clear(); - break; - case objectValue: - value_.map_->clear(); - break; -#endif - default: - break; - } -} - -void -Value::resize( UInt newSize ) -{ - JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); - if ( type_ == nullValue ) - *this = Value( arrayValue ); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - UInt oldSize = size(); - if ( newSize == 0 ) - clear(); - else if ( newSize > oldSize ) - (*this)[ newSize - 1 ]; - else - { - for ( UInt index = newSize; index < oldSize; ++index ) - value_.map_->erase( index ); - assert( size() == newSize ); - } -#else - value_.array_->resize( newSize ); -#endif -} - - -Value & -Value::operator[]( UInt index ) -{ - JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); - if ( type_ == nullValue ) - *this = Value( arrayValue ); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - CZString key( index ); - ObjectValues::iterator it = value_.map_->lower_bound( key ); - if ( it != value_.map_->end() && (*it).first == key ) - return (*it).second; - - ObjectValues::value_type defaultValue( key, null ); - it = value_.map_->insert( it, defaultValue ); - return (*it).second; -#else - return value_.array_->resolveReference( index ); -#endif -} - - -const Value & -Value::operator[]( UInt index ) const -{ - JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); - if ( type_ == nullValue ) - return null; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - CZString key( index ); - ObjectValues::const_iterator it = value_.map_->find( key ); - if ( it == value_.map_->end() ) - return null; - return (*it).second; -#else - Value *value = value_.array_->find( index ); - return value ? *value : null; -#endif -} - - -Value & -Value::operator[]( const char *key ) -{ - return resolveReference( key, false ); -} - - -Value & -Value::resolveReference( const char *key, - bool isStatic ) -{ - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); - if ( type_ == nullValue ) - *this = Value( objectValue ); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - CZString actualKey( key, isStatic ? CZString::noDuplication - : CZString::duplicateOnCopy ); - ObjectValues::iterator it = value_.map_->lower_bound( actualKey ); - if ( it != value_.map_->end() && (*it).first == actualKey ) - return (*it).second; - - ObjectValues::value_type defaultValue( actualKey, null ); - it = value_.map_->insert( it, defaultValue ); - Value &value = (*it).second; - return value; -#else - return value_.map_->resolveReference( key, isStatic ); -#endif -} - - -Value -Value::get( UInt index, - const Value &defaultValue ) const -{ - const Value *value = &((*this)[index]); - return value == &null ? defaultValue : *value; -} - - -bool -Value::isValidIndex( UInt index ) const -{ - return index < size(); -} - - - -const Value & -Value::operator[]( const char *key ) const -{ - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); - if ( type_ == nullValue ) - return null; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - CZString actualKey( key, CZString::noDuplication ); - ObjectValues::const_iterator it = value_.map_->find( actualKey ); - if ( it == value_.map_->end() ) - return null; - return (*it).second; -#else - const Value *value = value_.map_->find( key ); - return value ? *value : null; -#endif -} - - -Value & -Value::operator[]( const std::string &key ) -{ - return (*this)[ key.c_str() ]; -} - - -const Value & -Value::operator[]( const std::string &key ) const -{ - return (*this)[ key.c_str() ]; -} - -Value & -Value::operator[]( const StaticString &key ) -{ - return resolveReference( key, true ); -} - - -# ifdef JSON_USE_CPPTL -Value & -Value::operator[]( const CppTL::ConstString &key ) -{ - return (*this)[ key.c_str() ]; -} - - -const Value & -Value::operator[]( const CppTL::ConstString &key ) const -{ - return (*this)[ key.c_str() ]; -} -# endif - - -Value & -Value::append( const Value &value ) -{ - return (*this)[size()] = value; -} - - -Value -Value::get( const char *key, - const Value &defaultValue ) const -{ - const Value *value = &((*this)[key]); - return value == &null ? defaultValue : *value; -} - - -Value -Value::get( const std::string &key, - const Value &defaultValue ) const -{ - return get( key.c_str(), defaultValue ); -} - -Value -Value::removeMember( const char* key ) -{ - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); - if ( type_ == nullValue ) - return null; -#ifndef JSON_VALUE_USE_INTERNAL_MAP - CZString actualKey( key, CZString::noDuplication ); - ObjectValues::iterator it = value_.map_->find( actualKey ); - if ( it == value_.map_->end() ) - return null; - Value old(it->second); - value_.map_->erase(it); - return old; -#else - Value *value = value_.map_->find( key ); - if (value){ - Value old(*value); - value_.map_.remove( key ); - return old; - } else { - return null; - } -#endif -} - -Value -Value::removeMember( const std::string &key ) -{ - return removeMember( key.c_str() ); -} - -# ifdef JSON_USE_CPPTL -Value -Value::get( const CppTL::ConstString &key, - const Value &defaultValue ) const -{ - return get( key.c_str(), defaultValue ); -} -# endif - -bool -Value::isMember( const char *key ) const -{ - const Value *value = &((*this)[key]); - return value != &null; -} - - -bool -Value::isMember( const std::string &key ) const -{ - return isMember( key.c_str() ); -} - - -# ifdef JSON_USE_CPPTL -bool -Value::isMember( const CppTL::ConstString &key ) const -{ - return isMember( key.c_str() ); -} -#endif - -Value::Members -Value::getMemberNames() const -{ - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); - if ( type_ == nullValue ) - return Value::Members(); - Members members; - members.reserve( value_.map_->size() ); -#ifndef JSON_VALUE_USE_INTERNAL_MAP - ObjectValues::const_iterator it = value_.map_->begin(); - ObjectValues::const_iterator itEnd = value_.map_->end(); - for ( ; it != itEnd; ++it ) - members.push_back( std::string( (*it).first.c_str() ) ); -#else - ValueInternalMap::IteratorState it; - ValueInternalMap::IteratorState itEnd; - value_.map_->makeBeginIterator( it ); - value_.map_->makeEndIterator( itEnd ); - for ( ; !ValueInternalMap::equals( it, itEnd ); ValueInternalMap::increment(it) ) - members.push_back( std::string( ValueInternalMap::key( it ) ) ); -#endif - return members; -} -// -//# ifdef JSON_USE_CPPTL -//EnumMemberNames -//Value::enumMemberNames() const -//{ -// if ( type_ == objectValue ) -// { -// return CppTL::Enum::any( CppTL::Enum::transform( -// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), -// MemberNamesTransform() ) ); -// } -// return EnumMemberNames(); -//} -// -// -//EnumValues -//Value::enumValues() const -//{ -// if ( type_ == objectValue || type_ == arrayValue ) -// return CppTL::Enum::anyValues( *(value_.map_), -// CppTL::Type<const Value &>() ); -// return EnumValues(); -//} -// -//# endif - - -bool -Value::isNull() const -{ - return type_ == nullValue; -} - - -bool -Value::isBool() const -{ - return type_ == booleanValue; -} - - -bool -Value::isInt() const -{ - return type_ == intValue; -} - - -bool -Value::isUInt() const -{ - return type_ == uintValue; -} - - -bool -Value::isIntegral() const -{ - return type_ == intValue - || type_ == uintValue - || type_ == booleanValue; -} - - -bool -Value::isDouble() const -{ - return type_ == realValue; -} - - -bool -Value::isNumeric() const -{ - return isIntegral() || isDouble(); -} - - -bool -Value::isString() const -{ - return type_ == stringValue; -} - - -bool -Value::isArray() const -{ - return type_ == nullValue || type_ == arrayValue; -} - - -bool -Value::isObject() const -{ - return type_ == nullValue || type_ == objectValue; -} - - -void -Value::setComment( const char *comment, - CommentPlacement placement ) -{ - if ( !comments_ ) - comments_ = new CommentInfo[numberOfCommentPlacement]; - comments_[placement].setComment( comment ); -} - - -void -Value::setComment( const std::string &comment, - CommentPlacement placement ) -{ - setComment( comment.c_str(), placement ); -} - - -bool -Value::hasComment( CommentPlacement placement ) const -{ - return comments_ != 0 && comments_[placement].comment_ != 0; -} - -std::string -Value::getComment( CommentPlacement placement ) const -{ - if ( hasComment(placement) ) - return comments_[placement].comment_; - return ""; -} - - -std::string -Value::toStyledString() const -{ - StyledWriter writer; - return writer.write( *this ); -} - - -Value::const_iterator -Value::begin() const -{ - switch ( type_ ) - { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if ( value_.array_ ) - { - ValueInternalArray::IteratorState it; - value_.array_->makeBeginIterator( it ); - return const_iterator( it ); - } - break; - case objectValue: - if ( value_.map_ ) - { - ValueInternalMap::IteratorState it; - value_.map_->makeBeginIterator( it ); - return const_iterator( it ); - } - break; -#else - case arrayValue: - case objectValue: - if ( value_.map_ ) - return const_iterator( value_.map_->begin() ); - break; -#endif - default: - break; - } - return const_iterator(); -} - -Value::const_iterator -Value::end() const -{ - switch ( type_ ) - { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if ( value_.array_ ) - { - ValueInternalArray::IteratorState it; - value_.array_->makeEndIterator( it ); - return const_iterator( it ); - } - break; - case objectValue: - if ( value_.map_ ) - { - ValueInternalMap::IteratorState it; - value_.map_->makeEndIterator( it ); - return const_iterator( it ); - } - break; -#else - case arrayValue: - case objectValue: - if ( value_.map_ ) - return const_iterator( value_.map_->end() ); - break; -#endif - default: - break; - } - return const_iterator(); -} - - -Value::iterator -Value::begin() -{ - switch ( type_ ) - { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if ( value_.array_ ) - { - ValueInternalArray::IteratorState it; - value_.array_->makeBeginIterator( it ); - return iterator( it ); - } - break; - case objectValue: - if ( value_.map_ ) - { - ValueInternalMap::IteratorState it; - value_.map_->makeBeginIterator( it ); - return iterator( it ); - } - break; -#else - case arrayValue: - case objectValue: - if ( value_.map_ ) - return iterator( value_.map_->begin() ); - break; -#endif - default: - break; - } - return iterator(); -} - -Value::iterator -Value::end() -{ - switch ( type_ ) - { -#ifdef JSON_VALUE_USE_INTERNAL_MAP - case arrayValue: - if ( value_.array_ ) - { - ValueInternalArray::IteratorState it; - value_.array_->makeEndIterator( it ); - return iterator( it ); - } - break; - case objectValue: - if ( value_.map_ ) - { - ValueInternalMap::IteratorState it; - value_.map_->makeEndIterator( it ); - return iterator( it ); - } - break; -#else - case arrayValue: - case objectValue: - if ( value_.map_ ) - return iterator( value_.map_->end() ); - break; -#endif - default: - break; - } - return iterator(); -} - - -// class PathArgument -// ////////////////////////////////////////////////////////////////// - -PathArgument::PathArgument() - : kind_( kindNone ) -{ -} - - -PathArgument::PathArgument( Value::UInt index ) - : index_( index ) - , kind_( kindIndex ) -{ -} - - -PathArgument::PathArgument( const char *key ) - : key_( key ) - , kind_( kindKey ) -{ -} - - -PathArgument::PathArgument( const std::string &key ) - : key_( key.c_str() ) - , kind_( kindKey ) -{ -} - -// class Path -// ////////////////////////////////////////////////////////////////// - -Path::Path( const std::string &path, - const PathArgument &a1, - const PathArgument &a2, - const PathArgument &a3, - const PathArgument &a4, - const PathArgument &a5 ) -{ - InArgs in; - in.push_back( &a1 ); - in.push_back( &a2 ); - in.push_back( &a3 ); - in.push_back( &a4 ); - in.push_back( &a5 ); - makePath( path, in ); -} - - -void -Path::makePath( const std::string &path, - const InArgs &in ) -{ - const char *current = path.c_str(); - const char *end = current + path.length(); - InArgs::const_iterator itInArg = in.begin(); - while ( current != end ) - { - if ( *current == '[' ) - { - ++current; - if ( *current == '%' ) - addPathInArg( path, in, itInArg, PathArgument::kindIndex ); - else - { - Value::UInt index = 0; - for ( ; current != end && *current >= '0' && *current <= '9'; ++current ) - index = index * 10 + Value::UInt(*current - '0'); - args_.push_back( index ); - } - if ( current == end || *current++ != ']' ) - invalidPath( path, int(current - path.c_str()) ); - } - else if ( *current == '%' ) - { - addPathInArg( path, in, itInArg, PathArgument::kindKey ); - ++current; - } - else if ( *current == '.' ) - { - ++current; - } - else - { - const char *beginName = current; - while ( current != end && !strchr( "[.", *current ) ) - ++current; - args_.push_back( std::string( beginName, current ) ); - } - } -} - - -void -Path::addPathInArg( const std::string &path, - const InArgs &in, - InArgs::const_iterator &itInArg, - PathArgument::Kind kind ) -{ - if ( itInArg == in.end() ) - { - // Error: missing argument %d - } - else if ( (*itInArg)->kind_ != kind ) - { - // Error: bad argument type - } - else - { - args_.push_back( **itInArg ); - } -} - - -void -Path::invalidPath( const std::string &path, - int location ) -{ - // Error: invalid path. -} - - -const Value & -Path::resolve( const Value &root ) const -{ - const Value *node = &root; - for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) - { - const PathArgument &arg = *it; - if ( arg.kind_ == PathArgument::kindIndex ) - { - if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) - { - // Error: unable to resolve path (array value expected at position... - } - node = &((*node)[arg.index_]); - } - else if ( arg.kind_ == PathArgument::kindKey ) - { - if ( !node->isObject() ) - { - // Error: unable to resolve path (object value expected at position...) - } - node = &((*node)[arg.key_]); - if ( node == &Value::null ) - { - // Error: unable to resolve path (object has no member named '' at position...) - } - } - } - return *node; -} - - -Value -Path::resolve( const Value &root, - const Value &defaultValue ) const -{ - const Value *node = &root; - for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) - { - const PathArgument &arg = *it; - if ( arg.kind_ == PathArgument::kindIndex ) - { - if ( !node->isArray() || node->isValidIndex( arg.index_ ) ) - return defaultValue; - node = &((*node)[arg.index_]); - } - else if ( arg.kind_ == PathArgument::kindKey ) - { - if ( !node->isObject() ) - return defaultValue; - node = &((*node)[arg.key_]); - if ( node == &Value::null ) - return defaultValue; - } - } - return *node; -} - - -Value & -Path::make( Value &root ) const -{ - Value *node = &root; - for ( Args::const_iterator it = args_.begin(); it != args_.end(); ++it ) - { - const PathArgument &arg = *it; - if ( arg.kind_ == PathArgument::kindIndex ) - { - if ( !node->isArray() ) - { - // Error: node is not an array at position ... - } - node = &((*node)[arg.index_]); - } - else if ( arg.kind_ == PathArgument::kindKey ) - { - if ( !node->isObject() ) - { - // Error: node is not an object at position... - } - node = &((*node)[arg.key_]); - } - } - return *node; -} - - -} // namespace Json diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_valueiterator.inl b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_valueiterator.inl deleted file mode 100644 index 736e260e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_valueiterator.inl +++ /dev/null @@ -1,292 +0,0 @@ -// included by json_value.cpp -// everything is within Json namespace - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueIteratorBase -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueIteratorBase::ValueIteratorBase() -#ifndef JSON_VALUE_USE_INTERNAL_MAP - : current_() - , isNull_( true ) -{ -} -#else - : isArray_( true ) - , isNull_( true ) -{ - iterator_.array_ = ValueInternalArray::IteratorState(); -} -#endif - - -#ifndef JSON_VALUE_USE_INTERNAL_MAP -ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator ¤t ) - : current_( current ) - , isNull_( false ) -{ -} -#else -ValueIteratorBase::ValueIteratorBase( const ValueInternalArray::IteratorState &state ) - : isArray_( true ) -{ - iterator_.array_ = state; -} - - -ValueIteratorBase::ValueIteratorBase( const ValueInternalMap::IteratorState &state ) - : isArray_( false ) -{ - iterator_.map_ = state; -} -#endif - -Value & -ValueIteratorBase::deref() const -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - return current_->second; -#else - if ( isArray_ ) - return ValueInternalArray::dereference( iterator_.array_ ); - return ValueInternalMap::value( iterator_.map_ ); -#endif -} - - -void -ValueIteratorBase::increment() -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - ++current_; -#else - if ( isArray_ ) - ValueInternalArray::increment( iterator_.array_ ); - ValueInternalMap::increment( iterator_.map_ ); -#endif -} - - -void -ValueIteratorBase::decrement() -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - --current_; -#else - if ( isArray_ ) - ValueInternalArray::decrement( iterator_.array_ ); - ValueInternalMap::decrement( iterator_.map_ ); -#endif -} - - -ValueIteratorBase::difference_type -ValueIteratorBase::computeDistance( const SelfType &other ) const -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP -# ifdef JSON_USE_CPPTL_SMALLMAP - return current_ - other.current_; -# else - // Iterator for null value are initialized using the default - // constructor, which initialize current_ to the default - // std::map::iterator. As begin() and end() are two instance - // of the default std::map::iterator, they can not be compared. - // To allow this, we handle this comparison specifically. - if ( isNull_ && other.isNull_ ) - { - return 0; - } - - - // Usage of std::distance is not portable (does not compile with Sun Studio 12 RogueWave STL, - // which is the one used by default). - // Using a portable hand-made version for non random iterator instead: - // return difference_type( std::distance( current_, other.current_ ) ); - difference_type myDistance = 0; - for ( Value::ObjectValues::iterator it = current_; it != other.current_; ++it ) - { - ++myDistance; - } - return myDistance; -# endif -#else - if ( isArray_ ) - return ValueInternalArray::distance( iterator_.array_, other.iterator_.array_ ); - return ValueInternalMap::distance( iterator_.map_, other.iterator_.map_ ); -#endif -} - - -bool -ValueIteratorBase::isEqual( const SelfType &other ) const -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - if ( isNull_ ) - { - return other.isNull_; - } - return current_ == other.current_; -#else - if ( isArray_ ) - return ValueInternalArray::equals( iterator_.array_, other.iterator_.array_ ); - return ValueInternalMap::equals( iterator_.map_, other.iterator_.map_ ); -#endif -} - - -void -ValueIteratorBase::copy( const SelfType &other ) -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - current_ = other.current_; -#else - if ( isArray_ ) - iterator_.array_ = other.iterator_.array_; - iterator_.map_ = other.iterator_.map_; -#endif -} - - -Value -ValueIteratorBase::key() const -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - const Value::CZString czstring = (*current_).first; - if ( czstring.c_str() ) - { - if ( czstring.isStaticString() ) - return Value( StaticString( czstring.c_str() ) ); - return Value( czstring.c_str() ); - } - return Value( czstring.index() ); -#else - if ( isArray_ ) - return Value( ValueInternalArray::indexOf( iterator_.array_ ) ); - bool isStatic; - const char *memberName = ValueInternalMap::key( iterator_.map_, isStatic ); - if ( isStatic ) - return Value( StaticString( memberName ) ); - return Value( memberName ); -#endif -} - - -UInt -ValueIteratorBase::index() const -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - const Value::CZString czstring = (*current_).first; - if ( !czstring.c_str() ) - return czstring.index(); - return Value::UInt( -1 ); -#else - if ( isArray_ ) - return Value::UInt( ValueInternalArray::indexOf( iterator_.array_ ) ); - return Value::UInt( -1 ); -#endif -} - - -const char * -ValueIteratorBase::memberName() const -{ -#ifndef JSON_VALUE_USE_INTERNAL_MAP - const char *name = (*current_).first.c_str(); - return name ? name : ""; -#else - if ( !isArray_ ) - return ValueInternalMap::key( iterator_.map_ ); - return ""; -#endif -} - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueConstIterator -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueConstIterator::ValueConstIterator() -{ -} - - -#ifndef JSON_VALUE_USE_INTERNAL_MAP -ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator ¤t ) - : ValueIteratorBase( current ) -{ -} -#else -ValueConstIterator::ValueConstIterator( const ValueInternalArray::IteratorState &state ) - : ValueIteratorBase( state ) -{ -} - -ValueConstIterator::ValueConstIterator( const ValueInternalMap::IteratorState &state ) - : ValueIteratorBase( state ) -{ -} -#endif - -ValueConstIterator & -ValueConstIterator::operator =( const ValueIteratorBase &other ) -{ - copy( other ); - return *this; -} - - -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class ValueIterator -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -ValueIterator::ValueIterator() -{ -} - - -#ifndef JSON_VALUE_USE_INTERNAL_MAP -ValueIterator::ValueIterator( const Value::ObjectValues::iterator ¤t ) - : ValueIteratorBase( current ) -{ -} -#else -ValueIterator::ValueIterator( const ValueInternalArray::IteratorState &state ) - : ValueIteratorBase( state ) -{ -} - -ValueIterator::ValueIterator( const ValueInternalMap::IteratorState &state ) - : ValueIteratorBase( state ) -{ -} -#endif - -ValueIterator::ValueIterator( const ValueConstIterator &other ) - : ValueIteratorBase( other ) -{ -} - -ValueIterator::ValueIterator( const ValueIterator &other ) - : ValueIteratorBase( other ) -{ -} - -ValueIterator & -ValueIterator::operator =( const SelfType &other ) -{ - copy( other ); - return *this; -} diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_writer.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_writer.cpp deleted file mode 100644 index cdf4188f..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/json_writer.cpp +++ /dev/null @@ -1,829 +0,0 @@ -#include <json/writer.h> -#include <utility> -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include <iostream> -#include <sstream> -#include <iomanip> - -#if _MSC_VER >= 1400 // VC++ 8.0 -#pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. -#endif - -namespace Json { - -static bool isControlCharacter(char ch) -{ - return ch > 0 && ch <= 0x1F; -} - -static bool containsControlCharacter( const char* str ) -{ - while ( *str ) - { - if ( isControlCharacter( *(str++) ) ) - return true; - } - return false; -} -static void uintToString( unsigned int value, - char *¤t ) -{ - *--current = 0; - do - { - *--current = (value % 10) + '0'; - value /= 10; - } - while ( value != 0 ); -} - -std::string valueToString( Int value ) -{ - char buffer[32]; - char *current = buffer + sizeof(buffer); - bool isNegative = value < 0; - if ( isNegative ) - value = -value; - uintToString( UInt(value), current ); - if ( isNegative ) - *--current = '-'; - assert( current >= buffer ); - return current; -} - - -std::string valueToString( UInt value ) -{ - char buffer[32]; - char *current = buffer + sizeof(buffer); - uintToString( value, current ); - assert( current >= buffer ); - return current; -} - -std::string valueToString( double value ) -{ - char buffer[32]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning. - sprintf_s(buffer, sizeof(buffer), "%#.16g", value); -#else - sprintf(buffer, "%#.16g", value); -#endif - char* ch = buffer + strlen(buffer) - 1; - if (*ch != '0') return buffer; // nothing to truncate, so save time - while(ch > buffer && *ch == '0'){ - --ch; - } - char* last_nonzero = ch; - while(ch >= buffer){ - switch(*ch){ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - --ch; - continue; - case '.': - // Truncate zeroes to save bytes in output, but keep one. - *(last_nonzero+2) = '\0'; - return buffer; - default: - return buffer; - } - } - return buffer; -} - - -std::string valueToString( bool value ) -{ - return value ? "true" : "false"; -} - -std::string valueToQuotedString( const char *value ) -{ - // Not sure how to handle unicode... - if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value )) - return std::string("\"") + value + "\""; - // We have to walk value and escape any special characters. - // Appending to std::string is not efficient, but this should be rare. - // (Note: forward slashes are *not* rare, but I am not escaping them.) - unsigned maxsize = strlen(value)*2 + 3; // allescaped+quotes+NULL - std::string result; - result.reserve(maxsize); // to avoid lots of mallocs - result += "\""; - for (const char* c=value; *c != 0; ++c) - { - switch(*c) - { - case '\"': - result += "\\\""; - break; - case '\\': - result += "\\\\"; - break; - case '\b': - result += "\\b"; - break; - case '\f': - result += "\\f"; - break; - case '\n': - result += "\\n"; - break; - case '\r': - result += "\\r"; - break; - case '\t': - result += "\\t"; - break; - //case '/': - // Even though \/ is considered a legal escape in JSON, a bare - // slash is also legal, so I see no reason to escape it. - // (I hope I am not misunderstanding something. - // blep notes: actually escaping \/ may be useful in javascript to avoid </ - // sequence. - // Should add a flag to allow this compatibility mode and prevent this - // sequence from occurring. - default: - if ( isControlCharacter( *c ) ) - { - std::ostringstream oss; - oss << "\\u" << std::hex << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<int>(*c); - result += oss.str(); - } - else - { - result += *c; - } - break; - } - } - result += "\""; - return result; -} - -// Class Writer -// ////////////////////////////////////////////////////////////////// -Writer::~Writer() -{ -} - - -// Class FastWriter -// ////////////////////////////////////////////////////////////////// - -FastWriter::FastWriter() - : yamlCompatiblityEnabled_( false ) -{ -} - - -void -FastWriter::enableYAMLCompatibility() -{ - yamlCompatiblityEnabled_ = true; -} - - -std::string -FastWriter::write( const Value &root ) -{ - document_ = ""; - writeValue( root ); - document_ += "\n"; - return document_; -} - - -void -FastWriter::writeValue( const Value &value ) -{ - switch ( value.type() ) - { - case nullValue: - document_ += "null"; - break; - case intValue: - document_ += valueToString( value.asInt() ); - break; - case uintValue: - document_ += valueToString( value.asUInt() ); - break; - case realValue: - document_ += valueToString( value.asDouble() ); - break; - case stringValue: - document_ += valueToQuotedString( value.asCString() ); - break; - case booleanValue: - document_ += valueToString( value.asBool() ); - break; - case arrayValue: - { - document_ += "["; - int size = value.size(); - for ( int index =0; index < size; ++index ) - { - if ( index > 0 ) - document_ += ","; - writeValue( value[index] ); - } - document_ += "]"; - } - break; - case objectValue: - { - Value::Members members( value.getMemberNames() ); - document_ += "{"; - for ( Value::Members::iterator it = members.begin(); - it != members.end(); - ++it ) - { - const std::string &name = *it; - if ( it != members.begin() ) - document_ += ","; - document_ += valueToQuotedString( name.c_str() ); - document_ += yamlCompatiblityEnabled_ ? ": " - : ":"; - writeValue( value[name] ); - } - document_ += "}"; - } - break; - } -} - - -// Class StyledWriter -// ////////////////////////////////////////////////////////////////// - -StyledWriter::StyledWriter() - : rightMargin_( 74 ) - , indentSize_( 3 ) -{ -} - - -std::string -StyledWriter::write( const Value &root ) -{ - document_ = ""; - addChildValues_ = false; - indentString_ = ""; - writeCommentBeforeValue( root ); - writeValue( root ); - writeCommentAfterValueOnSameLine( root ); - document_ += "\n"; - return document_; -} - - -void -StyledWriter::writeValue( const Value &value ) -{ - switch ( value.type() ) - { - case nullValue: - pushValue( "null" ); - break; - case intValue: - pushValue( valueToString( value.asInt() ) ); - break; - case uintValue: - pushValue( valueToString( value.asUInt() ) ); - break; - case realValue: - pushValue( valueToString( value.asDouble() ) ); - break; - case stringValue: - pushValue( valueToQuotedString( value.asCString() ) ); - break; - case booleanValue: - pushValue( valueToString( value.asBool() ) ); - break; - case arrayValue: - writeArrayValue( value); - break; - case objectValue: - { - Value::Members members( value.getMemberNames() ); - if ( members.empty() ) - pushValue( "{}" ); - else - { - writeWithIndent( "{" ); - indent(); - Value::Members::iterator it = members.begin(); - while ( true ) - { - const std::string &name = *it; - const Value &childValue = value[name]; - writeCommentBeforeValue( childValue ); - writeWithIndent( valueToQuotedString( name.c_str() ) ); - document_ += " : "; - writeValue( childValue ); - if ( ++it == members.end() ) - { - writeCommentAfterValueOnSameLine( childValue ); - break; - } - document_ += ","; - writeCommentAfterValueOnSameLine( childValue ); - } - unindent(); - writeWithIndent( "}" ); - } - } - break; - } -} - - -void -StyledWriter::writeArrayValue( const Value &value ) -{ - unsigned size = value.size(); - if ( size == 0 ) - pushValue( "[]" ); - else - { - bool isArrayMultiLine = isMultineArray( value ); - if ( isArrayMultiLine ) - { - writeWithIndent( "[" ); - indent(); - bool hasChildValue = !childValues_.empty(); - unsigned index =0; - while ( true ) - { - const Value &childValue = value[index]; - writeCommentBeforeValue( childValue ); - if ( hasChildValue ) - writeWithIndent( childValues_[index] ); - else - { - writeIndent(); - writeValue( childValue ); - } - if ( ++index == size ) - { - writeCommentAfterValueOnSameLine( childValue ); - break; - } - document_ += ","; - writeCommentAfterValueOnSameLine( childValue ); - } - unindent(); - writeWithIndent( "]" ); - } - else // output on a single line - { - assert( childValues_.size() == size ); - document_ += "[ "; - for ( unsigned index =0; index < size; ++index ) - { - if ( index > 0 ) - document_ += ", "; - document_ += childValues_[index]; - } - document_ += " ]"; - } - } -} - - -bool -StyledWriter::isMultineArray( const Value &value ) -{ - int size = value.size(); - bool isMultiLine = size*3 >= rightMargin_ ; - childValues_.clear(); - for ( int index =0; index < size && !isMultiLine; ++index ) - { - const Value &childValue = value[index]; - isMultiLine = isMultiLine || - ( (childValue.isArray() || childValue.isObject()) && - childValue.size() > 0 ); - } - if ( !isMultiLine ) // check if line length > max line length - { - childValues_.reserve( size ); - addChildValues_ = true; - int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]' - for ( int index =0; index < size && !isMultiLine; ++index ) - { - writeValue( value[index] ); - lineLength += int( childValues_[index].length() ); - isMultiLine = isMultiLine && hasCommentForValue( value[index] ); - } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; - } - return isMultiLine; -} - - -void -StyledWriter::pushValue( const std::string &value ) -{ - if ( addChildValues_ ) - childValues_.push_back( value ); - else - document_ += value; -} - - -void -StyledWriter::writeIndent() -{ - if ( !document_.empty() ) - { - char last = document_[document_.length()-1]; - if ( last == ' ' ) // already indented - return; - if ( last != '\n' ) // Comments may add new-line - document_ += '\n'; - } - document_ += indentString_; -} - - -void -StyledWriter::writeWithIndent( const std::string &value ) -{ - writeIndent(); - document_ += value; -} - - -void -StyledWriter::indent() -{ - indentString_ += std::string( indentSize_, ' ' ); -} - - -void -StyledWriter::unindent() -{ - assert( int(indentString_.size()) >= indentSize_ ); - indentString_.resize( indentString_.size() - indentSize_ ); -} - - -void -StyledWriter::writeCommentBeforeValue( const Value &root ) -{ - if ( !root.hasComment( commentBefore ) ) - return; - document_ += normalizeEOL( root.getComment( commentBefore ) ); - document_ += "\n"; -} - - -void -StyledWriter::writeCommentAfterValueOnSameLine( const Value &root ) -{ - if ( root.hasComment( commentAfterOnSameLine ) ) - document_ += " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) ); - - if ( root.hasComment( commentAfter ) ) - { - document_ += "\n"; - document_ += normalizeEOL( root.getComment( commentAfter ) ); - document_ += "\n"; - } -} - - -bool -StyledWriter::hasCommentForValue( const Value &value ) -{ - return value.hasComment( commentBefore ) - || value.hasComment( commentAfterOnSameLine ) - || value.hasComment( commentAfter ); -} - - -std::string -StyledWriter::normalizeEOL( const std::string &text ) -{ - std::string normalized; - normalized.reserve( text.length() ); - const char *begin = text.c_str(); - const char *end = begin + text.length(); - const char *current = begin; - while ( current != end ) - { - char c = *current++; - if ( c == '\r' ) // mac or dos EOL - { - if ( *current == '\n' ) // convert dos EOL - ++current; - normalized += '\n'; - } - else // handle unix EOL & other char - normalized += c; - } - return normalized; -} - - -// Class StyledStreamWriter -// ////////////////////////////////////////////////////////////////// - -StyledStreamWriter::StyledStreamWriter( std::string indentation ) - : document_(NULL) - , rightMargin_( 74 ) - , indentation_( indentation ) -{ -} - - -void -StyledStreamWriter::write( std::ostream &out, const Value &root ) -{ - document_ = &out; - addChildValues_ = false; - indentString_ = ""; - writeCommentBeforeValue( root ); - writeValue( root ); - writeCommentAfterValueOnSameLine( root ); - *document_ << "\n"; - document_ = NULL; // Forget the stream, for safety. -} - - -void -StyledStreamWriter::writeValue( const Value &value ) -{ - switch ( value.type() ) - { - case nullValue: - pushValue( "null" ); - break; - case intValue: - pushValue( valueToString( value.asInt() ) ); - break; - case uintValue: - pushValue( valueToString( value.asUInt() ) ); - break; - case realValue: - pushValue( valueToString( value.asDouble() ) ); - break; - case stringValue: - pushValue( valueToQuotedString( value.asCString() ) ); - break; - case booleanValue: - pushValue( valueToString( value.asBool() ) ); - break; - case arrayValue: - writeArrayValue( value); - break; - case objectValue: - { - Value::Members members( value.getMemberNames() ); - if ( members.empty() ) - pushValue( "{}" ); - else - { - writeWithIndent( "{" ); - indent(); - Value::Members::iterator it = members.begin(); - while ( true ) - { - const std::string &name = *it; - const Value &childValue = value[name]; - writeCommentBeforeValue( childValue ); - writeWithIndent( valueToQuotedString( name.c_str() ) ); - *document_ << " : "; - writeValue( childValue ); - if ( ++it == members.end() ) - { - writeCommentAfterValueOnSameLine( childValue ); - break; - } - *document_ << ","; - writeCommentAfterValueOnSameLine( childValue ); - } - unindent(); - writeWithIndent( "}" ); - } - } - break; - } -} - - -void -StyledStreamWriter::writeArrayValue( const Value &value ) -{ - unsigned size = value.size(); - if ( size == 0 ) - pushValue( "[]" ); - else - { - bool isArrayMultiLine = isMultineArray( value ); - if ( isArrayMultiLine ) - { - writeWithIndent( "[" ); - indent(); - bool hasChildValue = !childValues_.empty(); - unsigned index =0; - while ( true ) - { - const Value &childValue = value[index]; - writeCommentBeforeValue( childValue ); - if ( hasChildValue ) - writeWithIndent( childValues_[index] ); - else - { - writeIndent(); - writeValue( childValue ); - } - if ( ++index == size ) - { - writeCommentAfterValueOnSameLine( childValue ); - break; - } - *document_ << ","; - writeCommentAfterValueOnSameLine( childValue ); - } - unindent(); - writeWithIndent( "]" ); - } - else // output on a single line - { - assert( childValues_.size() == size ); - *document_ << "[ "; - for ( unsigned index =0; index < size; ++index ) - { - if ( index > 0 ) - *document_ << ", "; - *document_ << childValues_[index]; - } - *document_ << " ]"; - } - } -} - - -bool -StyledStreamWriter::isMultineArray( const Value &value ) -{ - int size = value.size(); - bool isMultiLine = size*3 >= rightMargin_ ; - childValues_.clear(); - for ( int index =0; index < size && !isMultiLine; ++index ) - { - const Value &childValue = value[index]; - isMultiLine = isMultiLine || - ( (childValue.isArray() || childValue.isObject()) && - childValue.size() > 0 ); - } - if ( !isMultiLine ) // check if line length > max line length - { - childValues_.reserve( size ); - addChildValues_ = true; - int lineLength = 4 + (size-1)*2; // '[ ' + ', '*n + ' ]' - for ( int index =0; index < size && !isMultiLine; ++index ) - { - writeValue( value[index] ); - lineLength += int( childValues_[index].length() ); - isMultiLine = isMultiLine && hasCommentForValue( value[index] ); - } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; - } - return isMultiLine; -} - - -void -StyledStreamWriter::pushValue( const std::string &value ) -{ - if ( addChildValues_ ) - childValues_.push_back( value ); - else - *document_ << value; -} - - -void -StyledStreamWriter::writeIndent() -{ - /* - Some comments in this method would have been nice. ;-) - - if ( !document_.empty() ) - { - char last = document_[document_.length()-1]; - if ( last == ' ' ) // already indented - return; - if ( last != '\n' ) // Comments may add new-line - *document_ << '\n'; - } - */ - *document_ << '\n' << indentString_; -} - - -void -StyledStreamWriter::writeWithIndent( const std::string &value ) -{ - writeIndent(); - *document_ << value; -} - - -void -StyledStreamWriter::indent() -{ - indentString_ += indentation_; -} - - -void -StyledStreamWriter::unindent() -{ - assert( indentString_.size() >= indentation_.size() ); - indentString_.resize( indentString_.size() - indentation_.size() ); -} - - -void -StyledStreamWriter::writeCommentBeforeValue( const Value &root ) -{ - if ( !root.hasComment( commentBefore ) ) - return; - *document_ << normalizeEOL( root.getComment( commentBefore ) ); - *document_ << "\n"; -} - - -void -StyledStreamWriter::writeCommentAfterValueOnSameLine( const Value &root ) -{ - if ( root.hasComment( commentAfterOnSameLine ) ) - *document_ << " " + normalizeEOL( root.getComment( commentAfterOnSameLine ) ); - - if ( root.hasComment( commentAfter ) ) - { - *document_ << "\n"; - *document_ << normalizeEOL( root.getComment( commentAfter ) ); - *document_ << "\n"; - } -} - - -bool -StyledStreamWriter::hasCommentForValue( const Value &value ) -{ - return value.hasComment( commentBefore ) - || value.hasComment( commentAfterOnSameLine ) - || value.hasComment( commentAfter ); -} - - -std::string -StyledStreamWriter::normalizeEOL( const std::string &text ) -{ - std::string normalized; - normalized.reserve( text.length() ); - const char *begin = text.c_str(); - const char *end = begin + text.length(); - const char *current = begin; - while ( current != end ) - { - char c = *current++; - if ( c == '\r' ) // mac or dos EOL - { - if ( *current == '\n' ) // convert dos EOL - ++current; - normalized += '\n'; - } - else // handle unix EOL & other char - normalized += c; - } - return normalized; -} - - -std::ostream& operator<<( std::ostream &sout, const Value &root ) -{ - Json::StyledStreamWriter writer; - writer.write(sout, root); - return sout; -} - - -} // namespace Json diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/plugin.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/public/plugin.cpp deleted file mode 100644 index 6906275e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/plugin.cpp +++ /dev/null @@ -1,320 +0,0 @@ -#include "plugin.h" -#include "tokenizer.h" - -#ifdef _WINDOWS -#include <windows.h> -BOOL APIENTRY DllMain( HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved ) -{ - return TRUE; -} -#else -#include <errno.h> -#include <string.h> - -extern int errno; -#endif - -SendPluginEv SendPluginEvent; - -string g_GetSysErrMsg( void ) -{ - string strError = "Unknown"; - // Problem loading -#ifdef _WINDOWS - int nErrorCode = GetLastError(); - LPTSTR s; - if ( ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, nErrorCode, 0, ( LPTSTR ) &s, 0, NULL ) ) - { - strError = s; - } - else - { - char szBuf[ 20 ]; - _snprintf_s( szBuf, _countof(szBuf), 19, "%d", nErrorCode ); - strError = szBuf; - } -#else - char szError[80]; - if ( strerror_r( errno, szError, sizeof(szError) ) ) - { - strError = "no description found"; - } - else - { - strError = szError; - } -#endif - return strError; -} - -void g_sleep( unsigned int mseconds ) -{ -#ifdef _WINDOWS - Sleep( mseconds ); -#else - usleep( mseconds * 1000 ); -#endif -} - -string& g_trim( string& str ) -{ - // Whitespace characters - char whspc[] = " \t\r\n\v\f"; - - // Whack off first part - size_t pos = str.find_first_not_of( whspc ); - - if ( pos != string::npos ) - str.replace( 0, pos, "" ); - - // Whack off trailing stuff - pos = str.find_last_not_of( whspc ); - - if ( pos != string::npos ) - str.replace( pos + 1, str.length() - pos, "" ); - - return str; -} - -void g_tokenize( const string& str, const string& delimiters, vector<string>& tokens ) -{ - tokenize( str, tokens, delimiters ); -} - -char* SetEventFunc( SendPluginEv funcPtr ) -{ - static char * szObjList = onGetObjList(); - SendPluginEvent = funcPtr; - return szObjList; -} - - -const int nMAXSIZE = 512; -char* g_pszRetVal = NULL; - -//----------------------------------------------------------- -// Map from an object Id to an object instance -//----------------------------------------------------------- -typedef std::map<string, JSExt*> StringToJExt_T; - -//----------------------------------------------------------- -// Map from a browser context to an id mapping -//----------------------------------------------------------- -typedef std::map<void*, StringToJExt_T*> VoidToMap_T; - -VoidToMap_T g_context2Map; - -class GlobalSharedModule -{ - -public: - GlobalSharedModule( void ) - { - g_pszRetVal = new char[ nMAXSIZE ]; - } - - ~GlobalSharedModule() - { - delete [] g_pszRetVal; - - VoidToMap_T::iterator posMaps; - - for ( posMaps = g_context2Map.begin(); posMaps != g_context2Map.end(); ++posMaps ) - { - StringToJExt_T& id2Obj = *posMaps->second; - StringToJExt_T::iterator posMap; - - for ( posMap = id2Obj.begin(); posMap != id2Obj.end(); ++posMap ) - { - JSExt* pJSExt = posMap->second; - - if ( pJSExt->CanDelete() ) - { - delete pJSExt; - } - } - - id2Obj.erase( id2Obj.begin(), id2Obj.end() ); - } - - g_context2Map.erase( g_context2Map.begin(), g_context2Map.end() ); - } -}; - -GlobalSharedModule g_sharedModule; - -char* g_str2global( const string& strRetVal ) -{ - int nLen = strRetVal.size(); - - if ( nLen >= nMAXSIZE ) - { - delete [] g_pszRetVal; - g_pszRetVal = new char[ nLen + 1 ]; - } - - else - { - // To minimaize the number of memory reallocations, the assumption - // is that in most times this will be the case - delete [] g_pszRetVal; - g_pszRetVal = new char[ nMAXSIZE ]; - } - - strcpy( g_pszRetVal, strRetVal.c_str() ); - return g_pszRetVal; -} - -bool g_unregisterObject( const string& strObjId, void* pContext ) -{ - // Called by the plugin extension implementation - // if the extension handles the deletion of its object - - StringToJExt_T * pID2Obj = NULL; - - VoidToMap_T::iterator iter = g_context2Map.find( pContext ); - - if ( iter != g_context2Map.end() ) - { - pID2Obj = iter->second; - } - else - { - return false; - } - - StringToJExt_T& mapID2Obj = *pID2Obj; - - StringToJExt_T::iterator r = mapID2Obj.find( strObjId ); - - if ( r == mapID2Obj.end() ) - { - return false; - } - - mapID2Obj.erase( strObjId ); - return true; -} - -char* InvokeFunction( const char* szCommand, void* pContext ) -{ - StringToJExt_T * pID2Obj = NULL; - - VoidToMap_T::iterator iter = g_context2Map.find( pContext ); - - if ( iter != g_context2Map.end() ) - { - pID2Obj = iter->second; - } - else - { - pID2Obj = new StringToJExt_T; - g_context2Map[ pContext ] = pID2Obj; - } - - StringToJExt_T& mapID2Obj = *pID2Obj; - - string strFullCommand = szCommand; - vector<string> arParams; - g_tokenize( strFullCommand, " ", arParams ); - string strCommand = arParams[ 0 ]; - string strRetVal = szERROR; - - if ( strCommand == szCREATE ) - { - string strClassName = arParams[ 1 ]; - string strObjId = arParams[ 2 ]; - - StringToJExt_T::iterator r = mapID2Obj.find( strObjId ); - - if ( r != mapID2Obj.end() ) - { - strRetVal += strObjId; - strRetVal += " :Object already exists."; - return g_str2global( strRetVal ); - } - - JSExt* pJSExt = onCreateObject( strClassName, strObjId ); - - if ( pJSExt == NULL ) - { - strRetVal += strObjId; - strRetVal += " :Unknown object type "; - strRetVal += strClassName; - return g_str2global( strRetVal ); - } - - pJSExt->m_pContext = pContext; - mapID2Obj[ strObjId ] = pJSExt; - - strRetVal = szOK; - strRetVal += strObjId; - return g_str2global( strRetVal ); - } - else - if ( strCommand == szINVOKE ) - { - string strObjId = arParams[ 1 ]; - string strMethod = arParams[ 2 ]; - - StringToJExt_T::iterator r = mapID2Obj.find( strObjId ); - - if ( r == mapID2Obj.end() ) - { - strRetVal += strObjId; - strRetVal += " :No object found for id."; - return g_str2global( strRetVal ); - } - - JSExt* pJSExt = r->second; - - size_t nLoc = strFullCommand.find( strObjId ); - - if ( nLoc == string::npos ) - { - strRetVal += strObjId; - strRetVal += " :Internal InvokeMethod error."; - return g_str2global( strRetVal ); - } - - if ( strMethod == szDISPOSE ) - { - StringToJExt_T::iterator r = mapID2Obj.find( strObjId ); - - if ( r == mapID2Obj.end() ) - { - strRetVal = szERROR; - strRetVal += strObjId; - return g_str2global( strRetVal ); - } - - JSExt * pJSExt = mapID2Obj[ strObjId ]; - - if ( pJSExt->CanDelete() ) - { - delete pJSExt; - } - - mapID2Obj.erase( strObjId ); - strRetVal = szOK; - strRetVal += strObjId; - return g_str2global( strRetVal ); - } - - size_t nSuffixLoc = nLoc + strObjId.size(); - string strInvoke = strFullCommand.substr( nSuffixLoc ); - strInvoke = g_trim( strInvoke ); - strRetVal = pJSExt->InvokeMethod( strInvoke ); - return g_str2global( strRetVal ); - } - - strRetVal += " :Unknown command "; - strRetVal += strCommand; - return g_str2global( strRetVal ); -} - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/plugin.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/plugin.h deleted file mode 100644 index 4ef71169..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/plugin.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _PLUGIN_H -#define _PLUGIN_H - -#include <map> -#include <string> -#include <vector> -#include <unistd.h> -//#include "tokenizer.h" - -using namespace std; - -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%% Functions exported by this DLL -//%% Should always be only SetEventFunc and InvokeFunction -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -// g++ requires extern "C" otherwise the names of SetEventFunc and InvokeFunction -// are mangled C++ style. MS Visual Studio doesn't seem to care though. -extern "C" -{ - typedef void (*SendPluginEv)( const char* szEvent, void* pContext ); - char* SetEventFunc(SendPluginEv funcPtr); - char* InvokeFunction( const char* szCommand, void* pContext ); -} - -// JNEXT Framework function of the form: -// typedef void (*SendPluginEv)( const char* szEvent ); -// used to notify JavaScript of an asynchronous event -extern SendPluginEv SendPluginEvent; - -///////////////////////////////////////////////////////////////////////// -// Constants and methods common to all JNEXT extensions types -///////////////////////////////////////////////////////////////////////// -#define szERROR "Error " -#define szOK "Ok " - -#define szDISPOSE "Dispose" -#define szINVOKE "InvokeMethod" -#define szCREATE "CreateObj" - -///////////////////////////////////////////////////////////////////////// -// Utility functions -///////////////////////////////////////////////////////////////////////// -string& g_trim( string& str ); -void g_tokenize(const string& str,const string& delimiters, vector<string>& tokens); -char* g_str2static( const string& strRetVal ); -void g_sleep( unsigned int mseconds ); -bool g_unregisterObject( const string& strObjId, void* pContext ); - - -///////////////////////////////////////////////////////////////////////// -// Abstract extension object -///////////////////////////////////////////////////////////////////////// -class JSExt -{ -public: - virtual ~JSExt() {}; - virtual string InvokeMethod( const string& strCommand ) = 0; - virtual bool CanDelete( void ) = 0; - virtual void TryDelete( void ) {} -public: - void* m_pContext; -}; - -///////////////////////////////////////////////////////////////////////// -// Callback functions to be implemented by the plugin implementation -///////////////////////////////////////////////////////////////////////// -extern char* onGetObjList( void ); -extern JSExt* onCreateObject( const string& strClassName, const string& strObjId ); - -#endif diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/tokenizer.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/public/tokenizer.cpp deleted file mode 100644 index 4a39573b..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/tokenizer.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/************************************************************************ -The zlib/libpng License - -Copyright (c) 2006 Joerg Wiedenmann - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from -the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; -you must not claim that you wrote the original software. -If you use this software in a product, an acknowledgment -in the product documentation would be appreciated but is -not required. - -2. Altered source versions must be plainly marked as such, -and must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - -***********************************************************************/ - -/******************************************************************** - created: 2006-01-28 - filename: tokenizer.cpp - author: Jrg Wiedenmann - - purpose: A tokenizer function which provides a very - customizable way of breaking up strings. - - history: 2006-01-28, Original version - 2006-03-04, Fixed a small parsing bug, thanks Elias. -*********************************************************************/ - -#include "tokenizer.h" - -using namespace std; - -void tokenize ( const string& str, vector<string>& result, - const string& delimiters, const string& delimiters_preserve, - const string& quote, const string& esc ) -{ - // clear the vector - if ( false == result.empty() ) - { - result.clear(); - } - - string::size_type pos = 0; // the current position (char) in the string - char ch = 0; // buffer for the current character - char delimiter = 0; // the buffer for the delimiter char which - // will be added to the tokens if the delimiter - // is preserved - char current_quote = 0; // the char of the current open quote - bool quoted = false; // indicator if there is an open quote - string token; // string buffer for the token - bool token_complete = false; // indicates if the current token is - // read to be added to the result vector - string::size_type len = str.length(); // length of the input-string - - // for every char in the input-string - while ( len > pos ) - { - // get the character of the string and reset the delimiter buffer - ch = str.at(pos); - delimiter = 0; - - // assume ch isn't a delimiter - bool add_char = true; - - // check ... - - // ... if the delimiter is an escaped character - bool escaped = false; // indicates if the next char is protected - if ( false == esc.empty() ) // check if esc-chars are provided - { - if ( string::npos != esc.find_first_of(ch) ) - { - // get the escaped char - ++pos; - if ( pos < len ) // if there are more chars left - { - // get the next one - ch = str.at(pos); - - // add the escaped character to the token - add_char = true; - } - else // cannot get any more characters - { - // don't add the esc-char - add_char = false; - } - - // ignore the remaining delimiter checks - escaped = true; - } - } - - // ... if the delimiter is a quote - if ( false == quote.empty() && false == escaped ) - { - // if quote chars are provided and the char isn't protected - if ( string::npos != quote.find_first_of(ch) ) - { - // if not quoted, set state to open quote and set - // the quote character - if ( false == quoted ) - { - quoted = true; - current_quote = ch; - - // don't add the quote-char to the token - add_char = false; - } - else // if quote is open already - { - // check if it is the matching character to close it - if ( current_quote == ch ) - { - // close quote and reset the quote character - quoted = false; - current_quote = 0; - - // don't add the quote-char to the token - add_char = false; - } - } // else - } - } - - // ... if the delimiter isn't preserved - if ( false == delimiters.empty() && false == escaped && - false == quoted ) - { - // if a delimiter is provided and the char isn't protected by - // quote or escape char - if ( string::npos != delimiters.find_first_of(ch) ) - { - // if ch is a delimiter and the token string isn't empty - // the token is complete - if ( false == token.empty() ) // BUGFIX: 2006-03-04 - { - token_complete = true; - } - - // don't add the delimiter to the token - add_char = false; - } - } - - // ... if the delimiter is preserved - add it as a token - bool add_delimiter = false; - if ( false == delimiters_preserve.empty() && false == escaped && - false == quoted ) - { - // if a delimiter which will be preserved is provided and the - // char isn't protected by quote or escape char - if ( string::npos != delimiters_preserve.find_first_of(ch) ) - { - // if ch is a delimiter and the token string isn't empty - // the token is complete - if ( false == token.empty() ) // BUGFIX: 2006-03-04 - { - token_complete = true; - } - - // don't add the delimiter to the token - add_char = false; - - // add the delimiter - delimiter = ch; - add_delimiter = true; - } - } - - - // add the character to the token - if ( true == add_char ) - { - // add the current char - token.push_back( ch ); - } - - // add the token if it is complete - if ( true == token_complete && false == token.empty() ) - { - // add the token string - result.push_back( token ); - - // clear the contents - token.clear(); - - // build the next token - token_complete = false; - } - - // add the delimiter - if ( true == add_delimiter ) - { - // the next token is the delimiter - string delim_token; - delim_token.push_back( delimiter ); - result.push_back( delim_token ); - - // REMOVED: 2006-03-04, Bugfix - } - - // repeat for the next character - ++pos; - } // while - - // add the final token - if ( false == token.empty() ) - { - result.push_back( token ); - } -} diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/public/tokenizer.h b/plugins/com.ionic.keyboard/src/blackberry10/native/public/tokenizer.h deleted file mode 100644 index 75f567ce..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/public/tokenizer.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************ -The zlib/libpng License - -Copyright (c) 2006 Joerg Wiedenmann - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from -the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; - you must not claim that you wrote the original software. - If you use this software in a product, an acknowledgment - in the product documentation would be appreciated but is - not required. - -2. Altered source versions must be plainly marked as such, - and must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. - -***********************************************************************/ - -/******************************************************************** - created: 2006-01-28 - filename: tokenizer.cpp - author: Jrg Wiedenmann - - purpose: A tokenizer function which provides a very - customizable way of breaking up strings. -*********************************************************************/ - -#include <vector> -#include <string> -using namespace std; - -// Function to break up a string into tokens -// -// Parameters: -//----------- -// str = the input string that will be tokenized -// result = the tokens for str -// delimiters = the delimiter characters -// delimiters preserve = same as above, but the delimiter characters -// will be put into the result as a token -// quote = characters to protect the enclosed characters -// esc = characters to protect a single character -// - -void tokenize ( const string& str, vector<string>& result, - const string& delimiters, const string& delimiters_preserve = "", - const string& quote = "\"", const string& esc = "\\" ); diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_reader.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_reader.o Binary files differdeleted file mode 100644 index 16859fdb..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_reader.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_value.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_value.o Binary files differdeleted file mode 100644 index 396e7e4d..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_value.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_writer.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_writer.o Binary files differdeleted file mode 100644 index 7d1452d4..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/json_writer.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/plugin.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/plugin.o Binary files differdeleted file mode 100644 index 13048453..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/plugin.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/tokenizer.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/tokenizer.o Binary files differdeleted file mode 100644 index 4b4683cc..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/public/tokenizer.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/CallKeyboard.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/CallKeyboard.o Binary files differdeleted file mode 100644 index c67ac9e6..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/CallKeyboard.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/Logger.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/Logger.o Binary files differdeleted file mode 100644 index 7bb472f2..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/Logger.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/keyboard_js.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/keyboard_js.o Binary files differdeleted file mode 100644 index 2a578357..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/keyboard_js.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/keyboard_ndk.o b/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/keyboard_ndk.o Binary files differdeleted file mode 100644 index 989dc0b3..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/simulator/src/keyboard_ndk.o +++ /dev/null diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/src/Logger.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/src/Logger.cpp deleted file mode 100644 index 57b7075e..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/src/Logger.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2013 BlackBerry Limited - * - * Licensed 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 "Logger.hpp" -#include "keyboard_js.hpp" -#include <slog2.h> - -namespace webworks { - -Logger::Logger(const char* name, Keyboard_JS *parent): m_pParent(parent) { - buffer_config.buffer_set_name = name; - buffer_config.num_buffers = 2; - buffer_config.verbosity_level = SLOG2_DEBUG1; - - /* Configure the first buffer, using 7 x 4KB pages. This larger buffer will be used for - very chatty logging. Our goal is to have 30-60 seconds of history at any given time, - so we will want to log at a rate of around one log line with a string of 16 bytes - long every 150 milliseconds. - */ - - buffer_config.buffer_config[0].buffer_name = "low_priority"; - buffer_config.buffer_config[0].num_pages = 7; - - /* Configure the second buffer, which we will use for high level info logging that is very - infrequent, but we want a longer history (hours or maybe even over a day or two). This - buffer uses 1 x 4KB. - */ - - buffer_config.buffer_config[1].buffer_name = "high_priority"; - buffer_config.buffer_config[1].num_pages = 1; - - /* Register the buffer set. */ - - if( -1 == slog2_register( &buffer_config, buffer_handle, 0 ) ) { - fprintf( stderr, "Error registering slogger2 buffer!\n" ); - } else { - info("Created slogger2 buffers"); - } - -} - -Logger::~Logger() { - critical("slogger2 buffers reset"); - slog2_reset(); -} - -int Logger::log(slog2_buffer_t buffer, _Uint8t severity, const char* message) { - return slog2c(buffer, 0, severity, message); -} - -int Logger::debug(const char* message) { - return log(lowPriorityBuffer(), SLOG2_DEBUG1, message); -} - -int Logger::info(const char* message) { - return log(lowPriorityBuffer(), SLOG2_INFO, message); -} - -int Logger::notice(const char* message) { - return log(lowPriorityBuffer(), SLOG2_NOTICE, message); -} - -int Logger::warn(const char* message) { - return log(lowPriorityBuffer(), SLOG2_WARNING, message); -} - -int Logger::error(const char* message) { - return log(hiPriorityBuffer(), SLOG2_ERROR, message); -} - -int Logger::critical(const char* message) { - return log(hiPriorityBuffer(), SLOG2_CRITICAL, message); -} - -int Logger::setVerbosity(_Uint8t verbosity) { - return slog2_set_verbosity(buffer_handle[0], verbosity); -} - -_Uint8t Logger::getVerbosity() { - return slog2_get_verbosity(buffer_handle[0]); -} - -slog2_buffer_t Logger::hiPriorityBuffer() { - return buffer_handle[1]; -} - -slog2_buffer_t Logger::lowPriorityBuffer() { - return buffer_handle[0]; -} - -} /* namespace webworks */ diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/src/Logger.hpp b/plugins/com.ionic.keyboard/src/blackberry10/native/src/Logger.hpp deleted file mode 100644 index ca379ca7..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/src/Logger.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 BlackBerry Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LOGGER_HPP_ -#define LOGGER_HPP_ - -#include <string> -#include <slog2.h> - -class Keyboard_JS; - -namespace webworks { - -class Logger { -public: - explicit Logger(const char* name, Keyboard_JS *parent = NULL); - virtual ~Logger(); - int debug(const char* message); - int info(const char* message); - int notice(const char* message); - int warn(const char* message); - int error(const char* message); - int critical(const char* message); - int setVerbosity(_Uint8t verbosity); - _Uint8t getVerbosity(); - slog2_buffer_t hiPriorityBuffer(); - slog2_buffer_t lowPriorityBuffer(); -private: - Keyboard_JS *m_pParent; - slog2_buffer_set_config_t buffer_config; - slog2_buffer_t buffer_handle[2]; - int log(slog2_buffer_t buffer, _Uint8t severity, const char* message); -}; - -} /* namespace webworks */ -#endif /* LOGGER_HPP_ */ diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_js.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_js.cpp deleted file mode 100644 index 64250a14..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_js.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2013 BlackBerry Limited - * - * Licensed 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 <string> -#include "../public/tokenizer.h" -#include "keyboard_js.hpp" -#include "keyboard_ndk.hpp" -#include <sstream> - -using namespace std; - -/** - * Default constructor. - */ -Keyboard_JS::Keyboard_JS(const std::string& id) : - m_id(id) { - m_pLogger = new webworks::Logger("Keyboard_JS", this); - m_pKeyboardController = new webworks::Keyboard_NDK(this); - - -} - -/** - * Keyboard_JS destructor. - */ -Keyboard_JS::~Keyboard_JS() { - if (m_pKeyboardController) - delete m_pKeyboardController; - if (m_pLogger) - delete m_pLogger; -} - -webworks::Logger* Keyboard_JS::getLog() { - return m_pLogger; -} - -/** - * This method returns the list of objects implemented by this native - * extension. - */ -char* onGetObjList() { - static char name[] = "Keyboard_JS"; - return name; -} - -/** - * This method is used by JNext to instantiate the Keyboard_JS object when - * an object is created on the JavaScript server side. - */ -JSExt* onCreateObject(const string& className, const string& id) { - if (className == "Keyboard_JS") { - return new Keyboard_JS(id); - } - - return NULL; -} - -/** - * Method used by JNext to determine if the object can be deleted. - */ -bool Keyboard_JS::CanDelete() { - return true; -} - -/** - * It will be called from JNext JavaScript side with passed string. - * This method implements the interface for the JavaScript to native binding - * for invoking native code. This method is triggered when JNext.invoke is - * called on the JavaScript side with this native objects id. - */ -string Keyboard_JS::InvokeMethod(const string& command) { - // format must be: "command callbackId params" - size_t commandIndex = command.find_first_of(" "); - std::string strCommand = command.substr(0, commandIndex); - size_t callbackIndex = command.find_first_of(" ", commandIndex + 1); - std::string callbackId = command.substr(commandIndex + 1, callbackIndex - commandIndex - 1); - std::string arg = command.substr(callbackIndex + 1, command.length()); - - // based on the command given, run the appropriate method in keyboard_ndk.cpp - if (strCommand == "showKeyboard") { - m_pKeyboardController->callKeyboardEmail(); - return "Show Keyboard"; - } else if (strCommand == "closeKeyboard") { - m_pKeyboardController->cancelKeyboard(); - return "Cancel Keyboard"; - } - else if(strCommand == "startService"){ - m_pKeyboardController->keyboardStartThread(); - return "Starting Service"; - } - - strCommand.append(";"); - strCommand.append(command); - return strCommand; -} - -// Notifies JavaScript of an event -void Keyboard_JS::NotifyEvent(const std::string& event) { - std::string eventString = m_id + " "; - eventString.append(event); - SendPluginEvent(eventString.c_str(), m_pContext); - -} - diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_js.hpp b/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_js.hpp deleted file mode 100644 index 1ed3bb78..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_js.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -* Copyright (c) 2013 BlackBerry Limited -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef Keyboard_JS_HPP_ -#define Keyboard_JS_HPP_ - -#include <string> -#include "../public/plugin.h" -#include "keyboard_ndk.hpp" -#include "Logger.hpp" - - -class Keyboard_JS: public JSExt { - -public: - explicit Keyboard_JS(const std::string& id); - virtual ~Keyboard_JS(); - virtual bool CanDelete(); - virtual std::string InvokeMethod(const std::string& command); - void NotifyEvent(const std::string& event); - webworks::Logger* getLog(); -private: - std::string m_id; - webworks::Keyboard_NDK *m_pKeyboardController; - webworks::Logger *m_pLogger; - -}; - -#endif /* Keyboard_JS_HPP_ */ diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_ndk.cpp b/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_ndk.cpp deleted file mode 100644 index 26b2e39a..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_ndk.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2013 BlackBerry Limited - * - * Licensed 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 <string> -#include <sstream> -#include <json/reader.h> -#include <json/writer.h> -#include <pthread.h> -#include "keyboard_ndk.hpp" -#include "keyboard_js.hpp" -#include <QtCore> -namespace webworks { - -Keyboard_NDK::Keyboard_NDK(Keyboard_JS *parent): - m_pParent(parent), - keyboardProperty(50), - keyboardThreadCount(1), - threadHalt(true), - m_thread(0) { - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - bps_initialize(); - - virtualkeyboard_request_events(0); - - virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_EMAIL,VIRTUALKEYBOARD_ENTER_DEFAULT); - - m_pParent->getLog()->info("Keyboard Created"); - - -} - - -Keyboard_NDK::~Keyboard_NDK() { - //bps_shutdown(); -} - - -// Loops and runs the callback method -void* KeyboardThread(void* parent) { - Keyboard_NDK *pParent = static_cast<Keyboard_NDK *>(parent); - - sleep(1); - - // 1. Start the library - bps_initialize(); - - // 2. Request events to flow into the event queue - virtualkeyboard_request_events(0); - - sleep(3); - // 3. Use any service at any time - //virtualkeyboard_show(); // Show the virtual keyboard - - // 4. Listen for events - for (;;) { - // get an event - bps_event_t *event; - bps_get_event(&event, -1); // blocking - - // handle the event - pParent->event(event); - } - return NULL; -} - -// Starts the thread and returns a message on status -std::string Keyboard_NDK::keyboardStartThread() { - m_pParent->NotifyEvent("Teste"); - if (!m_thread) { - m_pParent->NotifyEvent("Teste"); - int rc; - rc = pthread_mutex_lock(&mutex); - threadHalt = false; - rc = pthread_cond_signal(&cond); - rc = pthread_mutex_unlock(&mutex); - - pthread_attr_t thread_attr; - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); - - pthread_create(&m_thread, &thread_attr, KeyboardThread, - static_cast<void *>(this)); - pthread_attr_destroy(&thread_attr); - //threadCallbackId = callbackId; - m_pParent->getLog()->info("Thread Started"); - return "Thread Started"; - } else { - m_pParent->getLog()->warn("Thread Started but already running"); - return "Thread Running"; - } -} - - -void Keyboard_NDK::event(bps_event_t *event) { - Json::FastWriter writer; - Json::Value root; - root["threadCount"] = "10"; - int domain = bps_event_get_domain(event); - if (domain == virtualkeyboard_get_domain()) { - int code = bps_event_get_code(event); - int a; - std::string str; - std::string eventString; - std::ostringstream strs; - switch(code) { - case VIRTUALKEYBOARD_EVENT_VISIBLE: - eventString = "native.keyboardshow"; - eventString.append(" "); - virtualkeyboard_get_height(&a) ; - strs << a; - str = strs.str(); - eventString.append("{\"keyboardHeight\":\""+str+"\"}"); - m_pParent->NotifyEvent(eventString); - - break; - case VIRTUALKEYBOARD_EVENT_HIDDEN: - - m_pParent->NotifyEvent("native.keyboardhide"); - break; - } - } - -} -void Keyboard_NDK::callKeyboardEmail(){ - virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_EMAIL,VIRTUALKEYBOARD_ENTER_SEND); - virtualkeyboard_show(); -} - -void Keyboard_NDK::callKeyboardNumber(){ - - virtualkeyboard_change_options(VIRTUALKEYBOARD_LAYOUT_NUMBER,VIRTUALKEYBOARD_ENTER_SEND); - virtualkeyboard_show(); -} -void Keyboard_NDK::cancelKeyboard(){ - virtualkeyboard_hide(); -} - - - - -} diff --git a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_ndk.hpp b/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_ndk.hpp deleted file mode 100644 index 01062274..00000000 --- a/plugins/com.ionic.keyboard/src/blackberry10/native/src/keyboard_ndk.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Copyright (c) 2013 BlackBerry Limited -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef Keyboard_NDK_HPP_ -#define Keyboard_NDK_HPP_ - -#include <string> -#include <pthread.h> -#include <bb/AbstractBpsEventHandler> -#include <bps/bps.h> -#include<bps/netstatus.h> -#include<bps/locale.h> -#include<bps/virtualkeyboard.h> -#include<bps/navigator.h> -#include <bps/event.h> -#include <string> -#include <sstream> - -class Keyboard_JS; - -namespace webworks { - -class Keyboard_NDK { -public: - explicit Keyboard_NDK(Keyboard_JS *parent = NULL); - virtual ~Keyboard_NDK(); - virtual void event(bps_event_t *event); - - void callKeyboardEmail(); // Method Calls the Keyboard style Email (default) - - void callKeyboardNumber(); // Method Calls the Keyboard style number - - void cancelKeyboard(); // Method cancel the keyboard - - std::string keyboardStartThread(); - - - - - - - -private: - - Keyboard_JS *m_pParent; - int keyboardProperty; - int keyboardThreadCount; - bool threadHalt; - std::string threadCallbackId; - pthread_t m_thread; - pthread_cond_t cond; - pthread_mutex_t mutex; - -}; - -} // namespace webworks - -#endif /* Keyboard_NDK_HPP_ */ diff --git a/plugins/com.ionic.keyboard/src/ios/IonicKeyboard.h b/plugins/com.ionic.keyboard/src/ios/IonicKeyboard.h deleted file mode 100644 index b54f430d..00000000 --- a/plugins/com.ionic.keyboard/src/ios/IonicKeyboard.h +++ /dev/null @@ -1,13 +0,0 @@ -#import <Cordova/CDVPlugin.h> - -@interface IonicKeyboard : CDVPlugin <UIScrollViewDelegate> { - @protected - id _keyboardShowObserver, _keyboardHideObserver; -} - -@property (readwrite, assign) BOOL hideKeyboardAccessoryBar; -@property (readwrite, assign) BOOL disableScroll; -//@property (readwrite, assign) BOOL styleDark; - -@end - diff --git a/plugins/com.ionic.keyboard/src/ios/IonicKeyboard.m b/plugins/com.ionic.keyboard/src/ios/IonicKeyboard.m deleted file mode 100644 index 045cc65f..00000000 --- a/plugins/com.ionic.keyboard/src/ios/IonicKeyboard.m +++ /dev/null @@ -1,160 +0,0 @@ -#import "IonicKeyboard.h" -#import "UIWebViewExtension.h" -#import <Cordova/CDVAvailability.h> - -@implementation IonicKeyboard - -@synthesize hideKeyboardAccessoryBar = _hideKeyboardAccessoryBar; -@synthesize disableScroll = _disableScroll; -//@synthesize styleDark = _styleDark; - -- (void)pluginInitialize { - - NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; - __weak IonicKeyboard* weakSelf = self; - - //set defaults - self.hideKeyboardAccessoryBar = NO; - self.disableScroll = NO; - //self.styleDark = NO; - - _keyboardShowObserver = [nc addObserverForName:UIKeyboardWillShowNotification - object:nil - queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification* notification) { - - CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; - keyboardFrame = [self.viewController.view convertRect:keyboardFrame fromView:nil]; - - [weakSelf.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.plugins.Keyboard.isVisible = true; cordova.fireWindowEvent('native.keyboardshow', { 'keyboardHeight': %@ }); ", [@(keyboardFrame.size.height) stringValue]]]; - - //deprecated - [weakSelf.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireWindowEvent('native.showkeyboard', { 'keyboardHeight': %@ }); ", [@(keyboardFrame.size.height) stringValue]]]; - }]; - - _keyboardHideObserver = [nc addObserverForName:UIKeyboardWillHideNotification - object:nil - queue:[NSOperationQueue mainQueue] - usingBlock:^(NSNotification* notification) { - [weakSelf.commandDelegate evalJs:@"cordova.plugins.Keyboard.isVisible = false; cordova.fireWindowEvent('native.keyboardhide'); "]; - - //deprecated - [weakSelf.commandDelegate evalJs:@"cordova.fireWindowEvent('native.hidekeyboard'); "]; - }]; -} -- (BOOL)disableScroll { - return _disableScroll; -} - -- (void)setDisableScroll:(BOOL)disableScroll { - if (disableScroll == _disableScroll) { - return; - } - if (disableScroll) { - self.webView.scrollView.scrollEnabled = NO; - self.webView.scrollView.delegate = self; - } - else { - self.webView.scrollView.scrollEnabled = YES; - self.webView.scrollView.delegate = nil; - } - - _disableScroll = disableScroll; -} - - -- (BOOL)hideKeyboardAccessoryBar { - return _hideKeyboardAccessoryBar; -} - -- (void)setHideKeyboardAccessoryBar:(BOOL)hideKeyboardAccessoryBar { - if (hideKeyboardAccessoryBar == _hideKeyboardAccessoryBar) { - return; - } - if (hideKeyboardAccessoryBar) { - self.webView.hackishlyHidesInputAccessoryView = YES; - } - else { - self.webView.hackishlyHidesInputAccessoryView = NO; - } - - _hideKeyboardAccessoryBar = hideKeyboardAccessoryBar; -} - -/* -- (BOOL)styleDark { - return _styleDark; -} - -- (void)setStyleDark:(BOOL)styleDark { - if (styleDark == _styleDark) { - return; - } - if (styleDark) { - self.webView.styleDark = YES; - } - else { - self.webView.styleDark = NO; - } - - _styleDark = styleDark; -} -*/ - - -/* ------------------------------------------------------------- */ - -- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - [scrollView setContentOffset: CGPointZero]; -} - -/* ------------------------------------------------------------- */ - -- (void)dealloc { - NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; - - [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil]; - [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil]; -} - -/* ------------------------------------------------------------- */ - -- (void) disableScroll:(CDVInvokedUrlCommand*)command { - if (!command.arguments || ![command.arguments count]){ - return; - } - id value = [command.arguments objectAtIndex:0]; - - self.disableScroll = [value boolValue]; -} - -- (void) hideKeyboardAccessoryBar:(CDVInvokedUrlCommand*)command { - if (!command.arguments || ![command.arguments count]){ - return; - } - id value = [command.arguments objectAtIndex:0]; - - self.hideKeyboardAccessoryBar = [value boolValue]; -} - -- (void) close:(CDVInvokedUrlCommand*)command { - [self.webView endEditing:YES]; -} - -- (void) show:(CDVInvokedUrlCommand*)command { - NSLog(@"Showing keyboard not supported in iOS due to platform limitations."); -} - -/* -- (void) styleDark:(CDVInvokedUrlCommand*)command { - if (!command.arguments || ![command.arguments count]){ - return; - } - id value = [command.arguments objectAtIndex:0]; - - self.styleDark = [value boolValue]; -} -*/ - -@end - diff --git a/plugins/com.ionic.keyboard/src/ios/UIWebViewExtension.h b/plugins/com.ionic.keyboard/src/ios/UIWebViewExtension.h deleted file mode 100644 index 1d6c293d..00000000 --- a/plugins/com.ionic.keyboard/src/ios/UIWebViewExtension.h +++ /dev/null @@ -1,4 +0,0 @@ -@interface UIWebView (HackishAccessoryHiding) -@property (nonatomic, assign) BOOL hackishlyHidesInputAccessoryView; -//@property (nonatomic, assign) BOOL styleDark; -@end diff --git a/plugins/com.ionic.keyboard/src/ios/UIWebViewExtension.m b/plugins/com.ionic.keyboard/src/ios/UIWebViewExtension.m deleted file mode 100644 index 25403e6f..00000000 --- a/plugins/com.ionic.keyboard/src/ios/UIWebViewExtension.m +++ /dev/null @@ -1,109 +0,0 @@ -#import <objc/runtime.h> -#import <UIKit/UIKit.h> -#import "UIWebViewExtension.h" - -//Credit: https://gist.github.com/bjhomer/2048571 -//Also: http://stackoverflow.com/a/23398487/1091751 -@implementation UIWebView (HackishAccessoryHiding) - -static const char * const hackishFixClassName = "UIWebBrowserViewMinusAccessoryView"; -static Class hackishFixClass = Nil; - -- (UIView *)hackishlyFoundBrowserView { - UIScrollView *scrollView = self.scrollView; - - UIView *browserView = nil; - for (UIView *subview in scrollView.subviews) { - if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) { - browserView = subview; - break; - } - } - return browserView; -} - -- (id)methodReturningNil { - return nil; -} - -- (void)ensureHackishSubclassExistsOfBrowserViewClass:(Class)browserViewClass { - if (!hackishFixClass) { - Class newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0); - IMP nilImp = [self methodForSelector:@selector(methodReturningNil)]; - class_addMethod(newClass, @selector(inputAccessoryView), nilImp, "@@:"); - objc_registerClassPair(newClass); - - hackishFixClass = newClass; - } -} - -- (BOOL) hackishlyHidesInputAccessoryView { - UIView *browserView = [self hackishlyFoundBrowserView]; - return [browserView class] == hackishFixClass; -} - -- (void) setHackishlyHidesInputAccessoryView:(BOOL)value { - UIView *browserView = [self hackishlyFoundBrowserView]; - if (browserView == nil) { - return; - } - [self ensureHackishSubclassExistsOfBrowserViewClass:[browserView class]]; - - if (value) { - object_setClass(browserView, hackishFixClass); - } - else { - Class normalClass = objc_getClass("UIWebBrowserView"); - object_setClass(browserView, normalClass); - } - [browserView reloadInputViews]; -} -/* ---------------------------------------------------------------- */ - -/* -- (UIKeyboardAppearance) darkKeyboardAppearanceTemplateMethod { - return UIKeyboardAppearanceDark; -} - -- (UIKeyboardAppearance) lightKeyboardAppearanceTemplateMethod { - return UIKeyboardAppearanceLight; -} - -- (BOOL) styleDark { - UIView *browserView = [self hackishlyFoundBrowserView]; - if (browserView == nil) { - return false; - } - - Method m = class_getInstanceMethod( [self class], @selector( darkKeyboardAppearanceTemplateMethod ) ); - IMP imp = method_getImplementation( m ); - - Method m2 = class_getInstanceMethod( [browserView class], @selector(keyboardAppearance) ); - IMP imp2 = method_getImplementation( m2 ); - - return imp == imp2; -} - -- (void) setStyleDark:(BOOL)styleDark { - UIView *browserView = [self hackishlyFoundBrowserView]; - if (browserView == nil) { - return; - } - - if ( styleDark ) { - Method m = class_getInstanceMethod( [self class], @selector( darkKeyboardAppearanceTemplateMethod ) ); - IMP imp = method_getImplementation( m ); - const char* typeEncoding = method_getTypeEncoding( m ); - class_replaceMethod( [browserView class], @selector(keyboardAppearance), imp, typeEncoding ); - } - else { - Method m = class_getInstanceMethod( [self class], @selector( lightKeyboardAppearanceTemplateMethod ) ); - IMP imp = method_getImplementation( m ); - const char* typeEncoding = method_getTypeEncoding( m ); - class_replaceMethod( [browserView class], @selector(keyboardAppearance), imp, typeEncoding ); - } -} -*/ - -@end - diff --git a/plugins/com.ionic.keyboard/www/keyboard.js b/plugins/com.ionic.keyboard/www/keyboard.js deleted file mode 100644 index 21b3bf63..00000000 --- a/plugins/com.ionic.keyboard/www/keyboard.js +++ /dev/null @@ -1,37 +0,0 @@ - -var argscheck = require('cordova/argscheck'), - utils = require('cordova/utils'), - exec = require('cordova/exec'); - - -var Keyboard = function() { -}; - -Keyboard.hideKeyboardAccessoryBar = function(hide) { - exec(null, null, "Keyboard", "hideKeyboardAccessoryBar", [hide]); -}; - -Keyboard.close = function() { - exec(null, null, "Keyboard", "close", []); -}; - -Keyboard.show = function() { - exec(null, null, "Keyboard", "show", []); -}; - -Keyboard.disableScroll = function(disable) { - exec(null, null, "Keyboard", "disableScroll", [disable]); -}; - -/* -Keyboard.styleDark = function(dark) { - exec(null, null, "Keyboard", "styleDark", [dark]); -}; -*/ - -Keyboard.isVisible = false; - -module.exports = Keyboard; - - - diff --git a/plugins/com.phonegap.plugins.OrientationLock/LICENSE.md b/plugins/com.phonegap.plugins.OrientationLock/LICENSE.md deleted file mode 100644 index b5627bb1..00000000 --- a/plugins/com.phonegap.plugins.OrientationLock/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2012-2014 Emil Varga <emil.varga@gmail.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/plugins/com.phonegap.plugins.OrientationLock/README.md b/plugins/com.phonegap.plugins.OrientationLock/README.md deleted file mode 100644 index 6a5899ed..00000000 --- a/plugins/com.phonegap.plugins.OrientationLock/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# OrientationLock # - -Android Cordova plugin for locking/unlocking the screen orientation from Javascript - -## Calling the plugin ## - -From your JavaScript code call -`window.plugins.orientationLock.unlock()` to unlock orientation, -`window.plugins.orientationLock.lock("portrait")` or `window.plugins.orientationLock.lock("landscape")` -to lock your screen to the specified orientation. - -To start your Cordova application pre-locked place -`setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);` or -`setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);` -in the `onCreate()` of your Cordova activity. - -Once unlocked, you can track orientation changes with the regular `orientationchange` event: - - window.addEventListener("orientationchange", function() { - alert(window.orientation); - }); - -## Adding the Plugin to your project ## - -Using this plugin requires [Apache Cordova for Android](https://github.com/apache/cordova-android). -Within your project, run the following command: - - cordova plugin add https://github.com/cogitor/PhoneGap-OrientationLock.git - diff --git a/plugins/com.phonegap.plugins.OrientationLock/plugin.xml b/plugins/com.phonegap.plugins.OrientationLock/plugin.xml deleted file mode 100644 index 8bd114b8..00000000 --- a/plugins/com.phonegap.plugins.OrientationLock/plugin.xml +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="com.phonegap.plugins.OrientationLock" - version="0.1"> - - <name>OrientationLock</name> - <author>Emil Varga</author> - - <description> - Android Cordova plugin for locking/unlocking the screen orientation from Javascript. - </description> - - <license>MIT</license> - - <js-module src="www/orientationLock.js" name="OrientationLock"> - <clobbers target="OrientationLock" /> - </js-module> - - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <platform name="android"> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="OrientationLock" > - <param name="android-package" value="com.plugin.phonegap.OrientationLock"/> - </feature> - </config-file> - - <source-file src="src/com/plugin/phonegap/OrientationLock.java" target-dir="src/com/plugin/phonegap/" /> - - </platform> -</plugin> diff --git a/plugins/com.phonegap.plugins.OrientationLock/src/com/plugin/phonegap/OrientationLock.java b/plugins/com.phonegap.plugins.OrientationLock/src/com/plugin/phonegap/OrientationLock.java deleted file mode 100644 index 063fb900..00000000 --- a/plugins/com.phonegap.plugins.OrientationLock/src/com/plugin/phonegap/OrientationLock.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.plugin.phonegap; - -import org.json.JSONArray; -import org.json.JSONException; - -import android.content.pm.ActivityInfo; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; - -/** - * - * Android Phonegap Plugin for locking/unlocking the orientation from JS code - * - */ -public class OrientationLock extends CordovaPlugin { - - private static final String LANSCAPE = "landscape"; - private static final String PORTRAIT = "portrait"; - - public OrientationLock() { - } - - public void unlock() { - this.cordova.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } - - public void lock(String orientation) { - if (orientation.equals(PORTRAIT)) - this.cordova.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - else - this.cordova.getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } - - @Override - public boolean execute(String action, JSONArray arguments, CallbackContext callbackContext) { - if (action.equals("lock")) { - - try { - String orientation = arguments.getString(0); - - if (orientation!=null && (orientation.equals(LANSCAPE) || orientation.equals(PORTRAIT))) { - this.lock(orientation); - callbackContext.success(); - return true; - } else { - return false; - } - } catch (JSONException e) { - callbackContext.error("JSON_EXCEPTION"); - return true; - } - - } else if (action.equals("unlock")) { - this.unlock(); - callbackContext.success(); - return true; - - } else { - return false; - } - } -} diff --git a/plugins/com.phonegap.plugins.OrientationLock/www/orientationLock.js b/plugins/com.phonegap.plugins.OrientationLock/www/orientationLock.js deleted file mode 100644 index 099a5359..00000000 --- a/plugins/com.phonegap.plugins.OrientationLock/www/orientationLock.js +++ /dev/null @@ -1,18 +0,0 @@ -var OrientationLock = function() {} - -OrientationLock.prototype.lock = function(orientation, success, fail) { - return cordova.exec(success, fail, "OrientationLock", "lock", [orientation]) -} - -OrientationLock.prototype.unlock = function(success, fail) { - return cordova.exec(success, fail, "OrientationLock", "unlock", []) -} - -if ( ! window.plugins ) { - window.plugins = {} -} -if ( ! window.plugins.orientationLock ) { - window.plugins.orientationLock = new OrientationLock() -} - -module.exports = OrientationLock diff --git a/plugins/cordova-plugin-crosswalk-webview/LICENSE b/plugins/cordova-plugin-crosswalk-webview/LICENSE deleted file mode 100644 index 578fa3bb..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/LICENSE +++ /dev/null @@ -1,235 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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. - -/************************************************/ -This product bundles CordovaXWalkCoreExtensionBridge.java as well -as the XWalk.pak and the Crosswalk JSApi which is available under a -"3-clause BSD" license. For details, see below: - - Copyright (c) 2013 Intel Corporation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/cordova-plugin-crosswalk-webview/NOTICE b/plugins/cordova-plugin-crosswalk-webview/NOTICE deleted file mode 100644 index 81636de1..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/NOTICE +++ /dev/null @@ -1,8 +0,0 @@ -Apache Cordova -Copyright 2014 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org) - -This software includes software developed at Intel Corporation. -Copyright 2014 Intel Corporation diff --git a/plugins/cordova-plugin-crosswalk-webview/PlatformScriptsWorkflow.md b/plugins/cordova-plugin-crosswalk-webview/PlatformScriptsWorkflow.md deleted file mode 100644 index aa31dcd0..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/PlatformScriptsWorkflow.md +++ /dev/null @@ -1,30 +0,0 @@ -### Directions for Non-CLI Android-Only cordova project - -* Pull down the Cordova Android -``` -$ git clone https://github.com/apache/cordova-android.git -``` -* Generate a project, e.g creating HelloWorld -``` -$ /path/to/cordova-android/bin/create hello com.example.hello HelloWorld -``` -* Navigate to the project folder -``` -$ cd hello -``` -* Install Crosswalk engine plugin by plugman (version >= 0.22.17) -``` -$ plugman install --platform android --plugin https://github.com/MobileChromeApps/cordova-crosswalk-engine.git --project . -``` -* Build -``` -$ ./cordova/build -``` -The build script will automatically fetch the Crosswalk WebView libraries from Crosswalk project download site (https://download.01.org/crosswalk/releases/crosswalk/android/) and build for both X86 and ARM architectures. - -For example, building HelloWorld generates: - -``` -/path/to/hello/build/outputs/apk/hello-x86-debug.apk -/path/to/hello/build/outputs/apk/hello-armv7-debug.apk -``` diff --git a/plugins/cordova-plugin-crosswalk-webview/README.md b/plugins/cordova-plugin-crosswalk-webview/README.md deleted file mode 100644 index 768990a8..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/README.md +++ /dev/null @@ -1,112 +0,0 @@ -# cordova-plugin-crosswalk-webview - -Makes your Cordova application use the [Crosswalk WebView](https://crosswalk-project.org/) -instead of the System WebView. Requires cordova-android 4.0 or greater. - -### Benefits - -* WebView doesn't change depending on Android version -* Capabilities: such as WebRTC, WebAudio, Web Components -* Performance improvements (compared to older system webviews) - - -### Drawbacks - -* Increased memory footprint - * An overhead of ~30MB (as reported by the RSS column of ps) -* Increased APK size (about 17MB) -* Increased size on disk when installed (about 50MB) -* Crosswalk WebView stores data (IndexedDB, LocalStorage, etc) separately from System WebView - * You'll need to manually migrate local data when switching between the two (note: this is fixed in Crosswalk 15) - -### Install - -The following directions are for cordova-cli (most people). Alternatively you can use the [Android platform scripts workflow](PlatformScriptsWorkflow.md). - -* Open an existing cordova project, with cordova-android 4.0.0+, and using the latest CLI. Crosswalk variables can be configured as an option when installing the plugin -* Add this plugin - -``` -$ cordova plugin add cordova-plugin-crosswalk-webview -``` - -* Build -``` -$ cordova build android -``` -The build script will automatically fetch the Crosswalk WebView libraries from Crosswalk project download site (https://download.01.org/crosswalk/releases/crosswalk/android/maven2/) and build for both X86 and ARM architectures. - -For example, building android with Crosswalk generates: - -``` -/path/to/hello/platforms/android/build/outputs/apk/hello-x86-debug.apk -/path/to/hello/platforms/android/build/outputs/apk/hello-armv7-debug.apk -``` - -Note that it is also possible to publish a multi-APK application on the Play Store that uses Crosswalk for Pre-L devices, and the (updatable) system webview for L+: - -To build Crosswalk-enabled apks, add this plugin and run: - - $ cordova build --release - -To build System-webview apk, remove this plugin and run: - - $ cordova build --release -- --minSdkVersion=21 - -### Configure - -You can try out a different Crosswalk version by specifying certain variables while installing the plugin, or by changing the value of `xwalkVersion` in your `config.xml` after installing the plugin. Some examples: - - <!-- These are all equivalent --> - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="org.xwalk:xwalk_core_library:14+" - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="xwalk_core_library:14+" - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="14+" - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="14" - <preference name="xwalkVersion" value="org.xwalk:xwalk_core_library:14+" /> - <preference name="xwalkVersion" value="xwalk_core_library:14+" /> - <preference name="xwalkVersion" value="14+" /> - <preference name="xwalkVersion" value="14" /> - -You can also use a Crosswalk beta version. Some examples: - - <!-- These are all equivalent --> - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="org.xwalk:xwalk_core_library_beta:14+" - <preference name="xwalkVersion" value="org.xwalk:xwalk_core_library_beta:14+" /> - -You can set [command-line flags](http://peter.sh/experiments/chromium-command-line-switches/) as well: - - <!-- This is the default --> - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_COMMANDLINE="--disable-pull-to-refresh-effect" - <preference name="xwalkCommandLine" value="--disable-pull-to-refresh-effect" /> - -You can use the Crosswalk [shared mode](https://crosswalk-project.org/documentation/shared_mode.html) which allows multiple Crosswalk applications to share one Crosswalk runtime downloaded from the Play Store. - - <!-- These are all equivalent --> - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_MODE="shared" - <preference name="xwalkMode" value="shared" /> -Note that if you want to specify the Crosswalk version when using shared mode, you need to use the shared version of the library, e.g.: - - <!-- Using a Crosswalk shared mode beta version --> - cordova plugin add cordova-plugin-crosswalk-webview --variable XWALK_VERSION="org.xwalk:xwalk_shared_library_beta:14+" - - -### Release Notes - -#### 1.3.0 (August 28, 2015) -* Crosswalk variables can be configured as an option via CLI -* Support for [Crosswalk's shared mode](https://crosswalk-project.org/documentation/shared_mode.html) via the XWALK_MODE install variable or xwalkMode preference -* Uses the latest Crosswalk 14 stable version by default -* The ANIMATABLE_XWALK_VIEW preference is false by default -* Doesn't work with Crosswalk 14.43.343.17 and earlier - -#### 1.2.0 (April 22, 2015) -* Made Crosswalk command-line configurable via `<preference name="xwalkCommandLine" value="..." />` -* Disabled pull-down-to-refresh by default - -#### 1.1.0 (April 21, 2015) -* Based on Crosswalk v13 -* Made Crosswalk version configurable via `<preference name="xwalkVersion" value="..." />` - -#### 1.0.0 (Mar 25, 2015) -* Initial release -* Based on Crosswalk v11 diff --git a/plugins/cordova-plugin-crosswalk-webview/hooks/after_plugin_install/000-shared_mode_special.js b/plugins/cordova-plugin-crosswalk-webview/hooks/after_plugin_install/000-shared_mode_special.js deleted file mode 100644 index b0581b02..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/hooks/after_plugin_install/000-shared_mode_special.js +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env node - -module.exports = function(context) { - - /** @external */ - var fs = context.requireCordovaModule('fs'), - path = context.requireCordovaModule('path'), - deferral = context.requireCordovaModule('q').defer(), - ConfigParser = context.requireCordovaModule("cordova-lib/src/configparser/ConfigParser"), - XmlHelpers = context.requireCordovaModule("cordova-lib/src/util/xml-helpers"), - et = context.requireCordovaModule('elementtree'); - - /** @defaults */ - var xwalkVariables = {'xwalkVersion':'14+', 'xwalkCommandLine':'--disable-pull-to-refresh-effect', - 'xwalkMode':'embedded'}, - argumentsString = context.cmdLine, - androidPlatformDir = path.join(context.opts.projectRoot, - 'platforms', 'android'), - projectConfigurationFile = path.join(context.opts.projectRoot, - 'config.xml'), - projectManifestFile = path.join(androidPlatformDir, - 'AndroidManifest.xml'), - platformJsonFile = path.join(context.opts.projectRoot, - 'plugins', 'android.json'); - - /** Init */ - var CordovaConfig = new ConfigParser(projectConfigurationFile); - - var addPermission = function() { - var projectManifestXmlRoot = XmlHelpers.parseElementtreeSync(projectManifestFile); - var child = et.XML('<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />'); - XmlHelpers.graftXML(projectManifestXmlRoot, [child], '/manifest'); - fs.writeFileSync(projectManifestFile, projectManifestXmlRoot.write({indent: 4}), 'utf-8'); - } - - /** Set preference */ - var addPreferences = function() { - var configXmlRoot = XmlHelpers.parseElementtreeSync(projectConfigurationFile); - for (name in xwalkVariables) { - var child = et.XML('<preference name="' + name + '" value="' + xwalkVariables[name] + '" />'); - XmlHelpers.graftXML(configXmlRoot, [child], '/*'); - } - fs.writeFileSync(projectConfigurationFile, configXmlRoot.write({indent: 4}), 'utf-8'); - } - - /** The style of name align with config.xml */ - var setConfigPreference = function(name, value) { - var localName = null; - if (name == 'XWALK_VERSION') { - localName = 'xwalkVersion'; - } else if (name == 'XWALK_COMMANDLINE') { - localName = 'xwalkCommandLine'; - } else if (name == 'XWALK_MODE') { - localName = 'xwalkMode'; - } - - if (localName) { - xwalkVariables[localName] = value; - } - } - - /** Pase the cli command to get the specific preferece*/ - var parseCliPreference = function() { - var commandlineVariablesList = argumentsString.split('variable'); - if (commandlineVariablesList) { - commandlineVariablesList.forEach(function(element) { - var spaceList = element.split(' '); - if (spaceList) { - spaceList.forEach(function(element) { - var preference = element.split('='); - if (preference && preference.length == 2) { - setConfigPreference(preference[0].toUpperCase(), preference[1]); - } - }); - } - }); - } - } - - /** Main method */ - var main = function() { - // Parse cli preference - parseCliPreference(); - - // Add xwalk preference to config.xml - addPreferences(); - - if (xwalkVariables['xwalkMode'] == 'shared') { - // Add the permission of write_external_storage in shared mode - addPermission(); - } - - deferral.resolve(); - }; - - main(); - - return deferral.promise; - -}; diff --git a/plugins/cordova-plugin-crosswalk-webview/hooks/before_plugin_uninstall/000-shared_mode_special.js b/plugins/cordova-plugin-crosswalk-webview/hooks/before_plugin_uninstall/000-shared_mode_special.js deleted file mode 100644 index 2cc741d3..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/hooks/before_plugin_uninstall/000-shared_mode_special.js +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env node - -module.exports = function(context) { - - /** @external */ - var fs = context.requireCordovaModule('fs'), - path = context.requireCordovaModule('path'), - deferral = context.requireCordovaModule('q').defer(), - ConfigParser = context.requireCordovaModule("cordova-lib/src/configparser/ConfigParser"), - XmlHelpers = context.requireCordovaModule("cordova-lib/src/util/xml-helpers"), - et = context.requireCordovaModule('elementtree'); - - /** @defaults */ - var xwalkVariables = ['xwalkVersion', 'xwalkCommandLine', 'xwalkMode']; - androidPlatformDir = path.join(context.opts.projectRoot, - 'platforms', 'android'), - projectConfigurationFile = path.join(context.opts.projectRoot, - 'config.xml'), - projectManifestFile = path.join(androidPlatformDir, - 'AndroidManifest.xml'); - - /** Init */ - var CordovaConfig = new ConfigParser(projectConfigurationFile); - - var removePermission = function() { - var projectManifestXmlRoot = XmlHelpers.parseElementtreeSync(projectManifestFile); - var child = et.XML('<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />'); - XmlHelpers.pruneXML(projectManifestXmlRoot, [child], '/manifest'); - fs.writeFileSync(projectManifestFile, projectManifestXmlRoot.write({indent: 4}), 'utf-8'); - } - - var removeXWalkVariables = function() { - var configXmlRoot = XmlHelpers.parseElementtreeSync(projectConfigurationFile); - for (var index = 0; index < xwalkVariables.length; index++) { - var child = configXmlRoot.find('./preference[@name="' + xwalkVariables[index] + '"]'); - if (child) { - XmlHelpers.pruneXML(configXmlRoot, [child], '/*'); - } - } - fs.writeFileSync(projectConfigurationFile, configXmlRoot.write({indent: 4}), 'utf-8'); - } - - /** Main method */ - var main = function() { - // Remove the xwalk variables - removeXWalkVariables(); - - if (CordovaConfig.getGlobalPreference('xwalkMode') == 'shared') { - // Add the permission of write_external_storage in shared mode - removePermission(); - } - - deferral.resolve(); - }; - - main(); - - return deferral.promise; - -}; diff --git a/plugins/cordova-plugin-crosswalk-webview/package.json b/plugins/cordova-plugin-crosswalk-webview/package.json deleted file mode 100644 index c4c95f1f..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "cordova-plugin-crosswalk-webview", - "version": "1.3.1", - "description": "Changes the default WebView to CrossWalk", - "cordova": { - "id": "cordova-plugin-crosswalk-webview", - "platforms": [ - "android" - ] - }, - "repository": { - "type": "git", - "url": "https://github.com/crosswalk-project/cordova-plugin-crosswalk-webview.git" - }, - "keywords": [ - "cordova", - "chromium", - "crosswalk", - "webview", - "engine", - "ecosystem:cordova", - "cordova-android" - ], - "engines": [ - { - "name": "cordova-android", - "version": ">=4" - }, - { - "name": "cordova-plugman", - "version": ">=4.2.0" - } - ], - "author": "", - "license": "Apache 2.0", - "bugs": { - "url": "https://crosswalk-project.org/jira" - }, - "homepage": "https://github.com/crosswalk-project/cordova-plugin-crosswalk-webview" -} diff --git a/plugins/cordova-plugin-crosswalk-webview/plugin.xml b/plugins/cordova-plugin-crosswalk-webview/plugin.xml deleted file mode 100644 index 95f35dc8..00000000 --- a/plugins/cordova-plugin-crosswalk-webview/plugin.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-crosswalk-webview" - version="1.3.1"> - - <name>Crosswalk WebView Engine</name> - <description>Changes the default WebView to CrossWalk</description> - <license>Apache 2.0</license> - <keywords>cordova,chromium,crosswalk,webview</keywords> - <repo>https://github.com/crosswalk-project/cordova-plugin-crosswalk-webview</repo> - <issue>https://crosswalk-project.org/jira</issue> - - <engines> - <engine name="cordova-android" version=">=4"/> - <engine name="cordova-plugman" version=">=4.2.0"/><!-- needed for gradleReference support --> - </engines> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <preference name="webView" value="org.crosswalk.engine.XWalkWebViewEngine"/> - <preference name="xwalkVersion" default="14+"/> - <preference name="xwalkCommandLine" default="--disable-pull-to-refresh-effect"/> - <preference name="xwalkMode" default="embedded" /> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/*"> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - </config-file> - - <source-file src="platforms/android/src/org/crosswalk/engine/XWalkWebViewEngine.java" target-dir="src/org/crosswalk/engine"/> - <source-file src="platforms/android/src/org/crosswalk/engine/XWalkExposedJsApi.java" target-dir="src/org/crosswalk/engine"/> - <source-file src="platforms/android/src/org/crosswalk/engine/XWalkCordovaResourceClient.java" target-dir="src/org/crosswalk/engine"/> - <source-file src="platforms/android/src/org/crosswalk/engine/XWalkCordovaUiClient.java" target-dir="src/org/crosswalk/engine"/> - <source-file src="platforms/android/src/org/crosswalk/engine/XWalkCordovaView.java" target-dir="src/org/crosswalk/engine"/> - <source-file src="platforms/android/src/org/crosswalk/engine/XWalkCordovaCookieManager.java" target-dir="src/org/crosswalk/engine"/> - - <framework src="platforms/android/xwalk.gradle" custom="true" type="gradleReference"/> - - <hook type="after_plugin_install" src="hooks/after_plugin_install/000-shared_mode_special.js"/> - <hook type="before_plugin_uninstall" src="hooks/before_plugin_uninstall/000-shared_mode_special.js"/> - </platform> -</plugin> diff --git a/plugins/cordova-plugin-file/CONTRIBUTING.md b/plugins/cordova-plugin-file/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/cordova-plugin-file/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/cordova-plugin-file/LICENSE b/plugins/cordova-plugin-file/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/cordova-plugin-file/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/NOTICE b/plugins/cordova-plugin-file/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/cordova-plugin-file/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/cordova-plugin-file/README.md b/plugins/cordova-plugin-file/README.md deleted file mode 100644 index 99d7cf3a..00000000 --- a/plugins/cordova-plugin-file/README.md +++ /dev/null @@ -1,452 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -This plugin implements a File API allowing read/write access to files residing on the device. - -This plugin is based on several specs, including : -The HTML5 File API -[http://www.w3.org/TR/FileAPI/](http://www.w3.org/TR/FileAPI/) - -The (now-defunct) Directories and System extensions -Latest: -[http://www.w3.org/TR/2012/WD-file-system-api-20120417/](http://www.w3.org/TR/2012/WD-file-system-api-20120417/) -Although most of the plugin code was written when an earlier spec was current: -[http://www.w3.org/TR/2011/WD-file-system-api-20110419/](http://www.w3.org/TR/2011/WD-file-system-api-20110419/) - -It also implements the FileWriter spec : -[http://dev.w3.org/2009/dap/file-system/file-writer.html](http://dev.w3.org/2009/dap/file-system/file-writer.html) - -For usage, please refer to HTML5 Rocks' excellent [FileSystem article.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -For an overview of other storage options, refer to Cordova's -[storage guide](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -This plugin defines global `cordova.file` object. - -Although in the global scope, it is not available until after the `deviceready` event. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - -## Installation - - cordova plugin add cordova-plugin-file - -## Supported Platforms - -- Amazon Fire OS -- Android -- BlackBerry 10 -- Firefox OS -- iOS -- Windows Phone 7 and 8* -- Windows 8* -- Windows* -- Browser - -\* _These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`._ - -## Where to Store Files - -As of v1.2.0, URLs to important file-system directories are provided. -Each URL is in the form _file:///path/to/spot/_, and can be converted to a -`DirectoryEntry` using `window.resolveLocalFileSystemURL()`. - -* `cordova.file.applicationDirectory` - Read-only directory where the application - is installed. (_iOS_, _Android_, _BlackBerry 10_) - -* `cordova.file.applicationStorageDirectory` - Root directory of the application's - sandbox; on iOS this location is read-only (but specific subdirectories [like - `/Documents`] are read-write). All data contained within is private to the app. ( - _iOS_, _Android_, _BlackBerry 10_) - -* `cordova.file.dataDirectory` - Persistent and private data storage within the - application's sandbox using internal memory (on Android, if you need to use - external memory, use `.externalDataDirectory`). On iOS, this directory is not - synced with iCloud (use `.syncedDataDirectory`). (_iOS_, _Android_, _BlackBerry 10_) - -* `cordova.file.cacheDirectory` - Directory for cached data files or any files - that your app can re-create easily. The OS may delete these files when the device - runs low on storage, nevertheless, apps should not rely on the OS to delete files - in here. (_iOS_, _Android_, _BlackBerry 10_) - -* `cordova.file.externalApplicationStorageDirectory` - Application space on - external storage. (_Android_) - -* `cordova.file.externalDataDirectory` - Where to put app-specific data files on - external storage. (_Android_) - -* `cordova.file.externalCacheDirectory` - Application cache on external storage. - (_Android_) - -* `cordova.file.externalRootDirectory` - External storage (SD card) root. (_Android_, _BlackBerry 10_) - -* `cordova.file.tempDirectory` - Temp directory that the OS can clear at will. Do not - rely on the OS to clear this directory; your app should always remove files as - applicable. (_iOS_) - -* `cordova.file.syncedDataDirectory` - Holds app-specific files that should be synced - (e.g. to iCloud). (_iOS_) - -* `cordova.file.documentsDirectory` - Files private to the app, but that are meaningful - to other application (e.g. Office files). (_iOS_) - -* `cordova.file.sharedDirectory` - Files globally available to all applications (_BlackBerry 10_) - -## File System Layouts - -Although technically an implementation detail, it can be very useful to know how -the `cordova.file.*` properties map to physical paths on a real device. - -### iOS File System Layout - -| Device Path | `cordova.file.*` | `iosExtraFileSystems` | r/w? | persistent? | OS clears | sync | private | -|:-----------------------------------------------|:----------------------------|:----------------------|:----:|:-----------:|:---------:|:----:|:-------:| -| `/var/mobile/Applications/<UUID>/` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Yes | -| `appname.app/` | applicationDirectory | bundle | r | N/A | N/A | N/A | Yes | -| `www/` | - | - | r | N/A | N/A | N/A | Yes | -| `Documents/` | documentsDirectory | documents | r/w | Yes | No | Yes | Yes | -| `NoCloud/` | - | documents-nosync | r/w | Yes | No | No | Yes | -| `Library` | - | library | r/w | Yes | No | Yes? | Yes | -| `NoCloud/` | dataDirectory | library-nosync | r/w | Yes | No | No | Yes | -| `Cloud/` | syncedDataDirectory | - | r/w | Yes | No | Yes | Yes | -| `Caches/` | cacheDirectory | cache | r/w | Yes* | Yes\*\*\*| No | Yes | -| `tmp/` | tempDirectory | - | r/w | No\*\* | Yes\*\*\*| No | Yes | - - - \* Files persist across app restarts and upgrades, but this directory can - be cleared whenever the OS desires. Your app should be able to recreate any - content that might be deleted. - -\*\* Files may persist across app restarts, but do not rely on this behavior. Files - are not guaranteed to persist across updates. Your app should remove files from - this directory when it is applicable, as the OS does not guarantee when (or even - if) these files are removed. - -\*\*\* The OS may clear the contents of this directory whenever it feels it is - necessary, but do not rely on this. You should clear this directory as - appropriate for your application. - -### Android File System Layout - -| Device Path | `cordova.file.*` | `AndroidExtraFileSystems` | r/w? | persistent? | OS clears | private | -|:------------------------------------------------|:----------------------------|:--------------------------|:----:|:-----------:|:---------:|:-------:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | Yes | -| `/data/data/<app-id>/` | applicationStorageDirectory | - | r/w | N/A | N/A | Yes | -| `cache` | cacheDirectory | cache | r/w | Yes | Yes\* | Yes | -| `files` | dataDirectory | files | r/w | Yes | No | Yes | -| `Documents` | | documents | r/w | Yes | No | Yes | -| `<sdcard>/` | externalRootDirectory | sdcard | r/w | Yes | No | No | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Yes | No | No | -| `cache` | externalCacheDirectry | cache-external | r/w | Yes | No\*\*| No | -| `files` | externalDataDirectory | files-external | r/w | Yes | No | No | - -\* The OS may periodically clear this directory, but do not rely on this behavior. Clear - the contents of this directory as appropriate for your application. Should a user - purge the cache manually, the contents of this directory are removed. - -\*\* The OS does not clear this directory automatically; you are responsible for managing - the contents yourself. Should the user purge the cache manually, the contents of the - directory are removed. - -**Note**: If external storage can't be mounted, the `cordova.file.external*` -properties are `null`. - -### BlackBerry 10 File System Layout - -| Device Path | `cordova.file.*` | r/w? | persistent? | OS clears | private | -|:-------------------------------------------------------------|:----------------------------|:----:|:-----------:|:---------:|:-------:| -| `file:///accounts/1000/appdata/<app id>/` | applicationStorageDirectory | r | N/A | N/A | Yes | -| `app/native` | applicationDirectory | r | N/A | N/A | Yes | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | No | Yes | Yes | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Yes | No | Yes | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | Yes | No | No | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | Yes | No | No | - -*Note*: When application is deployed to work perimeter, all paths are relative to /accounts/1000-enterprise. - -## Android Quirks - -### Android Persistent storage location - -There are multiple valid locations to store persistent files on an Android -device. See [this page](http://developer.android.com/guide/topics/data/data-storage.html) -for an extensive discussion of the various possibilities. - -Previous versions of the plugin would choose the location of the temporary and -persistent files on startup, based on whether the device claimed that the SD -Card (or equivalent storage partition) was mounted. If the SD Card was mounted, -or if a large internal storage partition was available (such as on Nexus -devices,) then the persistent files would be stored in the root of that space. -This meant that all Cordova apps could see all of the files available on the -card. - -If the SD card was not available, then previous versions would store data under -`/data/data/<packageId>`, which isolates apps from each other, but may still -cause data to be shared between users. - -It is now possible to choose whether to store files in the internal file -storage location, or using the previous logic, with a preference in your -application's `config.xml` file. To do this, add one of these two lines to -`config.xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - -Without this line, the File plugin will use `Compatibility` as the default. If -a preference tag is present, and is not one of these values, the application -will not start. - -If your application has previously been shipped to users, using an older (pre- -1.0) version of this plugin, and has stored files in the persistent filesystem, -then you should set the preference to `Compatibility`. Switching the location to -"Internal" would mean that existing users who upgrade their application may be -unable to access their previously-stored files, depending on their device. - -If your application is new, or has never previously stored files in the -persistent filesystem, then the `Internal` setting is generally recommended. - -### Slow recursive operations for /android_asset - -Listing asset directories is really slow on Android. You can speed it up though, by -adding `src/android/build-extras.gradle` to the root of your android project (also -requires cordova-android@4.0.0 or greater). - -## iOS Quirks - -- `cordova.file.applicationStorageDirectory` is read-only; attempting to store - files within the root directory will fail. Use one of the other `cordova.file.*` - properties defined for iOS (only `applicationDirectory` and `applicationStorageDirectory` are - read-only). -- `FileReader.readAsText(blob, encoding)` - - The `encoding` parameter is not supported, and UTF-8 encoding is always in effect. - -### iOS Persistent storage location - -There are two valid locations to store persistent files on an iOS device: the -Documents directory and the Library directory. Previous versions of the plugin -only ever stored persistent files in the Documents directory. This had the -side-effect of making all of an application's files visible in iTunes, which -was often unintended, especially for applications which handle lots of small -files, rather than producing complete documents for export, which is the -intended purpose of the directory. - -It is now possible to choose whether to store files in the documents or library -directory, with a preference in your application's `config.xml` file. To do this, -add one of these two lines to `config.xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - -Without this line, the File plugin will use `Compatibility` as the default. If -a preference tag is present, and is not one of these values, the application -will not start. - -If your application has previously been shipped to users, using an older (pre- -1.0) version of this plugin, and has stored files in the persistent filesystem, -then you should set the preference to `Compatibility`. Switching the location to -`Library` would mean that existing users who upgrade their application would be -unable to access their previously-stored files. - -If your application is new, or has never previously stored files in the -persistent filesystem, then the `Library` setting is generally recommended. - -## Firefox OS Quirks - -The File System API is not natively supported by Firefox OS and is implemented -as a shim on top of indexedDB. - -* Does not fail when removing non-empty directories -* Does not support metadata for directories -* Methods `copyTo` and `moveTo` do not support directories - -The following data paths are supported: -* `applicationDirectory` - Uses `xhr` to get local files that are packaged with the app. -* `dataDirectory` - For persistent app-specific data files. -* `cacheDirectory` - Cached files that should survive app restarts (Apps should not rely -on the OS to delete files in here). - -## Browser Quirks - -### Common quirks and remarks -- Each browser uses its own sandboxed filesystem. IE and Firefox use IndexedDB as a base. -All browsers use forward slash as directory separator in a path. -- Directory entries have to be created successively. -For example, the call `fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback)` -will fail if dir1 did not exist. -- The plugin requests user permission to use persistent storage at the application first start. -- Plugin supports `cdvfile://localhost` (local resources) only. I.e. external resources are not supported via `cdvfile`. -- The plugin does not follow ["File System API 8.3 Naming restrictions"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). -- Blob and File' `close` function is not supported. -- `FileSaver` and `BlobBuilder` are not supported by this plugin and don't have stubs. -- The plugin does not support `requestAllFileSystems`. This function is also missing in the specifications. -- Entries in directory will not be removed if you use `create: true` flag for existing directory. -- Files created via constructor are not supported. You should use entry.file method instead. -- Each browser uses its own form for blob URL references. -- `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension, -mediatype in IE is always empty (which is the same as `text-plain` according the specification), -the mediatype in Firefox is always `application/octet-stream`. -For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`, -IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. -- `toInternalURL` returns the path in the form `file:///persistent/path/to/entry` (Firefox, IE). -Chrome returns the path in the form `cdvfile://localhost/persistent/file`. - -### Chrome quirks -- Chrome filesystem is not immediately ready after device ready event. As a workaround you can subscribe to `filePluginIsReady` event. -Example: -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` -You can use `window.isFilePluginReadyRaised` function to check whether event was already raised. -- window.requestFileSystem TEMPORARY and PERSISTENT filesystem quotas are not limited in Chrome. -- To increase persistent storage in Chrome you need to call `window.initPersistentFileSystem` method. Persistent storage quota is 5 MB by default. -- Chrome requires `--allow-file-access-from-files` run argument to support API via `file:///` protocol. -- `File` object will be not changed if you use flag `{create:true}` when getting an existing `Entry`. -- events `cancelable` property is set to true in Chrome. This is contrary to the [specification](http://dev.w3.org/2009/dap/file-system/file-writer.html). -- `toURL` function in Chrome returns `filesystem:`-prefixed path depending on application host. -For example, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -- `toURL` function result does not contain trailing slash in case of directory entry. -Chrome resolves directories with slash-trailed urls correctly though. -- `resolveLocalFileSystemURL` method requires the inbound `url` to have `filesystem` prefix. For example, `url` parameter for `resolveLocalFileSystemURL` -should be in the form `filesystem:file:///persistent/somefile.txt` as opposed to the form `file:///persistent/somefile.txt` in Android. -- Deprecated `toNativeURL` function is not supported and does not have a stub. -- `setMetadata` function is not stated in the specifications and not supported. -- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of SYNTAX_ERR(code: 8) on requesting of a non-existant filesystem. -- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12) on trying to exclusively create a file or directory, which already exists. -- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively on the root file system. -- INVALID_MODIFICATION_ERR (code: 9) is thrown instead of NOT_FOUND_ERR(code: 1) on trying to moveTo directory that does not exist. - -### IndexedDB-based impl quirks (Firefox and IE) -- `.` and `..` are not supported. -- IE does not support `file:///`-mode; only hosted mode is supported (http://localhost:xxxx). -- Firefox filesystem size is not limited but each 50MB extension will request a user permission. -IE10 allows up to 10mb of combined AppCache and IndexedDB used in implementation of filesystem without prompting, -once you hit that level you will be asked if you want to allow it to be increased up to a max of 250mb per site. -So `size` parameter for `requestFileSystem` function does not affect filesystem in Firefox and IE. -- `readAsBinaryString` function is not stated in the Specs and not supported in IE and does not have a stub. -- `file.type` is always null. -- You should not create entry using DirectoryEntry instance callback result which was deleted. -Otherwise, you will get a 'hanging entry'. -- Before you can read a file, which was just written you need to get a new instance of this file. -- `setMetadata` function, which is not stated in the Specs supports `modificationTime` field change only. -- `copyTo` and `moveTo` functions do not support directories. -- Directories metadata is not supported. -- Both Entry.remove and directoryEntry.removeRecursively don't fail when removing -non-empty directories - directories being removed are cleaned along with contents instead. -- `abort` and `truncate` functions are not supported. -- progress events are not fired. For example, this handler will be not executed: -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## Upgrading Notes - -In v1.0.0 of this plugin, the `FileEntry` and `DirectoryEntry` structures have changed, -to be more in line with the published specification. - -Previous (pre-1.0.0) versions of the plugin stored the device-absolute-file-location -in the `fullPath` property of `Entry` objects. These paths would typically look like - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - -These paths were also returned by the `toURL()` method of the `Entry` objects. - -With v1.0.0, the `fullPath` attribute is the path to the file, _relative to the root of -the HTML filesystem_. So, the above paths would now both be represented by a `FileEntry` -object with a `fullPath` of - - /path/to/file - -If your application works with device-absolute-paths, and you previously retrieved those -paths through the `fullPath` property of `Entry` objects, then you should update your code -to use `entry.toURL()` instead. - -For backwards compatibility, the `resolveLocalFileSystemURL()` method will accept a -device-absolute-path, and will return an `Entry` object corresponding to it, as long as that -file exists within either the `TEMPORARY` or `PERSISTENT` filesystems. - -This has particularly been an issue with the File-Transfer plugin, which previously used -device-absolute-paths (and can still accept them). It has been updated to work correctly -with FileSystem URLs, so replacing `entry.fullPath` with `entry.toURL()` should resolve any -issues getting that plugin to work with files on the device. - -In v1.1.0 the return value of `toURL()` was changed (see [CB-6394] (https://issues.apache.org/jira/browse/CB-6394)) -to return an absolute 'file://' URL. wherever possible. To ensure a 'cdvfile:'-URL you can use `toInternalURL()` now. -This method will now return filesystem URLs of the form - - cdvfile://localhost/persistent/path/to/file - -which can be used to identify the file uniquely. - -## List of Error Codes and Meanings -When an error is thrown, one of the following codes will be used. - -| Code | Constant | -|-----:|:------------------------------| -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configuring the Plugin (Optional) - -The set of available filesystems can be configured per-platform. Both iOS and -Android recognize a <preference> tag in `config.xml` which names the -filesystems to be installed. By default, all file-system roots are enabled. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - -### Android - -* `files`: The application's internal file storage directory -* `files-external`: The application's external file storage directory -* `sdcard`: The global external file storage directory (this is the root of the SD card, if one is installed). You must have the `android.permission.WRITE_EXTERNAL_STORAGE` permission to use this. -* `cache`: The application's internal cache directory -* `cache-external`: The application's external cache directory -* `root`: The entire device filesystem - -Android also supports a special filesystem named "documents", which represents a "/Documents/" subdirectory within the "files" filesystem. - -### iOS - -* `library`: The application's Library directory -* `documents`: The application's Documents directory -* `cache`: The application's Cache directory -* `bundle`: The application's bundle; the location of the app itself on disk (read-only) -* `root`: The entire device filesystem - -By default, the library and documents directories can be synced to iCloud. You can also request two additional filesystems, `library-nosync` and `documents-nosync`, which represent a special non-synced directory within the `/Library` or `/Documents` filesystem. diff --git a/plugins/cordova-plugin-file/RELEASENOTES.md b/plugins/cordova-plugin-file/RELEASENOTES.md deleted file mode 100644 index 0181d7c7..00000000 --- a/plugins/cordova-plugin-file/RELEASENOTES.md +++ /dev/null @@ -1,364 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.2.1 (Sept 5, 2013) -* [CB-4656] Don't add newlines in data urls within readAsDataUrl. -* [CB-4514] Making DirectoryCopy Recursive -* [iOS] Simplify the code in resolveLocalFileSystemURI - -### 0.2.3 (Sept 25, 2013) -* CB-4889 bumping&resetting version -* [CB-4903] File Plugin not loading Windows8 -* [CB-4903] File Plugin not loading Windows8 -* CB-4889 renaming references -* CB-4889 renaming org.apache.cordova.core.file to org.apache.cordova.file -* Rename CHANGELOG.md -> RELEASENOTES.md -* [CB-4771] Expose TEMPORARY and PERSISTENT constants on window. -* Fix compiler/lint warnings -* [CB-4764] Move DirectoryManager.java into file plugin -* [CB-4763] Copy FileHelper.java into the plugin. -* [CB-2901] [BlackBerry10] Automatically unsandbox filesystem if path is not in app sandbox -* [CB-4752] Incremented plugin version on dev branch. - -### 0.2.4 (Oct 9, 2013) -* CB-5020 - File plugin should execute on a separate thread -* [CB-4915] Incremented plugin version on dev branch. -* CB-4504: Updating FileUtils.java to compensate for Java porting failures in the Android SDK. This fails because Java knows nothing about android_asset not being an actual filesystem - - ### 0.2.5 (Oct 28, 2013) -* CB-5129: Add a consistent filesystem attribute to FileEntry and DirectoryEntry objects -* CB-5128: added repo + issue tag to plugin.xml for file plugin -* CB-5015 [BlackBerry10] Add missing dependency for File.slice -* [CB-5010] Incremented plugin version on dev branch. - -### 1.0.0 (Feb 05, 2014) -* CB-5974: Use safe 'Compatibilty' mode by default -* CB-5915: CB-5916: Reorganize preference code to make defaults possible -* CB-5974: Android: Don't allow File operations to continue when not configured -* CB-5960: ios: android: Properly handle parent references in getFile/getDirectory -* [ubuntu] adopt to recent changes -* Add default FS root to new FS objects -* CB-5899: Make DirectoryReader.readEntries return properly formatted Entry objects -* Add constuctor params to FileUploadResult related to CB-2421 -* Fill out filesystem attribute of entities returned from resolveLocalFileSystemURL -* CB-5916: Create documents directories if they don't exist -* CB-5915: Create documents directories if they don't exist -* CB-5916: Android: Fix unfortunate NPE in config check -* CB-5916: Android: Add "/files/" to persistent files path -* CB-5915: ios: Update config preference (and docs) to match issue -* CB-5916: Android: Add config preference for Android persistent storage location -* iOS: Add config preference for iOS persistent storage location -* iOS: Android: Allow third-party plugin registration -* Android: Expose filePlugin getter so that other plugins can register filesystems -* Fix typos in deprecation message -* Add backwards-compatibility shim for file-transfer -* Android: Allow third-party plugin registration -* CB-5810 [BlackBerry10] resolve local:/// paths (application assets) -* CB-5774: create DirectoryEntry instead of FileEntry -* Initial fix for CB-5747 -* Change default FS URL scheme to "cdvfile" -* Android: Properly format content urls -* Android, iOS: Replace "filesystem" protocol string with constant -* Android: Allow absolute paths on Entry.getFile / Entry.getDirectory -* Android: Make clear that getFile takes a path, not just a filename -* CB-5008: Rename resolveLocalFileSystemURI to resolveLocalFileSystemURL; deprecate original -* Remove old file reference from plugin.xml -* Android: Refactor File API -* CB-4899 [BlackBerry10] Fix resolve directories -* CB-5602 Windows8. Fix File Api mobile spec tests -* Android: Better support for content urls and cross-filesystem copy/move ops -* CB-5699 [BlackBerry10] Update resolveLocalFileSystemURI implementation -* CB-5658 Update license comment formatting of doc/index.md -* CB-5658 Add doc.index.md for File plugin. -* CB-5658 Delete stale snapshot of plugin docs -* CB-5403: Backwards-compatibility with file:// urls where possible -* CB-5407: Fixes for ContentFilesystem -* Android: Add method for testing backwards-compatibility of filetransfer plugin -* iOS: Add method for testing backwards-compatiblity of filetransfer plugin -* Android: Updates to allow FileTransfer to continue to work -* Android: Clean up unclosed file objects -* CB-5407: Cleanup -* CB-5407: Add new Android source files to plugin.xml -* CB-5407: Move read, write and truncate methods into modules -* CB-5407: Move copy/move methods into FS modules -* CB-5407: Move getParent into FS modules -* CB-5407: Move getmetadata methods into FS modules -* CB-5407: Move readdir methods into FS modules -* CB-5407: Move remove methods into FS modules -* CB-5407: Move getFile into FS modules -* CB-5407: Start refactoring android code: Modular filesystems, rfs, rlfsurl -* CB-5407: Update android JS to use FS urls -* CB-5405: Use URL formatting for Entry.toURL -* CB-5532 Fix -* Log file path for File exceptions. -* Partial fix for iOS File compatibility with previous fileTransfer plugin -* CB-5532 WP8. Add binary data support to FileWriter -* CB-5531 WP8. File Api readAsText incorrectly handles position args -* Added ubuntu platform support -* Added amazon-fireos platform support -* CB-5118 [BlackBerry10] Add check for undefined error handler -* CB-5406: Extend public API for dependent plugins -* CB-5403: Bump File plugin major version -* CB-5406: Split iOS file plugin into modules -* CB-5406: Factor out filesystem providers in iOS -* CB-5408: Add handler for filesystem:// urls -* CB-5406: Update iOS native code to use filesystem URLs internally -* CB-5405: Update JS code to use URLs exclusively -* CB-4816 Fix file creation outside sandbox for BB10 - -### 1.0.1 (Feb 28, 2014) -* CB-6116 Fix error where resolveLocalFileSystemURL would fail -* CB-6106 Add support for nativeURL attribute on Entry objects -* CB-6110 iOS: Fix typo in filesystemPathForURL: method -* Android: Use most specific FS match when resolving file: URIs -* iOS: Update fileSystemURLforLocalPath: to return the most match url. -* Allow third-party plugin registration, and the total count of fs type is not limited to just 4. -* CB-6097 Added missing files for amazon-fireos platform. Added onLoad flag to true. -* CB-6087 Android, iOS: Load file plugin on startup -* CB-6013 BlackBerry10: wrap webkit prefixed called in requestAnimationFrame -* Update plugin writers' documentation -* CB-6080 Fix file copy when src and dst are on different local file systems -* CB-6057 Add methods for plugins to convert between URLs and paths -* CB-6050 Public method for returning a FileEntry from a device file path -* CB-2432 CB-3185, CB-5975: Fix Android handling of content:// URLs -* CB-6022 Add upgrade notes to doc -* CB-5233 Make asset-library urls work properly on iOS -* CB-6012 Preserve query strings on cdvfile:// URLs where necessary -* CB-6010 Test properly for presence of URLforFilesystemPath method -* CB-5959 Entry.getMetadata should return size attribute - -### 1.1.0 (Apr 17, 2014) -* CB-4965: Remove tests from file plugin -* Android: Allow file:/ URLs -* CB-6422: [windows8] use cordova/exec/proxy -* CB-6249: [android] Opportunistically resolve content urls to file -* CB-6394: [ios, android] Add extra filesystem roots -* CB-6394: [ios, android] Fix file resolution for the device root case -* CB-6394: [ios] Return ENCODING_ERR when fs name is not valid -* CB-6393: Change behaviour of toURL and toNativeURL -* ios: Style: plugin initialization -* ios: Fix handling of file URLs with encoded spaces -* Always use Android's recommended temp file location for temporary file system -* CB-6352: Allow FileSystem objects to be serialized to JSON -* CB-5959: size is explicitly 0 if not set, file.spec.46&47 are testing the type of size -* CB-6242: [BlackBerry10] Add deprecated version of resolveLocalFileSystemURI -* CB-6242: [BlackBerry10] add file:/// prefix for toURI / toURL -* CB-6242: [BlackBerry10] Polyfill window.requestAnimationFrame for OS < 10.2 -* CB-6242: [BlackBerry10] Override window.resolveLocalFileSystemURL -* CB-6212: [iOS] fix warnings compiled under arm64 64-bit -* ios: Don't cache responses from CDVFile's URLProtocol -* CB-6199: [iOS] Fix toNativeURL() not escaping characters properly -* CB-6148: Fix cross-filesystem copy and move -* fixed setMetadata() to use the formatted fullPath -* corrected typo which leads to a "comma expression" -* CB-4952: ios: Resolve symlinks in file:// URLs -* Add docs about the extraFileSystems preference -* CB-6460: Update license headers - -### 1.2.0 (Jun 05, 2014) -* CB-6127 Spanish and French Translations added. Github close #31 -* updated this reference to window -* Add missing semicolon (copy & paste error) -* Fix compiler warning about symbol in interface not matching implementation -* Fix sorting order in supported platforms -* ubuntu: increase quota value -* ubuntu: Change FS URL scheme to 'cdvfile' -* ubuntu: Return size with Entry.getMetadata() method -* CB-6803 Add license -* Initial implementation for Firefox OS -* Small wording tweaks -* Fixed toURL() toInternalURL() information in the doku -* ios: Don't fail a write of zero-length payload. -* CB-285 Docs for cordova.file.\*Directory properties -* CB-285 Add cordova.file.\*Directory properties for iOS & Android -* CB-3440 [BlackBerry10] Proxy based implementation -* Fix typo in docs "app-bundle" -> "bundle" -* CB-6583 ios: Fix failing to create entry when space in parent path -* CB-6571 android: Make DirectoryEntry.toURL() have a trailing / -* CB-6491 add CONTRIBUTING.md -* CB-6525 android, ios: Allow file: URLs in all APIs. Fixes FileTransfer.download not being called. -* fix the Windows 8 implementation of the getFile method -* Update File.js for typo: lastModifiedData --> lastModifiedDate (closes #38) -* Add error codes. -* CB-5980 Updated version and RELEASENOTES.md for release 1.0.0 -* Add NOTICE file -* CB-6114 Updated version and RELEASENOTES.md for release 1.0.1 -* CB-5980 Updated version and RELEASENOTES.md for release 1.0.0 - -### 1.2.1 -* CB-6922 Fix inconsistent handling of lastModifiedDate and modificationTime -* CB-285: Document filesystem root properties - -### 1.3.0 (Aug 06, 2014) -* **FFOS** Remove unsupported paths from requestAllPaths -* **FFOS** Support for resolve URI, request all paths and local app directory. -* CB-4263 set ready state to done before onload -* CB-7167 [BlackBerry10] copyTo - return wrapped entry rather than native -* CB-7167 [BlackBerry10] Add directory support to getFileMetadata -* CB-7167 [BlackBerry10] Fix tests detection of blob support (window.Blob is BlobConstructor object) -* CB-7161 [BlackBerry10] Add file system directory paths -* CB-7093 Create separate plugin.xml for new-style tests -* CB-7057 Docs update: elaborate on what directories are for -* CB-7093: Undo the effects of an old bad S&R command -* CB-7093: Remove a bunch of unneeded log messages -* CB-7093: Add JS module to plugin.xml file for auto-tests -* CB-7093 Ported automated file tests -* **WINDOWS** remove extra function closure, not needed -* **WINDOWS** remove check for undefined fail(), it is defined by the proxy and always exists -* **WINDOWS** re-apply readAsBinaryString and readAsArrayBuffer -* **WINDOWS** Moved similar calls to be the same calls, aliased long namespaced functions -* CB-6127 Updated translations for docs. -* CB-6571 Fix getParentForLocalURL to work correctly with directories with trailing '/' (This closes #58) -* UTTypeCopyPreferredTagWithClass returns nil mimetype for css when there is no network -* updated spec links in docs ( en only ) -* CB-6571 add trailing space it is missing in DirectoryEnty constructor. -* CB-6980 Fixing filesystem:null property in Entry -* Add win8 support for readAsBinaryString and readAsArrayBuffer -* [FFOS] Update FileProxy.js -* CB-6940: Fixing up commit from dzeims -* CB-6940: Android: cleanup try/catch exception handling -* CB-6940: context.getExternal* methods return null if sdcard isn't in mounted state, causing exceptions that prevent startup from reaching readystate -* Fix mis-handling of filesystem reference in Entry.moveTo ('this' used in closure). -* CB-6902: Use File.lastModified rather than .lastModifiedDate -* CB-6922: Remove unused getMetadata native code -* CB-6922: Use getFileMetadata consistently to get metadata -* changed fullPath to self.rootDocsPath -* CB-6890: Fix pluginManager access for 4.0.x branch - -### 1.3.1 (Sep 17, 2014) -* CB-7471 cordova-plugin-file documentation translation -* CB-7272 Replace confusing "r/o" abbreviation with just "r" -* CB-7423 encode path before attempting to resolve -* CB-7375 Fix the filesystem name in resolveLocalFileSystemUri -* CB-7445 [BlackBerry10] resolveLocalFileSystemURI - change DEFAULT_SIZE to MAX_SIZE -* CB-7458 [BlackBerry10] resolveLocalFileSystemURL - add filesystem property -* CB-7445 [BlackBerry10] Add default file system size to prevent quota exceeded error on initial install -* CB-7431 Avoid calling done() twice in file.spec.109 test -* CB-7413 Adds support of 'ms-appdata://' URIs -* CB-7422 [File Tests] Use proper fileSystem to create fullPath -* CB-7375 [Entry] get proper filesystem in Entry -* Amazon related changes. -* CB-7375 Remove leading slash statement from condition -* Refactored much of the logic in FileMetadata constructor. Directory.size will return 0 -* CB-7419 [WP8] Added support to get metada from dir -* CB-7418 [DirectoryEntry] Added fullPath variable as part of condition -* CB-7417 [File tests] added proper matcher to compare fullPath property -* CB-7375 Partial revert to resolve WP8 failures -* Overwrite existing file on getFile when create is true -* CB-7375 CB-6148: Ensure that return values from copy and move operations reference the correct filesystem -* CB-6724 changed style detail on documentation -* Added new js files to amazon-fireos platform. -* Adds Windows platform -* Fixes multiple mobilespec tests errors -* Removed test/tests.js module from main plugin.xml -* CB-7094 renamed folder to tests + added nested plugin.xml -* added documentation for manual tests -* CB-6923 Adding support to handle relative paths -* Style improvements on Manual tests -* CB-7094 Ported File manual tests - -### 1.3.2 (Dec 02, 2014) -* Gets rid of thread block error in File plugin -* CB-7917 Made tests file.spec.114 - 116 pass for **Windows** platform -* CB-7977 Mention `deviceready` in plugin docs -* CB-7602: Fix `isCopyOnItself` logic -* CB-7700 cordova-plugin-file documentation translation: cordova-plugin-file -* Use one proxy for both **Windows** and **Windows8** platforms -* CB-6994 Fixes result, returned by proxy's write method -* [fxos] update `__format__` to match `pathsPrefix` -* CB-6994 Improves merged code to be able to write a File -* Optimize `FileProxy` for **Windows** platforms -* Synchronize changes with **Windows** platform -* Fix function write for big files on **Windows 8** -* Write file in background -* CB-7487 **Android** Broadcast file write This allows MTP USB shares to show the file immediately without reboot/manual refresh using 3rd party app. -* CB-7700 cordova-plugin-file documentation translation: cordova-plugin-file -* CB-7571 Bump version of nested plugin to match parent plugin - -### 1.3.3 (Feb 04, 2015) -* CB-7927 Encoding data to bytes instead of chars when writing a file. -* ios: Fix compile warning about implicit int conversion -* CB-8351 ios: Use base64EncodedStringWithOptions instead of CordovaLib's class extension -* CB-8351 ios: Use argumentForIndex rather than NSArray extension -* CB-8351 ios: Use a local copy of valueForKeyIsNumber rather than CordovaLib's version -* windows: Handle url's containing absolute windows path starting with drive letter and colon (encoded as %3A) through root FS -* windows: Rework to use normal url form -* android: refactor: Make Filesystem base class store its own name, rootUri, and rootEntry -* android: Simplify code a bit by making makeEntryForPath not throw JSONException -* CB-6431 android: Fix plugin breaking content: URLs -* CB-7375 Never create new FileSystem instances (except on windows since they don't implement requestAllFileSystems()) - -### 2.0.0 (Apr 15, 2015) -* CB-8849 Fixed ReadAsArrayBuffer to return ArrayBuffer and not Array on WP8 -* CB-8819 Fixed FileReader's readAsBinaryString on wp8 -* CB-8746 gave plugin major version bump -* CB-8683 android: Fix broken unit tests from plugin rename -* CB-8683 changed plugin-id to pacakge-name -* CB-8653 properly updated translated docs to use new id -* CB-8653 updated translated docs to use new id -* Use TRAVIS_BUILD_DIR, install paramedic by npm -* docs: added Windows to supported platforms -* CB-8699 CB-6428 Fix uncompressed assets being copied as zero length files -* CB-6428 android: Fix assets FileEntry having size of -1 -* android: Move URLforFullPath into base class (and rename to localUrlforFullPath) -* CB-6428 Mention build-extras.gradle in README -* CB-7109 android: Parse arguments off of the main thread (close #97) -* CB-8695 ios: Fix `blob.slice()` for `asset-library` URLs (close #105) -* Tweak build-extras.gradle to just read/write to main `assets/` instead of `build/` -* CB-8689 Fix NPE in makeEntryForNativeUri (was affecting file-transfer) -* CB-8675 Revert "CB-8351 ios: Use base64EncodedStringWithOptions instead of CordovaLib's class extension" -* CB-8653 Updated Readme -* CB-8659: ios: 4.0.x Compatibility: Remove use of initWebView method -* Add a cache to speed up AssetFilesystem directory listings -* CB-8663 android: Don't notify MediaScanner of private files -* Don't log stacktrace for normal exceptions (e.g. file not found) -* android: Don't use LimitedInputStream when reading entire file (optimization) -* CB-6428 android: Add support for directory copies from assets -> filesystem -* android: Add `listChildren()`: Java-consumable version of `readEntriesAtLocalURL()` -* CB-6428 android: Add support for file:///android_asset URLs -* CB-8642 android: Fix content URIs not working with resolve / copy -* Tweak tests to fail if deleteEntry fails (rather than time out) -* android: Ensure LocalFilesystemURL can only be created with "cdvfile" URLs -* android: Move CordovaResourceApi into Filesystem base class -* android: Use `CordovaResourceApi.mapUriToFile()` rather than own custom logic in ContentFilesystem -* android: Use Uri.parse rather than manual parsing in resolveLocalFileSystemURI -* Tweak test case that failed twice on error rather than just once -* android: Delete invalid JavaDoc (lint errors) -* android: Use CordovaResourceApi rather than FileHelper -* CB-8032 - File Plugin - Add nativeURL external method support for CDVFileSystem->makeEntryForPath:isDirectory: (closes #96) -* CB-8567 Integrate TravisCI -* CB-8438 cordova-plugin-file documentation translation: cordova-plugin-file -* CB-8538 Added package.json file -* CB-7956 Add cordova-plugin-file support for browser platform -* CB-8423 Corrected usage of done() in async tests -* CB-8459 Fixes spec 111 failure due to incorrect relative paths handling -* Code cleanup, whitespace -* Added nativeURL property to FileEntry, implemented readAsArrayBuffer and readAsBinaryString - -### 2.1.0 (Jun 17, 2015) -* added missing license header -* CB-9128 cordova-plugin-file documentation translation: cordova-plugin-file -* fix npm md -* CB-8844 Increased timeout for asset tests -* Updated resolveFileSystem.js so it can be parsed by uglifyJS -* CB-8860 cordova-plugin-file documentation translation: cordova-plugin-file -* CB-8792 Fixes reading of json files using readAsText diff --git a/plugins/cordova-plugin-file/doc/de/README.md b/plugins/cordova-plugin-file/doc/de/README.md deleted file mode 100644 index 242a2f75..00000000 --- a/plugins/cordova-plugin-file/doc/de/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -Dieses Plugin implementiert eine File-API, die Lese-/Schreibzugriff Zugriff auf Dateien, die auf dem Gerät befinden. - -Dieses Plugin basiert auf mehrere Angaben, einschließlich: die HTML5-File-API <http://www.w3.org/TR/FileAPI/> - -Die (heute nicht mehr existierenden) Verzeichnisse und System neuesten Erweiterungen: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , obwohl die meisten von den Plugin-Code wurde geschrieben, als eine frühere Spec aktuell waren: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Es implementiert auch die FileWriter Spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Verwendung finden Sie in HTML5 Rocks ausgezeichnete [Dateisystem Artikel.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -Finden Sie einen Überblick über andere Speicheroptionen Cordovas [Speicher-Führer](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -Dieses Plugin wird global `cordova.file`-Objekt definiert. - -Obwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Installation - - cordova plugin add cordova-plugin-file - - -## Unterstützte Plattformen - - * Amazon Fire OS - * Android - * BlackBerry 10 - * Firefox OS - * iOS - * Windows Phone 7 und 8 * - * Windows 8 * - * Windows* - * Browser - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## Wo Dateien gespeichert - -Stand: V1 werden URLs auf wichtige Datei-System-Verzeichnisse zur Verfügung gestellt. Jede URL in der Form *file:///path/to/spot/* ist, und ein `DirectoryEntry` mit `window.resolveLocalFileSystemURL()` konvertiert werden können. - - * `cordova.file.applicationDirectory`-Die schreibgeschützten Verzeichnis, in dem die Anwendung installiert ist. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.applicationStorageDirectory`-Root-Verzeichnis der Anwendungs-Sandbox; auf iOS ist schreibgeschützt (aber bestimmte Unterverzeichnisse [wie `/Documents` ] sind Lese-und Schreibzugriff). Alle enthaltene Daten ist für die app privat. ( *iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.dataDirectory`-Beständige und private Datenspeicherung innerhalb der Anwendungs-Sandbox, die mit internen Speicher (auf Android, externen Speicher verwenden, verwenden Sie `.externalDataDirectory` ). Auf iOS, ist dieses Verzeichnis nicht mit iCloud synchronisiert (verwenden Sie `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.cacheDirectory`-Verzeichnis der zwischengespeicherten Daten-Dateien oder Dateien, die Ihre app einfach neu erstellen können. Das Betriebssystem kann diese Dateien löschen, wenn das Gerät auf Speicher knapp wird, dennoch sollten die apps vom Betriebssystem zum Löschen von Dateien hier nicht verlassen. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.externalApplicationStorageDirectory`-Anwendungsraum auf externen Speicher. (*Android*) - - * `cordova.file.externalDataDirectory`-Wo, app-spezifische Datendateien auf externen Speicher setzen. (*Android*) - - * `cordova.file.externalCacheDirectory`-Anwendungscache auf externen Speicher. (*Android*) - - * `cordova.file.externalRootDirectory`-Externer Speicher (SD-Karte) Stamm. (*Android*, *BlackBerry 10*) - - * `cordova.file.tempDirectory`-Temp-Verzeichnis, dem das OS auf deaktivieren können wird. Verlassen Sie sich nicht auf das Betriebssystem, um dieses Verzeichnis zu löschen; Ihre Anwendung sollte immer Dateien gegebenenfalls entfernen. (*iOS*) - - * `cordova.file.syncedDataDirectory`-Hält app-spezifische Dateien, die (z. B. auf iCloud) synchronisiert werden sollten. (*iOS*) - - * `cordova.file.documentsDirectory`-Dateien für die app, aber privat sind sinnvoll, andere Anwendungen (z.B. Office-Dateien). (*iOS*) - - * `cordova.file.sharedDirectory`-Dateien für alle Anwendungen (*BlackBerry 10* weltweit verfügbar) - -## Dateisystemlayouts - -Obwohl technisch ein Implementierungsdetail, kann es sehr hilfreich zu wissen, wie die `cordova.file.*`-Eigenschaften physikalische Pfade auf einem echten Gerät zugeordnet sein. - -### iOS-Datei-System-Layout - -| Gerätepfad | `Cordova.file.*` | `iosExtraFileSystems` | R/w? | persistent? | OS löscht | Sync | Private | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:-----------:|:------------:|:----:|:-------:| -| `/ Var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Ja | -| `appname.app/` | applicationDirectory | Bundle | r | N/A | N/A | N/A | Ja | -| `www/` | - | - | r | N/A | N/A | N/A | Ja | -| `Documents/` | documentsDirectory | Dokumente | R/w | Ja | Nein | Ja | Ja | -| `NoCloud/` | - | Dokumente-nosync | R/w | Ja | Nein | Nein | Ja | -| `Library` | - | Bibliothek | R/w | Ja | Nein | Ja? | Ja | -| `NoCloud/` | dataDirectory | Bibliothek-nosync | R/w | Ja | Nein | Nein | Ja | -| `Cloud/` | syncedDataDirectory | - | R/w | Ja | Nein | Ja | Ja | -| `Caches/` | cacheDirectory | Cache | R/w | Ja * | Ja**\* | Nein | Ja | -| `tmp/` | tempDirectory | - | R/w | Nein** | Ja**\* | Nein | Ja | - -\ * Dateien über app-Neustarts und Upgrades beibehalten, aber dieses Verzeichnis kann gelöscht werden, wenn das OS begehrt. Ihre Anwendung sollte in der Lage, alle Inhalte neu zu erstellen, die gelöscht werden können. - -** -Dateien kann über app-Neustarts beizubehalten, aber verlasse dich nicht auf dieses Verhalten. Dateien sind nicht unbedingt Aktuelles beibehalten. Ihre Anwendung sollte Dateien aus diesem Verzeichnis entfernen, wenn es gilt, diese Dateien werden entfernt, da das OS nicht wann (oder auch wenn) garantiert. - -**\ * The OS kann den Inhalt dieses Verzeichnisses löschen, wann immer es sich anfühlt, ist es erforderlich, aber verlassen Sie sich nicht dazu. Sie sollten dieses Verzeichnis entsprechend Ihrer Anwendung deaktivieren. - -### Android File System-Layout - -| Gerätepfad | `Cordova.file.*` | `AndroidExtraFileSystems` | R/w? | persistent? | OS löscht | Private | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:----:|:-----------:|:----------:|:-------:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | Ja | -| `/ Data/Data/< app-Id > /` | applicationStorageDirectory | - | R/w | N/A | N/A | Ja | -| `cache` | cacheDirectory | Cache | R/w | Ja | Ja\* | Ja | -| `files` | dataDirectory | Dateien | R/w | Ja | Nein | Ja | -| `Documents` | | Dokumente | R/w | Ja | Nein | Ja | -| `< Sdcard > /` | externalRootDirectory | sdcard | R/w | Ja | Nein | Nein | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | R/w | Ja | Nein | Nein | -| `cache` | externalCacheDirectry | Cache-extern | R/w | Ja | Nein** | Nein | -| `files` | externalDataDirectory | Dateien-extern | R/w | Ja | Nein | Nein | - -\ * OS kann regelmäßig dieses Verzeichnis zu löschen, aber verlasse dich nicht auf dieses Verhalten. Deaktivieren Sie den Inhalt dieses Verzeichnisses für Ihre Anwendung geeigneten. Ein Benutzer den Cache manuell löschen sollte, werden die Inhalte dieses Verzeichnisses entfernt. - -** Der OS nicht klar dieses Verzeichnis automatisch; Sie sind verantwortlich für die Inhalte selbst verwalten. Der Benutzer den Cache manuell löschen sollte, werden der Inhalt des Verzeichnisses entfernt. - -**Hinweis**: Wenn externe Speichergeräte nicht bereitgestellt werden kann, sind die `cordova.file.external*` Eigenschaften `null`. - -### BlackBerry 10-File-System-Layout - -| Gerätepfad | `Cordova.file.*` | R/w? | persistent? | OS löscht | Private | -|:----------------------------------------------------------- |:--------------------------- |:----:|:-----------:|:---------:|:-------:| -| `file:///Accounts/1000/APPDATA/ < app Id > /` | applicationStorageDirectory | r | N/A | N/A | Ja | -| `app/native` | applicationDirectory | r | N/A | N/A | Ja | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | R/w | Nein | Ja | Ja | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | R/w | Ja | Nein | Ja | -| `file:///Accounts/1000/Removable/sdcard` | externalRemovableDirectory | R/w | Ja | Nein | Nein | -| `file:///Accounts/1000/Shared` | sharedDirectory | R/w | Ja | Nein | Nein | - -*Hinweis*: Wenn die Anwendung bereitgestellt wird, um Perimeter zu arbeiten, alle Pfade sind relativ /accounts/1000-enterprise. - -## Android Eigenarten - -### Android permanenten Speicherort - -Es gibt mehrere gültige Speicherorte, persistente Dateien auf einem Android-Gerät zu speichern. Finden Sie auf [dieser Seite](http://developer.android.com/guide/topics/data/data-storage.html) eine ausführliche Diskussion über die verschiedenen Möglichkeiten. - -Frühere Versionen des Plugins wählen würde, den Speicherort der temporären und permanenten Dateien beim Start, basierend auf, ob das Gerät behauptete, dass die SD-Karte (oder gleichwertige Speicherpartition) bereitgestellt wurde. Wenn die SD-Karte eingelegt wurde, oder wenn eine große interne Speicherpartition verfügbar war (wie auf Nexus-Geräten) und dann in die Wurzel dieses Raumes, die persistenten Dateien gespeichert werden. Dies bedeutete, dass alle Cordova apps aller verfügbaren Dateien auf der Karte sehen konnte. - -Wenn die SD-Karte nicht verfügbar war, dann Vorgängerversionen Daten unter speichern würde `/data/data/<packageId>`, die isoliert Anwendungen voneinander, aber möglicherweise noch Ursache Daten zwischen Benutzern freigegeben werden. - -Es ist jetzt möglich, ob Sie Dateien der internen Datei-Speicherort oder unter Verwendung der bisherigen Logik, mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `"config.xml"`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Ohne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet. - -Wenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Wechseln die Location auf "Internal" würde bedeuten, dass Benutzer, die aktualisieren Sie ihre Anwendung, möglicherweise nicht auf ihre zuvor gespeicherte Dateien, abhängig von ihrem Gerät zugreifen. - -Wenn Ihre Anwendung neu ist, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die `Internal` Einstellung in der Regel empfohlen. - -### Langsame rekursive Operationen für /android_asset - -Auflisten von Verzeichnissen Vermögenswert ist wirklich langsam auf Android. Sie können beschleunigen, es oben aber durch `src/android/build-extras.gradle` in das Stammverzeichnis von Ihrem android Projekt hinzufügen (erfordert auch cordova-android@4.0.0 oder größer). - -## iOS Macken - - * `cordova.file.applicationStorageDirectory`ist schreibgeschützt; zum Speichern von Dateien im Stammverzeichnis der Versuch schlägt fehl. Verwenden Sie eine der anderen `cordova.file.*` für iOS definierten Eigenschaften (nur `applicationDirectory` und `applicationStorageDirectory` sind schreibgeschützt). - * `FileReader.readAsText(blob, encoding)` - * Die `encoding` Parameter wird nicht unterstützt und UTF-8-Kodierung ist immer wirksam. - -### iOS permanenten Speicherort - -Es gibt zwei gültige Speicherorte persistente Dateien auf ein iOS-Gerät speichern: das Dokumenten-Verzeichnis und das Verzeichnis Library. Frühere Versionen des Plugins gespeichert immer nur persistente Dateien im Verzeichnis Dokumente. Dies hatte den Nebeneffekt einer Anwendung Dateien in iTunes, die oft unbeabsichtigte, speziell für Anwendungen, die viele kleine Dateien behandeln war, sichtbar zu machen, anstatt komplette Dokumente für den Export, die den beabsichtigten Zweck des Verzeichnisses ist zu produzieren. - -Es ist jetzt möglich, ob Sie Dateien in Dokumente oder Verzeichnis Library mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `"config.xml"`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Ohne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet. - -Wenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Standort zur `Library` wechseln würde bedeuten, dass Benutzer, die ihre Anwendung aktualisieren nicht in der Lage wäre, ihre zuvor gespeicherte Dateien zugreifen. - -Wenn die Anwendung neu, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die Einstellung der `Library` allgemein empfohlen. - -## Firefox OS Macken - -Der Datei-System-API wird von Firefox-OS nicht nativ unterstützt und wird als ein Shim auf IndexedDB implementiert. - - * Schlägt nicht fehl, wenn Sie nicht leere Verzeichnisse entfernen - * Metadaten wird für Verzeichnisse nicht unterstützt. - * Methoden `copyTo` und `moveTo` unterstützen keine Verzeichnisse - -Die folgenden Datenpfade werden unterstützt: * `applicationDirectory` - `xhr` verwendet, um lokale Dateien erhalten, die mit der app verpackt sind. *`dataDirectory` - für persistente app-spezifische Daten-Dateien. *`cacheDirectory` - Cache-Dateien, die app startet überleben sollte (Apps sollten nicht vom Betriebssystem zum Löschen von Dateien hier verlassen). - -## Browser-Eigenheiten - -### Gemeinsamen Macken und Bemerkungen - - * Jeder Browser verwendet ein eigene Sandbox Dateisystem. IE und Firefox verwenden IndexedDB als Basis. Alle Browser verwenden Schrägstrich als Verzeichnistrennzeichen in einem Pfad. - * Directory-Einträge müssen nacheinander erstellt werden. Z. B. der Aufruf `fs.root.getDirectory ("dir1/Ordner2 ', {create:true}, SuccessCallback, ErrorCallback)` schlägt fehl, wenn dir1 nicht existierte. - * Das Plugin fordert Benutzer die Berechtigung zum permanenten Speicher beim ersten Start Anwendung verwenden. - * Plugin unterstützt `Cdvfile://localhost` (lokale Ressourcen) nur. D.h. externe Ressourcen nicht über `Cdvfile` unterstützt. - * Das Plugin folgt nicht ["File System API 8.3 Naming Einschränkungen"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). - * BLOB und Datei "`close`-Funktion wird nicht unterstützt. - * `FileSaver` und `BlobBuilder` werden von diesem Plugin nicht unterstützt und müssen nicht geboren. - * Das Plugin unterstützt keine `RequestAllFileSystems`. Diese Funktion fehlt auch in den Spezifikationen. - * Einträge im Verzeichnis werden nicht entfernt werden, wenn Sie verwenden `create: true` Flag für vorhandenes Verzeichnis. - * Über Konstruktor erstellte Dateien werden nicht unterstützt. Sie sollten stattdessen die entry.file-Methode verwenden. - * Jeder Browser verwendet eine eigene Form für Blob-URL-Verweise. - * `readAsDataURL`-Funktion wird unterstützt, aber die Mediatype in Chrom hängt von der Eintrag Namenerweiterung, Mediatype im IE immer leer ist (das ist dasselbe wie `Text-Plain` gemäß der Spezifikation), Mediatype in Firefox ist immer `Application/Octet-Stream`. Beispielsweise, wenn der Inhalt `Abcdefg` gibt dann Firefox `Daten: Anwendung / Octet-Stream; base64, YWJjZGVmZw ==`, IE gibt `Daten:; base64, YWJjZGVmZw ==`, Chrom gibt `Daten: < Mediatype je nach Erweiterung des Eintragsnamens >; base64, YWJjZGVmZw ==`. - * `ToInternalURL` gibt den Pfad zurück, in der Form `file:///persistent/path/to/entry` (Firefox, IE). Chrom gibt den Pfad zurück, in der Form `cdvfile://localhost/persistent/file`. - -### Chrom-Macken - - * Chrom-Dateisystem ist nicht sofort nach Gerät bereit. Als Workaround können Sie `FilePluginIsReady`-Ereignis abonnieren. Beispiel: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -`Window.isFilePluginReadyRaised`-Funktion können Sie überprüfen, ob Ereignis bereits ausgelöst wurde. -window.requestFileSystem temporär und PERSISTENTE Dateisystem-Quoten sind nicht begrenzt, in Chrom. -Um die dauerhafte Speicherung in Chrom zu erhöhen benötigen Sie `window.initPersistentFileSystem`-Methode aufrufen. Permanenter Speicherkontingent beträgt 5 MB standardmäßig. -Chrome erforderlich `--erlauben-Datei-Zugriff-aus-Files` Argument an den Support API via `file:///` Protokoll führen. -`Datei`-Objekt wird nicht geändert werden, wenn Sie Flag verwenden `{create:true}` als einen vorhandenen `Eintrag` zu erhalten. -Veranstaltungen `cancelable`-Eigenschaft festgelegt ist in Chrom wahr. Dies widerspricht der [Spezifikation](http://dev.w3.org/2009/dap/file-system/file-writer.html). -`toURL`-Funktion in Chrome zurück `Dateisystem:`-Pfad je nach Anwendungshost vorangestellt. Z. B. `filesystem:file:///persistent/somefile.txt`, `Filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` Funktionsergebnis enthält keine nachgestellten Schrägstrich bei Verzeichniseintrag. Chrom löst Verzeichnisse mit Schrägstrich-gezogene Urls aber korrekt. -`ResolveLocalFileSystemURL`-Methode erfordert die eingehenden `Url` `Dateisystem` Präfix haben. Beispielsweise sollte die `Url`-Parameter für `ResolveLocalFileSystemURL` in der Form `filesystem:file:///persistent/somefile.txt` im Gegensatz zu der Form `file:///persistent/somefile.txt` in Android. -Veraltete `ToNativeURL`-Funktion wird nicht unterstützt und muss keinen Stub. -`SetMetadata`-Funktion ist nicht in den Spezifikationen angegeben und nicht unterstützt. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, statt SYNTAX_ERR(code: 8) auf anfordern des Dateisystems nicht existent. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt PATH_EXISTS_ERR(code: 12) zu versuchen, die ausschließlich eine Datei oder ein Verzeichnis zu erstellen, die bereits vorhanden ist. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NO_MODIFICATION_ALLOWED_ERR(code: 6) zu versuchen, rufen Sie RemoveRecursively auf das Root-Dateisystem. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NOT_FOUND_ERR(code: 1) zu versuchen, MoveTo-Verzeichnis, das nicht vorhanden ist. - -### Auf der Grundlage von IndexedDB Impl Macken (Firefox und IE) - - * `.` und `.` werden nicht unterstützt. - * IE unterstützt keine `file:///`-Modus; nur der Modus für gehostete ist unterstützten (Http://localhost:xxxx). - * Firefox Dateisystem Größe ist nicht begrenzt, aber jede 50MB-Erweiterung wird eine Benutzer die Berechtigung anzufordern. IE10 können bis zu 10mb kombinierte AppCache und IndexedDB in Implementierung des Dateisystems verwendet, ohne Aufforderung, sobald Sie dieses Niveau, werden, das Sie aufgefordert werden schlagen, wenn Sie es bis Max 250 mb pro Standort erhöht werden sollen. `Size`-Parameter für `RequestFileSystem` Funktion wirkt also nicht Dateisystem in Firefox und IE. - * `ReadAsBinaryString` Funktion heißt es nicht in die Angaben und in IE nicht unterstützt und muss keinen Stub. - * `file.Type` ist immer null. - * Sie sollten nicht erstellen Eintrag mit DirectoryEntry Instanz Rückrufergebnis, die gelöscht wurde. Andernfalls erhalten Sie einen "hängende Eintrag". - * Bevor Sie eine Datei lesen können, die gerade geschrieben wurde, müssen Sie eine neue Instanz dieser Datei erhalten. - * `SetMetadata`-Funktion, die nicht in den Specs genannt unterstützt Feldänderung nur `ModificationTime`. - * `CopyTo` und `MoveTo`-Funktionen unterstützen keine Verzeichnisse. - * Verzeichnisse-Metadaten werden nicht unterstützt. - * Beide Entry.remove und directoryEntry.removeRecursively nicht scheitern, wenn nicht leere Verzeichnisse entfernen - Verzeichnisse entfernt werden stattdessen zusammen mit Inhalt gereinigt. - * `abort` und `truncate`-Funktionen werden nicht unterstützt. - * Progress-Ereignisse werden nicht ausgelöst. Beispielsweise wird dieser Handler nicht ausgeführt werden: - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## Upgrade Notes - -In v1.0.0 dieses Plugins haben die `FileEntry` und `DirectoryEntry` Strukturen geändert, um mehr im Einklang mit der veröffentlichten Spezifikation sein. - -Vorgängerversionen (Pre-1.0.0) des Plugins den Gerät-Absolute-Dateispeicherort in der Eigenschaft `fullPath` `Entry` Objekte gespeichert. Diese Pfade würde in der Regel aussehen - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Diese Pfade wurden auch von der `toURL()`-Methode der `Entry` Objekte zurückgegeben. - -Mit v1.0.0 ist das `fullPath`-Attribut den Pfad zu der Datei, *relativ zum Stammverzeichnis des Dateisystems HTML*. Also, würde die oben genannten Wege jetzt beide durch ein `FileEntry`-Objekt mit einem `fullPath` von dargestellt werden - - /path/to/file - - -Wenn Ihre Anwendung mit absoluter Gerätepfade arbeitet und Sie zuvor diese Pfade durch die Eigenschaft `fullPath` `Entry` Objekte abgerufen, sollten dann Sie den Code, um stattdessen `entry.toURL()` verwenden aktualisieren. - -Für rückwärts Kompatibilität, die `resolveLocalFileSystemURL()`-Methode wird einen Absolute-Gerätepfad zu akzeptieren und kehrt ein `Entry`-Objekt entspricht, solange diese Datei in den `TEMPORARY` oder `PERSISTENT` Dateisysteme existiert. - -Dies wurde vor allem ein Problem mit dem File-Transfer-Plugin, die zuvor-Absolute-Gerätepfade verwendet (und kann damit noch einverstanden). Es wurde überarbeitet, um mit Dateisystem-URLs korrekt zu arbeiten, damit ersetzen `entry.fullPath` mit `entry.toURL()` immer das Plugin zum Arbeiten mit Dateien auf dem Gerät Probleme lösen sollte. - -In v1.1.0 wurde der Rückgabewert von `toURL()` (siehe \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) geändert, um eine absolute "file://" URL zurückgeben. wo immer möglich. Sicherstellung einer ' Cdvfile:'-URL können Sie an `toInternalURL()`. Diese Methode gibt jetzt Dateisystem URLs der Form zurück. - - cdvfile://localhost/persistent/path/to/file - - -die benutzt werden können, um die Datei eindeutig zu identifizieren. - -## Liste der Fehlercodes und Bedeutungen - -Wenn ein Fehler ausgelöst wird, wird eines der folgenden Codes verwendet werden. - -| Code | Konstante | -| ----:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Konfigurieren das Plugin (Optional) - -Die Menge der verfügbaren Dateisysteme kann pro Plattform konfiguriert sein. Erkennen von iOS und Android ein <preference> Tag in `"config.xml"` die Namen der Dateisysteme installiert werden. Standardmäßig sind alle Datei-System-Roots aktiviert. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - - * `files`: interne Datei-Speicher-Verzeichnis der Anwendung - * `files-external`: Verzeichnis der Anwendung externe Datei Speicher - * `sdcard`: das externe Globaldatei-Speicherverzeichnis (Dies ist die Wurzel der SD-Karte, sofern installiert). Sie benötigen die Berechtigung zur Verwendung dieses `android.permission.WRITE_EXTERNAL_STORAGE`. - * `cache`: internen Cache-Verzeichnis der Anwendung - * `cache-external`: externer Cache-Verzeichnis der Anwendung - * `root`: das gesamte Gerät-Dateisystem - -Android unterstützt auch eine spezielle Dateisystem mit dem Namen "documents", die ein Unterverzeichnis "/Documents/" die "files" Dateisystem darstellt. - -### iOS - - * `library`: Bibliothek-Verzeichnis der Anwendung - * `documents`: Dokumente-Verzeichnis der Anwendung - * `cache`: Cache-Verzeichnis der Anwendung - * `bundle`: die Anwendung Bündel; den Speicherort der die app selbst auf dem Datenträger (schreibgeschützt) - * `root`: das gesamte Gerät-Dateisystem - -Standardmäßig können die Bibliothek und Dokumenten-Verzeichnisse mit iCloud synchronisiert werden. Sie können auch verlangen, zwei zusätzliche Dateisysteme, `library-nosync` und `documents-nosync`, die einem speziellen nicht synchronisierten Verzeichnis innerhalb darstellen der `/Library` oder `/Documents`-Dateisystem.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/de/index.md b/plugins/cordova-plugin-file/doc/de/index.md deleted file mode 100644 index 2a51695d..00000000 --- a/plugins/cordova-plugin-file/doc/de/index.md +++ /dev/null @@ -1,338 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -Dieses Plugin implementiert eine File-API, die Lese-/Schreibzugriff Zugriff auf Dateien, die auf dem Gerät befinden. - -Dieses Plugin basiert auf mehrere Angaben, einschließlich: die HTML5-File-API <http://www.w3.org/TR/FileAPI/> - -Die (heute nicht mehr existierenden) Verzeichnisse und System neuesten Erweiterungen: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , obwohl die meisten von den Plugin-Code wurde geschrieben, als eine frühere Spec aktuell waren: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Es implementiert auch die FileWriter Spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Verwendung finden Sie in HTML5 Rocks ausgezeichnete [Dateisystem Artikel.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -Finden Sie einen Überblick über andere Speicheroptionen Cordovas [Speicher-Führer][2]. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -Dieses Plugin wird global `cordova.file`-Objekt definiert. - -Obwohl im globalen Gültigkeitsbereich, steht es nicht bis nach dem `deviceready`-Ereignis. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Installation - - cordova plugin add cordova-plugin-file - - -## Unterstützte Plattformen - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows Phone 7 und 8 * -* Windows 8 * -* Browser - -* *Diese Plattformen unterstützen nicht `FileReader.readAsArrayBuffer` noch `FileWriter.write(blob)`.* - -## Wo Dateien gespeichert - -Stand: V1 werden URLs auf wichtige Datei-System-Verzeichnisse zur Verfügung gestellt. Jede URL in der Form *file:///path/to/spot/* ist, und ein `DirectoryEntry` mit `window.resolveLocalFileSystemURL()` konvertiert werden können. - -* `cordova.file.applicationDirectory`-Die schreibgeschützten Verzeichnis, in dem die Anwendung installiert ist. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.applicationStorageDirectory`-Root-Verzeichnis der Anwendungs-Sandbox; auf iOS ist schreibgeschützt (aber bestimmte Unterverzeichnisse [wie `/Documents` ] sind Lese-und Schreibzugriff). Alle enthaltene Daten ist für die app privat. ( *iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.dataDirectory`-Beständige und private Datenspeicherung innerhalb der Anwendungs-Sandbox, die mit internen Speicher (auf Android, externen Speicher verwenden, verwenden Sie `.externalDataDirectory` ). Auf iOS, ist dieses Verzeichnis nicht mit iCloud synchronisiert (verwenden Sie `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.cacheDirectory`-Verzeichnis der zwischengespeicherten Daten-Dateien oder Dateien, die Ihre app einfach neu erstellen können. Das Betriebssystem kann diese Dateien löschen, wenn das Gerät auf Speicher knapp wird, dennoch sollten die apps vom Betriebssystem zum Löschen von Dateien hier nicht verlassen. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.externalApplicationStorageDirectory`-Anwendungsraum auf externen Speicher. (*Android*) - -* `cordova.file.externalDataDirectory`-Wo, app-spezifische Datendateien auf externen Speicher setzen. (*Android*) - -* `cordova.file.externalCacheDirectory`-Anwendungscache auf externen Speicher. (*Android*) - -* `cordova.file.externalRootDirectory`-Externer Speicher (SD-Karte) Stamm. (*Android*, *BlackBerry 10*) - -* `cordova.file.tempDirectory`-Temp-Verzeichnis, dem das OS auf deaktivieren können wird. Verlassen Sie sich nicht auf das Betriebssystem, um dieses Verzeichnis zu löschen; Ihre Anwendung sollte immer Dateien gegebenenfalls entfernen. (*iOS*) - -* `cordova.file.syncedDataDirectory`-Hält app-spezifische Dateien, die (z. B. auf iCloud) synchronisiert werden sollten. (*iOS*) - -* `cordova.file.documentsDirectory`-Dateien für die app, aber privat sind sinnvoll, andere Anwendungen (z.B. Office-Dateien). (*iOS*) - -* `cordova.file.sharedDirectory`-Dateien für alle Anwendungen (*BlackBerry 10* weltweit verfügbar) - -## Dateisystemlayouts - -Obwohl technisch ein Implementierungsdetail, kann es sehr hilfreich zu wissen, wie die `cordova.file.*`-Eigenschaften physikalische Pfade auf einem echten Gerät zugeordnet sein. - -### iOS-Datei-System-Layout - -| Gerätepfad | `Cordova.file.*` | `iosExtraFileSystems` | R/w? | persistent? | OS löscht | Sync | Private | -|:-------------------------------------------- |:--------------------------- |:--------------------- |:----:|:-----------:|:----------:|:----:|:-------:| -| `/ Var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Ja | -| `appname.app/` | applicationDirectory | Bundle | r | N/A | N/A | N/A | Ja | -| `www/` | - | - | r | N/A | N/A | N/A | Ja | -| `Documents/` | documentsDirectory | Dokumente | R/w | Ja | Nein | Ja | Ja | -| `NoCloud/` | - | Dokumente-nosync | R/w | Ja | Nein | Nein | Ja | -| `Library` | - | Bibliothek | R/w | Ja | Nein | Ja? | Ja | -| `NoCloud/` | dataDirectory | Bibliothek-nosync | R/w | Ja | Nein | Nein | Ja | -| `Cloud/` | syncedDataDirectory | - | R/w | Ja | Nein | Ja | Ja | -| `Caches/` | cacheDirectory | Cache | R/w | Ja * | Ja * * *| | Nein | Ja | -| `tmp/` | tempDirectory | - | R/w | Nicht * * | Ja * * *| | Nein | Ja | - -* Dateien werden hinweg app Neustarts und Upgrades beibehalten, aber dieses Verzeichnis kann gelöscht werden, wenn das OS begehrt. Ihre Anwendung sollte in der Lage, Inhalte zu erschaffen, die möglicherweise gelöscht werden. - -* *-Dateien kann über app-Neustarts beizubehalten, aber verlasse dich nicht auf dieses Verhalten. Dateien sind nicht unbedingt Aktuelles beibehalten. Ihre Anwendung sollte Dateien aus diesem Verzeichnis entfernen, wenn es gilt, diese Dateien werden entfernt, da das OS nicht wann (oder auch wenn) garantiert. - -* * *| The OS kann den Inhalt dieses Verzeichnisses löschen, wenn es sich anfühlt, ist es erforderlich, aber verlassen Sie sich nicht dazu. Sie sollten dieses Verzeichnis entsprechend Ihrer Anwendung deaktivieren. - -### Android File System-Layout - -| Gerätepfad | `Cordova.file.*` | `AndroidExtraFileSystems` | R/w? | persistent? | OS löscht | Private | -|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:-----------:|:---------:|:-------:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | Ja | -| `/ Data/Data/< app-Id > /` | applicationStorageDirectory | - | R/w | N/A | N/A | Ja | -| `cache` | cacheDirectory | Cache | R/w | Ja | Ja * | Ja | -| `files` | dataDirectory | Dateien | R/w | Ja | Nein | Ja | -| `Documents` | | Dokumente | R/w | Ja | Nein | Ja | -| `< Sdcard > /` | externalRootDirectory | sdcard | R/w | Ja | Nein | Nein | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | R/w | Ja | Nein | Nein | -| `cache` | externalCacheDirectry | Cache-extern | R/w | Ja | Nicht * * | Nein | -| `files` | externalDataDirectory | Dateien-extern | R/w | Ja | Nein | Nein | - -* Das Betriebssystem kann regelmäßig dieses Verzeichnis zu löschen, aber verlasse dich nicht auf dieses Verhalten. Deaktivieren Sie den Inhalt dieses Verzeichnisses für Ihre Anwendung geeigneten. Ein Benutzer den Cache manuell löschen sollte, werden die Inhalte dieses Verzeichnisses entfernt. - -* * The OS nicht klar dieses Verzeichnis automatisch; Sie sind verantwortlich für die Inhalte selbst verwalten. Der Benutzer den Cache manuell löschen sollte, werden der Inhalt des Verzeichnisses entfernt. - -**Hinweis**: Wenn externe Speichergeräte nicht bereitgestellt werden kann, sind die `cordova.file.external*` Eigenschaften `null`. - -### BlackBerry 10-File-System-Layout - -| Gerätepfad | `Cordova.file.*` | R/w? | persistent? | OS löscht | Private | -|:--------------------------------------------------- |:--------------------------- |:----:|:-----------:|:---------:|:-------:| -| `file:///Accounts/1000/APPDATA/ < app Id > /` | applicationStorageDirectory | r | N/A | N/A | Ja | -| `app/native` | applicationDirectory | r | N/A | N/A | Ja | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | R/w | Nein | Ja | Ja | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | R/w | Ja | Nein | Ja | -| `file:///Accounts/1000/Removable/sdcard` | externalRemovableDirectory | R/w | Ja | Nein | Nein | -| `file:///Accounts/1000/Shared` | sharedDirectory | R/w | Ja | Nein | Nein | - -*Hinweis*: Wenn die Anwendung bereitgestellt wird, um Perimeter zu arbeiten, alle Pfade sind relativ /accounts/1000-enterprise. - -## Android Eigenarten - -### Android permanenten Speicherort - -Es gibt mehrere gültige Speicherorte, persistente Dateien auf einem Android-Gerät zu speichern. Finden Sie auf [dieser Seite][3] eine ausführliche Diskussion über die verschiedenen Möglichkeiten. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -Frühere Versionen des Plugins wählen würde, den Speicherort der temporären und permanenten Dateien beim Start, basierend auf, ob das Gerät behauptete, dass die SD-Karte (oder gleichwertige Speicherpartition) bereitgestellt wurde. Wenn die SD-Karte eingelegt wurde, oder wenn eine große interne Speicherpartition verfügbar war (wie auf Nexus-Geräten) und dann in die Wurzel dieses Raumes, die persistenten Dateien gespeichert werden. Dies bedeutete, dass alle Cordova apps aller verfügbaren Dateien auf der Karte sehen konnte. - -Wenn die SD-Karte nicht verfügbar war, dann Vorgängerversionen Daten unter speichern würde `/data/data/<packageId>`, die isoliert Anwendungen voneinander, aber möglicherweise noch Ursache Daten zwischen Benutzern freigegeben werden. - -Es ist jetzt möglich, ob Sie Dateien der internen Datei-Speicherort oder unter Verwendung der bisherigen Logik, mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `"config.xml"`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Ohne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet. - -Wenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Wechseln die Location auf "Internal" würde bedeuten, dass Benutzer, die aktualisieren Sie ihre Anwendung, möglicherweise nicht auf ihre zuvor gespeicherte Dateien, abhängig von ihrem Gerät zugreifen. - -Wenn Ihre Anwendung neu ist, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die `Internal` Einstellung in der Regel empfohlen. - -## iOS Macken - -* `cordova.file.applicationStorageDirectory`ist schreibgeschützt; zum Speichern von Dateien im Stammverzeichnis der Versuch schlägt fehl. Verwenden Sie eine der anderen `cordova.file.*` für iOS definierten Eigenschaften (nur `applicationDirectory` und `applicationStorageDirectory` sind schreibgeschützt). -* `FileReader.readAsText(blob, encoding)` - * Die `encoding` Parameter wird nicht unterstützt und UTF-8-Kodierung ist immer wirksam. - -### iOS permanenten Speicherort - -Es gibt zwei gültige Speicherorte persistente Dateien auf ein iOS-Gerät speichern: das Dokumenten-Verzeichnis und das Verzeichnis Library. Frühere Versionen des Plugins gespeichert immer nur persistente Dateien im Verzeichnis Dokumente. Dies hatte den Nebeneffekt einer Anwendung Dateien in iTunes, die oft unbeabsichtigte, speziell für Anwendungen, die viele kleine Dateien behandeln war, sichtbar zu machen, anstatt komplette Dokumente für den Export, die den beabsichtigten Zweck des Verzeichnisses ist zu produzieren. - -Es ist jetzt möglich, ob Sie Dateien in Dokumente oder Verzeichnis Library mit einer Präferenz in der Anwendung-`config.xml`-Datei speichern möchten. Hierzu fügen Sie eine dieser zwei Zeilen zu `"config.xml"`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Ohne diese Zeile wird das Datei Plugin `Compatibility` als Standard verwenden. Wenn ein Präferenz-Tag vorhanden ist, und nicht einen der folgenden Werte, wird die Anwendung nicht gestartet. - -Wenn Ihre Anwendung für Benutzer zuvor versandt wird, mithilfe eines älteren (Pre-1.0) Version dieses Plugins und gespeicherte Dateien im permanenten Dateisystem hat, dann sollten Sie die Einstellung zur `Compatibility` einstellen. Standort zur `Library` wechseln würde bedeuten, dass Benutzer, die ihre Anwendung aktualisieren nicht in der Lage wäre, ihre zuvor gespeicherte Dateien zugreifen. - -Wenn die Anwendung neu, oder nie zuvor Dateien im Dateisystem persistent gespeichert hat, wird die Einstellung der `Library` allgemein empfohlen. - -## Firefox OS Macken - -Der Datei-System-API wird von Firefox-OS nicht nativ unterstützt und wird als ein Shim auf IndexedDB implementiert. - -* Schlägt nicht fehl, wenn Sie nicht leere Verzeichnisse entfernen -* Metadaten wird für Verzeichnisse nicht unterstützt. -* Methoden `copyTo` und `moveTo` unterstützen keine Verzeichnisse - -Die folgenden Datenpfade werden unterstützt: * `applicationDirectory` - `xhr` verwendet, um lokale Dateien erhalten, die mit der app verpackt sind. *`dataDirectory` - für persistente app-spezifische Daten-Dateien. *`cacheDirectory` - Cache-Dateien, die app startet überleben sollte (Apps sollten nicht vom Betriebssystem zum Löschen von Dateien hier verlassen). - -## Browser-Eigenheiten - -### Gemeinsamen Macken und Bemerkungen - -* Jeder Browser verwendet ein eigene Sandbox Dateisystem. IE und Firefox verwenden IndexedDB als Basis. Alle Browser verwenden Schrägstrich als Verzeichnistrennzeichen in einem Pfad. -* Directory-Einträge müssen nacheinander erstellt werden. Z. B. der Aufruf `fs.root.getDirectory ("dir1/Ordner2 ', {create:true}, SuccessCallback, ErrorCallback)` schlägt fehl, wenn dir1 nicht existierte. -* Das Plugin fordert Benutzer die Berechtigung zum permanenten Speicher beim ersten Start Anwendung verwenden. -* Plugin unterstützt `Cdvfile://localhost` (lokale Ressourcen) nur. D.h. externe Ressourcen nicht über `Cdvfile` unterstützt. -* Das Plugin folgt nicht ["File System API 8.3 Naming Einschränkungen"][4]. -* BLOB und Datei "`close`-Funktion wird nicht unterstützt. -* `FileSaver` und `BlobBuilder` werden von diesem Plugin nicht unterstützt und müssen nicht geboren. -* Das Plugin unterstützt keine `RequestAllFileSystems`. Diese Funktion fehlt auch in den Spezifikationen. -* Einträge im Verzeichnis werden nicht entfernt werden, wenn Sie verwenden `create: true` Flag für vorhandenes Verzeichnis. -* Über Konstruktor erstellte Dateien werden nicht unterstützt. Sie sollten stattdessen die entry.file-Methode verwenden. -* Jeder Browser verwendet eine eigene Form für Blob-URL-Verweise. -* `readAsDataURL`-Funktion wird unterstützt, aber die Mediatype in Chrom hängt von der Eintrag Namenerweiterung, Mediatype im IE immer leer ist (das ist dasselbe wie `Text-Plain` gemäß der Spezifikation), Mediatype in Firefox ist immer `Application/Octet-Stream`. Beispielsweise, wenn der Inhalt `Abcdefg` gibt dann Firefox `Daten: Anwendung / Octet-Stream; base64, YWJjZGVmZw ==`, IE gibt `Daten:; base64, YWJjZGVmZw ==`, Chrom gibt `Daten: < Mediatype je nach Erweiterung des Eintragsnamens >; base64, YWJjZGVmZw ==`. -* `ToInternalURL` gibt den Pfad zurück, in der Form `file:///persistent/path/to/entry` (Firefox, IE). Chrom gibt den Pfad zurück, in der Form `cdvfile://localhost/persistent/file`. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### Chrom-Macken - -* Chrom-Dateisystem ist nicht sofort nach Gerät bereit. Als Workaround können Sie `FilePluginIsReady`-Ereignis abonnieren. Beispiel: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -`Window.isFilePluginReadyRaised`-Funktion können Sie überprüfen, ob Ereignis bereits ausgelöst wurde. -window.requestFileSystem temporär und PERSISTENTE Dateisystem-Quoten sind nicht begrenzt, in Chrom. -Um die dauerhafte Speicherung in Chrom zu erhöhen benötigen Sie `window.initPersistentFileSystem`-Methode aufrufen. Permanenter Speicherkontingent beträgt 5 MB standardmäßig. -Chrome erforderlich `--erlauben-Datei-Zugriff-aus-Files` Argument an den Support API via `file:///` Protokoll führen. -`Datei`-Objekt wird nicht geändert werden, wenn Sie Flag verwenden `{create:true}` als einen vorhandenen `Eintrag` zu erhalten. -Veranstaltungen `cancelable`-Eigenschaft festgelegt ist in Chrom wahr. Dies widerspricht der [Spezifikation][5]. -`toURL`-Funktion in Chrome zurück `Dateisystem:`-Pfad je nach Anwendungshost vorangestellt. Z. B. `filesystem:file:///persistent/somefile.txt`, `Filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` Funktionsergebnis enthält keine nachgestellten Schrägstrich bei Verzeichniseintrag. Chrom löst Verzeichnisse mit Schrägstrich-gezogene Urls aber korrekt. -`ResolveLocalFileSystemURL`-Methode erfordert die eingehenden `Url` `Dateisystem` Präfix haben. Beispielsweise sollte die `Url`-Parameter für `ResolveLocalFileSystemURL` in der Form `filesystem:file:///persistent/somefile.txt` im Gegensatz zu der Form `file:///persistent/somefile.txt` in Android. -Veraltete `ToNativeURL`-Funktion wird nicht unterstützt und muss keinen Stub. -`SetMetadata`-Funktion ist nicht in den Spezifikationen angegeben und nicht unterstützt. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, statt SYNTAX_ERR(code: 8) auf anfordern des Dateisystems nicht existent. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt PATH_EXISTS_ERR(code: 12) zu versuchen, die ausschließlich eine Datei oder ein Verzeichnis zu erstellen, die bereits vorhanden ist. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NO_MODIFICATION_ALLOWED_ERR(code: 6) zu versuchen, rufen Sie RemoveRecursively auf das Root-Dateisystem. -INVALID_MODIFICATION_ERR (Code: 9) wird ausgelöst, anstatt NOT_FOUND_ERR(code: 1) zu versuchen, MoveTo-Verzeichnis, das nicht vorhanden ist. - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### Auf der Grundlage von IndexedDB Impl Macken (Firefox und IE) - -* `.` und `.` werden nicht unterstützt. -* IE unterstützt keine `file:///`-Modus; nur der Modus für gehostete ist unterstützten (Http://localhost:xxxx). -* Firefox Dateisystem Größe ist nicht begrenzt, aber jede 50MB-Erweiterung wird eine Benutzer die Berechtigung anzufordern. IE10 können bis zu 10mb kombinierte AppCache und IndexedDB in Implementierung des Dateisystems verwendet, ohne Aufforderung, sobald Sie dieses Niveau, werden, das Sie aufgefordert werden schlagen, wenn Sie es bis Max 250 mb pro Standort erhöht werden sollen. `Size`-Parameter für `RequestFileSystem` Funktion wirkt also nicht Dateisystem in Firefox und IE. -* `ReadAsBinaryString` Funktion heißt es nicht in die Angaben und in IE nicht unterstützt und muss keinen Stub. -* `file.Type` ist immer null. -* Sie sollten nicht erstellen Eintrag mit DirectoryEntry Instanz Rückrufergebnis, die gelöscht wurde. Andernfalls erhalten Sie einen "hängende Eintrag". -* Bevor Sie eine Datei lesen können, die gerade geschrieben wurde, müssen Sie eine neue Instanz dieser Datei erhalten. -* `SetMetadata`-Funktion, die nicht in den Specs genannt unterstützt Feldänderung nur `ModificationTime`. -* `CopyTo` und `MoveTo`-Funktionen unterstützen keine Verzeichnisse. -* Verzeichnisse-Metadaten werden nicht unterstützt. -* Beide Entry.remove und directoryEntry.removeRecursively nicht scheitern, wenn nicht leere Verzeichnisse entfernen - Verzeichnisse entfernt werden stattdessen zusammen mit Inhalt gereinigt. -* `abort` und `truncate`-Funktionen werden nicht unterstützt. -* Progress-Ereignisse werden nicht ausgelöst. Beispielsweise wird dieser Handler nicht ausgeführt werden: - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## Upgrade Notes - -In v1.0.0 dieses Plugins haben die `FileEntry` und `DirectoryEntry` Strukturen geändert, um mehr im Einklang mit der veröffentlichten Spezifikation sein. - -Vorgängerversionen (Pre-1.0.0) des Plugins den Gerät-Absolute-Dateispeicherort in der Eigenschaft `fullPath` `Entry` Objekte gespeichert. Diese Pfade würde in der Regel aussehen - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Diese Pfade wurden auch von der `toURL()`-Methode der `Entry` Objekte zurückgegeben. - -Mit v1.0.0 ist das `fullPath`-Attribut den Pfad zu der Datei, *relativ zum Stammverzeichnis des Dateisystems HTML*. Also, würde die oben genannten Wege jetzt beide durch ein `FileEntry`-Objekt mit einem `fullPath` von dargestellt werden - - /path/to/file - - -Wenn Ihre Anwendung mit absoluter Gerätepfade arbeitet und Sie zuvor diese Pfade durch die Eigenschaft `fullPath` `Entry` Objekte abgerufen, sollten dann Sie den Code, um stattdessen `entry.toURL()` verwenden aktualisieren. - -Für rückwärts Kompatibilität, die `resolveLocalFileSystemURL()`-Methode wird einen Absolute-Gerätepfad zu akzeptieren und kehrt ein `Entry`-Objekt entspricht, solange diese Datei in den `TEMPORARY` oder `PERSISTENT` Dateisysteme existiert. - -Dies wurde vor allem ein Problem mit dem File-Transfer-Plugin, die zuvor-Absolute-Gerätepfade verwendet (und kann damit noch einverstanden). Es wurde überarbeitet, um mit Dateisystem-URLs korrekt zu arbeiten, damit ersetzen `entry.fullPath` mit `entry.toURL()` immer das Plugin zum Arbeiten mit Dateien auf dem Gerät Probleme lösen sollte. - -In v1.1.0 wurde der Rückgabewert von `toURL()` (siehe \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) geändert, um eine absolute "file://" URL zurückgeben. wo immer möglich. Sicherstellung einer ' Cdvfile:'-URL können Sie an `toInternalURL()`. Diese Methode gibt jetzt Dateisystem URLs der Form zurück. - - cdvfile://localhost/persistent/path/to/file - - -die benutzt werden können, um die Datei eindeutig zu identifizieren. - -## Liste der Fehlercodes und Bedeutungen - -Wenn ein Fehler ausgelöst wird, wird eines der folgenden Codes verwendet werden. - -| Code | Konstante | -| ----:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Konfigurieren das Plugin (Optional) - -Die Menge der verfügbaren Dateisysteme kann pro Plattform konfiguriert sein. Erkennen von iOS und Android ein <preference> Tag in `"config.xml"` die Namen der Dateisysteme installiert werden. Standardmäßig sind alle Datei-System-Roots aktiviert. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - -* `files`: interne Datei-Speicher-Verzeichnis der Anwendung -* `files-external`: Verzeichnis der Anwendung externe Datei Speicher -* `sdcard`: das externe Globaldatei-Speicherverzeichnis (Dies ist die Wurzel der SD-Karte, sofern installiert). Sie benötigen die Berechtigung zur Verwendung dieses `android.permission.WRITE_EXTERNAL_STORAGE`. -* `cache`: internen Cache-Verzeichnis der Anwendung -* `cache-external`: externer Cache-Verzeichnis der Anwendung -* `root`: das gesamte Gerät-Dateisystem - -Android unterstützt auch eine spezielle Dateisystem mit dem Namen "documents", die ein Unterverzeichnis "/Documents/" die "files" Dateisystem darstellt. - -### iOS - -* `library`: Bibliothek-Verzeichnis der Anwendung -* `documents`: Dokumente-Verzeichnis der Anwendung -* `cache`: Cache-Verzeichnis der Anwendung -* `bundle`: die Anwendung Bündel; den Speicherort der die app selbst auf dem Datenträger (schreibgeschützt) -* `root`: das gesamte Gerät-Dateisystem - -Standardmäßig können die Bibliothek und Dokumenten-Verzeichnisse mit iCloud synchronisiert werden. Sie können auch verlangen, zwei zusätzliche Dateisysteme, `library-nosync` und `documents-nosync`, die einem speziellen nicht synchronisierten Verzeichnis innerhalb darstellen der `/Library` oder `/Documents`-Dateisystem. diff --git a/plugins/cordova-plugin-file/doc/de/plugins.md b/plugins/cordova-plugin-file/doc/de/plugins.md deleted file mode 100644 index 1f4297f0..00000000 --- a/plugins/cordova-plugin-file/doc/de/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# Hinweise für Plugin-Entwickler - -Diese Notizen sollen in erster Linie für Android und iOS-Entwickler, die Plugins welche Schnittstelle mit dem Dateisystem, mit dem Datei-Plugin schreiben möchten. - -## Arbeiten mit Cordova-Datei-System-URLs - -Seit der Version 1.0.0, wurde dieses Plugin URLs mit verwendet eine `cdvfile` Regelung für die gesamte Kommunikation über die Brücke, sondern als raw-Device Dateisystempfade zu JavaScript auszusetzen. - -Auf der Seite JavaScript bedeutet dies, dass FileEntries und DirectoryEntry-Objekt ein FullPath-Attribut haben, die relativ zum Stammverzeichnis des Dateisystems HTML ist. Wenn Ihr Plugins-JavaScript-API ein FileEntries oder DirectoryEntry-Objekt akzeptiert, rufen Sie `.toURL()` auf das Objekt vor der Übergabe an systemeigenen Code über die Brücke. - -### Konvertieren von Cdvfile: / / URLs auf Fileystem Pfade - -Plugins, die auf das Dateisystem schreiben müssen, möchten möglicherweise eine empfangene Datei-System-URL auf eine tatsächliche Stelle des Dateisystems zu konvertieren. Es gibt mehrere Wege, dies zu tun, je nach einheitlichen Plattform. - -Es ist wichtig zu erinnern, dass nicht alle `cdvfile://` URLs sind zuweisbaren real Dateien auf das Gerät. Einige URLs verweisen auf Vermögenswerte auf Gerät die werden nicht durch Dateien dargestellt, oder sogar auf Remoteressourcen verweisen kann. Aufgrund dieser Möglichkeiten sollten Plugins immer testen, ob sie ein sinnvolles Ergebnis zu erhalten, wieder beim URLs in Pfade umwandeln. - -#### Android - -Auf Android, die einfachste Methode zum Konvertieren eines `cdvfile://` darin, dass die URL zu einem Dateisystempfad verwenden `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`verfügt über mehrere Methoden der verarbeiten kann `cdvfile://` URLs: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -Es ist auch möglich, das Plugin Datei direkt zu verwenden: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -Konvertieren von einen Pfad zu einer `cdvfile://` URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -Wenn Ihr Plugin eine Datei erstellt, und Sie dafür ein FileEntries-Objekt zurückgeben möchten, verwenden Sie das Datei-Plugin: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -Cordova auf iOS verwendet nicht das gleiche `CordovaResourceApi` Konzept als Android. Auf iOS sollten Sie das Datei-Plugin verwenden, zum Konvertieren von URLs und Dateisystem-Pfaden. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -Wenn Ihr Plugin eine Datei erstellt, und Sie dafür ein FileEntries-Objekt zurückgeben möchten, verwenden Sie das Datei-Plugin: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -In JavaScript, bekommen eine `cdvfile://` URL aus einem FileEntries oder DirectoryEntry-Objekt, rufen Sie einfach `.toURL()` drauf: - - var cdvfileURL = entry.toURL(); - - -Im Plugin Antwort Handler um aus einer zurückgegebenen FileEntries-Struktur in ein tatsächliches Entry-Objekt zu konvertieren sollte Handlercode importieren die Datei-Erweiterung und ein neues Objekt erstellen: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/es/README.md b/plugins/cordova-plugin-file/doc/es/README.md deleted file mode 100644 index 2a653bf5..00000000 --- a/plugins/cordova-plugin-file/doc/es/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -Este plugin implementa una API de archivo que permite acceso de lectura/escritura a los archivos que residen en el dispositivo. - -Este plugin se basa en varias especificaciones, incluyendo: el HTML5 archivo API <http://www.w3.org/TR/FileAPI/> - -Los directorios (ahora extinto) y sistema de extensiones más recientes: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> aunque la mayor parte del código del plugin fue escrito cuando una especificación anterior era actual: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -También implementa la especificación de FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Para el uso, por favor, consulte 'HTML5 Rocks excelente [FileSystem artículo.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -Para tener una visión general de otras opciones de almacenamiento, consulte [Guía de almacenamiento Cordova](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -Este plugin define global `cordova.file` objeto. - -Aunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Instalación - - cordova plugin add cordova-plugin-file - - -## Plataformas soportadas - - * Amazon fire OS - * Android - * BlackBerry 10 - * Firefox OS - * iOS - * Windows Phone 7 y 8 * - * Windows 8 * - * Windows* - * Explorador - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## Donde almacenar los archivos - -A partir de v1.2.0, URLs a directorios de sistema de archivos importantes son proporcionadas. Cada dirección URL está en la forma *file:///path/to/spot/*y se puede convertir en un `DirectoryEntry` usando`window.resolveLocalFileSystemURL()`. - - * `cordova.file.applicationDirectory`-Directorio Read-only donde está instalada la aplicación. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.applicationStorageDirectory`-Directorio del entorno limitado de la aplicación; en iOS esta ubicación es de sólo lectura (pero subdirectorios específicos [como `/Documents` ] son de lectura y escritura). Todos los datos contenidos dentro es privado para la aplicación. ( *iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.dataDirectory`-Almacenamiento de datos persistente y privadas dentro de entorno limitado de la aplicación utilizando la memoria interna (en Android, si necesitas usar memoria externa, use `.externalDataDirectory` ). En iOS, este directorio no está sincronizado con iCloud (utilice `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.cacheDirectory`-Directorio para los archivos de datos almacenados en caché o los archivos que su aplicación puede volver a crear fácilmente. El sistema operativo puede borrar estos archivos cuando el dispositivo se agota en almacenamiento de información, sin embargo, aplicaciones no deben confiar en el sistema operativo para eliminar los archivos de aquí. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.externalApplicationStorageDirectory`-Espacio aplicación de almacenamiento externo. (*Android*) - - * `cordova.file.externalDataDirectory`¿Dónde poner los archivos de datos específicos de la aplicación de almacenamiento externo. (*Android*) - - * `cordova.file.externalCacheDirectory`-Caché aplicación de almacenamiento externo. (*Android*) - - * `cordova.file.externalRootDirectory`-Raíz de almacenamiento externo (tarjeta SD). (*Android*, *BlackBerry 10*) - - * `cordova.file.tempDirectory`-Directorio temporal que puede borrar el sistema operativo en sí. No confíe en el sistema operativo para borrar este directorio; su aplicación siempre debe eliminar archivos según corresponda. (*iOS*) - - * `cordova.file.syncedDataDirectory`-Contiene los archivos de la aplicación específica que deben ser sincronizados (e.g. a iCloud). (*iOS*) - - * `cordova.file.documentsDirectory`-Archivos privados a la aplicación, pero que son significativos para otra aplicación (por ejemplo archivos de Office). (*iOS*) - - * `cordova.file.sharedDirectory`-Archivos disponibles globalmente para todas las aplicaciones (*BlackBerry 10*) - -## Diseños de sistema de archivo - -Aunque técnicamente un detalle de la implementación, puede ser muy útil saber cómo la `cordova.file.*` mapa de propiedades en trazados físicos en un dispositivo real. - -### iOS diseño de sistema de archivo - -| Ruta de dispositivo | `Cordova.file.*` | `iosExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | sincronización | privado | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:-------------:|:--------------:|:-------:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N / A | N / A | N / A | Sí | -| `appname.app/` | applicationDirectory | Bundle | r | N / A | N / A | N / A | Sí | -| `www/` | - | - | r | N / A | N / A | N / A | Sí | -| `Documents/` | documentsDirectory | documentos | r/w | Sí | No | Sí | Sí | -| `NoCloud/` | - | documentos-nosync | r/w | Sí | No | No | Sí | -| `Library` | - | Biblioteca | r/w | Sí | No | ¿Sí? | Sí | -| `NoCloud/` | dataDirectory | Biblioteca-nosync | r/w | Sí | No | No | Sí | -| `Cloud/` | syncedDataDirectory | - | r/w | Sí | No | Sí | Sí | -| `Caches/` | cacheDirectory | caché | r/w | Sí * | Yes**\* | No | Sí | -| `tmp/` | tempDirectory | - | r/w | No** | Yes**\* | No | Sí | - -\ * Archivos persisten a través de reinicios de aplicación y actualizaciones, pero este directorio puede ser despejó cuando el OS deseos. Su aplicación debe ser capaz de recrear cualquier contenido que puede ser eliminado. - -** Archivos puede persistir a través de la aplicación se reinicia, pero no confiar en este comportamiento. Los archivos no se garantizan que persisten a través de actualizaciones. Su aplicación debe eliminar los archivos de este directorio cuando es aplicable, como el sistema operativo no garantiza cuando (o incluso si) estos archivos se quitan. - -**\ * OS la puede borrar el contenido de este directorio siempre que se siente es necesario, pero no dependen de esto. Debe borrar este directorio según sea apropiado para su aplicación. - -### Disposición del sistema Android File - -| Ruta de dispositivo | `Cordova.file.*` | `AndroidExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | privado | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:-----:|:-------------:|:----------:|:-------:| -| `File:///android_asset/` | applicationDirectory | | r | N / A | N / A | Sí | -| `/Data/data/< id de aplicación > /` | applicationStorageDirectory | - | r/w | N / A | N / A | Sí | -| `cache` | cacheDirectory | caché | r/w | Sí | Sí \ * | Sí | -| `files` | dataDirectory | archivos | r/w | Sí | No | Sí | -| `Documents` | | documentos | r/w | Sí | No | Sí | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Sí | No | No | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Sí | No | No | -| `cache` | externalCacheDirectry | caché-externo | r/w | Sí | No** | No | -| `files` | externalDataDirectory | archivos externos | r/w | Sí | No | No | - -\ * El sistema operativo periódicamente puede borrar este directorio, pero no confiar en este comportamiento. Borrar el contenido de este directorio según sea apropiado para su aplicación. El contenido de este directorio debe un usuario purga la caché manualmente, se eliminan. - -** El sistema operativo no borrar este directorio automáticamente; usted es responsable de administrar el contenido usted mismo. Deberá el usuario purga la caché manualmente, se extraen los contenidos del directorio. - -**Nota**: Si no se puede montar de almacenamiento externo, el `cordova.file.external*` Propiedades`null`. - -### Disposición del sistema blackBerry 10 archivo - -| Ruta de dispositivo | `Cordova.file.*` | ¿r/w? | ¿persistente? | OS despeja | privado | -|:------------------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:----------:|:-------:| -| `File:///accounts/1000/AppData/ < id de aplicación > /` | applicationStorageDirectory | r | N / A | N / A | Sí | -| `app/native` | applicationDirectory | r | N / A | N / A | Sí | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | No | Sí | Sí | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Sí | No | Sí | -| `File:///accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Sí | No | No | -| `File:///accounts/1000/shared` | sharedDirectory | r/w | Sí | No | No | - -*Nota*: cuando se implementa la aplicación al trabajo de perímetro, todos los caminos son relativos a /accounts/1000-enterprise. - -## Rarezas Android - -### Ubicación de almacenamiento persistente Android - -Hay múltiples ubicaciones válidas para almacenar archivos persistentes en un dispositivo Android. Vea [esta página](http://developer.android.com/guide/topics/data/data-storage.html) para una extensa discusión de las distintas posibilidades. - -Las versiones anteriores del plugin elegiría la ubicación de los archivos temporales y persistentes en el arranque, basado en si el dispositivo afirmó que fue montado en la tarjeta SD (o partición de almacenamiento equivalente). Si fue montada en la tarjeta SD, o una partición de gran almacenamiento interno estaba disponible (como en dispositivos de Nexus,) y luego los archivos persistentes se almacenaría en la raíz de ese espacio. Esto significaba que todas las apps Cordova podían ver todos los archivos disponibles en la tarjeta. - -Si la tarjeta SD no estaba disponible, entonces versiones anteriores podría almacenar datos debajo de `/data/data/<packageId>` , que aísla las apps del otro, pero puede todavía causa datos para ser compartido entre los usuarios. - -Ahora es posible elegir si desea almacenar archivos en la ubicación de almacenamiento del archivo interno, o usando la lógica anterior, con una preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` : - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Sin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación. - -Si su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación para "Internal" significa que los usuarios existentes que actualización su aplicación pueden ser incapaces de acceder a sus archivos previamente almacenadas, dependiendo de su dispositivo. - -Si su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Internal` generalmente se recomienda el ajuste. - -### Operaciones recursivas lento para /android_asset - -Listado de directorios activos es realmente lento en Android. Usted puede acelerar hacia arriba, agregando `src/android/build-extras.gradle` a la raíz de tu proyecto android (también requiere de cordova-android@4.0.0 o mayor). - -## iOS rarezas - - * `cordova.file.applicationStorageDirectory`es de sólo lectura; intentar almacenar archivos en el directorio raíz fallará. Utilice uno de los `cordova.file.*` las propiedades definidas para iOS (sólo `applicationDirectory` y `applicationStorageDirectory` son de sólo lectura). - * `FileReader.readAsText(blob, encoding)` - * El `encoding` no se admite el parámetro, y codificación UTF-8 es siempre en efecto. - -### iOS ubicación de almacenamiento persistente - -Hay dos ubicaciones válidas para almacenar archivos persistentes en un dispositivo iOS: el directorio de documentos y el directorio de biblioteca. Las versiones anteriores del plugin sólo almacenan archivos persistentes en el directorio de documentos. Esto tenía el efecto secundario de todos los archivos de la aplicación haciendo visible en iTunes, que era a menudo involuntarios, especialmente para aplicaciones que manejan gran cantidad de archivos pequeños, en lugar de producir documentos completos para la exportación, que es la finalidad del directorio. - -Ahora es posible elegir si desea almacenar archivos en los documentos o directorio de bibliotecas, con preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` : - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Sin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación. - -Si su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación de `Library` significa que los usuarios existentes que actualización su aplicación sería incapaces de acceder a sus archivos previamente almacenadas. - -Si su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Library` generalmente se recomienda el ajuste. - -## Firefox OS rarezas - -La API de sistema de archivo de forma nativa no es compatible con Firefox OS y se implementa como una cuña en la parte superior indexedDB. - - * No falla cuando eliminar directorios no vacía - * No admite metadatos para directorios - * Los métodos `copyTo` y `moveTo` no son compatibles con directorios - -Se admiten las siguientes rutas de datos: * `applicationDirectory` -usa `xhr` para obtener los archivos locales que están envasados con la aplicación. * `dataDirectory` - Para archivos de datos específicos de aplicación persistente. * `cacheDirectory` -En caché archivos que deben sobrevivir se reinicia la aplicación (aplicaciones no deben confiar en el sistema operativo para eliminar archivos aquí). - -## Navegador rarezas - -### Rarezas y observaciones comunes - - * Cada navegador utiliza su propio sistema de ficheros un espacio aislado. IE y Firefox utilizan IndexedDB como base. Todos los navegadores utilizan diagonal como separador de directorio en un camino. - * Las entradas de directorio deben crearse sucesivamente. Por ejemplo, la llamada `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` se producirá un error si no existiera dir1. - * El plugin solicita permiso de usuario para usar almacenamiento persistente en el primer comienzo de la aplicación. - * Plugin soporta `cdvfile://localhost` (recursos locales) solamente. Es decir, no se admiten los recursos externos vía `cdvfile`. - * El plugin no sigue ["Archivo sistema API 8.3 nombrando restricciones"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). - * BLOB y archivo ' `close` la función no es compatible. - * `FileSaver` y `BlobBuilder` no son compatibles con este plugin y no tengo recibos. - * El plugin no es compatible con `requestAllFileSystems`. Esta función también está desaparecida en las especificaciones. - * No se quitarán las entradas de directorio Si utilizas `create: true` bandera de directorio existente. - * No se admiten archivos creados mediante el constructor. Debe utilizar método entry.file en su lugar. - * Cada navegador utiliza su propia forma de blob URL referencias. - * se admite la función `readAsDataURL`, pero el mediatype en cromo depende de la extensión de nombre de entrada, mediatype en IE siempre está vacío (que es lo mismo como `plain-text` según la especificación), el mediatype en Firefox siempre es `application/octet-stream`. Por ejemplo, si el contenido es `abcdefg` entonces Firefox devuelve `datos: aplicación / octet-stream; base64, YWJjZGVmZw ==`, es decir devuelve `datos:; base64, YWJjZGVmZw ==`, cromo devuelve `datos: < mediatype dependiendo de la extensión de nombre de la entrada >; base64, YWJjZGVmZw ==`. - * `toInternalURL` devuelve la ruta de la forma `file:///persistent/path/to/entry` (Firefox, IE). Cromo devuelve la ruta de acceso en el formulario `cdvfile://localhost/persistent/file`. - -### Rarezas de Chrome - - * Filesystem de Chrome no es inmediatamente después de evento ready dispositivo. Como solución temporal puede suscribirse al evento `filePluginIsReady`. Ejemplo: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -Puede utilizar la función `window.isFilePluginReadyRaised` para verificar si ya se provoca el evento. -window.requestFileSystem temporal y persistente filesystem cuotas no están limitadas en cromo. -Para aumentar el almacenamiento persistente en cromo necesitas llamar el método `window.initPersistentFileSystem`. Cuota de almacenamiento persistente es de 5 MB por defecto. -Chrome requiere `--permitir-archivo-acceso-de-archivos` ejecutar argumento al soporte API mediante protocolo `file:///`. -`Archivo` objeto no cambiará si utilizas bandera `{create:true}` cuando una `entrada` de existente. -eventos `cancelable` propiedad está establecida en true en cromo. Esto es contrario a la [Especificación](http://dev.w3.org/2009/dap/file-system/file-writer.html). -función de `toURL` en Chrome devuelve `filesystem:`-prefijo camino dependiendo de host de la aplicación. Por ejemplo, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -resultado de la función de `toURL` no contiene barra en caso de entrada en el directorio. Cromo resuelve directorios con urls slash-siguió correctamente sin embargo. -método `resolveLocalFileSystemURL` requiere la entrantes `url` que tienen prefijo `filesystem`. Por ejemplo, el parámetro de `url` para `resolveLocalFileSystemURL` debería estar en la forma `filesystem:file:///persistent/somefile.txt` en comparación con la forma `file:///persistent/somefile.txt` en Android. -Obsoleto `toNativeURL` función no es compatible y no tiene un trozo. -función de `setMetadata` no es indicada en las especificaciones y no admite. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de SYNTAX_ERR(code: 8) a petición de un sistema de ficheros inexistentes. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de PATH_EXISTS_ERR(code: 12) en intentar exclusivamente crear un archivo o directorio, que ya existe. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de NO_MODIFICATION_ALLOWED_ERR(code: 6) para tratar de llamar a removeRecursively en el sistema de archivos raíz. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de NOT_FOUND_ERR(code: 1) en tratar de moveTo directorio que no existe. - -### Impl base IndexedDB rarezas (IE y Firefox) - - * `.` y `..` no son compatibles. - * IE no soporta `file:///`-modo; modo alojado sólo es compatible (http://localhost:xxxx). - * Tamaño del sistema de archivos de Firefox no es limitada pero cada extensión de 50 MB solicitará un permiso de usuario. IE10 permite hasta 10mb de combinados AppCache y IndexedDB utilizados en la implementación del sistema de ficheros sin preguntar, cuando llegas a ese nivel que se le preguntará si desea permitir que ser aumentada hasta un máximo de 250 mb por sitio. Para que `size` parámetro para la función `requestFileSystem` no afecta sistema de ficheros en Firefox y IE. - * la función `readAsBinaryString` no se indica en las especificaciones y no compatible con IE y no tiene un trozo. - * `file.type` siempre es null. - * No debe crear entrada utilizando DirectoryEntry resultado de devolución de llamada de instancia que fue borrado. De lo contrario, obtendrá una entrada' colgar'. - * Antes de que se puede leer un archivo, el cual fue escrito sólo que necesitas una nueva instancia de este archivo. - * la función `setMetadata`, que no es indicada en las especificaciones soporta sólo el cambio de campo `modificationTime`. - * `copyTo` y `moveTo` funciones no son compatibles con directorios. - * Metadatos de directorios no es compatible. - * Tanto Entry.remove y directoryEntry.removeRecursively no fallan al retirar no vacía directorios - directorios de ser eliminados se limpian junto con contenido en su lugar. - * `abort` y `truncate` las funciones no son compatibles. - * eventos de progreso no están despedidos. Por ejemplo, este controlador no ejecutará: - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## Actualización de notas - -En v1.0.0 de este plugin, han cambiado las estructuras `FileEntry` y `DirectoryEntry`, para estar más acorde con las especificaciones publicadas. - -Versiones anteriores (pre-1.0.0) del plugin almacenan el dispositivo-absoluto-archivo-ubicación en la propiedad `fullPath` de objetos de `entrada`. Estos caminos típicamente parecería - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Estas rutas también fueron devueltos por el método `toURL()` de los objetos de `entrada`. - -Con v1.0.0, el atributo `fullPath` es la ruta del archivo, *relativo a la raíz del sistema de archivos HTML*. Así, los caminos más arriba sería ahora ambos ser representado por un objeto `FileEntry` con un `fullPath` de - - /path/to/file - - -Si su aplicación funciona con dispositivo-absoluto-caminos, y previamente obtenido esos caminos a través de la propiedad `fullPath` de objetos de `Entry`, deberá actualizar el código para utilizar `entry.toURL()` en su lugar. - -Para atrás compatibilidad, el método `resolveLocalFileSystemURL()` a aceptar un dispositivo-absoluto-trayectoria y devolverá un objeto de `Entry` correspondiente que, mientras exista ese archivo dentro de los sistemas de ficheros `TEMPORARY` o la `PERSISTENT`. - -Esto ha sido particularmente un problema con el plugin de transferencia de archivos, que anteriormente utilizado dispositivo-absoluto-caminos (y todavía puede aceptarlas). Ha sido actualizado para funcionar correctamente con sistema de ficheros URLs, para reemplazar `entry.fullPath` con `entry.toURL()` debe resolver cualquier problema conseguir ese plugin para trabajar con archivos en el dispositivo. - -En v1.1.0 el valor devuelto por `toURL()` fue cambiado (consulte \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) para devolver una dirección URL absoluta 'file://'. siempre que sea posible. Para asegurar una ' cdvfile:'-URL ahora puede utilizar `toInternalURL()`. Este método devolverá ahora filesystem URLs de la forma - - cdvfile://localhost/persistent/path/to/file - - -que puede utilizarse para identificar el archivo únicamente. - -## Lista de códigos de Error y significados - -Cuando se produce un error, uno de los siguientes códigos se utilizará. - -| Código | Constante | -| ------:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configurando el Plugin (opcional) - -El conjunto de los sistemas de ficheros disponibles puede ser configurado por plataforma. Tanto iOS y Android reconocen un <preference> etiqueta en el `archivo config.xml` que nombra a los sistemas de archivos para ser instalado. De forma predeterminada, se activan todas las raíces del sistema de archivos. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - - * `files`: directorio de almacenamiento de archivo interno de la aplicación - * `files-external`: directorio de almacenamiento de archivo externo de la aplicación - * `sdcard`: el directorio de almacenamiento de archivo externo global (esta es la raíz de la tarjeta SD, si uno está instalado). Debe tener el permiso de `android.permission.WRITE_EXTERNAL_STORAGE` a usar esto. - * `cache`: directorio de memoria caché interna de la aplicación - * `cache-external`: directorio de caché externo de la aplicación - * `root`: el sistema de archivos de todo el dispositivo - -Android también es compatible con un sistema de archivos especial llamado "documents", que representa un subdirectorio "/Documents/" dentro del sistema de archivos "archivos". - -### iOS - - * `library`: directorio de bibliotecas de la aplicación - * `documents`: directorio de documentos de la aplicación - * `cache`: directorio de caché de la aplicación - * `bundle`: paquete de la aplicación; la ubicación de la aplicación en sí mismo en el disco (sólo lectura) - * `root`: el sistema de archivos de todo el dispositivo - -De forma predeterminada, los directorios de documentos y la biblioteca pueden ser sincronizados con iCloud. También puede solicitar dos sistemas adicionales, `library-nosync` y `documents-nosync`, que representan un directorio especial no sincronizados dentro de la `/Library` o sistema de ficheros `/Documents`.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/es/index.md b/plugins/cordova-plugin-file/doc/es/index.md deleted file mode 100644 index a9c02643..00000000 --- a/plugins/cordova-plugin-file/doc/es/index.md +++ /dev/null @@ -1,336 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -Este plugin implementa una API de archivo que permite acceso de lectura/escritura a los archivos que residen en el dispositivo. - -Este plugin se basa en varias especificaciones, incluyendo: el HTML5 archivo API <http://www.w3.org/TR/FileAPI/> - -Los directorios (ahora extinto) y sistema de extensiones más recientes: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> aunque la mayor parte del código del plugin fue escrito cuando una especificación anterior era actual: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -También implementa la especificación de FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Para el uso, por favor, consulte 'HTML5 Rocks excelente [FileSystem artículo.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -Para tener una visión general de otras opciones de almacenamiento, consulte [Guía de almacenamiento Cordova][2]. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -Este plugin define global `cordova.file` objeto. - -Aunque en el ámbito global, no estará disponible hasta después de la `deviceready` evento. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Instalación - - cordova plugin add cordova-plugin-file - - -## Plataformas soportadas - -* Amazon fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows Phone 7 y 8 * -* Windows 8 * -* Explorador - -* *No son compatibles con estas plataformas `FileReader.readAsArrayBuffer` ni `FileWriter.write(blob)` .* - -## Donde almacenar los archivos - -A partir de v1.2.0, URLs a directorios de sistema de archivos importantes son proporcionadas. Cada dirección URL está en la forma *file:///path/to/spot/*y se puede convertir en un `DirectoryEntry` usando`window.resolveLocalFileSystemURL()`. - -* `cordova.file.applicationDirectory`-Directorio Read-only donde está instalada la aplicación. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.applicationStorageDirectory`-Directorio del entorno limitado de la aplicación; en iOS esta ubicación es de sólo lectura (pero subdirectorios específicos [como `/Documents` ] son de lectura y escritura). Todos los datos contenidos dentro es privado para la aplicación. ( *iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.dataDirectory`-Almacenamiento de datos persistente y privadas dentro de entorno limitado de la aplicación utilizando la memoria interna (en Android, si necesitas usar memoria externa, use `.externalDataDirectory` ). En iOS, este directorio no está sincronizado con iCloud (utilice `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.cacheDirectory`-Directorio para los archivos de datos almacenados en caché o los archivos que su aplicación puede volver a crear fácilmente. El sistema operativo puede borrar estos archivos cuando el dispositivo se agota en almacenamiento de información, sin embargo, aplicaciones no deben confiar en el sistema operativo para eliminar los archivos de aquí. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.externalApplicationStorageDirectory`-Espacio aplicación de almacenamiento externo. (*Android*) - -* `cordova.file.externalDataDirectory`¿Dónde poner los archivos de datos específicos de la aplicación de almacenamiento externo. (*Android*) - -* `cordova.file.externalCacheDirectory`-Caché aplicación de almacenamiento externo. (*Android*) - -* `cordova.file.externalRootDirectory`-Raíz de almacenamiento externo (tarjeta SD). (*Android*, *BlackBerry 10*) - -* `cordova.file.tempDirectory`-Directorio temporal que puede borrar el sistema operativo en sí. No confíe en el sistema operativo para borrar este directorio; su aplicación siempre debe eliminar archivos según corresponda. (*iOS*) - -* `cordova.file.syncedDataDirectory`-Contiene los archivos de la aplicación específica que deben ser sincronizados (e.g. a iCloud). (*iOS*) - -* `cordova.file.documentsDirectory`-Archivos privados a la aplicación, pero que son significativos para otra aplicación (por ejemplo archivos de Office). (*iOS*) - -* `cordova.file.sharedDirectory`-Archivos disponibles globalmente para todas las aplicaciones (*BlackBerry 10*) - -## Diseños de sistema de archivo - -Aunque técnicamente un detalle de la implementación, puede ser muy útil saber cómo la `cordova.file.*` mapa de propiedades en trazados físicos en un dispositivo real. - -### iOS diseño de sistema de archivo - -| Ruta de dispositivo | `Cordova.file.*` | `iosExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | sincronización | privado | -|:-------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:----------:|:--------------:|:-------:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N / A | N / A | N / A | Sí | -| `appname.app/` | applicationDirectory | Bundle | r | N / A | N / A | N / A | Sí | -| `www/` | - | - | r | N / A | N / A | N / A | Sí | -| `Documents/` | documentsDirectory | documentos | r/w | Sí | No | Sí | Sí | -| `NoCloud/` | - | documentos-nosync | r/w | Sí | No | No | Sí | -| `Library` | - | Biblioteca | r/w | Sí | No | ¿Sí? | Sí | -| `NoCloud/` | dataDirectory | Biblioteca-nosync | r/w | Sí | No | No | Sí | -| `Cloud/` | syncedDataDirectory | - | r/w | Sí | No | Sí | Sí | -| `Caches/` | cacheDirectory | caché | r/w | Sí * | Si * * *| | No | Sí | -| `tmp/` | tempDirectory | - | r/w | No * * | Si * * *| | No | Sí | - -* Archivos persisten a través de la aplicación se reinicia y actualizaciones, pero este directorio puede ser despejó cuando el OS desea. Su aplicación debe ser capaz de recrear cualquier contenido que puede ser eliminado. - -* * Archivos pueden persistir a través de la aplicación se reinicia, pero no confiar en este comportamiento. Los archivos no se garantizan que persisten a través de actualizaciones. Su aplicación debe eliminar los archivos de este directorio cuando es aplicable, como el sistema operativo no garantiza cuando (o incluso si) estos archivos se quitan. - -* * *| OS la puede borrar el contenido de este directorio cuando se siente que es necesario, pero no dependen de éste. Debe borrar este directorio según sea apropiado para su aplicación. - -### Disposición del sistema Android File - -| Ruta de dispositivo | `Cordova.file.*` | `AndroidExtraFileSystems` | ¿r/w? | ¿persistente? | OS despeja | privado | -|:----------------------------------------- |:----------------------------------- |:------------------------- |:-----:|:-------------:|:----------:|:-------:| -| `File:///android_asset/` | applicationDirectory | | r | N / A | N / A | Sí | -| `/Data/data/< id de aplicación > /` | applicationStorageDirectory | - | r/w | N / A | N / A | Sí | -| `cache` | cacheDirectory | caché | r/w | Sí | Sí * | Sí | -| `files` | dataDirectory | archivos | r/w | Sí | No | Sí | -| `Documents` | | documentos | r/w | Sí | No | Sí | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Sí | No | No | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Sí | No | No | -| `cache` | externalCacheDirectry | caché-externo | r/w | Sí | No * * | No | -| `files` | externalDataDirectory | archivos externos | r/w | Sí | No | No | - -* El sistema operativo puede eliminar periódicamente este directorio, pero no dependen de este comportamiento. Borrar el contenido de este directorio según sea apropiado para su aplicación. El contenido de este directorio debe un usuario purga la caché manualmente, se eliminan. - -* * El sistema operativo no borra este directorio automáticamente; Usted es responsable de administrar el contenido mismo. Deberá el usuario purga la caché manualmente, se extraen los contenidos del directorio. - -**Nota**: Si no se puede montar de almacenamiento externo, el `cordova.file.external*` Propiedades`null`. - -### Disposición del sistema blackBerry 10 archivo - -| Ruta de dispositivo | `Cordova.file.*` | ¿r/w? | ¿persistente? | OS despeja | privado | -|:------------------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:----------:|:-------:| -| `File:///accounts/1000/AppData/ < id de aplicación > /` | applicationStorageDirectory | r | N / A | N / A | Sí | -| `app/native` | applicationDirectory | r | N / A | N / A | Sí | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | No | Sí | Sí | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Sí | No | Sí | -| `File:///accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Sí | No | No | -| `File:///accounts/1000/shared` | sharedDirectory | r/w | Sí | No | No | - -*Nota*: cuando se implementa la aplicación al trabajo de perímetro, todos los caminos son relativos a /accounts/1000-enterprise. - -## Rarezas Android - -### Ubicación de almacenamiento persistente Android - -Hay múltiples ubicaciones válidas para almacenar archivos persistentes en un dispositivo Android. Vea [esta página][3] para una extensa discusión de las distintas posibilidades. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -Las versiones anteriores del plugin elegiría la ubicación de los archivos temporales y persistentes en el arranque, basado en si el dispositivo afirmó que fue montado en la tarjeta SD (o partición de almacenamiento equivalente). Si fue montada en la tarjeta SD, o una partición de gran almacenamiento interno estaba disponible (como en dispositivos de Nexus,) y luego los archivos persistentes se almacenaría en la raíz de ese espacio. Esto significaba que todas las apps Cordova podían ver todos los archivos disponibles en la tarjeta. - -Si la tarjeta SD no estaba disponible, entonces versiones anteriores podría almacenar datos debajo de `/data/data/<packageId>` , que aísla las apps del otro, pero puede todavía causa datos para ser compartido entre los usuarios. - -Ahora es posible elegir si desea almacenar archivos en la ubicación de almacenamiento del archivo interno, o usando la lógica anterior, con una preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` : - - < nombre de preferencia = "AndroidPersistentFileLocation" value = "Internal" / >< nombre de preferencia = "AndroidPersistentFileLocation" value = "Compatibilidad" / > - - -Sin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación. - -Si su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación para "Internal" significa que los usuarios existentes que actualización su aplicación pueden ser incapaces de acceder a sus archivos previamente almacenadas, dependiendo de su dispositivo. - -Si su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Internal` generalmente se recomienda el ajuste. - -## iOS rarezas - -* `cordova.file.applicationStorageDirectory`es de sólo lectura; intentar almacenar archivos en el directorio raíz fallará. Utilice uno de los `cordova.file.*` las propiedades definidas para iOS (sólo `applicationDirectory` y `applicationStorageDirectory` son de sólo lectura). -* `FileReader.readAsText(blob, encoding)` - * El `encoding` no se admite el parámetro, y codificación UTF-8 es siempre en efecto. - -### iOS ubicación de almacenamiento persistente - -Hay dos ubicaciones válidas para almacenar archivos persistentes en un dispositivo iOS: el directorio de documentos y el directorio de biblioteca. Las versiones anteriores del plugin sólo almacenan archivos persistentes en el directorio de documentos. Esto tenía el efecto secundario de todos los archivos de la aplicación haciendo visible en iTunes, que era a menudo involuntarios, especialmente para aplicaciones que manejan gran cantidad de archivos pequeños, en lugar de producir documentos completos para la exportación, que es la finalidad del directorio. - -Ahora es posible elegir si desea almacenar archivos en los documentos o directorio de bibliotecas, con preferencia en de la aplicación `config.xml` archivo. Para ello, añada una de estas dos líneas a `config.xml` : - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Sin esta línea, se utilizará el archivo plugin `Compatibility` como valor predeterminado. Si una etiqueta de preferencia está presente y no es uno de estos valores, no se iniciará la aplicación. - -Si su solicitud se ha enviado previamente a los usuarios, usando un mayor (1.0 pre) versión de este plugin y archivos almacenados en el sistema de ficheros persistente, entonces debería establecer la preferencia en `Compatibility` . Cambiar la ubicación de `Library` significa que los usuarios existentes que actualización su aplicación sería incapaces de acceder a sus archivos previamente almacenadas. - -Si su solicitud es nuevo, o nunca antes ha almacenado archivos en el sistema de ficheros persistente, entonces el `Library` generalmente se recomienda el ajuste. - -## Firefox OS rarezas - -La API de sistema de archivo de forma nativa no es compatible con Firefox OS y se implementa como una cuña en la parte superior indexedDB. - -* No falla cuando eliminar directorios no vacía -* No admite metadatos para directorios -* Los métodos `copyTo` y `moveTo` no son compatibles con directorios - -Se admiten las siguientes rutas de datos: * `applicationDirectory` -usa `xhr` para obtener los archivos locales que están envasados con la aplicación. * `dataDirectory` - Para archivos de datos específicos de aplicación persistente. * `cacheDirectory` -En caché archivos que deben sobrevivir se reinicia la aplicación (aplicaciones no deben confiar en el sistema operativo para eliminar archivos aquí). - -## Navegador rarezas - -### Rarezas y observaciones comunes - -* Cada navegador utiliza su propio sistema de ficheros un espacio aislado. IE y Firefox utilizan IndexedDB como base. Todos los navegadores utilizan diagonal como separador de directorio en un camino. -* Las entradas de directorio deben crearse sucesivamente. Por ejemplo, la llamada `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` se producirá un error si no existiera dir1. -* El plugin solicita permiso de usuario para usar almacenamiento persistente en el primer comienzo de la aplicación. -* Plugin soporta `cdvfile://localhost` (recursos locales) solamente. Es decir, no se admiten los recursos externos vía `cdvfile`. -* El plugin no sigue ["Archivo sistema API 8.3 nombrando restricciones"][4]. -* BLOB y archivo ' `close` la función no es compatible. -* `FileSaver` y `BlobBuilder` no son compatibles con este plugin y no tengo recibos. -* El plugin no es compatible con `requestAllFileSystems`. Esta función también está desaparecida en las especificaciones. -* No se quitarán las entradas de directorio Si utilizas `create: true` bandera de directorio existente. -* No se admiten archivos creados mediante el constructor. Debe utilizar método entry.file en su lugar. -* Cada navegador utiliza su propia forma de blob URL referencias. -* se admite la función `readAsDataURL`, pero el mediatype en cromo depende de la extensión de nombre de entrada, mediatype en IE siempre está vacío (que es lo mismo como `plain-text` según la especificación), el mediatype en Firefox siempre es `application/octet-stream`. Por ejemplo, si el contenido es `abcdefg` entonces Firefox devuelve `datos: aplicación / octet-stream; base64, YWJjZGVmZw ==`, es decir devuelve `datos:; base64, YWJjZGVmZw ==`, cromo devuelve `datos: < mediatype dependiendo de la extensión de nombre de la entrada >; base64, YWJjZGVmZw ==`. -* `toInternalURL` devuelve la ruta de la forma `file:///persistent/path/to/entry` (Firefox, IE). Cromo devuelve la ruta de acceso en el formulario `cdvfile://localhost/persistent/file`. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### Rarezas de Chrome - -* Filesystem de Chrome no es inmediatamente después de evento ready dispositivo. Como solución temporal puede suscribirse al evento `filePluginIsReady`. Ejemplo: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -Puede utilizar la función `window.isFilePluginReadyRaised` para verificar si ya se provoca el evento. -window.requestFileSystem temporal y persistente filesystem cuotas no están limitadas en cromo. -Para aumentar el almacenamiento persistente en cromo necesitas llamar el método `window.initPersistentFileSystem`. Cuota de almacenamiento persistente es de 5 MB por defecto. -Chrome requiere `--permitir-archivo-acceso-de-archivos` ejecutar argumento al soporte API mediante protocolo `file:///`. -`Archivo` objeto no cambiará si utilizas bandera `{create:true}` cuando una `entrada` de existente. -eventos `cancelable` propiedad está establecida en true en cromo. Esto es contrario a la [Especificación][5]. -función de `toURL` en Chrome devuelve `filesystem:`-prefijo camino dependiendo de host de la aplicación. Por ejemplo, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -resultado de la función de `toURL` no contiene barra en caso de entrada en el directorio. Cromo resuelve directorios con urls slash-siguió correctamente sin embargo. -método `resolveLocalFileSystemURL` requiere la entrantes `url` que tienen prefijo `filesystem`. Por ejemplo, el parámetro de `url` para `resolveLocalFileSystemURL` debería estar en la forma `filesystem:file:///persistent/somefile.txt` en comparación con la forma `file:///persistent/somefile.txt` en Android. -Obsoleto `toNativeURL` función no es compatible y no tiene un trozo. -función de `setMetadata` no es indicada en las especificaciones y no admite. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de SYNTAX_ERR(code: 8) a petición de un sistema de ficheros inexistentes. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de PATH_EXISTS_ERR(code: 12) en intentar exclusivamente crear un archivo o directorio, que ya existe. -INVALID_MODIFICATION_ERR (código: 9) se lanza en lugar de NO_MODIFICATION_ALLOWED_ERR(code: 6) para tratar de llamar a removeRecursively en el sistema de archivos raíz. -INVALID_MODIFICATION_ERR (código: 9) se lanza en vez de NOT_FOUND_ERR(code: 1) en tratar de moveTo directorio que no existe. - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### Impl base IndexedDB rarezas (IE y Firefox) - -* `.` y `..` no son compatibles. -* IE no soporta `file:///`-modo; modo alojado sólo es compatible (http://localhost:xxxx). -* Tamaño del sistema de archivos de Firefox no es limitada pero cada extensión de 50 MB solicitará un permiso de usuario. IE10 permite hasta 10mb de combinados AppCache y IndexedDB utilizados en la implementación del sistema de ficheros sin preguntar, cuando llegas a ese nivel que se le preguntará si desea permitir que ser aumentada hasta un máximo de 250 mb por sitio. Para que `size` parámetro para la función `requestFileSystem` no afecta sistema de ficheros en Firefox y IE. -* la función `readAsBinaryString` no se indica en las especificaciones y no compatible con IE y no tiene un trozo. -* `file.type` siempre es null. -* No debe crear entrada utilizando DirectoryEntry resultado de devolución de llamada de instancia que fue borrado. De lo contrario, obtendrá una entrada' colgar'. -* Antes de que se puede leer un archivo, el cual fue escrito sólo que necesitas una nueva instancia de este archivo. -* la función `setMetadata`, que no es indicada en las especificaciones soporta sólo el cambio de campo `modificationTime`. -* `copyTo` y `moveTo` funciones no son compatibles con directorios. -* Metadatos de directorios no es compatible. -* Tanto Entry.remove y directoryEntry.removeRecursively no fallan al retirar no vacía directorios - directorios de ser eliminados se limpian junto con contenido en su lugar. -* `abort` y `truncate` las funciones no son compatibles. -* eventos de progreso no están despedidos. Por ejemplo, este controlador no ejecutará: - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## Actualización de notas - -En v1.0.0 de este plugin, han cambiado las estructuras `FileEntry` y `DirectoryEntry`, para estar más acorde con las especificaciones publicadas. - -Versiones anteriores (pre-1.0.0) del plugin almacenan el dispositivo-absoluto-archivo-ubicación en la propiedad `fullPath` de objetos de `entrada`. Estos caminos típicamente parecería - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Estas rutas también fueron devueltos por el método `toURL()` de los objetos de `entrada`. - -Con v1.0.0, el atributo `fullPath` es la ruta del archivo, *relativo a la raíz del sistema de archivos HTML*. Así, los caminos más arriba sería ahora ambos ser representado por un objeto `FileEntry` con un `fullPath` de - - /path/to/file - - -Si su aplicación funciona con dispositivo-absoluto-caminos, y previamente obtenido esos caminos a través de la propiedad `fullPath` de objetos de `Entry`, deberá actualizar el código para utilizar `entry.toURL()` en su lugar. - -Para atrás compatibilidad, el método `resolveLocalFileSystemURL()` a aceptar un dispositivo-absoluto-trayectoria y devolverá un objeto de `Entry` correspondiente que, mientras exista ese archivo dentro de los sistemas de ficheros `TEMPORARY` o la `PERSISTENT`. - -Esto ha sido particularmente un problema con el plugin de transferencia de archivos, que anteriormente utilizado dispositivo-absoluto-caminos (y todavía puede aceptarlas). Ha sido actualizado para funcionar correctamente con sistema de ficheros URLs, para reemplazar `entry.fullPath` con `entry.toURL()` debe resolver cualquier problema conseguir ese plugin para trabajar con archivos en el dispositivo. - -En v1.1.0 el valor devuelto por `toURL()` fue cambiado (consulte \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) para devolver una dirección URL absoluta 'file://'. siempre que sea posible. Para asegurar una ' cdvfile:'-URL ahora puede utilizar `toInternalURL()`. Este método devolverá ahora filesystem URLs de la forma - - cdvfile://localhost/persistent/path/to/file - - -que puede utilizarse para identificar el archivo únicamente. - -## Lista de códigos de Error y significados - -Cuando se produce un error, uno de los siguientes códigos se utilizará. - -| Código | Constante | -| ------:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configurando el Plugin (opcional) - -El conjunto de los sistemas de ficheros disponibles puede ser configurado por plataforma. Tanto iOS y Android reconocen un <preference> etiqueta en el `archivo config.xml` que nombra a los sistemas de archivos para ser instalado. De forma predeterminada, se activan todas las raíces del sistema de archivos. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - -* `files`: directorio de almacenamiento de archivo interno de la aplicación -* `files-external`: directorio de almacenamiento de archivo externo de la aplicación -* `sdcard`: el directorio de almacenamiento de archivo externo global (esta es la raíz de la tarjeta SD, si uno está instalado). Debe tener el permiso de `android.permission.WRITE_EXTERNAL_STORAGE` a usar esto. -* `cache`: directorio de memoria caché interna de la aplicación -* `cache-external`: directorio de caché externo de la aplicación -* `root`: el sistema de archivos de todo el dispositivo - -Android también es compatible con un sistema de archivos especial llamado "documents", que representa un subdirectorio "/Documents/" dentro del sistema de archivos "archivos". - -### iOS - -* `library`: directorio de bibliotecas de la aplicación -* `documents`: directorio de documentos de la aplicación -* `cache`: directorio de caché de la aplicación -* `bundle`: paquete de la aplicación; la ubicación de la aplicación en sí mismo en el disco (sólo lectura) -* `root`: el sistema de archivos de todo el dispositivo - -De forma predeterminada, los directorios de documentos y la biblioteca pueden ser sincronizados con iCloud. También puede solicitar dos sistemas adicionales, `library-nosync` y `documents-nosync`, que representan un directorio especial no sincronizados dentro de la `/Library` o sistema de ficheros `/Documents`. diff --git a/plugins/cordova-plugin-file/doc/es/plugins.md b/plugins/cordova-plugin-file/doc/es/plugins.md deleted file mode 100644 index fd126fca..00000000 --- a/plugins/cordova-plugin-file/doc/es/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# Notas para los desarrolladores de plugin - -Estas notas están pensadas principalmente para los desarrolladores de Android y el iOS que quieran escribir plugins que interfaz con el sistema de archivos usando el plugin de archivo. - -## Trabajando con Cordova archivo sistema URLs - -Desde la versión 1.0.0, este plugin utiliza las direcciones URL con un `cdvfile` plan para todas las comunicaciones sobre el puente, en lugar de exponer rutas de sistema de archivo de dispositivo raw a JavaScript. - -En el lado de JavaScript, esto significa que los objetos FileEntry y DirectoryEntry tienen un atributo fullPath que es relativo a la raíz del sistema de archivos HTML. Si JavaScript API del plugin acepta un objeto FileEntry o DirectoryEntry, debe llamar a `.toURL()` en ese objeto antes de pasarla a través del puente a código nativo. - -### Conversión de cdvfile: / / URL al fileystem caminos - -Plugins que necesita escribir en el sistema de archivos puede querer convertir un archivo recibido sistema URL a una ubicación de archivos reales. Hay varias formas de hacer esto, dependiendo de la plataforma nativa. - -Es importante recordar que no todos `cdvfile://` URLs son asignables a los archivos reales en el dispositivo. Algunas URLs pueden referirse a activos en dispositivos que no están representados por los archivos, o incluso pueden referirse a recursos remotos. Debido a estas posibilidades, plugins siempre debe probar si consiguen un resultado significativo cuando tratando de convertir URLs en trazados. - -#### Android - -En Android, el método más sencillo para convertir un `cdvfile://` URL a una ruta de sistema de archivos es utilizar `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`tiene varios métodos que pueden manejar `cdvfile://` URLs: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -También es posible utilizar directamente el archivo plugin: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -Para convertir de un camino hacia un `cdvfile://` URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -Si tu plugin crea un archivo y desea devolver un objeto FileEntry para ello, utilice el archivo plugin: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -Cordova en iOS no utiliza el mismo `CordovaResourceApi` concepto como Android. En iOS, utilice el archivo plugin para convertir las direcciones URL y rutas de archivos. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -Si tu plugin crea un archivo y desea devolver un objeto FileEntry para ello, utilice el archivo plugin: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -En JavaScript, para conseguir un `cdvfile://` URL de un objeto FileEntry o DirectoryEntry, simplemente llame a `.toURL()` en él: - - var cdvfileURL = entry.toURL(); - - -En plugin manipuladores de respuesta, para convertir de una estructura FileEntry devuelta a un objeto real de la entrada, el código del controlador debe importar el archivo plugin y crear un nuevo objeto: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/fr/README.md b/plugins/cordova-plugin-file/doc/fr/README.md deleted file mode 100644 index 6296a842..00000000 --- a/plugins/cordova-plugin-file/doc/fr/README.md +++ /dev/null @@ -1,328 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -Ce plugin implémente une API de fichier permettant l'accès en lecture/écriture aux fichiers qui résident sur le périphérique. - -Ce plugin est basé sur plusieurs spécifications, y compris : l'API de fichier HTML5 <http://www.w3.org/TR/FileAPI/> - -Les répertoires (aujourd'hui disparue) et le système des extensions plus récentes : <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> bien que la plupart du code du plugin a été écrit quand une technique antérieure était en vigueur : <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Il met également en œuvre la spécification FileWriter : <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Pour son utilisation, veuillez vous reporter au HTML5 Rocks' excellent [article de système de fichiers.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -Pour un aperçu des autres options de stockage, consultez [guide d'entreposage de Cordova](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -Ce plugin définit global `cordova.file` objet. - -Bien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement. - - document.addEventListener (« deviceready », onDeviceReady, false) ; - function onDeviceReady() {console.log(cordova.file);} - - -## Installation - - cordova plugin add cordova-plugin-file - - -## Plates-formes supportées - - * Amazon Fire OS - * Android - * BlackBerry 10 - * Firefox OS - * iOS - * Windows Phone 7 et 8 * - * Windows 8 * - * Windows* - * Navigateur - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## Emplacement de stockage des fichiers - -À partir de v1.2.0, URL vers des répertoires de système de fichiers importants est fournis. Chaque URL est dans la forme *file:///path/to/spot/*et peut être converti en un `DirectoryEntry` à l'aide`window.resolveLocalFileSystemURL()`. - - * `cordova.file.applicationDirectory`-Lecture seule répertoire où l'application est installée. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.applicationStorageDirectory`-Répertoire racine du bac à sable de l'application ; cet endroit est en lecture seule sur iOS (mais les sous-répertoires spécifiques [comme `/Documents` ] sont en lecture / écriture). Toutes les données qu'il contient est privé de l'application. ( *iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.dataDirectory`-Stockage des données persistants et privés au sein de bac à sable de l'application à l'aide de la mémoire interne (sur Android, si vous avez besoin d'utiliser une mémoire externe, utilisez `.externalDataDirectory` ). Sur iOS, ce répertoire n'est pas synchronisé avec iCloud (utiliser `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.cacheDirectory`-Répertoire pour les fichiers de données en mémoire cache ou les fichiers que votre application peut recréer facilement. L'OS peut supprimer ces fichiers lorsque l'appareil faiblit sur stockage, néanmoins, les applications ne doivent pas compter sur l'OS pour supprimer les fichiers ici. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.externalApplicationStorageDirectory`-Espace l'application sur le stockage externe. (*Android*) - - * `cordova.file.externalDataDirectory`-Où placer les fichiers de données d'application spécifiques sur le stockage externe. (*Android*) - - * `cordova.file.externalCacheDirectory`-Cache de l'application sur le stockage externe. (*Android*) - - * `cordova.file.externalRootDirectory`-Racine de stockage externe (carte SD). (*Android*, *BlackBerry 10*) - - * `cordova.file.tempDirectory`-Répertoire temp que l'OS peut effacer à volonté. Ne comptez pas sur l'OS pour effacer ce répertoire ; votre application doit toujours supprimer les fichiers selon le cas. (*iOS*) - - * `cordova.file.syncedDataDirectory`-Contient des fichiers d'app spécifique qui doivent se synchroniser (par exemple à iCloud). (*iOS*) - - * `cordova.file.documentsDirectory`-Fichiers privés à l'app, mais qui sont significatives pour l'autre application (par exemple les fichiers Office). (*iOS*) - - * `cordova.file.sharedDirectory`-Fichiers disponibles globalement à toutes les applications (*BlackBerry 10*) - -## Structures de système de fichiers - -Bien que techniquement un détail d'implémentation, il peut être très utile de savoir comment les `cordova.file.*` carte de propriétés à des chemins d'accès physiques sur un périphérique réel. - -### iOS agencement de système de fichier - -| Chemin de l'unité | `Cordova.file.*` | `iosExtraFileSystems` | r/w ? | persistants ? | OS efface | Sync | privé | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:-------------:|:-----:|:-----:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Oui | -| `appname.app/` | applicationDirectory | Bundle | r | N/A | N/A | N/A | Oui | -| `www/` | - | - | r | N/A | N/A | N/A | Oui | -| `Documents/` | documentsDirectory | documents | r/w | Oui | Non | Oui | Oui | -| `NoCloud/` | - | documents-nosync | r/w | Oui | Non | Non | Oui | -| `Library` | - | Bibliothèque | r/w | Oui | Non | Oui ? | Oui | -| `NoCloud/` | dataDirectory | Bibliothèque-nosync | r/w | Oui | Non | Non | Oui | -| `Cloud/` | syncedDataDirectory | - | r/w | Oui | Non | Oui | Oui | -| `Caches/` | cacheDirectory | cache | r/w | Oui * | Oui**\* | Non | Oui | -| `tmp/` | tempDirectory | - | r/w | Non** | Oui**\* | Non | Oui | - -\ * Fichiers persistent à travers l'application redémarre et mises à niveau, mais ce répertoire peut être effacé à chaque fois que le système d'exploitation désire. Votre application doit être en mesure de recréer tout contenu qui pourrait être supprimé. - -** Fichiers peuvent persister redémarrages de l'application, mais ne vous fiez pas ce comportement. Les fichiers ne sont pas garantis à persister dans l'ensemble de mises à jour. Votre application doit supprimer les fichiers de ce répertoire lorsqu'elle s'applique, comme le système d'exploitation ne garantit pas quand (ou même si) ces fichiers sont supprimés. - -**\ * Le système d'exploitation peut effacer le contenu de ce répertoire chaque fois qu'il se sent il est nécessaire, mais ne comptez pas là-dessus. Vous devez supprimer ce répertoire comme approprié pour votre application. - -### Agencement de système de fichiers Android - -| Chemin de l'unité | `Cordova.file.*` | `AndroidExtraFileSystems` | r/w ? | persistants ? | OS efface | privé | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:-----:|:-------------:|:---------:|:-----:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | Oui | -| `/ données/data/app < id > /` | applicationStorageDirectory | - | r/w | N/A | N/A | Oui | -| `cache` | cacheDirectory | cache | r/w | Oui | Oui\ * | Oui | -| `files` | dataDirectory | fichiers | r/w | Oui | Non | Oui | -| `Documents` | | documents | r/w | Oui | Non | Oui | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Oui | Non | Non | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Oui | Non | Non | -| `cache` | externalCacheDirectry | cache-externe | r/w | Oui | Non** | Non | -| `files` | externalDataDirectory | fichiers externes | r/w | Oui | Non | Non | - -\ * L'OS peut effacer périodiquement ce répertoire, mais ne vous fiez pas ce comportement. Effacer le contenu de ce répertoire comme approprié pour votre application. Un utilisateur doit purger le cache manuellement, le contenu de ce répertoire est supprimé. - -** Le système d'exploitation n'efface pas ce répertoire automatiquement ; vous êtes chargé de gérer le contenu vous-même. L'utilisateur devrait purger le cache manuellement, le contenu du répertoire est supprimé. - -**Remarque**: si le stockage externe ne peut pas être monté, les `cordova.file.external*` sont des propriétés`null`. - -### Configuration du système blackBerry 10 fichier - -| Chemin de l'unité | `Cordova.file.*` | r/w ? | persistants ? | OS efface | privé | -|:----------------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:---------:|:-----:| -| `file:///Accounts/1000/AppData/ < id app > /` | applicationStorageDirectory | r | N/A | N/A | Oui | -| `app/native` | applicationDirectory | r | N/A | N/A | Oui | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | Non | Oui | Oui | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Oui | Non | Oui | -| `file:///Accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Oui | Non | Non | -| `file:///Accounts/1000/Shared` | sharedDirectory | r/w | Oui | Non | Non | - -*Remarque*: lorsque l'application est déployée dans le périmètre de travail, tous les chemins sont par rapport à /accounts/1000-enterprise. - -## Quirks Android - -### Emplacement de stockage persistant Android - -Il y a plusieurs emplacements valides pour stocker des fichiers persistants sur un appareil Android. Voir [cette page](http://developer.android.com/guide/topics/data/data-storage.html) pour une analyse approfondie des diverses possibilités. - -Les versions précédentes du plugin choisirait l'emplacement des fichiers temporaires et persistantes au démarrage, basé sur la question de savoir si le dispositif réclamé que la carte SD (ou une partition de stockage équivalent) a été montée. Si la carte SD a été montée, ou si une partition de stockage interne importante était disponible (comme sur les appareils Nexus,) puis les fichiers persistants seraient stockés dans la racine de cet espace. Cela signifie que toutes les apps de Cordova pouvaient voir tous les fichiers disponibles sur la carte. - -Si la carte SD n'était pas disponible, les versions précédentes pourraient stocker des données sous `/data/data/<packageId>` , qui isole des apps de l'autre, mais peut encore cause données à partager entre les utilisateurs. - -Il est maintenant possible de choisir de stocker les fichiers dans l'emplacement de stockage de fichier interne, ou en utilisant la logique précédente, avec une préférence au sein de votre application `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` : - - < nom de l'option = « AndroidPersistentFileLocation » value = « Internal » / >< nom de préférence = « AndroidPersistentFileLocation » value = « Compatibilité » / > - - -Sans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas. - -Si votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Commutation de l'emplacement « Internal » signifierait que les utilisateurs existants qui mettre à niveau leur application peuvent être impossible d'accéder à leurs fichiers déjà enregistrés, selon leur appareil. - -Si votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Internal` réglage est généralement recommandé. - -### Opérations récursives lent pour /android_asset - -Liste des répertoires actifs est vraiment lent sur Android. Vous pouvez accélérer il vers le haut, en ajoutant `src/android/build-extras.gradle` à la racine de votre projet android (requiert également cordova-android@4.0.0 ou supérieur). - -## Notes au sujet d'iOS - - * `cordova.file.applicationStorageDirectory`est en lecture seule ; tentative de stocker des fichiers dans le répertoire racine échoue. Utilisez l'une de l'autre `cordova.file.*` les propriétés définies pour iOS (seulement `applicationDirectory` et `applicationStorageDirectory` sont en lecture seule). - * `FileReader.readAsText(blob, encoding)` - * Le `encoding` paramètre n'est pas pris en charge, et le codage UTF-8 est toujours en vigueur. - -### emplacement de stockage persistant d'iOS - -Il y a deux emplacements valides pour stocker des fichiers persistants sur un appareil iOS : le répertoire de Documents et le répertoire de la bibliothèque. Les versions précédentes du plugin stockaient ne jamais fichiers persistants dans le répertoire de Documents. Cela a eu l'effet secondaire de rendre tous les fichiers de l'application visible dans iTunes, qui était souvent inattendus, en particulier pour les applications qui traitent beaucoup de petits fichiers, plutôt que de produire des documents complets destinés à l'exportation, qui est l'objectif visé par le répertoire. - -Il est maintenant possible de choisir de stocker les fichiers dans le répertoire de bibliothèque, avec une préférence au sein de votre application ou de documents `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` : - - < nom de l'option = « iosPersistentFileLocation » value = « Library » / >< nom de préférence = « iosPersistentFileLocation » value = « Compatibilité » / > - - -Sans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas. - -Si votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Changer l'emplacement de `Library` voudrait dire que les utilisateurs existants qui mettre à niveau leur application serait incapables d'accéder à leurs fichiers déjà enregistrés. - -Si votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Library` réglage est généralement recommandé. - -## Firefox OS Quirks - -L'API de système de fichier n'est pas nativement pris en charge par Firefox OS et est implémentée comme une cale d'épaisseur sur le dessus d'indexedDB. - - * Ne manque pas lors de la suppression des répertoires non vide - * Ne supporte pas les métadonnées pour les répertoires - * Méthodes `copyTo` et `moveTo` ne prennent pas en charge les répertoires - -Les chemins de données suivants sont pris en charge: * `applicationDirectory` -utilise `xhr` pour obtenir des fichiers les qui sont emballées avec l'app. * `dataDirectory` - Pour les fichiers de données persistantes de app spécifique. * `cacheDirectory` -Mise en cache de fichiers qui doivent survivre les redémarrages de l'application (les applications ne doivent pas compter sur le système d'exploitation pour supprimer les fichiers ici). - -## Bizarreries navigateur - -### Commune de bizarreries et de remarques - - * Chaque navigateur utilise son propre système de fichiers en bac à sable. IE et Firefox utilisent IndexedDB comme base. Tous les navigateurs utilisent oblique comme séparateur de répertoire dans un chemin d'accès. - * Entrées d'annuaire doivent être créées successivement. Par exemple, l'appel `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` échouera si dir1 n'existait pas. - * Le plugin demande utilisateur l'autorisation d'utiliser le stockage persistant lors du premier démarrage d'application. - * Plugin supporte `cdvfile://localhost` (ressources locales) seulement. C'est-à-dire les ressources externes ne sont pas supportés par l'intermédiaire de `cdvfile`. - * Le plugin ne suit pas les ["Restrictions de nommage des fichiers système API 8.3"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). - * BLOB et le fichier "`close` la fonction n'est pas pris en charge. - * `FileSaver` et `BlobBuilder` ne sont pas pris en charge par ce plugin et n'ont stubs. - * Le plugin ne supporte pas les `requestAllFileSystems`. Cette fonction est également absent dans les cahier des charges. - * Inscriptions dans l'annuaire ne seront pas supprimées si vous utilisez `create: true` drapeau pour le répertoire existant. - * Fichiers créés via le constructeur ne sont pas pris en charge. Vous devez plutôt utiliser entry.file méthode. - * Chaque navigateur utilise sa propre forme de références URL blob. - * `readAsDataURL` fonction est prise en charge, mais le mediatype en Chrome dépend de l'extension entrée, mediatype dans IE est toujours vide (qui est le même que le `texte-plaine` selon la spécification), le mediatype dans Firefox est toujours `application/octet-stream`. Par exemple, si le contenu est `abcdefg` puis Firefox renvoie `données : application / octet-stream ; base64, YWJjZGVmZw ==`, c'est à dire les retours `données:; base64, YWJjZGVmZw ==`, retours de Chrome `données : < mediatype selon l'extension de nom d'entrée > ; base64, YWJjZGVmZw ==`. - * `toInternalURL` retourne le chemin d'accès dans le formulaire `file:///persistent/path/to/entry` (Firefox, IE). Chrome retourne le chemin d'accès dans le formulaire `cdvfile://localhost/persistent/file`. - -### Bizarreries de chrome - - * Chrome filesystem n'est pas prête immédiatement après l'événement ready périphérique. Pour contourner le problème, vous pouvez vous abonner à l'événement `filePluginIsReady`. Exemple : - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -Vous pouvez utiliser la fonction `window.isFilePluginReadyRaised` pour vérifier si les événement était déjà déclenché. -quotas de window.requestFileSystem temporaire et permanent de système de fichiers ne sont pas limités en Chrome. -Pour augmenter le stockage persistant en Chrome, vous devez appeler la méthode `window.initPersistentFileSystem`. Quota de stockage persistant est 5 Mo par défaut. -Chrome nécessite `--permettre-fichier-accès-de-fichiers` exécuter l'argument au support API via le protocole `file:///`. -`Fichier` objet changera pas si vous utilisez le drapeau `{create:true}` lors du passage d'une `entrée` existante. -événements `annulables` propriété a la valeur true dans Chrome. Il s'agit à l'encontre de la [spécification](http://dev.w3.org/2009/dap/file-system/file-writer.html). -`toURL` renvoie à Chrome `système de fichiers :`-préfixe de chemin d'accès selon l'application hôte. Par exemple, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -résultat de la fonction `toURL` ne contient-elle pas de barre oblique dans le cas d'entrée d'annuaire. Chrome résout répertoires avec barre oblique-trainés URL correctement cependant. -`resolveLocalFileSystemURL` méthode nécessite l' entrant `url` préfixe de `système de fichiers`. Par exemple, le paramètre `d'url` pour `resolveLocalFileSystemURL` devrait être dans la forme `filesystem:file:///persistent/somefile.txt` par opposition à la forme `file:///persistent/somefile.txt` dans Android. -Déconseillée `toNativeURL` fonction n'est pas prise en charge et n'est pas une ébauche. -fonction de `setMetadata` n'est pas stipulée dans le devis et pas pris en charge. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de SYNTAX_ERR(code: 8) sur la demande d'un système de fichier inexistant. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de PATH_EXISTS_ERR(code: 12) à essayer de créer exclusivement un fichier ou un répertoire, qui existe déjà. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NO_MODIFICATION_ALLOWED_ERR(code: 6) à essayer d'appeler removeRecursively sur le système de fichiers racine. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NOT_FOUND_ERR(code: 1) en essayant de moveTo répertoire qui n'existe pas. - -### Base IndexedDB impl bizarreries (Firefox et IE) - - * `.` et `.` ne sont pas pris en charge. - * IE ne prend pas en charge les `file:///`-mode ; seul le mode hébergé est pris en charge (http://localhost:xxxx). - * Taille de système de fichiers de Firefox n'est pas limité, mais chaque extension de 50Mo demandera une autorisation de l'utilisateur. IE10 permet jusqu'à 10 Mo de combiné AppCache et IndexedDB utilisés dans la mise en œuvre du système de fichiers sans demander de confirmation, une fois que vous atteignez ce niveau, Qu'on vous demandera si vous souhaitez lui permettre d'être augmentée jusqu'à un maximum de 250 Mo par site. Si le paramètre de `taille` pour la fonction `requestFileSystem` n'affecte pas le système de fichiers dans Firefox et IE. - * fonction de `readAsBinaryString` n'est pas indiquée dans les spécifications et pas pris en charge dans Internet Explorer et n'a pas une ébauche. - * `file.type` est toujours null. - * Vous ne devez pas créer en utilisant le résultat du callback instance DirectoryEntry qui avait été supprimée. Sinon, vous obtiendrez une « entrée de pendaison ». - * Avant que vous pouvez lire un fichier qui a été écrit juste que vous devez obtenir une nouvelle instance de ce fichier. - * `setMetadata` fonction, qui n'est pas indiquée dans les spécifications supporte `modificationTime` changement de champ seulement. - * fonctions `copyTo` et `moveTo` ne supportent pas les répertoires. - * Répertoires métadonnées ne sont pas pris en charge. - * Les deux Entry.remove et directoryEntry.removeRecursively ne manquent pas lors de la suppression des répertoires non-vides - répertoires retirés sont nettoyés avec contenu au lieu de cela. - * fonctions `abort` et `truncate` ne sont pas supportées. - * événements de progression ne sont pas déclenchés. Par exemple, ce gestionnaire ne sera pas exécuté : - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## Notes de mise à niveau - -V1.0.0 de ce plugin, les structures `FileEntry` et `DirectoryEntry` ont changé, pour être plus conforme à la spécification publiée. - -Les versions précédentes de (pré-1.0.0) du plugin stockaient le dispositif-absolu--emplacement du fichier dans la propriété `fullPath` d'objets `d'entrée`. Ces chemins seraient présente généralement comme - - / var/mobile/Applications/< application UUID >/Documents/chemin/vers/fichier (iOS), /storage/emulated/0/path/to/file (Android) - - -Ces chemins ont été également retournés par la méthode de `toURL()` les objets `d'entrée`. - -Avec v1.0.0, l'attribut `fullPath` est le chemin d'accès au fichier, *par rapport à la racine du système de fichiers HTML*. Ainsi, les chemins d'accès ci-dessus seraient maintenant tous les deux être représentée par un objet `FileEntry` avec un `fullPath` de - - /path/to/file - - -Si votre application fonctionne avec le dispositif-absolu-chemins et que vous avez récupéré précédemment ces chemins d'accès par le biais de la propriété `fullPath` d'objets `d'entrée`, puis vous devez mettre à jour votre code afin d'utiliser `entry.toURL()` à la place. - -Pour vers l'arrière la compatibilité, la méthode `resolveLocalFileSystemURL()` sera un chemin absolu de l'unité et retourne un objet `Entry` correspondant à elle, tant que ce fichier existe au sein des systèmes de fichiers les `TEMPORARY` ou `PERSISTENT`. - -Cela a été particulièrement un problème avec le plugin de transfert de fichiers, qui autrefois périphérique-absolu-chemins (et peut encore accepter). Il a été mis à jour pour fonctionner correctement avec le système de fichiers URL, afin de remplacer `entry.fullPath` par `entry.toURL()` devrait résoudre tout problème obtenir ce plugin pour travailler avec des fichiers sur le périphérique. - -Dans v1.1.0 la valeur de retour de `toURL()` a été changée (voir \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) pour renvoyer une URL absolue "file://". dans la mesure du possible. Pour assurer un ' cdvfile:'-URL, vous pouvez utiliser `toInternalURL()` maintenant. Cette méthode retourne maintenant filesystem URL du formulaire - - cdvfile://localhost/persistent/path/to/file - - -qui peut servir à identifier de manière unique le fichier. - -## Liste des Codes d'erreur et leur signification - -Lorsqu'une erreur est levée, l'un des codes suivants sera utilisé. - -| Code | Constant | -| ----:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configuration du Plugin (facultatif) - -L'ensemble des systèmes de fichiers disponibles peut être configurée par plate-forme. Les iOS et Android reconnaissent une <preference> balise dans le `fichier config.xml` qui nomme les systèmes de fichiers à installer. Par défaut, toutes les racines du système de fichiers sont activées. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - - * `files` : répertoire de stockage de fichier interne de l'application - * `files-external` : répertoire de l'application de stockage de fichier externe - * `sdcard` : le répertoire de stockage global fichier externe (c'est la racine de la carte SD, s'il est installé). Vous devez avoir la permission de `android.permission.WRITE_EXTERNAL_STORAGE` de l'utiliser. - * `cache` : répertoire de cache interne de l'application - * `cache-external` : répertoire de cache externe de l'application - * `root` : le système de fichiers de tout dispositif - -Android prend également en charge un système de fichiers spécial nommé « documents », qui représente un sous-répertoire « / Documents / » dans le système de fichiers « files ». - -### iOS - - * `library` : répertoire de bibliothèque de l'application - * `documents` : répertoire de Documents de l'application - * `cache` : répertoire de Cache de l'application - * `bundle` : bundle de l'application ; l'emplacement de l'application elle-même sur disque (lecture seule) - * `root` : le système de fichiers de tout dispositif - -Par défaut, vous peuvent synchroniser les répertoires de la bibliothèque et les documents à iCloud. Vous pouvez également demander des deux systèmes de fichiers supplémentaires, `library-nosync` et `documents-nosync`, qui représentent un répertoire spécial non synchronisées dans le `/Library` ou système de fichiers `/ Documents`.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/fr/index.md b/plugins/cordova-plugin-file/doc/fr/index.md deleted file mode 100644 index 72355228..00000000 --- a/plugins/cordova-plugin-file/doc/fr/index.md +++ /dev/null @@ -1,331 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -Ce plugin implémente une API de fichier permettant l'accès en lecture/écriture aux fichiers qui résident sur le périphérique. - -Ce plugin est basé sur plusieurs spécifications, y compris : l'API de fichier HTML5 <http://www.w3.org/TR/FileAPI/> - -Les répertoires (aujourd'hui disparue) et le système des extensions plus récentes : <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> bien que la plupart du code du plugin a été écrit quand une technique antérieure était en vigueur : <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Il met également en œuvre la spécification FileWriter : <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Pour son utilisation, veuillez vous reporter au HTML5 Rocks' excellent [article de système de fichiers.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -Pour un aperçu des autres options de stockage, consultez [guide d'entreposage de Cordova][2]. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -Ce plugin définit global `cordova.file` objet. - -Bien que dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement. - - document.addEventListener (« deviceready », onDeviceReady, false) ; - function onDeviceReady() {console.log(cordova.file);} - - -## Installation - - Cordova plugin ajouter cordova-plugin-file - - -## Plates-formes prises en charge - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows Phone 7 et 8 * -* Windows 8 * -* Navigateur - -* *Ces plates-formes ne supportent pas `FileReader.readAsArrayBuffer` ni `FileWriter.write(blob)` .* - -## Emplacement de stockage des fichiers - -À partir de v1.2.0, URL vers des répertoires de système de fichiers importants est fournis. Chaque URL est dans la forme *file:///path/to/spot/*et peut être converti en un `DirectoryEntry` à l'aide`window.resolveLocalFileSystemURL()`. - -* `cordova.file.applicationDirectory`-Lecture seule répertoire où l'application est installée. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.applicationStorageDirectory`-Répertoire racine du bac à sable de l'application ; cet endroit est en lecture seule sur iOS (mais les sous-répertoires spécifiques [comme `/Documents` ] sont en lecture / écriture). Toutes les données qu'il contient est privé de l'application. ( *iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.dataDirectory`-Stockage des données persistants et privés au sein de bac à sable de l'application à l'aide de la mémoire interne (sur Android, si vous avez besoin d'utiliser une mémoire externe, utilisez `.externalDataDirectory` ). Sur iOS, ce répertoire n'est pas synchronisé avec iCloud (utiliser `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.cacheDirectory`-Répertoire pour les fichiers de données en mémoire cache ou les fichiers que votre application peut recréer facilement. L'OS peut supprimer ces fichiers lorsque l'appareil faiblit sur stockage, néanmoins, les applications ne doivent pas compter sur l'OS pour supprimer les fichiers ici. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.externalApplicationStorageDirectory`-Espace l'application sur le stockage externe. (*Android*) - -* `cordova.file.externalDataDirectory`-Où placer les fichiers de données d'application spécifiques sur le stockage externe. (*Android*) - -* `cordova.file.externalCacheDirectory`-Cache de l'application sur le stockage externe. (*Android*) - -* `cordova.file.externalRootDirectory`-Racine de stockage externe (carte SD). (*Android*, *BlackBerry 10*) - -* `cordova.file.tempDirectory`-Répertoire temp que l'OS peut effacer à volonté. Ne comptez pas sur l'OS pour effacer ce répertoire ; votre application doit toujours supprimer les fichiers selon le cas. (*iOS*) - -* `cordova.file.syncedDataDirectory`-Contient des fichiers d'app spécifique qui doivent se synchroniser (par exemple à iCloud). (*iOS*) - -* `cordova.file.documentsDirectory`-Fichiers privés à l'app, mais qui sont significatives pour l'autre application (par exemple les fichiers Office). (*iOS*) - -* `cordova.file.sharedDirectory`-Fichiers disponibles globalement à toutes les applications (*BlackBerry 10*) - -## Structures de système de fichiers - -Bien que techniquement un détail d'implémentation, il peut être très utile de savoir comment les `cordova.file.*` carte de propriétés à des chemins d'accès physiques sur un périphérique réel. - -### iOS agencement de système de fichier - -| Chemin de l'unité | `Cordova.file.*` | `iosExtraFileSystems` | r/w ? | persistants ? | OS efface | Sync | privé | -|:-------------------------------------------- |:--------------------------- |:--------------------- |:-----:|:-------------:|:-----------:|:-----:|:-----:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Oui | -| `appname.app/` | applicationDirectory | Bundle | r | N/A | N/A | N/A | Oui | -| `www/` | - | - | r | N/A | N/A | N/A | Oui | -| `Documents/` | documentsDirectory | documents | r/w | Oui | Non | Oui | Oui | -| `NoCloud/` | - | documents-nosync | r/w | Oui | Non | Non | Oui | -| `Library` | - | Bibliothèque | r/w | Oui | Non | Oui ? | Oui | -| `NoCloud/` | dataDirectory | Bibliothèque-nosync | r/w | Oui | Non | Non | Oui | -| `Cloud/` | syncedDataDirectory | - | r/w | Oui | Non | Oui | Oui | -| `Caches/` | cacheDirectory | cache | r/w | Oui * | Oui * * *| | Non | Oui | -| `tmp/` | tempDirectory | - | r/w | Ne * * | Oui * * *| | Non | Oui | - -* Fichiers persistent à travers les redémarrages de l'application et mises à niveau, mais ce répertoire peut être effacé à chaque fois que les désirs de l'OS. Votre application doit être en mesure de recréer tout contenu qui pourrait être supprimé. - -* * Fichiers peuvent persister redémarrages de l'application, mais ne vous fiez pas ce comportement. Les fichiers ne sont pas garantis à persister dans l'ensemble de mises à jour. Votre application doit supprimer les fichiers de ce répertoire lorsqu'elle s'applique, comme le système d'exploitation ne garantit pas quand (ou même si) ces fichiers sont supprimés. - -* * *| L'OS peut effacer le contenu de ce répertoire chaque fois qu'il se sent il est nécessaire, mais ne comptez pas là-dessus. Vous devez supprimer ce répertoire comme approprié pour votre application. - -### Agencement de système de fichiers Android - -| Chemin de l'unité | `Cordova.file.*` | `AndroidExtraFileSystems` | r/w ? | persistants ? | OS efface | privé | -|:----------------------------------- |:----------------------------------- |:------------------------- |:-----:|:-------------:|:---------:|:-----:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | Oui | -| `/ données/data/app < id > /` | applicationStorageDirectory | - | r/w | N/A | N/A | Oui | -| `cache` | cacheDirectory | cache | r/w | Oui | Oui * | Oui | -| `files` | dataDirectory | fichiers | r/w | Oui | Non | Oui | -| `Documents` | | documents | r/w | Oui | Non | Oui | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Oui | Non | Non | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Oui | Non | Non | -| `cache` | externalCacheDirectry | cache-externe | r/w | Oui | Ne * * | Non | -| `files` | externalDataDirectory | fichiers externes | r/w | Oui | Non | Non | - -* Le système d'exploitation peut effacer périodiquement ce répertoire, mais ne vous fiez pas ce comportement. Effacer le contenu de ce répertoire comme approprié pour votre application. Un utilisateur doit purger le cache manuellement, le contenu de ce répertoire est supprimé. - -* * The OS vous n'effacez pas ce répertoire automatiquement ; vous êtes chargé de gérer le contenu vous-même. L'utilisateur devrait purger le cache manuellement, le contenu du répertoire est supprimé. - -**Remarque**: si le stockage externe ne peut pas être monté, les `cordova.file.external*` sont des propriétés`null`. - -### Configuration du système blackBerry 10 fichier - -| Chemin de l'unité | `Cordova.file.*` | r/w ? | persistants ? | OS efface | privé | -|:--------------------------------------------------- |:--------------------------- |:-----:|:-------------:|:---------:|:-----:| -| `file:///Accounts/1000/AppData/ < id app > /` | applicationStorageDirectory | r | N/A | N/A | Oui | -| `app/native` | applicationDirectory | r | N/A | N/A | Oui | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | Non | Oui | Oui | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Oui | Non | Oui | -| `file:///Accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Oui | Non | Non | -| `file:///Accounts/1000/Shared` | sharedDirectory | r/w | Oui | Non | Non | - -*Remarque*: lorsque l'application est déployée dans le périmètre de travail, tous les chemins sont par rapport à /accounts/1000-enterprise. - -## Quirks Android - -### Emplacement de stockage persistant Android - -Il y a plusieurs emplacements valides pour stocker des fichiers persistants sur un appareil Android. Voir [cette page][3] pour une analyse approfondie des diverses possibilités. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -Les versions précédentes du plugin choisirait l'emplacement des fichiers temporaires et persistantes au démarrage, basé sur la question de savoir si le dispositif réclamé que la carte SD (ou une partition de stockage équivalent) a été montée. Si la carte SD a été montée, ou si une partition de stockage interne importante était disponible (comme sur les appareils Nexus,) puis les fichiers persistants seraient stockés dans la racine de cet espace. Cela signifie que toutes les apps de Cordova pouvaient voir tous les fichiers disponibles sur la carte. - -Si la carte SD n'était pas disponible, les versions précédentes pourraient stocker des données sous `/data/data/<packageId>` , qui isole des apps de l'autre, mais peut encore cause données à partager entre les utilisateurs. - -Il est maintenant possible de choisir de stocker les fichiers dans l'emplacement de stockage de fichier interne, ou en utilisant la logique précédente, avec une préférence au sein de votre application `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` : - - < nom de l'option = « AndroidPersistentFileLocation » value = « Internal » / >< nom de préférence = « AndroidPersistentFileLocation » value = « Compatibilité » / > - - -Sans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas. - -Si votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Commutation de l'emplacement « Internal » signifierait que les utilisateurs existants qui mettre à niveau leur application peuvent être impossible d'accéder à leurs fichiers déjà enregistrés, selon leur appareil. - -Si votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Internal` réglage est généralement recommandé. - -## iOS Quirks - -* `cordova.file.applicationStorageDirectory`est en lecture seule ; tentative de stocker des fichiers dans le répertoire racine échoue. Utilisez l'une de l'autre `cordova.file.*` les propriétés définies pour iOS (seulement `applicationDirectory` et `applicationStorageDirectory` sont en lecture seule). -* `FileReader.readAsText(blob, encoding)` - * Le `encoding` paramètre n'est pas pris en charge, et le codage UTF-8 est toujours en vigueur. - -### emplacement de stockage persistant d'iOS - -Il y a deux emplacements valides pour stocker des fichiers persistants sur un appareil iOS : le répertoire de Documents et le répertoire de la bibliothèque. Les versions précédentes du plugin stockaient ne jamais fichiers persistants dans le répertoire de Documents. Cela a eu l'effet secondaire de rendre tous les fichiers de l'application visible dans iTunes, qui était souvent inattendus, en particulier pour les applications qui traitent beaucoup de petits fichiers, plutôt que de produire des documents complets destinés à l'exportation, qui est l'objectif visé par le répertoire. - -Il est maintenant possible de choisir de stocker les fichiers dans le répertoire de bibliothèque, avec une préférence au sein de votre application ou de documents `config.xml` fichier. Pour ce faire, ajoutez l'un de ces deux lignes de `config.xml` : - - < nom de l'option = « iosPersistentFileLocation » value = « Library » / >< nom de préférence = « iosPersistentFileLocation » value = « Compatibilité » / > - - -Sans cette ligne, utilisera le fichier plugin `Compatibility` par défaut. Si une balise de préférence est présente et n'est pas une des valeurs suivantes, l'application ne démarrera pas. - -Si votre application a déjà été expédiée aux utilisateurs, en utilisant une ancienne (avant 1.0) version de ce plugin et dispose des fichiers stockés dans le système de fichiers persistant, alors vous devez définir la préférence au `Compatibility` . Changer l'emplacement de `Library` voudrait dire que les utilisateurs existants qui mettre à niveau leur application serait incapables d'accéder à leurs fichiers déjà enregistrés. - -Si votre application est nouvelle ou a jamais précédemment stocké les fichiers dans le système de fichiers persistant, puis la `Library` réglage est généralement recommandé. - -## Firefox OS Quirks - -L'API de système de fichier n'est pas nativement pris en charge par Firefox OS et est implémentée comme une cale d'épaisseur sur le dessus d'indexedDB. - -* Ne manque pas lors de la suppression des répertoires non vide -* Ne supporte pas les métadonnées pour les répertoires -* Méthodes `copyTo` et `moveTo` ne prennent pas en charge les répertoires - -Les chemins de données suivants sont pris en charge: * `applicationDirectory` -utilise `xhr` pour obtenir des fichiers les qui sont emballées avec l'app. * `dataDirectory` - Pour les fichiers de données persistantes de app spécifique. * `cacheDirectory` -Mise en cache de fichiers qui doivent survivre les redémarrages de l'application (les applications ne doivent pas compter sur le système d'exploitation pour supprimer les fichiers ici). - -## Bizarreries navigateur - -### Commune de bizarreries et de remarques - -* Chaque navigateur utilise son propre système de fichiers en bac à sable. IE et Firefox utilisent IndexedDB comme base. Tous les navigateurs utilisent oblique comme séparateur de répertoire dans un chemin d'accès. -* Entrées d'annuaire doivent être créées successivement. Par exemple, l'appel `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` échouera si dir1 n'existait pas. -* Le plugin demande utilisateur l'autorisation d'utiliser le stockage persistant lors du premier démarrage d'application. -* Plugin supporte `cdvfile://localhost` (ressources locales) seulement. C'est-à-dire les ressources externes ne sont pas supportés par l'intermédiaire de `cdvfile`. -* Le plugin ne suit pas les ["Restrictions de nommage des fichiers système API 8.3"][4]. -* BLOB et le fichier "`close` la fonction n'est pas pris en charge. -* `FileSaver` et `BlobBuilder` ne sont pas pris en charge par ce plugin et n'ont stubs. -* Le plugin ne supporte pas les `requestAllFileSystems`. Cette fonction est également absent dans les cahier des charges. -* Inscriptions dans l'annuaire ne seront pas supprimées si vous utilisez `create: true` drapeau pour le répertoire existant. -* Fichiers créés via le constructeur ne sont pas pris en charge. Vous devez plutôt utiliser entry.file méthode. -* Chaque navigateur utilise sa propre forme de références URL blob. -* `readAsDataURL` fonction est prise en charge, mais le mediatype en Chrome dépend de l'extension entrée, mediatype dans IE est toujours vide (qui est le même que le `texte-plaine` selon la spécification), le mediatype dans Firefox est toujours `application/octet-stream`. Par exemple, si le contenu est `abcdefg` puis Firefox renvoie `données : application / octet-stream ; base64, YWJjZGVmZw ==`, c'est à dire les retours `données:; base64, YWJjZGVmZw ==`, retours de Chrome `données : < mediatype selon l'extension de nom d'entrée > ; base64, YWJjZGVmZw ==`. -* `toInternalURL` retourne le chemin d'accès dans le formulaire `file:///persistent/path/to/entry` (Firefox, IE). Chrome retourne le chemin d'accès dans le formulaire `cdvfile://localhost/persistent/file`. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### Bizarreries de chrome - -* Chrome filesystem n'est pas prête immédiatement après l'événement ready périphérique. Pour contourner le problème, vous pouvez vous abonner à l'événement `filePluginIsReady`. Exemple : - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -Vous pouvez utiliser la fonction `window.isFilePluginReadyRaised` pour vérifier si les événement était déjà déclenché. -quotas de window.requestFileSystem temporaire et permanent de système de fichiers ne sont pas limités en Chrome. -Pour augmenter le stockage persistant en Chrome, vous devez appeler la méthode `window.initPersistentFileSystem`. Quota de stockage persistant est 5 Mo par défaut. -Chrome nécessite `--permettre-fichier-accès-de-fichiers` exécuter l'argument au support API via le protocole `file:///`. -`Fichier` objet changera pas si vous utilisez le drapeau `{create:true}` lors du passage d'une `entrée` existante. -événements `annulables` propriété a la valeur true dans Chrome. Il s'agit à l'encontre de la [spécification][5]. -`toURL` renvoie à Chrome `système de fichiers :`-préfixe de chemin d'accès selon l'application hôte. Par exemple, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -résultat de la fonction `toURL` ne contient-elle pas de barre oblique dans le cas d'entrée d'annuaire. Chrome résout répertoires avec barre oblique-trainés URL correctement cependant. -`resolveLocalFileSystemURL` méthode nécessite l' entrant `url` préfixe de `système de fichiers`. Par exemple, le paramètre `d'url` pour `resolveLocalFileSystemURL` devrait être dans la forme `filesystem:file:///persistent/somefile.txt` par opposition à la forme `file:///persistent/somefile.txt` dans Android. -Déconseillée `toNativeURL` fonction n'est pas prise en charge et n'est pas une ébauche. -fonction de `setMetadata` n'est pas stipulée dans le devis et pas pris en charge. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de SYNTAX_ERR(code: 8) sur la demande d'un système de fichier inexistant. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de PATH_EXISTS_ERR(code: 12) à essayer de créer exclusivement un fichier ou un répertoire, qui existe déjà. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NO_MODIFICATION_ALLOWED_ERR(code: 6) à essayer d'appeler removeRecursively sur le système de fichiers racine. -INVALID_MODIFICATION_ERR (code: 9) est levée au lieu de NOT_FOUND_ERR(code: 1) en essayant de moveTo répertoire qui n'existe pas. - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### Base IndexedDB impl bizarreries (Firefox et IE) - -* `.` et `.` ne sont pas pris en charge. -* IE ne prend pas en charge les `file:///`-mode ; seul le mode hébergé est pris en charge (http://localhost:xxxx). -* Taille de système de fichiers de Firefox n'est pas limité, mais chaque extension de 50Mo demandera une autorisation de l'utilisateur. IE10 permet jusqu'à 10 Mo de combiné AppCache et IndexedDB utilisés dans la mise en œuvre du système de fichiers sans demander de confirmation, une fois que vous atteignez ce niveau, Qu'on vous demandera si vous souhaitez lui permettre d'être augmentée jusqu'à un maximum de 250 Mo par site. Si le paramètre de `taille` pour la fonction `requestFileSystem` n'affecte pas le système de fichiers dans Firefox et IE. -* fonction de `readAsBinaryString` n'est pas indiquée dans les spécifications et pas pris en charge dans Internet Explorer et n'a pas une ébauche. -* `file.type` est toujours null. -* Vous ne devez pas créer en utilisant le résultat du callback instance DirectoryEntry qui avait été supprimée. Sinon, vous obtiendrez une « entrée de pendaison ». -* Avant que vous pouvez lire un fichier qui a été écrit juste que vous devez obtenir une nouvelle instance de ce fichier. -* `setMetadata` fonction, qui n'est pas indiquée dans les spécifications supporte `modificationTime` changement de champ seulement. -* fonctions `copyTo` et `moveTo` ne supportent pas les répertoires. -* Répertoires métadonnées ne sont pas pris en charge. -* Les deux Entry.remove et directoryEntry.removeRecursively ne manquent pas lors de la suppression des répertoires non-vides - répertoires retirés sont nettoyés avec contenu au lieu de cela. -* fonctions `abort` et `truncate` ne sont pas supportées. -* événements de progression ne sont pas déclenchés. Par exemple, ce gestionnaire ne sera pas exécuté : - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## Notes de mise à niveau - -V1.0.0 de ce plugin, les structures `FileEntry` et `DirectoryEntry` ont changé, pour être plus conforme à la spécification publiée. - -Les versions précédentes de (pré-1.0.0) du plugin stockaient le dispositif-absolu--emplacement du fichier dans la propriété `fullPath` d'objets `d'entrée`. Ces chemins seraient présente généralement comme - - / var/mobile/Applications/< application UUID >/Documents/chemin/vers/fichier (iOS), /storage/emulated/0/path/to/file (Android) - - -Ces chemins ont été également retournés par la méthode de `toURL()` les objets `d'entrée`. - -Avec v1.0.0, l'attribut `fullPath` est le chemin d'accès au fichier, *par rapport à la racine du système de fichiers HTML*. Ainsi, les chemins d'accès ci-dessus seraient maintenant tous les deux être représentée par un objet `FileEntry` avec un `fullPath` de - - /path/to/file - - -Si votre application fonctionne avec le dispositif-absolu-chemins et que vous avez récupéré précédemment ces chemins d'accès par le biais de la propriété `fullPath` d'objets `d'entrée`, puis vous devez mettre à jour votre code afin d'utiliser `entry.toURL()` à la place. - -Pour vers l'arrière la compatibilité, la méthode `resolveLocalFileSystemURL()` sera un chemin absolu de l'unité et retourne un objet `Entry` correspondant à elle, tant que ce fichier existe au sein des systèmes de fichiers les `TEMPORARY` ou `PERSISTENT`. - -Cela a été particulièrement un problème avec le plugin de transfert de fichiers, qui autrefois périphérique-absolu-chemins (et peut encore accepter). Il a été mis à jour pour fonctionner correctement avec le système de fichiers URL, afin de remplacer `entry.fullPath` par `entry.toURL()` devrait résoudre tout problème obtenir ce plugin pour travailler avec des fichiers sur le périphérique. - -Dans v1.1.0 la valeur de retour de `toURL()` a été changée (voir \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) pour renvoyer une URL absolue "file://". dans la mesure du possible. Pour assurer un ' cdvfile:'-URL, vous pouvez utiliser `toInternalURL()` maintenant. Cette méthode retourne maintenant filesystem URL du formulaire - - cdvfile://localhost/persistent/path/to/file - - -qui peut servir à identifier de manière unique le fichier. - -## Liste des Codes d'erreur et leur signification - -Lorsqu'une erreur est levée, l'un des codes suivants sera utilisé. - -| Code | Constant | -| ----:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configuration du Plugin (facultatif) - -L'ensemble des systèmes de fichiers disponibles peut être configurée par plate-forme. Les iOS et Android reconnaissent une <preference> balise dans le `fichier config.xml` qui nomme les systèmes de fichiers à installer. Par défaut, toutes les racines du système de fichiers sont activées. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - -* `files` : répertoire de stockage de fichier interne de l'application -* `files-external` : répertoire de l'application de stockage de fichier externe -* `sdcard` : le répertoire de stockage global fichier externe (c'est la racine de la carte SD, s'il est installé). Vous devez avoir la permission de `android.permission.WRITE_EXTERNAL_STORAGE` de l'utiliser. -* `cache` : répertoire de cache interne de l'application -* `cache-external` : répertoire de cache externe de l'application -* `root` : le système de fichiers de tout dispositif - -Android prend également en charge un système de fichiers spécial nommé « documents », qui représente un sous-répertoire « / Documents / » dans le système de fichiers « files ». - -### iOS - -* `library` : répertoire de bibliothèque de l'application -* `documents` : répertoire de Documents de l'application -* `cache` : répertoire de Cache de l'application -* `bundle` : bundle de l'application ; l'emplacement de l'application elle-même sur disque (lecture seule) -* `root` : le système de fichiers de tout dispositif - -Par défaut, vous peuvent synchroniser les répertoires de la bibliothèque et les documents à iCloud. Vous pouvez également demander des deux systèmes de fichiers supplémentaires, `library-nosync` et `documents-nosync`, qui représentent un répertoire spécial non synchronisées dans le `/Library` ou système de fichiers `/ Documents`. diff --git a/plugins/cordova-plugin-file/doc/fr/plugins.md b/plugins/cordova-plugin-file/doc/fr/plugins.md deleted file mode 100644 index 070384e5..00000000 --- a/plugins/cordova-plugin-file/doc/fr/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# Notes pour les développeurs de plugins - -Ces notes sont principalement destinés à des développeurs Android et iOS qui veulent écrire des plugins qui interface avec le système de fichiers en utilisant le fichier plugin. - -## Travaillant avec des URL de système pour le fichier Cordova - -Depuis la version 1.0.0, ce plugin utilise des URL avec un `cdvfile` guichet pour toutes les communications sur le pont, plutôt que d'exposer les chemins de système de fichiers de périphérique brut à JavaScript. - -Du côté du JavaScript, cela signifie que les objets DirectoryEntry et de FileEntry ont un attribut fullPath qui est relatif à la racine du système de fichiers HTML. Si l'API JavaScript de votre plugin accepte un objet FileEntry ou DirectoryEntry, vous devez appeler `.toURL()` sur cet objet avant de le passer sur le pont en code natif. - -### Conversion des cdvfile: / / URL pour les chemins de fileystem - -Plugins qui ont besoin d'écrire dans le système de fichiers pouvez convertir un fichier reçu système URL vers un emplacement de système de fichiers réels. Il y a plusieurs façons de le faire, selon la plate-forme native. - -Il est important de rappeler que pas tous les `cdvfile://` URL sont cartographiables à des fichiers sur le périphérique. Certaines URL peut faire référence aux actifs sur les périphériques qui ne sont pas représentés par des fichiers, ou peuvent même faire référence aux ressources distantes. En raison de ces possibilités, plugins devraient toujours tester si ils obtiennent un résultat significatif, retour en essayant de convertir les URL aux chemins d'accès. - -#### Android - -Sur Android, la méthode la plus simple pour convertir un `cdvfile://` URL vers un chemin d'accès de système de fichiers est d'utiliser `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`comporte plusieurs méthodes qui peuvent gérer `cdvfile://` URL : - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -Il est également possible d'utiliser le fichier plugin directement : - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -Pour convertir un chemin d'accès à un `cdvfile://` URL : - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -Si votre plugin crée un fichier et que vous souhaitez renvoyer un objet FileEntry pour cela, utilisez le fichier plugin : - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -Cordova sur iOS n'utilise pas le même `CordovaResourceApi` concept d'Android. Sur iOS, vous devez utiliser le fichier plugin pour convertir entre les URL et les chemins d'accès de système de fichiers. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -Si votre plugin crée un fichier et que vous souhaitez renvoyer un objet FileEntry pour cela, utilisez le fichier plugin : - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -En JavaScript, pour obtenir un `cdvfile://` URL d'un objet FileEntry ou DirectoryEntry, il suffit d'appeler `.toURL()` à ce sujet : - - var cdvfileURL = entry.toURL(); - - -Dans gestionnaires de plugin de réponse, pour convertir une structure FileEntry retournée vers un objet réel de l'entrée, votre code de gestionnaire doit importer le fichier plugin et créer un nouvel objet : - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/it/README.md b/plugins/cordova-plugin-file/doc/it/README.md deleted file mode 100644 index f8e302fa..00000000 --- a/plugins/cordova-plugin-file/doc/it/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -Questo plugin implementa un API File permettendo l'accesso di lettura/scrittura ai file che risiedono sul dispositivo. - -Questo plugin si basa su diverse specifiche, tra cui: The HTML5 File API <http://www.w3.org/TR/FileAPI/> - -Le directory (ormai defunta) e il sistema delle estensioni più recenti: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> anche se la maggior parte del codice plugin è stato scritto quando una spec precedenti era corrente: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Implementa inoltre FileWriter spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Per l'utilizzo, fare riferimento a HTML5 Rocks' eccellente [articolo FileSystem.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -Per una panoramica delle altre opzioni di archiviazione, consultare [Guida di archiviazione di Cordova](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -Questo plugin definisce oggetto global `cordova.file`. - -Anche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Installazione - - cordova plugin add cordova-plugin-file - - -## Piattaforme supportate - - * Amazon fuoco OS - * Android - * BlackBerry 10 - * Firefox OS - * iOS - * Windows Phone 7 e 8 * - * Windows 8 * - * Windows* - * Browser - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## Dove memorizzare i file - -A partire dalla v 1.2.0, vengono forniti gli URL per le directory importanti file di sistema. Ogni URL è nella forma *file:///path/to/spot/* e può essere convertito in un `DirectoryEntry` utilizzando `window.resolveLocalFileSystemURL()`. - - * `cordova.file.applicationDirectory`-Sola lettura directory dove è installato l'applicazione. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.applicationStorageDirectory`-Directory radice di sandbox dell'applicazione; su iOS questa posizione è in sola lettura (ma sottodirectory specifiche [come `/Documents` ] sono di sola lettura). Tutti i dati contenuti all'interno è privato all'app. ( *iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.dataDirectory`-Archiviazione dati persistente e privati nella sandbox dell'applicazione utilizzando la memoria interna (su Android, se è necessario utilizzare la memoria esterna, utilizzare `.externalDataDirectory` ). IOS, questa directory non è sincronizzata con iCloud (utilizzare `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.cacheDirectory`-Directory per i file memorizzati nella cache di dati o qualsiasi file che app possibile ricreare facilmente. L'OS può eliminare questi file quando il dispositivo viene eseguito basso sull'archiviazione, tuttavia, apps non deve basarsi sul sistema operativo per cancellare i file qui. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.externalApplicationStorageDirectory`-Spazio applicazione su storage esterno. (*Android*) - - * `cordova.file.externalDataDirectory`-Dove mettere i file di dati specifico app su storage esterno. (*Android*) - - * `cordova.file.externalCacheDirectory`-Cache applicazione su storage esterno. (*Android*) - - * `cordova.file.externalRootDirectory`-Radice di archiviazione esterna (scheda SD). (*Android*, *BlackBerry, 10*) - - * `cordova.file.tempDirectory`-Temp directory che l'OS è possibile cancellare a volontà. Non fare affidamento sul sistema operativo per cancellare questa directory; l'app deve sempre rimuovere file come applicabile. (*iOS*) - - * `cordova.file.syncedDataDirectory`-Contiene i file app specifiche che devono essere sincronizzati (per esempio a iCloud). (*iOS*) - - * `cordova.file.documentsDirectory`-I file privati per le app, ma che sono significativi per altre applicazioni (ad esempio i file di Office). (*iOS*) - - * `cordova.file.sharedDirectory`-File disponibili globalmente a tutte le applicazioni (*BlackBerry 10*) - -## Layout dei file di sistema - -Anche se tecnicamente un dettaglio di implementazione, può essere molto utile per conoscere come le proprietà `cordova.file.*` mappa di percorsi fisici su un dispositivo reale. - -### iOS File sistema Layout - -| Percorso dispositivo | `Cordova.file.*` | `iosExtraFileSystems` | r/w? | persistente? | OS cancella | sincronizzazione | privato | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:------------:|:------------:|:----------------:|:-------:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Sì | -| `appname.app/` | applicationDirectory | bundle | r | N/A | N/A | N/A | Sì | -| `www/` | - | - | r | N/A | N/A | N/A | Sì | -| `Documents/` | documentsDirectory | documenti | r/w | Sì | No | Sì | Sì | -| `NoCloud/` | - | nosync-documenti | r/w | Sì | No | No | Sì | -| `Library` | - | libreria | r/w | Sì | No | Sì? | Sì | -| `NoCloud/` | dataDirectory | nosync-libreria | r/w | Sì | No | No | Sì | -| `Cloud/` | syncedDataDirectory | - | r/w | Sì | No | Sì | Sì | -| `Caches/` | cacheDirectory | cache | r/w | Sì * | Sì**\* | No | Sì | -| `tmp/` | tempDirectory | - | r/w | No** | Sì**\* | No | Sì | - -\ * File persistono tra riavvii app e aggiornamenti, ma questa directory può essere cancellata ogni volta che il sistema operativo desideri. L'app dovrebbe essere in grado di ricreare qualsiasi contenuto che potrebbe essere eliminato. - -** File possono persistere riavvii del app, ma non fare affidamento su questo comportamento. I file non sono garantiti a persistere attraverso gli aggiornamenti. L'app deve rimuovere i file dalla directory quando è applicabile, come il sistema operativo non garantisce quando (o anche se) questi file vengono rimossi. - -**\ * The OS può cancellare il contenuto di questa directory ogni volta che si sente è necessario, ma non fare affidamento su questo. Si dovrebbe cancellare questa directory come adatto per l'applicazione. - -### Layout sistema Android File - -| Percorso dispositivo | `Cordova.file.*` | `AndroidExtraFileSystems` | r/w? | persistente? | OS cancella | privato | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:----:|:------------:|:-----------:|:-------:| -| `File:///android_asset/` | applicationDirectory | | r | N/A | N/A | Sì | -| `< app-id > /dati/dati / /` | applicationStorageDirectory | - | r/w | N/A | N/A | Sì | -| `cache` | cacheDirectory | cache | r/w | Sì | Sì\* | Sì | -| `files` | dataDirectory | file | r/w | Sì | No | Sì | -| `Documents` | | documenti | r/w | Sì | No | Sì | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Sì | No | No | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Sì | No | No | -| `cache` | externalCacheDirectry | cache-esterno | r/w | Sì | No** | No | -| `files` | externalDataDirectory | file-esterno | r/w | Sì | No | No | - -\ * Il sistema operativo può cancellare periodicamente questa directory, ma non fare affidamento su questo comportamento. Cancellare il contenuto di questa directory come adatto per l'applicazione. Il contenuto di questa directory dovrebbe un utente eliminare manualmente la cache, vengono rimossi. - -** Il sistema operativo non cancella questa directory automaticamente; Siete responsabili di gestire i contenuti da soli. Il contenuto della directory dovrebbe l'utente eliminare manualmente la cache, vengono rimossi. - -**Nota**: se la memorizzazione esterna non può essere montato, le proprietà `cordova.file.external*` sono `null`. - -### BlackBerry 10 File sistema Layout - -| Percorso dispositivo | `Cordova.file.*` | r/w? | persistente? | OS cancella | privato | -|:----------------------------------------------------------- |:--------------------------- |:----:|:------------:|:-----------:|:-------:| -| `File:///accounts/1000/AppData/ < id app > /` | applicationStorageDirectory | r | N/A | N/A | Sì | -| `app/native` | applicationDirectory | r | N/A | N/A | Sì | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | No | Sì | Sì | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Sì | No | Sì | -| `File:///accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Sì | No | No | -| `File:///accounts/1000/Shared` | sharedDirectory | r/w | Sì | No | No | - -*Nota*: quando l'applicazione viene distribuita a lavorare perimetrale, tutti i percorsi sono relativi a /accounts/1000-enterprise. - -## Stranezze Android - -### Posizione di archiviazione persistente Android - -Ci sono più percorsi validi per memorizzare i file persistenti su un dispositivo Android. Vedi [questa pagina](http://developer.android.com/guide/topics/data/data-storage.html) per un'ampia discussione delle varie possibilità. - -Versioni precedenti del plugin avrebbe scelto il percorso dei file temporanei e permanenti su avvio, in base se il dispositivo ha sostenuto che la scheda SD (o partizione storage equivalente) è stato montato. Se è stata montata sulla scheda SD o una partizione di storage interno grande era disponibile (come sui dispositivi Nexus,) allora saranno memorizzati i file persistenti nella radice di quello spazio. Questo significava che tutte le apps di Cordova poteva vedere tutti i file disponibili sulla carta. - -Se la scheda SD non era disponibile, poi versioni precedenti vuoi memorizzare dati sotto `/data/data/<packageId>`, che isola i apps da altro, ma può ancora causa dati da condividere tra gli utenti. - -Ora è possibile scegliere se memorizzare i file nel percorso di archiviazione di file interno o utilizzando la logica precedente, con una preferenza nel file `config. xml` dell'applicazione. Per fare questo, aggiungere una di queste due linee al `file config. xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Senza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia. - -Se l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione su "Interno" di commutazione significherebbe che gli utenti esistenti che aggiornare la loro applicazione potrebbero essere Impossibile accedere ai loro file precedentemente memorizzati, a seconda del loro dispositivo. - -Se l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione `Internal`. - -### Operazioni ricorsive lento per /android_asset - -L'elencazione delle directory asset è veramente lento su Android. È possibile velocizzare e fino anche se, con l'aggiunta di `src/android/build-extras.gradle` alla radice del tuo progetto android (richiede anche cordova-android@4.0.0 o superiore). - -## iOS stranezze - - * `cordova.file.applicationStorageDirectory`è di sola lettura; tentativo di memorizzare i file all'interno della directory radice avrà esito negativo. Utilizzare uno degli altri `cordova.file.*` proprietà definite per iOS (solo `applicationDirectory` e `applicationStorageDirectory` sono di sola lettura). - * `FileReader.readAsText(blob, encoding)` - * Il `encoding` parametro non è supportato, e codifica UTF-8 è sempre attivo. - -### posizione di archiviazione persistente di iOS - -Ci sono due percorsi validi per memorizzare i file persistenti su un dispositivo iOS: la directory documenti e la biblioteca. Precedenti versioni del plugin archiviati solo mai persistenti file nella directory documenti. Questo ha avuto l'effetto collaterale di tutti i file di un'applicazione che rende visibili in iTunes, che era spesso involontaria, soprattutto per le applicazioni che gestiscono un sacco di piccoli file, piuttosto che produrre documenti completi per l'esportazione, che è la destinazione della directory. - -Ora è possibile scegliere se memorizzare i file nella directory di libreria, con una preferenza nel file `config. xml` dell'applicazione o documenti. Per fare questo, aggiungere una di queste due linee al `file config. xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Senza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia. - -Se l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione di commutazione alla `libreria` significherebbe che gli utenti esistenti che aggiornare la loro applicazione è in grado di accedere ai loro file precedentemente memorizzati. - -Se l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione della `Library`. - -## Firefox OS stranezze - -L'API di sistema del File non è supportato nativamente dal sistema operativo Firefox e viene implementato come uno spessore in cima indexedDB. - - * Non manca quando si rimuove le directory non vuota - * Non supporta i metadati per le directory - * Metodi `copyTo` e `moveTo` non supporta le directory - -Sono supportati i seguenti percorsi di dati: * `applicationDirectory` - utilizza `xhr` per ottenere i file locali che sono confezionati con l'app. *`dataDirectory` - per i file di dati persistenti app specifiche. *`cacheDirectory` - file memorizzati nella cache che dovrebbe sopravvivere si riavvia app (applicazioni non devono basarsi sull'OS di eliminare i file qui). - -## Stranezze browser - -### Stranezze e osservazioni comuni - - * Ogni browser utilizza il proprio filesystem in modalità sandbox. IE e Firefox utilizzare IndexedDB come base. Tutti i browser utilizzano barra come separatore di directory in un percorso. - * Le voci di directory devono essere creato successivamente. Ad esempio, la chiamata `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` non riuscirà se non esistesse dir1. - * Il plugin richiede autorizzazione utente per utilizzare un archivio permanente presso il primo avvio dell'applicazione. - * Plugin supporta `cdvfile://localhost` (risorse locali) solo. Cioè risorse esterne non sono supportate tramite `cdvfile`. - * Il plugin non segue ["Limitazioni di denominazione 8.3 File sistema API"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). - * BLOB e File' `close` la funzione non è supportata. - * `FileSaver` e `BlobBuilder` non sono supportati da questo plugin e non hanno gli stub. - * Il plugin non supporta `requestAllFileSystems`. Questa funzione manca anche nelle specifiche. - * Entrate nella directory non verranno rimossi se si utilizza `create: true` bandiera per directory esistente. - * Non sono supportati i file creati tramite il costruttore. È invece necessario utilizzare il metodo entry.file. - * Ogni browser utilizza la propria forma per riferimenti URL blob. - * `readAsDataURL` funzione è supportata, ma il mediatype in Chrome dipende dall'estensione di voce, mediatype in IE è sempre vuota (che è lo stesso come `text-plain` secondo la specifica), il mediatype in Firefox è sempre `application/octet-stream`. Ad esempio, se il contenuto è `abcdefg` quindi Firefox restituisce `dati: applicazione / octet-stream; base64, YWJjZGVmZw = =`, cioè restituisce `dati:; base64, YWJjZGVmZw = =`, Chrome restituisce `dati: < mediatype a seconda dell'estensione del nome della voce >; base64, YWJjZGVmZw = =`. - * `toInternalURL` restituisce il percorso in forma `file:///persistent/path/to/entry` (Firefox, IE). Chrome restituisce il percorso nella forma `cdvfile://localhost/persistent/file`. - -### Stranezze di cromo - - * Cromo filesystem non è subito pronto dopo evento ready dispositivo. Come soluzione alternativa, è possibile iscriversi all'evento `filePluginIsReady`. Esempio: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -È possibile utilizzare la funzione `window.isFilePluginReadyRaised` per verificare se evento già è stato generato. -quote di filesystem TEMPORARY e PERSISTENT window.requestFileSystem non sono limitate in Chrome. -Per aumentare la memoria persistente in Chrome è necessario chiamare il metodo `window.initPersistentFileSystem`. Quota di archiviazione persistente è di 5 MB per impostazione predefinita. -Chrome richiede `-consentire-file-accesso-da-file` eseguire argomento a supporto API tramite protocollo `file:///`. -`File` oggetto non cambierà se si utilizza il flag `{create:true}` quando ottenendo un' esistente `entrata`. -eventi `cancelable` è impostata su true in Chrome. Ciò è in contrasto con la [specifica](http://dev.w3.org/2009/dap/file-system/file-writer.html). -funzione `toURL` Chrome restituisce `filesystem:`-premessi percorso a seconda dell'applicazione host. Ad esempio, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` risultato di funzione non contiene una barra finale in caso di voce di directory. Chrome risolve le directory con gli URL slash-trainati però correttamente. -`resolveLocalFileSystemURL` metodo richiede in ingresso `url` avere il prefisso del `file System`. Ad esempio, il parametro `url` per `resolveLocalFileSystemURL` dovrebbe essere nella forma `filesystem:file:///persistent/somefile.txt` in contrasto con la forma `file:///persistent/somefile.txt` in Android. -Obsoleto `toNativeURL` funzione non è supportata e non dispone di uno stub. -funzione `setMetadata` non è indicato nelle specifiche e non supportato. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di SYNTAX_ERR(code: 8) su richiesta di un filesystem inesistente. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di PATH_EXISTS_ERR(code: 12) sul tentativo di creare esclusivamente un file o una directory, che esiste già. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NO_MODIFICATION_ALLOWED_ERR(code: 6) sul tentativo di chiamare removeRecursively su file system root. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NOT_FOUND_ERR(code: 1) sul tentativo moveTo directory che non esiste. - -### Stranezze impl IndexedDB-basato (Firefox e IE) - - * `.` e `.` non sono supportati. - * IE non supporta `file:///`-modalità; modalità solo ospitata è supportato (http://localhost:xxxx). - * Dimensione filesystem Firefox non è limitata, ma ogni estensione 50MB sarà richiesta un'autorizzazione dell'utente. IE10 consente fino a 10mb di combinato AppCache e IndexedDB utilizzato nell'implementazione del filesystem senza chiedere conferma, una volta premuto quel livello che vi verrà chiesto se si desidera consentire ad essere aumentata fino a un max di 250 mb per ogni sito. Quindi la `size` parametro per la funzione `requestFileSystem` non influisce il filesystem in Firefox e IE. - * `readAsBinaryString` funzione non è indicato nelle specifiche e non supportati in IE e non dispone di uno stub. - * `file.Type` è sempre null. - * Non è necessario creare la voce utilizzando il risultato del callback istanza DirectoryEntry che è stato eliminato. In caso contrario, si otterrà una 'voce di sospensione'. - * Prima è possibile leggere un file che è stato appena scritto è necessario ottenere una nuova istanza di questo file. - * supporta la funzione `setMetadata`, che non è indicato nelle specifiche `modificationTime` cambiamento di campo solo. - * funzioni `copyTo` e `moveTo` non supporta le directory. - * Le directory metadati non sono supportato. - * Sia Entry.remove e directoryEntry.removeRecursively non fallire quando si rimuove le directory non vuota - directory da rimuovere vengono pulite invece insieme al contenuto. - * `abort` e `truncate` le funzioni non sono supportate. - * non vengono generati eventi di progresso. Ad esempio, questo gestore verrà non eseguito: - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## Note di aggiornamento - -In v 1.0.0 di questo plugin, le strutture `FileEntry` e `DirectoryEntry` sono cambiati, per essere più in linea con le specifiche pubblicate. - -Versioni precedenti (pre-1.0.0) del plugin archiviati il dispositivo-assoluto--percorso del file nella proprietà `fullPath` di oggetti della `voce`. In genere questi percorsi si sarebbe simile - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Questi percorsi sono stati anche restituiti dal metodo `toURL()` degli oggetti `Entry`. - -Con v 1.0.0, l'attributo `fullPath` è il percorso del file, *rispetto alla radice del filesystem HTML*. Così, i percorsi sopra sarebbe ora sia rappresentato da un oggetto `FileEntry` con un `fullPath` di - - /path/to/file - - -Se l'applicazione funziona con dispositivo-assoluto-percorsi, e precedentemente recuperato quei percorsi attraverso la proprietà `fullPath` della `voce` oggetti, è necessario aggiornare il codice per utilizzare `entry.toURL()` invece. - -Per indietro la compatibilità, il metodo `resolveLocalFileSystemURL()` verrà accettare un dispositivo-assoluto-percorso e restituirà un oggetto di `entrata` corrispondente ad essa, fintanto che il file esiste all'interno del filesystem la `temporanea` o `permanente`. - -Questo particolare è stato un problema con il plugin di trasferimento File, che in precedenza utilizzati percorsi-dispositivo-assoluto (e ancora può accoglierli). Esso è stato aggiornato per funzionare correttamente con gli URL di FileSystem, così sostituendo `entry.fullPath` con `entry.toURL()` dovrebbe risolvere eventuali problemi ottenendo quel plugin per lavorare con i file nel dispositivo. - -In v 1.1.0 il valore restituito di `toURL()` è stato cambiato (vedere \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) per restituire un URL assoluto 'file://'. ove possibile. Per assicurare un ' cdvfile:'-URL, è possibile utilizzare `toInternalURL()` ora. Questo metodo restituirà ora filesystem URL del modulo - - cdvfile://localhost/persistent/path/to/file - - -che può essere utilizzato per identificare univocamente il file. - -## Elenco dei codici di errore e significati - -Quando viene generato un errore, uno dei seguenti codici da utilizzare. - -| Codice | Costante | -| ------:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configurare il Plugin (opzionale) - -Il set di filesystem disponibili può essere configurato per ogni piattaforma. Sia iOS che Android riconoscere un <preference> Tag nel `file config. xml` che nomina il filesystem per essere installato. Per impostazione predefinita, tutte le radici del file system sono abilitate. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - - * `files`: directory di archiviazione di file interno dell'applicazione - * `files-external`: directory di archiviazione dell'applicazione file esterno - * `sdcard`: la directory di archiviazione di file esterni globale (questa è la radice della scheda SD, se uno è installato). È necessario disporre dell'autorizzazione `android.permission.WRITE_EXTERNAL_STORAGE` utilizzare questo. - * `cache`: la cache interna directory applicazione - * `cache-external`: directory di cache esterna dell'applicazione - * `root`: il dispositivo intero filesystem - -Android supporta anche un filesystem speciale denominato "documenti", che rappresenta una sottodirectory "/ documenti /" all'interno del filesystem "files". - -### iOS - - * `library`: la directory dell'applicazione libreria - * `documents`: la directory dell'applicazione documenti - * `cache`: la Cache directory applicazione - * `bundle`: bundle dell'applicazione; la posizione dell'app sul disco (sola lettura) - * `root`: il dispositivo intero filesystem - -Per impostazione predefinita, la directory di libreria e documenti può essere sincronizzata a iCloud. È anche possibile richiedere due filesystem aggiuntivi, `library-nosync` e `documents-nosync`, che rappresentano una speciale directory non sincronizzati entro il `/Library` o filesystem `/Documents`.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/it/index.md b/plugins/cordova-plugin-file/doc/it/index.md deleted file mode 100644 index f3cd731c..00000000 --- a/plugins/cordova-plugin-file/doc/it/index.md +++ /dev/null @@ -1,338 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -Questo plugin implementa un API File permettendo l'accesso di lettura/scrittura ai file che risiedono sul dispositivo. - -Questo plugin si basa su diverse specifiche, tra cui: The HTML5 File API <http://www.w3.org/TR/FileAPI/> - -Le directory (ormai defunta) e il sistema delle estensioni più recenti: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> anche se la maggior parte del codice plugin è stato scritto quando una spec precedenti era corrente: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Implementa inoltre FileWriter spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Per l'utilizzo, fare riferimento a HTML5 Rocks' eccellente [articolo FileSystem.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -Per una panoramica delle altre opzioni di archiviazione, consultare [Guida di archiviazione di Cordova][2]. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -Questo plugin definisce oggetto global `cordova.file`. - -Anche se in ambito globale, non è disponibile fino a dopo l'evento `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Installazione - - cordova plugin add cordova-plugin-file - - -## Piattaforme supportate - -* Amazon fuoco OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows Phone 7 e 8 * -* Windows 8 * -* Browser - -* *Queste piattaforme non supportano `FileReader.readAsArrayBuffer` né `FileWriter.write(blob)`.* - -## Dove memorizzare i file - -A partire dalla v 1.2.0, vengono forniti gli URL per le directory importanti file di sistema. Ogni URL è nella forma *file:///path/to/spot/* e può essere convertito in un `DirectoryEntry` utilizzando `window.resolveLocalFileSystemURL()`. - -* `cordova.file.applicationDirectory`-Sola lettura directory dove è installato l'applicazione. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.applicationStorageDirectory`-Directory radice di sandbox dell'applicazione; su iOS questa posizione è in sola lettura (ma sottodirectory specifiche [come `/Documents` ] sono di sola lettura). Tutti i dati contenuti all'interno è privato all'app. ( *iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.dataDirectory`-Archiviazione dati persistente e privati nella sandbox dell'applicazione utilizzando la memoria interna (su Android, se è necessario utilizzare la memoria esterna, utilizzare `.externalDataDirectory` ). IOS, questa directory non è sincronizzata con iCloud (utilizzare `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.cacheDirectory`-Directory per i file memorizzati nella cache di dati o qualsiasi file che app possibile ricreare facilmente. L'OS può eliminare questi file quando il dispositivo viene eseguito basso sull'archiviazione, tuttavia, apps non deve basarsi sul sistema operativo per cancellare i file qui. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.externalApplicationStorageDirectory`-Spazio applicazione su storage esterno. (*Android*) - -* `cordova.file.externalDataDirectory`-Dove mettere i file di dati specifico app su storage esterno. (*Android*) - -* `cordova.file.externalCacheDirectory`-Cache applicazione su storage esterno. (*Android*) - -* `cordova.file.externalRootDirectory`-Radice di archiviazione esterna (scheda SD). (*Android*, *BlackBerry, 10*) - -* `cordova.file.tempDirectory`-Temp directory che l'OS è possibile cancellare a volontà. Non fare affidamento sul sistema operativo per cancellare questa directory; l'app deve sempre rimuovere file come applicabile. (*iOS*) - -* `cordova.file.syncedDataDirectory`-Contiene i file app specifiche che devono essere sincronizzati (per esempio a iCloud). (*iOS*) - -* `cordova.file.documentsDirectory`-I file privati per le app, ma che sono significativi per altre applicazioni (ad esempio i file di Office). (*iOS*) - -* `cordova.file.sharedDirectory`-File disponibili globalmente a tutte le applicazioni (*BlackBerry 10*) - -## Layout dei file di sistema - -Anche se tecnicamente un dettaglio di implementazione, può essere molto utile per conoscere come le proprietà `cordova.file.*` mappa di percorsi fisici su un dispositivo reale. - -### iOS File sistema Layout - -| Percorso dispositivo | `Cordova.file.*` | `iosExtraFileSystems` | r/w? | persistente? | OS cancella | sincronizzazione | privato | -|:-------------------------------------------- |:--------------------------- |:--------------------- |:----:|:------------:|:-----------:|:----------------:|:-------:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | Sì | -| `appname.app/` | applicationDirectory | bundle | r | N/A | N/A | N/A | Sì | -| `www/` | - | - | r | N/A | N/A | N/A | Sì | -| `Documents/` | documentsDirectory | documenti | r/w | Sì | No | Sì | Sì | -| `NoCloud/` | - | nosync-documenti | r/w | Sì | No | No | Sì | -| `Library` | - | libreria | r/w | Sì | No | Sì? | Sì | -| `NoCloud/` | dataDirectory | nosync-libreria | r/w | Sì | No | No | Sì | -| `Cloud/` | syncedDataDirectory | - | r/w | Sì | No | Sì | Sì | -| `Caches/` | cacheDirectory | cache | r/w | Sì * | Sì * * *| | No | Sì | -| `tmp/` | tempDirectory | - | r/w | No * * | Sì * * *| | No | Sì | - -* File persistono attraverso riavvii app e aggiornamenti, ma questa directory può essere azzerata ogni volta che desideri l'OS. L'app dovrebbe essere in grado di ricreare qualsiasi contenuto che potrebbe essere eliminato. - -* * File può persistere attraverso app riavvii, ma non fare affidamento su questo comportamento. I file non sono garantiti a persistere attraverso gli aggiornamenti. L'app deve rimuovere i file dalla directory quando è applicabile, come il sistema operativo non garantisce quando (o anche se) questi file vengono rimossi. - -* * *| Il sistema operativo può cancellare il contenuto di questa directory ogni volta che si sente è necessario, ma non fare affidamento su questo. Si dovrebbe cancellare questa directory come adatto per l'applicazione. - -### Layout sistema Android File - -| Percorso dispositivo | `Cordova.file.*` | `AndroidExtraFileSystems` | r/w? | persistente? | OS cancella | privato | -|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:------------:|:-----------:|:-------:| -| `File:///android_asset/` | applicationDirectory | | r | N/A | N/A | Sì | -| `< app-id > /dati/dati / /` | applicationStorageDirectory | - | r/w | N/A | N/A | Sì | -| `cache` | cacheDirectory | cache | r/w | Sì | Sì * | Sì | -| `files` | dataDirectory | file | r/w | Sì | No | Sì | -| `Documents` | | documenti | r/w | Sì | No | Sì | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Sì | No | No | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Sì | No | No | -| `cache` | externalCacheDirectry | cache-esterno | r/w | Sì | No * * | No | -| `files` | externalDataDirectory | file-esterno | r/w | Sì | No | No | - -* Il sistema operativo può cancellare periodicamente questa directory, ma non fare affidamento su questo comportamento. Cancellare il contenuto di questa directory come adatto per l'applicazione. Il contenuto di questa directory dovrebbe un utente eliminare manualmente la cache, vengono rimossi. - -* * Il sistema operativo non cancella questa directory automaticamente; Tu sei responsabile per la gestione dei contenuti da soli. Il contenuto della directory dovrebbe l'utente eliminare manualmente la cache, vengono rimossi. - -**Nota**: se la memorizzazione esterna non può essere montato, le proprietà `cordova.file.external*` sono `null`. - -### BlackBerry 10 File sistema Layout - -| Percorso dispositivo | `Cordova.file.*` | r/w? | persistente? | OS cancella | privato | -|:--------------------------------------------------- |:--------------------------- |:----:|:------------:|:-----------:|:-------:| -| `File:///accounts/1000/AppData/ < id app > /` | applicationStorageDirectory | r | N/A | N/A | Sì | -| `app/native` | applicationDirectory | r | N/A | N/A | Sì | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | No | Sì | Sì | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Sì | No | Sì | -| `File:///accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Sì | No | No | -| `File:///accounts/1000/Shared` | sharedDirectory | r/w | Sì | No | No | - -*Nota*: quando l'applicazione viene distribuita a lavorare perimetrale, tutti i percorsi sono relativi a /accounts/1000-enterprise. - -## Stranezze Android - -### Posizione di archiviazione persistente Android - -Ci sono più percorsi validi per memorizzare i file persistenti su un dispositivo Android. Vedi [questa pagina][3] per un'ampia discussione delle varie possibilità. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -Versioni precedenti del plugin avrebbe scelto il percorso dei file temporanei e permanenti su avvio, in base se il dispositivo ha sostenuto che la scheda SD (o partizione storage equivalente) è stato montato. Se è stata montata sulla scheda SD o una partizione di storage interno grande era disponibile (come sui dispositivi Nexus,) allora saranno memorizzati i file persistenti nella radice di quello spazio. Questo significava che tutte le apps di Cordova poteva vedere tutti i file disponibili sulla carta. - -Se la scheda SD non era disponibile, poi versioni precedenti vuoi memorizzare dati sotto `/data/data/<packageId>`, che isola i apps da altro, ma può ancora causa dati da condividere tra gli utenti. - -Ora è possibile scegliere se memorizzare i file nel percorso di archiviazione di file interno o utilizzando la logica precedente, con una preferenza nel file `config. xml` dell'applicazione. Per fare questo, aggiungere una di queste due linee al `file config. xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Senza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia. - -Se l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione su "Interno" di commutazione significherebbe che gli utenti esistenti che aggiornare la loro applicazione potrebbero essere Impossibile accedere ai loro file precedentemente memorizzati, a seconda del loro dispositivo. - -Se l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione `Internal`. - -## iOS stranezze - -* `cordova.file.applicationStorageDirectory`è di sola lettura; tentativo di memorizzare i file all'interno della directory radice avrà esito negativo. Utilizzare uno degli altri `cordova.file.*` proprietà definite per iOS (solo `applicationDirectory` e `applicationStorageDirectory` sono di sola lettura). -* `FileReader.readAsText(blob, encoding)` - * Il `encoding` parametro non è supportato, e codifica UTF-8 è sempre attivo. - -### posizione di archiviazione persistente di iOS - -Ci sono due percorsi validi per memorizzare i file persistenti su un dispositivo iOS: la directory documenti e la biblioteca. Precedenti versioni del plugin archiviati solo mai persistenti file nella directory documenti. Questo ha avuto l'effetto collaterale di tutti i file di un'applicazione che rende visibili in iTunes, che era spesso involontaria, soprattutto per le applicazioni che gestiscono un sacco di piccoli file, piuttosto che produrre documenti completi per l'esportazione, che è la destinazione della directory. - -Ora è possibile scegliere se memorizzare i file nella directory di libreria, con una preferenza nel file `config. xml` dell'applicazione o documenti. Per fare questo, aggiungere una di queste due linee al `file config. xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Senza questa linea, il File del plugin utilizzerà la `Compatibility` come predefinito. Se è presente un tag di preferenza e non è uno di questi valori, l'applicazione non si avvia. - -Se l'applicazione è stato spedito in precedenza agli utenti, utilizzando un vecchio (pre-1.0) versione di questo plugin e ha i file memorizzati nel filesystem persistente, allora si dovrebbe impostare la preferenza di `Compatibility`. La posizione di commutazione alla `libreria` significherebbe che gli utenti esistenti che aggiornare la loro applicazione è in grado di accedere ai loro file precedentemente memorizzati. - -Se l'applicazione è nuova, o ha mai precedentemente memorizzati i file nel filesystem persistente, è generalmente consigliato l'impostazione della `Library`. - -## Firefox OS stranezze - -L'API di sistema del File non è supportato nativamente dal sistema operativo Firefox e viene implementato come uno spessore in cima indexedDB. - -* Non manca quando si rimuove le directory non vuota -* Non supporta i metadati per le directory -* Metodi `copyTo` e `moveTo` non supporta le directory - -Sono supportati i seguenti percorsi di dati: * `applicationDirectory` - utilizza `xhr` per ottenere i file locali che sono confezionati con l'app. *`dataDirectory` - per i file di dati persistenti app specifiche. *`cacheDirectory` - file memorizzati nella cache che dovrebbe sopravvivere si riavvia app (applicazioni non devono basarsi sull'OS di eliminare i file qui). - -## Stranezze browser - -### Stranezze e osservazioni comuni - -* Ogni browser utilizza il proprio filesystem in modalità sandbox. IE e Firefox utilizzare IndexedDB come base. Tutti i browser utilizzano barra come separatore di directory in un percorso. -* Le voci di directory devono essere creato successivamente. Ad esempio, la chiamata `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` non riuscirà se non esistesse dir1. -* Il plugin richiede autorizzazione utente per utilizzare un archivio permanente presso il primo avvio dell'applicazione. -* Plugin supporta `cdvfile://localhost` (risorse locali) solo. Cioè risorse esterne non sono supportate tramite `cdvfile`. -* Il plugin non segue ["Limitazioni di denominazione 8.3 File sistema API"][4]. -* BLOB e File' `close` la funzione non è supportata. -* `FileSaver` e `BlobBuilder` non sono supportati da questo plugin e non hanno gli stub. -* Il plugin non supporta `requestAllFileSystems`. Questa funzione manca anche nelle specifiche. -* Entrate nella directory non verranno rimossi se si utilizza `create: true` bandiera per directory esistente. -* Non sono supportati i file creati tramite il costruttore. È invece necessario utilizzare il metodo entry.file. -* Ogni browser utilizza la propria forma per riferimenti URL blob. -* `readAsDataURL` funzione è supportata, ma il mediatype in Chrome dipende dall'estensione di voce, mediatype in IE è sempre vuota (che è lo stesso come `text-plain` secondo la specifica), il mediatype in Firefox è sempre `application/octet-stream`. Ad esempio, se il contenuto è `abcdefg` quindi Firefox restituisce `dati: applicazione / octet-stream; base64, YWJjZGVmZw = =`, cioè restituisce `dati:; base64, YWJjZGVmZw = =`, Chrome restituisce `dati: < mediatype a seconda dell'estensione del nome della voce >; base64, YWJjZGVmZw = =`. -* `toInternalURL` restituisce il percorso in forma `file:///persistent/path/to/entry` (Firefox, IE). Chrome restituisce il percorso nella forma `cdvfile://localhost/persistent/file`. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### Stranezze di cromo - -* Cromo filesystem non è subito pronto dopo evento ready dispositivo. Come soluzione alternativa, è possibile iscriversi all'evento `filePluginIsReady`. Esempio: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -È possibile utilizzare la funzione `window.isFilePluginReadyRaised` per verificare se evento già è stato generato. -quote di filesystem TEMPORARY e PERSISTENT window.requestFileSystem non sono limitate in Chrome. -Per aumentare la memoria persistente in Chrome è necessario chiamare il metodo `window.initPersistentFileSystem`. Quota di archiviazione persistente è di 5 MB per impostazione predefinita. -Chrome richiede `-consentire-file-accesso-da-file` eseguire argomento a supporto API tramite protocollo `file:///`. -`File` oggetto non cambierà se si utilizza il flag `{create:true}` quando ottenendo un' esistente `entrata`. -eventi `cancelable` è impostata su true in Chrome. Ciò è in contrasto con la [specifica][5]. -funzione `toURL` Chrome restituisce `filesystem:`-premessi percorso a seconda dell'applicazione host. Ad esempio, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` risultato di funzione non contiene una barra finale in caso di voce di directory. Chrome risolve le directory con gli URL slash-trainati però correttamente. -`resolveLocalFileSystemURL` metodo richiede in ingresso `url` avere il prefisso del `file System`. Ad esempio, il parametro `url` per `resolveLocalFileSystemURL` dovrebbe essere nella forma `filesystem:file:///persistent/somefile.txt` in contrasto con la forma `file:///persistent/somefile.txt` in Android. -Obsoleto `toNativeURL` funzione non è supportata e non dispone di uno stub. -funzione `setMetadata` non è indicato nelle specifiche e non supportato. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di SYNTAX_ERR(code: 8) su richiesta di un filesystem inesistente. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di PATH_EXISTS_ERR(code: 12) sul tentativo di creare esclusivamente un file o una directory, che esiste già. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NO_MODIFICATION_ALLOWED_ERR(code: 6) sul tentativo di chiamare removeRecursively su file system root. -INVALID_MODIFICATION_ERR (codice: 9) viene generata invece di NOT_FOUND_ERR(code: 1) sul tentativo moveTo directory che non esiste. - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### Stranezze impl IndexedDB-basato (Firefox e IE) - -* `.` e `.` non sono supportati. -* IE non supporta `file:///`-modalità; modalità solo ospitata è supportato (http://localhost:xxxx). -* Dimensione filesystem Firefox non è limitata, ma ogni estensione 50MB sarà richiesta un'autorizzazione dell'utente. IE10 consente fino a 10mb di combinato AppCache e IndexedDB utilizzato nell'implementazione del filesystem senza chiedere conferma, una volta premuto quel livello che vi verrà chiesto se si desidera consentire ad essere aumentata fino a un max di 250 mb per ogni sito. Quindi la `size` parametro per la funzione `requestFileSystem` non influisce il filesystem in Firefox e IE. -* `readAsBinaryString` funzione non è indicato nelle specifiche e non supportati in IE e non dispone di uno stub. -* `file.Type` è sempre null. -* Non è necessario creare la voce utilizzando il risultato del callback istanza DirectoryEntry che è stato eliminato. In caso contrario, si otterrà una 'voce di sospensione'. -* Prima è possibile leggere un file che è stato appena scritto è necessario ottenere una nuova istanza di questo file. -* supporta la funzione `setMetadata`, che non è indicato nelle specifiche `modificationTime` cambiamento di campo solo. -* funzioni `copyTo` e `moveTo` non supporta le directory. -* Le directory metadati non sono supportato. -* Sia Entry.remove e directoryEntry.removeRecursively non fallire quando si rimuove le directory non vuota - directory da rimuovere vengono pulite invece insieme al contenuto. -* `abort` e `truncate` le funzioni non sono supportate. -* non vengono generati eventi di progresso. Ad esempio, questo gestore verrà non eseguito: - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## Note di aggiornamento - -In v 1.0.0 di questo plugin, le strutture `FileEntry` e `DirectoryEntry` sono cambiati, per essere più in linea con le specifiche pubblicate. - -Versioni precedenti (pre-1.0.0) del plugin archiviati il dispositivo-assoluto--percorso del file nella proprietà `fullPath` di oggetti della `voce`. In genere questi percorsi si sarebbe simile - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Questi percorsi sono stati anche restituiti dal metodo `toURL()` degli oggetti `Entry`. - -Con v 1.0.0, l'attributo `fullPath` è il percorso del file, *rispetto alla radice del filesystem HTML*. Così, i percorsi sopra sarebbe ora sia rappresentato da un oggetto `FileEntry` con un `fullPath` di - - /path/to/file - - -Se l'applicazione funziona con dispositivo-assoluto-percorsi, e precedentemente recuperato quei percorsi attraverso la proprietà `fullPath` della `voce` oggetti, è necessario aggiornare il codice per utilizzare `entry.toURL()` invece. - -Per indietro la compatibilità, il metodo `resolveLocalFileSystemURL()` verrà accettare un dispositivo-assoluto-percorso e restituirà un oggetto di `entrata` corrispondente ad essa, fintanto che il file esiste all'interno del filesystem la `temporanea` o `permanente`. - -Questo particolare è stato un problema con il plugin di trasferimento File, che in precedenza utilizzati percorsi-dispositivo-assoluto (e ancora può accoglierli). Esso è stato aggiornato per funzionare correttamente con gli URL di FileSystem, così sostituendo `entry.fullPath` con `entry.toURL()` dovrebbe risolvere eventuali problemi ottenendo quel plugin per lavorare con i file nel dispositivo. - -In v 1.1.0 il valore restituito di `toURL()` è stato cambiato (vedere \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) per restituire un URL assoluto 'file://'. ove possibile. Per assicurare un ' cdvfile:'-URL, è possibile utilizzare `toInternalURL()` ora. Questo metodo restituirà ora filesystem URL del modulo - - cdvfile://localhost/persistent/path/to/file - - -che può essere utilizzato per identificare univocamente il file. - -## Elenco dei codici di errore e significati - -Quando viene generato un errore, uno dei seguenti codici da utilizzare. - -| Codice | Costante | -| ------:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Configurare il Plugin (opzionale) - -Il set di filesystem disponibili può essere configurato per ogni piattaforma. Sia iOS che Android riconoscere un <preference> Tag nel `file config. xml` che nomina il filesystem per essere installato. Per impostazione predefinita, tutte le radici del file system sono abilitate. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - -* `files`: directory di archiviazione di file interno dell'applicazione -* `files-external`: directory di archiviazione dell'applicazione file esterno -* `sdcard`: la directory di archiviazione di file esterni globale (questa è la radice della scheda SD, se uno è installato). È necessario disporre dell'autorizzazione `android.permission.WRITE_EXTERNAL_STORAGE` utilizzare questo. -* `cache`: la cache interna directory applicazione -* `cache-external`: directory di cache esterna dell'applicazione -* `root`: il dispositivo intero filesystem - -Android supporta anche un filesystem speciale denominato "documenti", che rappresenta una sottodirectory "/ documenti /" all'interno del filesystem "files". - -### iOS - -* `library`: la directory dell'applicazione libreria -* `documents`: la directory dell'applicazione documenti -* `cache`: la Cache directory applicazione -* `bundle`: bundle dell'applicazione; la posizione dell'app sul disco (sola lettura) -* `root`: il dispositivo intero filesystem - -Per impostazione predefinita, la directory di libreria e documenti può essere sincronizzata a iCloud. È anche possibile richiedere due filesystem aggiuntivi, `library-nosync` e `documents-nosync`, che rappresentano una speciale directory non sincronizzati entro il `/Library` o filesystem `/Documents`. diff --git a/plugins/cordova-plugin-file/doc/it/plugins.md b/plugins/cordova-plugin-file/doc/it/plugins.md deleted file mode 100644 index c02ca2f2..00000000 --- a/plugins/cordova-plugin-file/doc/it/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# Note per gli sviluppatori di plugin - -Queste note sono principalmente destinate agli sviluppatori di Android e iOS che vogliono scrivere plugin quale interfaccia con il sistema di file utilizzando il File del plugin. - -## Lavorare con file di Cordova sistema gli URL - -Dalla versione 1.0.0, questo plugin ha utilizzato gli URL con un `cdvfile` regime per tutte le comunicazioni oltre il ponte, piuttosto che esporre i percorsi del dispositivo raw file system a JavaScript. - -Sul lato JavaScript, questo significa che gli oggetti FileEntry e DirectoryEntry hanno un attributo fullPath che è relativo alla directory principale del sistema di file HTML. Se JavaScript API del vostro plugin accetta un oggetto FileEntry o DirectoryEntry, dovrebbe chiamare `.toURL()` su quell'oggetto prima di passarlo attraverso il ponte in codice nativo. - -### Conversione cdvfile: / / URL per percorsi fileystem - -Plugin che occorre scrivere al filesystem potrebbe voler convertire un URL del sistema file ricevuto in una filesystem effettiva posizione. Ci sono diversi modi di fare questo, a seconda della piattaforma nativa. - -È importante ricordare che non tutti i `cdvfile://` gli URL sono mappabili ai veri file sul dispositivo. Alcuni URL può riferirsi a beni sul dispositivo che non sono rappresentati da file, o possono anche riferirsi a risorse remote. A causa di queste possibilità, plugin dovrebbe sempre verificare se ottengono un risultato espressivo indietro quando si tenta di convertire gli URL in tracciati. - -#### Android - -Su Android, il metodo più semplice per convertire un `cdvfile://` URL a un percorso di file System è quello di utilizzare `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`dispone di diversi metodi in grado di gestire `cdvfile://` URL: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -È anche possibile utilizzare direttamente il File del plugin: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -Per convertire da un percorso a un `cdvfile://` URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -Se il tuo plugin crea un file e si desidera restituire un oggetto FileEntry per esso, utilizzare il File del plugin: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -Cordova su iOS non utilizza lo stesso `CordovaResourceApi` concetto come Android. Su iOS, è necessario utilizzare il File del plugin per la conversione tra URL e percorsi del file System. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -Se il tuo plugin crea un file e si desidera restituire un oggetto FileEntry per esso, utilizzare il File del plugin: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -In JavaScript, per ottenere un `cdvfile://` URL da un oggetto FileEntry o DirectoryEntry, semplicemente chiamare `.toURL()` su di esso: - - var cdvfileURL = entry.toURL(); - - -Nei gestori di risposta plugin, per convertire da una struttura FileEntry restituita in un oggetto effettivo della voce, il codice del gestore dovrebbe importare il File del plugin e creare un nuovo oggetto: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/ja/README.md b/plugins/cordova-plugin-file/doc/ja/README.md deleted file mode 100644 index 96e8ff0b..00000000 --- a/plugins/cordova-plugin-file/doc/ja/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -このプラグインは、デバイス上のファイルへの読み取り/書き込みアクセスを許可するファイル API を実装します。 - -このプラグインを含む、いくつかの仕様に基づいています:、HTML5 File API の<http://www.w3.org/TR/FileAPI/> - -(今は亡き) ディレクトリとシステムは、最新の拡張機能: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/>プラグインのコードのほとんどはときに、以前の仕様に書かれていたが現在は: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -FileWriter 仕様も実装しています: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -使用法を参照してください HTML5 岩 ' 優秀な[ファイルシステム記事](http://www.html5rocks.com/en/tutorials/file/filesystem/)。 - -他のストレージ オプションの概要については、コルドバの[ストレージ ・ ガイド](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html)を参照してください。. - -このプラグインでは、グローバル `cordova.file` オブジェクトを定義します。 - -グローバル スコープではあるがそれがないまで `deviceready` イベントの後です。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## インストール - - cordova plugin add cordova-plugin-file - - -## サポートされているプラットフォーム - - * アマゾン火 OS - * アンドロイド - * ブラックベリー 10 - * Firefox の OS - * iOS - * Windows Phone 7 と 8 * - * Windows 8 * - * Windows* - * ブラウザー - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## ファイルを保存する場所 - -V1.2.0、現在重要なファイル システム ディレクトリへの Url を提供しています。 各 URL はフォーム *file:///path/to/spot/* で、`window.resolveLocalFileSystemURL()` を使用する `DirectoryEntry` に変換することができます。. - - * `cordova.file.applicationDirectory`-読み取り専用のディレクトリは、アプリケーションがインストールされています。(*iOS*、*アンドロイド*、*ブラックベリー 10*) - - * `cordova.file.applicationStorageDirectory`-アプリケーションのサンド ボックス; のルート ディレクトリiOS でこの場所が読み取り専用 (特定のサブディレクトリが [のような `/Documents` ] は、読み取り/書き込み)。 内に含まれるすべてのデータは、アプリケーションにプライベートです。 ( *iOS*、*アンドロイド*、*ブラックベリー 10*) - - * `cordova.file.dataDirectory`内部メモリを使用して、アプリケーションのサンド ボックス内で永続なプライベート データ ストレージ (外部メモリを使用する必要がある場合使用して Android 上で `.externalDataDirectory` )。 IOS は、このディレクトリは iCloud と同期されません (使用する `.syncedDataDirectory` )。 (*iOS*、*アンドロイド*、*ブラックベリー 10*) - - * `cordova.file.cacheDirectory`-キャッシュされたデータ ファイルやアプリに簡単に再作成できる任意のファイルのディレクトリ。 ストレージ デバイスが不足したときに、OS がこれらのファイルを削除可能性があります、それにもかかわらず、アプリはここにファイルを削除する OS に依存しないでください。 (*iOS*、*アンドロイド*、*ブラックベリー 10*) - - * `cordova.file.externalApplicationStorageDirectory`外部ストレージのアプリケーション領域。(*アンドロイド*) - - * `cordova.file.externalDataDirectory`-外部ストレージ上のアプリ固有のデータ ファイルを配置する場所。(*アンドロイド*) - - * `cordova.file.externalCacheDirectory`外部ストレージにアプリケーション キャッシュ。(*アンドロイド*) - - * `cordova.file.externalRootDirectory`-外部ストレージ (SD カード) ルート。(*アンドロイド*、*ブラックベリー 10*) - - * `cordova.file.tempDirectory`-OS をクリアすることができます temp ディレクトリが。 このディレクトリ; オフに OS に依存しません。アプリが常に該当するファイルを削除します。 (*iOS*) - - * `cordova.file.syncedDataDirectory`-(例えば iCloud) に同期する必要がありますアプリケーション固有のファイルを保持します。(*iOS*) - - * `cordova.file.documentsDirectory`-ファイル、アプリケーションにプライベートは他のアプリケーション (Office ファイルなど) を意味です。(*iOS*) - - * `cordova.file.sharedDirectory`すべてのアプリケーション (*ブラックベリー 10*にグローバルに使用できるファイル) - -## ファイル ・ システム ・ レイアウト - -技術的に実装の詳細、非常にどのように `cordova.file.*` プロパティは、実際のデバイス上の物理パスにマップを知っておくと便利することができます。 - -### iOS ファイル システムのレイアウト - -| デバイス ・ パス | `cordova.file.*` | `iosExtraFileSystems` | r/w ですか? | 永続的なですか? | OS を消去します | 同期 | プライベート | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:--------:|:---------:|:------------:|:------:|:------:| -| `/var/モバイル/アプリケーション/< UUID >/` | applicationStorageDirectory | - | r | N/A | N/A | N/A | はい | -| `appname.app/` | ディレクトリ | バンドル | r | N/A | N/A | N/A | はい | -| `www/` | - | - | r | N/A | N/A | N/A | はい | -| `Documents/` | documentsDirectory | ドキュメント | r/w | はい | いいえ | はい | はい | -| `NoCloud/` | - | ドキュメント nosync | r/w | はい | いいえ | いいえ | はい | -| `Library` | - | ライブラリ | r/w | はい | いいえ | はいですか? | はい | -| `NoCloud/` | dataDirectory | ライブラリ nosync | r/w | はい | いいえ | いいえ | はい | -| `Cloud/` | syncedDataDirectory | - | r/w | はい | いいえ | はい | はい | -| `Caches/` | cacheDirectory | キャッシュ | r/w | はい * | はい**\* | いいえ | はい | -| `tmp/` | tempDirectory | - | r/w | いいえ** | はい**\* | いいえ | はい | - -\ * アプリ再起動やアップグレード、永続化ファイルしますが、OS を希望するたびに、このディレクトリを削除することができます。アプリは削除可能性があります任意のコンテンツを再現することができるはず。 - -**ファイルはアプリ再起動の間続くことがありますが、この動作に依存しないでください。 ファイルは、更新を維持するは保証されません。 アプリが該当する場合このディレクトリからファイルを削除する必要があります、これらのファイルが削除されるとき (または場合でも)、OS は保証しません。 - -**\ * OS はそれ、必要だと感じているときにこのディレクトリの内容を消去可能性があります、これに依存しないようにします。 この適切なディレクトリに、アプリケーションをオフにする必要があります。 - -### 人造人間ファイル ・ システム ・ レイアウト - -| デバイス ・ パス | `cordova.file.*` | `AndroidExtraFileSystems` | r/w ですか? | 永続的なですか? | OS を消去します | プライベート | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:--------:|:--------:|:---------:|:------:| -| `file:///android_asset/` | ディレクトリ | | r | N/A | N/A | はい | -| `/データ/データ/< app id >/` | applicationStorageDirectory | - | r/w | N/A | N/A | はい | -| `cache` | cacheDirectory | キャッシュ | r/w | はい | はい\ * | はい | -| `files` | dataDirectory | ファイル | r/w | はい | いいえ | はい | -| `Documents` | | ドキュメント | r/w | はい | いいえ | はい | -| `< sd カード >/` | externalRootDirectory | sd カード | r/w | はい | いいえ | いいえ | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | はい | いいえ | いいえ | -| `cache` | externalCacheDirectry | 外部キャッシュ | r/w | はい | いいえ** | いいえ | -| `files` | externalDataDirectory | 外部ファイル | r/w | はい | いいえ | いいえ | - -\ * OS は定期的にこのディレクトリを消去可能性がありますが、この動作に依存しないでください。 アプリケーションの必要に応じてこのディレクトリの内容をオフにします。 ユーザーは手動でキャッシュを削除する必要があります、このディレクトリの内容が削除されます。 - -** OS はこのディレクトリを自動的にはクリアされません内容を自分で管理する責任があります。 ユーザは手動でキャッシュを消去する必要があります、ディレクトリの内容が削除されます。 - -**注**: 外部記憶装置をマウントできない場合は、`cordova.file.external*` プロパティを `null`. - -### ブラックベリー 10 ファイル ・ システム ・ レイアウト - -| デバイス ・ パス | `cordova.file.*` | r/w ですか? | 永続的なですか? | OS を消去します | プライベート | -|:----------------------------------------------------------- |:--------------------------- |:--------:|:--------:|:---------:|:------:| -| `file:///accounts/1000/appdata/< app id >/` | applicationStorageDirectory | r | N/A | N/A | はい | -| `app/native` | ディレクトリ | r | N/A | N/A | はい | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | いいえ | はい | はい | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | はい | いいえ | はい | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | はい | いいえ | いいえ | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | はい | いいえ | いいえ | - -*注*: すべてのパスは/accounts/1000-enterprise 基準に境界を動作するようにアプリケーションを展開するとき。 - -## Android の癖 - -### Android の永続的なストレージの場所 - -Android のデバイスに永続的なファイルを格納する複数の有効な場所があります。 さまざまな可能性について広範な議論のための [このページ](http://developer.android.com/guide/topics/data/data-storage.html) を参照してください。 - -以前のバージョンのプラグインは、デバイスの SD カード (または同等のストレージ パーティション) マウントされていたと主張したかどうかに基づいて、起動時に一時と永続的なファイルの場所を選ぶでしょう。 SD カードがマウントされている場合、または大規模な内部ストレージ パーティションが利用可能な場合 (ようネクサス デバイス上) し、永続的なファイルは、その領域のルートに格納されます。 これはすべての Cordova アプリ見ることができる利用可能なファイルのすべてのカードに意味しました。 - -SD カードがない場合、以前のバージョンがデータを格納する `/data/data/<packageId>`、お互いからアプリを分離するが、まだ原因可能性がありますユーザー間で共有するデータ。 - -内部ファイルの保存場所やアプリケーションの `config.xml` ファイルに優先順位を持つ以前のロジックを使用してファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。 - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -この行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。 - -アプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0) を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを彼らの装置によって、以前に保存されたファイルにアクセスすることができることがあることを意味する「内部」に場所をスイッチングします。 - -アプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`内部` 設定一般的に推奨されます。 - -### /Android_asset の低速の再帰的な操作 - -アセット ディレクトリの一覧表示は、人造人間本当に遅いです。 それをスピードアップすることができます`src/android/build-extras.gradle`を android プロジェクトのルートに追加することによって、最大 (また cordova-android@4.0.0 が必要ですまたはそれ以上)。 - -## iOS の癖 - - * `cordova.file.applicationStorageDirectory`読み取り専用;ルート ディレクトリ内のファイルを保存しようは失敗します。 他の 1 つを使用して `cordova.file.*` iOS のため定義されているプロパティ (のみ `applicationDirectory` と `applicationStorageDirectory` は読み取り専用)。 - * `FileReader.readAsText(blob, encoding)` - * `encoding`パラメーターはサポートされていませんし、utf-8 エンコーディングが常に有効です。 - -### iOS の永続的なストレージの場所 - -IOS デバイスに永続的なファイルを格納する 2 つの有効な場所がある: ドキュメントとライブラリのディレクトリ。 プラグインの以前のバージョンは、唯一のこれまでドキュメント ディレクトリに永続的なファイルを格納されます。 これは、ディレクトリの目的は、輸出のための完全なドキュメントを作成するのではなくなかったがしばしば意図されていたり、特に多数の小さいファイルを処理するアプリケーションの場合、iTunes に表示されているすべてのアプリケーションのファイルを作るの副作用があった。 - -ドキュメントまたはアプリケーションの `config.xml` ファイルに優先順位のライブラリ ディレクトリにファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。 - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -この行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。 - -アプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0) を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを以前に保存されたファイルにアクセスすることができるだろうことを意味する `Library` に場所をスイッチングします。 - -アプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`Library` 設定一般的に推奨されます。 - -## Firefox OS 癖 - -ファイル システム API Firefox OS でネイティブ サポートされていないと、indexedDB の上にシムとして実装されています。 - - * 空でないディレクトリを削除するときに失敗しません - * ディレクトリのメタデータをサポートしていません - * 方法 `copyTo` と `moveTo` ディレクトリをサポートしていません - -次のデータ パスがサポートされています: * `applicationDirectory` - `xhr` を使用して、アプリケーションと共にパッケージ化されるローカル ファイルを取得します。 * `dataDirectory` - 永続的なアプリケーション固有のデータ ファイル。 * `cacheDirectory` - アプリケーションの再起動後も維持する必要がありますキャッシュ ファイル (アプリはここにファイルを削除する OS に依存しないでください)。 - -## ブラウザーの癖 - -### 共通の癖と発言 - - * 各ブラウザーはサンド ボックス化されたファイルシステムを使用します。IE と Firefox IndexedDB をベースとして使用します。すべてのブラウザーは、パスにディレクトリの区切り記号としてスラッシュを使用します。 - * ディレクトリ エントリは連続して作成されなければなりません。 たとえば、コール `fs.root.getDirectory ('dir1 dir2'、{create:true}、successCallback、解り)` dir1 が存在しなかった場合は失敗します。 - * プラグインは、永続的なストレージ アプリケーションの最初の起動時に使用するユーザーのアクセス許可を要求します。 - * プラグインは、`cdvfile://localhost` (ローカル リソース) をサポートしているだけです。すなわち外部リソースは、`cdvfile` を介してサポートされていません. - * プラグインに [制限」のファイル システム API の 8.3 命名規則](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions) に従っていません。. - * Blob およびファイル ' `close` 関数はサポートされていません。 - * `FileSaver` と `BlobBuilder` このプラグインでサポートされていないスタブを持っていません。 - * プラグインは、`requestAllFileSystems` をサポートしません。この関数は、仕様で行方不明にも。 - * ディレクトリ内のエントリを使用すると削除されません `create: true` 既存ディレクトリのフラグ。 - * コンス トラクターで作成されたファイルはサポートされていません。代わりに entry.file メソッドを使用する必要があります。 - * 各ブラウザーは blob URL 参照の独自のフォームを使用します。 - * `readAsDataURL` 関数はサポートされてがクロムメッキで mediatype エントリ名の拡張子によって異なります、IE でメディアの種類は、常に空 (`text-plain` に従って、仕様と同じである)、Firefox でメディアの種類は常に `アプリケーションまたはオクテット-ストリーム`。 たとえば、コンテンツが場合 `abcdefg` し Firefox を返します `データ: アプリケーション/オクテット ストリーム、base64、YWJjZGVmZw = =`、すなわちを返します `データ:; base64、YWJjZGVmZw = =`、クロムを返します `データ: < エントリ名の拡張子によって mediatype >; base64、YWJjZGVmZw = =`. - * `toInternalURL` フォーム `file:///persistent/path/to/entry` (Firefox、IE) のパスを返します。 クロムの `cdvfile://localhost/persistent/file` フォームのパスを返します. - -### クロムの癖 - - * デバイスの準備ができているイベント後クローム ファイルシステムはすぐに準備ができています。回避策としては `filePluginIsReady` イベントにサブスクライブできます。例: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -`window.isFilePluginReadyRaised` 関数を使用して、イベントが既に発生したかどうかを確認できます。 -Chrome に window.requestFileSystem 一時と永続的なファイル ・ システムのクォータの制限はありません。 -クロム内の永続ストレージを増加する `window.initPersistentFileSystem` メソッドを呼び出す必要があります。 永続的な記憶域のクォータは、既定では 5 MB です。 クロムが必要です `--許可-ファイル-アクセス--ファイルから` `file:///` プロトコル経由でサポート API に引数を実行します。 -`ファイル` オブジェクト フラグを使用する場合ない変更されます `{create:true}` 既存の `エントリ` を取得するとき。 -イベント `cancelable` プロパティを設定するクロムの場合は true。 これは [仕様](http://dev.w3.org/2009/dap/file-system/file-writer.html) に反して。 -クロムメッキで `網` 関数を返します `ファイルシステム:`-アプリケーションのホストによってパスのプレフィックスします。 たとえば、`filesystem:file:///persistent/somefile.txt`、`filesystem:http://localhost:8080/persistent/somefile.txt`。 -`toURL` の関数の結果にはディレクトリ エントリ場合末尾にスラッシュが含まれていません。 クロムは、スラッシュ後塵 url を持つディレクトリが正しく解決されるも。 -`resolveLocalFileSystemURL` メソッドは、受信 `url` が `ファイルシステム` のプレフィックスが必要です。 たとえば、`resolveLocalFileSystemURL` の `url` パラメーター フォーム `filesystem:file:///persistent/somefile.txt` で人造人間フォーム `file:///persistent/somefile.txt` とは対照的にする必要があります。 -廃止された `toNativeURL` 関数はサポートされていません、スタブはありません。 -`setMetadata` 関数は、仕様に記載されていないありサポートされていません。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた SYNTAX_ERR(code: 8) の非実在しないファイルシステムの依頼を。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた PATH_EXISTS_ERR(code: 12)、排他的なファイルまたはディレクトリを作成しようとするが既に存在します。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた NO_MODIFICATION_ALLOWED_ERR(code: 6) ルート ・ ファイル ・ システムで removeRecursively を呼び出すをしようとして。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた NOT_FOUND_ERR(code: 1) [moveto] ディレクトリが存在しないをしようとして。 - -### IndexedDB ベース インプレ癖 (Firefox と IE) - - * `.` `です。` はサポートされていません。 - * IE は `file:///` をサポートしていません-モード;ホスト モードのみがサポートされている (http://localhost:xxxx) です。 - * Firefox のファイルシステムのサイズは無制限ですが各 50 MB の拡張機能がユーザーのアクセス許可を要求します。 IE10 は最大 10 mb の複合 AppCache と IndexedDB を求めず、サイトごとに 250 mb の最大値まで増加を許可するかどうかをたずねられますそのレベルに当ればファイルシステムの実装で使用することができます。 `RequestFileSystem` 関数の `size` パラメーターは、Firefox と IE のファイルシステムには影響しません。 - * `readAsBinaryString` 関数の仕様に記載されていない、IE でサポートされていないと、スタブを持っていません。 - * `file.type` は、常に null です。 - * 削除された DirectoryEntry インスタンスのコールバックの結果を使用してエントリを作成しないでください。それ以外の場合は、'ハンギングのエントリ' が表示されます。 - * ちょうど書かれていた、ファイルを読むことができます前にこのファイルの新しいインスタンスを取得する必要があります。 - * `setMetadata` 関数は、仕様に記載されていない `modificationTime` フィールド変更のみをサポートします。 - * `copyTo` と `moveTo` 関数ディレクトリをサポートしていません。 - * ディレクトリのメタデータはサポートされていません。 - * 両方の Entry.remove と directoryEntry.removeRecursively は空でないディレクトリを削除するときを失敗しない - 削除されるディレクトリ コンテンツと共にを掃除している代わりに。 - * `abort` し、`truncate` 機能はサポートされていません。 - * 進行状況イベントは起動しません。たとえば、このハンドラーがない実行されます。 - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## ノートをアップグレードします。 - -このプラグインのデベロッパー、公開された仕様に合うように、`認証` と `DirectoryEntry` の構造が変更されました。 - -プラグインの前 (pre 1.0.0) バージョンはデバイス絶対ファイル場所 `エントリ` オブジェクトの `fullPath` プロパティに格納されます。これらのパスはようになります通常 - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -これらのパスはまた `Entry` オブジェクトの `toURL()` メソッドによって返されます。 - -デベロッパー、`fullPath` 属性は *HTML ファイルシステムのルートに対する相対パス* のファイルへのパス。 したがって、上記のパスは今両方の `fullPath` と `FileEntry` オブジェクトで表される - - /path/to/file - - -デバイス絶対パスとアプリケーション動作以前 `Entry` オブジェクトの `fullPath` プロパティを使用してこれらのパスを取得した場合は、代わりに `entry.toURL()` を使用するコードを更新する必要があります。 - -下位互換性、`resolveLocalFileSystemURL()` メソッドは、デバイス絶対パスを受け入れるし、は、`TEMPORARY` または `PERSISTENT` ファイル ・ システム内でそのファイルが存在する限り、それに対応する `Entry` オブジェクトを返します。 - -これは特に以前デバイス絶対パスを使用してファイル転送のプラグインで問題となっている (そしてまだそれらを受け入れることができます)。 それがデバイス上のファイルで動作するプラグインを得る問題を解決する必要があります `entry.toURL()` で `entry.fullPath` を置き換えるので、ファイルシステムの Url で正常に動作にアップデートされました。 - -V1.1.0 の `toURL()` の戻り値に変更されました (\[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394) を参照) を絶対 'file://' で始まる URL を返します。 可能な限り。 確保するために、' cdvfile:'-`toInternalURL()` を今すぐ使用できます URL。 このメソッドは、フォームのファイルシステムの Url を返します今 - - cdvfile://localhost/persistent/path/to/file - - -これはファイルを一意に識別するために使用できます。 - -## エラー コードと意味のリスト - -エラーがスローされると、次のコードのいずれかが使用されます。 - -| コード | 定数 | -| ---:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## (省略可能) プラグインを構成します。 - -利用可能なファイルシステムのセットは構成されたプラットフォームをすることができます。IOS と Android の両方を認識します。 <preference> タグ `config.xml` をインストールするファイルシステムの名前します。既定では、すべてのファイル システムのルートが有効になります。 - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### アンドロイド - - * `files`: アプリケーションの内部ファイルのストレージ ディレクトリ - * `files-external`: アプリケーションの外部のファイルのストレージ ディレクトリ - * `sdcard`:、グローバル外部ストレージ ディレクトリをファイル (これは SD カードのルートがインストールされている場合)。 これを使用するには、`android.permission.WRITE_EXTERNAL_STORAGE` 権限が必要です。 - * `cache`: アプリケーションの内部キャッシュ ディレクトリ - * `cache-external`: 外部キャッシュのアプリケーションのディレクトリ - * `root`: デバイス全体のファイルシステム - -アンドロイドを「ファイル」ファイルシステム内の"ドキュメント/"サブディレクトリを表す"ドキュメント"という名前の特殊なファイルシステムもサポートしています。 - -### iOS - - * `library`: ライブラリのアプリケーションのディレクトリ - * `documents`: ドキュメントのアプリケーションのディレクトリ - * `cache`: キャッシュのアプリケーションのディレクトリ - * `bundle`: アプリケーションバンドル;アプリ自体 (読み取りのみ) ディスク上の場所 - * `root`: デバイス全体のファイルシステム - -既定では、ライブラリとドキュメント ディレクトリを iCloud に同期できます。 2 つの追加のファイルシステム、`library-nosync` および `documents-nosync` を表す、特別な非同期ディレクトリ内を要求することもできます、`/Library` または `Documents/` ファイルシステム。
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/ja/index.md b/plugins/cordova-plugin-file/doc/ja/index.md deleted file mode 100644 index 57fb7d29..00000000 --- a/plugins/cordova-plugin-file/doc/ja/index.md +++ /dev/null @@ -1,338 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -このプラグインは、デバイス上のファイルへの読み取り/書き込みアクセスを許可するファイル API を実装します。 - -このプラグインを含む、いくつかの仕様に基づいています:、HTML5 File API の<http://www.w3.org/TR/FileAPI/> - -(今は亡き) ディレクトリとシステムは、最新の拡張機能: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/>プラグインのコードのほとんどはときに、以前の仕様に書かれていたが現在は: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -FileWriter 仕様も実装しています: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -使用法を参照してください HTML5 岩 ' 優秀な[ファイルシステム記事][1]。 - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -他のストレージ オプションの概要については、コルドバの[ストレージ ・ ガイド][2]を参照してください。. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -このプラグインでは、グローバル `cordova.file` オブジェクトを定義します。 - -グローバル スコープではあるがそれがないまで `deviceready` イベントの後です。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## インストール - - cordova plugin add cordova-plugin-file - - -## サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* ブラックベリー 10 -* Firefox の OS -* iOS -* Windows Phone 7 と 8 * -* Windows 8 * -* ブラウザー - -* *`FileReader.readAsArrayBuffer` も `FileWriter.write(blob)` もこれらのプラットフォームはサポートしていません*。 - -## ファイルを保存する場所 - -V1.2.0、現在重要なファイル システム ディレクトリへの Url を提供しています。 各 URL はフォーム *file:///path/to/spot/* で、`window.resolveLocalFileSystemURL()` を使用する `DirectoryEntry` に変換することができます。. - -* `cordova.file.applicationDirectory`-読み取り専用のディレクトリは、アプリケーションがインストールされています。(*iOS*、*アンドロイド*、*ブラックベリー 10*) - -* `cordova.file.applicationStorageDirectory`-アプリケーションのサンド ボックス; のルート ディレクトリiOS でこの場所が読み取り専用 (特定のサブディレクトリが [のような `/Documents` ] は、読み取り/書き込み)。 内に含まれるすべてのデータは、アプリケーションにプライベートです。 ( *iOS*、*アンドロイド*、*ブラックベリー 10*) - -* `cordova.file.dataDirectory`内部メモリを使用して、アプリケーションのサンド ボックス内で永続なプライベート データ ストレージ (外部メモリを使用する必要がある場合使用して Android 上で `.externalDataDirectory` )。 IOS は、このディレクトリは iCloud と同期されません (使用する `.syncedDataDirectory` )。 (*iOS*、*アンドロイド*、*ブラックベリー 10*) - -* `cordova.file.cacheDirectory`-キャッシュされたデータ ファイルやアプリに簡単に再作成できる任意のファイルのディレクトリ。 ストレージ デバイスが不足したときに、OS がこれらのファイルを削除可能性があります、それにもかかわらず、アプリはここにファイルを削除する OS に依存しないでください。 (*iOS*、*アンドロイド*、*ブラックベリー 10*) - -* `cordova.file.externalApplicationStorageDirectory`外部ストレージのアプリケーション領域。(*アンドロイド*) - -* `cordova.file.externalDataDirectory`-外部ストレージ上のアプリ固有のデータ ファイルを配置する場所。(*アンドロイド*) - -* `cordova.file.externalCacheDirectory`外部ストレージにアプリケーション キャッシュ。(*アンドロイド*) - -* `cordova.file.externalRootDirectory`-外部ストレージ (SD カード) ルート。(*アンドロイド*、*ブラックベリー 10*) - -* `cordova.file.tempDirectory`-OS をクリアすることができます temp ディレクトリが。 このディレクトリ; オフに OS に依存しません。アプリが常に該当するファイルを削除します。 (*iOS*) - -* `cordova.file.syncedDataDirectory`-(例えば iCloud) に同期する必要がありますアプリケーション固有のファイルを保持します。(*iOS*) - -* `cordova.file.documentsDirectory`-ファイル、アプリケーションにプライベートは他のアプリケーション (Office ファイルなど) を意味です。(*iOS*) - -* `cordova.file.sharedDirectory`すべてのアプリケーション (*ブラックベリー 10*にグローバルに使用できるファイル) - -## ファイル ・ システム ・ レイアウト - -技術的に実装の詳細、非常にどのように `cordova.file.*` プロパティは、実際のデバイス上の物理パスにマップを知っておくと便利することができます。 - -### iOS ファイル システムのレイアウト - -| デバイス ・ パス | `cordova.file.*` | `iosExtraFileSystems` | r/w ですか? | 永続的なですか? | OS を消去します | 同期 | プライベート | -|:------------------------------------ |:--------------------------- |:--------------------- |:--------:|:--------:|:----------:|:------:|:------:| -| `/var/モバイル/アプリケーション/< UUID >/` | applicationStorageDirectory | - | r | N/A | N/A | N/A | はい | -| `appname.app/` | ディレクトリ | バンドル | r | N/A | N/A | N/A | はい | -| `www/` | - | - | r | N/A | N/A | N/A | はい | -| `Documents/` | documentsDirectory | ドキュメント | r/w | はい | いいえ | はい | はい | -| `NoCloud/` | - | ドキュメント nosync | r/w | はい | いいえ | いいえ | はい | -| `Library` | - | ライブラリ | r/w | はい | いいえ | はいですか? | はい | -| `NoCloud/` | dataDirectory | ライブラリ nosync | r/w | はい | いいえ | いいえ | はい | -| `Cloud/` | syncedDataDirectory | - | r/w | はい | いいえ | はい | はい | -| `Caches/` | cacheDirectory | キャッシュ | r/w | はい * | はい * * *| | いいえ | はい | -| `tmp/` | tempDirectory | - | r/w | いいえ * * | はい * * *| | いいえ | はい | - -* アプリを再起動し、アップグレードとの間でファイルを保持が、OS を希望するたびにこのディレクトリを削除することができます。アプリを削除可能性があります任意のコンテンツを再作成することができる必要があります。 - -* * ファイル アプリケーション再起動を渡って続くことがありますが、この動作に依存しないでください。 ファイルは、更新を維持するは保証されません。 アプリが該当する場合このディレクトリからファイルを削除する必要があります、これらのファイルが削除されるとき (または場合でも)、OS は保証しません。 - -* * *| OS はそれ、必要だと感じているときにこのディレクトリの内容を消去可能性がありますが、これに依存しません。 この適切なディレクトリに、アプリケーションをオフにする必要があります。 - -### 人造人間ファイル ・ システム ・ レイアウト - -| デバイス ・ パス | `cordova.file.*` | `AndroidExtraFileSystems` | r/w ですか? | 永続的なですか? | OS を消去します | プライベート | -|:--------------------------------- |:----------------------------------- |:------------------------- |:--------:|:--------:|:---------:|:------:| -| `file:///android_asset/` | ディレクトリ | | r | N/A | N/A | はい | -| `/データ/データ/< app id >/` | applicationStorageDirectory | - | r/w | N/A | N/A | はい | -| `cache` | cacheDirectory | キャッシュ | r/w | はい | はい * | はい | -| `files` | dataDirectory | ファイル | r/w | はい | いいえ | はい | -| `Documents` | | ドキュメント | r/w | はい | いいえ | はい | -| `< sd カード >/` | externalRootDirectory | sd カード | r/w | はい | いいえ | いいえ | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | はい | いいえ | いいえ | -| `cache` | externalCacheDirectry | 外部キャッシュ | r/w | はい | いいえ * * | いいえ | -| `files` | externalDataDirectory | 外部ファイル | r/w | はい | いいえ | いいえ | - -* OS このディレクトリを定期的に消去可能性がありますが、この動作に依存しないでください。 アプリケーションの必要に応じてこのディレクトリの内容をオフにします。 ユーザーは手動でキャッシュを削除する必要があります、このディレクトリの内容が削除されます。 - -* * OS はこのディレクトリは自動的にクリアされません自分でコンテンツを管理するために責任があります。 ユーザは手動でキャッシュを消去する必要があります、ディレクトリの内容が削除されます。 - -**注**: 外部記憶装置をマウントできない場合は、`cordova.file.external*` プロパティを `null`. - -### ブラックベリー 10 ファイル ・ システム ・ レイアウト - -| デバイス ・ パス | `cordova.file.*` | r/w ですか? | 永続的なですか? | OS を消去します | プライベート | -|:------------------------------------------------- |:--------------------------- |:--------:|:--------:|:---------:|:------:| -| `file:///accounts/1000/appdata/< app id >/` | applicationStorageDirectory | r | N/A | N/A | はい | -| `app/native` | ディレクトリ | r | N/A | N/A | はい | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | いいえ | はい | はい | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | はい | いいえ | はい | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | はい | いいえ | いいえ | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | はい | いいえ | いいえ | - -*注*: すべてのパスは/accounts/1000-enterprise 基準に境界を動作するようにアプリケーションを展開するとき。 - -## Android の癖 - -### Android の永続的なストレージの場所 - -Android のデバイスに永続的なファイルを格納する複数の有効な場所があります。 さまざまな可能性について広範な議論のための [このページ][3] を参照してください。 - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -以前のバージョンのプラグインは、デバイスの SD カード (または同等のストレージ パーティション) マウントされていたと主張したかどうかに基づいて、起動時に一時と永続的なファイルの場所を選ぶでしょう。 SD カードがマウントされている場合、または大規模な内部ストレージ パーティションが利用可能な場合 (ようネクサス デバイス上) し、永続的なファイルは、その領域のルートに格納されます。 これはすべての Cordova アプリ見ることができる利用可能なファイルのすべてのカードに意味しました。 - -SD カードがない場合、以前のバージョンがデータを格納する `/data/data/<packageId>`、お互いからアプリを分離するが、まだ原因可能性がありますユーザー間で共有するデータ。 - -内部ファイルの保存場所やアプリケーションの `config.xml` ファイルに優先順位を持つ以前のロジックを使用してファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。 - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -この行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。 - -アプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0) を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを彼らの装置によって、以前に保存されたファイルにアクセスすることができることがあることを意味する「内部」に場所をスイッチングします。 - -アプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`内部` 設定一般的に推奨されます。 - -## iOS の癖 - -* `cordova.file.applicationStorageDirectory`読み取り専用;ルート ディレクトリ内のファイルを保存しようは失敗します。 他の 1 つを使用して `cordova.file.*` iOS のため定義されているプロパティ (のみ `applicationDirectory` と `applicationStorageDirectory` は読み取り専用)。 -* `FileReader.readAsText(blob, encoding)` - * `encoding`パラメーターはサポートされていませんし、utf-8 エンコーディングが常に有効です。 - -### iOS の永続的なストレージの場所 - -IOS デバイスに永続的なファイルを格納する 2 つの有効な場所がある: ドキュメントとライブラリのディレクトリ。 プラグインの以前のバージョンは、唯一のこれまでドキュメント ディレクトリに永続的なファイルを格納されます。 これは、ディレクトリの目的は、輸出のための完全なドキュメントを作成するのではなくなかったがしばしば意図されていたり、特に多数の小さいファイルを処理するアプリケーションの場合、iTunes に表示されているすべてのアプリケーションのファイルを作るの副作用があった。 - -ドキュメントまたはアプリケーションの `config.xml` ファイルに優先順位のライブラリ ディレクトリにファイルを保存するかどうかを選択することが可能です今。 これを行うに、`config.xml` に次の 2 行のいずれかを追加します。 - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -この行がなければファイル プラグインはデフォルトとして `Compatibility` を使用します。優先タグが存在し、これらの値の 1 つではない場合、アプリケーションは起動しません。 - -アプリケーションは、ユーザーに以前出荷されている場合、古い (前 1.0) を使用して、このプラグインのバージョンし、永続的なファイルシステムに保存されているファイルには `Compatibility` を設定する必要があります。 自分のアプリケーションをアップグレードする既存のユーザーを以前に保存されたファイルにアクセスすることができるだろうことを意味する `Library` に場所をスイッチングします。 - -アプリケーションは、新しい、または永続的なファイルシステムにファイルが格納され以前は決して場合、`Library` 設定一般的に推奨されます。 - -## Firefox OS 癖 - -ファイル システム API Firefox OS でネイティブ サポートされていないと、indexedDB の上にシムとして実装されています。 - -* 空でないディレクトリを削除するときに失敗しません -* ディレクトリのメタデータをサポートしていません -* 方法 `copyTo` と `moveTo` ディレクトリをサポートしていません - -次のデータ パスがサポートされています: * `applicationDirectory` - `xhr` を使用して、アプリケーションと共にパッケージ化されるローカル ファイルを取得します。 * `dataDirectory` - 永続的なアプリケーション固有のデータ ファイル。 * `cacheDirectory` - アプリケーションの再起動後も維持する必要がありますキャッシュ ファイル (アプリはここにファイルを削除する OS に依存しないでください)。 - -## ブラウザーの癖 - -### 共通の癖と発言 - -* 各ブラウザーはサンド ボックス化されたファイルシステムを使用します。IE と Firefox IndexedDB をベースとして使用します。すべてのブラウザーは、パスにディレクトリの区切り記号としてスラッシュを使用します。 -* ディレクトリ エントリは連続して作成されなければなりません。 たとえば、コール `fs.root.getDirectory ('dir1 dir2'、{create:true}、successCallback、解り)` dir1 が存在しなかった場合は失敗します。 -* プラグインは、永続的なストレージ アプリケーションの最初の起動時に使用するユーザーのアクセス許可を要求します。 -* プラグインは、`cdvfile://localhost` (ローカル リソース) をサポートしているだけです。すなわち外部リソースは、`cdvfile` を介してサポートされていません. -* プラグインに [制限」のファイル システム API の 8.3 命名規則][4] に従っていません。. -* Blob およびファイル ' `close` 関数はサポートされていません。 -* `FileSaver` と `BlobBuilder` このプラグインでサポートされていないスタブを持っていません。 -* プラグインは、`requestAllFileSystems` をサポートしません。この関数は、仕様で行方不明にも。 -* ディレクトリ内のエントリを使用すると削除されません `create: true` 既存ディレクトリのフラグ。 -* コンス トラクターで作成されたファイルはサポートされていません。代わりに entry.file メソッドを使用する必要があります。 -* 各ブラウザーは blob URL 参照の独自のフォームを使用します。 -* `readAsDataURL` 関数はサポートされてがクロムメッキで mediatype エントリ名の拡張子によって異なります、IE でメディアの種類は、常に空 (`text-plain` に従って、仕様と同じである)、Firefox でメディアの種類は常に `アプリケーションまたはオクテット-ストリーム`。 たとえば、コンテンツが場合 `abcdefg` し Firefox を返します `データ: アプリケーション/オクテット ストリーム、base64、YWJjZGVmZw = =`、すなわちを返します `データ:; base64、YWJjZGVmZw = =`、クロムを返します `データ: < エントリ名の拡張子によって mediatype >; base64、YWJjZGVmZw = =`. -* `toInternalURL` フォーム `file:///persistent/path/to/entry` (Firefox、IE) のパスを返します。 クロムの `cdvfile://localhost/persistent/file` フォームのパスを返します. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### クロムの癖 - -* デバイスの準備ができているイベント後クローム ファイルシステムはすぐに準備ができています。回避策としては `filePluginIsReady` イベントにサブスクライブできます。例: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -`window.isFilePluginReadyRaised` 関数を使用して、イベントが既に発生したかどうかを確認できます。 -Chrome に window.requestFileSystem 一時と永続的なファイル ・ システムのクォータの制限はありません。 -クロム内の永続ストレージを増加する `window.initPersistentFileSystem` メソッドを呼び出す必要があります。 永続的な記憶域のクォータは、既定では 5 MB です。 クロムが必要です `--許可-ファイル-アクセス--ファイルから` `file:///` プロトコル経由でサポート API に引数を実行します。 -`ファイル` オブジェクト フラグを使用する場合ない変更されます `{create:true}` 既存の `エントリ` を取得するとき。 -イベント `cancelable` プロパティを設定するクロムの場合は true。 これは [仕様][5] に反して。 -クロムメッキで `網` 関数を返します `ファイルシステム:`-アプリケーションのホストによってパスのプレフィックスします。 たとえば、`filesystem:file:///persistent/somefile.txt`、`filesystem:http://localhost:8080/persistent/somefile.txt`。 -`toURL` の関数の結果にはディレクトリ エントリ場合末尾にスラッシュが含まれていません。 クロムは、スラッシュ後塵 url を持つディレクトリが正しく解決されるも。 -`resolveLocalFileSystemURL` メソッドは、受信 `url` が `ファイルシステム` のプレフィックスが必要です。 たとえば、`resolveLocalFileSystemURL` の `url` パラメーター フォーム `filesystem:file:///persistent/somefile.txt` で人造人間フォーム `file:///persistent/somefile.txt` とは対照的にする必要があります。 -廃止された `toNativeURL` 関数はサポートされていません、スタブはありません。 -`setMetadata` 関数は、仕様に記載されていないありサポートされていません。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた SYNTAX_ERR(code: 8) の非実在しないファイルシステムの依頼を。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた PATH_EXISTS_ERR(code: 12)、排他的なファイルまたはディレクトリを作成しようとするが既に存在します。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた NO_MODIFICATION_ALLOWED_ERR(code: 6) ルート ・ ファイル ・ システムで removeRecursively を呼び出すをしようとして。 -INVALID_MODIFICATION_ERR (コード: 9) の代わりにスローされた NOT_FOUND_ERR(code: 1) [moveto] ディレクトリが存在しないをしようとして。 - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### IndexedDB ベース インプレ癖 (Firefox と IE) - -* `.` `です。` はサポートされていません。 -* IE は `file:///` をサポートしていません-モード;ホスト モードのみがサポートされている (http://localhost:xxxx) です。 -* Firefox のファイルシステムのサイズは無制限ですが各 50 MB の拡張機能がユーザーのアクセス許可を要求します。 IE10 は最大 10 mb の複合 AppCache と IndexedDB を求めず、サイトごとに 250 mb の最大値まで増加を許可するかどうかをたずねられますそのレベルに当ればファイルシステムの実装で使用することができます。 `RequestFileSystem` 関数の `size` パラメーターは、Firefox と IE のファイルシステムには影響しません。 -* `readAsBinaryString` 関数の仕様に記載されていない、IE でサポートされていないと、スタブを持っていません。 -* `file.type` は、常に null です。 -* 削除された DirectoryEntry インスタンスのコールバックの結果を使用してエントリを作成しないでください。それ以外の場合は、'ハンギングのエントリ' が表示されます。 -* ちょうど書かれていた、ファイルを読むことができます前にこのファイルの新しいインスタンスを取得する必要があります。 -* `setMetadata` 関数は、仕様に記載されていない `modificationTime` フィールド変更のみをサポートします。 -* `copyTo` と `moveTo` 関数ディレクトリをサポートしていません。 -* ディレクトリのメタデータはサポートされていません。 -* 両方の Entry.remove と directoryEntry.removeRecursively は空でないディレクトリを削除するときを失敗しない - 削除されるディレクトリ コンテンツと共にを掃除している代わりに。 -* `abort` し、`truncate` 機能はサポートされていません。 -* 進行状況イベントは起動しません。たとえば、このハンドラーがない実行されます。 - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## ノートをアップグレードします。 - -このプラグインのデベロッパー、公開された仕様に合うように、`認証` と `DirectoryEntry` の構造が変更されました。 - -プラグインの前 (pre 1.0.0) バージョンはデバイス絶対ファイル場所 `エントリ` オブジェクトの `fullPath` プロパティに格納されます。これらのパスはようになります通常 - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -これらのパスはまた `Entry` オブジェクトの `toURL()` メソッドによって返されます。 - -デベロッパー、`fullPath` 属性は *HTML ファイルシステムのルートに対する相対パス* のファイルへのパス。 したがって、上記のパスは今両方の `fullPath` と `FileEntry` オブジェクトで表される - - /path/to/file - - -デバイス絶対パスとアプリケーション動作以前 `Entry` オブジェクトの `fullPath` プロパティを使用してこれらのパスを取得した場合は、代わりに `entry.toURL()` を使用するコードを更新する必要があります。 - -下位互換性、`resolveLocalFileSystemURL()` メソッドは、デバイス絶対パスを受け入れるし、は、`TEMPORARY` または `PERSISTENT` ファイル ・ システム内でそのファイルが存在する限り、それに対応する `Entry` オブジェクトを返します。 - -これは特に以前デバイス絶対パスを使用してファイル転送のプラグインで問題となっている (そしてまだそれらを受け入れることができます)。 それがデバイス上のファイルで動作するプラグインを得る問題を解決する必要があります `entry.toURL()` で `entry.fullPath` を置き換えるので、ファイルシステムの Url で正常に動作にアップデートされました。 - -V1.1.0 の `toURL()` の戻り値に変更されました (\[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394) を参照) を絶対 'file://' で始まる URL を返します。 可能な限り。 確保するために、' cdvfile:'-`toInternalURL()` を今すぐ使用できます URL。 このメソッドは、フォームのファイルシステムの Url を返します今 - - cdvfile://localhost/persistent/path/to/file - - -これはファイルを一意に識別するために使用できます。 - -## エラー コードと意味のリスト - -エラーがスローされると、次のコードのいずれかが使用されます。 - -| コード | 定数 | -| ---:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## (省略可能) プラグインを構成します。 - -利用可能なファイルシステムのセットは構成されたプラットフォームをすることができます。IOS と Android の両方を認識します。 <preference> タグ `config.xml` をインストールするファイルシステムの名前します。既定では、すべてのファイル システムのルートが有効になります。 - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### アンドロイド - -* `files`: アプリケーションの内部ファイルのストレージ ディレクトリ -* `files-external`: アプリケーションの外部のファイルのストレージ ディレクトリ -* `sdcard`:、グローバル外部ストレージ ディレクトリをファイル (これは SD カードのルートがインストールされている場合)。 これを使用するには、`android.permission.WRITE_EXTERNAL_STORAGE` 権限が必要です。 -* `cache`: アプリケーションの内部キャッシュ ディレクトリ -* `cache-external`: 外部キャッシュのアプリケーションのディレクトリ -* `root`: デバイス全体のファイルシステム - -アンドロイドを「ファイル」ファイルシステム内の"ドキュメント/"サブディレクトリを表す"ドキュメント"という名前の特殊なファイルシステムもサポートしています。 - -### iOS - -* `library`: ライブラリのアプリケーションのディレクトリ -* `documents`: ドキュメントのアプリケーションのディレクトリ -* `cache`: キャッシュのアプリケーションのディレクトリ -* `bundle`: アプリケーションバンドル;アプリ自体 (読み取りのみ) ディスク上の場所 -* `root`: デバイス全体のファイルシステム - -既定では、ライブラリとドキュメント ディレクトリを iCloud に同期できます。 2 つの追加のファイルシステム、`library-nosync` および `documents-nosync` を表す、特別な非同期ディレクトリ内を要求することもできます、`/Library` または `Documents/` ファイルシステム。 diff --git a/plugins/cordova-plugin-file/doc/ja/plugins.md b/plugins/cordova-plugin-file/doc/ja/plugins.md deleted file mode 100644 index 3dedb286..00000000 --- a/plugins/cordova-plugin-file/doc/ja/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# プラグイン開発者のためのノート - -これらのノートは、主に人造人間と iOS 開発者向けファイルのプラグインを使用して、ファイル システムでプラグインのインターフェイスを記述するもの。 - -## コルドバのファイル システムの Url の操作 - -バージョン 1.0.0 以降このプラグインが使用した Url とは `cdvfile` raw デバイス ファイル システム パスを JavaScript に公開するのではなく、ブリッジ上のすべての通信方式します。 - -JavaScript 側認証と DirectoryEntry オブジェクトの HTML ファイル システムのルートからの相対である fullPath 属性があることを意味します。 呼び出す必要がありますプラグインの JavaScript API は、認証または DirectoryEntry オブジェクトを受け入れる場合 `.toURL()` 、橋を渡ってネイティブ コードに渡す前に、そのオブジェクト。 - -### Cdvfile を変換する://fileystem のパスに Url - -ファイルシステムへの書き込みする必要があるプラグインは実際のファイルシステムの場所に受信ファイル用の URL を変換したい可能性があります。ネイティブのプラットフォームによって、これを行うための複数の方法があります。 - -覚えておくことが重要ですすべてではない `cdvfile://` の Url はデバイス上の実際のファイルをマッピング可能な。 いくつかの Url は、ファイルでは表されないまたはリモートのリソースを参照することができますもをデバイス上の資産を参照できます。 プラグインはこれらの可能性のために彼らの Url パスに変換するしようとしているときに戻って、有意義な結果を得るかどうか常にテスト必要があります。 - -#### アンドロイド - -Android 上で変換する最も簡単な方法は `cdvfile://` を使用してファイルシステムのパスに URL が `org.apache.cordova.CordovaResourceApi` 。 `CordovaResourceApi`扱うことができるいくつかの方法があります `cdvfile://` Url: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -また、ファイル プラグインを直接使用することが可能です。 - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -パスから変換する、 `cdvfile://` の URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -あなたのプラグインは、ファイルを作成し、認証オブジェクトを返す場合ファイルのプラグインを使用: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -IOS にコルドバと同じ使用しない `CordovaResourceApi` アンドロイドとして概念。IOS、上ファイル プラグインを使用して Url をファイルシステムのパスに変換する必要があります。 - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -あなたのプラグインは、ファイルを作成し、認証オブジェクトを返す場合ファイルのプラグインを使用: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### Java スクリプトの設定 - -Java スクリプトの設定を取得するには `cdvfile://` 認証または DirectoryEntry オブジェクトから URL を単に呼び出す `.toURL()` に: - - var cdvfileURL = entry.toURL(); - - -プラグインハンドラーの応答で返された FileEntry 構造体の実際のエントリ オブジェクトを変換するハンドラーのコードする必要がありますファイル プラグインをインポートし、新しいオブジェクトを作成します。 - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/ko/README.md b/plugins/cordova-plugin-file/doc/ko/README.md deleted file mode 100644 index a3f3e94e..00000000 --- a/plugins/cordova-plugin-file/doc/ko/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -이 플러그인은 장치에 있는 파일에 대 한 읽기/쓰기 액세스를 허용 하는 파일 API를 구현 합니다. - -이 플러그인을 포함 한 몇 가지 사양에 따라: HTML5 파일 API는 <http://www.w3.org/TR/FileAPI/> - -(지금은 없어진) 디렉터리와 시스템 확장 최신: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> 플러그인 코드의 대부분은 때 이전 사양 작성 되었습니다 있지만 현재는: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -그것은 또한 FileWriter 사양 구현: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -사용을 참조 하십시오 HTML5 바위 ' 우수한 [파일 시스템 문서.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -다른 저장소 옵션에 대 한 개요, 코르도바의 [저장소 가이드](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html) 를 참조합니다. - -이 플러그인 글로벌 `cordova.file` 개체를 정의합니다. - -전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## 설치 - - cordova plugin add cordova-plugin-file - - -## 지원 되는 플랫폼 - - * 아마존 화재 운영 체제 - * 안 드 로이드 - * 블랙베리 10 - * Firefox 운영 체제 - * iOS - * Windows Phone 7과 8 * - * 윈도우 8 * - * Windows* - * 브라우저 - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## 파일을 저장할 위치를 - -V1.2.0, 현재 중요 한 파일 시스템 디렉터리에 Url도 제공 됩니다. 각 URL 형태 *file:///path/to/spot/* 이며 `DirectoryEntry` `window.resolveLocalFileSystemURL()`를 사용 하 여 변환할 수 있습니다.. - - * `cordova.file.applicationDirectory`-읽기 전용 디렉터리는 응용 프로그램을 설치 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*) - - * `cordova.file.applicationStorageDirectory`응용 프로그램의 샌드박스;의 루트 디렉터리 iOS에이 위치에는 읽기 전용 (특정 하위 디렉토리만 [같은 `/Documents` ]은 읽기 / 쓰기). 포함 된 모든 데이터는 응용 프로그램에 전용. ( *iOS*, *안 드 로이드*, *블랙베리 10*) - - * `cordova.file.dataDirectory`-내부 메모리를 사용 하 여 응용 프로그램의 샌드박스 내에서 영구 및 개인 데이터 스토리지 (안 드 로이드, 외부 메모리를 사용 해야 하는 경우 사용 하 여 `.externalDataDirectory` ). IOS에이 디렉터리 iCloud와 동기화 되지 되 (를 사용 하 여 `.syncedDataDirectory` ). (*iOS*, *안 드 로이드*, *블랙베리 10*) - - * `cordova.file.cacheDirectory`-디렉터리 캐시 데이터 파일 또는 모든 파일을 당신의 app를 다시 쉽게 만들 수 있습니다. 운영 체제 장치 저장소 부족 하면 이러한 파일을 삭제할 수 있습니다, 그리고 그럼에도 불구 하 고, 애플 리 케이 션 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*) - - * `cordova.file.externalApplicationStorageDirectory`-응용 프로그램 외부 저장 공간입니다. (*안 드 로이드*) - - * `cordova.file.externalDataDirectory`-외부 저장소에 응용 프로그램 특정 데이터 파일을 넣어 어디. (*안 드 로이드*) - - * `cordova.file.externalCacheDirectory`외부 저장소에 응용 프로그램 캐시입니다. (*안 드 로이드*) - - * `cordova.file.externalRootDirectory`-외부 저장 (SD 카드) 루트입니다. (*안 드 로이드*, *블랙베리 10*) - - * `cordova.file.tempDirectory`-운영 체제에서 지울 수 있습니다 임시 디렉터리 것입니다. 이 디렉터리;를 운영 체제에 의존 하지 마십시오 귀하의 응용 프로그램 항상 해당 하는 경우 파일을 제거 해야 합니다. (*iOS*) - - * `cordova.file.syncedDataDirectory`-(ICloud)를 예를 들어 동기화 해야 하는 응용 프로그램 관련 파일을 보유 하 고 있습니다. (*iOS*) - - * `cordova.file.documentsDirectory`-파일 애플 리 케이 션, 하지만 그 개인은 다른 응용 프로그램 (예: Office 파일)에 의미입니다. (*iOS*) - - * `cordova.file.sharedDirectory`-모든 응용 프로그램 (*블랙베리 10* 에 전세계적으로 사용 가능한 파일) - -## 파일 시스템 레이아웃 - -하지만 구현 세부 사항을 기술적으로 `cordova.file.*` 속성 실제 장치에 실제 경로에 매핑하는 방법을 아는 것이 매우 유용할 수 있습니다. - -### iOS 파일 시스템 레이아웃 - -| 장치 경로 | `cordova.file.*` | `iosExtraFileSystems` | r/w? | 영구? | OS 지웁니다 | 동기화 | 개인 | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:--------:|:-------------:|:---:|:--:| -| `/ var/모바일/응용 프로그램/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | 예 | -| `appname.app/` | applicationDirectory | 번들 | r | N/A | N/A | N/A | 예 | -| `www/` | - | - | r | N/A | N/A | N/A | 예 | -| `Documents/` | documentsDirectory | 문서 | r/w | 예 | 없음 | 예 | 예 | -| `NoCloud/` | - | 문서 nosync | r/w | 예 | 없음 | 없음 | 예 | -| `Library` | - | 라이브러리 | r/w | 예 | 없음 | 그래? | 예 | -| `NoCloud/` | dataDirectory | 라이브러리 nosync | r/w | 예 | 없음 | 없음 | 예 | -| `Cloud/` | syncedDataDirectory | - | r/w | 예 | 없음 | 예 | 예 | -| `Caches/` | cacheDirectory | 캐시 | r/w | 예 * | Yes**\* | 없음 | 예 | -| `tmp/` | tempDirectory | - | r/w | No** | Yes**\* | 없음 | 예 | - -\ * 파일 응용 프로그램 다시 시작 및 업그레이드, 유지 하지만 때마다 OS 욕망이 디렉터리를 지울 수 있습니다. 앱 삭제 될 수 있습니다 모든 콘텐츠를 다시 만들 수 있어야 합니다. - -** 파일 응용 프로그램 다시 시작에서 지속 될 수 있습니다 하지만이 동작에 의존 하지 마십시오. 파일 여러 업데이트를 보장 하지 않습니다. 때 해당 앱이이 디렉터리에서 파일을 제거 해야, 이러한 파일을 제거할 때 (또는 경우에도) 운영 체제 보증 하지 않습니다으로. - -**\ * OS 그것이 필요를 느낀다 언제 든 지이 디렉터리의 내용을 취소 수 있습니다 하지만 이것에 의존 하지 마십시오. 이 디렉터리를 응용 프로그램에 대 한 적절 한 선택을 취소 해야 합니다. - -### 안 드 로이드 파일 시스템 레이아웃 - -| 장치 경로 | `cordova.file.*` | `AndroidExtraFileSystems` | r/w? | 영구? | OS 지웁니다 | 개인 | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:----:|:---:|:--------:|:--:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | 예 | -| `/data/데이터/< app id > /` | applicationStorageDirectory | - | r/w | N/A | N/A | 예 | -| `cache` | cacheDirectory | 캐시 | r/w | 예 | 예\* | 예 | -| `files` | dataDirectory | 파일 | r/w | 예 | 없음 | 예 | -| `Documents` | | 문서 | r/w | 예 | 없음 | 예 | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | 예 | 없음 | 없음 | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | 예 | 없음 | 없음 | -| `cache` | externalCacheDirectry | 외부 캐시 | r/w | 예 | 없음** | 없음 | -| `files` | externalDataDirectory | 파일 외부 | r/w | 예 | 없음 | 없음 | - -\ * 운영 체제 정기적으로이 디렉터리 삭제 수 있지만이 동작에 의존 하지 마십시오. 이 응용 프로그램이 디렉터리의 내용을 취소 합니다. 사용자 수동으로 캐시 제거 해야,이 디렉터리의 내용은 제거 됩니다. - -** 운영 체제 자동으로;이 디렉터리를 삭제 하지 않습니다 내용을 직접 관리에 대 한 책임이 있습니다. 사용자 수동으로 캐시 제거 합니다, 디렉터리의 내용은 제거 됩니다. - -**참고**: 외부 저장소를 탑재할 수 없는 경우 `cordova.file.external*` 속성은 `null`. - -### 블랙베리 10 파일 시스템 레이아웃 - -| 장치 경로 | `cordova.file.*` | r/w? | 영구? | OS 지웁니다 | 개인 | -|:----------------------------------------------------------- |:--------------------------- |:----:|:---:|:-------:|:--:| -| `file:///accounts/1000/appdata/ < app id > /` | applicationStorageDirectory | r | N/A | N/A | 예 | -| `app/native` | applicationDirectory | r | N/A | N/A | 예 | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | 없음 | 예 | 예 | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | 예 | 없음 | 예 | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | 예 | 없음 | 없음 | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | 예 | 없음 | 없음 | - -*참고*: 모든 경로 /accounts/1000-enterprise를 기준으로 응용 프로그램 경계를 작동 하도록 배포 될 때. - -## 안 드 로이드 단점 - -### 안 드 로이드 영구 저장 위치 - -안 드 로이드 장치에 영구 파일을 저장할 여러 유효한 위치가 있다. 다양 한 가능성의 광범위 한 토론에 대 한 [이 페이지](http://developer.android.com/guide/topics/data/data-storage.html)를 참조 하십시오. - -플러그인의 이전 버전을 시작할 때, 장치는 SD 카드 (또는 해당 스토리지 파티션) 탑재 했다 주장 하는 여부에 따라 임시 및 영구 파일의 위치를 선택 합니다. SD 카드 마운트, 또는 큰 내부 스토리지 파티션에 사용할 수 있었습니다 (같은 넥서스 장치에) 그 후에 영구 파일 공간의 루트에 저장 됩니다. 이 모든 코르 도우 바 애플 리 케이 션 카드에 모두 사용할 수 있는 파일을 볼 수 있는 의미 합니다. - -SD 카드는 사용할 수 있는 경우 이전 버전에서 데이터 저장 `/data/data/<packageId>`는 서로 다른 애플 리 케이 션을 분리 하지만 여전히 원인 데이터를 사용자 간에 공유할 수 있습니다. - -그것은 지금 내부 파일 저장 위치 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 이전 논리를 사용 하 여 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다. - -이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. "내부"의 위치 전환 그들의 응용 프로그램을 업그레이드 기존 사용자의 그들의 장치에 따라 그들의 이전에 저장 된 파일에 액세스할 수 수 있다는 뜻입니다. - -경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Internal` 설정은 일반적으로 권장 됩니다. - -### /Android_asset에 대 한 느린 재귀 작업 - -자산 디렉터리를 나열 하는 것은 안 드 로이드에 정말 느리다입니다. 속도 높일 수 있습니다 하지만, 안 드 로이드 프로젝트의 루트에 `src/android/build-extras.gradle` 를 추가 하 여 최대 (cordova-android@4.0.0 필요 이상). - -## iOS 단점 - - * `cordova.file.applicationStorageDirectory`읽기 전용; 루트 디렉터리 내에서 파일을 저장 하려고에 실패 합니다. 다른 중 하나를 사용 하 여 `cordova.file.*` iOS에 대해 정의 된 속성 (만 `applicationDirectory` 와 `applicationStorageDirectory` 는 읽기 전용). - * `FileReader.readAsText(blob, encoding)` - * `encoding`매개 변수는 지원 되지 않습니다, 및 효과에 항상 u t F-8 인코딩을 합니다. - -### iOS 영구 저장소 위치 - -IOS 디바이스에 영구 파일을 저장할 두 개의 유효한 위치가 있다: 문서 디렉터리 및 라이브러리 디렉터리. 플러그인의 이전 버전은 오직 문서 디렉토리에 영구 파일을 저장. 이 부작용 보다는 아니었다 수시로 특히 많은 작은 파일을 처리 하는 응용 프로그램에 대 한 의도, iTunes에 표시 모든 응용 프로그램 파일을 만드는 디렉터리의 용도 내보내기에 대 한 완전 한 문서를 생산 했다. - -그것은 지금 문서 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 라이브러리 디렉토리에 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다. - -이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. `Library`에 위치를 스위칭 기존 사용자에 게 응용 프로그램을 업그레이 드의 그들의 이전에 저장 된 파일에 액세스할 수 것을 의미할 것입니다. - -경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Library` 설정은 일반적으로 권장 됩니다. - -## 파이어 폭스 OS 단점 - -파일 시스템 API Firefox 운영 체제에서 기본적으로 지원 하지 및 indexedDB 위에 심으로 구현 됩니다. - - * 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다. - * 디렉터리에 대 한 메타 데이터를 지원 하지 않습니다. - * 메서드 `copyTo` 및 `moveTo` 디렉터리를 지원 하지 않습니다 - -다음 데이터 경로 지원 됩니다: * `applicationDirectory`-`xhr`를 사용 하 여 로컬 파일을 응용 프로그램 패키지를 가져옵니다. * `dataDirectory`-영구 응용 프로그램 특정 데이터 파일에 대 한. * `cacheDirectory`-응용 프로그램 다시 시작 해야 하는 캐시 된 파일 (애플 리 케이 션은 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야). - -## 브라우저 만지면 - -### 일반적인 단점 및 설명 - - * 각 브라우저는 샌드박스 자체 파일 시스템을 사용합니다. IE와 파이어 폭스 기반으로 IndexedDB를 사용합니다. 모든 브라우저는 경로에서 디렉터리 구분 기호로 슬래시를 사용합니다. - * 디렉터리 항목을 연속적으로 만들 수 있다. 예를 들어 전화 `fs.root.getDirectory ('dir1/dir2 ', {create:true}, successCallback, errorCallback)` d i r 1 존재 하지 않은 경우 실패 합니다. - * 플러그인 응용 프로그램 처음 시작할 영구 저장소를 사용 하 여 사용자 권한을 요청 합니다. - * 플러그인 지원 `cdvfile://localhost` (로컬 리소스)만. 즉, 외부 리소스는 `cdvfile`를 통해 지원 되지 않습니다.. - * 플러그인 ["파일 시스템 API 8.3 명명 제한"을](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions) 수행 하지 않습니다.. - * Blob 및 파일 ' `close` 함수는 지원 되지 않습니다. - * `FileSaver` 및 `BlobBuilder`는이 플러그 접속식에 의해 지원 되지 않습니다 그리고 명세서를 필요가 없습니다. - * 플러그인 `requestAllFileSystems`를 지원 하지 않습니다. 이 함수는 또한 사양에 빠진. - * 사용 하는 경우 디렉터리에서 항목 제거 되지 것입니다 `create: true` 기존 디렉터리에 대 한 플래그. - * 생성자를 통해 생성 된 파일은 지원 되지 않습니다. Entry.file 메서드를 대신 사용 해야 합니다. - * 각 브라우저 blob URL 참조에 대 한 그것의 자신의 형태를 사용합니다. - * `readAsDataURL` 기능을 지원 하지만 크롬에서 mediatype 항목 이름 확장명에 따라 달라 집니다, 그리고 mediatype IE에는 항상 빈 (`텍스트 일반` 사양에 따라 동일), 파이어 폭스에서 mediatype은 항상 `응용 프로그램/8 진수 스트림`. 예를 들어, 콘텐츠는 `abcdefg` 다음 파이어 폭스 반환 `데이터: 응용 프로그램 / 8 진수 스트림; base64, YWJjZGVmZw = =`, 즉 반환 `데이터:; base64, YWJjZGVmZw = =`, 반환 크롬 `데이터: < 항목 이름의 확장에 따라 mediatype >; base64, YWJjZGVmZw = =`. - * `toInternalURL` 양식 `file:///persistent/path/to/entry` (파이어 폭스, 인터넷 익스플로러)에서 경로 반환합니다. 크롬 양식 `cdvfile://localhost/persistent/file`에 경로 반환합니다.. - -### 크롬 특수 - - * 크롬 파일 시스템 장치 준비 이벤트 후 즉시 준비 되지 않습니다. 문제를 해결 하려면 `filePluginIsReady` 이벤트를 구독할 수 있습니다. 예를 들어: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -`Window.isFilePluginReadyRaised` 함수를 사용 하 여 이벤트가 이미 발생 여부를 확인할 수 있습니다. -window.requestFileSystem 임시 및 영구 파일 시스템 할당량 크롬에 제한 되지 않습니다. -크롬에서 영구 저장소를 증가 하려면 `window.initPersistentFileSystem` 메서드를 호출 해야 합니다. 영구 저장소 할당량은 기본적으로 5 메가바이트입니다. -크롬 필요 `-허용-파일-액세스-에서-파일` `file:///` 프로토콜을 통해 지원 API 인수를 실행 합니다. -플래그를 사용 하면 `파일` 개체 하지 변경할 수 `{create:true}` 때 기존 `항목`. -행사 `cancelable` 속성이로 설정 된 크롬에서. 이 [사양](http://dev.w3.org/2009/dap/file-system/file-writer.html) 대조적 이다. -크롬에서 `toURL` 함수 반환 합니다 `파일 시스템:`-응용 프로그램 호스트에 따라 경로 앞에. 예를 들어, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` 함수 결과 디렉터리 항목의 경우에 후행 슬래시를 포함 하지 않습니다. 크롬 하지만 제대로 붙여 슬래시 url이 포함 된 디렉터리 해결합니다. -`resolveLocalFileSystemURL` 메서드 인바운드 `url`을 `파일 시스템` 접두사가 필요 합니다. 예를 들어, `url` 매개 변수 `resolveLocalFileSystemURL`에 대 한 안 드 로이드에서 양식 `file:///persistent/somefile.txt` 반대로 양식 `filesystem:file:///persistent/somefile.txt`에 있어야 합니다. -사용 되지 않는 `toNativeURL` 함수는 지원 되지 않습니다 및 stub에는 없습니다. -`setMetadata` 함수는 규격에 명시 되지 않은 및 지원 되지 않습니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 SYNTAX_ERR(code: 8) 비 existant 파일 시스템의 요청에. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 PATH_EXISTS_ERR(code: 12) 독점적으로 파일 또는 디렉터리를 만들 려,는 이미 존재 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NO_MODIFICATION_ALLOWED_ERR(code: 6) 루트 파일 시스템에 removeRecursively을 호출 하려고 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NOT_FOUND_ERR(code: 1) moveTo 디렉터리 존재 하지 않는 것을 시도에. - -### IndexedDB 기반 구현이 특수 (파이어 폭스와 IE) - - * `.` `.`는 지원 되지 않습니다. - * IE `file:///`를 지원 하지 않습니다-모드; 호스트 모드 지원된 (http://localhost:xxxx)입니다. - * 파이어 폭스 파일 시스템 크기 제한 이지만 각 50MB 확장 사용자 권한을 요청 합니다. IE10 최대 10 mb 결합 AppCache 및 IndexedDB 묻는 사이트 당 250 mb의 최대 최대 증가 될 수 있도록 하려는 경우 해당 수준에 충돌 한 번 메시지를 표시 하지 않고 파일 시스템의 구현에 사용을 허용 한다. 그래서 `size` 매개 변수 `requestFileSystem` 함수에 대 한 파이어 폭스와 IE에서 파일 시스템 영향을 주지 않습니다. - * `readAsBinaryString` 함수 사양에 명시 되지 않은 IE에서 지원 되지 않으며 stub에는 없습니다. - * `file.type`은 항상 null입니다. - * 하지 항목 삭제 된 DirectoryEntry 인스턴스의 콜백 결과 사용 하 여 만들어야 합니다. 그렇지 않으면, '교수형 항목'을 얻을 것 이다. - * 그냥 작성 된 파일을 읽을 수 있는이 파일의 새 인스턴스를 얻으려면 해야 합니다. - * `setMetadata` 함수는 사양에 명시 되지 않은 지원 `modificationTime` 필드 변경에만 해당 합니다. - * `copyTo` 및 `moveTo` 함수는 디렉터리를 지원 하지 않습니다. - * 디렉터리 메타 데이터는 지원 되지 않습니다. - * 둘 다 Entry.remove와 directoryEntry.removeRecursively 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다-디렉터리 제거 되는 대신 내용을 함께 청소. - * `abort` 및 `truncate` 함수 지원 되지 않습니다. - * 진행 이벤트가 발생 하지 합니다. 예를 들어,이 처리기 하지 실행 됩니다. - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## 업그레이드 노트 - -이 플러그인의 v1.0.0에 게시 된 사양에 맞춰 더 많은 것 `FileEntry` 및 `DirectoryEntry` 구조 변경 되었습니다. - -플러그인의 이전 (pre-1.0.0) 버전 장치 절대 파일 위치 `Entry` 개체의 `fullPath` 속성에 저장 됩니다. 이러한 경로 일반적으로 같습니다. - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -이러한 경로 `항목` 개체의 `toURL()` 메서드에서 반환 했다. - -V1.0.0, `fullPath` 속성은 *HTML 파일 시스템의 루트에 상대적인* 파일의 경로를. 그래서, 위의 경로 지금 둘 다의 `fullPath`와 `FileEntry` 개체에 의해 표현 될 것 이다 - - /path/to/file - - -응용 프로그램 작동 장치 절대 경로, 이전 `항목` 개체의 `fullPath` 속성을 통해 그 경로 검색 하는 경우에, 당신은 대신 `entry.toURL()`를 사용 하 여 코드를 업데이트 해야 합니다. - -대 한 뒤 호환성, `resolveLocalFileSystemURL()` 메서드는 장치-절대-경로 수락 하 고 그 파일 중 `TEMPORARY` 또는 `PERSISTENT` 파일 시스템 내에서 존재 하는 경우, 해당 `Entry` 개체를 반환 합니다. - -이 특히 이전 장치 절대 경로 사용 하는 파일 전송 플러그인에 문제가 있다 (그리고 아직도 그들을 받아들일 수.) 그것은 `entry.toURL()`와 `entry.fullPath`를 대체 확인 장치에 파일을 사용 하는 플러그인을 지 고 그래서 파일 시스템 Url와 함께 제대로 작동 하려면 업데이트 되었습니다. - -V1.1.0에 `toURL()`의 반환 값 (\[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394) 참조)로 바뀌었다 'file://' 절대 URL을 반환. 가능 하다 면. 보장 하는 ' cdvfile:'-URL `toInternalURL()`를 지금 사용할 수 있습니다. 이 메서드 이제 양식의 파일 Url을 반환 합니다. - - cdvfile://localhost/persistent/path/to/file - - -어떤 파일을 고유 하 게 식별 하려면 사용할 수 있습니다. - -## 오류 코드 및 의미의 목록 - -오류가 throw 됩니다 때 다음 코드 중 하나가 사용 됩니다. - -| 코드 | 상수 | -| --:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## (선택 사항) 플러그인 구성 - -사용 가능한 파일 시스템의 집합 플랫폼 당 구성된 될 수 있습니다. IOS와 안 드 로이드를 인식 한 <preference> `config.xml` 설치 될 파일 시스템 이름에 태그. 기본적으로 모든 파일 시스템 루트 사용할 수 있습니다. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### 안 드 로이드 - - * `files`: 응용 프로그램의 내부 파일 저장 디렉토리 - * `files-external`: 응용 프로그램의 외부 파일 저장 디렉토리 - * `sdcard`: 글로벌 외부 파일 저장 디렉토리 (이것은 SD 카드의 루트 설치 된 경우). 이것을 사용 하려면 `android.permission.WRITE_EXTERNAL_STORAGE` 권한이 있어야 합니다. - * `cache`: 응용 프로그램의 내부 캐시 디렉터리 - * `cache-external`: 응용 프로그램의 외부 캐시 디렉터리 - * `root`: 전체 장치 파일 시스템 - -안 드 로이드는 또한 "파일" 파일 시스템 내에서 "/ 문서 /" 하위 디렉토리를 나타내는 "문서" 라는 특별 한 파일을 지원 합니다. - -### iOS - - * `library`: 응용 프로그램의 라이브러리 디렉터리 - * `documents`: 응용 프로그램의 문서 디렉토리 - * `cache`: 응용 프로그램의 캐시 디렉터리 - * `bundle`: 응용 프로그램의 번들; (읽기 전용) 디스크에 응용 프로그램 자체의 위치 - * `root`: 전체 장치 파일 시스템 - -기본적으로 라이브러리 및 문서 디렉토리 iCloud에 동기화 할 수 있습니다. 또한 2 개의 추가적인 파일 시스템, `library-nosync` 및 `documents-nosync`, 내 특별 한 동기화 되지 않은 디렉터리를 대표 하는 요청할 수 있습니다는 `/Library` 또는 `/Documents` 파일 시스템.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/ko/index.md b/plugins/cordova-plugin-file/doc/ko/index.md deleted file mode 100644 index 08340d83..00000000 --- a/plugins/cordova-plugin-file/doc/ko/index.md +++ /dev/null @@ -1,338 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -이 플러그인은 장치에 있는 파일에 대 한 읽기/쓰기 액세스를 허용 하는 파일 API를 구현 합니다. - -이 플러그인을 포함 한 몇 가지 사양에 따라: HTML5 파일 API는 <http://www.w3.org/TR/FileAPI/> - -(지금은 없어진) 디렉터리와 시스템 확장 최신: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> 플러그인 코드의 대부분은 때 이전 사양 작성 되었습니다 있지만 현재는: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -그것은 또한 FileWriter 사양 구현: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -사용을 참조 하십시오 HTML5 바위 ' 우수한 [파일 시스템 문서.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -다른 저장소 옵션에 대 한 개요, 코르도바의 [저장소 가이드][2] 를 참조합니다. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -이 플러그인 글로벌 `cordova.file` 개체를 정의합니다. - -전역 범위에 있지만 그것은 불가능까지 `deviceready` 이벤트 후. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## 설치 - - cordova plugin add cordova-plugin-file - - -## 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* 블랙베리 10 -* Firefox 운영 체제 -* iOS -* Windows Phone 7과 8 * -* 윈도우 8 * -* 브라우저 - -* *`FileReader.readAsArrayBuffer`도 `FileWriter.write(blob)`이 플랫폼을 지원 하지 않습니다.* - -## 파일을 저장할 위치를 - -V1.2.0, 현재 중요 한 파일 시스템 디렉터리에 Url도 제공 됩니다. 각 URL 형태 *file:///path/to/spot/* 이며 `DirectoryEntry` `window.resolveLocalFileSystemURL()`를 사용 하 여 변환할 수 있습니다.. - -* `cordova.file.applicationDirectory`-읽기 전용 디렉터리는 응용 프로그램을 설치 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*) - -* `cordova.file.applicationStorageDirectory`응용 프로그램의 샌드박스;의 루트 디렉터리 iOS에이 위치에는 읽기 전용 (특정 하위 디렉토리만 [같은 `/Documents` ]은 읽기 / 쓰기). 포함 된 모든 데이터는 응용 프로그램에 전용. ( *iOS*, *안 드 로이드*, *블랙베리 10*) - -* `cordova.file.dataDirectory`-내부 메모리를 사용 하 여 응용 프로그램의 샌드박스 내에서 영구 및 개인 데이터 스토리지 (안 드 로이드, 외부 메모리를 사용 해야 하는 경우 사용 하 여 `.externalDataDirectory` ). IOS에이 디렉터리 iCloud와 동기화 되지 되 (를 사용 하 여 `.syncedDataDirectory` ). (*iOS*, *안 드 로이드*, *블랙베리 10*) - -* `cordova.file.cacheDirectory`-디렉터리 캐시 데이터 파일 또는 모든 파일을 당신의 app를 다시 쉽게 만들 수 있습니다. 운영 체제 장치 저장소 부족 하면 이러한 파일을 삭제할 수 있습니다, 그리고 그럼에도 불구 하 고, 애플 리 케이 션 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야 합니다. (*iOS*, *안 드 로이드*, *블랙베리 10*) - -* `cordova.file.externalApplicationStorageDirectory`-응용 프로그램 외부 저장 공간입니다. (*안 드 로이드*) - -* `cordova.file.externalDataDirectory`-외부 저장소에 응용 프로그램 특정 데이터 파일을 넣어 어디. (*안 드 로이드*) - -* `cordova.file.externalCacheDirectory`외부 저장소에 응용 프로그램 캐시입니다. (*안 드 로이드*) - -* `cordova.file.externalRootDirectory`-외부 저장 (SD 카드) 루트입니다. (*안 드 로이드*, *블랙베리 10*) - -* `cordova.file.tempDirectory`-운영 체제에서 지울 수 있습니다 임시 디렉터리 것입니다. 이 디렉터리;를 운영 체제에 의존 하지 마십시오 귀하의 응용 프로그램 항상 해당 하는 경우 파일을 제거 해야 합니다. (*iOS*) - -* `cordova.file.syncedDataDirectory`-(ICloud)를 예를 들어 동기화 해야 하는 응용 프로그램 관련 파일을 보유 하 고 있습니다. (*iOS*) - -* `cordova.file.documentsDirectory`-파일 애플 리 케이 션, 하지만 그 개인은 다른 응용 프로그램 (예: Office 파일)에 의미입니다. (*iOS*) - -* `cordova.file.sharedDirectory`-모든 응용 프로그램 (*블랙베리 10* 에 전세계적으로 사용 가능한 파일) - -## 파일 시스템 레이아웃 - -하지만 구현 세부 사항을 기술적으로 `cordova.file.*` 속성 실제 장치에 실제 경로에 매핑하는 방법을 아는 것이 매우 유용할 수 있습니다. - -### iOS 파일 시스템 레이아웃 - -| 장치 경로 | `cordova.file.*` | `iosExtraFileSystems` | r/w? | 영구? | OS 지웁니다 | 동기화 | 개인 | -|:------------------------------------ |:--------------------------- |:--------------------- |:----:|:------:|:---------:|:---:|:--:| -| `/ var/모바일/응용 프로그램/< UUID > /` | applicationStorageDirectory | - | r | N/A | N/A | N/A | 예 | -| `appname.app/` | applicationDirectory | 번들 | r | N/A | N/A | N/A | 예 | -| `www/` | - | - | r | N/A | N/A | N/A | 예 | -| `Documents/` | documentsDirectory | 문서 | r/w | 예 | 없음 | 예 | 예 | -| `NoCloud/` | - | 문서 nosync | r/w | 예 | 없음 | 없음 | 예 | -| `Library` | - | 라이브러리 | r/w | 예 | 없음 | 그래? | 예 | -| `NoCloud/` | dataDirectory | 라이브러리 nosync | r/w | 예 | 없음 | 없음 | 예 | -| `Cloud/` | syncedDataDirectory | - | r/w | 예 | 없음 | 예 | 예 | -| `Caches/` | cacheDirectory | 캐시 | r/w | 예 * | 예 * * *| | 없음 | 예 | -| `tmp/` | tempDirectory | - | r/w | 아니 * * | 예 * * *| | 없음 | 예 | - -* 파일 응용 프로그램 다시 시작 및 업그레이드, 유지 하지만 OS 욕망 언제 든 지이 디렉터리를 지울 수 있습니다. 앱 삭제 될 수 있습니다 모든 콘텐츠를 다시 만들 수 있어야 합니다. - -* * 파일 응용 프로그램 다시 시작에서 지속 될 수 있습니다 하지만이 동작에 의존 하지 마십시오. 파일 여러 업데이트를 보장 하지 않습니다. 때 해당 앱이이 디렉터리에서 파일을 제거 해야, 이러한 파일을 제거할 때 (또는 경우에도) 운영 체제 보증 하지 않습니다으로. - -* * *| OS 그것이 필요를 느낀다 언제 든 지이 디렉터리의 내용을 취소 될 수 있습니다 하지만 이것에 의존 하지 마십시오. 이 디렉터리를 응용 프로그램에 대 한 적절 한 선택을 취소 해야 합니다. - -### 안 드 로이드 파일 시스템 레이아웃 - -| 장치 경로 | `cordova.file.*` | `AndroidExtraFileSystems` | r/w? | 영구? | OS 지웁니다 | 개인 | -|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:---:|:-------:|:--:| -| `file:///android_asset/` | applicationDirectory | | r | N/A | N/A | 예 | -| `/data/데이터/< app id > /` | applicationStorageDirectory | - | r/w | N/A | N/A | 예 | -| `cache` | cacheDirectory | 캐시 | r/w | 예 | 예 * | 예 | -| `files` | dataDirectory | 파일 | r/w | 예 | 없음 | 예 | -| `Documents` | | 문서 | r/w | 예 | 없음 | 예 | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | 예 | 없음 | 없음 | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | 예 | 없음 | 없음 | -| `cache` | externalCacheDirectry | 외부 캐시 | r/w | 예 | 아니 * * | 없음 | -| `files` | externalDataDirectory | 파일 외부 | r/w | 예 | 없음 | 없음 | - -* OS 수 있습니다 정기적으로이 디렉터리에 있지만이 동작에 의존 하지 마십시오. 이 응용 프로그램이 디렉터리의 내용을 취소 합니다. 사용자 수동으로 캐시 제거 해야,이 디렉터리의 내용은 제거 됩니다. - -* * OS 지워지지 않습니다이 디렉터리 자동으로; 콘텐츠를 관리 하기 위한 책임이 있습니다. 사용자 수동으로 캐시 제거 합니다, 디렉터리의 내용은 제거 됩니다. - -**참고**: 외부 저장소를 탑재할 수 없는 경우 `cordova.file.external*` 속성은 `null`. - -### 블랙베리 10 파일 시스템 레이아웃 - -| 장치 경로 | `cordova.file.*` | r/w? | 영구? | OS 지웁니다 | 개인 | -|:--------------------------------------------------- |:--------------------------- |:----:|:---:|:-------:|:--:| -| `file:///accounts/1000/appdata/ < app id > /` | applicationStorageDirectory | r | N/A | N/A | 예 | -| `app/native` | applicationDirectory | r | N/A | N/A | 예 | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | 없음 | 예 | 예 | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | 예 | 없음 | 예 | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | 예 | 없음 | 없음 | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | 예 | 없음 | 없음 | - -*참고*: 모든 경로 /accounts/1000-enterprise를 기준으로 응용 프로그램 경계를 작동 하도록 배포 될 때. - -## 안 드 로이드 단점 - -### 안 드 로이드 영구 저장 위치 - -안 드 로이드 장치에 영구 파일을 저장할 여러 유효한 위치가 있다. 다양 한 가능성의 광범위 한 토론에 대 한 [이 페이지][3]를 참조 하십시오. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -플러그인의 이전 버전을 시작할 때, 장치는 SD 카드 (또는 해당 스토리지 파티션) 탑재 했다 주장 하는 여부에 따라 임시 및 영구 파일의 위치를 선택 합니다. SD 카드 마운트, 또는 큰 내부 스토리지 파티션에 사용할 수 있었습니다 (같은 넥서스 장치에) 그 후에 영구 파일 공간의 루트에 저장 됩니다. 이 모든 코르 도우 바 애플 리 케이 션 카드에 모두 사용할 수 있는 파일을 볼 수 있는 의미 합니다. - -SD 카드는 사용할 수 있는 경우 이전 버전에서 데이터 저장 `/data/data/<packageId>`는 서로 다른 애플 리 케이 션을 분리 하지만 여전히 원인 데이터를 사용자 간에 공유할 수 있습니다. - -그것은 지금 내부 파일 저장 위치 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 이전 논리를 사용 하 여 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다. - -이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. "내부"의 위치 전환 그들의 응용 프로그램을 업그레이드 기존 사용자의 그들의 장치에 따라 그들의 이전에 저장 된 파일에 액세스할 수 수 있다는 뜻입니다. - -경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Internal` 설정은 일반적으로 권장 됩니다. - -## iOS 단점 - -* `cordova.file.applicationStorageDirectory`읽기 전용; 루트 디렉터리 내에서 파일을 저장 하려고에 실패 합니다. 다른 중 하나를 사용 하 여 `cordova.file.*` iOS에 대해 정의 된 속성 (만 `applicationDirectory` 와 `applicationStorageDirectory` 는 읽기 전용). -* `FileReader.readAsText(blob, encoding)` - * `encoding`매개 변수는 지원 되지 않습니다, 및 효과에 항상 u t F-8 인코딩을 합니다. - -### iOS 영구 저장소 위치 - -IOS 디바이스에 영구 파일을 저장할 두 개의 유효한 위치가 있다: 문서 디렉터리 및 라이브러리 디렉터리. 플러그인의 이전 버전은 오직 문서 디렉토리에 영구 파일을 저장. 이 부작용 보다는 아니었다 수시로 특히 많은 작은 파일을 처리 하는 응용 프로그램에 대 한 의도, iTunes에 표시 모든 응용 프로그램 파일을 만드는 디렉터리의 용도 내보내기에 대 한 완전 한 문서를 생산 했다. - -그것은 지금 문서 또는 응용 프로그램의 `config.xml` 파일에 기본 설정으로 라이브러리 디렉토리에 파일을 저장할 것인지를 선택할 수 있습니다. 이렇게 하려면 `config.xml`에이 두 줄 중 하나를 추가: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -이 줄이 없으면 파일 플러그인은 기본적으로 `Compatibility`을 사용 합니다. 기본 태그,이 이러한 값 중 하나가 아닌 경우에 응용 프로그램이 시작 되지 않습니다. - -이전 (사전 1.0)을 사용 하는 경우 응용 프로그램 사용자에 게 발송 되었다 이전,이 플러그인의 버전 영구 파일 시스템에 저장 된 파일은 그리고 `Compatibility` 환경 설정을 설정 해야 합니다. `Library`에 위치를 스위칭 기존 사용자에 게 응용 프로그램을 업그레이 드의 그들의 이전에 저장 된 파일에 액세스할 수 것을 의미할 것입니다. - -경우 응용 프로그램은 새로운, 또는 이전 영구 파일 시스템에 파일을 저장, `Library` 설정은 일반적으로 권장 됩니다. - -## 파이어 폭스 OS 단점 - -파일 시스템 API Firefox 운영 체제에서 기본적으로 지원 하지 및 indexedDB 위에 심으로 구현 됩니다. - -* 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다. -* 디렉터리에 대 한 메타 데이터를 지원 하지 않습니다. -* 메서드 `copyTo` 및 `moveTo` 디렉터리를 지원 하지 않습니다 - -다음 데이터 경로 지원 됩니다: * `applicationDirectory`-`xhr`를 사용 하 여 로컬 파일을 응용 프로그램 패키지를 가져옵니다. * `dataDirectory`-영구 응용 프로그램 특정 데이터 파일에 대 한. * `cacheDirectory`-응용 프로그램 다시 시작 해야 하는 캐시 된 파일 (애플 리 케이 션은 여기에 파일을 삭제 하려면 운영 체제에 의존 하지 말아야). - -## 브라우저 만지면 - -### 일반적인 단점 및 설명 - -* 각 브라우저는 샌드박스 자체 파일 시스템을 사용합니다. IE와 파이어 폭스 기반으로 IndexedDB를 사용합니다. 모든 브라우저는 경로에서 디렉터리 구분 기호로 슬래시를 사용합니다. -* 디렉터리 항목을 연속적으로 만들 수 있다. 예를 들어 전화 `fs.root.getDirectory ('dir1/dir2 ', {create:true}, successCallback, errorCallback)` d i r 1 존재 하지 않은 경우 실패 합니다. -* 플러그인 응용 프로그램 처음 시작할 영구 저장소를 사용 하 여 사용자 권한을 요청 합니다. -* 플러그인 지원 `cdvfile://localhost` (로컬 리소스)만. 즉, 외부 리소스는 `cdvfile`를 통해 지원 되지 않습니다.. -* 플러그인 ["파일 시스템 API 8.3 명명 제한"을][4] 수행 하지 않습니다.. -* Blob 및 파일 ' `close` 함수는 지원 되지 않습니다. -* `FileSaver` 및 `BlobBuilder`는이 플러그 접속식에 의해 지원 되지 않습니다 그리고 명세서를 필요가 없습니다. -* 플러그인 `requestAllFileSystems`를 지원 하지 않습니다. 이 함수는 또한 사양에 빠진. -* 사용 하는 경우 디렉터리에서 항목 제거 되지 것입니다 `create: true` 기존 디렉터리에 대 한 플래그. -* 생성자를 통해 생성 된 파일은 지원 되지 않습니다. Entry.file 메서드를 대신 사용 해야 합니다. -* 각 브라우저 blob URL 참조에 대 한 그것의 자신의 형태를 사용합니다. -* `readAsDataURL` 기능을 지원 하지만 크롬에서 mediatype 항목 이름 확장명에 따라 달라 집니다, 그리고 mediatype IE에는 항상 빈 (`텍스트 일반` 사양에 따라 동일), 파이어 폭스에서 mediatype은 항상 `응용 프로그램/8 진수 스트림`. 예를 들어, 콘텐츠는 `abcdefg` 다음 파이어 폭스 반환 `데이터: 응용 프로그램 / 8 진수 스트림; base64, YWJjZGVmZw = =`, 즉 반환 `데이터:; base64, YWJjZGVmZw = =`, 반환 크롬 `데이터: < 항목 이름의 확장에 따라 mediatype >; base64, YWJjZGVmZw = =`. -* `toInternalURL` 양식 `file:///persistent/path/to/entry` (파이어 폭스, 인터넷 익스플로러)에서 경로 반환합니다. 크롬 양식 `cdvfile://localhost/persistent/file`에 경로 반환합니다.. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### 크롬 특수 - -* 크롬 파일 시스템 장치 준비 이벤트 후 즉시 준비 되지 않습니다. 문제를 해결 하려면 `filePluginIsReady` 이벤트를 구독할 수 있습니다. 예를 들어: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -`Window.isFilePluginReadyRaised` 함수를 사용 하 여 이벤트가 이미 발생 여부를 확인할 수 있습니다. -window.requestFileSystem 임시 및 영구 파일 시스템 할당량 크롬에 제한 되지 않습니다. -크롬에서 영구 저장소를 증가 하려면 `window.initPersistentFileSystem` 메서드를 호출 해야 합니다. 영구 저장소 할당량은 기본적으로 5 메가바이트입니다. -크롬 필요 `-허용-파일-액세스-에서-파일` `file:///` 프로토콜을 통해 지원 API 인수를 실행 합니다. -플래그를 사용 하면 `파일` 개체 하지 변경할 수 `{create:true}` 때 기존 `항목`. -행사 `cancelable` 속성이로 설정 된 크롬에서. 이 [사양][5] 대조적 이다. -크롬에서 `toURL` 함수 반환 합니다 `파일 시스템:`-응용 프로그램 호스트에 따라 경로 앞에. 예를 들어, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -`toURL` 함수 결과 디렉터리 항목의 경우에 후행 슬래시를 포함 하지 않습니다. 크롬 하지만 제대로 붙여 슬래시 url이 포함 된 디렉터리 해결합니다. -`resolveLocalFileSystemURL` 메서드 인바운드 `url`을 `파일 시스템` 접두사가 필요 합니다. 예를 들어, `url` 매개 변수 `resolveLocalFileSystemURL`에 대 한 안 드 로이드에서 양식 `file:///persistent/somefile.txt` 반대로 양식 `filesystem:file:///persistent/somefile.txt`에 있어야 합니다. -사용 되지 않는 `toNativeURL` 함수는 지원 되지 않습니다 및 stub에는 없습니다. -`setMetadata` 함수는 규격에 명시 되지 않은 및 지원 되지 않습니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 SYNTAX_ERR(code: 8) 비 existant 파일 시스템의 요청에. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 PATH_EXISTS_ERR(code: 12) 독점적으로 파일 또는 디렉터리를 만들 려,는 이미 존재 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NO_MODIFICATION_ALLOWED_ERR(code: 6) 루트 파일 시스템에 removeRecursively을 호출 하려고 합니다. -INVALID_MODIFICATION_ERR (코드: 9) 대신 throw 됩니다 NOT_FOUND_ERR(code: 1) moveTo 디렉터리 존재 하지 않는 것을 시도에. - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### IndexedDB 기반 구현이 특수 (파이어 폭스와 IE) - -* `.` `.`는 지원 되지 않습니다. -* IE `file:///`를 지원 하지 않습니다-모드; 호스트 모드 지원된 (http://localhost:xxxx)입니다. -* 파이어 폭스 파일 시스템 크기 제한 이지만 각 50MB 확장 사용자 권한을 요청 합니다. IE10 최대 10 mb 결합 AppCache 및 IndexedDB 묻는 사이트 당 250 mb의 최대 최대 증가 될 수 있도록 하려는 경우 해당 수준에 충돌 한 번 메시지를 표시 하지 않고 파일 시스템의 구현에 사용을 허용 한다. 그래서 `size` 매개 변수 `requestFileSystem` 함수에 대 한 파이어 폭스와 IE에서 파일 시스템 영향을 주지 않습니다. -* `readAsBinaryString` 함수 사양에 명시 되지 않은 IE에서 지원 되지 않으며 stub에는 없습니다. -* `file.type`은 항상 null입니다. -* 하지 항목 삭제 된 DirectoryEntry 인스턴스의 콜백 결과 사용 하 여 만들어야 합니다. 그렇지 않으면, '교수형 항목'을 얻을 것 이다. -* 그냥 작성 된 파일을 읽을 수 있는이 파일의 새 인스턴스를 얻으려면 해야 합니다. -* `setMetadata` 함수는 사양에 명시 되지 않은 지원 `modificationTime` 필드 변경에만 해당 합니다. -* `copyTo` 및 `moveTo` 함수는 디렉터리를 지원 하지 않습니다. -* 디렉터리 메타 데이터는 지원 되지 않습니다. -* 둘 다 Entry.remove와 directoryEntry.removeRecursively 비어 있지 않은 디렉터리를 제거할 때 실패 하지 않습니다-디렉터리 제거 되는 대신 내용을 함께 청소. -* `abort` 및 `truncate` 함수 지원 되지 않습니다. -* 진행 이벤트가 발생 하지 합니다. 예를 들어,이 처리기 하지 실행 됩니다. - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## 업그레이드 노트 - -이 플러그인의 v1.0.0에 게시 된 사양에 맞춰 더 많은 것 `FileEntry` 및 `DirectoryEntry` 구조 변경 되었습니다. - -플러그인의 이전 (pre-1.0.0) 버전 장치 절대 파일 위치 `Entry` 개체의 `fullPath` 속성에 저장 됩니다. 이러한 경로 일반적으로 같습니다. - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -이러한 경로 `항목` 개체의 `toURL()` 메서드에서 반환 했다. - -V1.0.0, `fullPath` 속성은 *HTML 파일 시스템의 루트에 상대적인* 파일의 경로를. 그래서, 위의 경로 지금 둘 다의 `fullPath`와 `FileEntry` 개체에 의해 표현 될 것 이다 - - /path/to/file - - -응용 프로그램 작동 장치 절대 경로, 이전 `항목` 개체의 `fullPath` 속성을 통해 그 경로 검색 하는 경우에, 당신은 대신 `entry.toURL()`를 사용 하 여 코드를 업데이트 해야 합니다. - -대 한 뒤 호환성, `resolveLocalFileSystemURL()` 메서드는 장치-절대-경로 수락 하 고 그 파일 중 `TEMPORARY` 또는 `PERSISTENT` 파일 시스템 내에서 존재 하는 경우, 해당 `Entry` 개체를 반환 합니다. - -이 특히 이전 장치 절대 경로 사용 하는 파일 전송 플러그인에 문제가 있다 (그리고 아직도 그들을 받아들일 수.) 그것은 `entry.toURL()`와 `entry.fullPath`를 대체 확인 장치에 파일을 사용 하는 플러그인을 지 고 그래서 파일 시스템 Url와 함께 제대로 작동 하려면 업데이트 되었습니다. - -V1.1.0에 `toURL()`의 반환 값 (\[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394) 참조)로 바뀌었다 'file://' 절대 URL을 반환. 가능 하다 면. 보장 하는 ' cdvfile:'-URL `toInternalURL()`를 지금 사용할 수 있습니다. 이 메서드 이제 양식의 파일 Url을 반환 합니다. - - cdvfile://localhost/persistent/path/to/file - - -어떤 파일을 고유 하 게 식별 하려면 사용할 수 있습니다. - -## 오류 코드 및 의미의 목록 - -오류가 throw 됩니다 때 다음 코드 중 하나가 사용 됩니다. - -| 코드 | 상수 | -| --:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## (선택 사항) 플러그인 구성 - -사용 가능한 파일 시스템의 집합 플랫폼 당 구성된 될 수 있습니다. IOS와 안 드 로이드를 인식 한 <preference> `config.xml` 설치 될 파일 시스템 이름에 태그. 기본적으로 모든 파일 시스템 루트 사용할 수 있습니다. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### 안 드 로이드 - -* `files`: 응용 프로그램의 내부 파일 저장 디렉토리 -* `files-external`: 응용 프로그램의 외부 파일 저장 디렉토리 -* `sdcard`: 글로벌 외부 파일 저장 디렉토리 (이것은 SD 카드의 루트 설치 된 경우). 이것을 사용 하려면 `android.permission.WRITE_EXTERNAL_STORAGE` 권한이 있어야 합니다. -* `cache`: 응용 프로그램의 내부 캐시 디렉터리 -* `cache-external`: 응용 프로그램의 외부 캐시 디렉터리 -* `root`: 전체 장치 파일 시스템 - -안 드 로이드는 또한 "파일" 파일 시스템 내에서 "/ 문서 /" 하위 디렉토리를 나타내는 "문서" 라는 특별 한 파일을 지원 합니다. - -### iOS - -* `library`: 응용 프로그램의 라이브러리 디렉터리 -* `documents`: 응용 프로그램의 문서 디렉토리 -* `cache`: 응용 프로그램의 캐시 디렉터리 -* `bundle`: 응용 프로그램의 번들; (읽기 전용) 디스크에 응용 프로그램 자체의 위치 -* `root`: 전체 장치 파일 시스템 - -기본적으로 라이브러리 및 문서 디렉토리 iCloud에 동기화 할 수 있습니다. 또한 2 개의 추가적인 파일 시스템, `library-nosync` 및 `documents-nosync`, 내 특별 한 동기화 되지 않은 디렉터리를 대표 하는 요청할 수 있습니다는 `/Library` 또는 `/Documents` 파일 시스템. diff --git a/plugins/cordova-plugin-file/doc/ko/plugins.md b/plugins/cordova-plugin-file/doc/ko/plugins.md deleted file mode 100644 index d5ec121e..00000000 --- a/plugins/cordova-plugin-file/doc/ko/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# 플러그인 개발자를 위한 노트 - -이 노트는 주로 파일 플러그인을 사용 하 여 파일 시스템 플러그인 인터페이스를 작성 하 고 싶은 안 드 로이드와 iOS 개발자를 위한 것입니다. - -## 코르 도우 바 파일 시스템 Url 작업 - -버전 1.0.0, 이후이 플러그인과 Url 사용은 `cdvfile` 교량, 모든 통신 체계 보다는 자바 원시 장치 파일 시스템 경로 노출. - -자바 스크립트 측면에서 즉, FileEntry 및 DirectoryEntry 개체 fullPath 속성을 HTML 파일 시스템의 루트에 상대적입니다. FileEntry 또는 DirectoryEntry 개체를 수락 하는 플러그인의 자바 API를 호출 해야 `.toURL()` 다리에 걸쳐 네이티브 코드에 전달 하기 전에 해당 개체에. - -### Cdvfile 변환: / / fileystem 경로 Url - -플러그인 파일 시스템을 작성 하는 실제 파일 시스템 위치에 받은 파일 시스템 URL을 변환 할 수 있습니다. 이렇게, 네이티브 플랫폼에 따라 여러 방법이 있다. - -기억 하는 것이 중요 하다 모든 `cdvfile://` Url은 장치에 실제 파일을 매핑. 일부 Url 파일에 의해 표현 되지 않는 또는 심지어 원격 리소스를 참조할 수 있는 장치에 자산을 참조할 수 있습니다. 이러한 가능성 때문에 플러그인 경로를 Url을 변환 하려고 할 때 다시 의미 있는 결과 얻을 지 여부를 항상 테스트 해야 합니다. - -#### 안 드 로이드 - -안 드 로이드, 변환 하는 간단한 방법에는 `cdvfile://` URL을 파일 시스템 경로 사용 하는 `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`처리할 수 있는 여러 가지 방법에는 `cdvfile://` Url: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -그것은 또한 파일 플러그인을 직접 사용할 수 있습니다: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -경로를 변환 하는 `cdvfile://` URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -플러그인 파일을 만들고 그것에 대 한 FileEntry 개체를 반환 하려면, 파일 플러그인을 사용. - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -IOS에서 코르도바 같은 사용 하지 않는 `CordovaResourceApi` 안 드 로이드 개념. Ios, Url 및 파일 시스템 경로 사이의 변환할 파일 플러그인을 사용 해야 합니다. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -플러그인 파일을 만들고 그것에 대 한 FileEntry 개체를 반환 하려면, 파일 플러그인을 사용. - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### 자바 스크립트 - -자바 스크립트에서는 `cdvfile://` FileEntry 또는 DirectoryEntry 개체에서 URL를 호출 하면 `.toURL()` 그것에: - - var cdvfileURL = entry.toURL(); - - -플러그인 응답 처리기에서 반환 된 FileEntry 구조에서 실제 항목 개체 변환 하려면 처리기 코드 해야 파일 플러그인 가져오고 새 개체를 만들: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/pl/README.md b/plugins/cordova-plugin-file/doc/pl/README.md deleted file mode 100644 index 166c3ce9..00000000 --- a/plugins/cordova-plugin-file/doc/pl/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -Ten plugin implementuje API pliku, dzięki czemu dostęp do odczytu i zapisu do plików znajdujących się na urządzeniu. - -Ten plugin jest oparty na kilka specyfikacje, w tym: HTML5 File API <http://www.w3.org/TR/FileAPI/> - -Katalogi (nieistniejącego już) i System Najnowsze rozszerzenia: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , chociaż większość z ten plugin kod został napisany podczas wcześniejszych specyfikacji były aktualne: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -To również implementuje specyfikację FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Wykorzystania, prosimy odnieść się do skały HTML5 doskonałe [plików art.](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -Omówienie innych opcji przechowywania odnoszą się do Cordova z [magazynu przewodnik](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -Ten plugin określa globalne `cordova.file` obiektu. - -Chociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Instalacja - - cordova plugin add cordova-plugin-file - - -## Obsługiwane platformy - - * Amazon Fire OS - * Android - * BlackBerry 10 - * Firefox OS - * iOS - * Windows Phone 7 i 8 * - * Windows 8 * - * Windows* - * Przeglądarka - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## Gdzie przechowywać pliki - -Od v1.2.0 znajdują się adresy URL do katalogów ważne systemu plików. Każdy adres URL jest w formie *file:///path/to/spot/* i mogą być konwertowane na `DirectoryEntry` za pomocą `window.resolveLocalFileSystemURL()`. - - * `cordova.file.applicationDirectory`-Tylko do odczytu katalogu gdzie jest zainstalowana aplikacja. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.applicationStorageDirectory`-Katalogu obszaru izolowanego aplikacji; na iOS to miejsce jest tylko do odczytu (ale podkatalogów określonego [jak `/Documents` ] są odczytu i zapisu). Wszystkie dane zawarte w jest prywatną do aplikacji. ( *iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.dataDirectory`-Trwałe i prywatne dane magazynowanie w izolowanym aplikacji przy użyciu pamięci wewnętrznej (na Android, jeśli trzeba użyć zewnętrznej pamięci, należy użyć `.externalDataDirectory` ). Na iOS, Katalog ten nie jest zsynchronizowane z iCloud (za pomocą `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.cacheDirectory`-Katalog dla plików buforowanych danych lub pliki, które aplikacji ponownie można łatwo tworzyć. System operacyjny może usunąć te pliki, gdy urządzenie działa niski na przechowywanie, niemniej jednak aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj. (*iOS*, *Android*, *BlackBerry 10*) - - * `cordova.file.externalApplicationStorageDirectory`-Stosowania przestrzeni na zewnętrznej pamięci masowej. (*Android*) - - * `cordova.file.externalDataDirectory`-Gdzie umieścić pliki danych specyficznych dla aplikacji na zewnętrznej pamięci masowej. (*Android*) - - * `cordova.file.externalCacheDirectory`-Pamięci podręcznej aplikacji na zewnętrznej pamięci masowej. (*Android*) - - * `cordova.file.externalRootDirectory`-Korzeń zewnętrznej pamięci masowej (karty SD). (*Android*, *BlackBerry 10*) - - * `cordova.file.tempDirectory`-Temp katalogu systemu operacyjnego można wyczyścić w będzie. Nie należy polegać na OS wobec usunąć ten katalog; aplikacji należy zawsze usunąć pliki jako obowiązujące. (*iOS*) - - * `cordova.file.syncedDataDirectory`-Posiada pliki specyficzne dla aplikacji, które powinny być zsynchronizowane (np. do iCloud). (*iOS*) - - * `cordova.file.documentsDirectory`-Pliki prywatne do aplikacji, ale że mają znaczenie dla innych aplikacji (np. plików pakietu Office). (*iOS*) - - * `cordova.file.sharedDirectory`-Pliki dostępne na całym świecie do wszystkich aplikacji (*BlackBerry 10*) - -## Plik System układy - -Chociaż technicznie implementacyjnym, może być bardzo przydatne wiedzieć, jak `cordova.file.*` właściwości mapy fizycznej ścieżki na prawdziwe urządzenie. - -### iOS układ systemu plików - -| Ścieżka urządzenia | `Cordova.File.*` | `iosExtraFileSystems` | r/w? | trwałe? | Czyści OS | Synchronizacja | prywatne | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:--------:|:-------------:|:--------------:|:--------:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/D! | N/D! | N/D! | Tak | -| `appname.app/` | applicationDirectory | pakiet | r | N/D! | N/D! | N/D! | Tak | -| `www/` | - | - | r | N/D! | N/D! | N/D! | Tak | -| `Documents/` | documentsDirectory | dokumenty | r/w | Tak | Nr | Tak | Tak | -| `NoCloud/` | - | dokumenty nosync | r/w | Tak | Nr | Nr | Tak | -| `Library` | - | Biblioteka | r/w | Tak | Nr | Tak? | Tak | -| `NoCloud/` | dataDirectory | Biblioteka nosync | r/w | Tak | Nr | Nr | Tak | -| `Cloud/` | syncedDataDirectory | - | r/w | Tak | Nr | Tak | Tak | -| `Caches/` | cacheDirectory | pamięci podręcznej | r/w | Tak * | Yes**\* | Nr | Tak | -| `tmp/` | tempDirectory | - | r/w | No** | Yes**\* | Nr | Tak | - -\ * Pliki utrzymywały aplikacja zostanie ponownie uruchomiony i uaktualnienia, ale w tym katalogu mogą być rozliczone przy każdym OS pragnień. Aplikacji należy umożliwić odtworzenie treści, które mogą być usunięte. - -** Plików może utrzymywać się po ponownym uruchomieniu aplikacji, ale nie opierają się na tym zachowaniu. Pliki nie są gwarantowane w aktualizacji. Aplikacji należy usunąć pliki z tego katalogu, gdy ma to zastosowanie, ponieważ system operacyjny nie gwarantuje Kiedy (lub nawet jeśli) te pliki zostaną usunięte. - -**\ * System operacyjny może wyczyścić zawartość tego katalogu, gdy czuje, że jest to konieczne, ale nie powoływać się na to. Należy wyczyścić ten katalog jako odpowiednie dla aplikacji. - -### Układ systemu Android plików - -| Ścieżka urządzenia | `Cordova.File.*` | `AndroidExtraFileSystems` | r/w? | trwałe? | Czyści OS | prywatne | -|:------------------------------------------------ |:----------------------------------- |:------------------------------- |:----:|:-------:|:---------:|:--------:| -| `file:///android_asset/` | applicationDirectory | | r | N/D! | N/D! | Tak | -| `/Data/danych/< Aplikacja id > /` | applicationStorageDirectory | - | r/w | N/D! | N/D! | Tak | -| `cache` | cacheDirectory | pamięci podręcznej | r/w | Tak | Yes\ * | Tak | -| `files` | dataDirectory | pliki | r/w | Tak | Nr | Tak | -| `Documents` | | dokumenty | r/w | Tak | Nr | Tak | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Tak | Nr | Nr | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Tak | Nr | Nr | -| `cache` | externalCacheDirectry | zewnętrznych pamięci podręcznej | r/w | Tak | No** | Nr | -| `files` | externalDataDirectory | zewnętrznych plików | r/w | Tak | Nr | Nr | - -\ * OS może okresowo usunąć ten katalog, ale nie opierają się na tym zachowaniu. Wyczyść zawartość tego katalogu jako odpowiednie dla danej aplikacji. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość w tym katalogu są usuwane. - -** OS nie usunąć ten katalog automatycznie; Jesteś odpowiedzialny za zarządzanie zawartość siebie. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość katalogu są usuwane. - -**Uwaga**: Jeśli nie mogą być montowane pamięci masowej, właściwości `cordova.file.external*` są `wartości null`. - -### Układ systemu plików blackBerry 10 - -| Ścieżka urządzenia | `Cordova.File.*` | r/w? | trwałe? | Czyści OS | prywatne | -|:----------------------------------------------------------- |:--------------------------- |:----:|:-------:|:---------:|:--------:| -| `file:///accounts/1000/AppData/ < id aplikacji > /` | applicationStorageDirectory | r | N/D! | N/D! | Tak | -| `app/native` | applicationDirectory | r | N/D! | N/D! | Tak | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | Nr | Tak | Tak | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Tak | Nr | Tak | -| `file:///accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Tak | Nr | Nr | -| `file:///accounts/1000/Shared` | sharedDirectory | r/w | Tak | Nr | Nr | - -*Uwaga*: gdy aplikacja jest rozmieszczana do pracy obwodu, wszystkie ścieżki są względne do /accounts/1000-enterprise. - -## Dziwactwa Androida - -### Lokalizacja przechowywania trwałych Android - -Istnieje wiele prawidłowe lokalizacje do przechowywania trwałych plików na telefonie z systemem Android. Zobacz [tę stronę](http://developer.android.com/guide/topics/data/data-storage.html) do szerokiej dyskusji o różnych możliwościach. - -Poprzednie wersje pluginu wybrać lokalizację plików tymczasowych i trwałe podczas uruchamiania, czy urządzenie twierdził, że karta SD (lub równoważne magazynowanie podzia³) był montowany w oparciu. Czy karta SD została zamontowana, czy duży wewnętrzny magazynowanie podzia³ był dostępny (takie jak na Nexus urządzenia,) a następnie trwałe pliki będą przechowywane w katalogu głównego tego miejsca. Oznaczało to, że wszystkie aplikacje Cordova może Zobacz wszystkie pliki dostępne na karcie. - -Jeśli karta SD nie był dostępny, a następnie poprzednie wersje będzie przechowywać dane w `/data/data/<packageId>`, która izoluje aplikacje od siebie, ale nadal może spowodować danych, które mają być współużytkowane przez użytkowników. - -Teraz jest możliwe, aby zdecydować, czy do przechowywania plików w lokalizacji magazynu plików, lub przy użyciu poprzednich logiki, z preferencją w aplikacji w pliku `config.xml`. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Bez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona. - -Jeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do "Internal" oznacza, że istniejących użytkowników, którzy ich aplikacja może być niesłabnący wobec dostęp ich wcześniej zapisane pliki, w zależności od ich urządzenie. - -Jeśli aplikacja jest nowy, lub ma nigdy wcześniej przechowywane pliki w systemie plików trwałe, ustawienie `Internal` generalnie jest zalecane. - -### Powolny cyklicznych operacji dla /android_asset - -Lista katalogów aktywów jest bardzo powolny na Android. Można przyspieszyć to się jednak przez dodanie `src/android/build-extras.gradle` do katalogu głównego projektu android (również wymaga cordova-android@4.0.0 lub większej). - -## Dziwactwa iOS - - * `cordova.file.applicationStorageDirectory`jest tylko do odczytu; próby przechowywania plików w katalogu głównym zakończy się niepowodzeniem. Użyj jednego z innych `cordova.file.*` właściwości zdefiniowane dla iOS (tylko `applicationDirectory` i `applicationStorageDirectory` są tylko do odczytu). - * `FileReader.readAsText(blob, encoding)` - * `encoding`Parametr nie jest obsługiwana, i kodowanie UTF-8 jest zawsze w efekcie. - -### iOS lokalizacja przechowywania trwałych - -Istnieją dwa ważne miejsca trwałe pliki na urządzenia iOS: katalogu dokumentów i katalogu biblioteki. Poprzednie wersje pluginu tylko kiedykolwiek przechowywane trwałe pliki w katalogu dokumentów. To miał ten efekt uboczny od rozpoznawalności wszystkie pliki aplikacji w iTunes, który był często niezamierzone, zwłaszcza dla aplikacji, które obsługują wiele małych plików, zamiast produkuje kompletne dokumenty do wywozu, który jest przeznaczenie katalogu. - -Teraz jest możliwe, aby zdecydować, czy do przechowywania plików w dokumentach lub katalogu biblioteki, z preferencją w pliku `config.xml` aplikacji. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Bez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona. - -Jeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do `Library` oznaczałoby, że istniejących użytkowników, którzy ich aplikacja będzie niesłabnący wobec dostęp ich wcześniej zapisane pliki. - -Jeśli aplikacja jest nowy, lub nigdy wcześniej przechowywane pliki w trwałych plików, ustawień `Library` ogólnie jest zalecane. - -## Firefox OS dziwactwa - -API systemu plików nie jest obsługiwany macierzyście przez Firefox OS i jest zaimplementowany jako podkładki na indexedDB. - - * Nie usuwając niepuste katalogi - * Nie obsługuje metadane dla katalogów - * Metody `copyTo` i `moveTo` nie obsługuje katalogi - -Obsługiwane są następujące ścieżki danych: * `applicationDirectory` - używa `xhr`, aby uzyskać lokalne pliki, które są pakowane z aplikacji. * `dataDirectory` - na trwałe dane specyficzne dla aplikacji pliki. * `cacheDirectory` - buforowanych plików, które powinny przetrwać ponowne uruchomienie aplikacji (aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj). - -## Quirks przeglądarki - -### Wspólne dziwactw i uwagi - - * Każda przeglądarka używa własnej piaskownicy plików. IE i Firefox Użyj IndexedDB jako podstawa. Wszystkie przeglądarki za pomocą ukośnika jako separatora katalogu ścieżka. - * Wpisy w katalogu mają być tworzone sukcesywnie. Na przykład wywołanie `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` zakończy się niepowodzeniem, jeśli nie istnieje dir1. - * Plugin żądania użytkownika uprawnień do używania trwałe przechowywanie przy pierwszym uruchomieniu aplikacji. - * Wtyczka obsługuje `cdvfile://localhost` (lokalne zasoby) tylko. Czyli zewnętrznych zasobów nie są obsługiwane przez `cdvfile`. - * Plugin nie następować po ["Plik API systemu nazw 8.3 ograniczenia"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). - * Obiektu BLOB i pliku "`close` funkcja nie jest obsługiwana. - * `FileSaver` i `BlobBuilder` nie są obsługiwane przez ten plugin i nie ma artykułów. - * Plugin nie obsługuje `requestAllFileSystems`. Ta funkcja jest również brak w specyfikacji. - * Wpisy w katalogu nie zostaną usunięte, jeśli używasz `create: true` flaga dla istniejącego katalogu. - * Pliki utworzone za pomocą konstruktora nie są obsługiwane. Zamiast tego należy użyć metody entry.file. - * Każda przeglądarka używa własnej postaci URL odwołania blob. - * `readAsDataURL` funkcja jest obsługiwana, ale mediatype w Chrome zależy od wejścia z rozszerzeniem, mediatype w IE zawsze jest pusty (który jest taki sam jak `zwykły tekst` według specyfikacji), mediatype w Firefox jest zawsze `aplikacji/oktet strumień`. Na przykład, jeśli treść jest `abcdefg` Firefox wraca z `danych: stosowanie / octet-stream, base64, YWJjZGVmZw ==`, czyli zwraca `danych:; base64, YWJjZGVmZw ==`, Chrome zwraca `danych: < mediatype w zależności od rozszerzenia nazwy; > base64, YWJjZGVmZw ==`. - * `toInternalURL` zwraca ścieżkę w postaci `file:///persistent/path/to/entry` (Firefox, IE). Chrom zwraca ścieżkę w postaci `cdvfile://localhost/persistent/file`. - -### Dziwactwa chrom - - * Chrom plików nie jest od razu gotowy po gotowe urządzenia. Jako rozwiązanie alternatywne można subskrybować zdarzenia `filePluginIsReady`. Przykład: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -Funkcja `window.isFilePluginReadyRaised` służy do sprawdzenia, czy zdarzenie już została podniesiona. -kwoty plików tymczasowych i trwałe window.requestFileSystem nie są ograniczone w Chrome. -W celu zwiększenia trwałego magazynu w Chrome, należy wywołać metodę `window.initPersistentFileSystem`. Domyślnie trwałe dyskowa jest 5 MB. -Chrome wymaga `--pozwalają--dostęp z plików` uruchomić argument na poparcie API za pośrednictwem protokołu `file:///`. -`Plik` obiekt będzie nie zmieniło jeśli flaga `{create:true}` gdy już istniejący `wpis`. -wydarzenia `zwrotu` właściwość jest zestaw true w Chrome. Jest to sprzeczne ze [specyfikacji](http://dev.w3.org/2009/dap/file-system/file-writer.html). -Funkcja `toURL` w Chrome zwraca `plików:`-poprzedzona ścieżką w zależności od aplikacji hosta. Na przykład, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -wynik funkcji `toURL` nie zawierają ukośnika w wpis w katalogu. Chrom usuwa katalogi z ciąć doczepiane adresów URL poprawnie choć. -Metoda `resolveLocalFileSystemURL` wymaga przychodzących `url` mają prefiks `plików`. Na przykład parametr `adresu url` do `resolveLocalFileSystemURL` powinny być w formie `filesystem:file:///persistent/somefile.txt`, w przeciwieństwie do formularza `file:///persistent/somefile.txt` w Android. -Przestarzałe `toNativeURL` funkcja nie jest obsługiwana i nie tylko. -Funkcja `setMetadata` jest nie podane w specyfikacji i nie jest obsługiwane. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast SYNTAX_ERR(code: 8) na żądanie nieistniejącą plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast PATH_EXISTS_ERR(code: 12) próbuje stworzyć wyłącznie pliku lub katalogu, który już istnieje. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NO_MODIFICATION_ALLOWED_ERR(code: 6) na próby wywołania removeRecursively w głównym systemie plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NOT_FOUND_ERR(code: 1) na trudny do katalogu moveTo, który nie istnieje. - -### Na bazie IndexedDB impl dziwactw (Firefox i IE) - - * `.` i `.` nie są obsługiwane. - * IE obsługuje `file:///`-tryb; tylko obsługiwane tryb jest obsługiwany (http://localhost:xxxx). - * Rozmiar plików Firefox nie jest ograniczona, ale każde rozszerzenie 50MB zwróci użytkownikowi uprawnienia. IE10 pozwala maksymalnie 10mb połączone "appcache" i IndexedDB używane w implementacji systemu plików bez monitowania, gdy trafisz na tym poziomie, które uzyskasz, jeśli chcesz mogła ona zostać zwiększony do max 250mb na stronie. Więc `rozmiar` parametru funkcja `requestFileSystem` nie wpływa na system plików Firefox i IE. - * `readAsBinaryString` funkcja nie jest określona w specyfikacji i nie obsługiwane w IE i nie tylko. - * `File.Type` ma zawsze wartość null. - * Nie należy utworzyć wpis za pomocą DirectoryEntry wystąpienie wynik wywołania zwrotnego, który został usunięty. W przeciwnym razie dostaniesz wpisem"wiszące". - * Zanim będzie można przeczytać plik, który został napisany tylko trzeba uzyskać nowe wystąpienie tego pliku. - * Funkcja `setMetadata`, która nie jest określona w specyfikacji obsługuje tylko zmian pola `modificationTime`. - * `copyTo` i `moveTo` funkcji nie obsługuje katalogi. - * Metadanych w katalogów nie jest obsługiwana. - * Zarówno Entry.remove i directoryEntry.removeRecursively nie usuwając niepuste katalogi - katalogi są usuwane są czyszczone z treści zamiast. - * `abort` i `truncate` funkcje nie są obsługiwane. - * zdarzenia postępu nie są zwalniani. Na przykład to obsługa będzie nie wykonywane: - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## Uaktualniania notatek - -W v1.0.0 tego pluginu struktury `FileEntry` i `DirectoryEntry` zmieniły się więcej zgodnie z opublikowaną specyfikacją. - -Poprzednie wersje (pre-1.0.0) plugin przechowywane urządzenia bezwzględna plik lokalizacja we właściwości `fullPath` `wpis` obiektów. Te ścieżki zazwyczaj będzie wyglądać - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Te ścieżki były także zwracany przez metodę `toURL()` `Entry` obiektów. - -Z v1.0.0 atrybut `fullPath` jest ścieżką do pliku, *względem katalogu głównego systemu plików HTML*. Tak powyżej ścieżki będzie teraz zarówno być reprezentowane przez obiekt `FileEntry` z `fullPath` o - - /path/to/file - - -Jeśli aplikacja działa z ścieżki bezwzględnej urządzeń, i możesz wcześniej źródło tych ścieżek przez właściwość `fullPath` `wpis` obiektów, należy zaktualizować kod, aby zamiast tego użyj `entry.toURL()`. - -Dla wstecznej kompatybilności, Metoda `resolveLocalFileSystemURL()` będzie zaakceptować urządzenia ścieżka bezwzględna i zwróci obiekt `Entry` odpowiadający, tak długo, jak ten plik istnieje w albo `TEMPORARY` lub `PERSISTENT` systemy plików. - -To szczególnie został problem z pluginem transferu plików, które poprzednio używane ścieżki bezwzględnej urządzeń (i wciąż można je przyjąć). Została zaktualizowana do pracy poprawnie z adresów URL plików, więc wymiana `entry.fullPath` z `entry.toURL()` powinno rozwiązać wszelkie problemy dostawanie ten plugin do pracy z plików w pamięci urządzenia. - -W v1.1.0 wartość zwracana przez `toURL()` został zmieniony (patrz \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) zwraca adres URL absolutnej "file://". wszędzie tam, gdzie jest to możliwe. Aby zapewnić ' cdvfile:'-URL można użyć `toInternalURL()` teraz. Ta metoda zwróci teraz adresy URL plików formularza - - cdvfile://localhost/persistent/path/to/file - - -który służy do jednoznacznej identyfikacji pliku. - -## Wykaz kodów błędów i ich znaczenie - -Gdy błąd jest generowany, jeden z następujących kodów będzie służyć. - -| Kod | Stała | -| ---:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Konfigurowanie wtyczka (opcjonalny) - -Zestaw dostępnych plików może być skonfigurowany na platformie. Zarówno iOS i Android <preference> Tag w `pliku config.xml`, których nazwy plików do instalacji. Domyślnie włączone są wszystkie korzenie systemu plików. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - - * `files`: katalogu przechowywania plików aplikacji - * `files-external`: katalog aplikacji zewnętrznych plików - * `sdcard`: katalog globalny plik zewnętrzny (to jest głównym karty SD, jeśli jedna jest zainstalowana). Musi mieć uprawnienia `android.permission.WRITE_EXTERNAL_STORAGE` wobec używać ten. - * `cache`: katalogu wewnętrznej pamięci podręcznej aplikacji - * `cache-external`: katalogu aplikacji zewnętrznych pamięci podręcznej - * `root`: całe urządzenie systemu plików - -Android obsługuje również specjalnych plików o nazwie "dokumenty", który reprezentuje podkatalog "/ dokumenty /" w ramach systemu plików "pliki". - -### iOS - - * `library`: katalog biblioteki aplikacji - * `documents`: dokumenty katalogu aplikacji - * `cache`: katalogu pamięci podręcznej aplikacji - * `bundle`: pakiet aplikacji; Lokalizacja aplikacji na dysku (tylko do odczytu) - * `root`: całe urządzenie systemu plików - -Domyślnie katalogi biblioteki i dokumenty mogą być synchronizowane iCloud. Można również zażądać dwóch dodatkowych plików, `library-nosync` i `documents-nosync`, które stanowią specjalny katalog nie zsynchronizowane w `/Library` lub systemu plików `/Documents`.
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/pl/index.md b/plugins/cordova-plugin-file/doc/pl/index.md deleted file mode 100644 index 1ccb3300..00000000 --- a/plugins/cordova-plugin-file/doc/pl/index.md +++ /dev/null @@ -1,338 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -Ten plugin implementuje API pliku, dzięki czemu dostęp do odczytu i zapisu do plików znajdujących się na urządzeniu. - -Ten plugin jest oparty na kilka specyfikacje, w tym: HTML5 File API <http://www.w3.org/TR/FileAPI/> - -Katalogi (nieistniejącego już) i System Najnowsze rozszerzenia: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , chociaż większość z ten plugin kod został napisany podczas wcześniejszych specyfikacji były aktualne: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -To również implementuje specyfikację FileWriter: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Wykorzystania, prosimy odnieść się do skały HTML5 doskonałe [plików art.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -Omówienie innych opcji przechowywania odnoszą się do Cordova z [magazynu przewodnik][2]. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -Ten plugin określa globalne `cordova.file` obiektu. - -Chociaż w globalnym zasięgu, to nie dostępne dopiero po `deviceready` imprezie. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## Instalacja - - cordova plugin add cordova-plugin-file - - -## Obsługiwane platformy - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows Phone 7 i 8 * -* Windows 8 * -* Przeglądarka - -* *Nie obsługują tych platform, `FileReader.readAsArrayBuffer` ani `FileWriter.write(blob)`.* - -## Gdzie przechowywać pliki - -Od v1.2.0 znajdują się adresy URL do katalogów ważne systemu plików. Każdy adres URL jest w formie *file:///path/to/spot/* i mogą być konwertowane na `DirectoryEntry` za pomocą `window.resolveLocalFileSystemURL()`. - -* `cordova.file.applicationDirectory`-Tylko do odczytu katalogu gdzie jest zainstalowana aplikacja. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.applicationStorageDirectory`-Katalogu obszaru izolowanego aplikacji; na iOS to miejsce jest tylko do odczytu (ale podkatalogów określonego [jak `/Documents` ] są odczytu i zapisu). Wszystkie dane zawarte w jest prywatną do aplikacji. ( *iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.dataDirectory`-Trwałe i prywatne dane magazynowanie w izolowanym aplikacji przy użyciu pamięci wewnętrznej (na Android, jeśli trzeba użyć zewnętrznej pamięci, należy użyć `.externalDataDirectory` ). Na iOS, Katalog ten nie jest zsynchronizowane z iCloud (za pomocą `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.cacheDirectory`-Katalog dla plików buforowanych danych lub pliki, które aplikacji ponownie można łatwo tworzyć. System operacyjny może usunąć te pliki, gdy urządzenie działa niski na przechowywanie, niemniej jednak aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.externalApplicationStorageDirectory`-Stosowania przestrzeni na zewnętrznej pamięci masowej. (*Android*) - -* `cordova.file.externalDataDirectory`-Gdzie umieścić pliki danych specyficznych dla aplikacji na zewnętrznej pamięci masowej. (*Android*) - -* `cordova.file.externalCacheDirectory`-Pamięci podręcznej aplikacji na zewnętrznej pamięci masowej. (*Android*) - -* `cordova.file.externalRootDirectory`-Korzeń zewnętrznej pamięci masowej (karty SD). (*Android*, *BlackBerry 10*) - -* `cordova.file.tempDirectory`-Temp katalogu systemu operacyjnego można wyczyścić w będzie. Nie należy polegać na OS wobec usunąć ten katalog; aplikacji należy zawsze usunąć pliki jako obowiązujące. (*iOS*) - -* `cordova.file.syncedDataDirectory`-Posiada pliki specyficzne dla aplikacji, które powinny być zsynchronizowane (np. do iCloud). (*iOS*) - -* `cordova.file.documentsDirectory`-Pliki prywatne do aplikacji, ale że mają znaczenie dla innych aplikacji (np. plików pakietu Office). (*iOS*) - -* `cordova.file.sharedDirectory`-Pliki dostępne na całym świecie do wszystkich aplikacji (*BlackBerry 10*) - -## Plik System układy - -Chociaż technicznie implementacyjnym, może być bardzo przydatne wiedzieć, jak `cordova.file.*` właściwości mapy fizycznej ścieżki na prawdziwe urządzenie. - -### iOS układ systemu plików - -| Ścieżka urządzenia | `Cordova.File.*` | `iosExtraFileSystems` | r/w? | trwałe? | Czyści OS | Synchronizacja | prywatne | -|:-------------------------------------------- |:--------------------------- |:--------------------- |:----:|:-------:|:-----------:|:--------------:|:--------:| -| `/ var/mobile/Applications/< UUID > /` | applicationStorageDirectory | - | r | N/D! | N/D! | N/D! | Tak | -| `appname.app/` | applicationDirectory | pakiet | r | N/D! | N/D! | N/D! | Tak | -| `www/` | - | - | r | N/D! | N/D! | N/D! | Tak | -| `Documents/` | documentsDirectory | dokumenty | r/w | Tak | Nr | Tak | Tak | -| `NoCloud/` | - | dokumenty nosync | r/w | Tak | Nr | Nr | Tak | -| `Library` | - | Biblioteka | r/w | Tak | Nr | Tak? | Tak | -| `NoCloud/` | dataDirectory | Biblioteka nosync | r/w | Tak | Nr | Nr | Tak | -| `Cloud/` | syncedDataDirectory | - | r/w | Tak | Nr | Tak | Tak | -| `Caches/` | cacheDirectory | pamięci podręcznej | r/w | Tak * | Tak * * *| | Nr | Tak | -| `tmp/` | tempDirectory | - | r/w | Nie * * | Tak * * *| | Nr | Tak | - -* Pliki utrzymywały aplikacja zostanie ponownie uruchomiony i uaktualnienia, ale w tym katalogu mogą być rozliczone, gdy OS pragnienia. Aplikacji powinny być w stanie odtworzyć zawartość, która może być usunięta. - -* * Plików może utrzymywać się po ponownym uruchomieniu aplikacji, ale nie opierają się na tym zachowaniu. Pliki nie są gwarantowane w aktualizacji. Aplikacji należy usunąć pliki z tego katalogu, gdy ma to zastosowanie, ponieważ system operacyjny nie gwarantuje Kiedy (lub nawet jeśli) te pliki zostaną usunięte. - -* * *| System operacyjny może wyczyścić zawartość w tym katalogu, gdy czuje, że jest to konieczne, ale nie powoływać się na to. Należy wyczyścić ten katalog jako odpowiednie dla aplikacji. - -### Układ systemu Android plików - -| Ścieżka urządzenia | `Cordova.File.*` | `AndroidExtraFileSystems` | r/w? | trwałe? | Czyści OS | prywatne | -|:--------------------------------------- |:----------------------------------- |:------------------------------- |:----:|:-------:|:---------:|:--------:| -| `file:///android_asset/` | applicationDirectory | | r | N/D! | N/D! | Tak | -| `/Data/danych/< Aplikacja id > /` | applicationStorageDirectory | - | r/w | N/D! | N/D! | Tak | -| `cache` | cacheDirectory | pamięci podręcznej | r/w | Tak | Tak * | Tak | -| `files` | dataDirectory | pliki | r/w | Tak | Nr | Tak | -| `Documents` | | dokumenty | r/w | Tak | Nr | Tak | -| `< sdcard > /` | externalRootDirectory | sdcard | r/w | Tak | Nr | Nr | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Tak | Nr | Nr | -| `cache` | externalCacheDirectry | zewnętrznych pamięci podręcznej | r/w | Tak | Nie * * | Nr | -| `files` | externalDataDirectory | zewnętrznych plików | r/w | Tak | Nr | Nr | - -* System operacyjny może okresowo usunąć ten katalog, ale nie opierają się na tym zachowaniu. Wyczyść zawartość tego katalogu jako odpowiednie dla danej aplikacji. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość w tym katalogu są usuwane. - -* * System operacyjny nie usunąć ten katalog automatycznie; Jesteś odpowiedzialny za zarządzanie zawartość siebie. Należy użytkownik przeczyścić pamięć podręczną ręcznie, zawartość katalogu są usuwane. - -**Uwaga**: Jeśli nie mogą być montowane pamięci masowej, właściwości `cordova.file.external*` są `wartości null`. - -### Układ systemu plików blackBerry 10 - -| Ścieżka urządzenia | `Cordova.File.*` | r/w? | trwałe? | Czyści OS | prywatne | -|:--------------------------------------------------------- |:--------------------------- |:----:|:-------:|:---------:|:--------:| -| `file:///accounts/1000/AppData/ < id aplikacji > /` | applicationStorageDirectory | r | N/D! | N/D! | Tak | -| `app/native` | applicationDirectory | r | N/D! | N/D! | Tak | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | Nr | Tak | Tak | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Tak | Nr | Tak | -| `file:///accounts/1000/Removable/sdcard` | externalRemovableDirectory | r/w | Tak | Nr | Nr | -| `file:///accounts/1000/Shared` | sharedDirectory | r/w | Tak | Nr | Nr | - -*Uwaga*: gdy aplikacja jest rozmieszczana do pracy obwodu, wszystkie ścieżki są względne do /accounts/1000-enterprise. - -## Dziwactwa Androida - -### Lokalizacja przechowywania trwałych Android - -Istnieje wiele prawidłowe lokalizacje do przechowywania trwałych plików na telefonie z systemem Android. Zobacz [tę stronę][3] do szerokiej dyskusji o różnych możliwościach. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -Poprzednie wersje pluginu wybrać lokalizację plików tymczasowych i trwałe podczas uruchamiania, czy urządzenie twierdził, że karta SD (lub równoważne magazynowanie podzia³) był montowany w oparciu. Czy karta SD została zamontowana, czy duży wewnętrzny magazynowanie podzia³ był dostępny (takie jak na Nexus urządzenia,) a następnie trwałe pliki będą przechowywane w katalogu głównego tego miejsca. Oznaczało to, że wszystkie aplikacje Cordova może Zobacz wszystkie pliki dostępne na karcie. - -Jeśli karta SD nie był dostępny, a następnie poprzednie wersje będzie przechowywać dane w `/data/data/<packageId>`, która izoluje aplikacje od siebie, ale nadal może spowodować danych, które mają być współużytkowane przez użytkowników. - -Teraz jest możliwe, aby zdecydować, czy do przechowywania plików w lokalizacji magazynu plików, lub przy użyciu poprzednich logiki, z preferencją w aplikacji w pliku `config.xml`. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Bez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona. - -Jeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do "Internal" oznacza, że istniejących użytkowników, którzy ich aplikacja może być niesłabnący wobec dostęp ich wcześniej zapisane pliki, w zależności od ich urządzenie. - -Jeśli aplikacja jest nowy, lub ma nigdy wcześniej przechowywane pliki w systemie plików trwałe, ustawienie `Internal` generalnie jest zalecane. - -## Dziwactwa iOS - -* `cordova.file.applicationStorageDirectory`jest tylko do odczytu; próby przechowywania plików w katalogu głównym zakończy się niepowodzeniem. Użyj jednego z innych `cordova.file.*` właściwości zdefiniowane dla iOS (tylko `applicationDirectory` i `applicationStorageDirectory` są tylko do odczytu). -* `FileReader.readAsText(blob, encoding)` - * `encoding`Parametr nie jest obsługiwana, i kodowanie UTF-8 jest zawsze w efekcie. - -### iOS lokalizacja przechowywania trwałych - -Istnieją dwa ważne miejsca trwałe pliki na urządzenia iOS: katalogu dokumentów i katalogu biblioteki. Poprzednie wersje pluginu tylko kiedykolwiek przechowywane trwałe pliki w katalogu dokumentów. To miał ten efekt uboczny od rozpoznawalności wszystkie pliki aplikacji w iTunes, który był często niezamierzone, zwłaszcza dla aplikacji, które obsługują wiele małych plików, zamiast produkuje kompletne dokumenty do wywozu, który jest przeznaczenie katalogu. - -Teraz jest możliwe, aby zdecydować, czy do przechowywania plików w dokumentach lub katalogu biblioteki, z preferencją w pliku `config.xml` aplikacji. Aby to zrobić, Dodaj jedną z tych dwóch linii do `pliku config.xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Bez tej linii wtyczki pliku będzie używać `Compatibility` jako domyślny. Jeśli znacznik preferencji jest obecny i to nie jedną z tych wartości, aplikacja nie zostanie uruchomiona. - -Jeśli aplikacja wcześniej zostało wysłane do użytkowników, przy użyciu starszych (pre-1.0) wersję tego pluginu i ma zapisane na dysku pliki w trwałych plików, a następnie należy ustawić preferencje do `Compatibility`. Przełączania lokalizacji do `Library` oznaczałoby, że istniejących użytkowników, którzy ich aplikacja będzie niesłabnący wobec dostęp ich wcześniej zapisane pliki. - -Jeśli aplikacja jest nowy, lub nigdy wcześniej przechowywane pliki w trwałych plików, ustawień `Library` ogólnie jest zalecane. - -## Firefox OS dziwactwa - -API systemu plików nie jest obsługiwany macierzyście przez Firefox OS i jest zaimplementowany jako podkładki na indexedDB. - -* Nie usuwając niepuste katalogi -* Nie obsługuje metadane dla katalogów -* Metody `copyTo` i `moveTo` nie obsługuje katalogi - -Obsługiwane są następujące ścieżki danych: * `applicationDirectory` - używa `xhr`, aby uzyskać lokalne pliki, które są pakowane z aplikacji. * `dataDirectory` - na trwałe dane specyficzne dla aplikacji pliki. * `cacheDirectory` - buforowanych plików, które powinny przetrwać ponowne uruchomienie aplikacji (aplikacje nie powinny polegać na OS, aby usunąć pliki tutaj). - -## Quirks przeglądarki - -### Wspólne dziwactw i uwagi - -* Każda przeglądarka używa własnej piaskownicy plików. IE i Firefox Użyj IndexedDB jako podstawa. Wszystkie przeglądarki za pomocą ukośnika jako separatora katalogu ścieżka. -* Wpisy w katalogu mają być tworzone sukcesywnie. Na przykład wywołanie `fs.root.getDirectory (' dir1/dir2 ', {create:true}, successCallback, errorCallback)` zakończy się niepowodzeniem, jeśli nie istnieje dir1. -* Plugin żądania użytkownika uprawnień do używania trwałe przechowywanie przy pierwszym uruchomieniu aplikacji. -* Wtyczka obsługuje `cdvfile://localhost` (lokalne zasoby) tylko. Czyli zewnętrznych zasobów nie są obsługiwane przez `cdvfile`. -* Plugin nie następować po ["Plik API systemu nazw 8.3 ograniczenia"][4]. -* Obiektu BLOB i pliku "`close` funkcja nie jest obsługiwana. -* `FileSaver` i `BlobBuilder` nie są obsługiwane przez ten plugin i nie ma artykułów. -* Plugin nie obsługuje `requestAllFileSystems`. Ta funkcja jest również brak w specyfikacji. -* Wpisy w katalogu nie zostaną usunięte, jeśli używasz `create: true` flaga dla istniejącego katalogu. -* Pliki utworzone za pomocą konstruktora nie są obsługiwane. Zamiast tego należy użyć metody entry.file. -* Każda przeglądarka używa własnej postaci URL odwołania blob. -* `readAsDataURL` funkcja jest obsługiwana, ale mediatype w Chrome zależy od wejścia z rozszerzeniem, mediatype w IE zawsze jest pusty (który jest taki sam jak `zwykły tekst` według specyfikacji), mediatype w Firefox jest zawsze `aplikacji/oktet strumień`. Na przykład, jeśli treść jest `abcdefg` Firefox wraca z `danych: stosowanie / octet-stream, base64, YWJjZGVmZw ==`, czyli zwraca `danych:; base64, YWJjZGVmZw ==`, Chrome zwraca `danych: < mediatype w zależności od rozszerzenia nazwy; > base64, YWJjZGVmZw ==`. -* `toInternalURL` zwraca ścieżkę w postaci `file:///persistent/path/to/entry` (Firefox, IE). Chrom zwraca ścieżkę w postaci `cdvfile://localhost/persistent/file`. - - [4]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### Dziwactwa chrom - -* Chrom plików nie jest od razu gotowy po gotowe urządzenia. Jako rozwiązanie alternatywne można subskrybować zdarzenia `filePluginIsReady`. Przykład: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -Funkcja `window.isFilePluginReadyRaised` służy do sprawdzenia, czy zdarzenie już została podniesiona. -kwoty plików tymczasowych i trwałe window.requestFileSystem nie są ograniczone w Chrome. -W celu zwiększenia trwałego magazynu w Chrome, należy wywołać metodę `window.initPersistentFileSystem`. Domyślnie trwałe dyskowa jest 5 MB. -Chrome wymaga `--pozwalają--dostęp z plików` uruchomić argument na poparcie API za pośrednictwem protokołu `file:///`. -`Plik` obiekt będzie nie zmieniło jeśli flaga `{create:true}` gdy już istniejący `wpis`. -wydarzenia `zwrotu` właściwość jest zestaw true w Chrome. Jest to sprzeczne ze [specyfikacji][5]. -Funkcja `toURL` w Chrome zwraca `plików:`-poprzedzona ścieżką w zależności od aplikacji hosta. Na przykład, `filesystem:file:///persistent/somefile.txt`, `filesystem:http://localhost:8080/persistent/somefile.txt`. -wynik funkcji `toURL` nie zawierają ukośnika w wpis w katalogu. Chrom usuwa katalogi z ciąć doczepiane adresów URL poprawnie choć. -Metoda `resolveLocalFileSystemURL` wymaga przychodzących `url` mają prefiks `plików`. Na przykład parametr `adresu url` do `resolveLocalFileSystemURL` powinny być w formie `filesystem:file:///persistent/somefile.txt`, w przeciwieństwie do formularza `file:///persistent/somefile.txt` w Android. -Przestarzałe `toNativeURL` funkcja nie jest obsługiwana i nie tylko. -Funkcja `setMetadata` jest nie podane w specyfikacji i nie jest obsługiwane. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast SYNTAX_ERR(code: 8) na żądanie nieistniejącą plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast PATH_EXISTS_ERR(code: 12) próbuje stworzyć wyłącznie pliku lub katalogu, który już istnieje. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NO_MODIFICATION_ALLOWED_ERR(code: 6) na próby wywołania removeRecursively w głównym systemie plików. -INVALID_MODIFICATION_ERR (kod: 9) jest generowany zamiast NOT_FOUND_ERR(code: 1) na trudny do katalogu moveTo, który nie istnieje. - - [5]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -### Na bazie IndexedDB impl dziwactw (Firefox i IE) - -* `.` i `.` nie są obsługiwane. -* IE obsługuje `file:///`-tryb; tylko obsługiwane tryb jest obsługiwany (http://localhost:xxxx). -* Rozmiar plików Firefox nie jest ograniczona, ale każde rozszerzenie 50MB zwróci użytkownikowi uprawnienia. IE10 pozwala maksymalnie 10mb połączone "appcache" i IndexedDB używane w implementacji systemu plików bez monitowania, gdy trafisz na tym poziomie, które uzyskasz, jeśli chcesz mogła ona zostać zwiększony do max 250mb na stronie. Więc `rozmiar` parametru funkcja `requestFileSystem` nie wpływa na system plików Firefox i IE. -* `readAsBinaryString` funkcja nie jest określona w specyfikacji i nie obsługiwane w IE i nie tylko. -* `File.Type` ma zawsze wartość null. -* Nie należy utworzyć wpis za pomocą DirectoryEntry wystąpienie wynik wywołania zwrotnego, który został usunięty. W przeciwnym razie dostaniesz wpisem"wiszące". -* Zanim będzie można przeczytać plik, który został napisany tylko trzeba uzyskać nowe wystąpienie tego pliku. -* Funkcja `setMetadata`, która nie jest określona w specyfikacji obsługuje tylko zmian pola `modificationTime`. -* `copyTo` i `moveTo` funkcji nie obsługuje katalogi. -* Metadanych w katalogów nie jest obsługiwana. -* Zarówno Entry.remove i directoryEntry.removeRecursively nie usuwając niepuste katalogi - katalogi są usuwane są czyszczone z treści zamiast. -* `abort` i `truncate` funkcje nie są obsługiwane. -* zdarzenia postępu nie są zwalniani. Na przykład to obsługa będzie nie wykonywane: - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## Uaktualniania notatek - -W v1.0.0 tego pluginu struktury `FileEntry` i `DirectoryEntry` zmieniły się więcej zgodnie z opublikowaną specyfikacją. - -Poprzednie wersje (pre-1.0.0) plugin przechowywane urządzenia bezwzględna plik lokalizacja we właściwości `fullPath` `wpis` obiektów. Te ścieżki zazwyczaj będzie wyglądać - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Te ścieżki były także zwracany przez metodę `toURL()` `Entry` obiektów. - -Z v1.0.0 atrybut `fullPath` jest ścieżką do pliku, *względem katalogu głównego systemu plików HTML*. Tak powyżej ścieżki będzie teraz zarówno być reprezentowane przez obiekt `FileEntry` z `fullPath` o - - /path/to/file - - -Jeśli aplikacja działa z ścieżki bezwzględnej urządzeń, i możesz wcześniej źródło tych ścieżek przez właściwość `fullPath` `wpis` obiektów, należy zaktualizować kod, aby zamiast tego użyj `entry.toURL()`. - -Dla wstecznej kompatybilności, Metoda `resolveLocalFileSystemURL()` będzie zaakceptować urządzenia ścieżka bezwzględna i zwróci obiekt `Entry` odpowiadający, tak długo, jak ten plik istnieje w albo `TEMPORARY` lub `PERSISTENT` systemy plików. - -To szczególnie został problem z pluginem transferu plików, które poprzednio używane ścieżki bezwzględnej urządzeń (i wciąż można je przyjąć). Została zaktualizowana do pracy poprawnie z adresów URL plików, więc wymiana `entry.fullPath` z `entry.toURL()` powinno rozwiązać wszelkie problemy dostawanie ten plugin do pracy z plików w pamięci urządzenia. - -W v1.1.0 wartość zwracana przez `toURL()` został zmieniony (patrz \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) zwraca adres URL absolutnej "file://". wszędzie tam, gdzie jest to możliwe. Aby zapewnić ' cdvfile:'-URL można użyć `toInternalURL()` teraz. Ta metoda zwróci teraz adresy URL plików formularza - - cdvfile://localhost/persistent/path/to/file - - -który służy do jednoznacznej identyfikacji pliku. - -## Wykaz kodów błędów i ich znaczenie - -Gdy błąd jest generowany, jeden z następujących kodów będzie służyć. - -| Kod | Stała | -| ---:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Konfigurowanie wtyczka (opcjonalny) - -Zestaw dostępnych plików może być skonfigurowany na platformie. Zarówno iOS i Android <preference> Tag w `pliku config.xml`, których nazwy plików do instalacji. Domyślnie włączone są wszystkie korzenie systemu plików. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - -* `files`: katalogu przechowywania plików aplikacji -* `files-external`: katalog aplikacji zewnętrznych plików -* `sdcard`: katalog globalny plik zewnętrzny (to jest głównym karty SD, jeśli jedna jest zainstalowana). Musi mieć uprawnienia `android.permission.WRITE_EXTERNAL_STORAGE` wobec używać ten. -* `cache`: katalogu wewnętrznej pamięci podręcznej aplikacji -* `cache-external`: katalogu aplikacji zewnętrznych pamięci podręcznej -* `root`: całe urządzenie systemu plików - -Android obsługuje również specjalnych plików o nazwie "dokumenty", który reprezentuje podkatalog "/ dokumenty /" w ramach systemu plików "pliki". - -### iOS - -* `library`: katalog biblioteki aplikacji -* `documents`: dokumenty katalogu aplikacji -* `cache`: katalogu pamięci podręcznej aplikacji -* `bundle`: pakiet aplikacji; Lokalizacja aplikacji na dysku (tylko do odczytu) -* `root`: całe urządzenie systemu plików - -Domyślnie katalogi biblioteki i dokumenty mogą być synchronizowane iCloud. Można również zażądać dwóch dodatkowych plików, `library-nosync` i `documents-nosync`, które stanowią specjalny katalog nie zsynchronizowane w `/Library` lub systemu plików `/Documents`. diff --git a/plugins/cordova-plugin-file/doc/pl/plugins.md b/plugins/cordova-plugin-file/doc/pl/plugins.md deleted file mode 100644 index a1f9169f..00000000 --- a/plugins/cordova-plugin-file/doc/pl/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# Uwagi dla programistów wtyczki - -Te notatki są przeznaczone przede wszystkim dla Androida i iOS programistów, którzy chcieli pisac pluginy które interfejs z systemu plików za pomocą wtyczki pliku. - -## Praca z Cordova pliku system adresów URL - -Od wersji 1.0.0, ten plugin jest używane adresy URL z `cdvfile` system do komunikacji przez most, a nie narażać urządzenia raw ścieżki systemu plików JavaScript. - -Na stronie JavaScript oznacza to, że FileEntry i DirectoryEntry obiekty mają fullPath atrybut, który jest głównym systemie plików HTML. Jeśli twój plugin JavaScript API akceptuje obiektu DirectoryEntry lub FileEntry, należy zadzwonić `.toURL()` na obiekt przed przekazaniem przez most do kodu macierzystego. - -### Konwersja cdvfile: / / URL do ścieżki fileystem - -Wtyczek, które trzeba pisać do systemu plików może chcesz przekonwertować odebranych plików systemu adres URL lokalizacji rzeczywistych plików. Istnieje wiele sposobów działania, od macierzystego platformy. - -Ważne jest, aby pamiętać, że nie wszystkie `cdvfile://` adresy URL są można zmapować na prawdziwe akta urządzeniu. Niektóre adresy URL może odnosić się do aktywów na urządzeniu, które nie są reprezentowane przez pliki, lub nawet może odnosić się do zasobów zdalnych. Z powodu tych możliwości wtyczki należy zawsze sprawdzić, czy się znaczących wyników wstecz, podczas próby konwersji adresów URL do ścieżki. - -#### Android - -Na Android, najprostsza metoda konwersji `cdvfile://` URL do ścieżki systemu plików jest użycie `org.apache.cordova.CordovaResourceApi` . `CordovaResourceApi`jest kilka metod, które mogą obsługiwać `cdvfile://` adresów URL: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -Jest również możliwe, aby korzystać z wtyczki pliku bezpośrednio: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -Do przeliczenia ścieżki do `cdvfile://` adres URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -Jeśli twój plugin tworzy plik, i chcesz zwraca obiekt FileEntry dla niego, użyj pliku plugin: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -Cordova na iOS nie korzystać z tego samego `CordovaResourceApi` koncepcji jak Android. Na iOS należy użyć pliku plugin do konwersji między adresach URL i ścieżkach plików. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -Jeśli twój plugin tworzy plik, i chcesz zwraca obiekt FileEntry dla niego, użyj pliku plugin: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -W JavaScript, aby uzyskać `cdvfile://` adres URL z obiektu FileEntry lub DirectoryEntry, wystarczy zadzwonić `.toURL()` na to: - - var cdvfileURL = entry.toURL(); - - -W plugin obsługi odpowiedzi do przeliczenia strukturę FileEntry wrócił do rzeczywistego obiektu wejścia, kod obsługi należy importować pliku plugin i utworzyć nowy obiekt: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/plugins.md b/plugins/cordova-plugin-file/doc/plugins.md deleted file mode 100644 index a3329d67..00000000 --- a/plugins/cordova-plugin-file/doc/plugins.md +++ /dev/null @@ -1,120 +0,0 @@ -<!--- - 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. ---> - -Notes for plugin developers -=========================== - -These notes are primarily intended for Android and iOS developers who want to write plugins which interface with the file system using the File plugin. - -Working with Cordova file system URLs -------------------------------------- - -Since version 1.0.0, this plugin has used URLs with a `cdvfile` scheme for all communication over the bridge, rather than exposing raw device file system paths to JavaScript. - -On the JavaScript side, this means that FileEntry and DirectoryEntry objects have a fullPath attribute which is relative to the root of the HTML file system. If your plugin's JavaScript API accepts a FileEntry or DirectoryEntry object, you should call `.toURL()` on that object before passing it across the bridge to native code. - -### Converting cdvfile:// URLs to fileystem paths - -Plugins which need to write to the filesystem may want to convert a received file system URL to an actual filesystem location. There are multiple ways of doing this, depending on the native platform. - -It is important to remember that not all `cdvfile://` URLs are mappable to real files on the device. Some URLs can refer to assets on device which are not represented by files, or can even refer to remote resources. Because of these possibilities, plugins should always test whether they get a meaningful result back when trying to convert URLs to paths. - -#### Android - -On Android, the simplest method to convert a `cdvfile://` URL to a filesystem path is to use `org.apache.cordova.CordovaResourceApi`. `CordovaResourceApi` has several methods which can handle `cdvfile://` URLs: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - -It is also possible to use the File plugin directly: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - -To convert from a path to a `cdvfile://` URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - -If your plugin creates a file, and you want to return a FileEntry object for it, use the File plugin: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - -#### iOS - -Cordova on iOS does not use the same `CordovaResourceApi` concept as Android. On iOS, you should use the File plugin to convert between URLs and filesystem paths. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - -If your plugin creates a file, and you want to return a FileEntry object for it, use the File plugin: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - -#### JavaScript - -In JavaScript, to get a `cdvfile://` URL from a FileEntry or DirectoryEntry object, simply call `.toURL()` on it: - - var cdvfileURL = entry.toURL(); - -In plugin response handlers, to convert from a returned FileEntry structure to an actual Entry object, your handler code should import the File plugin and create a new object: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } - diff --git a/plugins/cordova-plugin-file/doc/ru/index.md b/plugins/cordova-plugin-file/doc/ru/index.md deleted file mode 100644 index 3c9fca9e..00000000 --- a/plugins/cordova-plugin-file/doc/ru/index.md +++ /dev/null @@ -1,275 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -Этот плагин реализует API файла, позволяя доступ на чтение и запись в файлы, находящиеся на устройстве. - -Этот плагин основан на нескольких спецификации, в том числе: HTML5 API файла <http://www.w3.org/TR/FileAPI/> - -(Ныне несуществующей) каталоги и систему расширений Последнее: <http://www.w3.org/TR/2012/WD-file-system-api-20120417/> , хотя большая часть кода, плагин был написан, когда ранее спец был текущим: <http://www.w3.org/TR/2011/WD-file-system-api-20110419/> - -Он также реализует уничтожал spec: <http://dev.w3.org/2009/dap/file-system/file-writer.html> - -Для использования, пожалуйста, обратитесь к HTML5 скалы отличные [файловой системы статьи.][1] - - [1]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -Обзор других вариантов хранения найти Cordova [хранения руководства][2]. - - [2]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -## Установка - - cordova plugin add cordova-plugin-file - - -## Поддерживаемые платформы - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows Phone 7 и 8 * -* Windows 8 * - -* *Эти платформы не поддерживают `FileReader.readAsArrayBuffer` , ни `FileWriter.write(blob)` .* - -## Где хранить файлы - -По состоянию на v1.2.0 приведены URL-адреса для важных файлов в системные каталоги. Каждый URL-адрес в виде *file:///path/to/spot/*и может быть преобразован в `DirectoryEntry` с помощью`window.resolveLocalFileSystemURL()`. - -* `cordova.file.applicationDirectory`-Каталог только для чтения, где установлено приложение. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.applicationStorageDirectory`-Корневой каталог приложения в песочнице; на iOS это место только для чтения (но определенных подкаталогов [как `/Documents` ], чтения записи). Все данные, содержащиеся в частных в приложение. ( *iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.dataDirectory`-Хранения стойкие и частных данных в приложения в песочнице с использованием внутренней памяти (на Android, если необходимо использовать внешнюю память, использовать `.externalDataDirectory` ). На iOS, этот каталог не синхронизируется с iCloud (использование `.syncedDataDirectory` ). (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.cacheDirectory`-Каталог для кэшированных данных файлов или все файлы, которые ваше приложение может повторно создать легко. ОС может удалить эти файлы, когда устройства хватает на хранение, тем не менее, приложения не должны опираться на OS, чтобы удалить файлы здесь. (*iOS*, *Android*, *BlackBerry 10*) - -* `cordova.file.externalApplicationStorageDirectory`-Пространство приложения на внешнем хранилище. (*Android*) - -* `cordova.file.externalDataDirectory`-Куда положить файлы данных конкретного приложения на внешнем хранилище. (*Android*) - -* `cordova.file.externalCacheDirectory`-Применение кэш на внешние накопители. (*Android*) - -* `cordova.file.externalRootDirectory`-Корень внешние накопители (SD карта). (*Android*, *BlackBerry 10*) - -* `cordova.file.tempDirectory`-Временный каталог, что ОС можно снять на будет. Не следует полагаться на OS, чтобы очистить этот каталог; Ваше приложение всегда следует удалять файлы в соответствующих случаях. (*iOS*) - -* `cordova.file.syncedDataDirectory`-Содержит файлы приложения, которые должны быть синхронизированы (например, к iCloud). (*iOS*) - -* `cordova.file.documentsDirectory`-Файлы для приложения, но это являются значимыми для других приложений (например, файлы Office). (*iOS*) - -* `cordova.file.sharedDirectory`-Файлы глобально доступной для всех приложений (*BlackBerry 10*) - -## Макеты файловой системы - -Хотя технически деталь реализации, она может быть очень полезно знать как `cordova.file.*` карта свойства физические пути на реальном устройстве. - -### iOS расположения файловой системы - -| Путь к устройству | `Cordova.File.*` | `iosExtraFileSystems` | r/w? | стойкие? | Очищает ОС | Синхронизация | частные | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:----:|:--------:|:----------:|:-------------:|:-------:| -| `/ var/мобильного/применения/< UUID > /` | applicationStorageDirectory | - | r | Н/Д | Н/Д | Н/Д | Да | -| `appname.app/` | applicationDirectory | расслоение | r | Н/Д | Н/Д | Н/Д | Да | -| `www/` | - | - | r | Н/Д | Н/Д | Н/Д | Да | -| `Documents/` | documentsDirectory | документы | r/w | Да | Нет | Да | Да | -| `NoCloud/` | - | документы nosync | r/w | Да | Нет | Нет | Да | -| `Library` | - | Библиотека | r/w | Да | Нет | Да? | Да | -| `NoCloud/` | dataDirectory | Библиотека nosync | r/w | Да | Нет | Нет | Да | -| `Cloud/` | syncedDataDirectory | - | r/w | Да | Нет | Да | Да | -| `Caches/` | cacheDirectory | кэш | r/w | Да * | Да * * *| | Нет | Да | -| `tmp/` | tempDirectory | - | r/w | Не * * | Да * * *| | Нет | Да | - -* Файлы сохраняются приложения перезагрузки и обновления, но этот каталог может быть очищен, когда ОС желаний. Ваше приложение должно иметь возможность воссоздать любое содержание, которое может быть удалено. - -* * Файлы могут сохраняться перезагрузками app, но не полагайтесь на это поведение. Для продолжения обновления файлов не гарантируется. Приложение должно удалить файлы из этого каталога, когда это применимо, как операционная система не гарантирует когда (или даже если) эти файлы будут удалены. - -* * *| ОС может очистить содержимое этого каталога, когда он считает это необходимым, но не полагайтесь на это. Необходимо снять этот каталог в зависимости от вашего приложения. - -### Расположения Android файловой системы - -| Путь к устройству | `Cordova.File.*` | `AndroidExtraFileSystems` | r/w? | стойкие? | Очищает ОС | частные | -|:--------------------------------- |:----------------------------------- |:------------------------- |:----:|:--------:|:----------:|:-------:| -| `File:///android_asset/` | applicationDirectory | | r | Н/Д | Н/Д | Да | -| `/ Data/data/< app-id > /` | applicationStorageDirectory | - | r/w | Н/Д | Н/Д | Да | -| `cache` | cacheDirectory | кэш | r/w | Да | Да * | Да | -| `files` | dataDirectory | файлы | r/w | Да | Нет | Да | -| `Documents` | | документы | r/w | Да | Нет | Да | -| `< sdcard > /` | externalRootDirectory | SDCard | r/w | Да | Нет | Нет | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | Да | Нет | Нет | -| `cache` | externalCacheDirectry | кэш внешние | r/w | Да | Не * * | Нет | -| `files` | externalDataDirectory | файлы внешние | r/w | Да | Нет | Нет | - -* ОС может периодически удалять этот каталог, но не полагайтесь на это поведение. Очистите содержимое этого каталога в зависимости от вашего приложения. Если пользователь вручную очистить кэш, содержимое этого каталога будут удалены. - -* * ОС не ясно этот каталог автоматически; Вы несете ответственность за управление содержимым самостоятельно. Если пользователь вручную очистить кэш, содержимое каталога будут удалены. - -**Примечание**: Если нельзя монтировать внешние накопители, `cordova.file.external*` Свойства`null`. - -### BlackBerry 10 расположения файловой системы - -| Путь к устройству | `Cordova.File.*` | r/w? | стойкие? | Очищает ОС | частные | -|:--------------------------------------------------- |:--------------------------- |:----:|:--------:|:----------:|:-------:| -| `File:///Accounts/1000/AppData/ < app id > /` | applicationStorageDirectory | r | Н/Д | Н/Д | Да | -| `app/native` | applicationDirectory | r | Н/Д | Н/Д | Да | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | Нет | Да | Да | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | Да | Нет | Да | -| `File:///Accounts/1000/Removable/SDCard` | externalRemovableDirectory | r/w | Да | Нет | Нет | -| `File:///Accounts/1000/Shared` | sharedDirectory | r/w | Да | Нет | Нет | - -*Примечание*: при развертывании приложения для работы периметра, все пути относительны /accounts/1000-enterprise. - -## Особенности Android - -### Местоположение Android постоянного хранения - -Есть несколько допустимых мест для хранения постоянных файлов на устройстве Android. Смотрите [эту страницу][3] для широкого обсуждения различных возможностей. - - [3]: http://developer.android.com/guide/topics/data/data-storage.html - -Предыдущие версии плагина будет выбирать расположение временных и постоянных файлов при запуске, основанный на ли устройство утверждал, что SD-карта (или эквивалентные хранения раздел) был смонтирован. Если была смонтирована SD-карты, или если большой внутренней памяти раздел был доступен (такие как на устройствах Nexus,), то постоянные файлы будут храниться в корне этого пространства. Это означало, что все apps Cordova могли видеть все файлы, имеющиеся на карте. - -Если SD-карты не был доступен, то предыдущих версий будет хранить данные в `/data/data/<packageId>` , которая изолирует приложения друг от друга, но все еще может причина данные распределяются между пользователями. - -Это теперь можно выбрать, следует ли хранить файлы в месте хранения внутренних файлов, или с использованием предыдущей логики, с предпочтением в вашем приложении `config.xml` файл. Чтобы сделать это, добавить один из этих двух линий в `config.xml` : - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -Без этой линии, будет использовать файл плагина `Compatibility` по умолчанию. Если тег предпочтений присутствует и не является одним из этих значений, приложение не запустится. - -Если ранее была отгружена приложения для пользователей, используя старые (до 1.0) версию этого плагина и имеет сохраненные файлы в файловой системе постоянных, то вы должны установить предпочтения `Compatibility` . Переключение местоположение для «Внутреннего» будет означать, что существующие пользователи, которые обновить их применение может быть не в состоянии получить доступ к их сохраненные ранее файлы, в зависимости от их устройства. - -Если ваше приложение является новым или ранее никогда не хранит файлы в стойких файловой системы, то `Internal` как правило рекомендуется настройка. - -## Особенности iOS - -* `cordova.file.applicationStorageDirectory`доступен только для чтения; попытка хранения файлов в корневом каталоге не удастся. Использовать один из других `cordova.file.*` свойства, определенные для iOS (только `applicationDirectory` и `applicationStorageDirectory` доступны только для чтения). -* `FileReader.readAsText(blob, encoding)` - * `encoding`Параметр не поддерживается, и UTF-8 кодирование действует всегда. - -### iOS место постоянного хранения - -Существует два допустимых местоположений для хранения постоянных файлов на устройства iOS: документы каталогов и библиотека. Предыдущие версии плагина только когда-либо постоянные файлы хранятся в папке документы. Это был побочный эффект делает все файлы приложения в iTunes, который часто был непреднамеренным, особенно для приложений, которые обрабатывают большое количество мелких файлов, вместо того, чтобы производить полный комплект документов для экспорта, который является цель каталога. - -Это теперь можно выбрать, следует ли хранить файлы в документы или каталоге библиотеки, с предпочтением в вашем приложении `config.xml` файл. Чтобы сделать это, добавить один из этих двух линий в `config.xml` : - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -Без этой линии, будет использовать файл плагина `Compatibility` по умолчанию. Если тег предпочтений присутствует и не является одним из этих значений, приложение не запустится. - -Если ранее была отгружена приложения для пользователей, используя старые (до 1.0) версию этого плагина и имеет сохраненные файлы в файловой системе постоянных, то вы должны установить предпочтения `Compatibility` . Переключение расположения `Library` будет означать, что существующих пользователей обновить их применения будет не в состоянии получить доступ к их сохраненные ранее файлы. - -Если ваше приложение является новым или ранее никогда не хранит файлы в стойких файловой системы, то `Library` как правило рекомендуется настройка. - -## Особенности Firefox OS - -API файловой системы изначально не поддерживается Firefox OS и реализуется как оболочка поверх indexedDB. - -* Не вынимая непустые каталоги -* Не поддерживает метаданные для каталогов -* Методы `copyTo` и `moveTo` не поддерживает каталоги - -Поддерживаются следующие пути данных: * `applicationDirectory` -использует `xhr` чтобы получить локальные файлы, которые упакованы с приложением. * `dataDirectory` - Для постоянных данных конкретного приложения файлов. * `cacheDirectory` -Кэшированных файлов, которые должны выжить перезагрузки приложения (Apps не следует полагаться на OS, чтобы удалить файлы из здесь). - -## Обновление примечания - -В v1.0.0 этого плагина `FileEntry` и `DirectoryEntry` структур изменились, более соответствует опубликованной спецификации. - -Предыдущий (pre-1.0.0) версии плагина хранятся устройства Абсолют файл расположение в `fullPath` свойства `Entry` объектов. Эти пути обычно будет выглядеть - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -Эти пути также были возвращены `toURL()` метода `Entry` объектов. - -С v1.0.0 `fullPath` атрибут является путь к файлу, *заданный относительно корня файловой системы HTML*. Таким образом, выше пути будет теперь оба быть представлено `FileEntry` объект с `fullPath` из - - /path/to/file - - -Если ваше приложение работает с устройства Абсолют путями, и ранее были получены эти пути через `fullPath` свойства `Entry` объектов, то вам следует обновить код для использования `entry.toURL()` вместо этого. - -Для обратной совместимости, `resolveLocalFileSystemURL()` метод будет принимать путь Абсолют устройства и будет возвращать `Entry` объект, соответствующий его, до тех пор, как этот файл существует в рамках либо `TEMPORARY` или `PERSISTENT` файловых систем. - -Это особенно была проблема с плагином передачи файлов, который ранее использовался устройства Абсолют пути (и все еще может принять их). Он был обновлен для корректной работы с файловой системы URL, так что замена `entry.fullPath` с `entry.toURL()` должен решить любые вопросы, получить этот плагин для работы с файлами на устройстве. - -В v1.1.0 возвращаемое значение из `toURL()` был изменен (см. \[CB-6394\] (https://issues.apache.org/jira/browse/CB-6394)) для возвращения URL-адрес абсолютным «file://». где это возможно. Для обеспечения ' cdvfile:'-вы можете использовать URL-адрес `toInternalURL()` сейчас. Этот метод будет возвращать теперь файловой системы URL формы - - cdvfile://localhost/persistent/path/to/file - - -который может использоваться для уникальной идентификации файла. - -## Список кодов ошибок и значения - -Когда возникает ошибка, один из следующих кодов будет использоваться. - -| Код | Постоянная | -| ---:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## Настройка плагина (опционально) - -Набор доступных файловых систем может быть настроен на платформе. IOS и Android признают <preference> тег в `config.xml` имена которых файловые системы для установки. По умолчанию включены все корни файловой системы. - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android - -* `files`: Каталог для хранения внутреннего файла приложения -* `files-external`: Каталог хранения внешнего файла приложения -* `sdcard`: Глобальный внешний файл каталог хранения (это корень SD-карты, если таковая установлена). Вы должны иметь `android.permission.WRITE_EXTERNAL_STORAGE` разрешение использовать это. -* `cache`: Каталог внутреннего кэша приложения -* `cache-external`: Каталог приложения внешней кэш-памяти -* `root`: Все устройство файловой системы - -Android поддерживает также Специальный файловую систему под названием «документы», которая представляет подкаталог «/ документы /» в пределах файловой системы «файлы». - -### iOS - -* `library`: Каталог библиотеки приложения -* `documents`: Каталог документов приложения -* `cache`: Каталог кэша приложения -* `bundle`: Пакет приложения; расположение самого приложения на диске (только для чтения) -* `root`: Все устройство файловой системы - -По умолчанию каталоги библиотеки и документы можно синхронизировать с iCloud. Вы также можете заказать два дополнительных файловых систем, `library-nosync` и `documents-nosync` , которые представляют Специальный каталог не синхронизируются в `/Library` или `/Documents` файловой системы. diff --git a/plugins/cordova-plugin-file/doc/ru/plugins.md b/plugins/cordova-plugin-file/doc/ru/plugins.md deleted file mode 100644 index 2445d09d..00000000 --- a/plugins/cordova-plugin-file/doc/ru/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# Примечания для разработчиков плагинов - -Эти примечания предназначены прежде всего для Android и iOS разработчиков, которые хотят писать плагины какой интерфейс с файловой системой, с помощью файла плагина. - -## Работа с Кордова файловой системы URL - -Начиная с версии 1.0.0, этот плагин использует URL-адресов с `cdvfile` схема для всех коммуникации через мост, а не подвергая пути файловой системы raw устройства для JavaScript. - -На стороне JavaScript это означает, что объекты DirectoryEntry и FileEntry fullPath атрибут, который является по отношению к корневой файловой системе HTML. Если ваш плагин JavaScript API принимает объект DirectoryEntry или FileEntry, необходимо вызвать `.toURL()` для этого объекта перед передачей их через мост в машинный код. - -### Преобразование cdvfile: / / URL-адреса в пути fileystem - -Плагины, которые нужно написать в файловой системе может потребоваться преобразовать URL-адреса системы полученный файл в место фактической файловой системы. Существует несколько способов сделать это, в зависимости от родной платформе. - -Важно помнить, что не все `cdvfile://` URL-адреса являются отображаемыми файлами на устройстве. Некоторые URL может относиться к активам на устройстве, которые не представлены файлы, или может даже обратиться к удаленным ресурсам. Из-за эти возможности плагины следует всегда проверять ли они получают результат обратно при попытке преобразовать URL-адреса в пути. - -#### Android - -На Android, самый простой способ для преобразования `cdvfile://` URL-адрес к пути файловой системы заключается в использовании `cordova-plugin-CordovaResourceApi` . `CordovaResourceApi`Есть несколько методов, которые можно обработать `cdvfile://` URL-адреса: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -Это также можно использовать плагин файл непосредственно: - - import cordova-plugin-file.FileUtils; - import cordova-plugin-file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -Для преобразования пути к `cdvfile://` URL-адрес: - - import cordova-plugin-file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -Если ваш плагин создает файл, и вы хотите вернуть объект FileEntry для него, используйте файл плагина: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -Кордова на iOS не использовать те же `CordovaResourceApi` понятие, как Android. На iOS вы должны использовать файл плагин для преобразования URL-адреса и пути файловой системы. - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -Если ваш плагин создает файл, и вы хотите вернуть объект FileEntry для него, используйте файл плагина: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -В JavaScript, чтобы получить `cdvfile://` URL от объекта DirectoryEntry или FileEntry, просто позвоните `.toURL()` на него: - - var cdvfileURL = entry.toURL(); - - -В плагин обработчики ответ для преобразования из возвращаемой структуры FileEntry объект фактического вступления, код обработчика следует импортировать файл плагина и создайте новый объект: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } diff --git a/plugins/cordova-plugin-file/doc/zh/README.md b/plugins/cordova-plugin-file/doc/zh/README.md deleted file mode 100644 index c6005878..00000000 --- a/plugins/cordova-plugin-file/doc/zh/README.md +++ /dev/null @@ -1,335 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-file - -[](https://travis-ci.org/apache/cordova-plugin-file) - -這個外掛程式實現檔 API 允許對檔駐留在該設備上的讀/寫訪問。 - -這個外掛程式基於幾個規格,包括: HTML5 檔 API [HTTP://www.w3.org/TR/FileAPI/](http://www.w3.org/TR/FileAPI/) - -(現已解散) 目錄和系統擴展最新: [HTTP://www.w3.org/TR/2012/WD-file-system-api-20120417/](http://www.w3.org/TR/2012/WD-file-system-api-20120417/)雖然大部分的外掛程式代碼寫時較早的規格是當前: [HTTP://www.w3.org/TR/2011/WD-file-system-api-20110419/](http://www.w3.org/TR/2011/WD-file-system-api-20110419/) - -它還實現 FileWriter 規格: [HTTP://dev.w3.org/2009/dap/file-system/file-writer.html](http://dev.w3.org/2009/dap/file-system/file-writer.html) - -用法,請參閱對 HTML5 的岩石優秀[檔案系統文章。](http://www.html5rocks.com/en/tutorials/file/filesystem/) - -其他存儲選項的概述,請參閱科爾多瓦的[存儲指南](http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html). - -這個外掛程式定義全球 `cordova.file` 物件。 - -雖然在全球範圍內,它不可用直到 `deviceready` 事件之後。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## 安裝 - - cordova plugin add cordova-plugin-file - - -## 支援的平臺 - - * 亞馬遜火 OS - * Android 系統 - * 黑莓 10 - * 火狐瀏覽器作業系統 - * iOS - * Windows Phone 7 和 8 * - * Windows 8 * - * Windows* - * 瀏覽器 - -\* *These platforms do not support `FileReader.readAsArrayBuffer` nor `FileWriter.write(blob)`.* - -## 存儲檔的位置 - -截至 v1.2.0,提供重要的檔案系統目錄的 Url。 每個 URL 位於表單 *file:///path/to/spot/*,和可以轉換為使用 `window.resolveLocalFileSystemURL()` 的 `DirectoryEntry`. - - * `cordova.file.applicationDirectory`-唯讀目錄在哪裡安裝的應用程式。(*iOS*、*安卓*、*黑莓 10*) - - * `cordova.file.applicationStorageDirectory`-根目錄下的應用程式的沙箱 ;在 iOS 上此位置是唯讀 (但特定的子目錄 [像 `/Documents` ] 都是讀寫)。 中包含的所有資料都是私有的應用程式。 ( *iOS*、*安卓*、*黑莓 10*) - - * `cordova.file.dataDirectory`資料持久性和私有資料存儲在內部記憶體使用的應用程式的沙箱內 (在安卓系統,如果你需要使用外部儲存體,使用 `.externalDataDirectory` )。 在 iOS,此目錄不與 iCloud 同步 (使用 `.syncedDataDirectory` )。 (*iOS*、*安卓*、*黑莓 10*) - - * `cordova.file.cacheDirectory`-緩存的資料檔案或您的應用程式重新可以輕鬆地創建的任何檔的目錄。 作業系統可能會刪除這些檔,該設備在存儲上運行低時,然而,應用程式不應依賴的作業系統,請刪除檔在這裡。 (*iOS*、*安卓*、*黑莓 10*) - - * `cordova.file.externalApplicationStorageDirectory`-應用程式外部存儲上的空間。(*安卓*) - - * `cordova.file.externalDataDirectory`-放在外部存儲特定于應用程式的資料檔案的位置。(*安卓*) - - * `cordova.file.externalCacheDirectory`-在外部存儲應用程式緩存。(*安卓*) - - * `cordova.file.externalRootDirectory`-外部存儲 (SD 卡) 的根。(*安卓*、*黑莓 10*) - - * `cordova.file.tempDirectory`-OS 可以清除時的空目錄會。 不依賴于 OS,以清除此目錄 ;您的應用程式,應總是移除作為適用的檔。 (*iOS*) - - * `cordova.file.syncedDataDirectory`-保存應同步 (例如到 iCloud) 的特定于應用程式的檔。(*iOS*) - - * `cordova.file.documentsDirectory`-檔私有的應用程式,但這是對其他應用程式 (例如 Office 檔) 有意義。(*iOS*) - - * `cordova.file.sharedDirectory`-對所有應用程式 (*黑莓 10*全域可用的檔) - -## 檔案系統佈局 - -雖然技術上實現的細節,它可以是很有必要瞭解如何 `cordova.file.*` 屬性對應到實體路徑在實際設備上。 - -### iOS 檔案系統佈局 - -| 設備路徑 | `cordova.file.*` | `iosExtraFileSystems` | r/w 嗎? | 持續性嗎? | OS 清除 | 同步 | 私人 | -|:---------------------------------------------- |:--------------------------- |:--------------------- |:------:|:-------:|:------------:|:---:|:--:| -| `/ 無功/移動/應用程式/< UUID > /` | applicationStorageDirectory | - | r | 不適用 | 不適用 | 不適用 | 是啊 | -| `appname.app/` | applicationDirectory | 束 | r | 不適用 | 不適用 | 不適用 | 是啊 | -| `www/` | - | - | r | 不適用 | 不適用 | 不適用 | 是啊 | -| `Documents/` | documentsDirectory | 檔 | r/w | 是啊 | 無 | 是啊 | 是啊 | -| `NoCloud/` | - | 檔 nosync | r/w | 是啊 | 無 | 無 | 是啊 | -| `Library` | - | 圖書館 | r/w | 是啊 | 無 | 是嗎? | 是啊 | -| `NoCloud/` | dataDirectory | 圖書館 nosync | r/w | 是啊 | 無 | 無 | 是啊 | -| `Cloud/` | syncedDataDirectory | - | r/w | 是啊 | 無 | 是啊 | 是啊 | -| `Caches/` | cacheDirectory | 快取記憶體 | r/w | 是啊 * | 是啊**\* | 無 | 是啊 | -| `tmp/` | tempDirectory | - | r/w | 無** | 是啊**\* | 無 | 是啊 | - -\ * 檔堅持跨應用程式重新開機和升級,但每當 OS 的欲望,可以清除此目錄。您的應用程式應該能夠重新創建任何內容可能會被刪除。 - -**檔可能會持續整個應用程式重新開機,但不是依賴于這種行為。 不保證檔在更新之間持續存在。 您的應用程式時適用,是應該刪除此目錄的檔,因為作業系統並不能保證何時 (或即使) 中刪除這些檔。 - -**\ * 作業系統可能會清除此目錄的內容,每當它感覺它是必要的但做不依賴于此。 你應該清除此目錄為適合您的應用程式。 - -### Android 的檔案系統佈局 - -| 設備路徑 | `cordova.file.*` | `AndroidExtraFileSystems` | r/w 嗎? | 持續性嗎? | OS 清除 | 私人 | -|:------------------------------------------------ |:----------------------------------- |:------------------------- |:------:|:-----:|:-------:|:--:| -| `file:///android_asset/` | applicationDirectory | | r | 不適用 | 不適用 | 是啊 | -| `/ 資料資料/< 應用程式 id > /` | applicationStorageDirectory | - | r/w | 不適用 | 不適用 | 是啊 | -| `cache` | cacheDirectory | 快取記憶體 | r/w | 是啊 | 是啊\* | 是啊 | -| `files` | dataDirectory | 檔 | r/w | 是啊 | 無 | 是啊 | -| `Documents` | | 檔 | r/w | 是啊 | 無 | 是啊 | -| `< sd 卡 > /` | externalRootDirectory | sd 卡 | r/w | 是啊 | 無 | 無 | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | 是啊 | 無 | 無 | -| `cache` | externalCacheDirectry | 外部快取記憶體 | r/w | 是啊 | 無** | 無 | -| `files` | externalDataDirectory | 外部檔 | r/w | 是啊 | 無 | 無 | - -\ * 作業系統可能定期清除此目錄,但不是依賴于這種行為。 清除此為適合您的應用程式的目錄的內容。 使用者應手動清除緩存,將刪除此目錄的內容。 - -** OS 不會清除此目錄自動;你是負責管理自己的內容。 使用者應手動清除緩存,目錄中的內容將被刪除。 - -**注**: 如果外部存儲無法裝入,`cordova.file.external*` 屬性為 `空`. - -### 黑莓 10 檔案系統佈局 - -| 設備路徑 | `cordova.file.*` | r/w 嗎? | 持續性嗎? | OS 清除 | 私人 | -|:----------------------------------------------------------- |:--------------------------- |:------:|:-----:|:-----:|:--:| -| `file:///accounts/1000/appdata/ < 應用程式 id > /` | applicationStorageDirectory | r | 不適用 | 不適用 | 是啊 | -| `app/native` | applicationDirectory | r | 不適用 | 不適用 | 是啊 | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | 無 | 是啊 | 是啊 | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | 是啊 | 無 | 是啊 | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | 是啊 | 無 | 無 | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | 是啊 | 無 | 無 | - -*注意*: 當應用程式部署工作週邊時,所有路徑都是相對於 /accounts/1000-enterprise。 - -## Android 的怪癖 - -### Android 的持久性存儲位置 - -有很多有效的位置來存儲持久性檔在 Android 設備上。 請參閱 [此頁面](http://developer.android.com/guide/topics/data/data-storage.html) 的各種可能性進行廣泛討論。 - -以前版本的外掛程式會選擇在啟動時,基於該設備是否聲稱 SD 卡 (或等效存儲分區) 展開,臨時和永久檔的位置。 如果被掛載 SD 卡,或一個大的內部存儲分區可用 (如 nexus 系列設備上) 然後持久性檔將存儲在該空間的根目錄中。 這意味著所有的科爾多瓦應用程式可以看到所有可用的檔在卡片上。 - -如果 SD 卡不是可用的那麼以前的版本中將存儲資料下的 `/data/data/<packageId>`,其中隔離應用程式從彼此,但仍可能導致使用者之間共用的資料。 - -現在可以選擇是否將檔存儲在內部檔的存儲位置,或使用以前的邏輯,與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作,請將以下兩行之一添加到 `config.xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -如果這條線,沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在,並不是這些值之一,應用程式將無法啟動。 - -如果您的應用程式以前已被運到使用者,使用較舊的 (預 1.0) 版本的這個外掛程式,並具有持久性的檔,系統中存儲的檔,然後您應該設置 `Compatibility` 偏好。 切換到"Internal"的位置,將意味著現有使用者升級他們的應用程式可能無法訪問他們以前存儲的檔,具體取決於他們的設備。 - -如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔,那麼通常建議使用 `Internal` 設置。 - -### 緩慢的遞迴操作為 /android_asset 的 - -上市資產目錄是在 android 系統很慢的。 你可以讓時間加速了不過,通過將`src/android/build-extras.gradle`添加到您的 android 專案的根 (也需要 cordova-android@4.0.0 或更高版本)。 - -## iOS 的怪癖 - - * `cordova.file.applicationStorageDirectory`是唯讀的 ;試圖存儲內的根目錄中的檔將會失敗。 使用的另一個 `cordova.file.*` 為 iOS 定義的屬性 (只有 `applicationDirectory` 和 `applicationStorageDirectory` 都是唯讀)。 - * `FileReader.readAsText(blob, encoding)` - * `encoding`參數不受支援,而 utf-8 編碼總是效果。 - -### iOS 的持久性存儲位置 - -有兩個有效的位置來存儲持久性在 iOS 設備上的檔: 檔目錄和圖書館目錄。 以前版本的外掛程式永遠只能將持久性檔存儲在文檔目錄中。 這已經使所有應用程式檔可見在 iTunes,往往是無意為之,尤其是對於處理大量小檔的應用程式中,而不是生產供出口,該目錄的既定的目標是證件齊全的副作用。 - -現在可以選擇是否將檔存儲在檔或庫目錄,與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作,請將以下兩行之一添加到 `config.xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -如果這條線,沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在,並不是這些值之一,應用程式將無法啟動。 - -如果您的應用程式以前已被運到使用者,使用較舊的 (預 1.0) 版本的這個外掛程式,並具有持久性的檔,系統中存儲的檔,然後您應該設置 `Compatibility` 偏好。 切換到 `Library` 的位置,將意味著現有使用者升級他們的應用程式將無法訪問他們以前存儲的檔。 - -如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔,那麼通常建議使用 `Internal` 設置。 - -## 火狐瀏覽器作業系統的怪癖 - -檔案系統 API 本身不支援火狐瀏覽器的作業系統,作為墊片在 indexedDB 上實現的。 - - * 不會失敗時刪除非空的目錄 - * 不支援中繼資料的目錄 - * 方法 `copyTo` 和 `moveTo` 不支援目錄 - -支援以下資料路徑: * `applicationDirectory`-使用 `xhr` 獲取與應用程式打包的本地檔。 `dataDirectory`-用於持久性的特定于應用程式的資料檔案。 `cacheDirectory`-生存應重新開機應用程式的快取檔案 (應用程式不應依賴作業系統來刪除檔在這裡)。 - -## 瀏覽器的怪癖 - -### 常見的怪癖和備註 - - * 每個瀏覽器使用其自己的沙箱檔案系統。IE 和火狐瀏覽器使用 IndexedDB 作為一個基地。所有瀏覽器都使用正斜杠作為路徑中的目錄分隔符號。 - * 目錄條目不得不先後創建。 例如,調用 `fs.root.getDirectory (' dir1/dir2 ',{create:true},successCallback,errorCallback)`,如果不存在 dir1 將失敗。 - * 外掛程式將請求使用者許可權,以便在應用程式初次開機使用持久性存儲。 - * 外掛程式支援 `cdvfile://localhost` (本地資源) 只。通過 `cdvfile` 不支援外部資源即. - * 該外掛程式不遵循 ["檔案系統 API 8.3 命名限制"](http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions). - * Blob 和檔 ' `close` 功能不受支援。 - * `FileSaver` 和 `BlobBuilder` 不支援這個外掛程式,沒有存根 (stub)。 - * 該外掛程式不支援 `requestAllFileSystems`。這個功能也是缺少規範中。 - * 在目錄中的條目將不會被刪除,如果您使用 `create: true` 標誌為現有目錄。 - * 不支援通過建構函式創建的檔。你應該使用 entry.file 方法。 - * 每個瀏覽器使用它自己的形式為 blob 的 URL 引用。 - * 支援 `readAsDataURL` 功能,但在 Chrome 中的媒體類型取決於輸入副檔名,在 IE 中的媒體類型都始終空著 (這是 `純文字` 按照說明書一樣),在 Firefox 中的媒體類型始終是 `應用程式/八位位元組流`。 例如,如果內容是 `abcdefg` 然後火狐瀏覽器返回 `資料: 應用程式 / 八位位元組流 ; base64,YWJjZGVmZw = =`,即返回 `資料: ; base64,YWJjZGVmZw = =`,鉻返回 `資料: < 媒體類型根據擴展條目名稱 > ; base64,YWJjZGVmZw = =`. - * 在表單 `file:///persistent/path/to/entry` 火狐瀏覽器 IE),`toInternalURL` 返回的路徑。 鉻在表單 `cdvfile://localhost/persistent/file` 返回的路徑. - -### 鉻的怪癖 - - * 設備準備好事件之後,chrome 檔案系統並不能立即準備。作為一種變通方法,您可以訂閱到 `filePluginIsReady` 事件。示例: - -```javascript -window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); -``` - -你可以使用 `window.isFilePluginReadyRaised` 函數來檢查是否已經引發了事件。 -window.requestFileSystem 臨時和永久性檔案系統配額並不局限于鉻。 為增加中鉻的持久性存儲,您需要調用 `window.initPersistentFileSystem` 方法。 預設情況下,持久性存儲配額為 5 MB。 鉻需要 `— — 允許--訪問-從-檔` 通過 `file:///` 協定運行參數對 API 的支援。 -如果您使用標誌,將不更改 `檔` 物件 `{create:true}` 現有 `條目` 的時候。 -事件 `可取消` 屬性設置為 true 在 Chrome 中。 這是違反了 [規範](http://dev.w3.org/2009/dap/file-system/file-writer.html)。 -中鉻的 `toURL` 函數返回 `檔案系統:`-首碼路徑具體取決於應用程式主機。 例如,`filesystem:file:///persistent/somefile.txt`,`filesystem:HTTP://localhost:8080/persistent/somefile.txt`。 -`toURL` 函數結果不包含尾部反斜線在目錄條目的情況下。 鉻雖然正確解析目錄帶斜杠落後的 url。 -`resolveLocalFileSystemURL` 方法需要入站的 `url` 必須具有 `檔案系統` 首碼。 例如,`resolveLocalFileSystemURL` 的 `url` 參數應在表單 `filesystem:file:///persistent/somefile.txt` 而不是表單 `file:///persistent/somefile.txt` 在安卓系統。 -不推薦使用 `toNativeURL` 函數不受支援,並且沒有存根 (stub)。 -`setMetadata` 功能是沒有說出的規格,並且不支援。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 SYNTAX_ERR(code: 8) 上請求一個不存在的檔案系統。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 PATH_EXISTS_ERR(code: 12) 上嘗試專門創建一個檔或目錄,它已經存在。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 NO_MODIFICATION_ALLOWED_ERR(code: 6) 在試圖調用 removeRecursively 的根檔案系統上。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 NOT_FOUND_ERR(code: 1) 試到 moveTo 目錄不存在。 - -### 基於 IndexedDB 的 impl 怪癖 (Firefox 和 IE) - - * `.` 和 `.` 不受支援。 - * IE 不支援 `file:///`-模式 ;只有託管的模式是支援 (HTTP://localhost:xxxx)。 - * 火狐瀏覽器的檔案系統大小不是有限,但每個 50 MB 擴展會要求使用者的許可權。 IE10 允許達 10 mb 的 AppCache 和 IndexedDB 檔案系統的實現中使用而不會提示,一旦你達到這一水準你會詢問您是否允許它增加到每個網站的 250 mb 的最大合併。 所以 `requestFileSystem` 函數的 `大小` 參數並不影響檔案系統相容 Firefox 和 IE。 - * `readAsBinaryString` 函數在規範中沒有注明不支援在 IE 中和沒有存根 (stub)。 - * `file.type` 始終為 null。 - * 您不應創建條目使用已刪除的目錄實例回檔結果。否則,你會得到一個 '掛條目'。 - * 您可以讀取一個檔,其中只是寫之前你需要獲得的此檔的新實例。 - * `setMetadata` 函數,在規範中沒有注明支援 `modificationTime` 欄位的更改。 - * `copyTo` 和 `moveTo` 函數不支援目錄。 - * 不支援目錄的中繼資料。 - * 兩個 Entry.remove 和 directoryEntry.removeRecursively 不失敗時刪除非空的目錄-相反與內容一起清理目錄被刪除。 - * 不支援 `abort` 和 `truncate` 函數。 - * 進度事件不會觸發。例如,將不執行此處理程式: - -```javascript -writer.onprogress = function() { /*commands*/ }; -``` - -## 升級筆記 - -在這個外掛程式 v1.0.0,`FileEntry` 和 `DirectoryEntry` 的結構已經改變,以更加一致的已發表說明書。 - -以前 (pre-1.0.0) 版本的外掛程式中 `輸入` 物件的 `完整路徑` 屬性存放裝置固定檔案位置。這些路徑通常會看起來像 - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -這些路徑還返回的 `Entry` 物件的 `toURL()` 方法。 - -與 v1.0.0,`完整路徑` 屬性是到檔中,*相對於 HTML 檔案系統的根目錄* 的路徑。 因此,上述路徑會現在都由一個 `FileEntry` 物件的 `完整路徑`, - - /path/to/file - - -如果您的應用程式與設備-絕對路徑,並且您以前檢索到這些路徑通過 `條目` 物件的 `完整路徑` 屬性,然後您應該更新您的代碼以改用 `entry.toURL()`。 - -為向後相容性,`resolveLocalFileSystemURL()` 方法將接受一個設備-絕對路徑,並將返回相應的 `條目` 物件,只要在 `臨時` 或 `永久性` 的檔案系統內的檔是否存在。 - -這尤其是一直與檔案傳輸外掛程式,以前使用設備絕對路徑的問題 (和仍然可以接受他們)。 已更新它能夠正常運行與檔案系統的 Url,所以用 `entry.toURL()` 替換 `entry.fullPath` 應解決任何問題,得到該外掛程式來處理設備上的檔。 - -在 v1.1.0 `toURL()` 的傳回值被更改 (見 [CB-6394] (HTTPs://issues.apache.org/jira/browse/CB-6394)) 為返回絕對 file:// URL。 只要有可能。 確保 'cdvfile:' — — 你現在可以用 `toInternalURL()` 的 URL。 現在,此方法將返回檔案系統表單的 Url - - cdvfile://localhost/persistent/path/to/file - - -它可以用於唯一地標識該檔。 - -## 錯誤代碼及其含義的清單中 - -當拋出一個錯誤時,將使用以下代碼之一。 - -| 代碼 | 恒 | -| --:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## 配置外掛程式 (可選) - -可用的檔案系統的一整套可以配置每個平臺。IOS 和安卓系統認識到 <preference> 在 `config.xml` 名稱要安裝的檔案系統中的標記。預設情況下,啟用所有檔案系統的根。 - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android 系統 - - * `files`: 該應用程式的內部檔存儲目錄 - * `files-external`: 應用程式的外部檔存儲目錄 - * `sdcard`: 全球外部檔存儲目錄 (如果安裝了一個,這是 SD 卡的根目錄)。 你必須具有 `android.permission.WRITE_EXTERNAL_STORAGE` 許可權,用這個。 - * `cache`: 應用程式的內部緩存目錄 - * `cache-external`: 應用程式的外部快取記憶體目錄 - * `root`: 整個設備的檔案系統 - -安卓系統還支援特殊的檔命名為"檔",表示"/ 檔 /""檔"的檔案系統中的子目錄。 - -### iOS - - * `library`: 應用程式的庫目錄 - * `documents`: 應用程式的檔目錄 - * `cache`: 應用程式的緩存目錄 - * `bundle`: 應用程式的包 ;應用程式本身 (唯讀) 的磁片上的位置 - * `root`: 整個設備的檔案系統 - -預設情況下,圖書館和檔目錄可以同步到 iCloud。 您也可以要求兩個額外的檔案系統、 `library-nosync` 和 `documents-nosync`,代表一個特殊的非同步目錄內 `/Library` 或 `/Documents` 的檔案系統。
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/doc/zh/index.md b/plugins/cordova-plugin-file/doc/zh/index.md deleted file mode 100644 index 6eec44de..00000000 --- a/plugins/cordova-plugin-file/doc/zh/index.md +++ /dev/null @@ -1,343 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-file - -這個外掛程式實現檔 API 允許對檔駐留在該設備上的讀/寫訪問。 - -這個外掛程式基於幾個規格,包括: HTML5 檔 API [HTTP://www.w3.org/TR/FileAPI/][1] - - [1]: http://www.w3.org/TR/FileAPI/ - -(現已解散) 目錄和系統擴展最新: [HTTP://www.w3.org/TR/2012/WD-file-system-api-20120417/][2]雖然大部分的外掛程式代碼寫時較早的規格是當前: [HTTP://www.w3.org/TR/2011/WD-file-system-api-20110419/][3] - - [2]: http://www.w3.org/TR/2012/WD-file-system-api-20120417/ - [3]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/ - -它還實現 FileWriter 規格: [HTTP://dev.w3.org/2009/dap/file-system/file-writer.html][4] - - [4]: http://dev.w3.org/2009/dap/file-system/file-writer.html - -用法,請參閱對 HTML5 的岩石優秀[檔案系統文章。][5] - - [5]: http://www.html5rocks.com/en/tutorials/file/filesystem/ - -其他存儲選項的概述,請參閱科爾多瓦的[存儲指南][6]. - - [6]: http://cordova.apache.org/docs/en/edge/cordova_storage_storage.md.html - -這個外掛程式定義全球 `cordova.file` 物件。 - -雖然在全球範圍內,它不可用直到 `deviceready` 事件之後。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(cordova.file); - } - - -## 安裝 - - cordova plugin add cordova-plugin-file - - -## 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* 黑莓 10 -* 火狐瀏覽器的作業系統 -* iOS -* Windows Phone 7 和 8 * -* Windows 8 * -* 瀏覽器 - -* *這些平臺不支援 `FileReader.readAsArrayBuffer` 或 `FileWriter.write(blob)`.* - -## 存儲檔的位置 - -截至 v1.2.0,提供重要的檔案系統目錄的 Url。 每個 URL 位於表單 *file:///path/to/spot/*,和可以轉換為使用 `window.resolveLocalFileSystemURL()` 的 `DirectoryEntry`. - -* `cordova.file.applicationDirectory`-唯讀目錄在哪裡安裝的應用程式。(*iOS*、*安卓*、*黑莓 10*) - -* `cordova.file.applicationStorageDirectory`-根目錄下的應用程式的沙箱 ;在 iOS 上此位置是唯讀 (但特定的子目錄 [像 `/Documents` ] 都是讀寫)。 中包含的所有資料都是私有的應用程式。 ( *iOS*、*安卓*、*黑莓 10*) - -* `cordova.file.dataDirectory`資料持久性和私有資料存儲在內部記憶體使用的應用程式的沙箱內 (在安卓系統,如果你需要使用外部儲存體,使用 `.externalDataDirectory` )。 在 iOS,此目錄不與 iCloud 同步 (使用 `.syncedDataDirectory` )。 (*iOS*、*安卓*、*黑莓 10*) - -* `cordova.file.cacheDirectory`-緩存的資料檔案或您的應用程式重新可以輕鬆地創建的任何檔的目錄。 作業系統可能會刪除這些檔,該設備在存儲上運行低時,然而,應用程式不應依賴的作業系統,請刪除檔在這裡。 (*iOS*、*安卓*、*黑莓 10*) - -* `cordova.file.externalApplicationStorageDirectory`-應用程式外部存儲上的空間。(*安卓*) - -* `cordova.file.externalDataDirectory`-放在外部存儲特定于應用程式的資料檔案的位置。(*安卓*) - -* `cordova.file.externalCacheDirectory`-在外部存儲應用程式緩存。(*安卓*) - -* `cordova.file.externalRootDirectory`-外部存儲 (SD 卡) 的根。(*安卓*、*黑莓 10*) - -* `cordova.file.tempDirectory`-OS 可以清除時的空目錄會。 不依賴于 OS,以清除此目錄 ;您的應用程式,應總是移除作為適用的檔。 (*iOS*) - -* `cordova.file.syncedDataDirectory`-保存應同步 (例如到 iCloud) 的特定于應用程式的檔。(*iOS*) - -* `cordova.file.documentsDirectory`-檔私有的應用程式,但這是對其他應用程式 (例如 Office 檔) 有意義。(*iOS*) - -* `cordova.file.sharedDirectory`-對所有應用程式 (*黑莓 10*全域可用的檔) - -## 檔案系統佈局 - -雖然技術上實現的細節,它可以是很有必要瞭解如何 `cordova.file.*` 屬性對應到實體路徑在實際設備上。 - -### iOS 檔案系統佈局 - -| 設備路徑 | `cordova.file.*` | `iosExtraFileSystems` | r/w 嗎? | 持續性嗎? | OS 清除 | 同步 | 私人 | -|:------------------------------- |:--------------------------- |:--------------------- |:------:|:------:|:----------:|:---:|:--:| -| `/ 無功/移動/應用程式/< UUID > /` | applicationStorageDirectory | - | r | 不適用 | 不適用 | 不適用 | 是啊 | -| `appname.app/` | applicationDirectory | 束 | r | 不適用 | 不適用 | 不適用 | 是啊 | -| `www/` | - | - | r | 不適用 | 不適用 | 不適用 | 是啊 | -| `Documents/` | documentsDirectory | 檔 | r/w | 是啊 | 無 | 是啊 | 是啊 | -| `NoCloud/` | - | 檔 nosync | r/w | 是啊 | 無 | 無 | 是啊 | -| `Library` | - | 圖書館 | r/w | 是啊 | 無 | 是嗎? | 是啊 | -| `NoCloud/` | dataDirectory | 圖書館 nosync | r/w | 是啊 | 無 | 無 | 是啊 | -| `Cloud/` | syncedDataDirectory | - | r/w | 是啊 | 無 | 是啊 | 是啊 | -| `Caches/` | cacheDirectory | 快取記憶體 | r/w | 是啊 * | 是的 * * *| | 無 | 是啊 | -| `tmp/` | tempDirectory | - | r/w | 沒有 * * | 是的 * * *| | 無 | 是啊 | - -* 檔堅持跨應用程式重新開機和升級,但是每當作業系統的欲望,可以清除此目錄。您的應用程式應該能夠重新創建任何內容可能會被刪除。 - -* * 檔可能會持續整個應用程式重新開機,但不要依賴此行為。 不保證檔在更新之間持續存在。 您的應用程式時適用,是應該刪除此目錄的檔,因為作業系統並不能保證何時 (或即使) 中刪除這些檔。 - -* * *| 作業系統可能會清除此目錄的內容,每當它感覺它是必要的但不要依賴于此。 你應該清除此目錄為適合您的應用程式。 - -### Android 的檔案系統佈局 - -| 設備路徑 | `cordova.file.*` | `AndroidExtraFileSystems` | r/w 嗎? | 持續性嗎? | OS 清除 | 私人 | -|:--------------------------------- |:----------------------------------- |:------------------------- |:------:|:-----:|:------:|:--:| -| `file:///android_asset/` | applicationDirectory | | r | 不適用 | 不適用 | 是啊 | -| `/ 資料資料/< 應用程式 id > /` | applicationStorageDirectory | - | r/w | 不適用 | 不適用 | 是啊 | -| `cache` | cacheDirectory | 快取記憶體 | r/w | 是啊 | 是啊 * | 是啊 | -| `files` | dataDirectory | 檔 | r/w | 是啊 | 無 | 是啊 | -| `Documents` | | 檔 | r/w | 是啊 | 無 | 是啊 | -| `< sd 卡 > /` | externalRootDirectory | sd 卡 | r/w | 是啊 | 無 | 無 | -| `Android/data/<app-id>/` | externalApplicationStorageDirectory | - | r/w | 是啊 | 無 | 無 | -| `cache` | externalCacheDirectry | 外部快取記憶體 | r/w | 是啊 | 沒有 * * | 無 | -| `files` | externalDataDirectory | 外部檔 | r/w | 是啊 | 無 | 無 | - -* 的作業系統可能會定期清除此目錄中,但不是依賴于這種行為。 清除此為適合您的應用程式的目錄的內容。 使用者應手動清除緩存,將刪除此目錄的內容。 - -* * 作業系統不會自動清除此目錄你是負責管理自己的內容。 使用者應手動清除緩存,目錄中的內容將被刪除。 - -**注**: 如果外部存儲無法裝入,`cordova.file.external*` 屬性為 `空`. - -### 黑莓 10 檔案系統佈局 - -| 設備路徑 | `cordova.file.*` | r/w 嗎? | 持續性嗎? | OS 清除 | 私人 | -|:---------------------------------------------------- |:--------------------------- |:------:|:-----:|:-----:|:--:| -| `file:///accounts/1000/appdata/ < 應用程式 id > /` | applicationStorageDirectory | r | 不適用 | 不適用 | 是啊 | -| `app/native` | applicationDirectory | r | 不適用 | 不適用 | 是啊 | -| `data/webviews/webfs/temporary/local__0` | cacheDirectory | r/w | 無 | 是啊 | 是啊 | -| `data/webviews/webfs/persistent/local__0` | dataDirectory | r/w | 是啊 | 無 | 是啊 | -| `file:///accounts/1000/removable/sdcard` | externalRemovableDirectory | r/w | 是啊 | 無 | 無 | -| `file:///accounts/1000/shared` | sharedDirectory | r/w | 是啊 | 無 | 無 | - -*注意*: 當應用程式部署工作週邊時,所有路徑都是相對於 /accounts/1000-enterprise。 - -## Android 的怪癖 - -### Android 的持久性存儲位置 - -有很多有效的位置來存儲持久性檔在 Android 設備上。 請參閱 [此頁面][7] 的各種可能性進行廣泛討論。 - - [7]: http://developer.android.com/guide/topics/data/data-storage.html - -以前版本的外掛程式會選擇在啟動時,基於該設備是否聲稱 SD 卡 (或等效存儲分區) 展開,臨時和永久檔的位置。 如果被掛載 SD 卡,或一個大的內部存儲分區可用 (如 nexus 系列設備上) 然後持久性檔將存儲在該空間的根目錄中。 這意味著所有的科爾多瓦應用程式可以看到所有可用的檔在卡片上。 - -如果 SD 卡不是可用的那麼以前的版本中將存儲資料下的 `/data/data/<packageId>`,其中隔離應用程式從彼此,但仍可能導致使用者之間共用的資料。 - -現在可以選擇是否將檔存儲在內部檔的存儲位置,或使用以前的邏輯,與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作,請將以下兩行之一添加到 `config.xml`: - - <preference name="AndroidPersistentFileLocation" value="Internal" /> - - <preference name="AndroidPersistentFileLocation" value="Compatibility" /> - - -如果這條線,沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在,並不是這些值之一,應用程式將無法啟動。 - -如果您的應用程式以前已被運到使用者,使用較舊的 (預 1.0) 版本的這個外掛程式,並具有持久性的檔,系統中存儲的檔,然後您應該設置 `Compatibility` 偏好。 切換到"Internal"的位置,將意味著現有使用者升級他們的應用程式可能無法訪問他們以前存儲的檔,具體取決於他們的設備。 - -如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔,那麼通常建議使用 `Internal` 設置。 - -## iOS 的怪癖 - -* `cordova.file.applicationStorageDirectory`是唯讀的 ;試圖存儲內的根目錄中的檔將會失敗。 使用的另一個 `cordova.file.*` 為 iOS 定義的屬性 (只有 `applicationDirectory` 和 `applicationStorageDirectory` 都是唯讀)。 -* `FileReader.readAsText(blob, encoding)` - * `encoding`參數不受支援,而 utf-8 編碼總是效果。 - -### iOS 的持久性存儲位置 - -有兩個有效的位置來存儲持久性在 iOS 設備上的檔: 檔目錄和圖書館目錄。 以前版本的外掛程式永遠只能將持久性檔存儲在文檔目錄中。 這已經使所有應用程式檔可見在 iTunes,往往是無意為之,尤其是對於處理大量小檔的應用程式中,而不是生產供出口,該目錄的既定的目標是證件齊全的副作用。 - -現在可以選擇是否將檔存儲在檔或庫目錄,與您的應用程式的 `config.xml` 檔中的偏好。 要執行此操作,請將以下兩行之一添加到 `config.xml`: - - <preference name="iosPersistentFileLocation" value="Library" /> - - <preference name="iosPersistentFileLocation" value="Compatibility" /> - - -如果這條線,沒有檔外掛程式將使用 `Compatibility` 作為預設值。如果首選項標記存在,並不是這些值之一,應用程式將無法啟動。 - -如果您的應用程式以前已被運到使用者,使用較舊的 (預 1.0) 版本的這個外掛程式,並具有持久性的檔,系統中存儲的檔,然後您應該設置 `Compatibility` 偏好。 切換到 `Library` 的位置,將意味著現有使用者升級他們的應用程式將無法訪問他們以前存儲的檔。 - -如果您的應用程式是新的或以前從未有持久性的檔案系統中存儲檔,那麼通常建議使用 `Internal` 設置。 - -## 火狐瀏覽器作業系統的怪癖 - -檔案系統 API 本身不支援火狐瀏覽器的作業系統,作為墊片在 indexedDB 上實現的。 - -* 不會失敗時刪除非空的目錄 -* 不支援中繼資料的目錄 -* 方法 `copyTo` 和 `moveTo` 不支援目錄 - -支援以下資料路徑: * `applicationDirectory`-使用 `xhr` 獲取與應用程式打包的本地檔。 `dataDirectory`-用於持久性的特定于應用程式的資料檔案。 `cacheDirectory`-生存應重新開機應用程式的快取檔案 (應用程式不應依賴作業系統來刪除檔在這裡)。 - -## 瀏覽器的怪癖 - -### 常見的怪癖和備註 - -* 每個瀏覽器使用其自己的沙箱檔案系統。IE 和火狐瀏覽器使用 IndexedDB 作為一個基地。所有瀏覽器都使用正斜杠作為路徑中的目錄分隔符號。 -* 目錄條目不得不先後創建。 例如,調用 `fs.root.getDirectory (' dir1/dir2 ',{create:true},successCallback,errorCallback)`,如果不存在 dir1 將失敗。 -* 外掛程式將請求使用者許可權,以便在應用程式初次開機使用持久性存儲。 -* 外掛程式支援 `cdvfile://localhost` (本地資源) 只。通過 `cdvfile` 不支援外部資源即. -* 該外掛程式不遵循 ["檔案系統 API 8.3 命名限制"][8]. -* Blob 和檔 ' `close` 功能不受支援。 -* `FileSaver` 和 `BlobBuilder` 不支援這個外掛程式,沒有存根 (stub)。 -* 該外掛程式不支援 `requestAllFileSystems`。這個功能也是缺少規範中。 -* 在目錄中的條目將不會被刪除,如果您使用 `create: true` 標誌為現有目錄。 -* 不支援通過建構函式創建的檔。你應該使用 entry.file 方法。 -* 每個瀏覽器使用它自己的形式為 blob 的 URL 引用。 -* 支援 `readAsDataURL` 功能,但在 Chrome 中的媒體類型取決於輸入副檔名,在 IE 中的媒體類型都始終空著 (這是 `純文字` 按照說明書一樣),在 Firefox 中的媒體類型始終是 `應用程式/八位位元組流`。 例如,如果內容是 `abcdefg` 然後火狐瀏覽器返回 `資料: 應用程式 / 八位位元組流 ; base64,YWJjZGVmZw = =`,即返回 `資料: ; base64,YWJjZGVmZw = =`,鉻返回 `資料: < 媒體類型根據擴展條目名稱 > ; base64,YWJjZGVmZw = =`. -* 在表單 `file:///persistent/path/to/entry` 火狐瀏覽器 IE),`toInternalURL` 返回的路徑。 鉻在表單 `cdvfile://localhost/persistent/file` 返回的路徑. - - [8]: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions - -### 鉻的怪癖 - -* 設備準備好事件之後,chrome 檔案系統並不能立即準備。作為一種變通方法,您可以訂閱到 `filePluginIsReady` 事件。示例: - - javascript - window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); - - -你可以使用 `window.isFilePluginReadyRaised` 函數來檢查是否已經引發了事件。 -window.requestFileSystem 臨時和永久性檔案系統配額並不局限于鉻。 為增加中鉻的持久性存儲,您需要調用 `window.initPersistentFileSystem` 方法。 預設情況下,持久性存儲配額為 5 MB。 鉻需要 `— — 允許--訪問-從-檔` 通過 `file:///` 協定運行參數對 API 的支援。 -如果您使用標誌,將不更改 `檔` 物件 `{create:true}` 現有 `條目` 的時候。 -事件 `可取消` 屬性設置為 true 在 Chrome 中。 這是違反了 [規範][4]。 -中鉻的 `toURL` 函數返回 `檔案系統:`-首碼路徑具體取決於應用程式主機。 例如,`filesystem:file:///persistent/somefile.txt`,`filesystem:HTTP://localhost:8080/persistent/somefile.txt`。 -`toURL` 函數結果不包含尾部反斜線在目錄條目的情況下。 鉻雖然正確解析目錄帶斜杠落後的 url。 -`resolveLocalFileSystemURL` 方法需要入站的 `url` 必須具有 `檔案系統` 首碼。 例如,`resolveLocalFileSystemURL` 的 `url` 參數應在表單 `filesystem:file:///persistent/somefile.txt` 而不是表單 `file:///persistent/somefile.txt` 在安卓系統。 -不推薦使用 `toNativeURL` 函數不受支援,並且沒有存根 (stub)。 -`setMetadata` 功能是沒有說出的規格,並且不支援。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 SYNTAX_ERR(code: 8) 上請求一個不存在的檔案系統。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 PATH_EXISTS_ERR(code: 12) 上嘗試專門創建一個檔或目錄,它已經存在。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 NO_MODIFICATION_ALLOWED_ERR(code: 6) 在試圖調用 removeRecursively 的根檔案系統上。 -INVALID_MODIFICATION_ERR (代碼: 9) 而不是引發 NOT_FOUND_ERR(code: 1) 試到 moveTo 目錄不存在。 - -### 基於 IndexedDB 的 impl 怪癖 (Firefox 和 IE) - -* `.` 和 `.` 不受支援。 -* IE 不支援 `file:///`-模式 ;只有託管的模式是支援 (HTTP://localhost:xxxx)。 -* 火狐瀏覽器的檔案系統大小不是有限,但每個 50 MB 擴展會要求使用者的許可權。 IE10 允許達 10 mb 的 AppCache 和 IndexedDB 檔案系統的實現中使用而不會提示,一旦你達到這一水準你會詢問您是否允許它增加到每個網站的 250 mb 的最大合併。 所以 `requestFileSystem` 函數的 `大小` 參數並不影響檔案系統相容 Firefox 和 IE。 -* `readAsBinaryString` 函數在規範中沒有注明不支援在 IE 中和沒有存根 (stub)。 -* `file.type` 始終為 null。 -* 您不應創建條目使用已刪除的目錄實例回檔結果。否則,你會得到一個 '掛條目'。 -* 您可以讀取一個檔,其中只是寫之前你需要獲得的此檔的新實例。 -* `setMetadata` 函數,在規範中沒有注明支援 `modificationTime` 欄位的更改。 -* `copyTo` 和 `moveTo` 函數不支援目錄。 -* 不支援目錄的中繼資料。 -* 兩個 Entry.remove 和 directoryEntry.removeRecursively 不失敗時刪除非空的目錄-相反與內容一起清理目錄被刪除。 -* 不支援 `abort` 和 `truncate` 函數。 -* 進度事件不會觸發。例如,將不執行此處理程式: - - javascript - writer.onprogress = function() { /*commands*/ }; - - -## 升級筆記 - -在這個外掛程式 v1.0.0,`FileEntry` 和 `DirectoryEntry` 的結構已經改變,以更加一致的已發表說明書。 - -以前 (pre-1.0.0) 版本的外掛程式中 `輸入` 物件的 `完整路徑` 屬性存放裝置固定檔案位置。這些路徑通常會看起來像 - - /var/mobile/Applications/<application UUID>/Documents/path/to/file (iOS) - /storage/emulated/0/path/to/file (Android) - - -這些路徑還返回的 `Entry` 物件的 `toURL()` 方法。 - -與 v1.0.0,`完整路徑` 屬性是到檔中,*相對於 HTML 檔案系統的根目錄* 的路徑。 因此,上述路徑會現在都由一個 `FileEntry` 物件的 `完整路徑`, - - /path/to/file - - -如果您的應用程式與設備-絕對路徑,並且您以前檢索到這些路徑通過 `條目` 物件的 `完整路徑` 屬性,然後您應該更新您的代碼以改用 `entry.toURL()`。 - -為向後相容性,`resolveLocalFileSystemURL()` 方法將接受一個設備-絕對路徑,並將返回相應的 `條目` 物件,只要在 `臨時` 或 `永久性` 的檔案系統內的檔是否存在。 - -這尤其是一直與檔案傳輸外掛程式,以前使用設備絕對路徑的問題 (和仍然可以接受他們)。 已更新它能夠正常運行與檔案系統的 Url,所以用 `entry.toURL()` 替換 `entry.fullPath` 應解決任何問題,得到該外掛程式來處理設備上的檔。 - -在 v1.1.0 `toURL()` 的傳回值被更改 (見 [CB-6394] (HTTPs://issues.apache.org/jira/browse/CB-6394)) 為返回絕對 file:// URL。 只要有可能。 確保 'cdvfile:' — — 你現在可以用 `toInternalURL()` 的 URL。 現在,此方法將返回檔案系統表單的 Url - - cdvfile://localhost/persistent/path/to/file - - -它可以用於唯一地標識該檔。 - -## 錯誤代碼及其含義的清單中 - -當拋出一個錯誤時,將使用以下代碼之一。 - -| 代碼 | 恒 | -| --:|:----------------------------- | -| 1 | `NOT_FOUND_ERR` | -| 2 | `SECURITY_ERR` | -| 3 | `ABORT_ERR` | -| 4 | `NOT_READABLE_ERR` | -| 5 | `ENCODING_ERR` | -| 6 | `NO_MODIFICATION_ALLOWED_ERR` | -| 7 | `INVALID_STATE_ERR` | -| 8 | `SYNTAX_ERR` | -| 9 | `INVALID_MODIFICATION_ERR` | -| 10 | `QUOTA_EXCEEDED_ERR` | -| 11 | `TYPE_MISMATCH_ERR` | -| 12 | `PATH_EXISTS_ERR` | - -## 配置外掛程式 (可選) - -可用的檔案系統的一整套可以配置每個平臺。IOS 和安卓系統認識到 <preference> 在 `config.xml` 名稱要安裝的檔案系統中的標記。預設情況下,啟用所有檔案系統的根。 - - <preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /> - <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,root" /> - - -### Android 系統 - -* `files`: 該應用程式的內部檔存儲目錄 -* `files-external`: 應用程式的外部檔存儲目錄 -* `sdcard`: 全球外部檔存儲目錄 (如果安裝了一個,這是 SD 卡的根目錄)。 你必須具有 `android.permission.WRITE_EXTERNAL_STORAGE` 許可權,用這個。 -* `cache`: 應用程式的內部緩存目錄 -* `cache-external`: 應用程式的外部快取記憶體目錄 -* `root`: 整個設備的檔案系統 - -安卓系統還支援特殊的檔命名為"檔",表示"/ 檔 /""檔"的檔案系統中的子目錄。 - -### iOS - -* `library`: 應用程式的庫目錄 -* `documents`: 應用程式的檔目錄 -* `cache`: 應用程式的緩存目錄 -* `bundle`: 應用程式的包 ;應用程式本身 (唯讀) 的磁片上的位置 -* `root`: 整個設備的檔案系統 - -預設情況下,圖書館和檔目錄可以同步到 iCloud。 您也可以要求兩個額外的檔案系統、 `library-nosync` 和 `documents-nosync`,代表一個特殊的非同步目錄內 `/Library` 或 `/Documents` 的檔案系統。 diff --git a/plugins/cordova-plugin-file/doc/zh/plugins.md b/plugins/cordova-plugin-file/doc/zh/plugins.md deleted file mode 100644 index 462fb062..00000000 --- a/plugins/cordova-plugin-file/doc/zh/plugins.md +++ /dev/null @@ -1,124 +0,0 @@ -<!--- - 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. ---> - -# 外掛程式開發人員須知 - -這些筆記主要針對 Android 和 iOS 開發者想要使用的檔案系統使用的檔外掛程式編寫外掛程式哪個介面。 - -## 工作與科爾多瓦檔案系統 Url - -1.0.0 版以來,這個外掛程式用了 Url 與 `cdvfile` 在橋樑,為所有的通信計畫,而不是暴露 JavaScript 原始設備的檔案系統路徑。 - -在 JavaScript 方面,這意味著 FileEntry 和 DirectoryEntry 的物件具有一個完整路徑屬性是相對於 HTML 檔案系統的根目錄。 如果你的外掛程式的 JavaScript API 接受 FileEntry 或 DirectoryEntry 的物件,則應調用 `.toURL()` 對該物件之前將它在橋上傳遞給本機代碼。 - -### 轉換 cdvfile: / / fileystem 的路徑的 Url - -需要寫入到檔案系統的外掛程式可能會想要將收到的檔案系統的 URL 轉換為實際的檔案系統位置。有多種方法做這個,根據本機平臺。 - -它是重要的是要記住,不是所有 `cdvfile://` 的 Url 均可映射到設備上的實際檔。 某些 Url 可以引用在設備上不是由檔,或甚至可以引用遠端資源的資產。 由於這些可能性,外掛程式應始終測試是否回試圖將 Url 轉換成路徑時,他們得到有意義的結果。 - -#### Android 系統 - -在 android 系統,最簡單的方法來轉換 `cdvfile://` 檔案系統路徑的 URL 是使用 `org.apache.cordova.CordovaResourceApi` 。 `CordovaResourceApi`有幾種方法,可處理 `cdvfile://` 的 Url: - - // webView is a member of the Plugin class - CordovaResourceApi resourceApi = webView.getResourceApi(); - - // Obtain a file:/// URL representing this file on the device, - // or the same URL unchanged if it cannot be mapped to a file - Uri fileURL = resourceApi.remapUri(Uri.parse(cdvfileURL)); - - -它也是可以直接使用檔外掛程式: - - import org.apache.cordova.file.FileUtils; - import org.apache.cordova.file.FileSystem; - import java.net.MalformedURLException; - - // Get the File plugin from the plugin manager - FileUtils filePlugin = (FileUtils)webView.pluginManager.getPlugin("File"); - - // Given a URL, get a path for it - try { - String path = filePlugin.filesystemPathForURL(cdvfileURL); - } catch (MalformedURLException e) { - // The filesystem url wasn't recognized - } - - -要轉換的路徑從 `cdvfile://` 的 URL: - - import org.apache.cordova.file.LocalFilesystemURL; - - // Get a LocalFilesystemURL object for a device path, - // or null if it cannot be represented as a cdvfile URL. - LocalFilesystemURL url = filePlugin.filesystemURLforLocalPath(path); - // Get the string representation of the URL object - String cdvfileURL = url.toString(); - - -如果你的外掛程式創建一個檔,並且您想要為它返回一個 FileEntry 物件,使用該檔外掛程式: - - // Return a JSON structure suitable for returning to JavaScript, - // or null if this file is not representable as a cdvfile URL. - JSONObject entry = filePlugin.getEntryForFile(file); - - -#### iOS - -科爾多瓦在 iOS 上的不使用相同 `CordovaResourceApi` 作為 android 系統的概念。在 iOS,應使用檔外掛程式的 Url 和檔案系統路徑之間進行轉換。 - - // Get a CDVFilesystem URL object from a URL string - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithString:cdvfileURL]; - // Get a path for the URL object, or nil if it cannot be mapped to a file - NSString* path = [filePlugin filesystemPathForURL:url]; - - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get the string representation of the URL object - NSString* cdvfileURL = [url absoluteString]; - - -如果你的外掛程式創建一個檔,並且您想要為它返回一個 FileEntry 物件,使用該檔外掛程式: - - // Get a CDVFilesystem URL object for a device path, or - // nil if it cannot be represented as a cdvfile URL. - CDVFilesystemURL* url = [filePlugin fileSystemURLforLocalPath:path]; - // Get a structure to return to JavaScript - NSDictionary* entry = [filePlugin makeEntryForLocalURL:url] - - -#### JavaScript - -在 JavaScript 中,得到 `cdvfile://` URL 從 FileEntry 或 DirectoryEntry 的物件,只需調用 `.toURL()` 對它: - - var cdvfileURL = entry.toURL(); - - -在外掛程式回應處理常式,將從返回的 FileEntry 結構轉換為實際的輸入物件,您的處理常式代碼應該導入的檔外掛程式並創建一個新的物件: - - // create appropriate Entry object - var entry; - if (entryStruct.isDirectory) { - entry = new DirectoryEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - } else { - entry = new FileEntry(entryStruct.name, entryStruct.fullPath, new FileSystem(entryStruct.filesystemName)); - }
\ No newline at end of file diff --git a/plugins/cordova-plugin-file/package.json b/plugins/cordova-plugin-file/package.json deleted file mode 100644 index 4f7442da..00000000 --- a/plugins/cordova-plugin-file/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "cordova-plugin-file", - "version": "2.1.0", - "description": "Cordova File Plugin", - "cordova": { - "id": "cordova-plugin-file", - "platforms": [ - "android", - "amazon-fireos", - "ubuntu", - "ios", - "wp7", - "wp8", - "blackberry10", - "windows8", - "windows", - "firefoxos" - ] - }, - "repository": { - "type": "git", - "url": "https://github.com/apache/cordova-plugin-file" - }, - "keywords": [ - "cordova", - "file", - "ecosystem:cordova", - "cordova-android", - "cordova-amazon-fireos", - "cordova-ubuntu", - "cordova-ios", - "cordova-wp7", - "cordova-wp8", - "cordova-blackberry10", - "cordova-windows8", - "cordova-windows", - "cordova-firefoxos" - ], - "author": "Apache Software Foundation", - "license": "Apache 2.0" -} diff --git a/plugins/cordova-plugin-file/plugin.xml b/plugins/cordova-plugin-file/plugin.xml deleted file mode 100644 index c375c9c0..00000000 --- a/plugins/cordova-plugin-file/plugin.xml +++ /dev/null @@ -1,368 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" -xmlns:android="http://schemas.android.com/apk/res/android" - id="cordova-plugin-file" - version="2.1.0"> - <name>File</name> - <description>Cordova File Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,file</keywords> - <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git</repo> - <issue>https://issues.apache.org/jira/browse/CB/component/12320651</issue> - <engines> - <engine name="cordova-android" version=">=3.1.0" /><!-- Uses CordovaResourceApi --> - </engines> - - <js-module src="www/DirectoryEntry.js" name="DirectoryEntry"> - <clobbers target="window.DirectoryEntry" /> - </js-module> - - <js-module src="www/DirectoryReader.js" name="DirectoryReader"> - <clobbers target="window.DirectoryReader" /> - </js-module> - - <js-module src="www/Entry.js" name="Entry"> - <clobbers target="window.Entry" /> - </js-module> - - <js-module src="www/File.js" name="File"> - <clobbers target="window.File" /> - </js-module> - - <js-module src="www/FileEntry.js" name="FileEntry"> - <clobbers target="window.FileEntry" /> - </js-module> - - <js-module src="www/FileError.js" name="FileError"> - <clobbers target="window.FileError" /> - </js-module> - - <js-module src="www/FileReader.js" name="FileReader"> - <clobbers target="window.FileReader" /> - </js-module> - - <js-module src="www/FileSystem.js" name="FileSystem"> - <clobbers target="window.FileSystem" /> - </js-module> - - <js-module src="www/FileUploadOptions.js" name="FileUploadOptions"> - <clobbers target="window.FileUploadOptions" /> - </js-module> - - <js-module src="www/FileUploadResult.js" name="FileUploadResult"> - <clobbers target="window.FileUploadResult" /> - </js-module> - - <js-module src="www/FileWriter.js" name="FileWriter"> - <clobbers target="window.FileWriter" /> - </js-module> - - <js-module src="www/Flags.js" name="Flags"> - <clobbers target="window.Flags" /> - </js-module> - - <js-module src="www/LocalFileSystem.js" name="LocalFileSystem"> - <!-- Non-standards way --> - <clobbers target="window.LocalFileSystem" /> - <!-- Standards-compliant way --> - <merges target="window" /> - </js-module> - - <js-module src="www/Metadata.js" name="Metadata"> - <clobbers target="window.Metadata" /> - </js-module> - - <js-module src="www/ProgressEvent.js" name="ProgressEvent"> - <clobbers target="window.ProgressEvent" /> - </js-module> - - <js-module src="www/fileSystems.js" name="fileSystems" /> - - <js-module src="www/requestFileSystem.js" name="requestFileSystem"> - <clobbers target="window.requestFileSystem" /> - </js-module> - - <js-module src="www/resolveLocalFileSystemURI.js" name="resolveLocalFileSystemURI"> - <merges target="window" /> - </js-module> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="File" > - <param name="android-package" value="org.apache.cordova.file.FileUtils"/> - <param name="onload" value="true" /> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/*"> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </config-file> - - <source-file src="src/android/EncodingException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/FileExistsException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/InvalidModificationException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/NoModificationAllowedException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/TypeMismatchException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/FileUtils.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/DirectoryManager.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/LocalFilesystemURL.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/Filesystem.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/LocalFilesystem.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/ContentFilesystem.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/AssetFilesystem.java" target-dir="src/org/apache/cordova/file" /> - - <!-- android specific file apis --> - <js-module src="www/android/FileSystem.js" name="androidFileSystem"> - <merges target="FileSystem" /> - </js-module> - <js-module src="www/fileSystems-roots.js" name="fileSystems-roots"> - <runs/> - </js-module> - <js-module src="www/fileSystemPaths.js" name="fileSystemPaths"> - <merges target="cordova" /> - <runs/> - </js-module> - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="File" > - <param name="android-package" value="org.apache.cordova.file.FileUtils"/> - <param name="onload" value="true" /> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/*"> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </config-file> - - <source-file src="src/android/EncodingException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/FileExistsException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/InvalidModificationException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/NoModificationAllowedException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/TypeMismatchException.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/FileUtils.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/DirectoryManager.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/LocalFilesystemURL.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/Filesystem.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/LocalFilesystem.java" target-dir="src/org/apache/cordova/file" /> - <source-file src="src/android/ContentFilesystem.java" target-dir="src/org/apache/cordova/file" /> - - <!-- android specific file apis --> - <js-module src="www/android/FileSystem.js" name="androidFileSystem"> - <merges target="window.FileSystem" /> - </js-module> - <js-module src="www/fileSystems-roots.js" name="fileSystems-roots"> - <runs/> - </js-module> - <js-module src="www/fileSystemPaths.js" name="fileSystemPaths"> - <merges target="cordova" /> - <runs/> - </js-module> - </platform> - - <!-- ubuntu --> - <platform name="ubuntu"> - <header-file src="src/ubuntu/file.h" /> - <source-file src="src/ubuntu/file.cpp" /> - <js-module src="www/ubuntu/FileSystem.js" name="ubuntuFileSystem1"> - <merges target="window.FileSystem" /> - </js-module> - <js-module src="www/ubuntu/FileWriter.js" name="FileWriter1"> - <merges target="window.FileWriter" /> - </js-module> - <js-module src="www/ubuntu/fileSystems-roots.js" name="fileSystems-roots"> - <runs/> - </js-module> - </platform> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="File"> - <param name="ios-package" value="CDVFile" /> - <param name="onload" value="true" /> - </feature> - </config-file> - <header-file src="src/ios/CDVFile.h" /> - <source-file src="src/ios/CDVFile.m" /> - <header-file src="src/ios/CDVLocalFilesystem.h" /> - <source-file src="src/ios/CDVLocalFilesystem.m" /> - <header-file src="src/ios/CDVAssetLibraryFilesystem.h" /> - <source-file src="src/ios/CDVAssetLibraryFilesystem.m" /> - - <!-- ios specific file apis --> - <js-module src="www/ios/FileSystem.js" name="iosFileSystem"> - <merges target="FileSystem" /> - </js-module> - - <js-module src="www/fileSystems-roots.js" name="fileSystems-roots"> - <runs/> - </js-module> - - <js-module src="www/fileSystemPaths.js" name="fileSystemPaths"> - <merges target="cordova" /> - <runs/> - </js-module> - - <framework src="AssetsLibrary.framework" /> - <framework src="MobileCoreServices.framework" /> - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="config.xml" parent="/*"> - <feature name="File"> - <param name="wp-package" value="File"/> - </feature> - </config-file> - - <source-file src="src/wp/File.cs" /> - - <!-- wp specific file apis --> - <js-module src="www/wp/FileUploadOptions.js" name="FileUploadOptions1"> - <merges target="window.FileUploadOptions" /> - </js-module> - - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="File"> - <param name="wp-package" value="File"/> - </feature> - </config-file> - - <source-file src="src/wp/File.cs" /> - - <!-- wp specific file apis --> - <js-module src="www/wp/FileUploadOptions.js" name="FileUploadOptions1"> - <merges target="window.FileUploadOptions" /> - </js-module> - - </platform> - - <!-- blackberry10 --> - <platform name="blackberry10"> - <config-file target="www/config.xml" parent="/widget"> - <feature name="File" value="File" /> - </config-file> - <js-module src="www/blackberry10/FileProxy.js" name="FileProxy" > - <runs /> - </js-module> - <js-module src="www/blackberry10/info.js" name="bb10FileSystemInfo"> - <runs /> - </js-module> - <js-module src="www/blackberry10/createEntryFromNative.js" name="bb10CreateEntryFromNative"> - <runs /> - </js-module> - <js-module src="www/blackberry10/requestAnimationFrame.js" name="bb10RequestAnimationFrame"> - <runs /> - </js-module> - <js-module src="www/blackberry10/FileSystem.js" name="bb10FileSystem"> - <merges target="window.FileSystem" /> - </js-module> - <js-module src="www/fileSystems-roots.js" name="fileSystems-roots"> - <runs/> - </js-module> - <js-module src="www/fileSystemPaths.js" name="fileSystemPaths"> - <merges target="cordova" /> - </js-module> - <js-module src="www/blackberry10/copyTo.js" name="copyToProxy" /> - <js-module src="www/blackberry10/getDirectory.js" name="getDirectoryProxy" /> - <js-module src="www/blackberry10/getFile.js" name="getFileProxy" /> - <js-module src="www/blackberry10/getFileMetadata.js" name="getFileMetadataProxy" /> - <js-module src="www/blackberry10/getMetadata.js" name="getMetadataProxy" /> - <js-module src="www/blackberry10/getParent.js" name="getParentProxy" /> - <js-module src="www/blackberry10/moveTo.js" name="moveToProxy" /> - <js-module src="www/blackberry10/readAsArrayBuffer.js" name="readAsArrayBufferProxy" /> - <js-module src="www/blackberry10/readAsBinaryString.js" name="readAsBinaryStringProxy" /> - <js-module src="www/blackberry10/readAsDataURL.js" name="readAsDataURLProxy" /> - <js-module src="www/blackberry10/readAsText.js" name="readAsTextProxy" /> - <js-module src="www/blackberry10/readEntries.js" name="readEntriesProxy" /> - <js-module src="www/blackberry10/remove.js" name="removeProxy" /> - <js-module src="www/blackberry10/removeRecursively.js" name="removeRecursivelyProxy" /> - <js-module src="www/blackberry10/resolveLocalFileSystemURI.js" name="resolveLocalFileSystemURIProxy" /> - <js-module src="www/blackberry10/requestAllFileSystems.js" name="requestAllFileSystemsProxy" /> - <js-module src="www/blackberry10/requestFileSystem.js" name="requestFileSystemProxy" /> - <js-module src="www/blackberry10/setMetadata.js" name="setMetadataProxy" /> - <js-module src="www/blackberry10/truncate.js" name="truncateProxy" /> - <js-module src="www/blackberry10/write.js" name="writeProxy" /> - <source-file src="src/blackberry10/index.js" target-dir="File" /> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="src/windows/FileProxy.js" name="FileProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- windows --> - <platform name="windows"> - <js-module src="src/windows/FileProxy.js" name="FileProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- firefox os --> - <platform name="firefoxos"> - <js-module src="src/firefoxos/FileProxy.js" name="FileProxy"> - <runs /> - </js-module> - - <js-module src="www/fileSystemPaths.js" name="fileSystemPaths"> - <merges target="cordova" /> - <runs/> - </js-module> - - <!-- Firefox OS specific file apis --> - <js-module src="www/firefoxos/FileSystem.js" name="firefoxFileSystem"> - <merges target="window.FileSystem" /> - </js-module> - </platform> - - <platform name="browser"> - <!-- File for Chrome --> - <js-module src="www/browser/Preparing.js" name="Preparing"> - <runs /> - </js-module> - - <js-module src="src/browser/FileProxy.js" name="browserFileProxy"> - <runs /> - </js-module> - - <js-module src="www/fileSystemPaths.js" name="fileSystemPaths"> - <merges target="cordova" /> - <runs /> - </js-module> - - <js-module src="www/browser/FileSystem.js" name="firefoxFileSystem"> - <merges target="window.FileSystem" /> - </js-module> - </platform> - -</plugin> diff --git a/plugins/cordova-plugin-file/src/android/AssetFilesystem.java b/plugins/cordova-plugin-file/src/android/AssetFilesystem.java deleted file mode 100644 index f501b279..00000000 --- a/plugins/cordova-plugin-file/src/android/AssetFilesystem.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file; - -import android.content.res.AssetManager; -import android.net.Uri; -import android.util.Log; - -import org.apache.cordova.CordovaResourceApi; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.util.HashMap; -import java.util.Map; - -public class AssetFilesystem extends Filesystem { - - private final AssetManager assetManager; - - // A custom gradle hook creates the cdvasset.manifest file, which speeds up asset listing a tonne. - // See: http://stackoverflow.com/questions/16911558/android-assetmanager-list-incredibly-slow - private static Object listCacheLock = new Object(); - private static boolean listCacheFromFile; - private static Map<String, String[]> listCache; - private static Map<String, Long> lengthCache; - - private void lazyInitCaches() { - synchronized (listCacheLock) { - if (listCache == null) { - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(assetManager.open("cdvasset.manifest")); - listCache = (Map<String, String[]>) ois.readObject(); - lengthCache = (Map<String, Long>) ois.readObject(); - listCacheFromFile = true; - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - // Asset manifest won't exist if the gradle hook isn't set up correctly. - } finally { - if (ois != null) { - try { - ois.close(); - } catch (IOException e) { - } - } - } - if (listCache == null) { - Log.w("AssetFilesystem", "Asset manifest not found. Recursive copies and directory listing will be slow."); - listCache = new HashMap<String, String[]>(); - } - } - } - } - - private String[] listAssets(String assetPath) throws IOException { - if (assetPath.startsWith("/")) { - assetPath = assetPath.substring(1); - } - lazyInitCaches(); - String[] ret = listCache.get(assetPath); - if (ret == null) { - if (listCacheFromFile) { - ret = new String[0]; - } else { - ret = assetManager.list(assetPath); - listCache.put(assetPath, ret); - } - } - return ret; - } - - private long getAssetSize(String assetPath) throws FileNotFoundException { - if (assetPath.startsWith("/")) { - assetPath = assetPath.substring(1); - } - lazyInitCaches(); - if (lengthCache != null) { - Long ret = lengthCache.get(assetPath); - if (ret == null) { - throw new FileNotFoundException("Asset not found: " + assetPath); - } - return ret; - } - CordovaResourceApi.OpenForReadResult offr = null; - try { - offr = resourceApi.openForRead(nativeUriForFullPath(assetPath)); - long length = offr.length; - if (length < 0) { - // available() doesn't always yield the file size, but for assets it does. - length = offr.inputStream.available(); - } - return length; - } catch (IOException e) { - throw new FileNotFoundException("File not found: " + assetPath); - } finally { - if (offr != null) { - try { - offr.inputStream.close(); - } catch (IOException e) { - } - } - } - } - - public AssetFilesystem(AssetManager assetManager, CordovaResourceApi resourceApi) { - super(Uri.parse("file:///android_asset/"), "assets", resourceApi); - this.assetManager = assetManager; - } - - @Override - public Uri toNativeUri(LocalFilesystemURL inputURL) { - return nativeUriForFullPath(inputURL.path); - } - - @Override - public LocalFilesystemURL toLocalUri(Uri inputURL) { - if (!"file".equals(inputURL.getScheme())) { - return null; - } - File f = new File(inputURL.getPath()); - // Removes and duplicate /s (e.g. file:///a//b/c) - Uri resolvedUri = Uri.fromFile(f); - String rootUriNoTrailingSlash = rootUri.getEncodedPath(); - rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1); - if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) { - return null; - } - String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length()); - // Strip leading slash - if (!subPath.isEmpty()) { - subPath = subPath.substring(1); - } - Uri.Builder b = new Uri.Builder() - .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL) - .authority("localhost") - .path(name); - if (!subPath.isEmpty()) { - b.appendEncodedPath(subPath); - } - if (isDirectory(subPath) || inputURL.getPath().endsWith("/")) { - // Add trailing / for directories. - b.appendEncodedPath(""); - } - return LocalFilesystemURL.parse(b.build()); - } - - private boolean isDirectory(String assetPath) { - try { - return listAssets(assetPath).length != 0; - } catch (IOException e) { - return false; - } - } - - @Override - public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException { - String pathNoSlashes = inputURL.path.substring(1); - if (pathNoSlashes.endsWith("/")) { - pathNoSlashes = pathNoSlashes.substring(0, pathNoSlashes.length() - 1); - } - - String[] files; - try { - files = listAssets(pathNoSlashes); - } catch (IOException e) { - throw new FileNotFoundException(); - } - - LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length]; - for (int i = 0; i < files.length; ++i) { - entries[i] = localUrlforFullPath(new File(inputURL.path, files[i]).getPath()); - } - return entries; - } - - @Override - public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, - String path, JSONObject options, boolean directory) - throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { - if (options != null && options.optBoolean("create")) { - throw new UnsupportedOperationException("Assets are read-only"); - } - - // Check whether the supplied path is absolute or relative - if (directory && !path.endsWith("/")) { - path += "/"; - } - - LocalFilesystemURL requestedURL; - if (path.startsWith("/")) { - requestedURL = localUrlforFullPath(normalizePath(path)); - } else { - requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path)); - } - - // Throws a FileNotFoundException if it doesn't exist. - getFileMetadataForLocalURL(requestedURL); - - boolean isDir = isDirectory(requestedURL.path); - if (directory && !isDir) { - throw new TypeMismatchException("path doesn't exist or is file"); - } else if (!directory && isDir) { - throw new TypeMismatchException("path doesn't exist or is directory"); - } - - // Return the directory - return makeEntryForURL(requestedURL); - } - - @Override - public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { - JSONObject metadata = new JSONObject(); - long size = inputURL.isDirectory ? 0 : getAssetSize(inputURL.path); - try { - metadata.put("size", size); - metadata.put("type", inputURL.isDirectory ? "text/directory" : resourceApi.getMimeType(toNativeUri(inputURL))); - metadata.put("name", new File(inputURL.path).getName()); - metadata.put("fullPath", inputURL.path); - metadata.put("lastModifiedDate", 0); - } catch (JSONException e) { - return null; - } - return metadata; - } - - @Override - public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { - return false; - } - - @Override - long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, boolean isBinary) throws NoModificationAllowedException, IOException { - throw new NoModificationAllowedException("Assets are read-only"); - } - - @Override - long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException, NoModificationAllowedException { - throw new NoModificationAllowedException("Assets are read-only"); - } - - @Override - String filesystemPathForURL(LocalFilesystemURL url) { - return null; - } - - @Override - LocalFilesystemURL URLforFilesystemPath(String path) { - return null; - } - - @Override - boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException { - throw new NoModificationAllowedException("Assets are read-only"); - } - - @Override - boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws NoModificationAllowedException { - throw new NoModificationAllowedException("Assets are read-only"); - } - -} diff --git a/plugins/cordova-plugin-file/src/android/ContentFilesystem.java b/plugins/cordova-plugin-file/src/android/ContentFilesystem.java deleted file mode 100644 index 883e7cf5..00000000 --- a/plugins/cordova-plugin-file/src/android/ContentFilesystem.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; - -import org.apache.cordova.CordovaResourceApi; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.ContentResolver; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.provider.MediaStore; -import android.provider.OpenableColumns; - -public class ContentFilesystem extends Filesystem { - - private final Context context; - - public ContentFilesystem(Context context, CordovaResourceApi resourceApi) { - super(Uri.parse("content://"), "content", resourceApi); - this.context = context; - } - - @Override - public Uri toNativeUri(LocalFilesystemURL inputURL) { - String authorityAndPath = inputURL.uri.getEncodedPath().substring(this.name.length() + 2); - if (authorityAndPath.length() < 2) { - return null; - } - String ret = "content://" + authorityAndPath; - String query = inputURL.uri.getEncodedQuery(); - if (query != null) { - ret += '?' + query; - } - String frag = inputURL.uri.getEncodedFragment(); - if (frag != null) { - ret += '#' + frag; - } - return Uri.parse(ret); - } - - @Override - public LocalFilesystemURL toLocalUri(Uri inputURL) { - if (!"content".equals(inputURL.getScheme())) { - return null; - } - String subPath = inputURL.getEncodedPath(); - if (subPath.length() > 0) { - subPath = subPath.substring(1); - } - Uri.Builder b = new Uri.Builder() - .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL) - .authority("localhost") - .path(name) - .appendPath(inputURL.getAuthority()); - if (subPath.length() > 0) { - b.appendEncodedPath(subPath); - } - Uri localUri = b.encodedQuery(inputURL.getEncodedQuery()) - .encodedFragment(inputURL.getEncodedFragment()) - .build(); - return LocalFilesystemURL.parse(localUri); - } - - @Override - public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, - String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException { - throw new UnsupportedOperationException("getFile() not supported for content:. Use resolveLocalFileSystemURL instead."); - } - - @Override - public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) - throws NoModificationAllowedException { - Uri contentUri = toNativeUri(inputURL); - try { - context.getContentResolver().delete(contentUri, null, null); - } catch (UnsupportedOperationException t) { - // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator. - // The ContentResolver applies only when the file was registered in the - // first case, which is generally only the case with images. - throw new NoModificationAllowedException("Deleting not supported for content uri: " + contentUri); - } - return true; - } - - @Override - public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) - throws NoModificationAllowedException { - throw new NoModificationAllowedException("Cannot remove content url"); - } - - @Override - public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException { - throw new UnsupportedOperationException("readEntriesAtLocalURL() not supported for content:. Use resolveLocalFileSystemURL instead."); - } - - @Override - public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { - long size = -1; - long lastModified = 0; - Uri nativeUri = toNativeUri(inputURL); - String mimeType = resourceApi.getMimeType(nativeUri); - Cursor cursor = openCursorForURL(nativeUri); - try { - if (cursor != null && cursor.moveToFirst()) { - size = resourceSizeForCursor(cursor); - lastModified = lastModifiedDateForCursor(cursor); - } else { - // Some content providers don't support cursors at all! - CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(nativeUri); - size = offr.length; - } - } catch (IOException e) { - throw new FileNotFoundException(); - } finally { - if (cursor != null) - cursor.close(); - } - - JSONObject metadata = new JSONObject(); - try { - metadata.put("size", size); - metadata.put("type", mimeType); - metadata.put("name", name); - metadata.put("fullPath", inputURL.path); - metadata.put("lastModifiedDate", lastModified); - } catch (JSONException e) { - return null; - } - return metadata; - } - - @Override - public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, - int offset, boolean isBinary) throws NoModificationAllowedException { - throw new NoModificationAllowedException("Couldn't write to file given its content URI"); - } - @Override - public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) - throws NoModificationAllowedException { - throw new NoModificationAllowedException("Couldn't truncate file given its content URI"); - } - - protected Cursor openCursorForURL(Uri nativeUri) { - ContentResolver contentResolver = context.getContentResolver(); - try { - return contentResolver.query(nativeUri, null, null, null, null); - } catch (UnsupportedOperationException e) { - return null; - } - } - - private Long resourceSizeForCursor(Cursor cursor) { - int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE); - if (columnIndex != -1) { - String sizeStr = cursor.getString(columnIndex); - if (sizeStr != null) { - return Long.parseLong(sizeStr); - } - } - return null; - } - - protected Long lastModifiedDateForCursor(Cursor cursor) { - final String[] LOCAL_FILE_PROJECTION = { MediaStore.MediaColumns.DATE_MODIFIED }; - int columnIndex = cursor.getColumnIndex(LOCAL_FILE_PROJECTION[0]); - if (columnIndex != -1) { - String dateStr = cursor.getString(columnIndex); - if (dateStr != null) { - return Long.parseLong(dateStr); - } - } - return null; - } - - @Override - public String filesystemPathForURL(LocalFilesystemURL url) { - File f = resourceApi.mapUriToFile(toNativeUri(url)); - return f == null ? null : f.getAbsolutePath(); - } - - @Override - public LocalFilesystemURL URLforFilesystemPath(String path) { - // Returns null as we don't support reverse mapping back to content:// URLs - return null; - } - - @Override - public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { - return true; - } -} diff --git a/plugins/cordova-plugin-file/src/android/DirectoryManager.java b/plugins/cordova-plugin-file/src/android/DirectoryManager.java deleted file mode 100644 index bcc005b2..00000000 --- a/plugins/cordova-plugin-file/src/android/DirectoryManager.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.file; - -import android.os.Environment; -import android.os.StatFs; - -import java.io.File; - -/** - * This class provides file directory utilities. - * All file operations are performed on the SD card. - * - * It is used by the FileUtils class. - */ -public class DirectoryManager { - - @SuppressWarnings("unused") - private static final String LOG_TAG = "DirectoryManager"; - - /** - * Determine if a file or directory exists. - * @param name The name of the file to check. - * @return T=exists, F=not found - */ - public static boolean testFileExists(String name) { - boolean status; - - // If SD card exists - if ((testSaveLocationExists()) && (!name.equals(""))) { - File path = Environment.getExternalStorageDirectory(); - File newPath = constructFilePaths(path.toString(), name); - status = newPath.exists(); - } - // If no SD card - else { - status = false; - } - return status; - } - - /** - * Get the free disk space - * - * @return Size in KB or -1 if not available - */ - public static long getFreeDiskSpace(boolean checkInternal) { - String status = Environment.getExternalStorageState(); - long freeSpace = 0; - - // If SD card exists - if (status.equals(Environment.MEDIA_MOUNTED)) { - freeSpace = freeSpaceCalculation(Environment.getExternalStorageDirectory().getPath()); - } - else if (checkInternal) { - freeSpace = freeSpaceCalculation("/"); - } - // If no SD card and we haven't been asked to check the internal directory then return -1 - else { - return -1; - } - - return freeSpace; - } - - /** - * Given a path return the number of free KB - * - * @param path to the file system - * @return free space in KB - */ - private static long freeSpaceCalculation(String path) { - StatFs stat = new StatFs(path); - long blockSize = stat.getBlockSize(); - long availableBlocks = stat.getAvailableBlocks(); - return availableBlocks * blockSize / 1024; - } - - /** - * Determine if SD card exists. - * - * @return T=exists, F=not found - */ - public static boolean testSaveLocationExists() { - String sDCardStatus = Environment.getExternalStorageState(); - boolean status; - - // If SD card is mounted - if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) { - status = true; - } - - // If no SD card - else { - status = false; - } - return status; - } - - /** - * Create a new file object from two file paths. - * - * @param file1 Base file path - * @param file2 Remaining file path - * @return File object - */ - private static File constructFilePaths (String file1, String file2) { - File newPath; - if (file2.startsWith(file1)) { - newPath = new File(file2); - } - else { - newPath = new File(file1 + "/" + file2); - } - return newPath; - } -} diff --git a/plugins/cordova-plugin-file/src/android/EncodingException.java b/plugins/cordova-plugin-file/src/android/EncodingException.java deleted file mode 100644 index e9e1653b..00000000 --- a/plugins/cordova-plugin-file/src/android/EncodingException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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. -*/ - -package org.apache.cordova.file; - -@SuppressWarnings("serial") -public class EncodingException extends Exception { - - public EncodingException(String message) { - super(message); - } - -} diff --git a/plugins/cordova-plugin-file/src/android/FileExistsException.java b/plugins/cordova-plugin-file/src/android/FileExistsException.java deleted file mode 100644 index 5c4d83dc..00000000 --- a/plugins/cordova-plugin-file/src/android/FileExistsException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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. -*/ - -package org.apache.cordova.file; - -@SuppressWarnings("serial") -public class FileExistsException extends Exception { - - public FileExistsException(String msg) { - super(msg); - } - -} diff --git a/plugins/cordova-plugin-file/src/android/FileUtils.java b/plugins/cordova-plugin-file/src/android/FileUtils.java deleted file mode 100644 index f57d26b3..00000000 --- a/plugins/cordova-plugin-file/src/android/FileUtils.java +++ /dev/null @@ -1,1027 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file; - -import android.app.Activity; -import android.content.Context; -import android.net.Uri; -import android.os.Environment; -import android.util.Base64; -import android.util.Log; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.PluginResult; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; - -/** - * This class provides file and directory services to JavaScript. - */ -public class FileUtils extends CordovaPlugin { - private static final String LOG_TAG = "FileUtils"; - - public static int NOT_FOUND_ERR = 1; - public static int SECURITY_ERR = 2; - public static int ABORT_ERR = 3; - - public static int NOT_READABLE_ERR = 4; - public static int ENCODING_ERR = 5; - public static int NO_MODIFICATION_ALLOWED_ERR = 6; - public static int INVALID_STATE_ERR = 7; - public static int SYNTAX_ERR = 8; - public static int INVALID_MODIFICATION_ERR = 9; - public static int QUOTA_EXCEEDED_ERR = 10; - public static int TYPE_MISMATCH_ERR = 11; - public static int PATH_EXISTS_ERR = 12; - - public static int UNKNOWN_ERR = 1000; - - private boolean configured = false; - - // This field exists only to support getEntry, below, which has been deprecated - private static FileUtils filePlugin; - - private interface FileOp { - void run(JSONArray args) throws Exception; - } - - private ArrayList<Filesystem> filesystems; - - public void registerFilesystem(Filesystem fs) { - if (fs != null && filesystemForName(fs.name)== null) { - this.filesystems.add(fs); - } - } - - private Filesystem filesystemForName(String name) { - for (Filesystem fs:filesystems) { - if (fs != null && fs.name != null && fs.name.equals(name)) { - return fs; - } - } - return null; - } - - protected String[] getExtraFileSystemsPreference(Activity activity) { - String fileSystemsStr = activity.getIntent().getStringExtra("androidextrafilesystems"); - if (fileSystemsStr == null) { - fileSystemsStr = "files,files-external,documents,sdcard,cache,cache-external,root"; - } - return fileSystemsStr.split(","); - } - - protected void registerExtraFileSystems(String[] filesystems, HashMap<String, String> availableFileSystems) { - HashSet<String> installedFileSystems = new HashSet<String>(); - - /* Register filesystems in order */ - for (String fsName : filesystems) { - if (!installedFileSystems.contains(fsName)) { - String fsRoot = availableFileSystems.get(fsName); - if (fsRoot != null) { - File newRoot = new File(fsRoot); - if (newRoot.mkdirs() || newRoot.isDirectory()) { - registerFilesystem(new LocalFilesystem(fsName, webView.getContext(), webView.getResourceApi(), newRoot)); - installedFileSystems.add(fsName); - } else { - Log.d(LOG_TAG, "Unable to create root dir for filesystem \"" + fsName + "\", skipping"); - } - } else { - Log.d(LOG_TAG, "Unrecognized extra filesystem identifier: " + fsName); - } - } - } - } - - protected HashMap<String, String> getAvailableFileSystems(Activity activity) { - Context context = activity.getApplicationContext(); - HashMap<String, String> availableFileSystems = new HashMap<String,String>(); - - availableFileSystems.put("files", context.getFilesDir().getAbsolutePath()); - availableFileSystems.put("documents", new File(context.getFilesDir(), "Documents").getAbsolutePath()); - availableFileSystems.put("cache", context.getCacheDir().getAbsolutePath()); - availableFileSystems.put("root", "/"); - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - try { - availableFileSystems.put("files-external", context.getExternalFilesDir(null).getAbsolutePath()); - availableFileSystems.put("sdcard", Environment.getExternalStorageDirectory().getAbsolutePath()); - availableFileSystems.put("cache-external", context.getExternalCacheDir().getAbsolutePath()); - } - catch(NullPointerException e) { - Log.d(LOG_TAG, "External storage unavailable, check to see if USB Mass Storage Mode is on"); - } - } - - return availableFileSystems; - } - - @Override - public void initialize(CordovaInterface cordova, CordovaWebView webView) { - super.initialize(cordova, webView); - this.filesystems = new ArrayList<Filesystem>(); - - String tempRoot = null; - String persistentRoot = null; - - Activity activity = cordova.getActivity(); - String packageName = activity.getPackageName(); - - String location = activity.getIntent().getStringExtra("androidpersistentfilelocation"); - if (location == null) { - location = "compatibility"; - } - tempRoot = activity.getCacheDir().getAbsolutePath(); - if ("internal".equalsIgnoreCase(location)) { - persistentRoot = activity.getFilesDir().getAbsolutePath() + "/files/"; - this.configured = true; - } else if ("compatibility".equalsIgnoreCase(location)) { - /* - * Fall-back to compatibility mode -- this is the logic implemented in - * earlier versions of this plugin, and should be maintained here so - * that apps which were originally deployed with older versions of the - * plugin can continue to provide access to files stored under those - * versions. - */ - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - persistentRoot = Environment.getExternalStorageDirectory().getAbsolutePath(); - tempRoot = Environment.getExternalStorageDirectory().getAbsolutePath() + - "/Android/data/" + packageName + "/cache/"; - } else { - persistentRoot = "/data/data/" + packageName; - } - this.configured = true; - } - - if (this.configured) { - // Create the directories if they don't exist. - File tmpRootFile = new File(tempRoot); - File persistentRootFile = new File(persistentRoot); - tmpRootFile.mkdirs(); - persistentRootFile.mkdirs(); - - // Register initial filesystems - // Note: The temporary and persistent filesystems need to be the first two - // registered, so that they will match window.TEMPORARY and window.PERSISTENT, - // per spec. - this.registerFilesystem(new LocalFilesystem("temporary", webView.getContext(), webView.getResourceApi(), tmpRootFile)); - this.registerFilesystem(new LocalFilesystem("persistent", webView.getContext(), webView.getResourceApi(), persistentRootFile)); - this.registerFilesystem(new ContentFilesystem(webView.getContext(), webView.getResourceApi())); - this.registerFilesystem(new AssetFilesystem(webView.getContext().getAssets(), webView.getResourceApi())); - - registerExtraFileSystems(getExtraFileSystemsPreference(activity), getAvailableFileSystems(activity)); - - // Initialize static plugin reference for deprecated getEntry method - if (filePlugin == null) { - FileUtils.filePlugin = this; - } - } else { - Log.e(LOG_TAG, "File plugin configuration error: Please set AndroidPersistentFileLocation in config.xml to one of \"internal\" (for new applications) or \"compatibility\" (for compatibility with previous versions)"); - activity.finish(); - } - } - - public static FileUtils getFilePlugin() { - return filePlugin; - } - - private Filesystem filesystemForURL(LocalFilesystemURL localURL) { - if (localURL == null) return null; - return filesystemForName(localURL.fsName); - } - - @Override - public Uri remapUri(Uri uri) { - // Remap only cdvfile: URLs (not content:). - if (!LocalFilesystemURL.FILESYSTEM_PROTOCOL.equals(uri.getScheme())) { - return null; - } - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - return null; - } - String path = fs.filesystemPathForURL(inputURL); - if (path != null) { - return Uri.parse("file://" + fs.filesystemPathForURL(inputURL)); - } - return null; - } catch (IllegalArgumentException e) { - return null; - } - } - - public boolean execute(String action, final String rawArgs, final CallbackContext callbackContext) { - if (!configured) { - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "File plugin is not configured. Please see the README.md file for details on how to update config.xml")); - return true; - } - if (action.equals("testSaveLocationExists")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) { - boolean b = DirectoryManager.testSaveLocationExists(); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); - } - }, rawArgs, callbackContext); - } - else if (action.equals("getFreeDiskSpace")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) { - long l = DirectoryManager.getFreeDiskSpace(false); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, l)); - } - }, rawArgs, callbackContext); - } - else if (action.equals("testFileExists")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException { - String fname=args.getString(0); - boolean b = DirectoryManager.testFileExists(fname); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); - } - }, rawArgs, callbackContext); - } - else if (action.equals("testDirectoryExists")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException { - String fname=args.getString(0); - boolean b = DirectoryManager.testFileExists(fname); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b)); - } - }, rawArgs, callbackContext); - } - else if (action.equals("readAsText")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { - String encoding = args.getString(1); - int start = args.getInt(2); - int end = args.getInt(3); - String fname=args.getString(0); - readFileAs(fname, start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING); - } - }, rawArgs, callbackContext); - } - else if (action.equals("readAsDataURL")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { - int start = args.getInt(1); - int end = args.getInt(2); - String fname=args.getString(0); - readFileAs(fname, start, end, callbackContext, null, -1); - } - }, rawArgs, callbackContext); - } - else if (action.equals("readAsArrayBuffer")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { - int start = args.getInt(1); - int end = args.getInt(2); - String fname=args.getString(0); - readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER); - } - }, rawArgs, callbackContext); - } - else if (action.equals("readAsBinaryString")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, MalformedURLException { - int start = args.getInt(1); - int end = args.getInt(2); - String fname=args.getString(0); - readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING); - } - }, rawArgs, callbackContext); - } - else if (action.equals("write")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException { - String fname=args.getString(0); - String data=args.getString(1); - int offset=args.getInt(2); - Boolean isBinary=args.getBoolean(3); - long fileSize = write(fname, data, offset, isBinary); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize)); - } - }, rawArgs, callbackContext); - } - else if (action.equals("truncate")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, FileNotFoundException, IOException, NoModificationAllowedException { - String fname=args.getString(0); - int offset=args.getInt(1); - long fileSize = truncateFile(fname, offset); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize)); - } - }, rawArgs, callbackContext); - } - else if (action.equals("requestAllFileSystems")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws IOException, JSONException { - callbackContext.success(requestAllFileSystems()); - } - }, rawArgs, callbackContext); - } else if (action.equals("requestAllPaths")) { - cordova.getThreadPool().execute( - new Runnable() { - public void run() { - try { - callbackContext.success(requestAllPaths()); - } catch (JSONException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - ); - } else if (action.equals("requestFileSystem")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws IOException, JSONException { - int fstype=args.getInt(0); - long size = args.optLong(1); - if (size != 0 && size > (DirectoryManager.getFreeDiskSpace(true) * 1024)) { - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, FileUtils.QUOTA_EXCEEDED_ERR)); - } else { - JSONObject obj = requestFileSystem(fstype); - callbackContext.success(obj); - } - } - }, rawArgs, callbackContext); - } - else if (action.equals("resolveLocalFileSystemURI")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws IOException, JSONException { - String fname=args.getString(0); - JSONObject obj = resolveLocalFileSystemURI(fname); - callbackContext.success(obj); - } - }, rawArgs, callbackContext); - } - else if (action.equals("getFileMetadata")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException { - String fname=args.getString(0); - JSONObject obj = getFileMetadata(fname); - callbackContext.success(obj); - } - }, rawArgs, callbackContext); - } - else if (action.equals("getParent")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, IOException { - String fname=args.getString(0); - JSONObject obj = getParent(fname); - callbackContext.success(obj); - } - }, rawArgs, callbackContext); - } - else if (action.equals("getDirectory")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { - String dirname=args.getString(0); - String path=args.getString(1); - JSONObject obj = getFile(dirname, path, args.optJSONObject(2), true); - callbackContext.success(obj); - } - }, rawArgs, callbackContext); - } - else if (action.equals("getFile")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { - String dirname=args.getString(0); - String path=args.getString(1); - JSONObject obj = getFile(dirname, path, args.optJSONObject(2), false); - callbackContext.success(obj); - } - }, rawArgs, callbackContext); - } - else if (action.equals("remove")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, NoModificationAllowedException, InvalidModificationException, MalformedURLException { - String fname=args.getString(0); - boolean success = remove(fname); - if (success) { - callbackContext.success(); - } else { - callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR); - } - } - }, rawArgs, callbackContext); - } - else if (action.equals("removeRecursively")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, FileExistsException, MalformedURLException, NoModificationAllowedException { - String fname=args.getString(0); - boolean success = removeRecursively(fname); - if (success) { - callbackContext.success(); - } else { - callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR); - } - } - }, rawArgs, callbackContext); - } - else if (action.equals("moveTo")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { - String fname=args.getString(0); - String newParent=args.getString(1); - String newName=args.getString(2); - JSONObject entry = transferTo(fname, newParent, newName, true); - callbackContext.success(entry); - } - }, rawArgs, callbackContext); - } - else if (action.equals("copyTo")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { - String fname=args.getString(0); - String newParent=args.getString(1); - String newName=args.getString(2); - JSONObject entry = transferTo(fname, newParent, newName, false); - callbackContext.success(entry); - } - }, rawArgs, callbackContext); - } - else if (action.equals("readEntries")) { - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException { - String fname=args.getString(0); - JSONArray entries = readEntries(fname); - callbackContext.success(entries); - } - }, rawArgs, callbackContext); - } - else if (action.equals("_getLocalFilesystemPath")) { - // Internal method for testing: Get the on-disk location of a local filesystem url. - // [Currently used for testing file-transfer] - threadhelper( new FileOp( ){ - public void run(JSONArray args) throws FileNotFoundException, JSONException, MalformedURLException { - String localURLstr = args.getString(0); - String fname = filesystemPathForURL(localURLstr); - callbackContext.success(fname); - } - }, rawArgs, callbackContext); - } - else { - return false; - } - return true; - } - - public LocalFilesystemURL resolveNativeUri(Uri nativeUri) { - LocalFilesystemURL localURL = null; - - // Try all installed filesystems. Return the best matching URL - // (determined by the shortest resulting URL) - for (Filesystem fs : filesystems) { - LocalFilesystemURL url = fs.toLocalUri(nativeUri); - if (url != null) { - // A shorter fullPath implies that the filesystem is a better - // match for the local path than the previous best. - if (localURL == null || (url.uri.toString().length() < localURL.toString().length())) { - localURL = url; - } - } - } - return localURL; - } - - /* - * These two native-only methods can be used by other plugins to translate between - * device file system paths and URLs. By design, there is no direct JavaScript - * interface to these methods. - */ - - public String filesystemPathForURL(String localURLstr) throws MalformedURLException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(localURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.filesystemPathForURL(inputURL); - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } - - public LocalFilesystemURL filesystemURLforLocalPath(String localPath) { - LocalFilesystemURL localURL = null; - int shortestFullPath = 0; - - // Try all installed filesystems. Return the best matching URL - // (determined by the shortest resulting URL) - for (Filesystem fs: filesystems) { - LocalFilesystemURL url = fs.URLforFilesystemPath(localPath); - if (url != null) { - // A shorter fullPath implies that the filesystem is a better - // match for the local path than the previous best. - if (localURL == null || (url.path.length() < shortestFullPath)) { - localURL = url; - shortestFullPath = url.path.length(); - } - } - } - return localURL; - } - - - /* helper to execute functions async and handle the result codes - * - */ - private void threadhelper(final FileOp f, final String rawArgs, final CallbackContext callbackContext){ - cordova.getThreadPool().execute(new Runnable() { - public void run() { - try { - JSONArray args = new JSONArray(rawArgs); - f.run(args); - } catch ( Exception e) { - if( e instanceof EncodingException){ - callbackContext.error(FileUtils.ENCODING_ERR); - } else if(e instanceof FileNotFoundException) { - callbackContext.error(FileUtils.NOT_FOUND_ERR); - } else if(e instanceof FileExistsException) { - callbackContext.error(FileUtils.PATH_EXISTS_ERR); - } else if(e instanceof NoModificationAllowedException ) { - callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR); - } else if(e instanceof InvalidModificationException ) { - callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR); - } else if(e instanceof MalformedURLException ) { - callbackContext.error(FileUtils.ENCODING_ERR); - } else if(e instanceof IOException ) { - callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR); - } else if(e instanceof EncodingException ) { - callbackContext.error(FileUtils.ENCODING_ERR); - } else if(e instanceof TypeMismatchException ) { - callbackContext.error(FileUtils.TYPE_MISMATCH_ERR); - } else if(e instanceof JSONException ) { - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); - } else { - e.printStackTrace(); - callbackContext.error(FileUtils.UNKNOWN_ERR); - } - } - } - }); - } - - /** - * Allows the user to look up the Entry for a file or directory referred to by a local URI. - * - * @param uriString of the file/directory to look up - * @return a JSONObject representing a Entry from the filesystem - * @throws MalformedURLException if the url is not valid - * @throws FileNotFoundException if the file does not exist - * @throws IOException if the user can't read the file - * @throws JSONException - */ - private JSONObject resolveLocalFileSystemURI(String uriString) throws IOException, JSONException { - if (uriString == null) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - Uri uri = Uri.parse(uriString); - - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(uri); - if (inputURL == null) { - /* Check for file://, content:// urls */ - inputURL = resolveNativeUri(uri); - } - - try { - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - if (fs.exists(inputURL)) { - return fs.getEntryForLocalURL(inputURL); - } - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - throw new FileNotFoundException(); - } - - /** - * Read the list of files from this directory. - * - * @return a JSONArray containing JSONObjects that represent Entry objects. - * @throws FileNotFoundException if the directory is not found. - * @throws JSONException - * @throws MalformedURLException - */ - private JSONArray readEntries(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.readEntriesAtLocalURL(inputURL); - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } - - /** - * A setup method that handles the move/copy of files/directories - * - * @param newName for the file directory to be called, if null use existing file name - * @param move if false do a copy, if true do a move - * @return a Entry object - * @throws NoModificationAllowedException - * @throws IOException - * @throws InvalidModificationException - * @throws EncodingException - * @throws JSONException - * @throws FileExistsException - */ - private JSONObject transferTo(String srcURLstr, String destURLstr, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException { - if (srcURLstr == null || destURLstr == null) { - // either no source or no destination provided - throw new FileNotFoundException(); - } - - LocalFilesystemURL srcURL = LocalFilesystemURL.parse(srcURLstr); - LocalFilesystemURL destURL = LocalFilesystemURL.parse(destURLstr); - - Filesystem srcFs = this.filesystemForURL(srcURL); - Filesystem destFs = this.filesystemForURL(destURL); - - // Check for invalid file name - if (newName != null && newName.contains(":")) { - throw new EncodingException("Bad file name"); - } - - return destFs.copyFileToURL(destURL, newName, srcFs, srcURL, move); - } - - /** - * Deletes a directory and all of its contents, if any. In the event of an error - * [e.g. trying to delete a directory that contains a file that cannot be removed], - * some of the contents of the directory may be deleted. - * It is an error to attempt to delete the root directory of a filesystem. - * - * @return a boolean representing success of failure - * @throws FileExistsException - * @throws NoModificationAllowedException - * @throws MalformedURLException - */ - private boolean removeRecursively(String baseURLstr) throws FileExistsException, NoModificationAllowedException, MalformedURLException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - // You can't delete the root directory. - if ("".equals(inputURL.path) || "/".equals(inputURL.path)) { - throw new NoModificationAllowedException("You can't delete the root directory"); - } - - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.recursiveRemoveFileAtLocalURL(inputURL); - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } - - - /** - * Deletes a file or directory. It is an error to attempt to delete a directory that is not empty. - * It is an error to attempt to delete the root directory of a filesystem. - * - * @return a boolean representing success of failure - * @throws NoModificationAllowedException - * @throws InvalidModificationException - * @throws MalformedURLException - */ - private boolean remove(String baseURLstr) throws NoModificationAllowedException, InvalidModificationException, MalformedURLException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - // You can't delete the root directory. - if ("".equals(inputURL.path) || "/".equals(inputURL.path)) { - - throw new NoModificationAllowedException("You can't delete the root directory"); - } - - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.removeFileAtLocalURL(inputURL); - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } - - /** - * Creates or looks up a file. - * - * @param baseURLstr base directory - * @param path file/directory to lookup or create - * @param options specify whether to create or not - * @param directory if true look up directory, if false look up file - * @return a Entry object - * @throws FileExistsException - * @throws IOException - * @throws TypeMismatchException - * @throws EncodingException - * @throws JSONException - */ - private JSONObject getFile(String baseURLstr, String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.getFileForLocalURL(inputURL, path, options, directory); - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - - } - - /** - * Look up the parent DirectoryEntry containing this Entry. - * If this Entry is the root of its filesystem, its parent is itself. - */ - private JSONObject getParent(String baseURLstr) throws JSONException, IOException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.getParentForLocalURL(inputURL); - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } - - /** - * Returns a File that represents the current state of the file that this FileEntry represents. - * - * @return returns a JSONObject represent a W3C File object - */ - private JSONObject getFileMetadata(String baseURLstr) throws FileNotFoundException, JSONException, MalformedURLException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(baseURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - return fs.getFileMetadataForLocalURL(inputURL); - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } - - /** - * Requests a filesystem in which to store application data. - * - * @param type of file system requested - * @return a JSONObject representing the file system - * @throws IOException - * @throws JSONException - */ - private JSONObject requestFileSystem(int type) throws IOException, JSONException { - JSONObject fs = new JSONObject(); - Filesystem rootFs = null; - try { - rootFs = this.filesystems.get(type); - } catch (ArrayIndexOutOfBoundsException e) { - // Pass null through - } - if (rootFs == null) { - throw new IOException("No filesystem of type requested"); - } - fs.put("name", rootFs.name); - fs.put("root", rootFs.getRootEntry()); - return fs; - } - - - /** - * Requests a filesystem in which to store application data. - * - * @return a JSONObject representing the file system - */ - private JSONArray requestAllFileSystems() throws IOException, JSONException { - JSONArray ret = new JSONArray(); - for (Filesystem fs : filesystems) { - ret.put(fs.getRootEntry()); - } - return ret; - } - - private static String toDirUrl(File f) { - return Uri.fromFile(f).toString() + '/'; - } - - private JSONObject requestAllPaths() throws JSONException { - Context context = cordova.getActivity(); - JSONObject ret = new JSONObject(); - ret.put("applicationDirectory", "file:///android_asset/"); - ret.put("applicationStorageDirectory", toDirUrl(context.getFilesDir().getParentFile())); - ret.put("dataDirectory", toDirUrl(context.getFilesDir())); - ret.put("cacheDirectory", toDirUrl(context.getCacheDir())); - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - try { - ret.put("externalApplicationStorageDirectory", toDirUrl(context.getExternalFilesDir(null).getParentFile())); - ret.put("externalDataDirectory", toDirUrl(context.getExternalFilesDir(null))); - ret.put("externalCacheDirectory", toDirUrl(context.getExternalCacheDir())); - ret.put("externalRootDirectory", toDirUrl(Environment.getExternalStorageDirectory())); - } - catch(NullPointerException e) { - /* If external storage is unavailable, context.getExternal* returns null */ - Log.d(LOG_TAG, "Unable to access these paths, most liklely due to USB storage"); - } - } - return ret; - } - - /** - * Returns a JSON object representing the given File. Internal APIs should be modified - * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin. - * - * @param file the File to convert - * @return a JSON representation of the given File - * @throws JSONException - */ - public JSONObject getEntryForFile(File file) throws JSONException { - JSONObject entry; - - for (Filesystem fs : filesystems) { - entry = fs.makeEntryForFile(file); - if (entry != null) { - return entry; - } - } - return null; - } - - /** - * Returns a JSON object representing the given File. Deprecated, as this is only used by - * FileTransfer, and because it is a static method that should really be an instance method, - * since it depends on the actual filesystem roots in use. Internal APIs should be modified - * to use URLs instead of raw FS paths wherever possible, when interfacing with this plugin. - * - * @param file the File to convert - * @return a JSON representation of the given File - * @throws JSONException - */ - @Deprecated - public static JSONObject getEntry(File file) throws JSONException { - if (getFilePlugin() != null) { - return getFilePlugin().getEntryForFile(file); - } - return null; - } - - /** - * Read the contents of a file. - * This is done in a background thread; the result is sent to the callback. - * - * @param start Start position in the file. - * @param end End position to stop at (exclusive). - * @param callbackContext The context through which to send the result. - * @param encoding The encoding to return contents as. Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets) - * @param resultType The desired type of data to send to the callback. - * @return Contents of file. - */ - public void readFileAs(final String srcURLstr, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) throws MalformedURLException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - - fs.readFileAtURL(inputURL, start, end, new Filesystem.ReadFileCallback() { - public void handleData(InputStream inputStream, String contentType) { - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - final int BUFFER_SIZE = 8192; - byte[] buffer = new byte[BUFFER_SIZE]; - - for (;;) { - int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE); - - if (bytesRead <= 0) { - break; - } - os.write(buffer, 0, bytesRead); - } - - PluginResult result; - switch (resultType) { - case PluginResult.MESSAGE_TYPE_STRING: - result = new PluginResult(PluginResult.Status.OK, os.toString(encoding)); - break; - case PluginResult.MESSAGE_TYPE_ARRAYBUFFER: - result = new PluginResult(PluginResult.Status.OK, os.toByteArray()); - break; - case PluginResult.MESSAGE_TYPE_BINARYSTRING: - result = new PluginResult(PluginResult.Status.OK, os.toByteArray(), true); - break; - default: // Base64. - byte[] base64 = Base64.encode(os.toByteArray(), Base64.NO_WRAP); - String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII"); - result = new PluginResult(PluginResult.Status.OK, s); - } - - callbackContext.sendPluginResult(result); - } catch (IOException e) { - Log.d(LOG_TAG, e.getLocalizedMessage()); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR)); - } - } - }); - - - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } catch (FileNotFoundException e) { - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR)); - } catch (IOException e) { - Log.d(LOG_TAG, e.getLocalizedMessage()); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR)); - } - } - - - /** - * Write contents of file. - * - * @param data The contents of the file. - * @param offset The position to begin writing the file. - * @param isBinary True if the file contents are base64-encoded binary data - */ - /**/ - public long write(String srcURLstr, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - - long x = fs.writeToFileAtURL(inputURL, data, offset, isBinary); Log.d("TEST",srcURLstr + ": "+x); return x; - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - - } - - /** - * Truncate the file to size - */ - private long truncateFile(String srcURLstr, long size) throws FileNotFoundException, IOException, NoModificationAllowedException { - try { - LocalFilesystemURL inputURL = LocalFilesystemURL.parse(srcURLstr); - Filesystem fs = this.filesystemForURL(inputURL); - if (fs == null) { - throw new MalformedURLException("No installed handlers for this URL"); - } - - return fs.truncateFileAtURL(inputURL, size); - } catch (IllegalArgumentException e) { - throw new MalformedURLException("Unrecognized filesystem URL"); - } - } -} diff --git a/plugins/cordova-plugin-file/src/android/Filesystem.java b/plugins/cordova-plugin-file/src/android/Filesystem.java deleted file mode 100644 index faf31d2a..00000000 --- a/plugins/cordova-plugin-file/src/android/Filesystem.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file; - -import android.net.Uri; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; - -import org.apache.cordova.CordovaResourceApi; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -public abstract class Filesystem { - - protected final Uri rootUri; - protected final CordovaResourceApi resourceApi; - public final String name; - private JSONObject rootEntry; - - public Filesystem(Uri rootUri, String name, CordovaResourceApi resourceApi) { - this.rootUri = rootUri; - this.name = name; - this.resourceApi = resourceApi; - } - - public interface ReadFileCallback { - public void handleData(InputStream inputStream, String contentType) throws IOException; - } - - public static JSONObject makeEntryForURL(LocalFilesystemURL inputURL, Uri nativeURL) { - try { - String path = inputURL.path; - int end = path.endsWith("/") ? 1 : 0; - String[] parts = path.substring(0, path.length() - end).split("/+"); - String fileName = parts[parts.length - 1]; - - JSONObject entry = new JSONObject(); - entry.put("isFile", !inputURL.isDirectory); - entry.put("isDirectory", inputURL.isDirectory); - entry.put("name", fileName); - entry.put("fullPath", path); - // The file system can't be specified, as it would lead to an infinite loop, - // but the filesystem name can be. - entry.put("filesystemName", inputURL.fsName); - // Backwards compatibility - entry.put("filesystem", "temporary".equals(inputURL.fsName) ? 0 : 1); - - String nativeUrlStr = nativeURL.toString(); - if (inputURL.isDirectory && !nativeUrlStr.endsWith("/")) { - nativeUrlStr += "/"; - } - entry.put("nativeURL", nativeUrlStr); - return entry; - } catch (JSONException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public JSONObject makeEntryForURL(LocalFilesystemURL inputURL) { - Uri nativeUri = toNativeUri(inputURL); - return nativeUri == null ? null : makeEntryForURL(inputURL, nativeUri); - } - - public JSONObject makeEntryForNativeUri(Uri nativeUri) { - LocalFilesystemURL inputUrl = toLocalUri(nativeUri); - return inputUrl == null ? null : makeEntryForURL(inputUrl, nativeUri); - } - - public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException { - return makeEntryForURL(inputURL); - } - - public JSONObject makeEntryForFile(File file) { - return makeEntryForNativeUri(Uri.fromFile(file)); - } - - abstract JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, String path, - JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException; - - abstract boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException; - - abstract boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException, NoModificationAllowedException; - - abstract LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException; - - public final JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { - LocalFilesystemURL[] children = listChildren(inputURL); - JSONArray entries = new JSONArray(); - if (children != null) { - for (LocalFilesystemURL url : children) { - entries.put(makeEntryForURL(url)); - } - } - return entries; - } - - abstract JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException; - - public Uri getRootUri() { - return rootUri; - } - - public boolean exists(LocalFilesystemURL inputURL) { - try { - getFileMetadataForLocalURL(inputURL); - } catch (FileNotFoundException e) { - return false; - } - return true; - } - - public Uri nativeUriForFullPath(String fullPath) { - Uri ret = null; - if (fullPath != null) { - String encodedPath = Uri.fromFile(new File(fullPath)).getEncodedPath(); - if (encodedPath.startsWith("/")) { - encodedPath = encodedPath.substring(1); - } - ret = rootUri.buildUpon().appendEncodedPath(encodedPath).build(); - } - return ret; - } - - public LocalFilesystemURL localUrlforFullPath(String fullPath) { - Uri nativeUri = nativeUriForFullPath(fullPath); - if (nativeUri != null) { - return toLocalUri(nativeUri); - } - return null; - } - - /** - * Removes multiple repeated //s, and collapses processes ../s. - */ - protected static String normalizePath(String rawPath) { - // If this is an absolute path, trim the leading "/" and replace it later - boolean isAbsolutePath = rawPath.startsWith("/"); - if (isAbsolutePath) { - rawPath = rawPath.replaceFirst("/+", ""); - } - ArrayList<String> components = new ArrayList<String>(Arrays.asList(rawPath.split("/+"))); - for (int index = 0; index < components.size(); ++index) { - if (components.get(index).equals("..")) { - components.remove(index); - if (index > 0) { - components.remove(index-1); - --index; - } - } - } - StringBuilder normalizedPath = new StringBuilder(); - for(String component: components) { - normalizedPath.append("/"); - normalizedPath.append(component); - } - if (isAbsolutePath) { - return normalizedPath.toString(); - } else { - return normalizedPath.toString().substring(1); - } - } - - - - public abstract Uri toNativeUri(LocalFilesystemURL inputURL); - public abstract LocalFilesystemURL toLocalUri(Uri inputURL); - - public JSONObject getRootEntry() { - if (rootEntry == null) { - rootEntry = makeEntryForNativeUri(rootUri); - } - return rootEntry; - } - - public JSONObject getParentForLocalURL(LocalFilesystemURL inputURL) throws IOException { - Uri parentUri = inputURL.uri; - String parentPath = new File(inputURL.uri.getPath()).getParent(); - if (!"/".equals(parentPath)) { - parentUri = inputURL.uri.buildUpon().path(parentPath + '/').build(); - } - return getEntryForLocalURL(LocalFilesystemURL.parse(parentUri)); - } - - protected LocalFilesystemURL makeDestinationURL(String newName, LocalFilesystemURL srcURL, LocalFilesystemURL destURL, boolean isDirectory) { - // I know this looks weird but it is to work around a JSON bug. - if ("null".equals(newName) || "".equals(newName)) { - newName = srcURL.uri.getLastPathSegment();; - } - - String newDest = destURL.uri.toString(); - if (newDest.endsWith("/")) { - newDest = newDest + newName; - } else { - newDest = newDest + "/" + newName; - } - if (isDirectory) { - newDest += '/'; - } - return LocalFilesystemURL.parse(newDest); - } - - /* Read a source URL (possibly from a different filesystem, srcFs,) and copy it to - * the destination URL on this filesystem, optionally with a new filename. - * If move is true, then this method should either perform an atomic move operation - * or remove the source file when finished. - */ - public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, - Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { - // First, check to see that we can do it - if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) { - throw new NoModificationAllowedException("Cannot move file at source URL"); - } - final LocalFilesystemURL destination = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory); - - Uri srcNativeUri = srcFs.toNativeUri(srcURL); - - CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcNativeUri); - OutputStream os = null; - try { - os = getOutputStreamForURL(destination); - } catch (IOException e) { - ofrr.inputStream.close(); - throw e; - } - // Closes streams. - resourceApi.copyResource(ofrr, os); - - if (move) { - srcFs.removeFileAtLocalURL(srcURL); - } - return getEntryForLocalURL(destination); - } - - public OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL) throws IOException { - return resourceApi.openOutputStream(toNativeUri(inputURL)); - } - - public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end, - ReadFileCallback readFileCallback) throws IOException { - CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(toNativeUri(inputURL)); - if (end < 0) { - end = ofrr.length; - } - long numBytesToRead = end - start; - try { - if (start > 0) { - ofrr.inputStream.skip(start); - } - InputStream inputStream = ofrr.inputStream; - if (end < ofrr.length) { - inputStream = new LimitedInputStream(inputStream, numBytesToRead); - } - readFileCallback.handleData(inputStream, ofrr.mimeType); - } finally { - ofrr.inputStream.close(); - } - } - - abstract long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, - boolean isBinary) throws NoModificationAllowedException, IOException; - - abstract long truncateFileAtURL(LocalFilesystemURL inputURL, long size) - throws IOException, NoModificationAllowedException; - - // This method should return null if filesystem urls cannot be mapped to paths - abstract String filesystemPathForURL(LocalFilesystemURL url); - - abstract LocalFilesystemURL URLforFilesystemPath(String path); - - abstract boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL); - - protected class LimitedInputStream extends FilterInputStream { - long numBytesToRead; - public LimitedInputStream(InputStream in, long numBytesToRead) { - super(in); - this.numBytesToRead = numBytesToRead; - } - @Override - public int read() throws IOException { - if (numBytesToRead <= 0) { - return -1; - } - numBytesToRead--; - return in.read(); - } - @Override - public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { - if (numBytesToRead <= 0) { - return -1; - } - int bytesToRead = byteCount; - if (byteCount > numBytesToRead) { - bytesToRead = (int)numBytesToRead; // Cast okay; long is less than int here. - } - int numBytesRead = in.read(buffer, byteOffset, bytesToRead); - numBytesToRead -= numBytesRead; - return numBytesRead; - } - } -} diff --git a/plugins/cordova-plugin-file/src/android/InvalidModificationException.java b/plugins/cordova-plugin-file/src/android/InvalidModificationException.java deleted file mode 100644 index 8f6bec59..00000000 --- a/plugins/cordova-plugin-file/src/android/InvalidModificationException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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. -*/ - - -package org.apache.cordova.file; - -@SuppressWarnings("serial") -public class InvalidModificationException extends Exception { - - public InvalidModificationException(String message) { - super(message); - } - -} diff --git a/plugins/cordova-plugin-file/src/android/LocalFilesystem.java b/plugins/cordova-plugin-file/src/android/LocalFilesystem.java deleted file mode 100644 index 3b1ecca8..00000000 --- a/plugins/cordova-plugin-file/src/android/LocalFilesystem.java +++ /dev/null @@ -1,505 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.nio.channels.FileChannel; -import org.apache.cordova.CordovaResourceApi; -import org.json.JSONException; -import org.json.JSONObject; - -import android.os.Build; -import android.os.Environment; -import android.util.Base64; -import android.net.Uri; -import android.content.Context; -import android.content.Intent; - -public class LocalFilesystem extends Filesystem { - private final Context context; - - public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, File fsRoot) { - super(Uri.fromFile(fsRoot).buildUpon().appendEncodedPath("").build(), name, resourceApi); - this.context = context; - } - - public String filesystemPathForFullPath(String fullPath) { - return new File(rootUri.getPath(), fullPath).toString(); - } - - @Override - public String filesystemPathForURL(LocalFilesystemURL url) { - return filesystemPathForFullPath(url.path); - } - - private String fullPathForFilesystemPath(String absolutePath) { - if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) { - return absolutePath.substring(rootUri.getPath().length() - 1); - } - return null; - } - - @Override - public Uri toNativeUri(LocalFilesystemURL inputURL) { - return nativeUriForFullPath(inputURL.path); - } - - @Override - public LocalFilesystemURL toLocalUri(Uri inputURL) { - if (!"file".equals(inputURL.getScheme())) { - return null; - } - File f = new File(inputURL.getPath()); - // Removes and duplicate /s (e.g. file:///a//b/c) - Uri resolvedUri = Uri.fromFile(f); - String rootUriNoTrailingSlash = rootUri.getEncodedPath(); - rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1); - if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) { - return null; - } - String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length()); - // Strip leading slash - if (!subPath.isEmpty()) { - subPath = subPath.substring(1); - } - Uri.Builder b = new Uri.Builder() - .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL) - .authority("localhost") - .path(name); - if (!subPath.isEmpty()) { - b.appendEncodedPath(subPath); - } - if (f.isDirectory() || inputURL.getPath().endsWith("/")) { - // Add trailing / for directories. - b.appendEncodedPath(""); - } - return LocalFilesystemURL.parse(b.build()); - } - - @Override - public LocalFilesystemURL URLforFilesystemPath(String path) { - return localUrlforFullPath(fullPathForFilesystemPath(path)); - } - - @Override - public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL, - String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException { - boolean create = false; - boolean exclusive = false; - - if (options != null) { - create = options.optBoolean("create"); - if (create) { - exclusive = options.optBoolean("exclusive"); - } - } - - // Check for a ":" character in the file to line up with BB and iOS - if (path.contains(":")) { - throw new EncodingException("This path has an invalid \":\" in it."); - } - - LocalFilesystemURL requestedURL; - - // Check whether the supplied path is absolute or relative - if (directory && !path.endsWith("/")) { - path += "/"; - } - if (path.startsWith("/")) { - requestedURL = localUrlforFullPath(normalizePath(path)); - } else { - requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path)); - } - - File fp = new File(this.filesystemPathForURL(requestedURL)); - - if (create) { - if (exclusive && fp.exists()) { - throw new FileExistsException("create/exclusive fails"); - } - if (directory) { - fp.mkdir(); - } else { - fp.createNewFile(); - } - if (!fp.exists()) { - throw new FileExistsException("create fails"); - } - } - else { - if (!fp.exists()) { - throw new FileNotFoundException("path does not exist"); - } - if (directory) { - if (fp.isFile()) { - throw new TypeMismatchException("path doesn't exist or is file"); - } - } else { - if (fp.isDirectory()) { - throw new TypeMismatchException("path doesn't exist or is directory"); - } - } - } - - // Return the directory - return makeEntryForURL(requestedURL); - } - - @Override - public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException { - - File fp = new File(filesystemPathForURL(inputURL)); - - // You can't delete a directory that is not empty - if (fp.isDirectory() && fp.list().length > 0) { - throw new InvalidModificationException("You can't delete a directory that is not empty."); - } - - return fp.delete(); - } - - @Override - public boolean exists(LocalFilesystemURL inputURL) { - File fp = new File(filesystemPathForURL(inputURL)); - return fp.exists(); - } - - @Override - public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException { - File directory = new File(filesystemPathForURL(inputURL)); - return removeDirRecursively(directory); - } - - protected boolean removeDirRecursively(File directory) throws FileExistsException { - if (directory.isDirectory()) { - for (File file : directory.listFiles()) { - removeDirRecursively(file); - } - } - - if (!directory.delete()) { - throw new FileExistsException("could not delete: " + directory.getName()); - } else { - return true; - } - } - - @Override - public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException { - File fp = new File(filesystemPathForURL(inputURL)); - - if (!fp.exists()) { - // The directory we are listing doesn't exist so we should fail. - throw new FileNotFoundException(); - } - - File[] files = fp.listFiles(); - if (files == null) { - // inputURL is a directory - return null; - } - LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length]; - for (int i = 0; i < files.length; i++) { - entries[i] = URLforFilesystemPath(files[i].getPath()); - } - - return entries; - } - - @Override - public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException { - File file = new File(filesystemPathForURL(inputURL)); - - if (!file.exists()) { - throw new FileNotFoundException("File at " + inputURL.uri + " does not exist."); - } - - JSONObject metadata = new JSONObject(); - try { - // Ensure that directories report a size of 0 - metadata.put("size", file.isDirectory() ? 0 : file.length()); - metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file))); - metadata.put("name", file.getName()); - metadata.put("fullPath", inputURL.path); - metadata.put("lastModifiedDate", file.lastModified()); - } catch (JSONException e) { - return null; - } - return metadata; - } - - private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException { - if (move) { - String realSrcPath = srcFs.filesystemPathForURL(srcURL); - if (realSrcPath != null) { - File srcFile = new File(realSrcPath); - if (srcFile.renameTo(destFile)) { - return; - } - // Trying to rename the file failed. Possibly because we moved across file system on the device. - } - } - - CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(srcFs.toNativeUri(srcURL)); - copyResource(offr, new FileOutputStream(destFile)); - - if (move) { - srcFs.removeFileAtLocalURL(srcURL); - } - } - - private void copyDirectory(Filesystem srcFs, LocalFilesystemURL srcURL, File dstDir, boolean move) throws IOException, NoModificationAllowedException, InvalidModificationException, FileExistsException { - if (move) { - String realSrcPath = srcFs.filesystemPathForURL(srcURL); - if (realSrcPath != null) { - File srcDir = new File(realSrcPath); - // If the destination directory already exists and is empty then delete it. This is according to spec. - if (dstDir.exists()) { - if (dstDir.list().length > 0) { - throw new InvalidModificationException("directory is not empty"); - } - dstDir.delete(); - } - // Try to rename the directory - if (srcDir.renameTo(dstDir)) { - return; - } - // Trying to rename the file failed. Possibly because we moved across file system on the device. - } - } - - if (dstDir.exists()) { - if (dstDir.list().length > 0) { - throw new InvalidModificationException("directory is not empty"); - } - } else { - if (!dstDir.mkdir()) { - // If we can't create the directory then fail - throw new NoModificationAllowedException("Couldn't create the destination directory"); - } - } - - LocalFilesystemURL[] children = srcFs.listChildren(srcURL); - for (LocalFilesystemURL childLocalUrl : children) { - File target = new File(dstDir, new File(childLocalUrl.path).getName()); - if (childLocalUrl.isDirectory) { - copyDirectory(srcFs, childLocalUrl, target, false); - } else { - copyFile(srcFs, childLocalUrl, target, false); - } - } - - if (move) { - srcFs.recursiveRemoveFileAtLocalURL(srcURL); - } - } - - @Override - public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName, - Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException { - - // Check to see if the destination directory exists - String newParent = this.filesystemPathForURL(destURL); - File destinationDir = new File(newParent); - if (!destinationDir.exists()) { - // The destination does not exist so we should fail. - throw new FileNotFoundException("The source does not exist"); - } - - // Figure out where we should be copying to - final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory); - - Uri dstNativeUri = toNativeUri(destinationURL); - Uri srcNativeUri = srcFs.toNativeUri(srcURL); - // Check to see if source and destination are the same file - if (dstNativeUri.equals(srcNativeUri)) { - throw new InvalidModificationException("Can't copy onto itself"); - } - - if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) { - throw new InvalidModificationException("Source URL is read-only (cannot move)"); - } - - File destFile = new File(dstNativeUri.getPath()); - if (destFile.exists()) { - if (!srcURL.isDirectory && destFile.isDirectory()) { - throw new InvalidModificationException("Can't copy/move a file to an existing directory"); - } else if (srcURL.isDirectory && destFile.isFile()) { - throw new InvalidModificationException("Can't copy/move a directory to an existing file"); - } - } - - if (srcURL.isDirectory) { - // E.g. Copy /sdcard/myDir to /sdcard/myDir/backup - if (dstNativeUri.toString().startsWith(srcNativeUri.toString() + '/')) { - throw new InvalidModificationException("Can't copy directory into itself"); - } - copyDirectory(srcFs, srcURL, destFile, move); - } else { - copyFile(srcFs, srcURL, destFile, move); - } - return makeEntryForURL(destinationURL); - } - - @Override - public long writeToFileAtURL(LocalFilesystemURL inputURL, String data, - int offset, boolean isBinary) throws IOException, NoModificationAllowedException { - - boolean append = false; - if (offset > 0) { - this.truncateFileAtURL(inputURL, offset); - append = true; - } - - byte[] rawData; - if (isBinary) { - rawData = Base64.decode(data, Base64.DEFAULT); - } else { - rawData = data.getBytes(); - } - ByteArrayInputStream in = new ByteArrayInputStream(rawData); - try - { - byte buff[] = new byte[rawData.length]; - String absolutePath = filesystemPathForURL(inputURL); - FileOutputStream out = new FileOutputStream(absolutePath, append); - try { - in.read(buff, 0, buff.length); - out.write(buff, 0, rawData.length); - out.flush(); - } finally { - // Always close the output - out.close(); - } - if (isPublicDirectory(absolutePath)) { - broadcastNewFile(Uri.fromFile(new File(absolutePath))); - } - } - catch (NullPointerException e) - { - // This is a bug in the Android implementation of the Java Stack - NoModificationAllowedException realException = new NoModificationAllowedException(inputURL.toString()); - throw realException; - } - - return rawData.length; - } - - private boolean isPublicDirectory(String absolutePath) { - // TODO: should expose a way to scan app's private files (maybe via a flag). - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - // Lollipop has a bug where SD cards are null. - for (File f : context.getExternalMediaDirs()) { - if(f != null && absolutePath.startsWith(f.getAbsolutePath())) { - return true; - } - } - } - - String extPath = Environment.getExternalStorageDirectory().getAbsolutePath(); - return absolutePath.startsWith(extPath); - } - - /** - * Send broadcast of new file so files appear over MTP - */ - private void broadcastNewFile(Uri nativeUri) { - Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, nativeUri); - context.sendBroadcast(intent); - } - - @Override - public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException { - File file = new File(filesystemPathForURL(inputURL)); - - if (!file.exists()) { - throw new FileNotFoundException("File at " + inputURL.uri + " does not exist."); - } - - RandomAccessFile raf = new RandomAccessFile(filesystemPathForURL(inputURL), "rw"); - try { - if (raf.length() >= size) { - FileChannel channel = raf.getChannel(); - channel.truncate(size); - return size; - } - - return raf.length(); - } finally { - raf.close(); - } - - - } - - @Override - public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) { - String path = filesystemPathForURL(inputURL); - File file = new File(path); - return file.exists(); - } - - // This is a copy & paste from CordovaResource API that is required since CordovaResourceApi - // has a bug pre-4.0.0. - // TODO: Once cordova-android@4.0.0 is released, delete this copy and make the plugin depend on - // 4.0.0 with an engine tag. - private static void copyResource(CordovaResourceApi.OpenForReadResult input, OutputStream outputStream) throws IOException { - try { - InputStream inputStream = input.inputStream; - if (inputStream instanceof FileInputStream && outputStream instanceof FileOutputStream) { - FileChannel inChannel = ((FileInputStream)input.inputStream).getChannel(); - FileChannel outChannel = ((FileOutputStream)outputStream).getChannel(); - long offset = 0; - long length = input.length; - if (input.assetFd != null) { - offset = input.assetFd.getStartOffset(); - } - // transferFrom()'s 2nd arg is a relative position. Need to set the absolute - // position first. - inChannel.position(offset); - outChannel.transferFrom(inChannel, 0, length); - } else { - final int BUFFER_SIZE = 8192; - byte[] buffer = new byte[BUFFER_SIZE]; - - for (;;) { - int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE); - - if (bytesRead <= 0) { - break; - } - outputStream.write(buffer, 0, bytesRead); - } - } - } finally { - input.inputStream.close(); - if (outputStream != null) { - outputStream.close(); - } - } - } -} diff --git a/plugins/cordova-plugin-file/src/android/LocalFilesystemURL.java b/plugins/cordova-plugin-file/src/android/LocalFilesystemURL.java deleted file mode 100644 index 74f43db6..00000000 --- a/plugins/cordova-plugin-file/src/android/LocalFilesystemURL.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file; - -import android.net.Uri; - -public class LocalFilesystemURL { - - public static final String FILESYSTEM_PROTOCOL = "cdvfile"; - - public final Uri uri; - public final String fsName; - public final String path; - public final boolean isDirectory; - - private LocalFilesystemURL(Uri uri, String fsName, String fsPath, boolean isDirectory) { - this.uri = uri; - this.fsName = fsName; - this.path = fsPath; - this.isDirectory = isDirectory; - } - - public static LocalFilesystemURL parse(Uri uri) { - if (!FILESYSTEM_PROTOCOL.equals(uri.getScheme())) { - return null; - } - String path = uri.getPath(); - if (path.length() < 1) { - return null; - } - int firstSlashIdx = path.indexOf('/', 1); - if (firstSlashIdx < 0) { - return null; - } - String fsName = path.substring(1, firstSlashIdx); - path = path.substring(firstSlashIdx); - boolean isDirectory = path.charAt(path.length() - 1) == '/'; - return new LocalFilesystemURL(uri, fsName, path, isDirectory); - } - - public static LocalFilesystemURL parse(String uri) { - return parse(Uri.parse(uri)); - } - - public String toString() { - return uri.toString(); - } -} diff --git a/plugins/cordova-plugin-file/src/android/NoModificationAllowedException.java b/plugins/cordova-plugin-file/src/android/NoModificationAllowedException.java deleted file mode 100644 index 627eafb5..00000000 --- a/plugins/cordova-plugin-file/src/android/NoModificationAllowedException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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. -*/ - -package org.apache.cordova.file; - -@SuppressWarnings("serial") -public class NoModificationAllowedException extends Exception { - - public NoModificationAllowedException(String message) { - super(message); - } - -} diff --git a/plugins/cordova-plugin-file/src/android/TypeMismatchException.java b/plugins/cordova-plugin-file/src/android/TypeMismatchException.java deleted file mode 100644 index 1315f9a9..00000000 --- a/plugins/cordova-plugin-file/src/android/TypeMismatchException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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. -*/ - - -package org.apache.cordova.file; - -@SuppressWarnings("serial") -public class TypeMismatchException extends Exception { - - public TypeMismatchException(String message) { - super(message); - } - -} diff --git a/plugins/cordova-plugin-file/src/android/build-extras.gradle b/plugins/cordova-plugin-file/src/android/build-extras.gradle deleted file mode 100644 index a0a7844a..00000000 --- a/plugins/cordova-plugin-file/src/android/build-extras.gradle +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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. - */ -ext.postBuildExtras = { - def inAssetsDir = file("assets") - def outAssetsDir = inAssetsDir - def outFile = new File(outAssetsDir, "cdvasset.manifest") - - def newTask = task("cdvCreateAssetManifest") << { - def contents = new HashMap() - def sizes = new HashMap() - contents[""] = inAssetsDir.list() - def tree = fileTree(dir: inAssetsDir) - tree.visit { fileDetails -> - if (fileDetails.isDirectory()) { - contents[fileDetails.relativePath.toString()] = fileDetails.file.list() - } else { - sizes[fileDetails.relativePath.toString()] = fileDetails.file.length() - } - } - - outAssetsDir.mkdirs() - outFile.withObjectOutputStream { oos -> - oos.writeObject(contents) - oos.writeObject(sizes) - } - } - newTask.inputs.dir inAssetsDir - newTask.outputs.file outFile - def preBuildTask = tasks["preBuild"] - preBuildTask.dependsOn(newTask) -} diff --git a/plugins/cordova-plugin-file/src/blackberry10/index.js b/plugins/cordova-plugin-file/src/blackberry10/index.js deleted file mode 100644 index 913ab30a..00000000 --- a/plugins/cordova-plugin-file/src/blackberry10/index.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * 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. - * -*/ -module.exports = { - setSandbox : function (success, fail, args, env) { - require("lib/webview").setSandbox(JSON.parse(decodeURIComponent(args[0]))); - new PluginResult(args, env).ok(); - }, - - getHomePath: function (success, fail, args, env) { - var homeDir = window.qnx.webplatform.getApplication().getEnv("HOME"); - new PluginResult(args, env).ok(homeDir); - }, - - requestAllPaths: function (success, fail, args, env) { - var homeDir = 'file://' + window.qnx.webplatform.getApplication().getEnv("HOME").replace('/data', ''), - paths = { - applicationDirectory: homeDir + '/app/native/', - applicationStorageDirectory: homeDir + '/', - dataDirectory: homeDir + '/data/webviews/webfs/persistent/local__0/', - cacheDirectory: homeDir + '/data/webviews/webfs/temporary/local__0/', - externalRootDirectory: 'file:///accounts/1000/removable/sdcard/', - sharedDirectory: homeDir + '/shared/' - }; - success(paths); - } -}; diff --git a/plugins/cordova-plugin-file/src/browser/FileProxy.js b/plugins/cordova-plugin-file/src/browser/FileProxy.js deleted file mode 100644 index c853db8d..00000000 --- a/plugins/cordova-plugin-file/src/browser/FileProxy.js +++ /dev/null @@ -1,964 +0,0 @@ -/* - * - * 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. - * - */ - -/*global require, exports, module*/ -/*global FILESYSTEM_PREFIX*/ -/*global IDBKeyRange*/ - -/* Heavily based on https://github.com/ebidel/idb.filesystem.js */ - -// window.webkitRequestFileSystem and window.webkitResolveLocalFileSystemURL -// are available only in Chrome and possible a good flag to indicate -// that we're running in Chrome -var isChrome = window.webkitRequestFileSystem && window.webkitResolveLocalFileSystemURL; - -// For chrome we don't need to implement proxy methods -// All functionality can be accessed natively. -if (isChrome) { - var pathsPrefix = { - // Read-only directory where the application is installed. - applicationDirectory: location.origin + "/", - // Where to put app-specific data files. - dataDirectory: 'filesystem:file:///persistent/', - // Cached files that should survive app restarts. - // Apps should not rely on the OS to delete files in here. - cacheDirectory: 'filesystem:file:///temporary/', - }; - - exports.requestAllPaths = function(successCallback) { - successCallback(pathsPrefix); - }; - - require("cordova/exec/proxy").add("File", module.exports); - return; -} - -var LocalFileSystem = require('./LocalFileSystem'), - FileSystem = require('./FileSystem'), - FileEntry = require('./FileEntry'), - FileError = require('./FileError'), - DirectoryEntry = require('./DirectoryEntry'), - File = require('./File'); - -(function(exports, global) { - var indexedDB = global.indexedDB || global.mozIndexedDB; - if (!indexedDB) { - throw "Firefox OS File plugin: indexedDB not supported"; - } - - var fs_ = null; - - var idb_ = {}; - idb_.db = null; - var FILE_STORE_ = 'entries'; - - var DIR_SEPARATOR = '/'; - - var pathsPrefix = { - // Read-only directory where the application is installed. - applicationDirectory: location.origin + "/", - // Where to put app-specific data files. - dataDirectory: 'file:///persistent/', - // Cached files that should survive app restarts. - // Apps should not rely on the OS to delete files in here. - cacheDirectory: 'file:///temporary/', - }; - - var unicodeLastChar = 65535; - -/*** Exported functionality ***/ - - exports.requestFileSystem = function(successCallback, errorCallback, args) { - var type = args[0]; - // Size is ignored since IDB filesystem size depends - // on browser implementation and can't be set up by user - var size = args[1]; // jshint ignore: line - - if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent'; - var storageName = (location.protocol + location.host).replace(/:/g, '_'); - - var root = new DirectoryEntry('', DIR_SEPARATOR); - fs_ = new FileSystem(name, root); - - idb_.open(storageName, function() { - successCallback(fs_); - }, errorCallback); - }; - - // Overridden by Android, BlackBerry 10 and iOS to populate fsMap - require('./fileSystems').getFs = function(name, callback) { - callback(new FileSystem(name, fs_.root)); - }; - - // list a directory's contents (files and folders). - exports.readEntries = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - - if (typeof successCallback !== 'function') { - throw Error('Expected successCallback argument.'); - } - - var path = resolveToFullPath_(fullPath); - - exports.getDirectory(function() { - idb_.getAllEntries(path.fullPath + DIR_SEPARATOR, path.storagePath, function(entries) { - successCallback(entries); - }, errorCallback); - }, function() { - if (errorCallback) { - errorCallback(FileError.NOT_FOUND_ERR); - } - }, [path.storagePath, path.fullPath, {create: false}]); - }; - - exports.getFile = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - var path = args[1]; - var options = args[2] || {}; - - // Create an absolute path if we were handed a relative one. - path = resolveToFullPath_(fullPath, path); - - idb_.get(path.storagePath, function(fileEntry) { - if (options.create === true && options.exclusive === true && fileEntry) { - // If create and exclusive are both true, and the path already exists, - // getFile must fail. - - if (errorCallback) { - errorCallback(FileError.PATH_EXISTS_ERR); - } - } else if (options.create === true && !fileEntry) { - // If create is true, the path doesn't exist, and no other error occurs, - // getFile must create it as a zero-length file and return a corresponding - // FileEntry. - var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root)); - - newFileEntry.file_ = new MyFile({ - size: 0, - name: newFileEntry.name, - lastModifiedDate: new Date(), - storagePath: path.storagePath - }); - - idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback); - } else if (options.create === true && fileEntry) { - if (fileEntry.isFile) { - // Overwrite file, delete then create new. - idb_['delete'](path.storagePath, function() { - var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root)); - - newFileEntry.file_ = new MyFile({ - size: 0, - name: newFileEntry.name, - lastModifiedDate: new Date(), - storagePath: path.storagePath - }); - - idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback); - }, errorCallback); - } else { - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } - } else if ((!options.create || options.create === false) && !fileEntry) { - // If create is not true and the path doesn't exist, getFile must fail. - if (errorCallback) { - errorCallback(FileError.NOT_FOUND_ERR); - } - } else if ((!options.create || options.create === false) && fileEntry && - fileEntry.isDirectory) { - // If create is not true and the path exists, but is a directory, getFile - // must fail. - if (errorCallback) { - errorCallback(FileError.TYPE_MISMATCH_ERR); - } - } else { - // Otherwise, if no other error occurs, getFile must return a FileEntry - // corresponding to path. - - successCallback(fileEntryFromIdbEntry(fileEntry)); - } - }, errorCallback); - }; - - exports.getFileMetadata = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - - exports.getFile(function(fileEntry) { - successCallback(new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate, - fileEntry.file_.size)); - }, errorCallback, [fullPath, null]); - }; - - exports.getMetadata = function(successCallback, errorCallback, args) { - exports.getFile(function (fileEntry) { - successCallback( - { - modificationTime: fileEntry.file_.lastModifiedDate, - size: fileEntry.file_.lastModifiedDate - }); - }, errorCallback, args); - }; - - exports.setMetadata = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - var metadataObject = args[1]; - - exports.getFile(function (fileEntry) { - fileEntry.file_.lastModifiedDate = metadataObject.modificationTime; - idb_.put(fileEntry, fileEntry.file_.storagePath, successCallback, errorCallback); - }, errorCallback, [fullPath, null]); - }; - - exports.write = function(successCallback, errorCallback, args) { - var fileName = args[0], - data = args[1], - position = args[2], - isBinary = args[3]; // jshint ignore: line - - if (!data) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - if (typeof data === 'string' || data instanceof String) { - data = new Blob([data]); - } - - exports.getFile(function(fileEntry) { - var blob_ = fileEntry.file_.blob_; - - if (!blob_) { - blob_ = new Blob([data], {type: data.type}); - } else { - // Calc the head and tail fragments - var head = blob_.slice(0, position); - var tail = blob_.slice(position + (data.size || data.byteLength)); - - // Calc the padding - var padding = position - head.size; - if (padding < 0) { - padding = 0; - } - - // Do the "write". In fact, a full overwrite of the Blob. - blob_ = new Blob([head, new Uint8Array(padding), data, tail], - {type: data.type}); - } - - // Set the blob we're writing on this file entry so we can recall it later. - fileEntry.file_.blob_ = blob_; - fileEntry.file_.lastModifiedDate = new Date() || null; - fileEntry.file_.size = blob_.size; - fileEntry.file_.name = blob_.name; - fileEntry.file_.type = blob_.type; - - idb_.put(fileEntry, fileEntry.file_.storagePath, function() { - successCallback(data.size || data.byteLength); - }, errorCallback); - }, errorCallback, [fileName, null]); - }; - - exports.readAsText = function(successCallback, errorCallback, args) { - var fileName = args[0], - enc = args[1], - startPos = args[2], - endPos = args[3]; - - readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback); - }; - - exports.readAsDataURL = function(successCallback, errorCallback, args) { - var fileName = args[0], - startPos = args[1], - endPos = args[2]; - - readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback); - }; - - exports.readAsBinaryString = function(successCallback, errorCallback, args) { - var fileName = args[0], - startPos = args[1], - endPos = args[2]; - - readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback); - }; - - exports.readAsArrayBuffer = function(successCallback, errorCallback, args) { - var fileName = args[0], - startPos = args[1], - endPos = args[2]; - - readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback); - }; - - exports.removeRecursively = exports.remove = function(successCallback, errorCallback, args) { - if (typeof successCallback !== 'function') { - throw Error('Expected successCallback argument.'); - } - - var fullPath = resolveToFullPath_(args[0]).storagePath; - if (fullPath === pathsPrefix.cacheDirectory || fullPath === pathsPrefix.dataDirectory) { - errorCallback(FileError.NO_MODIFICATION_ALLOWED_ERR); - return; - } - - function deleteEntry(isDirectory) { - // TODO: This doesn't protect against directories that have content in it. - // Should throw an error instead if the dirEntry is not empty. - idb_['delete'](fullPath, function() { - successCallback(); - }, function() { - if (errorCallback) { errorCallback(); } - }, isDirectory); - } - - // We need to to understand what we are deleting: - exports.getDirectory(function(entry) { - deleteEntry(entry.isDirectory); - }, function(){ - //DirectoryEntry was already deleted or entry is FileEntry - deleteEntry(false); - }, [fullPath, null, {create: false}]); - }; - - exports.getDirectory = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - var path = args[1]; - var options = args[2]; - - // Create an absolute path if we were handed a relative one. - path = resolveToFullPath_(fullPath, path); - - idb_.get(path.storagePath, function(folderEntry) { - if (!options) { - options = {}; - } - - if (options.create === true && options.exclusive === true && folderEntry) { - // If create and exclusive are both true, and the path already exists, - // getDirectory must fail. - if (errorCallback) { - errorCallback(FileError.PATH_EXISTS_ERR); - } - // There is a strange bug in mobilespec + FF, which results in coming to multiple else-if's - // so we are shielding from it with returns. - return; - } - - if (options.create === true && !folderEntry) { - // If create is true, the path doesn't exist, and no other error occurs, - // getDirectory must create it as a zero-length file and return a corresponding - // MyDirectoryEntry. - var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root)); - - idb_.put(dirEntry, path.storagePath, successCallback, errorCallback); - return; - } - - if (options.create === true && folderEntry) { - - if (folderEntry.isDirectory) { - // IDB won't save methods, so we need re-create the MyDirectoryEntry. - successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem)); - } else { - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } - return; - } - - if ((!options.create || options.create === false) && !folderEntry) { - // Handle root special. It should always exist. - if (path.fullPath === DIR_SEPARATOR) { - successCallback(fs_.root); - return; - } - - // If create is not true and the path doesn't exist, getDirectory must fail. - if (errorCallback) { - errorCallback(FileError.NOT_FOUND_ERR); - } - - return; - } - if ((!options.create || options.create === false) && folderEntry && folderEntry.isFile) { - // If create is not true and the path exists, but is a file, getDirectory - // must fail. - if (errorCallback) { - errorCallback(FileError.TYPE_MISMATCH_ERR); - } - return; - } - - // Otherwise, if no other error occurs, getDirectory must return a - // MyDirectoryEntry corresponding to path. - - // IDB won't' save methods, so we need re-create MyDirectoryEntry. - successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.filesystem)); - }, errorCallback); - }; - - exports.getParent = function(successCallback, errorCallback, args) { - if (typeof successCallback !== 'function') { - throw Error('Expected successCallback argument.'); - } - - var fullPath = args[0]; - //fullPath is like this: - //file:///persistent/path/to/file or - //file:///persistent/path/to/directory/ - - if (fullPath === DIR_SEPARATOR || fullPath === pathsPrefix.cacheDirectory || - fullPath === pathsPrefix.dataDirectory) { - successCallback(fs_.root); - return; - } - - //To delete all slashes at the end - while (fullPath[fullPath.length - 1] === '/') { - fullPath = fullPath.substr(0, fullPath.length - 1); - } - - var pathArr = fullPath.split(DIR_SEPARATOR); - pathArr.pop(); - var parentName = pathArr.pop(); - var path = pathArr.join(DIR_SEPARATOR) + DIR_SEPARATOR; - - //To get parent of root files - var joined = path + parentName + DIR_SEPARATOR;//is like this: file:///persistent/ - if (joined === pathsPrefix.cacheDirectory || joined === pathsPrefix.dataDirectory) { - exports.getDirectory(successCallback, errorCallback, [joined, DIR_SEPARATOR, {create: false}]); - return; - } - - exports.getDirectory(successCallback, errorCallback, [path, parentName, {create: false}]); - }; - - exports.copyTo = function(successCallback, errorCallback, args) { - var srcPath = args[0]; - var parentFullPath = args[1]; - var name = args[2]; - - if (name.indexOf('/') !== -1 || srcPath === parentFullPath + name) { - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - - return; - } - - // Read src file - exports.getFile(function(srcFileEntry) { - - var path = resolveToFullPath_(parentFullPath); - //Check directory - exports.getDirectory(function() { - - // Create dest file - exports.getFile(function(dstFileEntry) { - - exports.write(function() { - successCallback(dstFileEntry); - }, errorCallback, [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]); - - }, errorCallback, [parentFullPath, name, {create: true}]); - - }, function() { if (errorCallback) { errorCallback(FileError.NOT_FOUND_ERR); }}, - [path.storagePath, null, {create:false}]); - - }, errorCallback, [srcPath, null]); - }; - - exports.moveTo = function(successCallback, errorCallback, args) { - var srcPath = args[0]; - // parentFullPath and name parameters is ignored because - // args is being passed downstream to exports.copyTo method - var parentFullPath = args[1]; // jshint ignore: line - var name = args[2]; // jshint ignore: line - - exports.copyTo(function (fileEntry) { - - exports.remove(function () { - successCallback(fileEntry); - }, errorCallback, [srcPath]); - - }, errorCallback, args); - }; - - exports.resolveLocalFileSystemURI = function(successCallback, errorCallback, args) { - var path = args[0]; - - // Ignore parameters - if (path.indexOf('?') !== -1) { - path = String(path).split("?")[0]; - } - - // support for encodeURI - if (/\%5/g.test(path) || /\%20/g.test(path)) { - path = decodeURI(path); - } - - if (path.trim()[0] === '/') { - errorCallback && errorCallback(FileError.ENCODING_ERR); - return; - } - - //support for cdvfile - if (path.trim().substr(0,7) === "cdvfile") { - if (path.indexOf("cdvfile://localhost") === -1) { - errorCallback && errorCallback(FileError.ENCODING_ERR); - return; - } - - var indexPersistent = path.indexOf("persistent"); - var indexTemporary = path.indexOf("temporary"); - - //cdvfile://localhost/persistent/path/to/file - if (indexPersistent !== -1) { - path = "file:///persistent" + path.substr(indexPersistent + 10); - } else if (indexTemporary !== -1) { - path = "file:///temporary" + path.substr(indexTemporary + 9); - } else { - errorCallback && errorCallback(FileError.ENCODING_ERR); - return; - } - } - - // to avoid path form of '///path/to/file' - function handlePathSlashes(path) { - var cutIndex = 0; - for (var i = 0; i < path.length - 1; i++) { - if (path[i] === DIR_SEPARATOR && path[i + 1] === DIR_SEPARATOR) { - cutIndex = i + 1; - } else break; - } - - return path.substr(cutIndex); - } - - // Handle localhost containing paths (see specs ) - if (path.indexOf('file://localhost/') === 0) { - path = path.replace('file://localhost/', 'file:///'); - } - - if (path.indexOf(pathsPrefix.dataDirectory) === 0) { - path = path.substring(pathsPrefix.dataDirectory.length - 1); - path = handlePathSlashes(path); - - exports.requestFileSystem(function() { - exports.getFile(successCallback, function() { - exports.getDirectory(successCallback, errorCallback, [pathsPrefix.dataDirectory, path, - {create: false}]); - }, [pathsPrefix.dataDirectory, path, {create: false}]); - }, errorCallback, [LocalFileSystem.PERSISTENT]); - } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) { - path = path.substring(pathsPrefix.cacheDirectory.length - 1); - path = handlePathSlashes(path); - - exports.requestFileSystem(function() { - exports.getFile(successCallback, function() { - exports.getDirectory(successCallback, errorCallback, [pathsPrefix.cacheDirectory, path, - {create: false}]); - }, [pathsPrefix.cacheDirectory, path, {create: false}]); - }, errorCallback, [LocalFileSystem.TEMPORARY]); - } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) { - path = path.substring(pathsPrefix.applicationDirectory.length); - //TODO: need to cut out redundant slashes? - - var xhr = new XMLHttpRequest(); - xhr.open("GET", path, true); - xhr.onreadystatechange = function () { - if (xhr.status === 200 && xhr.readyState === 4) { - exports.requestFileSystem(function(fs) { - fs.name = location.hostname; - - //TODO: need to call exports.getFile(...) to handle errors correct - fs.root.getFile(path, {create: true}, writeFile, errorCallback); - }, errorCallback, [LocalFileSystem.PERSISTENT]); - } - }; - - xhr.onerror = function () { - errorCallback && errorCallback(FileError.NOT_READABLE_ERR); - }; - - xhr.send(); - } else { - errorCallback && errorCallback(FileError.NOT_FOUND_ERR); - } - - function writeFile(entry) { - entry.createWriter(function (fileWriter) { - fileWriter.onwriteend = function (evt) { - if (!evt.target.error) { - entry.filesystemName = location.hostname; - successCallback(entry); - } - }; - fileWriter.onerror = function () { - errorCallback && errorCallback(FileError.NOT_READABLE_ERR); - }; - fileWriter.write(new Blob([xhr.response])); - }, errorCallback); - } - }; - - exports.requestAllPaths = function(successCallback) { - successCallback(pathsPrefix); - }; - -/*** Helpers ***/ - - /** - * Interface to wrap the native File interface. - * - * This interface is necessary for creating zero-length (empty) files, - * something the Filesystem API allows you to do. Unfortunately, File's - * constructor cannot be called directly, making it impossible to instantiate - * an empty File in JS. - * - * @param {Object} opts Initial values. - * @constructor - */ - function MyFile(opts) { - var blob_ = new Blob(); - - this.size = opts.size || 0; - this.name = opts.name || ''; - this.type = opts.type || ''; - this.lastModifiedDate = opts.lastModifiedDate || null; - this.storagePath = opts.storagePath || ''; - - // Need some black magic to correct the object's size/name/type based on the - // blob that is saved. - Object.defineProperty(this, 'blob_', { - enumerable: true, - get: function() { - return blob_; - }, - set: function(val) { - blob_ = val; - this.size = blob_.size; - this.name = blob_.name; - this.type = blob_.type; - this.lastModifiedDate = blob_.lastModifiedDate; - }.bind(this) - }); - } - - MyFile.prototype.constructor = MyFile; - - // When saving an entry, the fullPath should always lead with a slash and never - // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute - // one. This method ensures path is legit! - function resolveToFullPath_(cwdFullPath, path) { - path = path || ''; - var fullPath = path; - var prefix = ''; - - cwdFullPath = cwdFullPath || DIR_SEPARATOR; - if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) { - prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length)); - cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length)); - } - - var relativePath = path[0] !== DIR_SEPARATOR; - if (relativePath) { - fullPath = cwdFullPath; - if (cwdFullPath !== DIR_SEPARATOR) { - fullPath += DIR_SEPARATOR + path; - } else { - fullPath += path; - } - } - - // Remove doubled separator substrings - var re = new RegExp(DIR_SEPARATOR + DIR_SEPARATOR, 'g'); - fullPath = fullPath.replace(re, DIR_SEPARATOR); - - // Adjust '..'s by removing parent directories when '..' flows in path. - var parts = fullPath.split(DIR_SEPARATOR); - for (var i = 0; i < parts.length; ++i) { - var part = parts[i]; - if (part === '..') { - parts[i - 1] = ''; - parts[i] = ''; - } - } - fullPath = parts.filter(function(el) { - return el; - }).join(DIR_SEPARATOR); - - // Add back in leading slash. - if (fullPath[0] !== DIR_SEPARATOR) { - fullPath = DIR_SEPARATOR + fullPath; - } - - // Replace './' by current dir. ('./one/./two' -> one/two) - fullPath = fullPath.replace(/\.\//g, DIR_SEPARATOR); - - // Replace '//' with '/'. - fullPath = fullPath.replace(/\/\//g, DIR_SEPARATOR); - - // Replace '/.' with '/'. - fullPath = fullPath.replace(/\/\./g, DIR_SEPARATOR); - - // Remove '/' if it appears on the end. - if (fullPath[fullPath.length - 1] === DIR_SEPARATOR && - fullPath !== DIR_SEPARATOR) { - fullPath = fullPath.substring(0, fullPath.length - 1); - } - - var storagePath = prefix + fullPath; - storagePath = decodeURI(storagePath); - fullPath = decodeURI(fullPath); - - return { - storagePath: storagePath, - fullPath: fullPath, - fileName: fullPath.split(DIR_SEPARATOR).pop(), - fsName: prefix.split(DIR_SEPARATOR).pop() - }; - } - - function fileEntryFromIdbEntry(fileEntry) { - // IDB won't save methods, so we need re-create the FileEntry. - var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.filesystem); - clonedFileEntry.file_ = fileEntry.file_; - - return clonedFileEntry; - } - - function readAs(what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) { - exports.getFile(function(fileEntry) { - var fileReader = new FileReader(), - blob = fileEntry.file_.blob_.slice(startPos, endPos); - - fileReader.onload = function(e) { - successCallback(e.target.result); - }; - - fileReader.onerror = errorCallback; - - switch (what) { - case 'text': - fileReader.readAsText(blob, encoding); - break; - case 'dataURL': - fileReader.readAsDataURL(blob); - break; - case 'arrayBuffer': - fileReader.readAsArrayBuffer(blob); - break; - case 'binaryString': - fileReader.readAsBinaryString(blob); - break; - } - - }, errorCallback, [fullPath, null]); - } - -/*** Core logic to handle IDB operations ***/ - - idb_.open = function(dbName, successCallback, errorCallback) { - var self = this; - - // TODO: FF 12.0a1 isn't liking a db name with : in it. - var request = indexedDB.open(dbName.replace(':', '_')/*, 1 /*version*/); - - request.onerror = errorCallback || onError; - - request.onupgradeneeded = function(e) { - // First open was called or higher db version was used. - - // console.log('onupgradeneeded: oldVersion:' + e.oldVersion, - // 'newVersion:' + e.newVersion); - - self.db = e.target.result; - self.db.onerror = onError; - - if (!self.db.objectStoreNames.contains(FILE_STORE_)) { - self.db.createObjectStore(FILE_STORE_/*,{keyPath: 'id', autoIncrement: true}*/); - } - }; - - request.onsuccess = function(e) { - self.db = e.target.result; - self.db.onerror = onError; - successCallback(e); - }; - - request.onblocked = errorCallback || onError; - }; - - idb_.close = function() { - this.db.close(); - this.db = null; - }; - - idb_.get = function(fullPath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var tx = this.db.transaction([FILE_STORE_], 'readonly'); - - var request = tx.objectStore(FILE_STORE_).get(fullPath); - - tx.onabort = errorCallback || onError; - tx.oncomplete = function() { - successCallback(request.result); - }; - }; - - idb_.getAllEntries = function(fullPath, storagePath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var results = []; - - if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) { - storagePath = storagePath.substring(0, storagePath.length - 1); - } - - var range = IDBKeyRange.bound(storagePath + DIR_SEPARATOR + ' ', - storagePath + DIR_SEPARATOR + String.fromCharCode(unicodeLastChar)); - - var tx = this.db.transaction([FILE_STORE_], 'readonly'); - tx.onabort = errorCallback || onError; - tx.oncomplete = function() { - results = results.filter(function(val) { - var pathWithoutSlash = val.fullPath; - - if (val.fullPath[val.fullPath.length - 1] === DIR_SEPARATOR) { - pathWithoutSlash = pathWithoutSlash.substr(0, pathWithoutSlash.length - 1); - } - - var valPartsLen = pathWithoutSlash.split(DIR_SEPARATOR).length; - var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length; - - /* Input fullPath parameter equals '//' for root folder */ - /* Entries in root folder has valPartsLen equals 2 (see below) */ - if (fullPath[fullPath.length -1] === DIR_SEPARATOR && fullPath.trim().length === 2) { - fullPathPartsLen = 1; - } else if (fullPath[fullPath.length -1] === DIR_SEPARATOR) { - fullPathPartsLen = fullPath.substr(0, fullPath.length - 1).split(DIR_SEPARATOR).length; - } else { - fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length; - } - - if (valPartsLen === fullPathPartsLen + 1) { - // If this a subfolder and entry is a direct child, include it in - // the results. Otherwise, it's not an entry of this folder. - return val; - } else return false; - }); - - successCallback(results); - }; - - var request = tx.objectStore(FILE_STORE_).openCursor(range); - - request.onsuccess = function(e) { - var cursor = e.target.result; - if (cursor) { - var val = cursor.value; - - results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.filesystem)); - cursor['continue'](); - } - }; - }; - - idb_['delete'] = function(fullPath, successCallback, errorCallback, isDirectory) { - if (!idb_.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var tx = this.db.transaction([FILE_STORE_], 'readwrite'); - tx.oncomplete = successCallback; - tx.onabort = errorCallback || onError; - tx.oncomplete = function() { - if (isDirectory) { - //We delete nested files and folders after deleting parent folder - //We use ranges: https://developer.mozilla.org/en-US/docs/Web/API/IDBKeyRange - fullPath = fullPath + DIR_SEPARATOR; - - //Range contains all entries in the form fullPath<symbol> where - //symbol in the range from ' ' to symbol which has code `unicodeLastChar` - var range = IDBKeyRange.bound(fullPath + ' ', fullPath + String.fromCharCode(unicodeLastChar)); - - var newTx = this.db.transaction([FILE_STORE_], 'readwrite'); - newTx.oncomplete = successCallback; - newTx.onabort = errorCallback || onError; - newTx.objectStore(FILE_STORE_)['delete'](range); - } else { - successCallback(); - } - }; - tx.objectStore(FILE_STORE_)['delete'](fullPath); - }; - - idb_.put = function(entry, storagePath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var tx = this.db.transaction([FILE_STORE_], 'readwrite'); - tx.onabort = errorCallback || onError; - tx.oncomplete = function() { - // TODO: Error is thrown if we pass the request event back instead. - successCallback(entry); - }; - - tx.objectStore(FILE_STORE_).put(entry, storagePath); - }; - - // Global error handler. Errors bubble from request, to transaction, to db. - function onError(e) { - switch (e.target.errorCode) { - case 12: - console.log('Error - Attempt to open db with a lower version than the ' + - 'current one.'); - break; - default: - console.log('errorCode: ' + e.target.errorCode); - } - - console.log(e, e.code, e.message); - } - -})(module.exports, window); - -require("cordova/exec/proxy").add("File", module.exports); diff --git a/plugins/cordova-plugin-file/src/firefoxos/FileProxy.js b/plugins/cordova-plugin-file/src/firefoxos/FileProxy.js deleted file mode 100644 index 340ae4bc..00000000 --- a/plugins/cordova-plugin-file/src/firefoxos/FileProxy.js +++ /dev/null @@ -1,785 +0,0 @@ -/* - * - * 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 LocalFileSystem = require('./LocalFileSystem'), - FileSystem = require('./FileSystem'), - FileEntry = require('./FileEntry'), - FileError = require('./FileError'), - DirectoryEntry = require('./DirectoryEntry'), - File = require('./File'); - -/* -QUIRKS: - Does not fail when removing non-empty directories - Does not support metadata for directories - Does not support requestAllFileSystems - Does not support resolveLocalFileSystemURI - Methods copyTo and moveTo do not support directories - - Heavily based on https://github.com/ebidel/idb.filesystem.js - */ - - -(function(exports, global) { - var indexedDB = global.indexedDB || global.mozIndexedDB; - if (!indexedDB) { - throw "Firefox OS File plugin: indexedDB not supported"; - } - - var fs_ = null; - - var idb_ = {}; - idb_.db = null; - var FILE_STORE_ = 'entries'; - - var DIR_SEPARATOR = '/'; - var DIR_OPEN_BOUND = String.fromCharCode(DIR_SEPARATOR.charCodeAt(0) + 1); - - var pathsPrefix = { - // Read-only directory where the application is installed. - applicationDirectory: location.origin + "/", - // Where to put app-specific data files. - dataDirectory: 'file:///persistent/', - // Cached files that should survive app restarts. - // Apps should not rely on the OS to delete files in here. - cacheDirectory: 'file:///temporary/', - }; - -/*** Exported functionality ***/ - - exports.requestFileSystem = function(successCallback, errorCallback, args) { - var type = args[0]; - var size = args[1]; - - if (type !== LocalFileSystem.TEMPORARY && type !== LocalFileSystem.PERSISTENT) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var name = type === LocalFileSystem.TEMPORARY ? 'temporary' : 'persistent'; - var storageName = (location.protocol + location.host).replace(/:/g, '_'); - - var root = new DirectoryEntry('', DIR_SEPARATOR); - fs_ = new FileSystem(name, root); - - idb_.open(storageName, function() { - successCallback(fs_); - }, errorCallback); - }; - - require('./fileSystems').getFs = function(name, callback) { - callback(new FileSystem(name, fs_.root)); - }; - - // list a directory's contents (files and folders). - exports.readEntries = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - - if (!successCallback) { - throw Error('Expected successCallback argument.'); - } - - var path = resolveToFullPath_(fullPath); - - idb_.getAllEntries(path.fullPath, path.storagePath, function(entries) { - successCallback(entries); - }, errorCallback); - }; - - exports.getFile = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - var path = args[1]; - var options = args[2] || {}; - - // Create an absolute path if we were handed a relative one. - path = resolveToFullPath_(fullPath, path); - - idb_.get(path.storagePath, function(fileEntry) { - if (options.create === true && options.exclusive === true && fileEntry) { - // If create and exclusive are both true, and the path already exists, - // getFile must fail. - - if (errorCallback) { - errorCallback(FileError.PATH_EXISTS_ERR); - } - } else if (options.create === true && !fileEntry) { - // If create is true, the path doesn't exist, and no other error occurs, - // getFile must create it as a zero-length file and return a corresponding - // FileEntry. - var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root)); - - newFileEntry.file_ = new MyFile({ - size: 0, - name: newFileEntry.name, - lastModifiedDate: new Date(), - storagePath: path.storagePath - }); - - idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback); - } else if (options.create === true && fileEntry) { - if (fileEntry.isFile) { - // Overwrite file, delete then create new. - idb_['delete'](path.storagePath, function() { - var newFileEntry = new FileEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root)); - - newFileEntry.file_ = new MyFile({ - size: 0, - name: newFileEntry.name, - lastModifiedDate: new Date(), - storagePath: path.storagePath - }); - - idb_.put(newFileEntry, path.storagePath, successCallback, errorCallback); - }, errorCallback); - } else { - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } - } else if ((!options.create || options.create === false) && !fileEntry) { - // If create is not true and the path doesn't exist, getFile must fail. - if (errorCallback) { - errorCallback(FileError.NOT_FOUND_ERR); - } - } else if ((!options.create || options.create === false) && fileEntry && - fileEntry.isDirectory) { - // If create is not true and the path exists, but is a directory, getFile - // must fail. - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } else { - // Otherwise, if no other error occurs, getFile must return a FileEntry - // corresponding to path. - - successCallback(fileEntryFromIdbEntry(fileEntry)); - } - }, errorCallback); - }; - - exports.getFileMetadata = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - - exports.getFile(function(fileEntry) { - successCallback(new File(fileEntry.file_.name, fileEntry.fullPath, '', fileEntry.file_.lastModifiedDate, - fileEntry.file_.size)); - }, errorCallback, [fullPath, null]); - }; - - exports.getMetadata = function(successCallback, errorCallback, args) { - exports.getFile(function (fileEntry) { - successCallback( - { - modificationTime: fileEntry.file_.lastModifiedDate, - size: fileEntry.file_.lastModifiedDate - }); - }, errorCallback, args); - }; - - exports.setMetadata = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - var metadataObject = args[1]; - - exports.getFile(function (fileEntry) { - fileEntry.file_.lastModifiedDate = metadataObject.modificationTime; - }, errorCallback, [fullPath, null]); - }; - - exports.write = function(successCallback, errorCallback, args) { - var fileName = args[0], - data = args[1], - position = args[2], - isBinary = args[3]; - - if (!data) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - exports.getFile(function(fileEntry) { - var blob_ = fileEntry.file_.blob_; - - if (!blob_) { - blob_ = new Blob([data], {type: data.type}); - } else { - // Calc the head and tail fragments - var head = blob_.slice(0, position); - var tail = blob_.slice(position + data.byteLength); - - // Calc the padding - var padding = position - head.size; - if (padding < 0) { - padding = 0; - } - - // Do the "write". In fact, a full overwrite of the Blob. - blob_ = new Blob([head, new Uint8Array(padding), data, tail], - {type: data.type}); - } - - // Set the blob we're writing on this file entry so we can recall it later. - fileEntry.file_.blob_ = blob_; - fileEntry.file_.lastModifiedDate = data.lastModifiedDate || null; - fileEntry.file_.size = blob_.size; - fileEntry.file_.name = blob_.name; - fileEntry.file_.type = blob_.type; - - idb_.put(fileEntry, fileEntry.file_.storagePath, function() { - successCallback(data.byteLength); - }, errorCallback); - }, errorCallback, [fileName, null]); - }; - - exports.readAsText = function(successCallback, errorCallback, args) { - var fileName = args[0], - enc = args[1], - startPos = args[2], - endPos = args[3]; - - readAs('text', fileName, enc, startPos, endPos, successCallback, errorCallback); - }; - - exports.readAsDataURL = function(successCallback, errorCallback, args) { - var fileName = args[0], - startPos = args[1], - endPos = args[2]; - - readAs('dataURL', fileName, null, startPos, endPos, successCallback, errorCallback); - }; - - exports.readAsBinaryString = function(successCallback, errorCallback, args) { - var fileName = args[0], - startPos = args[1], - endPos = args[2]; - - readAs('binaryString', fileName, null, startPos, endPos, successCallback, errorCallback); - }; - - exports.readAsArrayBuffer = function(successCallback, errorCallback, args) { - var fileName = args[0], - startPos = args[1], - endPos = args[2]; - - readAs('arrayBuffer', fileName, null, startPos, endPos, successCallback, errorCallback); - }; - - exports.removeRecursively = exports.remove = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - - // TODO: This doesn't protect against directories that have content in it. - // Should throw an error instead if the dirEntry is not empty. - idb_['delete'](fullPath, function() { - successCallback(); - }, errorCallback); - }; - - exports.getDirectory = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - var path = args[1]; - var options = args[2]; - - // Create an absolute path if we were handed a relative one. - path = resolveToFullPath_(fullPath, path); - - idb_.get(path.storagePath, function(folderEntry) { - if (!options) { - options = {}; - } - - if (options.create === true && options.exclusive === true && folderEntry) { - // If create and exclusive are both true, and the path already exists, - // getDirectory must fail. - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } else if (options.create === true && !folderEntry) { - // If create is true, the path doesn't exist, and no other error occurs, - // getDirectory must create it as a zero-length file and return a corresponding - // MyDirectoryEntry. - var dirEntry = new DirectoryEntry(path.fileName, path.fullPath, new FileSystem(path.fsName, fs_.root)); - - idb_.put(dirEntry, path.storagePath, successCallback, errorCallback); - } else if (options.create === true && folderEntry) { - - if (folderEntry.isDirectory) { - // IDB won't save methods, so we need re-create the MyDirectoryEntry. - successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.fileSystem)); - } else { - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } - } else if ((!options.create || options.create === false) && !folderEntry) { - // Handle root special. It should always exist. - if (path.fullPath === DIR_SEPARATOR) { - successCallback(fs_.root); - return; - } - - // If create is not true and the path doesn't exist, getDirectory must fail. - if (errorCallback) { - errorCallback(FileError.NOT_FOUND_ERR); - } - } else if ((!options.create || options.create === false) && folderEntry && - folderEntry.isFile) { - // If create is not true and the path exists, but is a file, getDirectory - // must fail. - if (errorCallback) { - errorCallback(FileError.INVALID_MODIFICATION_ERR); - } - } else { - // Otherwise, if no other error occurs, getDirectory must return a - // MyDirectoryEntry corresponding to path. - - // IDB won't' save methods, so we need re-create MyDirectoryEntry. - successCallback(new DirectoryEntry(folderEntry.name, folderEntry.fullPath, folderEntry.fileSystem)); - } - }, errorCallback); - }; - - exports.getParent = function(successCallback, errorCallback, args) { - var fullPath = args[0]; - - if (fullPath === DIR_SEPARATOR) { - successCallback(fs_.root); - return; - } - - var pathArr = fullPath.split(DIR_SEPARATOR); - pathArr.pop(); - var namesa = pathArr.pop(); - var path = pathArr.join(DIR_SEPARATOR); - - exports.getDirectory(successCallback, errorCallback, [path, namesa, {create: false}]); - }; - - exports.copyTo = function(successCallback, errorCallback, args) { - var srcPath = args[0]; - var parentFullPath = args[1]; - var name = args[2]; - - // Read src file - exports.getFile(function(srcFileEntry) { - - // Create dest file - exports.getFile(function(dstFileEntry) { - - exports.write(function() { - successCallback(dstFileEntry); - }, errorCallback, [dstFileEntry.file_.storagePath, srcFileEntry.file_.blob_, 0]); - - }, errorCallback, [parentFullPath, name, {create: true}]); - - }, errorCallback, [srcPath, null]); - }; - - exports.moveTo = function(successCallback, errorCallback, args) { - var srcPath = args[0]; - var parentFullPath = args[1]; - var name = args[2]; - - exports.copyTo(function (fileEntry) { - - exports.remove(function () { - successCallback(fileEntry); - }, errorCallback, [srcPath]); - - }, errorCallback, args); - }; - - exports.resolveLocalFileSystemURI = function(successCallback, errorCallback, args) { - var path = args[0]; - - // Ignore parameters - if (path.indexOf('?') !== -1) { - path = String(path).split("?")[0]; - } - - // support for encodeURI - if (/\%5/g.test(path)) { - path = decodeURI(path); - } - - if (path.indexOf(pathsPrefix.dataDirectory) === 0) { - path = path.substring(pathsPrefix.dataDirectory.length - 1); - - exports.requestFileSystem(function(fs) { - fs.root.getFile(path, {create: false}, successCallback, function() { - fs.root.getDirectory(path, {create: false}, successCallback, errorCallback); - }); - }, errorCallback, [LocalFileSystem.PERSISTENT]); - } else if (path.indexOf(pathsPrefix.cacheDirectory) === 0) { - path = path.substring(pathsPrefix.cacheDirectory.length - 1); - - exports.requestFileSystem(function(fs) { - fs.root.getFile(path, {create: false}, successCallback, function() { - fs.root.getDirectory(path, {create: false}, successCallback, errorCallback); - }); - }, errorCallback, [LocalFileSystem.TEMPORARY]); - } else if (path.indexOf(pathsPrefix.applicationDirectory) === 0) { - path = path.substring(pathsPrefix.applicationDirectory.length); - - var xhr = new XMLHttpRequest(); - xhr.open("GET", path, true); - xhr.onreadystatechange = function () { - if (xhr.status === 200 && xhr.readyState === 4) { - exports.requestFileSystem(function(fs) { - fs.name = location.hostname; - fs.root.getFile(path, {create: true}, writeFile, errorCallback); - }, errorCallback, [LocalFileSystem.PERSISTENT]); - } - }; - - xhr.onerror = function () { - errorCallback && errorCallback(FileError.NOT_READABLE_ERR); - }; - - xhr.send(); - } else { - errorCallback && errorCallback(FileError.NOT_FOUND_ERR); - } - - function writeFile(entry) { - entry.createWriter(function (fileWriter) { - fileWriter.onwriteend = function (evt) { - if (!evt.target.error) { - entry.filesystemName = location.hostname; - successCallback(entry); - } - }; - fileWriter.onerror = function () { - errorCallback && errorCallback(FileError.NOT_READABLE_ERR); - }; - fileWriter.write(new Blob([xhr.response])); - }, errorCallback); - } - }; - - exports.requestAllPaths = function(successCallback) { - successCallback(pathsPrefix); - }; - -/*** Helpers ***/ - - /** - * Interface to wrap the native File interface. - * - * This interface is necessary for creating zero-length (empty) files, - * something the Filesystem API allows you to do. Unfortunately, File's - * constructor cannot be called directly, making it impossible to instantiate - * an empty File in JS. - * - * @param {Object} opts Initial values. - * @constructor - */ - function MyFile(opts) { - var blob_ = new Blob(); - - this.size = opts.size || 0; - this.name = opts.name || ''; - this.type = opts.type || ''; - this.lastModifiedDate = opts.lastModifiedDate || null; - this.storagePath = opts.storagePath || ''; - - // Need some black magic to correct the object's size/name/type based on the - // blob that is saved. - Object.defineProperty(this, 'blob_', { - enumerable: true, - get: function() { - return blob_; - }, - set: function(val) { - blob_ = val; - this.size = blob_.size; - this.name = blob_.name; - this.type = blob_.type; - this.lastModifiedDate = blob_.lastModifiedDate; - }.bind(this) - }); - } - - MyFile.prototype.constructor = MyFile; - - // When saving an entry, the fullPath should always lead with a slash and never - // end with one (e.g. a directory). Also, resolve '.' and '..' to an absolute - // one. This method ensures path is legit! - function resolveToFullPath_(cwdFullPath, path) { - path = path || ''; - var fullPath = path; - var prefix = ''; - - cwdFullPath = cwdFullPath || DIR_SEPARATOR; - if (cwdFullPath.indexOf(FILESYSTEM_PREFIX) === 0) { - prefix = cwdFullPath.substring(0, cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length)); - cwdFullPath = cwdFullPath.substring(cwdFullPath.indexOf(DIR_SEPARATOR, FILESYSTEM_PREFIX.length)); - } - - var relativePath = path[0] !== DIR_SEPARATOR; - if (relativePath) { - fullPath = cwdFullPath; - if (cwdFullPath != DIR_SEPARATOR) { - fullPath += DIR_SEPARATOR + path; - } else { - fullPath += path; - } - } - - // Adjust '..'s by removing parent directories when '..' flows in path. - var parts = fullPath.split(DIR_SEPARATOR); - for (var i = 0; i < parts.length; ++i) { - var part = parts[i]; - if (part == '..') { - parts[i - 1] = ''; - parts[i] = ''; - } - } - fullPath = parts.filter(function(el) { - return el; - }).join(DIR_SEPARATOR); - - // Add back in leading slash. - if (fullPath[0] !== DIR_SEPARATOR) { - fullPath = DIR_SEPARATOR + fullPath; - } - - // Replace './' by current dir. ('./one/./two' -> one/two) - fullPath = fullPath.replace(/\.\//g, DIR_SEPARATOR); - - // Replace '//' with '/'. - fullPath = fullPath.replace(/\/\//g, DIR_SEPARATOR); - - // Replace '/.' with '/'. - fullPath = fullPath.replace(/\/\./g, DIR_SEPARATOR); - - // Remove '/' if it appears on the end. - if (fullPath[fullPath.length - 1] == DIR_SEPARATOR && - fullPath != DIR_SEPARATOR) { - fullPath = fullPath.substring(0, fullPath.length - 1); - } - - return { - storagePath: prefix + fullPath, - fullPath: fullPath, - fileName: fullPath.split(DIR_SEPARATOR).pop(), - fsName: prefix.split(DIR_SEPARATOR).pop() - }; - } - - function fileEntryFromIdbEntry(fileEntry) { - // IDB won't save methods, so we need re-create the FileEntry. - var clonedFileEntry = new FileEntry(fileEntry.name, fileEntry.fullPath, fileEntry.fileSystem); - clonedFileEntry.file_ = fileEntry.file_; - - return clonedFileEntry; - } - - function readAs(what, fullPath, encoding, startPos, endPos, successCallback, errorCallback) { - exports.getFile(function(fileEntry) { - var fileReader = new FileReader(), - blob = fileEntry.file_.blob_.slice(startPos, endPos); - - fileReader.onload = function(e) { - successCallback(e.target.result); - }; - - fileReader.onerror = errorCallback; - - switch (what) { - case 'text': - fileReader.readAsText(blob, encoding); - break; - case 'dataURL': - fileReader.readAsDataURL(blob); - break; - case 'arrayBuffer': - fileReader.readAsArrayBuffer(blob); - break; - case 'binaryString': - fileReader.readAsBinaryString(blob); - break; - } - - }, errorCallback, [fullPath, null]); - } - -/*** Core logic to handle IDB operations ***/ - - idb_.open = function(dbName, successCallback, errorCallback) { - var self = this; - - // TODO: FF 12.0a1 isn't liking a db name with : in it. - var request = indexedDB.open(dbName.replace(':', '_')/*, 1 /*version*/); - - request.onerror = errorCallback || onError; - - request.onupgradeneeded = function(e) { - // First open was called or higher db version was used. - - // console.log('onupgradeneeded: oldVersion:' + e.oldVersion, - // 'newVersion:' + e.newVersion); - - self.db = e.target.result; - self.db.onerror = onError; - - if (!self.db.objectStoreNames.contains(FILE_STORE_)) { - var store = self.db.createObjectStore(FILE_STORE_/*,{keyPath: 'id', autoIncrement: true}*/); - } - }; - - request.onsuccess = function(e) { - self.db = e.target.result; - self.db.onerror = onError; - successCallback(e); - }; - - request.onblocked = errorCallback || onError; - }; - - idb_.close = function() { - this.db.close(); - this.db = null; - }; - - idb_.get = function(fullPath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var tx = this.db.transaction([FILE_STORE_], 'readonly'); - - //var request = tx.objectStore(FILE_STORE_).get(fullPath); - var range = IDBKeyRange.bound(fullPath, fullPath + DIR_OPEN_BOUND, - false, true); - var request = tx.objectStore(FILE_STORE_).get(range); - - tx.onabort = errorCallback || onError; - tx.oncomplete = function(e) { - successCallback(request.result); - }; - }; - - idb_.getAllEntries = function(fullPath, storagePath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var results = []; - - if (storagePath[storagePath.length - 1] === DIR_SEPARATOR) { - storagePath = storagePath.substring(0, storagePath.length - 1); - } - - range = IDBKeyRange.bound( - storagePath + DIR_SEPARATOR, storagePath + DIR_OPEN_BOUND, false, true); - - var tx = this.db.transaction([FILE_STORE_], 'readonly'); - tx.onabort = errorCallback || onError; - tx.oncomplete = function(e) { - results = results.filter(function(val) { - var valPartsLen = val.fullPath.split(DIR_SEPARATOR).length; - var fullPathPartsLen = fullPath.split(DIR_SEPARATOR).length; - - if (fullPath === DIR_SEPARATOR && valPartsLen < fullPathPartsLen + 1) { - // Hack to filter out entries in the root folder. This is inefficient - // because reading the entires of fs.root (e.g. '/') returns ALL - // results in the database, then filters out the entries not in '/'. - return val; - } else if (fullPath !== DIR_SEPARATOR && - valPartsLen === fullPathPartsLen + 1) { - // If this a subfolder and entry is a direct child, include it in - // the results. Otherwise, it's not an entry of this folder. - return val; - } - }); - - successCallback(results); - }; - - var request = tx.objectStore(FILE_STORE_).openCursor(range); - - request.onsuccess = function(e) { - var cursor = e.target.result; - if (cursor) { - var val = cursor.value; - - results.push(val.isFile ? fileEntryFromIdbEntry(val) : new DirectoryEntry(val.name, val.fullPath, val.fileSystem)); - cursor['continue'](); - } - }; - }; - - idb_['delete'] = function(fullPath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var tx = this.db.transaction([FILE_STORE_], 'readwrite'); - tx.oncomplete = successCallback; - tx.onabort = errorCallback || onError; - - //var request = tx.objectStore(FILE_STORE_).delete(fullPath); - var range = IDBKeyRange.bound( - fullPath, fullPath + DIR_OPEN_BOUND, false, true); - tx.objectStore(FILE_STORE_)['delete'](range); - }; - - idb_.put = function(entry, storagePath, successCallback, errorCallback) { - if (!this.db) { - errorCallback && errorCallback(FileError.INVALID_MODIFICATION_ERR); - return; - } - - var tx = this.db.transaction([FILE_STORE_], 'readwrite'); - tx.onabort = errorCallback || onError; - tx.oncomplete = function(e) { - // TODO: Error is thrown if we pass the request event back instead. - successCallback(entry); - }; - - tx.objectStore(FILE_STORE_).put(entry, storagePath); - }; - - // Global error handler. Errors bubble from request, to transaction, to db. - function onError(e) { - switch (e.target.errorCode) { - case 12: - console.log('Error - Attempt to open db with a lower version than the ' + - 'current one.'); - break; - default: - console.log('errorCode: ' + e.target.errorCode); - } - - console.log(e, e.code, e.message); - } - -// Clean up. -// TODO: Is there a place for this? -// global.addEventListener('beforeunload', function(e) { -// idb_.db && idb_.db.close(); -// }, false); - -})(module.exports, window); - -require("cordova/exec/proxy").add("File", module.exports); diff --git a/plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.h b/plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.h deleted file mode 100644 index e09e2250..00000000 --- a/plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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 "CDVFile.h" - -extern NSString* const kCDVAssetsLibraryPrefix; -extern NSString* const kCDVAssetsLibraryScheme; - -@interface CDVAssetLibraryFilesystem : NSObject<CDVFileSystem> { -} - -- (id) initWithName:(NSString *)name; - -@end diff --git a/plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.m b/plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.m deleted file mode 100644 index 0b95fac3..00000000 --- a/plugins/cordova-plugin-file/src/ios/CDVAssetLibraryFilesystem.m +++ /dev/null @@ -1,253 +0,0 @@ -/* - 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 "CDVFile.h" -#import "CDVAssetLibraryFilesystem.h" -#import <Cordova/CDV.h> -#import <AssetsLibrary/ALAsset.h> -#import <AssetsLibrary/ALAssetRepresentation.h> -#import <AssetsLibrary/ALAssetsLibrary.h> -#import <MobileCoreServices/MobileCoreServices.h> - -NSString* const kCDVAssetsLibraryPrefix = @"assets-library://"; -NSString* const kCDVAssetsLibraryScheme = @"assets-library"; - -@implementation CDVAssetLibraryFilesystem -@synthesize name=_name, urlTransformer; - - -/* - The CDVAssetLibraryFilesystem works with resources which are identified - by iOS as - asset-library://<path> - and represents them internally as URLs of the form - cdvfile://localhost/assets-library/<path> - */ - -- (NSURL *)assetLibraryURLForLocalURL:(CDVFilesystemURL *)url -{ - if ([url.url.scheme isEqualToString:kCDVFilesystemURLPrefix]) { - NSString *path = [[url.url absoluteString] substringFromIndex:[@"cdvfile://localhost/assets-library" length]]; - return [NSURL URLWithString:[NSString stringWithFormat:@"assets-library:/%@", path]]; - } - return url.url; -} - -- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url -{ - NSDictionary* entry = [self makeEntryForLocalURL:url]; - return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry]; -} - -- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url { - return [self makeEntryForPath:url.fullPath isDirectory:NO]; -} - -- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir -{ - NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5]; - NSString* lastPart = [fullPath lastPathComponent]; - if (isDir && ![fullPath hasSuffix:@"/"]) { - fullPath = [fullPath stringByAppendingString:@"/"]; - } - [dirEntry setObject:[NSNumber numberWithBool:!isDir] forKey:@"isFile"]; - [dirEntry setObject:[NSNumber numberWithBool:isDir] forKey:@"isDirectory"]; - [dirEntry setObject:fullPath forKey:@"fullPath"]; - [dirEntry setObject:lastPart forKey:@"name"]; - [dirEntry setObject:self.name forKey: @"filesystemName"]; - - NSURL* nativeURL = [NSURL URLWithString:[NSString stringWithFormat:@"assets-library:/%@",fullPath]]; - if (self.urlTransformer) { - nativeURL = self.urlTransformer(nativeURL); - } - dirEntry[@"nativeURL"] = [nativeURL absoluteString]; - - return dirEntry; -} - -/* helper function to get the mimeType from the file extension - * IN: - * NSString* fullPath - filename (may include path) - * OUT: - * NSString* the mime type as type/subtype. nil if not able to determine - */ -+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath -{ - NSString* mimeType = nil; - - if (fullPath) { - CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL); - if (typeId) { - mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType); - if (!mimeType) { - // special case for m4a - if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) { - mimeType = @"audio/mp4"; - } else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) { - mimeType = @"audio/wav"; - } else if ([[fullPath pathExtension] rangeOfString:@"css"].location != NSNotFound) { - mimeType = @"text/css"; - } - } - CFRelease(typeId); - } - } - return mimeType; -} - -- (id)initWithName:(NSString *)name -{ - if (self) { - _name = name; - } - return self; -} - -- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options -{ - // return unsupported result for assets-library URLs - return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"getFile not supported for assets-library URLs."]; -} - -- (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI -{ - // we don't (yet?) support getting the parent of an asset - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_READABLE_ERR]; -} - -- (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options -{ - // setMetadata doesn't make sense for asset library files - return [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; -} - -- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI -{ - // return error for assets-library URLs - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR]; -} - -- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI -{ - // return error for assets-library URLs - return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"removeRecursively not supported for assets-library URLs."]; -} - -- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI -{ - // return unsupported result for assets-library URLs - return [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"readEntries not supported for assets-library URLs."]; -} - -- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos -{ - // assets-library files can't be truncated - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR]; -} - -- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend -{ - // text can't be written into assets-library files - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR]; -} - -- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback -{ - // Copying to an assets library file is not doable, since we can't write it. - CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR]; - callback(result); -} - -- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url -{ - NSString *path = nil; - if ([[url.url scheme] isEqualToString:kCDVAssetsLibraryScheme]) { - path = [url.url path]; - } else { - path = url.fullPath; - } - if ([path hasSuffix:@"/"]) { - path = [path substringToIndex:([path length]-1)]; - } - return path; -} - -- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback -{ - ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) { - if (asset) { - // We have the asset! Get the data and send it off. - ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation]; - NSUInteger size = (end > start) ? (end - start) : [assetRepresentation size]; - Byte* buffer = (Byte*)malloc(size); - NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:start length:size error:nil]; - NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES]; - NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType); - - callback(data, MIMEType, NO_ERROR); - } else { - callback(nil, nil, NOT_FOUND_ERR); - } - }; - - ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) { - // Retrieving the asset failed for some reason. Send the appropriate error. - NSLog(@"Error: %@", error); - callback(nil, nil, SECURITY_ERR); - }; - - ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init]; - [assetsLibrary assetForURL:[self assetLibraryURLForLocalURL:localURL] resultBlock:resultBlock failureBlock:failureBlock]; -} - -- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback -{ - // In this case, we need to use an asynchronous method to retrieve the file. - // Because of this, we can't just assign to `result` and send it at the end of the method. - // Instead, we return after calling the asynchronous method and send `result` in each of the blocks. - ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) { - if (asset) { - // We have the asset! Populate the dictionary and send it off. - NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5]; - ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation]; - [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:[assetRepresentation size]] forKey:@"size"]; - [fileInfo setObject:localURL.fullPath forKey:@"fullPath"]; - NSString* filename = [assetRepresentation filename]; - [fileInfo setObject:filename forKey:@"name"]; - [fileInfo setObject:[CDVAssetLibraryFilesystem getMimeTypeFromPath:filename] forKey:@"type"]; - NSDate* creationDate = [asset valueForProperty:ALAssetPropertyDate]; - NSNumber* msDate = [NSNumber numberWithDouble:[creationDate timeIntervalSince1970] * 1000]; - [fileInfo setObject:msDate forKey:@"lastModifiedDate"]; - - callback([CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo]); - } else { - // We couldn't find the asset. Send the appropriate error. - callback([CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]); - } - }; - ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) { - // Retrieving the asset failed for some reason. Send the appropriate error. - callback([CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]]); - }; - - ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init]; - [assetsLibrary assetForURL:[self assetLibraryURLForLocalURL:localURL] resultBlock:resultBlock failureBlock:failureBlock]; - return; -} -@end diff --git a/plugins/cordova-plugin-file/src/ios/CDVFile.h b/plugins/cordova-plugin-file/src/ios/CDVFile.h deleted file mode 100644 index 33630c03..00000000 --- a/plugins/cordova-plugin-file/src/ios/CDVFile.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> - -NSString* const kCDVAssetsLibraryPrefix; -NSString* const kCDVFilesystemURLPrefix; - -enum CDVFileError { - NO_ERROR = 0, - NOT_FOUND_ERR = 1, - SECURITY_ERR = 2, - ABORT_ERR = 3, - NOT_READABLE_ERR = 4, - ENCODING_ERR = 5, - NO_MODIFICATION_ALLOWED_ERR = 6, - INVALID_STATE_ERR = 7, - SYNTAX_ERR = 8, - INVALID_MODIFICATION_ERR = 9, - QUOTA_EXCEEDED_ERR = 10, - TYPE_MISMATCH_ERR = 11, - PATH_EXISTS_ERR = 12 -}; -typedef int CDVFileError; - -@interface CDVFilesystemURL : NSObject { - NSURL *_url; - NSString *_fileSystemName; - NSString *_fullPath; -} - -- (id) initWithString:(NSString*)strURL; -- (id) initWithURL:(NSURL*)URL; -+ (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL; -+ (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL; - -- (NSString *)absoluteURL; - -@property (atomic) NSURL *url; -@property (atomic) NSString *fileSystemName; -@property (atomic) NSString *fullPath; - -@end - -@interface CDVFilesystemURLProtocol : NSURLProtocol -@end - -@protocol CDVFileSystem -- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url; -- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options; -- (CDVPluginResult *)getParentForURL:(CDVFilesystemURL *)localURI; -- (CDVPluginResult *)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options; -- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI; -- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI; -- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI; -- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos; -- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend; -- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback; -- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback; -- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback; - -- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url; -- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir; - -@property (nonatomic,strong) NSString *name; -@property (nonatomic, copy) NSURL*(^urlTransformer)(NSURL*); - -@optional -- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURI; -- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path; - -@end - -@interface CDVFile : CDVPlugin { - NSString* rootDocsPath; - NSString* appDocsPath; - NSString* appLibraryPath; - NSString* appTempPath; - - NSMutableArray* fileSystems_; - BOOL userHasAllowed; -} - -- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath; -- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir; -- (NSDictionary *)makeEntryForURL:(NSURL *)URL; -- (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath; - -- (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL; - -/* Native Registration API */ -- (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs; -- (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName; - -/* Exec API */ -- (void)requestFileSystem:(CDVInvokedUrlCommand*)command; -- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command; -- (void)getDirectory:(CDVInvokedUrlCommand*)command; -- (void)getFile:(CDVInvokedUrlCommand*)command; -- (void)getParent:(CDVInvokedUrlCommand*)command; -- (void)removeRecursively:(CDVInvokedUrlCommand*)command; -- (void)remove:(CDVInvokedUrlCommand*)command; -- (void)copyTo:(CDVInvokedUrlCommand*)command; -- (void)moveTo:(CDVInvokedUrlCommand*)command; -- (void)getFileMetadata:(CDVInvokedUrlCommand*)command; -- (void)readEntries:(CDVInvokedUrlCommand*)command; -- (void)readAsText:(CDVInvokedUrlCommand*)command; -- (void)readAsDataURL:(CDVInvokedUrlCommand*)command; -- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command; -- (void)write:(CDVInvokedUrlCommand*)command; -- (void)testFileExists:(CDVInvokedUrlCommand*)command; -- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command; -- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command; -- (void)truncate:(CDVInvokedUrlCommand*)command; -- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy; - -/* Compatibilty with older File API */ -- (NSString*)getMimeTypeFromPath:(NSString*)fullPath; -- (NSDictionary *)getDirectoryEntry:(NSString *)target isDirectory:(BOOL)bDirRequest; - -/* Conversion between filesystem paths and URLs */ -- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)URL; - -/* Internal methods for testing */ -- (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command; - -@property (nonatomic, strong) NSString* rootDocsPath; -@property (nonatomic, strong) NSString* appDocsPath; -@property (nonatomic, strong) NSString* appLibraryPath; -@property (nonatomic, strong) NSString* appTempPath; -@property (nonatomic, strong) NSString* persistentPath; -@property (nonatomic, strong) NSString* temporaryPath; -@property (nonatomic, strong) NSMutableArray* fileSystems; - -@property BOOL userHasAllowed; - -@end - -#define kW3FileTemporary @"temporary" -#define kW3FilePersistent @"persistent" diff --git a/plugins/cordova-plugin-file/src/ios/CDVFile.m b/plugins/cordova-plugin-file/src/ios/CDVFile.m deleted file mode 100644 index eec8978e..00000000 --- a/plugins/cordova-plugin-file/src/ios/CDVFile.m +++ /dev/null @@ -1,1092 +0,0 @@ -/* - 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 <Cordova/CDV.h> -#import "CDVFile.h" -#import "CDVLocalFilesystem.h" -#import "CDVAssetLibraryFilesystem.h" -#import <objc/message.h> - -CDVFile *filePlugin = nil; - -extern NSString * const NSURLIsExcludedFromBackupKey __attribute__((weak_import)); - -#ifndef __IPHONE_5_1 - NSString* const NSURLIsExcludedFromBackupKey = @"NSURLIsExcludedFromBackupKey"; -#endif - -NSString* const kCDVFilesystemURLPrefix = @"cdvfile"; - -@implementation CDVFilesystemURL -@synthesize url=_url; -@synthesize fileSystemName=_fileSystemName; -@synthesize fullPath=_fullPath; - -- (id) initWithString:(NSString *)strURL -{ - if ( self = [super init] ) { - NSURL *decodedURL = [NSURL URLWithString:strURL]; - return [self initWithURL:decodedURL]; - } - return nil; -} - --(id) initWithURL:(NSURL *)URL -{ - if ( self = [super init] ) { - _url = URL; - _fileSystemName = [self filesystemNameForLocalURI:URL]; - _fullPath = [self fullPathForLocalURI:URL]; - } - return self; -} - -/* - * IN - * NSString localURI - * OUT - * NSString FileSystem Name for this URI, or nil if it is not recognized. - */ -- (NSString *)filesystemNameForLocalURI:(NSURL *)uri -{ - if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@"localhost"]) { - NSArray *pathComponents = [uri pathComponents]; - if (pathComponents != nil && pathComponents.count > 1) { - return [pathComponents objectAtIndex:1]; - } - } else if ([[uri scheme] isEqualToString:kCDVAssetsLibraryScheme]) { - return @"assets-library"; - } - return nil; -} - -/* - * IN - * NSString localURI - * OUT - * NSString fullPath component suitable for an Entry object. - * The incoming URI should be properly escaped. The returned fullPath is unescaped. - */ -- (NSString *)fullPathForLocalURI:(NSURL *)uri -{ - if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@"localhost"]) { - NSString *path = [uri path]; - if ([uri query]) { - path = [NSString stringWithFormat:@"%@?%@", path, [uri query]]; - } - NSRange slashRange = [path rangeOfString:@"/" options:0 range:NSMakeRange(1, path.length-1)]; - if (slashRange.location == NSNotFound) { - return @""; - } - return [path substringFromIndex:slashRange.location]; - } else if ([[uri scheme] isEqualToString:kCDVAssetsLibraryScheme]) { - return [[uri absoluteString] substringFromIndex:[kCDVAssetsLibraryScheme length]+2]; - } - return nil; -} - -+ (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL -{ - return [[CDVFilesystemURL alloc] initWithString:strURL]; -} - -+ (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL -{ - return [[CDVFilesystemURL alloc] initWithURL:URL]; -} - -- (NSString *)absoluteURL -{ - return [NSString stringWithFormat:@"cdvfile://localhost/%@%@", self.fileSystemName, self.fullPath]; -} - -@end - -@implementation CDVFilesystemURLProtocol - -+ (BOOL)canInitWithRequest:(NSURLRequest*)request -{ - NSURL* url = [request URL]; - return [[url scheme] isEqualToString:kCDVFilesystemURLPrefix]; -} - -+ (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request -{ - return request; -} - -+ (BOOL)requestIsCacheEquivalent:(NSURLRequest*)requestA toRequest:(NSURLRequest*)requestB -{ - return [[[requestA URL] resourceSpecifier] isEqualToString:[[requestB URL] resourceSpecifier]]; -} - -- (void)startLoading -{ - CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithURL:[[self request] URL]]; - NSObject<CDVFileSystem> *fs = [filePlugin filesystemForURL:url]; - [fs readFileAtURL:url start:0 end:-1 callback:^void(NSData *data, NSString *mimetype, CDVFileError error) { - NSMutableDictionary* responseHeaders = [[NSMutableDictionary alloc] init]; - responseHeaders[@"Cache-Control"] = @"no-cache"; - - if (!error) { - responseHeaders[@"Content-Type"] = mimetype; - NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:200 HTTPVersion:@"HTTP/1.1"headerFields:responseHeaders]; - [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [[self client] URLProtocol:self didLoadData:data]; - [[self client] URLProtocolDidFinishLoading:self]; - } else { - NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:404 HTTPVersion:@"HTTP/1.1"headerFields:responseHeaders]; - [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [[self client] URLProtocolDidFinishLoading:self]; - } - }]; -} - -- (void)stopLoading -{} - -- (NSCachedURLResponse *)connection:(NSURLConnection *)connection - willCacheResponse:(NSCachedURLResponse*)cachedResponse { - return nil; -} - -@end - - -@implementation CDVFile - -@synthesize rootDocsPath, appDocsPath, appLibraryPath, appTempPath, userHasAllowed, fileSystems=fileSystems_; - -- (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs { - __weak CDVFile* weakSelf = self; - SEL sel = NSSelectorFromString(@"urlTransformer"); - // for backwards compatibility - we check if this property is there - // we create a wrapper block because the urlTransformer property - // on the commandDelegate might be set dynamically at a future time - // (and not dependent on plugin loading order) - if ([self.commandDelegate respondsToSelector:sel]) { - fs.urlTransformer = ^NSURL*(NSURL* urlToTransform) { - // grab the block from the commandDelegate - NSURL* (^urlTransformer)(NSURL*) = ((id(*)(id, SEL))objc_msgSend)(weakSelf.commandDelegate, sel); - // if block is not null, we call it - if (urlTransformer) { - return urlTransformer(urlToTransform); - } else { // else we return the same url - return urlToTransform; - } - }; - } - [fileSystems_ addObject:fs]; -} - -- (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName -{ - if (self.fileSystems != nil) { - for (NSObject<CDVFileSystem> *fs in self.fileSystems) { - if ([fs.name isEqualToString:fsName]) { - return fs; - } - } - } - return nil; - -} - -- (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL { - if (localURL.fileSystemName == nil) return nil; - @try { - return [self fileSystemByName:localURL.fileSystemName]; - } - @catch (NSException *e) { - return nil; - } -} - -- (NSArray *)getExtraFileSystemsPreference:(UIViewController *)vc -{ - NSString *filesystemsStr = nil; - if([self.viewController isKindOfClass:[CDVViewController class]]) { - CDVViewController *vc = (CDVViewController *)self.viewController; - NSDictionary *settings = [vc settings]; - filesystemsStr = [settings[@"iosextrafilesystems"] lowercaseString]; - } - if (!filesystemsStr) { - filesystemsStr = @"library,library-nosync,documents,documents-nosync,cache,bundle,root"; - } - return [filesystemsStr componentsSeparatedByString:@","]; -} - -- (void)makeNonSyncable:(NSString*)path { - [[NSFileManager defaultManager] createDirectoryAtPath:path - withIntermediateDirectories:YES - attributes:nil - error:nil]; - NSURL* url = [NSURL fileURLWithPath:path]; - [url setResourceValue: [NSNumber numberWithBool: YES] - forKey: NSURLIsExcludedFromBackupKey error:nil]; - -} - -- (void)registerExtraFileSystems:(NSArray *)filesystems fromAvailableSet:(NSDictionary *)availableFileSystems -{ - NSMutableSet *installedFilesystems = [[NSMutableSet alloc] initWithCapacity:7]; - - /* Build non-syncable directories as necessary */ - for (NSString *nonSyncFS in @[@"library-nosync", @"documents-nosync"]) { - if ([filesystems containsObject:nonSyncFS]) { - [self makeNonSyncable:availableFileSystems[nonSyncFS]]; - } - } - - /* Register filesystems in order */ - for (NSString *fsName in filesystems) { - if (![installedFilesystems containsObject:fsName]) { - NSString *fsRoot = availableFileSystems[fsName]; - if (fsRoot) { - [filePlugin registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:fsName root:fsRoot]]; - [installedFilesystems addObject:fsName]; - } else { - NSLog(@"Unrecognized extra filesystem identifier: %@", fsName); - } - } - } -} - -- (NSDictionary *)getAvailableFileSystems -{ - NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]; - NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; - return @{ - @"library": libPath, - @"library-nosync": [libPath stringByAppendingPathComponent:@"NoCloud"], - @"documents": docPath, - @"documents-nosync": [docPath stringByAppendingPathComponent:@"NoCloud"], - @"cache": [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0], - @"bundle": [[NSBundle mainBundle] bundlePath], - @"root": @"/" - }; -} - -- (void)pluginInitialize -{ - filePlugin = self; - [NSURLProtocol registerClass:[CDVFilesystemURLProtocol class]]; - - fileSystems_ = [[NSMutableArray alloc] initWithCapacity:3]; - - // Get the Library directory path - NSArray* paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); - self.appLibraryPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"files"]; - - // Get the Temporary directory path - self.appTempPath = [NSTemporaryDirectory()stringByStandardizingPath]; // remove trailing slash from NSTemporaryDirectory() - - // Get the Documents directory path - paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - self.rootDocsPath = [paths objectAtIndex:0]; - self.appDocsPath = [self.rootDocsPath stringByAppendingPathComponent:@"files"]; - - - NSString *location = nil; - if([self.viewController isKindOfClass:[CDVViewController class]]) { - CDVViewController *vc = (CDVViewController *)self.viewController; - NSMutableDictionary *settings = vc.settings; - location = [[settings objectForKey:@"iospersistentfilelocation"] lowercaseString]; - } - if (location == nil) { - // Compatibilty by default (if the config preference is not set, or - // if we're not embedded in a CDVViewController somehow.) - location = @"compatibility"; - } - - NSError *error; - if ([[NSFileManager defaultManager] createDirectoryAtPath:self.appTempPath - withIntermediateDirectories:YES - attributes:nil - error:&error]) { - [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@"temporary" root:self.appTempPath]]; - } else { - NSLog(@"Unable to create temporary directory: %@", error); - } - if ([location isEqualToString:@"library"]) { - if ([[NSFileManager defaultManager] createDirectoryAtPath:self.appLibraryPath - withIntermediateDirectories:YES - attributes:nil - error:&error]) { - [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@"persistent" root:self.appLibraryPath]]; - } else { - NSLog(@"Unable to create library directory: %@", error); - } - } else if ([location isEqualToString:@"compatibility"]) { - /* - * Fall-back to compatibility mode -- this is the logic implemented in - * earlier versions of this plugin, and should be maintained here so - * that apps which were originally deployed with older versions of the - * plugin can continue to provide access to files stored under those - * versions. - */ - [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@"persistent" root:self.rootDocsPath]]; - } else { - NSAssert(false, - @"File plugin configuration error: Please set iosPersistentFileLocation in config.xml to one of \"library\" (for new applications) or \"compatibility\" (for compatibility with previous versions)"); - } - [self registerFilesystem:[[CDVAssetLibraryFilesystem alloc] initWithName:@"assets-library"]]; - - [self registerExtraFileSystems:[self getExtraFileSystemsPreference:self.viewController] - fromAvailableSet:[self getAvailableFileSystems]]; - -} - -- (CDVFilesystemURL *)fileSystemURLforArg:(NSString *)urlArg -{ - CDVFilesystemURL* ret = nil; - if ([urlArg hasPrefix:@"file://"]) { - /* This looks like a file url. Get the path, and see if any handlers recognize it. */ - NSURL *fileURL = [NSURL URLWithString:urlArg]; - NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath]; - NSString *path = [resolvedFileURL path]; - ret = [self fileSystemURLforLocalPath:path]; - } else { - ret = [CDVFilesystemURL fileSystemURLWithString:urlArg]; - } - return ret; -} - -- (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath -{ - CDVFilesystemURL *localURL = nil; - NSUInteger shortestFullPath = 0; - - // Try all installed filesystems, in order. Return the most match url. - for (id object in self.fileSystems) { - if ([object respondsToSelector:@selector(URLforFilesystemPath:)]) { - CDVFilesystemURL *url = [object URLforFilesystemPath:localPath]; - if (url){ - // A shorter fullPath would imply that the filesystem is a better match for the local path - if (!localURL || ([[url fullPath] length] < shortestFullPath)) { - localURL = url; - shortestFullPath = [[url fullPath] length]; - } - } - } - } - return localURL; -} - -- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath -{ - NSFileManager* fMgr = [[NSFileManager alloc] init]; - - NSError* __autoreleasing pError = nil; - - NSDictionary* pDict = [fMgr attributesOfFileSystemForPath:appPath error:&pError]; - NSNumber* pNumAvail = (NSNumber*)[pDict objectForKey:NSFileSystemFreeSize]; - - return pNumAvail; -} - -/* Request the File System info - * - * IN: - * arguments[0] - type (number as string) - * TEMPORARY = 0, PERSISTENT = 1; - * arguments[1] - size - * - * OUT: - * Dictionary representing FileSystem object - * name - the human readable directory name - * root = DirectoryEntry object - * bool isDirectory - * bool isFile - * string name - * string fullPath - * fileSystem = FileSystem object - !! ignored because creates circular reference !! - */ - -- (void)requestFileSystem:(CDVInvokedUrlCommand*)command -{ - // arguments - NSString* strType = [command argumentAtIndex:0]; - unsigned long long size = [[command argumentAtIndex:1] longLongValue]; - - int type = [strType intValue]; - CDVPluginResult* result = nil; - - if (type > self.fileSystems.count) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR]; - NSLog(@"No filesystem of type requested"); - } else { - NSString* fullPath = @"/"; - // check for avail space for size request - NSNumber* pNumAvail = [self checkFreeDiskSpace:self.rootDocsPath]; - // NSLog(@"Free space: %@", [NSString stringWithFormat:@"%qu", [ pNumAvail unsignedLongLongValue ]]); - if (pNumAvail && ([pNumAvail unsignedLongLongValue] < size)) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:QUOTA_EXCEEDED_ERR]; - } else { - NSObject<CDVFileSystem> *rootFs = [self.fileSystems objectAtIndex:type]; - if (rootFs == nil) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR]; - NSLog(@"No filesystem of type requested"); - } else { - NSMutableDictionary* fileSystem = [NSMutableDictionary dictionaryWithCapacity:2]; - [fileSystem setObject:rootFs.name forKey:@"name"]; - NSDictionary* dirEntry = [self makeEntryForPath:fullPath fileSystemName:rootFs.name isDirectory:YES]; - [fileSystem setObject:dirEntry forKey:@"root"]; - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem]; - } - } - } - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - - -- (void)requestAllFileSystems:(CDVInvokedUrlCommand*)command -{ - NSMutableArray* ret = [[NSMutableArray alloc] init]; - for (NSObject<CDVFileSystem>* root in fileSystems_) { - [ret addObject:[self makeEntryForPath:@"/" fileSystemName:root.name isDirectory:YES]]; - } - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:ret]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -- (void)requestAllPaths:(CDVInvokedUrlCommand*)command -{ - NSString* libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0]; - NSString* libPathSync = [libPath stringByAppendingPathComponent:@"Cloud"]; - NSString* libPathNoSync = [libPath stringByAppendingPathComponent:@"NoCloud"]; - NSString* docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; - NSString* storagePath = [libPath stringByDeletingLastPathComponent]; - NSString* cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; - - // Create the directories if necessary. - [[NSFileManager defaultManager] createDirectoryAtPath:libPathSync withIntermediateDirectories:YES attributes:nil error:nil]; - [[NSFileManager defaultManager] createDirectoryAtPath:libPathNoSync withIntermediateDirectories:YES attributes:nil error:nil]; - // Mark NoSync as non-iCloud. - [[NSURL fileURLWithPath:libPathNoSync] setResourceValue: [NSNumber numberWithBool: YES] - forKey: NSURLIsExcludedFromBackupKey error:nil]; - - NSDictionary* ret = @{ - @"applicationDirectory": [[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]] absoluteString], - @"applicationStorageDirectory": [[NSURL fileURLWithPath:storagePath] absoluteString], - @"dataDirectory": [[NSURL fileURLWithPath:libPathNoSync] absoluteString], - @"syncedDataDirectory": [[NSURL fileURLWithPath:libPathSync] absoluteString], - @"documentsDirectory": [[NSURL fileURLWithPath:docPath] absoluteString], - @"cacheDirectory": [[NSURL fileURLWithPath:cachePath] absoluteString], - @"tempDirectory": [[NSURL fileURLWithPath:NSTemporaryDirectory()] absoluteString] - }; - - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:ret]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* Creates and returns a dictionary representing an Entry Object - * - * IN: - * NSString* fullPath of the entry - * int fsType - FileSystem type - * BOOL isDirectory - YES if this is a directory, NO if is a file - * OUT: - * NSDictionary* Entry object - * bool as NSNumber isDirectory - * bool as NSNumber isFile - * NSString* name - last part of path - * NSString* fullPath - * NSString* filesystemName - FileSystem name -- actual filesystem will be created on the JS side if necessary, to avoid - * creating circular reference (FileSystem contains DirectoryEntry which contains FileSystem.....!!) - */ -- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir -{ - NSObject<CDVFileSystem> *fs = [self fileSystemByName:fsName]; - return [fs makeEntryForPath:fullPath isDirectory:isDir]; -} - -- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)localURL -{ - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURL]; - return [fs makeEntryForLocalURL:localURL]; -} - -- (NSDictionary *)makeEntryForURL:(NSURL *)URL -{ - CDVFilesystemURL* fsURL = [self fileSystemURLforArg:[URL absoluteString]]; - return [self makeEntryForLocalURL:fsURL]; -} - -/* - * Given a URI determine the File System information associated with it and return an appropriate W3C entry object - * IN - * NSString* localURI: Should be an escaped local filesystem URI - * OUT - * Entry object - * bool isDirectory - * bool isFile - * string name - * string fullPath - * fileSystem = FileSystem object - !! ignored because creates circular reference FileSystem contains DirectoryEntry which contains FileSystem.....!! - */ -- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command -{ - // arguments - NSString* localURIstr = [command argumentAtIndex:0]; - CDVPluginResult* result; - - localURIstr = [self encodePath:localURIstr]; //encode path before resolving - CDVFilesystemURL* inputURI = [self fileSystemURLforArg:localURIstr]; - - if (inputURI == nil || inputURI.fileSystemName == nil) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR]; - } else { - NSObject<CDVFileSystem> *fs = [self filesystemForURL:inputURI]; - if (fs == nil) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR]; - } else { - result = [fs entryForLocalURI:inputURI]; - } - } - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -//encode path with percent escapes --(NSString *)encodePath:(NSString *)path -{ - NSString *decodedPath = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //decode incase it's already encoded to avoid encoding twice - return [decodedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; -} - - -/* Part of DirectoryEntry interface, creates or returns the specified directory - * IN: - * NSString* localURI - local filesystem URI for this directory - * NSString* path - directory to be created/returned; may be full path or relative path - * NSDictionary* - Flags object - * boolean as NSNumber create - - * if create is true and directory does not exist, create dir and return directory entry - * if create is true and exclusive is true and directory does exist, return error - * if create is false and directory does not exist, return error - * if create is false and the path represents a file, return error - * boolean as NSNumber exclusive - used in conjunction with create - * if exclusive is true and create is true - specifies failure if directory already exists - * - * - */ -- (void)getDirectory:(CDVInvokedUrlCommand*)command -{ - NSMutableArray* arguments = [NSMutableArray arrayWithArray:command.arguments]; - NSMutableDictionary* options = nil; - - if ([arguments count] >= 3) { - options = [command argumentAtIndex:2 withDefault:nil]; - } - // add getDir to options and call getFile() - if (options != nil) { - options = [NSMutableDictionary dictionaryWithDictionary:options]; - } else { - options = [NSMutableDictionary dictionaryWithCapacity:1]; - } - [options setObject:[NSNumber numberWithInt:1] forKey:@"getDir"]; - if ([arguments count] >= 3) { - [arguments replaceObjectAtIndex:2 withObject:options]; - } else { - [arguments addObject:options]; - } - CDVInvokedUrlCommand* subCommand = - [[CDVInvokedUrlCommand alloc] initWithArguments:arguments - callbackId:command.callbackId - className:command.className - methodName:command.methodName]; - - [self getFile:subCommand]; -} - -/* Part of DirectoryEntry interface, creates or returns the specified file - * IN: - * NSString* baseURI - local filesytem URI for the base directory to search - * NSString* requestedPath - file to be created/returned; may be absolute path or relative path - * NSDictionary* options - Flags object - * boolean as NSNumber create - - * if create is true and file does not exist, create file and return File entry - * if create is true and exclusive is true and file does exist, return error - * if create is false and file does not exist, return error - * if create is false and the path represents a directory, return error - * boolean as NSNumber exclusive - used in conjunction with create - * if exclusive is true and create is true - specifies failure if file already exists - */ -- (void)getFile:(CDVInvokedUrlCommand*)command -{ - NSString* baseURIstr = [command argumentAtIndex:0]; - CDVFilesystemURL* baseURI = [self fileSystemURLforArg:baseURIstr]; - NSString* requestedPath = [command argumentAtIndex:1]; - NSDictionary* options = [command argumentAtIndex:2 withDefault:nil]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:baseURI]; - CDVPluginResult* result = [fs getFileForURL:baseURI requestedPath:requestedPath options:options]; - - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* - * Look up the parent Entry containing this Entry. - * If this Entry is the root of its filesystem, its parent is itself. - * IN: - * NSArray* arguments - * 0 - NSString* localURI - * NSMutableDictionary* options - * empty - */ -- (void)getParent:(CDVInvokedUrlCommand*)command -{ - // arguments are URL encoded - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - CDVPluginResult* result = [fs getParentForURL:localURI]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* - * set MetaData of entry - * Currently we only support "com.apple.MobileBackup" (boolean) - */ -- (void)setMetadata:(CDVInvokedUrlCommand*)command -{ - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSDictionary* options = [command argumentAtIndex:1 withDefault:nil]; - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - CDVPluginResult* result = [fs setMetadataForURL:localURI withObject:options]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* removes the directory or file entry - * IN: - * NSArray* arguments - * 0 - NSString* localURI - * - * returns NO_MODIFICATION_ALLOWED_ERR if is top level directory or no permission to delete dir - * returns INVALID_MODIFICATION_ERR if is non-empty dir or asset library file - * returns NOT_FOUND_ERR if file or dir is not found -*/ -- (void)remove:(CDVInvokedUrlCommand*)command -{ - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - CDVPluginResult* result = nil; - - if ([localURI.fullPath isEqualToString:@""]) { - // error if try to remove top level (documents or tmp) dir - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR]; - } else { - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - result = [fs removeFileAtURL:localURI]; - } - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* recursively removes the directory - * IN: - * NSArray* arguments - * 0 - NSString* localURI - * - * returns NO_MODIFICATION_ALLOWED_ERR if is top level directory or no permission to delete dir - * returns NOT_FOUND_ERR if file or dir is not found - */ -- (void)removeRecursively:(CDVInvokedUrlCommand*)command -{ - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - CDVPluginResult* result = nil; - - if ([localURI.fullPath isEqualToString:@""]) { - // error if try to remove top level (documents or tmp) dir - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR]; - } else { - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - result = [fs recursiveRemoveFileAtURL:localURI]; - } - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -- (void)copyTo:(CDVInvokedUrlCommand*)command -{ - [self doCopyMove:command isCopy:YES]; -} - -- (void)moveTo:(CDVInvokedUrlCommand*)command -{ - [self doCopyMove:command isCopy:NO]; -} - -/* Copy/move a file or directory to a new location - * IN: - * NSArray* arguments - * 0 - NSString* URL of entry to copy - * 1 - NSString* URL of the directory into which to copy/move the entry - * 2 - Optionally, the new name of the entry, defaults to the current name - * BOOL - bCopy YES if copy, NO if move - */ -- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy -{ - NSArray* arguments = command.arguments; - - // arguments - NSString* srcURLstr = [command argumentAtIndex:0]; - NSString* destURLstr = [command argumentAtIndex:1]; - - CDVPluginResult *result; - - if (!srcURLstr || !destURLstr) { - // either no source or no destination provided - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - return; - } - - CDVFilesystemURL* srcURL = [self fileSystemURLforArg:srcURLstr]; - CDVFilesystemURL* destURL = [self fileSystemURLforArg:destURLstr]; - - NSObject<CDVFileSystem> *srcFs = [self filesystemForURL:srcURL]; - NSObject<CDVFileSystem> *destFs = [self filesystemForURL:destURL]; - - // optional argument; use last component from srcFullPath if new name not provided - NSString* newName = ([arguments count] > 2) ? [command argumentAtIndex:2] : [srcURL.url lastPathComponent]; - if ([newName rangeOfString:@":"].location != NSNotFound) { - // invalid chars in new name - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - return; - } - - [destFs copyFileToURL:destURL withName:newName fromFileSystem:srcFs atURL:srcURL copy:bCopy callback:^(CDVPluginResult* result) { - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; - -} - -- (void)getFileMetadata:(CDVInvokedUrlCommand*)command -{ - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - - [fs getFileMetadataForURL:localURI callback:^(CDVPluginResult* result) { - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; -} - -- (void)readEntries:(CDVInvokedUrlCommand*)command -{ - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - CDVPluginResult *result = [fs readEntriesAtURL:localURI]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* read and return file data - * IN: - * NSArray* arguments - * 0 - NSString* fullPath - * 1 - NSString* encoding - * 2 - NSString* start - * 3 - NSString* end - */ -- (void)readAsText:(CDVInvokedUrlCommand*)command -{ - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSString* encoding = [command argumentAtIndex:1]; - NSInteger start = [[command argumentAtIndex:2] integerValue]; - NSInteger end = [[command argumentAtIndex:3] integerValue]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - - if (fs == nil) { - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - return; - } - - // TODO: implement - if ([@"UTF-8" caseInsensitiveCompare : encoding] != NSOrderedSame) { - NSLog(@"Only UTF-8 encodings are currently supported by readAsText"); - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - return; - } - - [self.commandDelegate runInBackground:^ { - [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) { - CDVPluginResult* result = nil; - if (data != nil) { - NSString* str = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSUTF8StringEncoding freeWhenDone:NO]; - // Check that UTF8 conversion did not fail. - if (str != nil) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:str]; - result.associatedObject = data; - } else { - errorCode = ENCODING_ERR; - } - } - if (result == nil) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; - }]; -} - -/* Read content of text file and return as base64 encoded data url. - * IN: - * NSArray* arguments - * 0 - NSString* fullPath - * 1 - NSString* start - * 2 - NSString* end - * - * Determines the mime type from the file extension, returns ENCODING_ERR if mimetype can not be determined. - */ - -- (void)readAsDataURL:(CDVInvokedUrlCommand*)command -{ - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSInteger start = [[command argumentAtIndex:1] integerValue]; - NSInteger end = [[command argumentAtIndex:2] integerValue]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - - [self.commandDelegate runInBackground:^ { - [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) { - CDVPluginResult* result = nil; - if (data != nil) { - SEL selector = NSSelectorFromString(@"cdv_base64EncodedString"); - if (![data respondsToSelector:selector]) { - selector = NSSelectorFromString(@"base64EncodedString"); - } - id (*func)(id, SEL) = (void *)[data methodForSelector:selector]; - NSString* b64Str = func(data, selector); - NSString* output = [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, b64Str]; - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output]; - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; - }]; -} - -/* Read content of text file and return as an arraybuffer - * IN: - * NSArray* arguments - * 0 - NSString* fullPath - * 1 - NSString* start - * 2 - NSString* end - */ - -- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command -{ - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSInteger start = [[command argumentAtIndex:1] integerValue]; - NSInteger end = [[command argumentAtIndex:2] integerValue]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - - [self.commandDelegate runInBackground:^ { - [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) { - CDVPluginResult* result = nil; - if (data != nil) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArrayBuffer:data]; - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; - }]; -} - -- (void)readAsBinaryString:(CDVInvokedUrlCommand*)command -{ - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - NSInteger start = [[command argumentAtIndex:1] integerValue]; - NSInteger end = [[command argumentAtIndex:2] integerValue]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - - [self.commandDelegate runInBackground:^ { - [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) { - CDVPluginResult* result = nil; - if (data != nil) { - NSString* payload = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSASCIIStringEncoding freeWhenDone:NO]; - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload]; - result.associatedObject = data; - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; - }]; -} - - -- (void)truncate:(CDVInvokedUrlCommand*)command -{ - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - unsigned long long pos = (unsigned long long)[[command argumentAtIndex:1] longLongValue]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - CDVPluginResult *result = [fs truncateFileAtURL:localURI atPosition:pos]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -/* write - * IN: - * NSArray* arguments - * 0 - NSString* localURI of file to write to - * 1 - NSString* or NSData* data to write - * 2 - NSNumber* position to begin writing - */ -- (void)write:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^ { - NSString* callbackId = command.callbackId; - - // arguments - CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; - id argData = [command argumentAtIndex:1]; - unsigned long long pos = (unsigned long long)[[command argumentAtIndex:2] longLongValue]; - - NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; - - - [fs truncateFileAtURL:localURI atPosition:pos]; - CDVPluginResult *result; - if ([argData isKindOfClass:[NSString class]]) { - NSData *encData = [argData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; - result = [fs writeToFileAtURL:localURI withData:encData append:YES]; - } else if ([argData isKindOfClass:[NSData class]]) { - result = [fs writeToFileAtURL:localURI withData:argData append:YES]; - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Invalid parameter type"]; - } - [self.commandDelegate sendPluginResult:result callbackId:callbackId]; - }]; -} - -#pragma mark Methods for converting between URLs and paths - -- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURL -{ - for (NSObject<CDVFileSystem> *fs in self.fileSystems) { - if ([fs.name isEqualToString:localURL.fileSystemName]) { - if ([fs respondsToSelector:@selector(filesystemPathForURL:)]) { - return [fs filesystemPathForURL:localURL]; - } - } - } - return nil; -} - -#pragma mark Undocumented Filesystem API - -- (void)testFileExists:(CDVInvokedUrlCommand*)command -{ - // arguments - NSString* argPath = [command argumentAtIndex:0]; - - // Get the file manager - NSFileManager* fMgr = [NSFileManager defaultManager]; - NSString* appFile = argPath; // [ self getFullPath: argPath]; - - BOOL bExists = [fMgr fileExistsAtPath:appFile]; - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(bExists ? 1 : 0)]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command -{ - // arguments - NSString* argPath = [command argumentAtIndex:0]; - - // Get the file manager - NSFileManager* fMgr = [[NSFileManager alloc] init]; - NSString* appFile = argPath; // [self getFullPath: argPath]; - BOOL bIsDir = NO; - BOOL bExists = [fMgr fileExistsAtPath:appFile isDirectory:&bIsDir]; - - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:((bExists && bIsDir) ? 1 : 0)]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -// Returns number of bytes available via callback -- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command -{ - // no arguments - - NSNumber* pNumAvail = [self checkFreeDiskSpace:self.appDocsPath]; - - NSString* strFreeSpace = [NSString stringWithFormat:@"%qu", [pNumAvail unsignedLongLongValue]]; - // NSLog(@"Free space is %@", strFreeSpace ); - - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:strFreeSpace]; - - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -#pragma mark Compatibility with older File API - -- (NSString*)getMimeTypeFromPath:(NSString*)fullPath -{ - return [CDVLocalFilesystem getMimeTypeFromPath:fullPath]; -} - -- (NSDictionary *)getDirectoryEntry:(NSString *)localPath isDirectory:(BOOL)bDirRequest -{ - CDVFilesystemURL *localURL = [self fileSystemURLforLocalPath:localPath]; - return [self makeEntryForPath:localURL.fullPath fileSystemName:localURL.fileSystemName isDirectory:bDirRequest]; -} - -#pragma mark Internal methods for testing -// Internal methods for testing: Get the on-disk location of a local filesystem url. -// [Currently used for testing file-transfer] - -- (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command -{ - CDVFilesystemURL* localURL = [self fileSystemURLforArg:command.arguments[0]]; - - NSString* fsPath = [self filesystemPathForURL:localURL]; - CDVPluginResult* result; - if (fsPath) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:fsPath]; - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Cannot resolve URL to a file"]; - } - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; -} - -@end diff --git a/plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.h b/plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.h deleted file mode 100644 index a0186c85..00000000 --- a/plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - 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 "CDVFile.h" - -@interface CDVLocalFilesystem : NSObject<CDVFileSystem> { - NSString *_name; - NSString *_fsRoot; -} - -- (id) initWithName:(NSString *)name root:(NSString *)fsRoot; -+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath; - -@property (nonatomic,strong) NSString *fsRoot; - -@end diff --git a/plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.m b/plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.m deleted file mode 100644 index 72bc421e..00000000 --- a/plugins/cordova-plugin-file/src/ios/CDVLocalFilesystem.m +++ /dev/null @@ -1,734 +0,0 @@ -/* - 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 "CDVFile.h" -#import "CDVLocalFilesystem.h" -#import <Cordova/CDV.h> -#import <MobileCoreServices/MobileCoreServices.h> -#import <sys/xattr.h> - -@implementation CDVLocalFilesystem -@synthesize name=_name, fsRoot=_fsRoot, urlTransformer; - -- (id) initWithName:(NSString *)name root:(NSString *)fsRoot -{ - if (self) { - _name = name; - _fsRoot = fsRoot; - } - return self; -} - -/* - * IN - * NSString localURI - * OUT - * CDVPluginResult result containing a file or directoryEntry for the localURI, or an error if the - * URI represents a non-existent path, or is unrecognized or otherwise malformed. - */ -- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url -{ - CDVPluginResult* result = nil; - NSDictionary* entry = [self makeEntryForLocalURL:url]; - if (entry) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry]; - } else { - // return NOT_FOUND_ERR - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; - } - return result; -} -- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url { - NSString *path = [self filesystemPathForURL:url]; - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - BOOL isDir = NO; - // see if exists and is file or dir - BOOL bExists = [fileMgr fileExistsAtPath:path isDirectory:&isDir]; - if (bExists) { - return [self makeEntryForPath:url.fullPath isDirectory:isDir]; - } else { - return nil; - } -} -- (NSDictionary*)makeEntryForPath:(NSString*)fullPath isDirectory:(BOOL)isDir -{ - NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5]; - NSString* lastPart = [[self stripQueryParametersFromPath:fullPath] lastPathComponent]; - if (isDir && ![fullPath hasSuffix:@"/"]) { - fullPath = [fullPath stringByAppendingString:@"/"]; - } - [dirEntry setObject:[NSNumber numberWithBool:!isDir] forKey:@"isFile"]; - [dirEntry setObject:[NSNumber numberWithBool:isDir] forKey:@"isDirectory"]; - [dirEntry setObject:fullPath forKey:@"fullPath"]; - [dirEntry setObject:lastPart forKey:@"name"]; - [dirEntry setObject:self.name forKey: @"filesystemName"]; - - NSURL* nativeURL = [NSURL fileURLWithPath:[self filesystemPathForFullPath:fullPath]]; - if (self.urlTransformer) { - nativeURL = self.urlTransformer(nativeURL); - } - - dirEntry[@"nativeURL"] = [nativeURL absoluteString]; - - return dirEntry; -} - -- (NSString *)stripQueryParametersFromPath:(NSString *)fullPath -{ - NSRange questionMark = [fullPath rangeOfString:@"?"]; - if (questionMark.location != NSNotFound) { - return [fullPath substringWithRange:NSMakeRange(0,questionMark.location)]; - } - return fullPath; -} - -- (NSString *)filesystemPathForFullPath:(NSString *)fullPath -{ - NSString *path = nil; - NSString *strippedFullPath = [self stripQueryParametersFromPath:fullPath]; - path = [NSString stringWithFormat:@"%@%@", self.fsRoot, strippedFullPath]; - if ([path length] > 1 && [path hasSuffix:@"/"]) { - path = [path substringToIndex:([path length]-1)]; - } - return path; -} -/* - * IN - * NSString localURI - * OUT - * NSString full local filesystem path for the represented file or directory, or nil if no such path is possible - * The file or directory does not necessarily have to exist. nil is returned if the filesystem type is not recognized, - * or if the URL is malformed. - * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding is expected). - */ -- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url -{ - return [self filesystemPathForFullPath:url.fullPath]; -} - -- (CDVFilesystemURL *)URLforFullPath:(NSString *)fullPath -{ - if (fullPath) { - NSString* escapedPath = [fullPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - if ([fullPath hasPrefix:@"/"]) { - return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@"%@://localhost/%@%@", kCDVFilesystemURLPrefix, self.name, escapedPath]]; - } - return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@"%@://localhost/%@/%@", kCDVFilesystemURLPrefix, self.name, escapedPath]]; - } - return nil; -} - -- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path -{ - return [self URLforFullPath:[self fullPathForFileSystemPath:path]]; - -} - -- (NSString *)normalizePath:(NSString *)rawPath -{ - // If this is an absolute path, the first path component will be '/'. Skip it if that's the case - BOOL isAbsolutePath = [rawPath hasPrefix:@"/"]; - if (isAbsolutePath) { - rawPath = [rawPath substringFromIndex:1]; - } - NSMutableArray *components = [NSMutableArray arrayWithArray:[rawPath pathComponents]]; - for (int index = 0; index < [components count]; ++index) { - if ([[components objectAtIndex:index] isEqualToString:@".."]) { - [components removeObjectAtIndex:index]; - if (index > 0) { - [components removeObjectAtIndex:index-1]; - --index; - } - } - } - - if (isAbsolutePath) { - return [NSString stringWithFormat:@"/%@", [components componentsJoinedByString:@"/"]]; - } else { - return [components componentsJoinedByString:@"/"]; - } - - -} - -- (BOOL)valueForKeyIsNumber:(NSDictionary*)dict key:(NSString*)key -{ - BOOL bNumber = NO; - NSObject* value = dict[key]; - if (value) { - bNumber = [value isKindOfClass:[NSNumber class]]; - } - return bNumber; -} - -- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString *)requestedPath options:(NSDictionary *)options -{ - CDVPluginResult* result = nil; - BOOL bDirRequest = NO; - BOOL create = NO; - BOOL exclusive = NO; - int errorCode = 0; // !!! risky - no error code currently defined for 0 - - if ([self valueForKeyIsNumber:options key:@"create"]) { - create = [(NSNumber*)[options valueForKey:@"create"] boolValue]; - } - if ([self valueForKeyIsNumber:options key:@"exclusive"]) { - exclusive = [(NSNumber*)[options valueForKey:@"exclusive"] boolValue]; - } - if ([self valueForKeyIsNumber:options key:@"getDir"]) { - // this will not exist for calls directly to getFile but will have been set by getDirectory before calling this method - bDirRequest = [(NSNumber*)[options valueForKey:@"getDir"] boolValue]; - } - // see if the requested path has invalid characters - should we be checking for more than just ":"? - if ([requestedPath rangeOfString:@":"].location != NSNotFound) { - errorCode = ENCODING_ERR; - } else { - // Build new fullPath for the requested resource. - // We concatenate the two paths together, and then scan the resulting string to remove - // parent ("..") references. Any parent references at the beginning of the string are - // silently removed. - NSString *combinedPath = [baseURI.fullPath stringByAppendingPathComponent:requestedPath]; - combinedPath = [self normalizePath:combinedPath]; - CDVFilesystemURL* requestedURL = [self URLforFullPath:combinedPath]; - - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - BOOL bIsDir; - BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:requestedURL] isDirectory:&bIsDir]; - if (bExists && (create == NO) && (bIsDir == !bDirRequest)) { - // path exists and is not of requested type - return TYPE_MISMATCH_ERR - errorCode = TYPE_MISMATCH_ERR; - } else if (!bExists && (create == NO)) { - // path does not exist and create is false - return NOT_FOUND_ERR - errorCode = NOT_FOUND_ERR; - } else if (bExists && (create == YES) && (exclusive == YES)) { - // file/dir already exists and exclusive and create are both true - return PATH_EXISTS_ERR - errorCode = PATH_EXISTS_ERR; - } else { - // if bExists and create == YES - just return data - // if bExists and create == NO - just return data - // if !bExists and create == YES - create and return data - BOOL bSuccess = YES; - NSError __autoreleasing* pError = nil; - if (!bExists && (create == YES)) { - if (bDirRequest) { - // create the dir - bSuccess = [fileMgr createDirectoryAtPath:[self filesystemPathForURL:requestedURL] withIntermediateDirectories:NO attributes:nil error:&pError]; - } else { - // create the empty file - bSuccess = [fileMgr createFileAtPath:[self filesystemPathForURL:requestedURL] contents:nil attributes:nil]; - } - } - if (!bSuccess) { - errorCode = ABORT_ERR; - if (pError) { - NSLog(@"error creating directory: %@", [pError localizedDescription]); - } - } else { - // NSLog(@"newly created file/dir (%@) exists: %d", reqFullPath, [fileMgr fileExistsAtPath:reqFullPath]); - // file existed or was created - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self makeEntryForPath:requestedURL.fullPath isDirectory:bDirRequest]]; - } - } // are all possible conditions met? - } - - if (errorCode > 0) { - // create error callback - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - return result; - -} - -- (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI -{ - CDVPluginResult* result = nil; - CDVFilesystemURL *newURI = nil; - if ([localURI.fullPath isEqualToString:@""]) { - // return self - newURI = localURI; - } else { - newURI = [CDVFilesystemURL fileSystemURLWithURL:[localURI.url URLByDeletingLastPathComponent]]; /* TODO: UGLY - FIX */ - } - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - BOOL bIsDir; - BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:newURI] isDirectory:&bIsDir]; - if (bExists) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self makeEntryForPath:newURI.fullPath isDirectory:bIsDir]]; - } else { - // invalid path or file does not exist - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; - } - return result; -} - -- (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary *)options -{ - BOOL ok = NO; - - NSString* filePath = [self filesystemPathForURL:localURI]; - // we only care about this iCloud key for now. - // set to 1/true to skip backup, set to 0/false to back it up (effectively removing the attribute) - NSString* iCloudBackupExtendedAttributeKey = @"com.apple.MobileBackup"; - id iCloudBackupExtendedAttributeValue = [options objectForKey:iCloudBackupExtendedAttributeKey]; - - if ((iCloudBackupExtendedAttributeValue != nil) && [iCloudBackupExtendedAttributeValue isKindOfClass:[NSNumber class]]) { - if (IsAtLeastiOSVersion(@"5.1")) { - NSURL* url = [NSURL fileURLWithPath:filePath]; - NSError* __autoreleasing error = nil; - - ok = [url setResourceValue:[NSNumber numberWithBool:[iCloudBackupExtendedAttributeValue boolValue]] forKey:NSURLIsExcludedFromBackupKey error:&error]; - } else { // below 5.1 (deprecated - only really supported in 5.01) - u_int8_t value = [iCloudBackupExtendedAttributeValue intValue]; - if (value == 0) { // remove the attribute (allow backup, the default) - ok = (removexattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], 0) == 0); - } else { // set the attribute (skip backup) - ok = (setxattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], &value, sizeof(value), 0, 0) == 0); - } - } - } - - if (ok) { - return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else { - return [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; - } -} - -/* remove the file or directory (recursively) - * IN: - * NSString* fullPath - the full path to the file or directory to be removed - * NSString* callbackId - * called from remove and removeRecursively - check all pubic api specific error conditions (dir not empty, etc) before calling - */ - -- (CDVPluginResult*)doRemove:(NSString*)fullPath -{ - CDVPluginResult* result = nil; - BOOL bSuccess = NO; - NSError* __autoreleasing pError = nil; - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - - @try { - bSuccess = [fileMgr removeItemAtPath:fullPath error:&pError]; - if (bSuccess) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else { - // see if we can give a useful error - CDVFileError errorCode = ABORT_ERR; - NSLog(@"error removing filesystem entry at %@: %@", fullPath, [pError localizedDescription]); - if ([pError code] == NSFileNoSuchFileError) { - errorCode = NOT_FOUND_ERR; - } else if ([pError code] == NSFileWriteNoPermissionError) { - errorCode = NO_MODIFICATION_ALLOWED_ERR; - } - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - } @catch(NSException* e) { // NSInvalidArgumentException if path is . or .. - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:SYNTAX_ERR]; - } - - return result; -} - -- (CDVPluginResult *)removeFileAtURL:(CDVFilesystemURL *)localURI -{ - NSString *fileSystemPath = [self filesystemPathForURL:localURI]; - - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - BOOL bIsDir = NO; - BOOL bExists = [fileMgr fileExistsAtPath:fileSystemPath isDirectory:&bIsDir]; - if (!bExists) { - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; - } - if (bIsDir && ([[fileMgr contentsOfDirectoryAtPath:fileSystemPath error:nil] count] != 0)) { - // dir is not empty - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:INVALID_MODIFICATION_ERR]; - } - return [self doRemove:fileSystemPath]; -} - -- (CDVPluginResult *)recursiveRemoveFileAtURL:(CDVFilesystemURL *)localURI -{ - NSString *fileSystemPath = [self filesystemPathForURL:localURI]; - return [self doRemove:fileSystemPath]; -} - -/* - * IN - * NSString localURI - * OUT - * NSString full local filesystem path for the represented file or directory, or nil if no such path is possible - * The file or directory does not necessarily have to exist. nil is returned if the filesystem type is not recognized, - * or if the URL is malformed. - * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding is expected). - */ -- (NSString *)fullPathForFileSystemPath:(NSString *)fsPath -{ - if ([fsPath hasPrefix:self.fsRoot]) { - return [fsPath substringFromIndex:[self.fsRoot length]]; - } - return nil; -} - - -- (CDVPluginResult *)readEntriesAtURL:(CDVFilesystemURL *)localURI -{ - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - NSError* __autoreleasing error = nil; - NSString *fileSystemPath = [self filesystemPathForURL:localURI]; - - NSArray* contents = [fileMgr contentsOfDirectoryAtPath:fileSystemPath error:&error]; - - if (contents) { - NSMutableArray* entries = [NSMutableArray arrayWithCapacity:1]; - if ([contents count] > 0) { - // create an Entry (as JSON) for each file/dir - for (NSString* name in contents) { - // see if is dir or file - NSString* entryPath = [fileSystemPath stringByAppendingPathComponent:name]; - BOOL bIsDir = NO; - [fileMgr fileExistsAtPath:entryPath isDirectory:&bIsDir]; - NSDictionary* entryDict = [self makeEntryForPath:[self fullPathForFileSystemPath:entryPath] isDirectory:bIsDir]; - [entries addObject:entryDict]; - } - } - return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:entries]; - } else { - // assume not found but could check error for more specific error conditions - return [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; - } -} - -- (unsigned long long)truncateFile:(NSString*)filePath atPosition:(unsigned long long)pos -{ - unsigned long long newPos = 0UL; - - NSFileHandle* file = [NSFileHandle fileHandleForWritingAtPath:filePath]; - - if (file) { - [file truncateFileAtOffset:(unsigned long long)pos]; - newPos = [file offsetInFile]; - [file synchronizeFile]; - [file closeFile]; - } - return newPos; -} - -- (CDVPluginResult *)truncateFileAtURL:(CDVFilesystemURL *)localURI atPosition:(unsigned long long)pos -{ - unsigned long long newPos = [self truncateFile:[self filesystemPathForURL:localURI] atPosition:pos]; - return [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)newPos]; -} - -- (CDVPluginResult *)writeToFileAtURL:(CDVFilesystemURL *)localURL withData:(NSData*)encData append:(BOOL)shouldAppend -{ - NSString *filePath = [self filesystemPathForURL:localURL]; - - CDVPluginResult* result = nil; - CDVFileError errCode = INVALID_MODIFICATION_ERR; - int bytesWritten = 0; - - if (filePath) { - NSOutputStream* fileStream = [NSOutputStream outputStreamToFileAtPath:filePath append:shouldAppend]; - if (fileStream) { - NSUInteger len = [encData length]; - if (len == 0) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:(double)len]; - } else { - [fileStream open]; - - bytesWritten = (int)[fileStream write:[encData bytes] maxLength:len]; - - [fileStream close]; - if (bytesWritten > 0) { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:bytesWritten]; - // } else { - // can probably get more detailed error info via [fileStream streamError] - // errCode already set to INVALID_MODIFICATION_ERR; - // bytesWritten = 0; // may be set to -1 on error - } - } - } // else fileStream not created return INVALID_MODIFICATION_ERR - } else { - // invalid filePath - errCode = NOT_FOUND_ERR; - } - if (!result) { - // was an error - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode]; - } - return result; -} - -/** - * Helper function to check to see if the user attempted to copy an entry into its parent without changing its name, - * or attempted to copy a directory into a directory that it contains directly or indirectly. - * - * IN: - * NSString* srcDir - * NSString* destinationDir - * OUT: - * YES copy/ move is allows - * NO move is onto itself - */ -- (BOOL)canCopyMoveSrc:(NSString*)src ToDestination:(NSString*)dest -{ - // This weird test is to determine if we are copying or moving a directory into itself. - // Copy /Documents/myDir to /Documents/myDir-backup is okay but - // Copy /Documents/myDir to /Documents/myDir/backup not okay - BOOL copyOK = YES; - NSRange range = [dest rangeOfString:src]; - - if (range.location != NSNotFound) { - NSRange testRange = {range.length - 1, ([dest length] - range.length)}; - NSRange resultRange = [dest rangeOfString:@"/" options:0 range:testRange]; - if (resultRange.location != NSNotFound) { - copyOK = NO; - } - } - return copyOK; -} - -- (void)copyFileToURL:(CDVFilesystemURL *)destURL withName:(NSString *)newName fromFileSystem:(NSObject<CDVFileSystem> *)srcFs atURL:(CDVFilesystemURL *)srcURL copy:(BOOL)bCopy callback:(void (^)(CDVPluginResult *))callback -{ - NSFileManager *fileMgr = [[NSFileManager alloc] init]; - NSString *destRootPath = [self filesystemPathForURL:destURL]; - BOOL bDestIsDir = NO; - BOOL bDestExists = [fileMgr fileExistsAtPath:destRootPath isDirectory:&bDestIsDir]; - - NSString *newFileSystemPath = [destRootPath stringByAppendingPathComponent:newName]; - NSString *newFullPath = [self fullPathForFileSystemPath:newFileSystemPath]; - - BOOL bNewIsDir = NO; - BOOL bNewExists = [fileMgr fileExistsAtPath:newFileSystemPath isDirectory:&bNewIsDir]; - - CDVPluginResult *result = nil; - int errCode = 0; - - if (!bDestExists) { - // the destination root does not exist - errCode = NOT_FOUND_ERR; - } - - else if ([srcFs isKindOfClass:[CDVLocalFilesystem class]]) { - /* Same FS, we can shortcut with NSFileManager operations */ - NSString *srcFullPath = [srcFs filesystemPathForURL:srcURL]; - - BOOL bSrcIsDir = NO; - BOOL bSrcExists = [fileMgr fileExistsAtPath:srcFullPath isDirectory:&bSrcIsDir]; - - if (!bSrcExists) { - // the source does not exist - errCode = NOT_FOUND_ERR; - } else if ([newFileSystemPath isEqualToString:srcFullPath]) { - // source and destination can not be the same - errCode = INVALID_MODIFICATION_ERR; - } else if (bSrcIsDir && (bNewExists && !bNewIsDir)) { - // can't copy/move dir to file - errCode = INVALID_MODIFICATION_ERR; - } else { // no errors yet - NSError* __autoreleasing error = nil; - BOOL bSuccess = NO; - if (bCopy) { - if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFileSystemPath]) { - // can't copy dir into self - errCode = INVALID_MODIFICATION_ERR; - } else if (bNewExists) { - // the full destination should NOT already exist if a copy - errCode = PATH_EXISTS_ERR; - } else { - bSuccess = [fileMgr copyItemAtPath:srcFullPath toPath:newFileSystemPath error:&error]; - } - } else { // move - // iOS requires that destination must not exist before calling moveTo - // is W3C INVALID_MODIFICATION_ERR error if destination dir exists and has contents - // - if (!bSrcIsDir && (bNewExists && bNewIsDir)) { - // can't move a file to directory - errCode = INVALID_MODIFICATION_ERR; - } else if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFileSystemPath]) { - // can't move a dir into itself - errCode = INVALID_MODIFICATION_ERR; - } else if (bNewExists) { - if (bNewIsDir && ([[fileMgr contentsOfDirectoryAtPath:newFileSystemPath error:NULL] count] != 0)) { - // can't move dir to a dir that is not empty - errCode = INVALID_MODIFICATION_ERR; - newFileSystemPath = nil; // so we won't try to move - } else { - // remove destination so can perform the moveItemAtPath - bSuccess = [fileMgr removeItemAtPath:newFileSystemPath error:NULL]; - if (!bSuccess) { - errCode = INVALID_MODIFICATION_ERR; // is this the correct error? - newFileSystemPath = nil; - } - } - } else if (bNewIsDir && [newFileSystemPath hasPrefix:srcFullPath]) { - // can't move a directory inside itself or to any child at any depth; - errCode = INVALID_MODIFICATION_ERR; - newFileSystemPath = nil; - } - - if (newFileSystemPath != nil) { - bSuccess = [fileMgr moveItemAtPath:srcFullPath toPath:newFileSystemPath error:&error]; - } - } - if (bSuccess) { - // should verify it is there and of the correct type??? - NSDictionary* newEntry = [self makeEntryForPath:newFullPath isDirectory:bSrcIsDir]; - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry]; - } else { - if (error) { - if (([error code] == NSFileReadUnknownError) || ([error code] == NSFileReadTooLargeError)) { - errCode = NOT_READABLE_ERR; - } else if ([error code] == NSFileWriteOutOfSpaceError) { - errCode = QUOTA_EXCEEDED_ERR; - } else if ([error code] == NSFileWriteNoPermissionError) { - errCode = NO_MODIFICATION_ALLOWED_ERR; - } - } - } - } - } else { - // Need to copy the hard way - [srcFs readFileAtURL:srcURL start:0 end:-1 callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) { - CDVPluginResult* result = nil; - if (data != nil) { - BOOL bSuccess = [data writeToFile:newFileSystemPath atomically:YES]; - if (bSuccess) { - // should verify it is there and of the correct type??? - NSDictionary* newEntry = [self makeEntryForPath:newFullPath isDirectory:NO]; - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry]; - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ABORT_ERR]; - } - } else { - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; - } - callback(result); - }]; - return; // Async IO; return without callback. - } - if (result == nil) { - if (!errCode) { - errCode = INVALID_MODIFICATION_ERR; // Catch-all default - } - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errCode]; - } - callback(result); -} - -/* helper function to get the mimeType from the file extension - * IN: - * NSString* fullPath - filename (may include path) - * OUT: - * NSString* the mime type as type/subtype. nil if not able to determine - */ -+ (NSString*)getMimeTypeFromPath:(NSString*)fullPath -{ - NSString* mimeType = nil; - - if (fullPath) { - CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL); - if (typeId) { - mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType); - if (!mimeType) { - // special case for m4a - if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) { - mimeType = @"audio/mp4"; - } else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) { - mimeType = @"audio/wav"; - } else if ([[fullPath pathExtension] rangeOfString:@"css"].location != NSNotFound) { - mimeType = @"text/css"; - } - } - CFRelease(typeId); - } - } - return mimeType; -} - -- (void)readFileAtURL:(CDVFilesystemURL *)localURL start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback -{ - NSString *path = [self filesystemPathForURL:localURL]; - - NSString* mimeType = [CDVLocalFilesystem getMimeTypeFromPath:path]; - if (mimeType == nil) { - mimeType = @"*/*"; - } - NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:path]; - if (start > 0) { - [file seekToFileOffset:start]; - } - - NSData* readData; - if (end < 0) { - readData = [file readDataToEndOfFile]; - } else { - readData = [file readDataOfLength:(end - start)]; - } - [file closeFile]; - - callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR); -} - -- (void)getFileMetadataForURL:(CDVFilesystemURL *)localURL callback:(void (^)(CDVPluginResult *))callback -{ - NSString *path = [self filesystemPathForURL:localURL]; - CDVPluginResult *result; - NSFileManager* fileMgr = [[NSFileManager alloc] init]; - - NSError* __autoreleasing error = nil; - NSDictionary* fileAttrs = [fileMgr attributesOfItemAtPath:path error:&error]; - - if (fileAttrs) { - - // create dictionary of file info - NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5]; - - [fileInfo setObject:localURL.fullPath forKey:@"fullPath"]; - [fileInfo setObject:@"" forKey:@"type"]; // can't easily get the mimetype unless create URL, send request and read response so skipping - [fileInfo setObject:[path lastPathComponent] forKey:@"name"]; - - // Ensure that directories (and other non-regular files) report size of 0 - unsigned long long size = ([fileAttrs fileType] == NSFileTypeRegular ? [fileAttrs fileSize] : 0); - [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:size] forKey:@"size"]; - - NSDate* modDate = [fileAttrs fileModificationDate]; - if (modDate) { - [fileInfo setObject:[NSNumber numberWithDouble:[modDate timeIntervalSince1970] * 1000] forKey:@"lastModifiedDate"]; - } - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo]; - - } else { - // didn't get fileAttribs - CDVFileError errorCode = ABORT_ERR; - NSLog(@"error getting metadata: %@", [error localizedDescription]); - if ([error code] == NSFileNoSuchFileError || [error code] == NSFileReadNoSuchFileError) { - errorCode = NOT_FOUND_ERR; - } - // log [NSNumber numberWithDouble: theMessage] objCtype to see what it returns - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode]; - } - - callback(result); -} - -@end diff --git a/plugins/cordova-plugin-file/src/ubuntu/file.cpp b/plugins/cordova-plugin-file/src/ubuntu/file.cpp deleted file mode 100644 index 395ab2dd..00000000 --- a/plugins/cordova-plugin-file/src/ubuntu/file.cpp +++ /dev/null @@ -1,912 +0,0 @@ -/* - * Licensed 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 "file.h" - -#include <QApplication> - -namespace { - class FileError { - public: - static const QString kEncodingErr; - static const QString kTypeMismatchErr; - static const QString kNotFoundErr; - static const QString kSecurityErr; - static const QString kAbortErr; - static const QString kNotReadableErr; - static const QString kNoModificationAllowedErr; - static const QString kInvalidStateErr; - static const QString kSyntaxErr; - static const QString kInvalidModificationErr; - static const QString kQuotaExceededErr; - static const QString kPathExistsErr; - }; - - bool checkFileName(const QString &name) { - if (name.contains(":")){ - return false; - } - return true; - } -}; - -const QString FileError::kEncodingErr("FileError.ENCODING_ERR"); -const QString FileError::kTypeMismatchErr("FileError.TYPE_MISMATCH_ERR"); -const QString FileError::kNotFoundErr("FileError.NOT_FOUND_ERR"); -const QString FileError::kSecurityErr("FileError.SECURITY_ERR"); -const QString FileError::kAbortErr("FileError.ABORT_ERR"); -const QString FileError::kNotReadableErr("FileError.NOT_READABLE_ERR"); -const QString FileError::kNoModificationAllowedErr("FileError.NO_MODIFICATION_ALLOWED_ERR"); -const QString FileError::kInvalidStateErr("FileError.INVALID_STATE_ERR"); -const QString FileError::kSyntaxErr("FileError.SYNTAX_ERR"); -const QString FileError::kInvalidModificationErr("FileError.INVALID_MODIFICATION_ERR"); -const QString FileError::kQuotaExceededErr("FileError.QUOTA_EXCEEDED_ERR"); -const QString FileError::kPathExistsErr("FileError.PATH_EXISTS_ERR"); - -File::File(Cordova *cordova) : - CPlugin(cordova), - _persistentDir(QString("%1/.local/share/%2/persistent").arg(QDir::homePath()).arg(QCoreApplication::applicationName())) { - QDir::root().mkpath(_persistentDir.absolutePath()); -} - -QVariantMap File::file2map(const QFileInfo &fileInfo) { - QVariantMap res; - - res.insert("name", fileInfo.fileName()); - QPair<QString, QString> r = GetRelativePath(fileInfo); - res.insert("fullPath", QString("/") + r.second); - res.insert("filesystemName", r.first); - - res.insert("nativeURL", QString("file://localhost") + fileInfo.absoluteFilePath()); - res.insert("isDirectory", (int)fileInfo.isDir()); - res.insert("isFile", (int)fileInfo.isFile()); - - return res; -} - -QVariantMap File::dir2map(const QDir &dir) { - return file2map(QFileInfo(dir.absolutePath())); -} - -QPair<QString, QString> File::GetRelativePath(const QFileInfo &fileInfo) { - QString fullPath = fileInfo.isDir() ? QDir::cleanPath(fileInfo.absoluteFilePath()) : fileInfo.absoluteFilePath(); - - QString relativePath1 = _persistentDir.relativeFilePath(fullPath); - QString relativePath2 = QDir::temp().relativeFilePath(fullPath); - - if (!(relativePath1[0] != '.' || relativePath2[0] != '.')) { - if (relativePath1.size() > relativePath2.size()) { - return QPair<QString, QString>("temporary", relativePath2); - } else { - return QPair<QString, QString>("persistent", relativePath1); - } - } - - if (relativePath1[0] != '.') - return QPair<QString, QString>("persistent", relativePath1); - return QPair<QString, QString>("temporary", relativePath2); -} - -void File::requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size) { - QDir dir; - - if (size >= 1000485760){ - this->callback(ecId, FileError::kQuotaExceededErr); - return; - } - - if (type == 0) - dir = QDir::temp(); - else - dir = _persistentDir; - - if (type > 1) { - this->callback(ecId, FileError::kSyntaxErr); - return; - } else { - QVariantMap res; - res.insert("root", dir2map(dir)); - if (type == 0) - res.insert("name", "temporary"); - else - res.insert("name", "persistent"); - - this->cb(scId, res); - } -} - -QPair<bool, QFileInfo> File::resolveURI(int ecId, const QString &uri) { - QPair<bool, QFileInfo> result; - - result.first = false; - - QUrl url = QUrl::fromUserInput(uri); - - if (url.scheme() == "file" && url.isValid()) { - result.first = true; - result.second = QFileInfo(url.path()); - return result; - } - - if (url.scheme() != "cdvfile") { - if (ecId) - this->callback(ecId, FileError::kTypeMismatchErr); - return result; - } - - QString path = url.path().replace("//", "/"); - //NOTE: colon is not safe in url, it is not a valid path in Win and Mac, simple disable it here. - if (path.contains(":") || !url.isValid()){ - if (ecId) - this->callback(ecId, FileError::kEncodingErr); - return result; - } - if (!path.startsWith("/persistent/") && !path.startsWith("/temporary/")) { - if (ecId) - this->callback(ecId, FileError::kEncodingErr); - return result; - } - - result.first = true; - if (path.startsWith("/persistent/")) { - QString relativePath = path.mid(QString("/persistent/").size()); - result.second = QFileInfo(_persistentDir.filePath(relativePath)); - } else { - QString relativePath = path.mid(QString("/temporary/").size()); - result.second = QFileInfo(QDir::temp().filePath(relativePath)); - } - return result; -} - -QPair<bool, QFileInfo> File::resolveURI(const QString &uri) { - return resolveURI(0, uri); -} - - -void File::_getLocalFilesystemPath(int scId, int ecId, const QString& uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - this->cb(scId, f1.second.absoluteFilePath()); -} - -void File::resolveLocalFileSystemURI(int scId, int ecId, const QString &uri) { - if (uri[0] == '/' || uri[0] == '.') { - this->callback(ecId, FileError::kEncodingErr); - return; - } - - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFileInfo fileInfo = f1.second; - if (!fileInfo.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - this->cb(scId, file2map(fileInfo)); -} - -void File::getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, parentPath + "/" + rpath); - if (!f1.first) - return; - - bool create = options.value("create").toBool(); - bool exclusive = options.value("exclusive").toBool(); - QFile file(f1.second.absoluteFilePath()); - - // if create is false and the path represents a directory, return error - QFileInfo fileInfo = f1.second; - if ((!create) && fileInfo.isDir()) { - this->callback(ecId, FileError::kTypeMismatchErr); - return; - } - - // if file does exist, and create is true and exclusive is true, return error - if (file.exists()) { - if (create && exclusive) { - this->callback(ecId, FileError::kPathExistsErr); - return; - } - } - else { - // if file does not exist and create is false, return error - if (!create) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - file.open(QIODevice::WriteOnly); - file.close(); - - // Check if creation was successfull - if (!file.exists()) { - this->callback(ecId, FileError::kNoModificationAllowedErr); - return; - } - } - - this->cb(scId, file2map(QFileInfo(file))); -} - -void File::getDirectory(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, parentPath + "/" + rpath); - if (!f1.first) - return; - - bool create = options.value("create").toBool(); - bool exclusive = options.value("exclusive").toBool(); - QDir dir(f1.second.absoluteFilePath()); - - QFileInfo &fileInfo = f1.second; - if ((!create) && fileInfo.isFile()) { - this->callback(ecId, FileError::kTypeMismatchErr); - return; - } - - if (dir.exists()) { - if (create && exclusive) { - this->callback(ecId, FileError::kPathExistsErr); - return; - } - } - else { - if (!create) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - QString folderName = dir.dirName(); - dir.cdUp(); - dir.mkdir(folderName); - dir.cd(folderName); - - if (!dir.exists()) { - this->callback(ecId, FileError::kNoModificationAllowedErr); - return; - } - } - - this->cb(scId, dir2map(dir)); -} - -void File::removeRecursively(int scId, int ecId, const QString &uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QDir dir(f1.second.absoluteFilePath()); - if (File::rmDir(dir)) - this->cb(scId); - else - this->callback(ecId, FileError::kNoModificationAllowedErr); -} - -void File::write(int scId, int ecId, const QString &uri, const QString &_data, unsigned long long position, bool binary) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFile file(f1.second.absoluteFilePath()); - - file.open(QIODevice::WriteOnly); - file.close(); - - if (!file.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - QFileInfo fileInfo(file); - if (!file.open(QIODevice::ReadWrite)) { - this->callback(ecId, FileError::kNoModificationAllowedErr); - return; - } - - if (!binary) { - QTextStream textStream(&file); - textStream.setCodec("UTF-8"); - textStream.setAutoDetectUnicode(true); - - if (!textStream.seek(position)) { - file.close(); - fileInfo.refresh(); - - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - textStream << _data; - textStream.flush(); - } else { - QByteArray data(_data.toUtf8()); - if (!file.seek(position)) { - file.close(); - fileInfo.refresh(); - - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - file.write(data.data(), data.length()); - } - - file.flush(); - file.close(); - fileInfo.refresh(); - - this->cb(scId, fileInfo.size() - position); -} - -void File::truncate(int scId, int ecId, const QString &uri, unsigned long long size) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFile file(f1.second.absoluteFilePath()); - - if (!file.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - if (!file.resize(size)) { - this->callback(ecId, FileError::kNoModificationAllowedErr); - return; - } - - this->cb(scId, size); -} - -void File::getParent(int scId, int ecId, const QString &uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - QDir dir(f1.second.absoluteFilePath()); - - //can't cdup more than app's root - // Try to change into upper directory - if (dir != _persistentDir && dir != QDir::temp()){ - if (!dir.cdUp()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - } - this->cb(scId, dir2map(dir)); -} - -void File::remove(int scId, int ecId, const QString &uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - if (!f1.first) - return; - - QFileInfo &fileInfo = f1.second; - //TODO: fix - if (!fileInfo.exists() || (fileInfo.absoluteFilePath() == _persistentDir.absolutePath()) || (QDir::temp() == fileInfo.absoluteFilePath())) { - this->callback(ecId, FileError::kNoModificationAllowedErr); - return; - } - - if (fileInfo.isDir()) { - QDir dir(fileInfo.absoluteFilePath()); - if (dir.rmdir(dir.absolutePath())) { - this->cb(scId); - return; - } - } else { - QFile file(fileInfo.absoluteFilePath()); - if (file.remove()) { - this->cb(scId); - return; - } - } - - this->callback(ecId, FileError::kInvalidModificationErr); -} - -void File::getFileMetadata(int scId, int ecId, const QString &uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - QFileInfo &fileInfo = f1.second; - - if (!fileInfo.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - } else { - QMimeType mime = _db.mimeTypeForFile(fileInfo.fileName()); - - QString args = QString("{name: %1, fullPath: %2, type: %3, lastModifiedDate: new Date(%4), size: %5}") - .arg(CordovaInternal::format(fileInfo.fileName())).arg(CordovaInternal::format(fileInfo.absoluteFilePath())) - .arg(CordovaInternal::format(mime.name())).arg(fileInfo.lastModified().toMSecsSinceEpoch()) - .arg(fileInfo.size()); - - this->callback(scId, args); - } -} - -void File::getMetadata(int scId, int ecId, const QString &uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - QFileInfo &fileInfo = f1.second; - - if (!fileInfo.exists()) - this->callback(ecId, FileError::kNotFoundErr); - else { - QVariantMap obj; - obj.insert("modificationTime", fileInfo.lastModified().toMSecsSinceEpoch()); - obj.insert("size", fileInfo.isDir() ? 0 : fileInfo.size()); - this->cb(scId, obj); - } -} - -void File::readEntries(int scId, int ecId, const QString &uri) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - QDir dir(f1.second.absoluteFilePath()); - QString entriesList; - - if (!dir.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - for (const QFileInfo &fileInfo: dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) { - entriesList += CordovaInternal::format(file2map(fileInfo)) + ","; - } - // Remove trailing comma - if (entriesList.size() > 0) - entriesList.remove(entriesList.size() - 1, 1); - - entriesList = "new Array(" + entriesList + ")"; - - this->callback(scId, entriesList); -} - -void File::readAsText(int scId, int ecId, const QString &uri, const QString &/*encoding*/, int sliceStart, int sliceEnd) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFile file(f1.second.absoluteFilePath()); - - if (!file.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - if (!file.open(QIODevice::ReadOnly)) { - this->callback(ecId, FileError::kNotReadableErr); - return; - } - - QByteArray content = file.readAll(); - - if (sliceEnd == -1) - sliceEnd = content.size(); - if (sliceEnd < 0) { - sliceEnd++; - sliceEnd = std::max(0, content.size() + sliceEnd); - } - if (sliceEnd > content.size()) - sliceEnd = content.size(); - - if (sliceStart < 0) - sliceStart = std::max(0, content.size() + sliceStart); - if (sliceStart > content.size()) - sliceStart = content.size(); - - if (sliceStart > sliceEnd) - sliceEnd = sliceStart; - - //FIXME: encoding - content = content.mid(sliceStart, sliceEnd - sliceStart); - - this->cb(scId, content); -} - -void File::readAsArrayBuffer(int scId, int ecId, const QString &uri, int sliceStart, int sliceEnd) { - const QString str2array("\ - (function strToArray(str) { \ - var res = new Uint8Array(str.length); \ - for (var i = 0; i < str.length; i++) { \ - res[i] = str.charCodeAt(i); \ - } \ - return res; \ - })(\"%1\")"); - - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFile file(f1.second.absoluteFilePath()); - - if (!file.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - if (!file.open(QIODevice::ReadOnly)) { - this->callback(ecId, FileError::kNotReadableErr); - return; - } - QString res; - QByteArray content = file.readAll(); - - if (sliceEnd == -1) - sliceEnd = content.size(); - if (sliceEnd < 0) { - sliceEnd++; - sliceEnd = std::max(0, content.size() + sliceEnd); - } - if (sliceEnd > content.size()) - sliceEnd = content.size(); - - if (sliceStart < 0) - sliceStart = std::max(0, content.size() + sliceStart); - if (sliceStart > content.size()) - sliceStart = content.size(); - - if (sliceStart > sliceEnd) - sliceEnd = sliceStart; - - content = content.mid(sliceStart, sliceEnd - sliceStart); - - res.reserve(content.length() * 6); - for (uchar c: content) { - res += "\\x"; - res += QString::number(c, 16).rightJustified(2, '0').toUpper(); - } - - this->callback(scId, str2array.arg(res)); -} - -void File::readAsBinaryString(int scId, int ecId, const QString &uri, int sliceStart, int sliceEnd) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFile file(f1.second.absoluteFilePath()); - - if (!file.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - if (!file.open(QIODevice::ReadOnly)) { - this->callback(ecId, FileError::kNotReadableErr); - return; - } - QString res; - QByteArray content = file.readAll(); - - if (sliceEnd == -1) - sliceEnd = content.size(); - if (sliceEnd < 0) { - sliceEnd++; - sliceEnd = std::max(0, content.size() + sliceEnd); - } - if (sliceEnd > content.size()) - sliceEnd = content.size(); - - if (sliceStart < 0) - sliceStart = std::max(0, content.size() + sliceStart); - if (sliceStart > content.size()) - sliceStart = content.size(); - - if (sliceStart > sliceEnd) - sliceEnd = sliceStart; - - content = content.mid(sliceStart, sliceEnd - sliceStart); - - res.reserve(content.length() * 6); - for (uchar c: content) { - res += "\\x"; - res += QString::number(c, 16).rightJustified(2, '0').toUpper(); - } - this->callback(scId, "\"" + res + "\""); -} - -void File::readAsDataURL(int scId, int ecId, const QString &uri, int sliceStart, int sliceEnd) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, uri); - - if (!f1.first) - return; - - QFile file(f1.second.absoluteFilePath()); - QFileInfo &fileInfo = f1.second; - - if (!file.exists()) { - this->callback(ecId, FileError::kNotReadableErr); - return; - } - - if (!file.open(QIODevice::ReadOnly)) { - this->callback(ecId, FileError::kNotReadableErr); - return; - } - - QByteArray content = file.readAll(); - QString contentType(_db.mimeTypeForFile(fileInfo.fileName()).name()); - - if (sliceEnd == -1) - sliceEnd = content.size(); - if (sliceEnd < 0) { - sliceEnd++; - sliceEnd = std::max(0, content.size() + sliceEnd); - } - if (sliceEnd > content.size()) - sliceEnd = content.size(); - - if (sliceStart < 0) - sliceStart = std::max(0, content.size() + sliceStart); - if (sliceStart > content.size()) - sliceStart = content.size(); - - if (sliceStart > sliceEnd) - sliceEnd = sliceStart; - - content = content.mid(sliceStart, sliceEnd - sliceStart); - - this->cb(scId, QString("data:%1;base64,").arg(contentType) + content.toBase64()); -} - -bool File::rmDir(const QDir &dir) { - if (dir == _persistentDir || dir == QDir::temp()) {//can't remove root dir - return false; - } - bool result = true; - if (dir.exists()) { - // Iterate over entries and remove them - Q_FOREACH(const QFileInfo &fileInfo, dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) { - if (fileInfo.isDir()) { - result = rmDir(fileInfo.absoluteFilePath()); - } - else { - result = QFile::remove(fileInfo.absoluteFilePath()); - } - - if (!result) { - return result; - } - } - - // Finally remove the current dir - return dir.rmdir(dir.absolutePath()); - } - return result; -} - -bool File::copyFile(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName) { - QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri); - QPair<bool, QFileInfo> sourceFile = resolveURI(ecId, sourceUri); - - if (!destDir.first || !sourceFile.first) - return false; - - if (!checkFileName(newName)) { - this->callback(ecId, FileError::kEncodingErr); - return false; - } - - if (destDir.second.isFile()) { - this->callback(ecId, FileError::kInvalidModificationErr); - return false; - } - - if (!destDir.second.isDir()) { - this->callback(ecId, FileError::kNotFoundErr); - return false; - } - - QFileInfo &fileInfo = sourceFile.second; - QString fileName((newName.isEmpty()) ? fileInfo.fileName() : newName); - QString destinationFile(QDir(destDir.second.absoluteFilePath()).filePath(fileName)); - if (QFile::copy(fileInfo.absoluteFilePath(), destinationFile)){ - this->cb(scId, file2map(QFileInfo(destinationFile))); - return true; - } - this->callback(ecId, FileError::kInvalidModificationErr); - return false; -} - -void File::copyDir(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName) { - QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri); - QPair<bool, QFileInfo> sourceDir = resolveURI(ecId, sourceUri); - - if (!destDir.first || !sourceDir.first) - return; - if (!checkFileName(newName)) { - this->callback(ecId, FileError::kEncodingErr); - return; - } - - QString targetName = ((newName.isEmpty()) ? sourceDir.second.fileName() : newName); - QString target(QDir(destDir.second.absoluteFilePath()).filePath(targetName)); - - if (QFileInfo(target).isFile()){ - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - // check: copy directory into itself - if (QDir(sourceDir.second.absoluteFilePath()).relativeFilePath(target)[0] != '.'){ - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - if (!QDir(target).exists()){ - QDir(destDir.second.absoluteFilePath()).mkdir(target);; - } else{ - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - if (copyFolder(sourceDir.second.absoluteFilePath(), target)){ - this->cb(scId, dir2map(QDir(target))); - return; - } - this->callback(ecId, FileError::kInvalidModificationErr); - return; -} - -void File::copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, source); - - if (!f1.first) - return; - - if (f1.second.isDir()) - copyDir(scId, ecId, source, destinationDir, newName); - else - copyFile(scId, ecId, source, destinationDir, newName); -} - -void File::moveFile(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName) { - QPair<bool, QFileInfo> sourceFile = resolveURI(ecId, sourceUri); - QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri); - - if (!destDir.first || !sourceFile.first) - return; - if (!checkFileName(newName)) { - this->callback(ecId, FileError::kEncodingErr); - return; - } - - QString fileName = ((newName.isEmpty()) ? sourceFile.second.fileName() : newName); - QString target = QDir(destDir.second.absoluteFilePath()).filePath(fileName); - - if (sourceFile.second == QFileInfo(target)) { - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - if (!destDir.second.exists()) { - this->callback(ecId, FileError::kNotFoundErr); - return; - } - if (!destDir.second.isDir()){ - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - if (QFileInfo(target).exists()) { - if (!QFile::remove(target)) { - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - } - - QFile::rename(sourceFile.second.absoluteFilePath(), target); - this->cb(scId, file2map(QFileInfo(target))); -} - -void File::moveDir(int scId, int ecId,const QString& sourceUri, const QString& destinationUri, const QString& newName){ - QPair<bool, QFileInfo> sourceDir = resolveURI(ecId, sourceUri); - QPair<bool, QFileInfo> destDir = resolveURI(ecId, destinationUri); - - if (!destDir.first || !sourceDir.first) - return; - if (!checkFileName(newName)) { - this->callback(ecId, FileError::kEncodingErr); - return; - } - - QString fileName = ((newName.isEmpty()) ? sourceDir.second.fileName() : newName); - QString target = QDir(destDir.second.absoluteFilePath()).filePath(fileName); - - if (!destDir.second.exists()){ - this->callback(ecId, FileError::kNotFoundErr); - return; - } - - if (destDir.second.isFile()){ - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - // check: copy directory into itself - if (QDir(sourceDir.second.absoluteFilePath()).relativeFilePath(target)[0] != '.'){ - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - if (QFileInfo(target).exists() && !QDir(destDir.second.absoluteFilePath()).rmdir(fileName)) { - this->callback(ecId, FileError::kInvalidModificationErr); - return; - } - - if (copyFolder(sourceDir.second.absoluteFilePath(), target)) { - rmDir(sourceDir.second.absoluteFilePath()); - this->cb(scId, file2map(QFileInfo(target))); - } else { - this->callback(ecId, FileError::kNoModificationAllowedErr); - } -} - -void File::moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName) { - QPair<bool, QFileInfo> f1 = resolveURI(ecId, source); - - if (!f1.first) - return; - - if (f1.second.isDir()) - moveDir(scId, ecId, source, destinationDir, newName); - else - moveFile(scId, ecId, source, destinationDir, newName); -} - -bool File::copyFolder(const QString& sourceFolder, const QString& destFolder) { - QDir sourceDir(sourceFolder); - if (!sourceDir.exists()) - return false; - QDir destDir(destFolder); - if (!destDir.exists()){ - destDir.mkdir(destFolder); - } - QStringList files = sourceDir.entryList(QDir::Files); - for (int i = 0; i< files.count(); i++) - { - QString srcName = sourceFolder + "/" + files[i]; - QString destName = destFolder + "/" + files[i]; - QFile::copy(srcName, destName); - } - files.clear(); - files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot); - for (int i = 0; i< files.count(); i++) - { - QString srcName = sourceFolder + "/" + files[i]; - QString destName = destFolder + "/" + files[i]; - copyFolder(srcName, destName); - } - return true; -} diff --git a/plugins/cordova-plugin-file/src/ubuntu/file.h b/plugins/cordova-plugin-file/src/ubuntu/file.h deleted file mode 100644 index de277623..00000000 --- a/plugins/cordova-plugin-file/src/ubuntu/file.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FILEAPI_H_SDASDASDAS -#define FILEAPI_H_SDASDASDAS - -#include <QNetworkReply> -#include <QtCore> - -#include <cplugin.h> -#include <cordova.h> - -class File: public CPlugin { - Q_OBJECT -public: - explicit File(Cordova *cordova); - - virtual const QString fullName() override { - return File::fullID(); - } - - virtual const QString shortName() override { - return "File"; - } - - static const QString fullID() { - return "File"; - } - QPair<bool, QFileInfo> resolveURI(const QString &uri); - QPair<bool, QFileInfo> resolveURI(int ecId, const QString &uri); - QVariantMap file2map(const QFileInfo &dir); - -public slots: - void requestFileSystem(int scId, int ecId, unsigned short type, unsigned long long size); - void resolveLocalFileSystemURI(int scId, int ecId, const QString&); - void getDirectory(int scId, int ecId, const QString&, const QString&, const QVariantMap&); - void getFile(int scId, int ecId, const QString &parentPath, const QString &rpath, const QVariantMap &options); - void readEntries(int scId, int ecId, const QString &uri); - void getParent(int scId, int ecId, const QString &uri); - void copyTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName); - void moveTo(int scId, int ecId, const QString& source, const QString& destinationDir, const QString& newName); - void getFileMetadata(int scId, int ecId, const QString &); - void getMetadata(int scId, int ecId, const QString &); - void remove(int scId, int ecId, const QString &); - void removeRecursively(int scId, int ecId, const QString&); - void write(int scId, int ecId, const QString&, const QString&, unsigned long long position, bool binary); - void readAsText(int scId, int ecId, const QString&, const QString &encoding, int sliceStart, int sliceEnd); - void readAsDataURL(int scId, int ecId, const QString&, int sliceStart, int sliceEnd); - void readAsArrayBuffer(int scId, int ecId, const QString&, int sliceStart, int sliceEnd); - void readAsBinaryString(int scId, int ecId, const QString&, int sliceStart, int sliceEnd); - void truncate(int scId, int ecId, const QString&, unsigned long long size); - - void _getLocalFilesystemPath(int scId, int ecId, const QString&); -private: - void moveFile(int scId, int ecId,const QString&, const QString&, const QString&); - void moveDir(int scId, int ecId,const QString&, const QString&, const QString&); - bool copyFile(int scId, int ecId, const QString&, const QString&, const QString&); - void copyDir(int scId, int ecId, const QString&, const QString&, const QString&); - bool rmDir(const QDir &dir); - bool copyFolder(const QString&, const QString&); - - QPair<QString, QString> GetRelativePath(const QFileInfo &fileInfo); - QVariantMap dir2map(const QDir &dir); - - QMimeDatabase _db; - const QDir _persistentDir; - QNetworkAccessManager _manager; -}; - -#endif diff --git a/plugins/cordova-plugin-file/src/windows/FileProxy.js b/plugins/cordova-plugin-file/src/windows/FileProxy.js deleted file mode 100644 index d1769b7b..00000000 --- a/plugins/cordova-plugin-file/src/windows/FileProxy.js +++ /dev/null @@ -1,1186 +0,0 @@ -/* - * - * 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 cordova = require('cordova'); -var File = require('./File'), - FileError = require('./FileError'), - Flags = require('./Flags'), - FileSystem = require('./FileSystem'), - LocalFileSystem = require('./LocalFileSystem'), - utils = require('cordova/utils'); - -function Entry(isFile, isDirectory, name, fullPath, filesystemName, nativeURL) { - this.isFile = !!isFile; - this.isDirectory = !!isDirectory; - this.name = name || ''; - this.fullPath = fullPath || ''; - this.filesystemName = filesystemName || null; - this.nativeURL = nativeURL || null; -} - -var FileEntry = function(name, fullPath, filesystemName, nativeURL) { - FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath, filesystemName, nativeURL]); -}; - -utils.extend(FileEntry, Entry); - -var DirectoryEntry = function(name, fullPath, filesystemName, nativeURL) { - DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath, filesystemName, nativeURL); -}; - -utils.extend(DirectoryEntry, Entry); - - -var getFolderFromPathAsync = Windows.Storage.StorageFolder.getFolderFromPathAsync; -var getFileFromPathAsync = Windows.Storage.StorageFile.getFileFromPathAsync; - -function writeBytesAsync(storageFile, data, position) { - return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite) - .then(function (output) { - output.seek(position); - var dataWriter = new Windows.Storage.Streams.DataWriter(output); - dataWriter.writeBytes(data); - return dataWriter.storeAsync().then(function (size) { - output.size = position+size; - return dataWriter.flushAsync().then(function() { - output.close(); - return size; - }); - }); - }); -} - -function writeTextAsync(storageFile, data, position) { - return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite) - .then(function (output) { - output.seek(position); - var dataWriter = new Windows.Storage.Streams.DataWriter(output); - dataWriter.writeString(data); - return dataWriter.storeAsync().then(function (size) { - output.size = position+size; - return dataWriter.flushAsync().then(function() { - output.close(); - return size; - }); - }); - }); -} - -function writeBlobAsync(storageFile, data, position) { - return storageFile.openAsync(Windows.Storage.FileAccessMode.readWrite) - .then(function (output) { - output.seek(position); - var dataSize = data.size; - var input = (data.detachStream || data.msDetachStream).call(data); - - // Copy the stream from the blob to the File stream - return Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output) - .then(function () { - output.size = position+dataSize; - return output.flushAsync().then(function () { - input.close(); - output.close(); - - return dataSize; - }); - }); - }); -} - -function writeArrayBufferAsync(storageFile, data, position) { - return writeBlobAsync(storageFile, new Blob([data]), position); -} - -function cordovaPathToNative(path) { - // turn / into \\ - var cleanPath = path.replace(/\//g, '\\'); - // turn \\ into \ - cleanPath = cleanPath.replace(/\\+/g, '\\'); - return cleanPath; -} - -function nativePathToCordova(path) { - var cleanPath = path.replace(/\\/g, '/'); - return cleanPath; -} - -var driveRE = new RegExp("^[/]*([A-Z]:)"); -var invalidNameRE = /[\\?*|"<>:]/; -function validName(name) { - return !invalidNameRE.test(name.replace(driveRE,'')); -} - -function sanitize(path) { - var slashesRE = new RegExp('/{2,}','g'); - var components = path.replace(slashesRE, '/').split(/\/+/); - // Remove double dots, use old school array iteration instead of RegExp - // since it is impossible to debug them - for (var index = 0; index < components.length; ++index) { - if (components[index] === "..") { - components.splice(index, 1); - if (index > 0) { - // if we're not in the start of array then remove preceeding path component, - // In case if relative path points above the root directory, just ignore double dots - // See file.spec.111 should not traverse above above the root directory for test case - components.splice(index-1, 1); - --index; - } - } - } - return components.join('/'); -} - -var WinFS = function(name, root) { - this.winpath = root.winpath; - if (this.winpath && !/\/$/.test(this.winpath)) { - this.winpath += "/"; - } - this.makeNativeURL = function(path) { - return encodeURI(this.root.nativeURL + sanitize(path.replace(':','%3A')));}; - root.fullPath = '/'; - if (!root.nativeURL) - root.nativeURL = 'file://'+sanitize(this.winpath + root.fullPath).replace(':','%3A'); - WinFS.__super__.constructor.call(this, name, root); -}; - -utils.extend(WinFS, FileSystem); - -WinFS.prototype.__format__ = function(fullPath) { - var path = sanitize('/'+this.name+(fullPath[0]==='/'?'':'/')+encodeURI(fullPath)); - return 'cdvfile://localhost' + path; -}; - -var AllFileSystems; - -function getAllFS() { - if (!AllFileSystems) { - var storageFolderPermanent = Windows.Storage.ApplicationData.current.localFolder.path, - storageFolderTemporary = Windows.Storage.ApplicationData.current.temporaryFolder.path; - AllFileSystems = { - 'persistent': - Object.freeze(new WinFS('persistent', { - name: 'persistent', - nativeURL: 'ms-appdata:///local', - winpath: nativePathToCordova(Windows.Storage.ApplicationData.current.localFolder.path) - })), - 'temporary': - Object.freeze(new WinFS('temporary', { - name: 'temporary', - nativeURL: 'ms-appdata:///temp', - winpath: nativePathToCordova(Windows.Storage.ApplicationData.current.temporaryFolder.path) - })), - 'root': - Object.freeze(new WinFS('root', { - name: 'root', - //nativeURL: 'file:///' - winpath: '' - })) - }; - } - return AllFileSystems; -} - -function getFS(name) { - return getAllFS()[name]; -} - -FileSystem.prototype.__format__ = function(fullPath) { - return getFS(this.name).__format__(fullPath); -}; - -require('./fileSystems').getFs = function(name, callback) { - setTimeout(function(){callback(getFS(name));}); -}; - -function getFilesystemFromPath(path) { - var res; - var allfs = getAllFS(); - Object.keys(allfs).some(function(fsn) { - var fs = allfs[fsn]; - if (path.indexOf(fs.winpath) === 0) - res = fs; - return res; - }); - return res; -} - -var msapplhRE = new RegExp('^ms-appdata://localhost/'); -function pathFromURL(url) { - url=url.replace(msapplhRE,'ms-appdata:///'); - var path = decodeURI(url); - // support for file name with parameters - if (/\?/g.test(path)) { - path = String(path).split("?")[0]; - } - if (path.indexOf("file:/")===0) { - if (path.indexOf("file://") !== 0) { - url = "file:///" + url.substr(6); - } - } - - ['file://','ms-appdata:///','cdvfile://localhost/'].every(function(p) { - if (path.indexOf(p)!==0) - return true; - var thirdSlash = path.indexOf("/", p.length); - if (thirdSlash < 0) { - path = ""; - } else { - path = sanitize(path.substr(thirdSlash)); - } - }); - - return path.replace('%3A',':').replace(driveRE,'$1'); -} - -function getFilesystemFromURL(url) { - url=url.replace(msapplhRE,'ms-appdata:///'); - var res; - if (url.indexOf("file:/")===0) - res = getFilesystemFromPath(pathFromURL(url)); - else { - var allfs = getAllFS(); - Object.keys(allfs).every(function(fsn) { - var fs = allfs[fsn]; - if (url.indexOf(fs.root.nativeURL) === 0 || - url.indexOf('cdvfile://localhost/'+fs.name+'/') === 0) - { - res = fs; - return false; - } - return true; - }); - } - return res; -} - -function getFsPathForWinPath(fs, wpath) { - var path = nativePathToCordova(wpath); - if (path.indexOf(fs.winpath) !== 0) - return null; - return path.replace(fs.winpath,'/'); -} - -var WinError = { - invalidArgument: -2147024809, - fileNotFound: -2147024894, - accessDenied: -2147024891 -}; - -function openPath(path, ops) { - ops=ops?ops:{}; - return new WinJS.Promise(function (complete,failed) { - getFileFromPathAsync(path).done( - function(file) { - complete({file:file}); - }, - function(err) { - if (err.number != WinError.fileNotFound && err.number != WinError.invalidArgument) - failed(FileError.NOT_READABLE_ERR); - getFolderFromPathAsync(path) - .done( - function(dir) { - if (!ops.getContent) - complete({folder:dir}); - else - WinJS.Promise.join({ - files:dir.getFilesAsync(), - folders:dir.getFoldersAsync() - }).done( - function(a) { - complete({ - folder:dir, - files:a.files, - folders:a.folders - }); - }, - function(err) { - failed(FileError.NOT_READABLE_ERR); - } - ); - }, - function(err) { - if (err.number == WinError.fileNotFound || err.number == WinError.invalidArgument) - complete({}); - else - failed(FileError.NOT_READABLE_ERR); - } - ); - } - ); - }); -} - -function copyFolder(src,dst,name) { - name = name?name:src.name; - return new WinJS.Promise(function (complete,failed) { - WinJS.Promise.join({ - fld:dst.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists), - files:src.getFilesAsync(), - folders:src.getFoldersAsync() - }).done( - function(the) { - if (!(the.files.length || the.folders.length)) { - complete(); - return; - } - var todo = the.files.length; - var copyfolders = function() { - if (!todo--) { - complete(); - return; - } - copyFolder(the.folders[todo],dst) - .done(function() {copyfolders(); }, failed); - }; - var copyfiles = function() { - if (!todo--) { - todo = the.folders.length; - copyfolders(); - return; - } - the.files[todo].copyAsync(the.fld) - .done(function() {copyfiles(); }, failed); - }; - copyfiles(); - }, - failed - ); - }); -} - -function moveFolder(src,dst,name) { - name = name?name:src.name; - return new WinJS.Promise(function (complete,failed) { - var pending = []; - WinJS.Promise.join({ - fld:dst.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists), - files:src.getFilesAsync(), - folders:src.getFoldersAsync() - }).done( - function(the) { - if (!(the.files.length || the.folders.length)) { - complete(); - return; - } - var todo = the.files.length; - var movefolders = function() { - if (!todo--) { - src.deleteAsync().done(complete,failed); - return; - } - moveFolder(the.folders[todo],dst) - .done(movefolders,failed); - }; - var movefiles = function() { - if (!todo--) { - todo = the.folders.length; - movefolders(); - return; - } - the.files[todo].moveAsync(the.fld) - .done(function() {movefiles(); }, failed); - }; - movefiles(); - }, - failed - ); - }); -} - -function transport(success, fail, args, ops) { // ["fullPath","parent", "newName"] - var src = args[0]; - var parent = args[1]; - var name = args[2]; - - var srcFS = getFilesystemFromURL(src); - var dstFS = getFilesystemFromURL(parent); - var srcPath = pathFromURL(src); - var dstPath = pathFromURL(parent); - if (!(srcFS && dstFS && validName(name))){ - fail(FileError.ENCODING_ERR); - return; - } - - var srcWinPath = cordovaPathToNative(sanitize(srcFS.winpath + srcPath)); - var dstWinPath = cordovaPathToNative(sanitize(dstFS.winpath + dstPath)); - var tgtFsPath = sanitize(dstPath+'/'+name); - var tgtWinPath = cordovaPathToNative(sanitize(dstFS.winpath + dstPath+'/'+name)); - if (srcWinPath == dstWinPath || srcWinPath == tgtWinPath) { - fail(FileError.INVALID_MODIFICATION_ERR); - return; - } - - - WinJS.Promise.join({ - src:openPath(srcWinPath), - dst:openPath(dstWinPath), - tgt:openPath(tgtWinPath,{getContent:true}) - }) - .done( - function (the) { - if ((!the.dst.folder) || !(the.src.folder || the.src.file)) { - fail(FileError.NOT_FOUND_ERR); - return; - } - if ( (the.src.folder && the.tgt.file) - || (the.src.file && the.tgt.folder) - || (the.tgt.folder && (the.tgt.files.length || the.tgt.folders.length))) - { - fail(FileError.INVALID_MODIFICATION_ERR); - return; - } - if (the.src.file) - ops.fileOp(the.src.file,the.dst.folder, name, Windows.Storage.NameCollisionOption.replaceExisting) - .done( - function (storageFile) { - success(new FileEntry( - name, - tgtFsPath, - dstFS.name, - dstFS.makeNativeURL(tgtFsPath) - )); - }, - function (err) { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - else - ops.folderOp(the.src.folder, the.dst.folder, name).done( - function () { - success(new DirectoryEntry( - name, - tgtFsPath, - dstFS.name, - dstFS.makeNativeURL(tgtFsPath) - )); - }, - function() { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - }, - function(err) { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); -} - -module.exports = { - requestAllFileSystems: function() { - return getAllFS(); - }, - getFileMetadata: function (success, fail, args) { - module.exports.getMetadata(success, fail, args); - }, - - getMetadata: function (success, fail, args) { - var fs = getFilesystemFromURL(args[0]); - var path = pathFromURL(args[0]); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - var fullPath = cordovaPathToNative(fs.winpath + path); - - var getMetadataForFile = function (storageFile) { - storageFile.getBasicPropertiesAsync().then( - function (basicProperties) { - success(new File(storageFile.name, storageFile.path, storageFile.fileType, basicProperties.dateModified, basicProperties.size)); - }, function () { - fail(FileError.NOT_READABLE_ERR); - } - ); - }; - - var getMetadataForFolder = function (storageFolder) { - storageFolder.getBasicPropertiesAsync().then( - function (basicProperties) { - var metadata = { - size: basicProperties.size, - lastModifiedDate: basicProperties.dateModified - }; - success(metadata); - }, - function () { - fail(FileError.NOT_READABLE_ERR); - } - ); - }; - - getFileFromPathAsync(fullPath).then(getMetadataForFile, - function () { - getFolderFromPathAsync(fullPath).then(getMetadataForFolder, - function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - } - ); - }, - - getParent: function (win, fail, args) { // ["fullPath"] - var fs = getFilesystemFromURL(args[0]); - var path = pathFromURL(args[0]); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - if (!path || (new RegExp('/[^/]*/?$')).test(path)) { - win(new DirectoryEntry(fs.root.name, fs.root.fullPath, fs.name, fs.makeNativeURL(fs.root.fullPath))); - return; - } - - var parpath = path.replace(new RegExp('/[^/]+/?$','g'),''); - var parname = path.substr(parpath.length); - var fullPath = cordovaPathToNative(fs.winpath + parpath); - - var result = new DirectoryEntry(parname, parpath, fs.name, fs.makeNativeURL(parpath)); - getFolderFromPathAsync(fullPath).done( - function () { win(result); }, - function () { fail(FileError.INVALID_STATE_ERR); } - ); - }, - - readAsText: function (win, fail, args) { - - var url = args[0], - enc = args[1], - startPos = args[2], - endPos = args[3]; - - var fs = getFilesystemFromURL(url); - var path = pathFromURL(url); - if (!fs){ - fail(FileError.ENCODING_ERR); - return; - } - var wpath = cordovaPathToNative(sanitize(fs.winpath + path)); - - var encoding = Windows.Storage.Streams.UnicodeEncoding.utf8; - if (enc == 'Utf16LE' || enc == 'utf16LE') { - encoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE; - } else if (enc == 'Utf16BE' || enc == 'utf16BE') { - encoding = Windows.Storage.Streams.UnicodeEncoding.utf16BE; - } - - getFileFromPathAsync(wpath).then(function(file) { - return file.openReadAsync(); - }).then(function (stream) { - startPos = (startPos < 0) ? Math.max(stream.size + startPos, 0) : Math.min(stream.size, startPos); - endPos = (endPos < 0) ? Math.max(endPos + stream.size, 0) : Math.min(stream.size, endPos); - stream.seek(startPos); - - var readSize = endPos - startPos, - buffer = new Windows.Storage.Streams.Buffer(readSize); - - return stream.readAsync(buffer, readSize, Windows.Storage.Streams.InputStreamOptions.none); - }).done(function(buffer) { - win(Windows.Security.Cryptography.CryptographicBuffer.convertBinaryToString(encoding, buffer)); - },function() { - fail(FileError.NOT_FOUND_ERR); - }); - }, - - readAsBinaryString:function(win,fail,args) { - var url = args[0], - startPos = args[1], - endPos = args[2]; - - var fs = getFilesystemFromURL(url); - var path = pathFromURL(url); - if (!fs){ - fail(FileError.ENCODING_ERR); - return; - } - var wpath = cordovaPathToNative(sanitize(fs.winpath + path)); - - getFileFromPathAsync(wpath).then( - function (storageFile) { - Windows.Storage.FileIO.readBufferAsync(storageFile).done( - function (buffer) { - var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(buffer); - // var fileContent = dataReader.readString(buffer.length); - var byteArray = new Uint8Array(buffer.length), - byteString = ""; - dataReader.readBytes(byteArray); - dataReader.close(); - for (var i = 0; i < byteArray.length; i++) { - var charByte = byteArray[i]; - // var charRepresentation = charByte <= 127 ? String.fromCharCode(charByte) : charByte.toString(16); - var charRepresentation = String.fromCharCode(charByte); - byteString += charRepresentation; - } - win(byteString.slice(startPos, endPos)); - } - ); - }, function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - }, - - readAsArrayBuffer:function(win,fail,args) { - var url = args[0]; - var fs = getFilesystemFromURL(url); - var path = pathFromURL(url); - if (!fs){ - fail(FileError.ENCODING_ERR); - return; - } - var wpath = cordovaPathToNative(sanitize(fs.winpath + path)); - - getFileFromPathAsync(wpath).then( - function (storageFile) { - var blob = MSApp.createFileFromStorageFile(storageFile); - var url = URL.createObjectURL(blob, { oneTimeOnly: true }); - var xhr = new XMLHttpRequest(); - xhr.open("GET", url, true); - xhr.responseType = 'arraybuffer'; - xhr.onload = function () { - var resultArrayBuffer = xhr.response; - // get start and end position of bytes in buffer to be returned - var startPos = args[1] || 0, - endPos = args[2] || resultArrayBuffer.length; - // if any of them is specified, we'll slice output array - if (startPos !== 0 || endPos !== resultArrayBuffer.length) { - // slice method supported only on Windows 8.1, so we need to check if it's available - // see http://msdn.microsoft.com/en-us/library/ie/dn641192(v=vs.94).aspx - if (resultArrayBuffer.slice) { - resultArrayBuffer = resultArrayBuffer.slice(startPos, endPos); - } else { - // if slice isn't available, we'll use workaround method - var tempArray = new Uint8Array(resultArrayBuffer), - resBuffer = new ArrayBuffer(endPos - startPos), - resArray = new Uint8Array(resBuffer); - - for (var i = 0; i < resArray.length; i++) { - resArray[i] = tempArray[i + startPos]; - } - resultArrayBuffer = resBuffer; - } - } - win(resultArrayBuffer); - }; - xhr.send(); - }, function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - }, - - readAsDataURL: function (win, fail, args) { - var url = args[0]; - var fs = getFilesystemFromURL(url); - var path = pathFromURL(url); - if (!fs){ - fail(FileError.ENCODING_ERR); - return; - } - var wpath = cordovaPathToNative(sanitize(fs.winpath + path)); - - getFileFromPathAsync(wpath).then( - function (storageFile) { - Windows.Storage.FileIO.readBufferAsync(storageFile).done( - function (buffer) { - var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer); - //the method encodeToBase64String will add "77u/" as a prefix, so we should remove it - if(String(strBase64).substr(0,4) == "77u/") { - strBase64 = strBase64.substr(4); - } - var mediaType = storageFile.contentType; - var result = "data:" + mediaType + ";base64," + strBase64; - win(result); - } - ); - }, function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - }, - - getDirectory: function (win, fail, args) { - var dirurl = args[0]; - var path = args[1]; - var options = args[2]; - - var fs = getFilesystemFromURL(dirurl); - var dirpath = pathFromURL(dirurl); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - var fspath = sanitize(dirpath +'/'+ path); - var completePath = sanitize(fs.winpath + fspath); - - var name = completePath.substring(completePath.lastIndexOf('/')+1); - - var wpath = cordovaPathToNative(completePath.substring(0, completePath.lastIndexOf('/'))); - - var flag = ""; - if (options) { - flag = new Flags(options.create, options.exclusive); - } else { - flag = new Flags(false, false); - } - - getFolderFromPathAsync(wpath).done( - function (storageFolder) { - if (flag.create === true && flag.exclusive === true) { - storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.failIfExists).done( - function (storageFolder) { - win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath))); - }, function (err) { - fail(FileError.PATH_EXISTS_ERR); - } - ); - } else if (flag.create === true && flag.exclusive === false) { - storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists).done( - function (storageFolder) { - win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath))); - }, function () { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - } else if (flag.create === false) { - storageFolder.getFolderAsync(name).done( - function (storageFolder) { - win(new DirectoryEntry(storageFolder.name, fspath, fs.name, fs.makeNativeURL(fspath))); - }, - function () { - // check if path actually points to a file - storageFolder.getFileAsync(name).done( - function () { - fail(FileError.TYPE_MISMATCH_ERR); - }, function() { - fail(FileError.NOT_FOUND_ERR); - } - ); - } - ); - } - }, function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - }, - - remove: function (win, fail, args) { - var fs = getFilesystemFromURL(args[0]); - var path = pathFromURL(args[0]); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - - // FileSystem root can't be removed! - if (!path || path=='/'){ - fail(FileError.NO_MODIFICATION_ALLOWED_ERR); - return; - } - var fullPath = cordovaPathToNative(fs.winpath + path); - - getFileFromPathAsync(fullPath).then( - function (storageFile) { - storageFile.deleteAsync().done(win, function () { - fail(FileError.INVALID_MODIFICATION_ERR); - }); - }, - function () { - getFolderFromPathAsync(fullPath).done( - function (sFolder) { - sFolder.getFilesAsync() - // check for files - .then(function(fileList) { - if (fileList) { - if (fileList.length === 0) { - return sFolder.getFoldersAsync(); - } else { - fail(FileError.INVALID_MODIFICATION_ERR); - } - } - }) - // check for folders - .done(function (folderList) { - if (folderList) { - if (folderList.length === 0) { - sFolder.deleteAsync().done( - win, - function () { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - } else { - fail(FileError.INVALID_MODIFICATION_ERR); - } - } - }); - }, - function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - } - ); - }, - - removeRecursively: function (successCallback, fail, args) { - - var fs = getFilesystemFromURL(args[0]); - var path = pathFromURL(args[0]); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - - // FileSystem root can't be removed! - if (!path || path=='/'){ - fail(FileError.NO_MODIFICATION_ALLOWED_ERR); - return; - } - var fullPath = cordovaPathToNative(fs.winpath + path); - - getFolderFromPathAsync(fullPath).done(function (storageFolder) { - storageFolder.deleteAsync().done(function (res) { - successCallback(res); - }, function (err) { - fail(err); - }); - - }, function () { - fail(FileError.FILE_NOT_FOUND_ERR); - }); - }, - - getFile: function (win, fail, args) { - - var dirurl = args[0]; - var path = args[1]; - var options = args[2]; - - var fs = getFilesystemFromURL(dirurl); - var dirpath = pathFromURL(dirurl); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - var fspath = sanitize(dirpath +'/'+ path); - var completePath = sanitize(fs.winpath + fspath); - - var fileName = completePath.substring(completePath.lastIndexOf('/')+1); - - var wpath = cordovaPathToNative(completePath.substring(0, completePath.lastIndexOf('/'))); - - var flag = ""; - if (options !== null) { - flag = new Flags(options.create, options.exclusive); - } else { - flag = new Flags(false, false); - } - - getFolderFromPathAsync(wpath).done( - function (storageFolder) { - if (flag.create === true && flag.exclusive === true) { - storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.failIfExists).done( - function (storageFile) { - win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath))); - }, function () { - fail(FileError.PATH_EXISTS_ERR); - } - ); - } else if (flag.create === true && flag.exclusive === false) { - storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.openIfExists).done( - function (storageFile) { - win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath))); - }, function () { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - } else if (flag.create === false) { - storageFolder.getFileAsync(fileName).done( - function (storageFile) { - win(new FileEntry(storageFile.name, fspath, fs.name, fs.makeNativeURL(fspath))); - }, function () { - // check if path actually points to a folder - storageFolder.getFolderAsync(fileName).done( - function () { - fail(FileError.TYPE_MISMATCH_ERR); - }, function () { - fail(FileError.NOT_FOUND_ERR); - }); - } - ); - } - }, function (err) { - fail( - err.number == WinError.accessDenied? - FileError.SECURITY_ERR: - FileError.NOT_FOUND_ERR - ); - } - ); - }, - - readEntries: function (win, fail, args) { // ["fullPath"] - var fs = getFilesystemFromURL(args[0]); - var path = pathFromURL(args[0]); - if (!fs || !validName(path)){ - fail(FileError.ENCODING_ERR); - return; - } - var fullPath = cordovaPathToNative(fs.winpath + path); - - var result = []; - - getFolderFromPathAsync(fullPath).done(function (storageFolder) { - var promiseArr = []; - var index = 0; - promiseArr[index++] = storageFolder.getFilesAsync().then(function (fileList) { - if (fileList !== null) { - for (var i = 0; i < fileList.length; i++) { - var fspath = getFsPathForWinPath(fs, fileList[i].path); - if (!fspath) { - fail(FileError.NOT_FOUND_ERR); - return; - } - result.push(new FileEntry(fileList[i].name, fspath, fs.name, fs.makeNativeURL(fspath))); - } - } - }); - promiseArr[index++] = storageFolder.getFoldersAsync().then(function (folderList) { - if (folderList !== null) { - for (var j = 0; j < folderList.length; j++) { - var fspath = getFsPathForWinPath(fs, folderList[j].path); - if (!fspath) { - fail(FileError.NOT_FOUND_ERR); - return; - } - result.push(new DirectoryEntry(folderList[j].name, fspath, fs.name, fs.makeNativeURL(fspath))); - } - } - }); - WinJS.Promise.join(promiseArr).then(function () { - win(result); - }); - - }, function () { fail(FileError.NOT_FOUND_ERR); }); - }, - - write: function (win, fail, args) { - - var url = args[0], - data = args[1], - position = args[2], - isBinary = args[3]; - - var fs = getFilesystemFromURL(url); - var path = pathFromURL(url); - if (!fs){ - fail(FileError.ENCODING_ERR); - return; - } - var completePath = sanitize(fs.winpath + path); - var fileName = completePath.substring(completePath.lastIndexOf('/')+1); - var dirpath = completePath.substring(0,completePath.lastIndexOf('/')); - var wpath = cordovaPathToNative(dirpath); - - function getWriteMethodForData(data, isBinary) { - - if (data instanceof Blob) { - return writeBlobAsync; - } - - if (data instanceof ArrayBuffer) { - return writeArrayBufferAsync; - } - - if (isBinary) { - return writeBytesAsync; - } - - if (typeof data === 'string') { - return writeTextAsync; - } - - throw new Error('Unsupported data type for write method'); - } - - var writePromise = getWriteMethodForData(data, isBinary); - - getFolderFromPathAsync(wpath).done( - function (storageFolder) { - storageFolder.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.openIfExists).done( - function (storageFile) { - writePromise(storageFile, data, position).done( - function (bytesWritten) { - var written = bytesWritten || data.length; - win(written); - }, - function () { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - }, - function () { - fail(FileError.INVALID_MODIFICATION_ERR); - } - ); - - }, - function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - }, - - truncate: function (win, fail, args) { // ["fileName","size"] - var url = args[0]; - var size = args[1]; - - var fs = getFilesystemFromURL(url); - var path = pathFromURL(url); - if (!fs){ - fail(FileError.ENCODING_ERR); - return; - } - var completePath = sanitize(fs.winpath + path); - var wpath = cordovaPathToNative(completePath); - var dirwpath = cordovaPathToNative(completePath.substring(0,completePath.lastIndexOf('/'))); - - getFileFromPathAsync(wpath).done(function(storageFile){ - //the current length of the file. - var leng = 0; - - storageFile.getBasicPropertiesAsync().then(function (basicProperties) { - leng = basicProperties.size; - if (Number(size) >= leng) { - win(this.length); - return; - } - if (Number(size) >= 0) { - Windows.Storage.FileIO.readTextAsync(storageFile, Windows.Storage.Streams.UnicodeEncoding.utf8).then(function (fileContent) { - fileContent = fileContent.substr(0, size); - var fullPath = storageFile.path; - var name = storageFile.name; - storageFile.deleteAsync().then(function () { - return getFolderFromPathAsync(dirwpath); - }).done(function (storageFolder) { - storageFolder.createFileAsync(name).then(function (newStorageFile) { - Windows.Storage.FileIO.writeTextAsync(newStorageFile, fileContent).done(function () { - win(String(fileContent).length); - }, function () { - fail(FileError.NO_MODIFICATION_ALLOWED_ERR); - }); - }, function() { - fail(FileError.NO_MODIFICATION_ALLOWED_ERR); - }); - }); - }, function () { fail(FileError.NOT_FOUND_ERR); }); - } - }); - }, function () { fail(FileError.NOT_FOUND_ERR); }); - }, - - copyTo: function (success, fail, args) { // ["fullPath","parent", "newName"] - transport(success, fail, args, - { - fileOp:function(file,folder,name,coll) { - return file.copyAsync(folder,name,coll); - }, - folderOp:function(src,dst,name) { - return copyFolder(src,dst,name); - }} - ); - }, - - moveTo: function (success, fail, args) { - transport(success, fail, args, - { - fileOp:function(file,folder,name,coll) { - return file.moveAsync(folder,name,coll); - }, - folderOp:function(src,dst,name) { - return moveFolder(src,dst,name); - }} - ); - }, - tempFileSystem:null, - - persistentFileSystem:null, - - requestFileSystem: function (win, fail, args) { - - var type = args[0]; - var size = args[1]; - var MAX_SIZE = 10000000000; - if (size > MAX_SIZE) { - fail(FileError.QUOTA_EXCEEDED_ERR); - return; - } - - var fs; - switch (type) { - case LocalFileSystem.TEMPORARY: - fs = getFS('temporary'); - break; - case LocalFileSystem.PERSISTENT: - fs = getFS('persistent'); - break; - } - if (fs) - win(fs); - else - fail(FileError.NOT_FOUND_ERR); - }, - - resolveLocalFileSystemURI: function (success, fail, args) { - - var uri = args[0]; - var inputURL; - - var path = pathFromURL(uri); - var fs = getFilesystemFromURL(uri); - if (!fs || !validName(path)) { - fail(FileError.ENCODING_ERR); - return; - } - if (path.indexOf(fs.winpath) === 0) - path=path.substr(fs.winpath.length); - var abspath = cordovaPathToNative(fs.winpath+path); - - getFileFromPathAsync(abspath).done( - function (storageFile) { - success(new FileEntry(storageFile.name, path, fs.name, fs.makeNativeURL(path))); - }, function () { - getFolderFromPathAsync(abspath).done( - function (storageFolder) { - success(new DirectoryEntry(storageFolder.name, path, fs.name,fs.makeNativeURL(path))); - }, function () { - fail(FileError.NOT_FOUND_ERR); - } - ); - } - ); - } - - -}; - -require("cordova/exec/proxy").add("File",module.exports); diff --git a/plugins/cordova-plugin-file/src/wp/File.cs b/plugins/cordova-plugin-file/src/wp/File.cs deleted file mode 100644 index 203d8d42..00000000 --- a/plugins/cordova-plugin-file/src/wp/File.cs +++ /dev/null @@ -1,1800 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.IO.IsolatedStorage; -using System.Runtime.Serialization; -using System.Security; -using System.Text; -using System.Windows; -using System.Windows.Resources; -using WPCordovaClassLib.Cordova.JSON; - -namespace WPCordovaClassLib.Cordova.Commands -{ - /// <summary> - /// Provides access to isolated storage - /// </summary> - public class File : BaseCommand - { - // Error codes - public const int NOT_FOUND_ERR = 1; - public const int SECURITY_ERR = 2; - public const int ABORT_ERR = 3; - public const int NOT_READABLE_ERR = 4; - public const int ENCODING_ERR = 5; - public const int NO_MODIFICATION_ALLOWED_ERR = 6; - public const int INVALID_STATE_ERR = 7; - public const int SYNTAX_ERR = 8; - public const int INVALID_MODIFICATION_ERR = 9; - public const int QUOTA_EXCEEDED_ERR = 10; - public const int TYPE_MISMATCH_ERR = 11; - public const int PATH_EXISTS_ERR = 12; - - // File system options - public const int TEMPORARY = 0; - public const int PERSISTENT = 1; - public const int RESOURCE = 2; - public const int APPLICATION = 3; - - /// <summary> - /// Temporary directory name - /// </summary> - private readonly string TMP_DIRECTORY_NAME = "tmp"; - - /// <summary> - /// Represents error code for callback - /// </summary> - [DataContract] - public class ErrorCode - { - /// <summary> - /// Error code - /// </summary> - [DataMember(IsRequired = true, Name = "code")] - public int Code { get; set; } - - /// <summary> - /// Creates ErrorCode object - /// </summary> - public ErrorCode(int code) - { - this.Code = code; - } - } - - /// <summary> - /// Represents File action options. - /// </summary> - [DataContract] - public class FileOptions - { - /// <summary> - /// File path - /// </summary> - /// - private string _fileName; - [DataMember(Name = "fileName")] - public string FilePath - { - get - { - return this._fileName; - } - - set - { - int index = value.IndexOfAny(new char[] { '#', '?' }); - this._fileName = index > -1 ? value.Substring(0, index) : value; - } - } - - /// <summary> - /// Full entryPath - /// </summary> - [DataMember(Name = "fullPath")] - public string FullPath { get; set; } - - /// <summary> - /// Directory name - /// </summary> - [DataMember(Name = "dirName")] - public string DirectoryName { get; set; } - - /// <summary> - /// Path to create file/directory - /// </summary> - [DataMember(Name = "path")] - public string Path { get; set; } - - /// <summary> - /// The encoding to use to encode the file's content. Default is UTF8. - /// </summary> - [DataMember(Name = "encoding")] - public string Encoding { get; set; } - - /// <summary> - /// Uri to get file - /// </summary> - /// - private string _uri; - [DataMember(Name = "uri")] - public string Uri - { - get - { - return this._uri; - } - - set - { - int index = value.IndexOfAny(new char[] { '#', '?' }); - this._uri = index > -1 ? value.Substring(0, index) : value; - } - } - - /// <summary> - /// Size to truncate file - /// </summary> - [DataMember(Name = "size")] - public long Size { get; set; } - - /// <summary> - /// Data to write in file - /// </summary> - [DataMember(Name = "data")] - public string Data { get; set; } - - /// <summary> - /// Position the writing starts with - /// </summary> - [DataMember(Name = "position")] - public int Position { get; set; } - - /// <summary> - /// Type of file system requested - /// </summary> - [DataMember(Name = "type")] - public int FileSystemType { get; set; } - - /// <summary> - /// New file/directory name - /// </summary> - [DataMember(Name = "newName")] - public string NewName { get; set; } - - /// <summary> - /// Destination directory to copy/move file/directory - /// </summary> - [DataMember(Name = "parent")] - public string Parent { get; set; } - - /// <summary> - /// Options for getFile/getDirectory methods - /// </summary> - [DataMember(Name = "options")] - public CreatingOptions CreatingOpt { get; set; } - - /// <summary> - /// Creates options object with default parameters - /// </summary> - public FileOptions() - { - this.SetDefaultValues(new StreamingContext()); - } - - /// <summary> - /// Initializes default values for class fields. - /// Implemented in separate method because default constructor is not invoked during deserialization. - /// </summary> - /// <param name="context"></param> - [OnDeserializing()] - public void SetDefaultValues(StreamingContext context) - { - this.Encoding = "UTF-8"; - this.FilePath = ""; - this.FileSystemType = -1; - } - } - - /// <summary> - /// Stores image info - /// </summary> - [DataContract] - public class FileMetadata - { - [DataMember(Name = "fileName")] - public string FileName { get; set; } - - [DataMember(Name = "fullPath")] - public string FullPath { get; set; } - - [DataMember(Name = "type")] - public string Type { get; set; } - - [DataMember(Name = "lastModifiedDate")] - public string LastModifiedDate { get; set; } - - [DataMember(Name = "size")] - public long Size { get; set; } - - public FileMetadata(string filePath) - { - if (string.IsNullOrEmpty(filePath)) - { - throw new FileNotFoundException("File doesn't exist"); - } - - this.FullPath = filePath; - this.Size = 0; - this.FileName = string.Empty; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - bool IsFile = isoFile.FileExists(filePath); - bool IsDirectory = isoFile.DirectoryExists(filePath); - - if (!IsDirectory) - { - if (!IsFile) // special case, if isoFile cannot find it, it might still be part of the app-package - { - // attempt to get it from the resources - - Uri fileUri = new Uri(filePath, UriKind.Relative); - StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri); - if (streamInfo != null) - { - this.Size = streamInfo.Stream.Length; - this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1); - } - else - { - throw new FileNotFoundException("File doesn't exist"); - } - } - else - { - using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile)) - { - this.Size = stream.Length; - } - - this.FileName = System.IO.Path.GetFileName(filePath); - this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString(); - } - } - - this.Type = MimeTypeMapper.GetMimeType(this.FileName); - } - } - } - - /// <summary> - /// Represents file or directory modification metadata - /// </summary> - [DataContract] - public class ModificationMetadata - { - /// <summary> - /// Modification time - /// </summary> - [DataMember] - public string modificationTime { get; set; } - } - - /// <summary> - /// Represents file or directory entry - /// </summary> - [DataContract] - public class FileEntry - { - - /// <summary> - /// File type - /// </summary> - [DataMember(Name = "isFile")] - public bool IsFile { get; set; } - - /// <summary> - /// Directory type - /// </summary> - [DataMember(Name = "isDirectory")] - public bool IsDirectory { get; set; } - - /// <summary> - /// File/directory name - /// </summary> - [DataMember(Name = "name")] - public string Name { get; set; } - - /// <summary> - /// Full path to file/directory - /// </summary> - [DataMember(Name = "fullPath")] - public string FullPath { get; set; } - - /// <summary> - /// URI encoded fullpath - /// </summary> - [DataMember(Name = "nativeURL")] - public string NativeURL - { - set { } - get - { - string escaped = Uri.EscapeUriString(this.FullPath); - escaped = escaped.Replace("//", "/"); - if (escaped.StartsWith("/")) - { - escaped = escaped.Insert(0, "/"); - } - return escaped; - } - } - - public bool IsResource { get; set; } - - public static FileEntry GetEntry(string filePath, bool bIsRes=false) - { - FileEntry entry = null; - try - { - entry = new FileEntry(filePath, bIsRes); - - } - catch (Exception ex) - { - Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message); - } - return entry; - } - - /// <summary> - /// Creates object and sets necessary properties - /// </summary> - /// <param name="filePath"></param> - public FileEntry(string filePath, bool bIsRes = false) - { - if (string.IsNullOrEmpty(filePath)) - { - throw new ArgumentException(); - } - - if(filePath.Contains(" ")) - { - Debug.WriteLine("FilePath with spaces :: " + filePath); - } - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - IsResource = bIsRes; - IsFile = isoFile.FileExists(filePath); - IsDirectory = isoFile.DirectoryExists(filePath); - if (IsFile) - { - this.Name = Path.GetFileName(filePath); - } - else if (IsDirectory) - { - this.Name = this.GetDirectoryName(filePath); - if (string.IsNullOrEmpty(Name)) - { - this.Name = "/"; - } - } - else - { - if (IsResource) - { - this.Name = Path.GetFileName(filePath); - } - else - { - throw new FileNotFoundException(); - } - } - - try - { - this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath; - } - catch (Exception) - { - this.FullPath = filePath; - } - } - } - - /// <summary> - /// Extracts directory name from path string - /// Path should refer to a directory, for example \foo\ or /foo. - /// </summary> - /// <param name="path"></param> - /// <returns></returns> - private string GetDirectoryName(string path) - { - if (String.IsNullOrEmpty(path)) - { - return path; - } - - string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries); - if (split.Length < 1) - { - return null; - } - else - { - return split[split.Length - 1]; - } - } - } - - - /// <summary> - /// Represents info about requested file system - /// </summary> - [DataContract] - public class FileSystemInfo - { - /// <summary> - /// file system type - /// </summary> - [DataMember(Name = "name", IsRequired = true)] - public string Name { get; set; } - - /// <summary> - /// Root directory entry - /// </summary> - [DataMember(Name = "root", EmitDefaultValue = false)] - public FileEntry Root { get; set; } - - /// <summary> - /// Creates class instance - /// </summary> - /// <param name="name"></param> - /// <param name="rootEntry"> Root directory</param> - public FileSystemInfo(string name, FileEntry rootEntry = null) - { - Name = name; - Root = rootEntry; - } - } - - [DataContract] - public class CreatingOptions - { - /// <summary> - /// Create file/directory if is doesn't exist - /// </summary> - [DataMember(Name = "create")] - public bool Create { get; set; } - - /// <summary> - /// Generate an exception if create=true and file/directory already exists - /// </summary> - [DataMember(Name = "exclusive")] - public bool Exclusive { get; set; } - - - } - - // returns null value if it fails. - private string[] getOptionStrings(string options) - { - string[] optStings = null; - try - { - optStings = JSON.JsonHelper.Deserialize<string[]>(options); - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId); - } - return optStings; - } - - /// <summary> - /// Gets amount of free space available for Isolated Storage - /// </summary> - /// <param name="options">No options is needed for this method</param> - public void getFreeDiskSpace(string options) - { - string callbackId = getOptionStrings(options)[0]; - - try - { - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId); - } - } - catch (IsolatedStorageException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - /// <summary> - /// Check if file exists - /// </summary> - /// <param name="options">File path</param> - public void testFileExists(string options) - { - IsDirectoryOrFileExist(options, false); - } - - /// <summary> - /// Check if directory exists - /// </summary> - /// <param name="options">directory name</param> - public void testDirectoryExists(string options) - { - IsDirectoryOrFileExist(options, true); - } - - /// <summary> - /// Check if file or directory exist - /// </summary> - /// <param name="options">File path/Directory name</param> - /// <param name="isDirectory">Flag to recognize what we should check</param> - public void IsDirectoryOrFileExist(string options, bool isDirectory) - { - string[] args = getOptionStrings(options); - string callbackId = args[1]; - FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]); - string filePath = args[0]; - - if (fileOptions == null) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - } - - try - { - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - bool isExist; - if (isDirectory) - { - isExist = isoFile.DirectoryExists(fileOptions.DirectoryName); - } - else - { - isExist = isoFile.FileExists(fileOptions.FilePath); - } - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId); - } - } - catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - } - - } - - public void readAsDataURL(string options) - { - string[] optStrings = getOptionStrings(options); - string filePath = optStrings[0]; - int startPos = int.Parse(optStrings[1]); - int endPos = int.Parse(optStrings[2]); - string callbackId = optStrings[3]; - - if (filePath != null) - { - try - { - string base64URL = null; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoFile.FileExists(filePath)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - string mimeType = MimeTypeMapper.GetMimeType(filePath); - - using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read)) - { - string base64String = GetFileContent(stream); - base64URL = "data:" + mimeType + ";base64," + base64String; - } - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - } - - private byte[] readFileBytes(string filePath,int startPos,int endPos, IsolatedStorageFile isoFile) - { - byte[] buffer; - using (IsolatedStorageFileStream reader = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read)) - { - if (startPos < 0) - { - startPos = Math.Max((int)reader.Length + startPos, 0); - } - else if (startPos > 0) - { - startPos = Math.Min((int)reader.Length, startPos); - } - if (endPos > 0) - { - endPos = Math.Min((int)reader.Length, endPos); - } - else if (endPos < 0) - { - endPos = Math.Max(endPos + (int)reader.Length, 0); - } - - buffer = new byte[endPos - startPos]; - reader.Seek(startPos, SeekOrigin.Begin); - reader.Read(buffer, 0, buffer.Length); - } - - return buffer; - } - - public void readAsArrayBuffer(string options) - { - string[] optStrings = getOptionStrings(options); - string filePath = optStrings[0]; - int startPos = int.Parse(optStrings[1]); - int endPos = int.Parse(optStrings[2]); - string callbackId = optStrings[3]; - - try - { - byte[] buffer; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoFile.FileExists(filePath)) - { - readResourceAsText(options); - return; - } - buffer = readFileBytes(filePath, startPos, endPos, isoFile); - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, buffer), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - public void readAsBinaryString(string options) - { - string[] optStrings = getOptionStrings(options); - string filePath = optStrings[0]; - int startPos = int.Parse(optStrings[1]); - int endPos = int.Parse(optStrings[2]); - string callbackId = optStrings[3]; - - try - { - string result; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoFile.FileExists(filePath)) - { - readResourceAsText(options); - return; - } - - byte[] buffer = readFileBytes(filePath, startPos, endPos, isoFile); - result = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(buffer, 0, buffer.Length); - - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, result), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - public void readAsText(string options) - { - string[] optStrings = getOptionStrings(options); - string filePath = optStrings[0]; - string encStr = optStrings[1]; - int startPos = int.Parse(optStrings[2]); - int endPos = int.Parse(optStrings[3]); - string callbackId = optStrings[4]; - - try - { - string text = ""; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoFile.FileExists(filePath)) - { - readResourceAsText(options); - return; - } - Encoding encoding = Encoding.GetEncoding(encStr); - - byte[] buffer = this.readFileBytes(filePath, startPos, endPos, isoFile); - text = encoding.GetString(buffer, 0, buffer.Length); - } - - // JIRA: https://issues.apache.org/jira/browse/CB-8792 - // Need to perform additional serialization here because NativeExecution is always trying - // to do JSON.parse() on command result. This leads to issue when trying to read JSON files - var resultText = JsonHelper.Serialize(text); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, resultText), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - /// <summary> - /// Reads application resource as a text - /// </summary> - /// <param name="options">Path to a resource</param> - public void readResourceAsText(string options) - { - string[] optStrings = getOptionStrings(options); - string pathToResource = optStrings[0]; - string encStr = optStrings[1]; - int start = int.Parse(optStrings[2]); - int endMarker = int.Parse(optStrings[3]); - string callbackId = optStrings[4]; - - try - { - if (pathToResource.StartsWith("/")) - { - pathToResource = pathToResource.Remove(0, 1); - } - - var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative)); - - if (resource == null) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - - string text; - StreamReader streamReader = new StreamReader(resource.Stream); - text = streamReader.ReadToEnd(); - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - public void truncate(string options) - { - string[] optStrings = getOptionStrings(options); - - string filePath = optStrings[0]; - int size = int.Parse(optStrings[1]); - string callbackId = optStrings[2]; - - try - { - long streamLength = 0; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoFile.FileExists(filePath)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - - using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile)) - { - if (0 <= size && size <= stream.Length) - { - stream.SetLength(size); - } - streamLength = stream.Length; - } - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - //write:[filePath,data,position,isBinary,callbackId] - public void write(string options) - { - string[] optStrings = getOptionStrings(options); - - string filePath = optStrings[0]; - string data = optStrings[1]; - int position = int.Parse(optStrings[2]); - bool isBinary = bool.Parse(optStrings[3]); - string callbackId = optStrings[4]; - - try - { - if (string.IsNullOrEmpty(data)) - { - Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath); - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - - byte[] dataToWrite = isBinary ? JSON.JsonHelper.Deserialize<byte[]>(data) : - System.Text.Encoding.UTF8.GetBytes(data); - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - // create the file if not exists - if (!isoFile.FileExists(filePath)) - { - var file = isoFile.CreateFile(filePath); - file.Close(); - } - - using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile)) - { - if (0 <= position && position <= stream.Length) - { - stream.SetLength(position); - } - using (BinaryWriter writer = new BinaryWriter(stream)) - { - writer.Seek(0, SeekOrigin.End); - writer.Write(dataToWrite); - } - } - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, dataToWrite.Length), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - /// <summary> - /// Look up metadata about this entry. - /// </summary> - /// <param name="options">filePath to entry</param> - public void getMetadata(string options) - { - string[] optStings = getOptionStrings(options); - string filePath = optStings[0]; - string callbackId = optStings[1]; - - if (filePath != null) - { - try - { - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (isoFile.FileExists(filePath)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, - new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId); - } - else if (isoFile.DirectoryExists(filePath)) - { - string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString(); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - - } - } - catch (IsolatedStorageException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - - } - - - /// <summary> - /// Returns a File that represents the current state of the file that this FileEntry represents. - /// </summary> - /// <param name="filePath">filePath to entry</param> - /// <returns></returns> - public void getFileMetadata(string options) - { - string[] optStings = getOptionStrings(options); - string filePath = optStings[0]; - string callbackId = optStings[1]; - - if (!string.IsNullOrEmpty(filePath)) - { - try - { - FileMetadata metaData = new FileMetadata(filePath); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId); - } - catch (IsolatedStorageException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId); - } - } - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - } - - /// <summary> - /// Look up the parent DirectoryEntry containing this Entry. - /// If this Entry is the root of IsolatedStorage, its parent is itself. - /// </summary> - /// <param name="options"></param> - public void getParent(string options) - { - string[] optStings = getOptionStrings(options); - string filePath = optStings[0]; - string callbackId = optStings[1]; - - if (filePath != null) - { - try - { - if (string.IsNullOrEmpty(filePath)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId); - return; - } - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - FileEntry entry; - - if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath)) - { - - - string path = this.GetParentDirectory(filePath); - entry = FileEntry.GetEntry(path); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId); - } - - } - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId); - } - } - } - } - - public void remove(string options) - { - string[] args = getOptionStrings(options); - string filePath = args[0]; - string callbackId = args[1]; - - if (filePath != null) - { - try - { - if (filePath == "/" || filePath == "" || filePath == @"\") - { - throw new Exception("Cannot delete root file system") ; - } - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (isoFile.FileExists(filePath)) - { - isoFile.DeleteFile(filePath); - } - else - { - if (isoFile.DirectoryExists(filePath)) - { - isoFile.DeleteDirectory(filePath); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId); - return; - } - } - DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId); - } - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId); - } - } - } - } - - public void removeRecursively(string options) - { - string[] args = getOptionStrings(options); - string filePath = args[0]; - string callbackId = args[1]; - - if (filePath != null) - { - if (string.IsNullOrEmpty(filePath)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId); - } - else - { - if (removeDirRecursively(filePath, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - } - } - } - } - - public void readEntries(string options) - { - string[] args = getOptionStrings(options); - string filePath = args[0]; - string callbackId = args[1]; - - if (filePath != null) - { - try - { - if (string.IsNullOrEmpty(filePath)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId); - return; - } - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (isoFile.DirectoryExists(filePath)) - { - string path = File.AddSlashToDirectory(filePath); - List<FileEntry> entries = new List<FileEntry>(); - string[] files = isoFile.GetFileNames(path + "*"); - string[] dirs = isoFile.GetDirectoryNames(path + "*"); - foreach (string file in files) - { - entries.Add(FileEntry.GetEntry(path + file)); - } - foreach (string dir in dirs) - { - entries.Add(FileEntry.GetEntry(path + dir + "/")); - } - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId); - } - } - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId); - } - } - } - } - - public void requestFileSystem(string options) - { - // TODO: try/catch - string[] optVals = getOptionStrings(options); - //FileOptions fileOptions = new FileOptions(); - int fileSystemType = int.Parse(optVals[0]); - double size = double.Parse(optVals[1]); - string callbackId = optVals[2]; - - - IsolatedStorageFile.GetUserStoreForApplication(); - - if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up! - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId); - return; - } - - try - { - if (size != 0) - { - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - long availableSize = isoFile.AvailableFreeSpace; - if (size > availableSize) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId); - return; - } - } - } - - if (fileSystemType == PERSISTENT) - { - // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId); - } - else if (fileSystemType == TEMPORARY) - { - using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoStorage.FileExists(TMP_DIRECTORY_NAME)) - { - isoStorage.CreateDirectory(TMP_DIRECTORY_NAME); - } - } - - string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/"; - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId); - } - else if (fileSystemType == RESOURCE) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId); - } - else if (fileSystemType == APPLICATION) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId); - } - - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId); - } - } - } - - public void resolveLocalFileSystemURI(string options) - { - - string[] optVals = getOptionStrings(options); - string uri = optVals[0].Split('?')[0]; - string callbackId = optVals[1]; - - if (uri != null) - { - // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid - if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/") - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId); - return; - } - try - { - // fix encoded spaces - string path = Uri.UnescapeDataString(uri); - - FileEntry uriEntry = FileEntry.GetEntry(path); - if (uriEntry != null) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId); - } - } - } - } - - public void copyTo(string options) - { - TransferTo(options, false); - } - - public void moveTo(string options) - { - TransferTo(options, true); - } - - public void getFile(string options) - { - GetFileOrDirectory(options, false); - } - - public void getDirectory(string options) - { - GetFileOrDirectory(options, true); - } - - #region internal functionality - - /// <summary> - /// Retrieves the parent directory name of the specified path, - /// </summary> - /// <param name="path">Path</param> - /// <returns>Parent directory name</returns> - private string GetParentDirectory(string path) - { - if (String.IsNullOrEmpty(path) || path == "/") - { - return "/"; - } - - if (path.EndsWith(@"/") || path.EndsWith(@"\")) - { - return this.GetParentDirectory(Path.GetDirectoryName(path)); - } - - string result = Path.GetDirectoryName(path); - if (result == null) - { - result = "/"; - } - - return result; - } - - private bool removeDirRecursively(string fullPath,string callbackId) - { - try - { - if (fullPath == "/") - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId); - return false; - } - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (isoFile.DirectoryExists(fullPath)) - { - string tempPath = File.AddSlashToDirectory(fullPath); - string[] files = isoFile.GetFileNames(tempPath + "*"); - if (files.Length > 0) - { - foreach (string file in files) - { - isoFile.DeleteFile(tempPath + file); - } - } - string[] dirs = isoFile.GetDirectoryNames(tempPath + "*"); - if (dirs.Length > 0) - { - foreach (string dir in dirs) - { - if (!removeDirRecursively(tempPath + dir, callbackId)) - { - return false; - } - } - } - isoFile.DeleteDirectory(fullPath); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId); - } - } - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId); - return false; - } - } - return true; - } - - private bool CanonicalCompare(string pathA, string pathB) - { - string a = pathA.Replace("//", "/"); - string b = pathB.Replace("//", "/"); - - return a.Equals(b, StringComparison.OrdinalIgnoreCase); - } - - /* - * copyTo:["fullPath","parent", "newName"], - * moveTo:["fullPath","parent", "newName"], - */ - private void TransferTo(string options, bool move) - { - // TODO: try/catch - string[] optStrings = getOptionStrings(options); - string fullPath = optStrings[0]; - string parent = optStrings[1]; - string newFileName = optStrings[2]; - string callbackId = optStrings[3]; - - char[] invalids = Path.GetInvalidPathChars(); - - if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 ) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId); - return; - } - - try - { - if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath))) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - - string parentPath = File.AddSlashToDirectory(parent); - string currentPath = fullPath; - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - bool isFileExist = isoFile.FileExists(currentPath); - bool isDirectoryExist = isoFile.DirectoryExists(currentPath); - bool isParentExist = isoFile.DirectoryExists(parentPath); - - if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist ) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - string newName; - string newPath; - if (isFileExist) - { - newName = (string.IsNullOrEmpty(newFileName)) - ? Path.GetFileName(currentPath) - : newFileName; - - newPath = Path.Combine(parentPath, newName); - - // sanity check .. - // cannot copy file onto itself - if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId); - return; - } - else if (isoFile.DirectoryExists(newPath)) - { - // there is already a folder with the same name, operation is not allowed - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId); - return; - } - else if (isoFile.FileExists(newPath)) - { // remove destination file if exists, in other case there will be exception - isoFile.DeleteFile(newPath); - } - - if (move) - { - isoFile.MoveFile(currentPath, newPath); - } - else - { - isoFile.CopyFile(currentPath, newPath, true); - } - } - else - { - newName = (string.IsNullOrEmpty(newFileName)) - ? currentPath - : newFileName; - - newPath = Path.Combine(parentPath, newName); - - if (move) - { - // remove destination directory if exists, in other case there will be exception - // target directory should be empty - if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath)) - { - isoFile.DeleteDirectory(newPath); - } - - isoFile.MoveDirectory(currentPath, newPath); - } - else - { - CopyDirectory(currentPath, newPath, isoFile); - } - } - FileEntry entry = FileEntry.GetEntry(newPath); - if (entry != null) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - } - - } - catch (Exception ex) - { - if (!this.HandleException(ex, callbackId)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId); - } - } - } - - private bool HandleException(Exception ex, string cbId="") - { - bool handled = false; - string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId; - if (ex is SecurityException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId); - handled = true; - } - else if (ex is FileNotFoundException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - handled = true; - } - else if (ex is ArgumentException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId); - handled = true; - } - else if (ex is IsolatedStorageException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId); - handled = true; - } - else if (ex is DirectoryNotFoundException) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - handled = true; - } - return handled; - } - - private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile) - { - string path = File.AddSlashToDirectory(sourceDir); - - bool bExists = isoFile.DirectoryExists(destDir); - - if (!bExists) - { - isoFile.CreateDirectory(destDir); - } - - destDir = File.AddSlashToDirectory(destDir); - - string[] files = isoFile.GetFileNames(path + "*"); - - if (files.Length > 0) - { - foreach (string file in files) - { - isoFile.CopyFile(path + file, destDir + file,true); - } - } - string[] dirs = isoFile.GetDirectoryNames(path + "*"); - if (dirs.Length > 0) - { - foreach (string dir in dirs) - { - CopyDirectory(path + dir, destDir + dir, isoFile); - } - } - } - - private string RemoveExtraSlash(string path) { - if (path.StartsWith("//")) { - path = path.Remove(0, 1); - path = RemoveExtraSlash(path); - } - return path; - } - - private string ResolvePath(string parentPath, string path) - { - string absolutePath = null; - - if (path.Contains("..")) - { - if (parentPath.Length > 1 && parentPath.StartsWith("/") && parentPath !="/") - { - parentPath = RemoveExtraSlash(parentPath); - } - - string fullPath = Path.GetFullPath(Path.Combine(parentPath, path)); - absolutePath = fullPath.Replace(Path.GetPathRoot(fullPath), @"//"); - } - else - { - absolutePath = Path.Combine(parentPath + "/", path); - } - return absolutePath; - } - - private void GetFileOrDirectory(string options, bool getDirectory) - { - FileOptions fOptions = new FileOptions(); - string[] args = getOptionStrings(options); - - fOptions.FullPath = args[0]; - fOptions.Path = args[1]; - - string callbackId = args[3]; - - try - { - fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]); - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - - try - { - if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath))) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - - string path; - - if (fOptions.Path.Split(':').Length > 2) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId); - return; - } - - try - { - path = ResolvePath(fOptions.FullPath, fOptions.Path); - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId); - return; - } - - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - bool isFile = isoFile.FileExists(path); - bool isDirectory = isoFile.DirectoryExists(path); - bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create; - bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive; - if (create) - { - if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path))) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId); - return; - } - - // need to make sure the parent exists - // it is an error to create a directory whose immediate parent does not yet exist - // see issue: https://issues.apache.org/jira/browse/CB-339 - string[] pathParts = path.Split('/'); - string builtPath = pathParts[0]; - for (int n = 1; n < pathParts.Length - 1; n++) - { - builtPath += "/" + pathParts[n]; - if (!isoFile.DirectoryExists(builtPath)) - { - Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path)); - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - return; - } - } - - if ((getDirectory) && (!isDirectory)) - { - isoFile.CreateDirectory(path); - } - else - { - if ((!getDirectory) && (!isFile)) - { - - IsolatedStorageFileStream fileStream = isoFile.CreateFile(path); - fileStream.Close(); - } - } - } - else // (not create) - { - if ((!isFile) && (!isDirectory)) - { - if (path.IndexOf("//www") == 0) - { - Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative); - StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri); - if (streamInfo != null) - { - FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true); - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId); - - //using (BinaryReader br = new BinaryReader(streamInfo.Stream)) - //{ - // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length); - - //} - - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - - - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - return; - } - if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile))) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId); - return; - } - } - FileEntry entry = FileEntry.GetEntry(path); - if (entry != null) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId); - } - } - } - catch (Exception ex) - { - if (!this.HandleException(ex)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId); - } - } - } - - private static string AddSlashToDirectory(string dirPath) - { - if (dirPath.EndsWith("/")) - { - return dirPath; - } - else - { - return dirPath + "/"; - } - } - - /// <summary> - /// Returns file content in a form of base64 string - /// </summary> - /// <param name="stream">File stream</param> - /// <returns>Base64 representation of the file</returns> - private string GetFileContent(Stream stream) - { - int streamLength = (int)stream.Length; - byte[] fileData = new byte[streamLength + 1]; - stream.Read(fileData, 0, streamLength); - stream.Close(); - return Convert.ToBase64String(fileData); - } - - #endregion - - } -} diff --git a/plugins/cordova-plugin-file/tests/plugin.xml b/plugins/cordova-plugin-file/tests/plugin.xml deleted file mode 100644 index 6c2b1efc..00000000 --- a/plugins/cordova-plugin-file/tests/plugin.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:rim="http://www.blackberry.com/ns/widgets" - xmlns:android="http://schemas.android.com/apk/res/android" - id="cordova-plugin-file-tests" - version="2.1.0"> - - <name>Cordova File Plugin Tests</name> - <license>Apache 2.0</license> - - <js-module src="tests.js" name="tests"> - </js-module> - - <platform name="android"> - <source-file src="src/android/TestContentProvider.java" target-dir="src/org/apache/cordova/file/test" /> - <config-file target="AndroidManifest.xml" parent="/*/application"> - <provider - android:name="org.apache.cordova.file.test.TestContentProvider" - android:authorities="org.apache.cordova.file.testprovider" - android:exported="false" /> - </config-file> - </platform> -</plugin> diff --git a/plugins/cordova-plugin-file/tests/src/android/TestContentProvider.java b/plugins/cordova-plugin-file/tests/src/android/TestContentProvider.java deleted file mode 100644 index cf4fadf3..00000000 --- a/plugins/cordova-plugin-file/tests/src/android/TestContentProvider.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.file.test; - -import android.content.ContentProvider; -import android.net.Uri; -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import android.content.ContentValues; -import android.database.Cursor; -import android.os.ParcelFileDescriptor; - -import org.apache.cordova.CordovaResourceApi; - -import java.io.IOException; -import java.util.HashMap; - -public class TestContentProvider extends ContentProvider { - - @Override - public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - String fileName = uri.getQueryParameter("realPath"); - if (fileName == null) { - fileName = uri.getPath(); - } - if (fileName == null || fileName.length() < 1) { - throw new FileNotFoundException(); - } - CordovaResourceApi resourceApi = new CordovaResourceApi(getContext(), null); - try { - File f = File.createTempFile("test-content-provider", ".tmp"); - resourceApi.copyResource(Uri.parse("file:///android_asset" + fileName), Uri.fromFile(f)); - FileInputStream fis = new FileInputStream(f); - String thisIsDumb = fis.getFD().toString(); - int fd = Integer.parseInt(thisIsDumb.substring("FileDescriptor[".length(), thisIsDumb.length() - 1)); - return ParcelFileDescriptor.adoptFd(fd); - } catch (FileNotFoundException e) { - throw e; - } catch (IOException e) { - e.printStackTrace(); - throw new FileNotFoundException("IO error: " + e.toString()); - } - } - - @Override - public boolean onCreate() { - return false; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - throw new UnsupportedOperationException(); - } - - @Override - public String getType(Uri uri) { - return "text/html"; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - throw new UnsupportedOperationException(); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException(); - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException(); - } - - -} diff --git a/plugins/cordova-plugin-file/tests/tests.js b/plugins/cordova-plugin-file/tests/tests.js deleted file mode 100644 index a46ba800..00000000 --- a/plugins/cordova-plugin-file/tests/tests.js +++ /dev/null @@ -1,3681 +0,0 @@ -/* - * - * 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. - * - */ - -/*global cordova, exports*/ -/*jshint jasmine: true*/ -/*global FileError, LocalFileSystem, Metadata, Flags*/ - -exports.defineAutoTests = function () { - var isBrowser = (cordova.platformId === "browser"); - // Use feature detection to determine current browser instead of checking user-agent - var isChrome = isBrowser && window.webkitRequestFileSystem && window.webkitResolveLocalFileSystemURL; - var isIE = isBrowser && (window.msIndexedDB); - var isIndexedDBShim = isBrowser && !isChrome; // Firefox and IE for example - - var isWindows = (cordova.platformId === "windows" || cordova.platformId === "windows8"); - - var MEDIUM_TIMEOUT = 15000; - var LONG_TIMEOUT = 60000; - - describe('File API', function () { - // Adding a Jasmine helper matcher, to report errors when comparing to FileError better. - var fileErrorMap = { - 1 : 'NOT_FOUND_ERR', - 2 : 'SECURITY_ERR', - 3 : 'ABORT_ERR', - 4 : 'NOT_READABLE_ERR', - 5 : 'ENCODING_ERR', - 6 : 'NO_MODIFICATION_ALLOWED_ERR', - 7 : 'INVALID_STATE_ERR', - 8 : 'SYNTAX_ERR', - 9 : 'INVALID_MODIFICATION_ERR', - 10 : 'QUOTA_EXCEEDED_ERR', - 11 : 'TYPE_MISMATCH_ERR', - 12 : 'PATH_EXISTS_ERR' - }, - root, - temp_root, - persistent_root; - beforeEach(function (done) { - // Custom Matchers - jasmine.Expectation.addMatchers({ - toBeFileError : function () { - return { - compare : function (error, code) { - var pass = error.code === code; - return { - pass : pass, - message : 'Expected FileError with code ' + fileErrorMap[error.code] + ' (' + error.code + ') to be ' + fileErrorMap[code] + '(' + code + ')' - }; - } - }; - }, - toCanonicallyMatch : function () { - return { - compare : function (currentPath, path) { - var a = path.split("/").join("").split("\\").join(""), - b = currentPath.split("/").join("").split("\\").join(""), - pass = a === b; - return { - pass : pass, - message : 'Expected paths to match : ' + path + ' should be ' + currentPath - }; - } - }; - }, - toFailWithMessage : function () { - return { - compare : function (error, message) { - var pass = false; - return { - pass : pass, - message : message - }; - } - }; - }, - toBeDataUrl: function () { - return { - compare : function (url) { - var pass = false; - // "data:application/octet-stream;base64," - var header = url.substr(0, url.indexOf(',')); - var headerParts = header.split(/[:;]/); - if (headerParts.length === 3 && - headerParts[0] === 'data' && - headerParts[2] === 'base64') { - pass = true; - } - var message = 'Expected ' + url + ' to be a valid data url. ' + header + ' is not valid header for data uris'; - return { - pass : pass, - message : message - }; - } - }; - } - }); - //Define global variables - var onError = function (e) { - console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.'); - console.log(JSON.stringify(e)); - }; - window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) { - root = fileSystem.root; - // set in file.tests.js - persistent_root = root; - window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function (fileSystem) { - temp_root = fileSystem.root; - // set in file.tests.js - done(); - }, onError); - }, onError); - }); - // HELPER FUNCTIONS - // deletes specified file or directory - var deleteEntry = function (name, success, error) { - // deletes entry, if it exists - // entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface - success = success || function() {}; - error = error || failed.bind(null, success, 'deleteEntry failed.'); - - window.resolveLocalFileSystemURL(root.toURL() + '/' + name, function (entry) { - if (entry.isDirectory === true) { - entry.removeRecursively(success, error); - } else { - entry.remove(success, error); - } - }, success); - }; - // deletes file, if it exists, then invokes callback - var deleteFile = function (fileName, callback) { - // entry.remove success callback is required: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#the-entry-interface - callback = callback || function() {}; - - root.getFile(fileName, null, // remove file system entry - function (entry) { - entry.remove(callback, function () { - console.log('[ERROR] deleteFile cleanup method invoked fail callback.'); - }); - }, // doesn't exist - callback); - }; - // deletes and re-creates the specified file - var createFile = function (fileName, success, error) { - deleteEntry(fileName, function () { - root.getFile(fileName, { - create : true - }, success, error); - }, error); - }; - // deletes and re-creates the specified directory - var createDirectory = function (dirName, success, error) { - deleteEntry(dirName, function () { - root.getDirectory(dirName, { - create : true - }, success, error); - }, error); - }; - var failed = function (done, msg, error) { - var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg; - var codeMsg = (error && error.code) ? (': ' + fileErrorMap[error.code]) : ''; - expect(true).toFailWithMessage(info + '\n' + JSON.stringify(error) + codeMsg); - done(); - }; - var succeed = function (done, msg) { - var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg; - expect(true).toFailWithMessage(info); - done(); - }; - var joinURL = function (base, extension) { - if (base.charAt(base.length - 1) !== '/' && extension.charAt(0) !== '/') { - return base + '/' + extension; - } - if (base.charAt(base.length - 1) === '/' && extension.charAt(0) === '/') { - return base + extension.substring(1); - } - return base + extension; - }; - describe('FileError object', function () { - it("file.spec.1 should define FileError constants", function () { - expect(FileError.NOT_FOUND_ERR).toBe(1); - expect(FileError.SECURITY_ERR).toBe(2); - expect(FileError.ABORT_ERR).toBe(3); - expect(FileError.NOT_READABLE_ERR).toBe(4); - expect(FileError.ENCODING_ERR).toBe(5); - expect(FileError.NO_MODIFICATION_ALLOWED_ERR).toBe(6); - expect(FileError.INVALID_STATE_ERR).toBe(7); - expect(FileError.SYNTAX_ERR).toBe(8); - expect(FileError.INVALID_MODIFICATION_ERR).toBe(9); - expect(FileError.QUOTA_EXCEEDED_ERR).toBe(10); - expect(FileError.TYPE_MISMATCH_ERR).toBe(11); - expect(FileError.PATH_EXISTS_ERR).toBe(12); - }); - }); - describe('LocalFileSystem', function () { - it("file.spec.2 should define LocalFileSystem constants", function () { - expect(LocalFileSystem.TEMPORARY).toBe(0); - expect(LocalFileSystem.PERSISTENT).toBe(1); - }); - describe('window.requestFileSystem', function () { - it("file.spec.3 should be defined", function () { - expect(window.requestFileSystem).toBeDefined(); - }); - it("file.spec.4 should be able to retrieve a PERSISTENT file system", function (done) { - var win = function (fileSystem) { - expect(fileSystem).toBeDefined(); - expect(fileSystem.name).toBeDefined(); - isChrome ? expect(fileSystem.name).toContain("Persistent") - : expect(fileSystem.name).toBe("persistent"); - expect(fileSystem.root).toBeDefined(); - expect(fileSystem.root.filesystem).toBeDefined(); - // Shouldn't use cdvfile by default. - expect(fileSystem.root.toURL()).not.toMatch(/^cdvfile:/); - // All DirectoryEntry URLs should always have a trailing slash. - expect(fileSystem.root.toURL()).toMatch(/\/$/); - done(); - }; - // retrieve PERSISTENT file system - window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, win, failed.bind(null, done, 'window.requestFileSystem - Error retrieving PERSISTENT file system')); - }); - it("file.spec.5 should be able to retrieve a TEMPORARY file system", function (done) { - var win = function (fileSystem) { - expect(fileSystem).toBeDefined(); - isChrome ? expect(fileSystem.name).toContain("Temporary") - : expect(fileSystem.name).toBe("temporary"); - expect(fileSystem.root).toBeDefined(); - expect(fileSystem.root.filesystem).toBeDefined(); - expect(fileSystem.root.filesystem).toBe(fileSystem); - done(); - }; - //retrieve TEMPORARY file system - window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, win, failed.bind(null, done, 'window.requestFileSystem - Error retrieving TEMPORARY file system')); - }); - it("file.spec.6 should error if you request a file system that is too large", function (done) { - if (isBrowser) { - /*window.requestFileSystem TEMPORARY and PERSISTENT filesystem quota is not limited in Chrome. - Firefox filesystem size is not limited but every 50MB request user permission. - IE10 allows up to 10mb of combined AppCache and IndexedDB used in implementation - of filesystem without prompting, once you hit that level you will be asked if you - want to allow it to be increased up to a max of 250mb per site. - So `size` parameter for `requestFileSystem` function does not affect on filesystem in Firefox and IE.*/ - pending(); - } - - var fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.QUOTA_EXCEEDED_ERR); - done(); - }; - //win = createWin('window.requestFileSystem'); - // Request the file system - window.requestFileSystem(LocalFileSystem.TEMPORARY, 1000000000000000, failed.bind(null, done, 'window.requestFileSystem - Error retrieving TEMPORARY file system'), fail); - }); - it("file.spec.7 should error out if you request a file system that does not exist", function (done) { - - var fail = function (error) { - expect(error).toBeDefined(); - if (isChrome) { - /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of SYNTAX_ERR(code: 8) - on requesting of a non-existant filesystem.*/ - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - } else { - expect(error).toBeFileError(FileError.SYNTAX_ERR); - } - done(); - }; - // Request the file system - window.requestFileSystem(-1, 0, succeed.bind(null, done, 'window.requestFileSystem'), fail); - }); - }); - describe('window.resolveLocalFileSystemURL', function () { - it("file.spec.8 should be defined", function () { - expect(window.resolveLocalFileSystemURL).toBeDefined(); - }); - it("file.spec.9 should resolve a valid file name", function (done) { - var fileName = 'file.spec.9'; - var win = function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.name).toCanonicallyMatch(fileName); - expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL'); - expect(fileEntry.toURL()).not.toMatch(/\/$/, 'URL should not end with a slash'); - // Clean-up - deleteEntry(fileName, done); - }; - createFile(fileName, function (entry) { - window.resolveLocalFileSystemURL(entry.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toURL())); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName), failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.9.5 should resolve a directory", function (done) { - var fileName = 'file.spec.9.5'; - var win = function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.name).toCanonicallyMatch(fileName); - expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL'); - expect(fileEntry.toURL()).toMatch(/\/$/, 'URL end with a slash'); - // cleanup - deleteEntry(fileName, done); - }; - function gotDirectory(entry) { - // lookup file system entry - window.resolveLocalFileSystemURL(entry.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving directory URL: ' + entry.toURL())); - } - createDirectory(fileName, gotDirectory, failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName), failed.bind(null, done, 'createDirectory - Error creating directory: ' + fileName)); - }); - it("file.spec.10 resolve valid file name with parameters", function (done) { - var fileName = "resolve.file.uri.params", - win = function (fileEntry) { - expect(fileEntry).toBeDefined(); - if (fileEntry.toURL().toLowerCase().substring(0, 10) === "cdvfile://") { - expect(fileEntry.fullPath).toBe("/" + fileName + "?1234567890"); - } - expect(fileEntry.name).toBe(fileName); - // cleanup - deleteEntry(fileName, done); - }; - // create a new file entry - createFile(fileName, function (entry) { - window.resolveLocalFileSystemURL(entry.toURL() + "?1234567890", win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URI: ' + entry.toURL())); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.11 should error (NOT_FOUND_ERR) when resolving (non-existent) invalid file name", function (done) { - var fileName = cordova.platformId === 'windowsphone' ? root.toURL() + "/" + "this.is.not.a.valid.file.txt" : joinURL(root.toURL(), "this.is.not.a.valid.file.txt"); - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }; - // lookup file system entry - window.resolveLocalFileSystemURL(fileName, succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Error unexpected callback resolving file URI: ' + fileName), fail); - }); - it("file.spec.12 should error (ENCODING_ERR) when resolving invalid URI with leading /", function (done) { - var fileName = "/this.is.not.a.valid.url", - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.ENCODING_ERR); - done(); - }; - // lookup file system entry - window.resolveLocalFileSystemURL(fileName, succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Error unexpected callback resolving file URI: ' + fileName), fail); - }); - }); - }); - //LocalFileSystem - describe('Metadata interface', function () { - it("file.spec.13 should exist and have the right properties", function () { - var metadata = new Metadata(); - expect(metadata).toBeDefined(); - expect(metadata.modificationTime).toBeDefined(); - }); - }); - describe('Flags interface', function () { - it("file.spec.14 should exist and have the right properties", function () { - var flags = new Flags(false, true); - expect(flags).toBeDefined(); - expect(flags.create).toBeDefined(); - expect(flags.create).toBe(false); - expect(flags.exclusive).toBeDefined(); - expect(flags.exclusive).toBe(true); - }); - }); - describe('FileSystem interface', function () { - it("file.spec.15 should have a root that is a DirectoryEntry", function (done) { - var win = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(false); - expect(entry.isDirectory).toBe(true); - expect(entry.name).toBeDefined(); - expect(entry.fullPath).toBeDefined(); - expect(entry.getMetadata).toBeDefined(); - expect(entry.moveTo).toBeDefined(); - expect(entry.copyTo).toBeDefined(); - expect(entry.toURL).toBeDefined(); - expect(entry.remove).toBeDefined(); - expect(entry.getParent).toBeDefined(); - expect(entry.createReader).toBeDefined(); - expect(entry.getFile).toBeDefined(); - expect(entry.getDirectory).toBeDefined(); - expect(entry.removeRecursively).toBeDefined(); - done(); - }; - window.resolveLocalFileSystemURL(root.toURL(), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving file URI: ' + root.toURL())); - }); - }); - describe('DirectoryEntry', function () { - it("file.spec.16 getFile: get Entry for file that does not exist", function (done) { - var fileName = "de.no.file", - filePath = joinURL(root.fullPath, fileName), - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }; - // create:false, exclusive:false, file does not exist - root.getFile(fileName, { - create : false - }, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName), fail); - }); - it("file.spec.17 getFile: create new file", function (done) { - var fileName = "de.create.file", - filePath = joinURL(root.fullPath, fileName), - win = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(fileName); - expect(entry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(entry.name, done); - }; - // create:true, exclusive:false, file does not exist - root.getFile(fileName, { - create : true - }, win, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName)); - }); - it("file.spec.18 getFile: create new file (exclusive)", function (done) { - var fileName = "de.create.exclusive.file", - filePath = joinURL(root.fullPath, fileName), - win = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toBe(fileName); - expect(entry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(entry.name, done); - }; - // create:true, exclusive:true, file does not exist - root.getFile(fileName, { - create : true, - exclusive : true - }, win, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }); - it("file.spec.19 getFile: create file that already exists", function (done) { - var fileName = "de.create.existing.file", - filePath = joinURL(root.fullPath, fileName), - getFile = function (file) { - // create:true, exclusive:false, file exists - root.getFile(fileName, { - create : true - }, win, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }, - win = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(fileName); - expect(entry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(entry.name, done); - }; - // create file to kick off it - root.getFile(fileName, { - create : true - }, getFile, failed.bind(null, done, 'root.getFile - Error on initial creating file: ' + fileName)); - }); - it("file.spec.20 getFile: create file that already exists (exclusive)", function (done) { - - var fileName = "de.create.exclusive.existing.file", - filePath = joinURL(root.fullPath, fileName), - existingFile, - getFile = function (file) { - existingFile = file; - // create:true, exclusive:true, file exists - root.getFile(fileName, { - create : true, - exclusive : true - }, succeed.bind(null, done, 'root.getFile - getFile function - Error unexpected callback, file should exists: ' + fileName), fail); - }, - fail = function (error) { - expect(error).toBeDefined(); - if (isChrome) { - /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12) - on trying to exclusively create a file, which already exists in Chrome.*/ - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - } else { - expect(error).toBeFileError(FileError.PATH_EXISTS_ERR); - } - // cleanup - deleteEntry(existingFile.name, done); - }; - // create file to kick off it - root.getFile(fileName, { - create : true - }, getFile, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }); - it("file.spec.21 DirectoryEntry.getFile: get Entry for existing file", function (done) { - var fileName = "de.get.file", - filePath = joinURL(root.fullPath, fileName), - win = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(fileName); - expect(entry.fullPath).toCanonicallyMatch(filePath); - expect(entry.filesystem).toBeDefined(); - expect(entry.filesystem).toBe(root.filesystem); - //clean up - deleteEntry(entry.name, done); - }, - getFile = function (file) { - // create:false, exclusive:false, file exists - root.getFile(fileName, { - create : false - }, win, failed.bind(null, done, 'root.getFile - Error getting file entry: ' + fileName)); - }; - // create file to kick off it - root.getFile(fileName, { - create : true - }, getFile, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }); - it("file.spec.22 DirectoryEntry.getFile: get FileEntry for invalid path", function (done) { - if (isBrowser) { - /*The plugin does not follow to ["8.3 Naming restrictions"] - (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).*/ - pending(); - } - - var fileName = "de:invalid:path", - fail = function (error) { - console.error(error); - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.ENCODING_ERR); - done(); - }; - // create:false, exclusive:false, invalid path - root.getFile(fileName, { - create : false - }, succeed.bind(null, done, 'root.getFile - Error unexpected callback, file should not exists: ' + fileName), fail); - }); - it("file.spec.23 DirectoryEntry.getDirectory: get Entry for directory that does not exist", function (done) { - var dirName = "de.no.dir", - dirPath = joinURL(root.fullPath, dirName), - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }; - // create:false, exclusive:false, directory does not exist - root.getDirectory(dirName, { - create : false - }, succeed.bind(null, done, 'root.getDirectory - Error unexpected callback, directory should not exists: ' + dirName), fail); - }); - it("file.spec.24 DirectoryEntry.getDirectory: create new dir with space then resolveLocalFileSystemURL", function (done) { - var dirName = "de create dir", - dirPath = joinURL(root.fullPath, encodeURIComponent(dirName)), - getDir = function (dirEntry) { - expect(dirEntry.filesystem).toBeDefined(); - expect(dirEntry.filesystem).toBe(root.filesystem); - var dirURI = dirEntry.toURL(); - // now encode URI and try to resolve - window.resolveLocalFileSystemURL(dirURI, win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - getDir function - Error resolving directory: ' + dirURI)); - }, - win = function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - expect(directory.fullPath).toCanonicallyMatch(joinURL(root.fullPath, dirName)); - // cleanup - deleteEntry(directory.name, done); - }; - // create:true, exclusive:false, directory does not exist - root.getDirectory(dirName, { - create : true - }, getDir, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - // This test is excluded, and should probably be removed. Filesystem - // should always be properly encoded URLs, and *not* raw paths, and it - // doesn't make sense to double-encode the URLs and expect that to be - // handled by the implementation. - // If a particular platform uses paths internally rather than URLs, // then that platform should careful to pass them correctly to its - // backend. - xit("file.spec.25 DirectoryEntry.getDirectory: create new dir with space resolveLocalFileSystemURL with encoded URI", function (done) { - var dirName = "de create dir2", - dirPath = joinURL(root.fullPath, dirName), - getDir = function (dirEntry) { - var dirURI = dirEntry.toURL(); - // now encode URI and try to resolve - window.resolveLocalFileSystemURL(encodeURI(dirURI), win, failed.bind(null, done, 'window.resolveLocalFileSystemURL - getDir function - Error resolving directory: ' + dirURI)); - }, - win = function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - expect(directory.fullPath).toCanonicallyMatch(dirPath); - // cleanup - deleteEntry(directory.name, done); - }; - // create:true, exclusive:false, directory does not exist - root.getDirectory(dirName, { - create : true - }, getDir, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.26 DirectoryEntry.getDirectory: create new directory", function (done) { - var dirName = "de.create.dir", - dirPath = joinURL(root.fullPath, dirName), - win = function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - expect(directory.fullPath).toCanonicallyMatch(dirPath); - expect(directory.filesystem).toBeDefined(); - expect(directory.filesystem).toBe(root.filesystem); - // cleanup - deleteEntry(directory.name, done); - }; - // create:true, exclusive:false, directory does not exist - root.getDirectory(dirName, { - create : true - }, win, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.27 DirectoryEntry.getDirectory: create new directory (exclusive)", function (done) { - var dirName = "de.create.exclusive.dir", - dirPath = joinURL(root.fullPath, dirName), - win = function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - expect(directory.fullPath).toCanonicallyMatch(dirPath); - expect(directory.filesystem).toBeDefined(); - expect(directory.filesystem).toBe(root.filesystem); - // cleanup - deleteEntry(directory.name, done); - }; - // create:true, exclusive:true, directory does not exist - root.getDirectory(dirName, { - create : true, - exclusive : true - }, win, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.28 DirectoryEntry.getDirectory: create directory that already exists", function (done) { - var dirName = "de.create.existing.dir", - dirPath = joinURL(root.fullPath, dirName), - win = function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - expect(directory.fullPath).toCanonicallyMatch(dirPath); - // cleanup - deleteEntry(directory.name, done); - }; - // create directory to kick off it - root.getDirectory(dirName, { - create : true - }, function () { - root.getDirectory(dirName, { - create : true - }, win, failed.bind(null, done, 'root.getDirectory - Error creating existent second directory : ' + dirName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.29 DirectoryEntry.getDirectory: create directory that already exists (exclusive)", function (done) { - - var dirName = "de.create.exclusive.existing.dir", - dirPath = joinURL(root.fullPath, dirName), - existingDir, - fail = function (error) { - expect(error).toBeDefined(); - if (isChrome) { - /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of PATH_EXISTS_ERR(code: 12) - on trying to exclusively create a file or directory, which already exists (Chrome).*/ - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - } else { - expect(error).toBeFileError(FileError.PATH_EXISTS_ERR); - } - // cleanup - deleteEntry(existingDir.name, done); - }; - // create directory to kick off it - root.getDirectory(dirName, { - create : true - }, function (directory) { - existingDir = directory; - // create:true, exclusive:true, directory exists - root.getDirectory(dirName, { - create : true, - exclusive : true - }, failed.bind(null, done, 'root.getDirectory - Unexpected success callback, second directory should not be created : ' + dirName), fail); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.30 DirectoryEntry.getDirectory: get Entry for existing directory", function (done) { - var dirName = "de.get.dir", - dirPath = joinURL(root.fullPath, dirName), - win = function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - expect(directory.fullPath).toCanonicallyMatch(dirPath); - // cleanup - deleteEntry(directory.name, done); - }; - // create directory to kick it off - root.getDirectory(dirName, { - create : true - }, function () { - root.getDirectory(dirName, { - create : false - }, win, failed.bind(null, done, 'root.getDirectory - Error getting directory entry : ' + dirName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.31 DirectoryEntry.getDirectory: get DirectoryEntry for invalid path", function (done) { - if (isBrowser) { - /*The plugin does not follow to ["8.3 Naming restrictions"] - (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions).*/ - pending(); - } - - var dirName = "de:invalid:path", - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.ENCODING_ERR); - done(); - }; - // create:false, exclusive:false, invalid path - root.getDirectory(dirName, { - create : false - }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + dirName), fail); - }); - it("file.spec.32 DirectoryEntry.getDirectory: get DirectoryEntry for existing file", function (done) { - var fileName = "de.existing.file", - existingFile, - filePath = joinURL(root.fullPath, fileName), - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR); - // cleanup - deleteEntry(existingFile.name, done); - }; - // create file to kick off it - root.getFile(fileName, { - create : true - }, function (file) { - existingFile = file; - root.getDirectory(fileName, { - create : false - }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + fileName), fail); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName)); - }); - it("file.spec.33 DirectoryEntry.getFile: get FileEntry for existing directory", function (done) { - var dirName = "de.existing.dir", - existingDir, - dirPath = joinURL(root.fullPath, dirName), - fail = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR); - // cleanup - deleteEntry(existingDir.name, done); - }; - // create directory to kick off it - root.getDirectory(dirName, { - create : true - }, function (directory) { - existingDir = directory; - root.getFile(dirName, { - create : false - }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, file should not exists: ' + dirName), fail); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.34 DirectoryEntry.removeRecursively on directory", function (done) { - var dirName = "de.removeRecursively", - subDirName = "dir", - dirPath = joinURL(root.fullPath, dirName), - subDirPath = joinURL(dirPath, subDirName), - dirExists = function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }; - // create a new directory entry to kick off it - root.getDirectory(dirName, { - create : true - }, function (entry) { - entry.getDirectory(subDirName, { - create : true - }, function (dir) { - entry.removeRecursively(function () { - root.getDirectory(dirName, { - create : false - }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory should not exists: ' + dirName), dirExists); - }, failed.bind(null, done, 'entry.removeRecursively - Error removing directory recursively : ' + dirName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + subDirName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.35 createReader: create reader on existing directory", function () { - // create reader for root directory - var reader = root.createReader(); - expect(reader).toBeDefined(); - expect(typeof reader.readEntries).toBe('function'); - }); - it("file.spec.36 removeRecursively on root file system", function (done) { - - var remove = function (error) { - expect(error).toBeDefined(); - if (isChrome) { - /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of - NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively - on the root file system (Chrome).*/ - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - } else { - expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR); - } - done(); - }; - // remove root file system - root.removeRecursively(succeed.bind(null, done, 'root.removeRecursively - Unexpected success callback, root cannot be removed'), remove); - }); - }); - describe('DirectoryReader interface', function () { - describe("readEntries", function () { - it("file.spec.37 should read contents of existing directory", function (done) { - var reader, - win = function (entries) { - expect(entries).toBeDefined(); - expect(entries instanceof Array).toBe(true); - done(); - }; - // create reader for root directory - reader = root.createReader(); - // read entries - reader.readEntries(win, failed.bind(null, done, 'reader.readEntries - Error reading entries')); - }); - it("file.spec.37.1 should read contents of existing directory", function (done) { - var dirName = 'readEntries.dir', - fileName = 'readeEntries.file'; - root.getDirectory(dirName, { - create : true - }, function (directory) { - directory.getFile(fileName, { - create : true - }, function (fileEntry) { - var reader = directory.createReader(); - reader.readEntries(function (entries) { - expect(entries).toBeDefined(); - expect(entries instanceof Array).toBe(true); - expect(entries.length).toBe(1); - expect(entries[0].fullPath).toCanonicallyMatch(fileEntry.fullPath); - expect(entries[0].filesystem).not.toBe(null); - if (isChrome) { - // Slicing '[object {type}]' -> '{type}' - expect(entries[0].filesystem.toString().slice(8, -1)).toEqual("DOMFileSystem"); - } - else { - expect(entries[0].filesystem instanceof FileSystem).toBe(true); - } - - // cleanup - deleteEntry(directory.name, done); - }, failed.bind(null, done, 'reader.readEntries - Error reading entries from directory: ' + dirName)); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + fileName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.109 should return an empty entry list on the second call", function (done) { - var reader, - fileName = 'test109.txt'; - // Add a file to ensure the root directory is non-empty and then read the contents of the directory. - root.getFile(fileName, { - create : true - }, function (entry) { - reader = root.createReader(); - //First read - reader.readEntries(function (entries) { - expect(entries).toBeDefined(); - expect(entries instanceof Array).toBe(true); - expect(entries.length).not.toBe(0); - //Second read - reader.readEntries(function (entries_) { - expect(entries_).toBeDefined(); - expect(entries_ instanceof Array).toBe(true); - expect(entries_.length).toBe(0); - //Clean up - deleteEntry(entry.name, done); - }, failed.bind(null, done, 'reader.readEntries - Error during SECOND reading of entries from [root] directory')); - }, failed.bind(null, done, 'reader.readEntries - Error during FIRST reading of entries from [root] directory')); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName)); - }); - }); - it("file.spec.38 should read contents of directory that has been removed", function (done) { - var dirName = "de.createReader.notfound", - dirPath = joinURL(root.fullPath, dirName); - // create a new directory entry to kick off it - root.getDirectory(dirName, { - create : true - }, function (directory) { - directory.removeRecursively(function () { - var reader = directory.createReader(); - reader.readEntries(succeed.bind(null, done, 'reader.readEntries - Unexpected success callback, it should not read entries from deleted dir: ' + dirName), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - root.getDirectory(dirName, { - create : false - }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, it should not get deleted directory: ' + dirName), function (err) { - expect(err).toBeDefined(); - expect(err).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }); - }); - }, failed.bind(null, done, 'directory.removeRecursively - Error removing directory recursively : ' + dirName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - }); - //DirectoryReader interface - describe('File', function () { - it("file.spec.39 constructor should be defined", function () { - expect(File).toBeDefined(); - expect(typeof File).toBe('function'); - }); - it("file.spec.40 should be define File attributes", function () { - var file = new File(); - expect(file.name).toBeDefined(); - expect(file.type).toBeDefined(); - expect(file.lastModifiedDate).toBeDefined(); - expect(file.size).toBeDefined(); - }); - }); - //File - describe('FileEntry', function () { - - it("file.spec.41 should be define FileEntry methods", function (done) { - var fileName = "fe.methods", - testFileEntry = function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(typeof fileEntry.createWriter).toBe('function'); - expect(typeof fileEntry.file).toBe('function'); - // cleanup - deleteEntry(fileEntry.name, done); - }; - // create a new file entry to kick off it - root.getFile(fileName, { - create : true - }, testFileEntry, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName)); - }); - it("file.spec.42 createWriter should return a FileWriter object", function (done) { - var fileName = "fe.createWriter", - testFile, - testWriter = function (writer) { - expect(writer).toBeDefined(); - if (isChrome) { - // Slicing '[object {type}]' -> '{type}' - expect(writer.toString().slice(8, -1)).toEqual("FileWriter"); - } - else { - expect(writer instanceof FileWriter).toBe(true); - } - - // cleanup - deleteEntry(testFile.name, done); - }; - // create a new file entry to kick off it - root.getFile(fileName, { - create : true - }, function (fileEntry) { - testFile = fileEntry; - fileEntry.createWriter(testWriter, failed.bind(null, done, 'fileEntry.createWriter - Error creating Writer from entry')); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName)); - }); - it("file.spec.43 file should return a File object", function (done) { - var fileName = "fe.file", - newFile, - testFile = function (file) { - expect(file).toBeDefined(); - if (isChrome) { - // Slicing '[object {type}]' -> '{type}' - expect(file.toString().slice(8, -1)).toEqual("File"); - } - else { - expect(file instanceof File).toBe(true); - } - - // cleanup - deleteEntry(newFile.name, done); - }; - // create a new file entry to kick off it - root.getFile(fileName, { - create : true - }, function (fileEntry) { - newFile = fileEntry; - fileEntry.file(testFile, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName)); - }); - it("file.spec.44 file: on File that has been removed", function (done) { - var fileName = "fe.no.file"; - // create a new file entry to kick off it - root.getFile(fileName, { - create : true - }, function (fileEntry) { - fileEntry.remove(function () { - fileEntry.file(succeed.bind(null, done, 'fileEntry.file - Unexpected success callback, file it should not be created from removed entry'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }); - }, failed.bind(null, done, 'fileEntry.remove - Error removing entry : ' + fileName)); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + fileName)); - }); - }); - //FileEntry - describe('Entry', function () { - it("file.spec.45 Entry object", function (done) { - var fileName = "entry", - fullPath = joinURL(root.fullPath, fileName), - winEntry = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(fileName); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - expect(typeof entry.getMetadata).toBe('function'); - expect(typeof entry.setMetadata).toBe('function'); - expect(typeof entry.moveTo).toBe('function'); - expect(typeof entry.copyTo).toBe('function'); - expect(typeof entry.toURL).toBe('function'); - expect(typeof entry.remove).toBe('function'); - expect(typeof entry.getParent).toBe('function'); - expect(typeof entry.createWriter).toBe('function'); - expect(typeof entry.file).toBe('function'); - // Clean up - deleteEntry(fileName, done); - }; - // create a new file entry - createFile(fileName, winEntry, failed.bind(null, done, 'createFile - Error creating file : ' + fileName)); - }); - it("file.spec.46 Entry.getMetadata on file", function (done) { - var fileName = "entry.metadata.file"; - // create a new file entry - createFile(fileName, function (entry) { - entry.getMetadata(function (metadata) { - expect(metadata).toBeDefined(); - expect(metadata.modificationTime instanceof Date).toBe(true); - expect(typeof metadata.size).toBe("number"); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'entry.getMetadata - Error getting metadata from entry : ' + fileName)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName)); - }); - it("file.spec.47 Entry.getMetadata on directory", function (done) { - if (isIndexedDBShim) { - /* Does not support metadata for directories (Firefox, IE) */ - pending(); - } - - var dirName = "entry.metadata.dir"; - // create a new directory entry - createDirectory(dirName, function (entry) { - entry.getMetadata(function (metadata) { - expect(metadata).toBeDefined(); - expect(metadata.modificationTime instanceof Date).toBe(true); - expect(typeof metadata.size).toBe("number"); - expect(metadata.size).toBe(0); - // cleanup - deleteEntry(dirName, done); - }, failed.bind(null, done, 'entry.getMetadata - Error getting metadata from entry : ' + dirName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.48 Entry.getParent on file in root file system", function (done) { - var fileName = "entry.parent.file", - rootPath = root.fullPath; - // create a new file entry - createFile(fileName, function (entry) { - entry.getParent(function (parent) { - expect(parent).toBeDefined(); - expect(parent.fullPath).toCanonicallyMatch(rootPath); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'entry.getParent - Error getting parent directory of file : ' + fileName)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName)); - }); - it("file.spec.49 Entry.getParent on directory in root file system", function (done) { - var dirName = "entry.parent.dir", - rootPath = root.fullPath; - // create a new directory entry - createDirectory(dirName, function (entry) { - entry.getParent(function (parent) { - expect(parent).toBeDefined(); - expect(parent.fullPath).toCanonicallyMatch(rootPath); - // cleanup - deleteEntry(dirName, done); - }, failed.bind(null, done, 'entry.getParent - Error getting parent directory of directory : ' + dirName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.50 Entry.getParent on root file system", function (done) { - var rootPath = root.fullPath, - winParent = function (parent) { - expect(parent).toBeDefined(); - expect(parent.fullPath).toCanonicallyMatch(rootPath); - done(); - }; - // create a new directory entry - root.getParent(winParent, failed.bind(null, done, 'root.getParent - Error getting parent directory of root')); - }); - it("file.spec.51 Entry.toURL on file", function (done) { - var fileName = "entry.uri.file", - rootPath = root.fullPath, - winURI = function (entry) { - var uri = entry.toURL(); - expect(uri).toBeDefined(); - expect(uri.indexOf(rootPath)).not.toBe(-1); - // cleanup - deleteEntry(fileName, done); - }; - // create a new file entry - createFile(fileName, winURI, failed.bind(null, done, 'createFile - Error creating file : ' + fileName)); - }); - it("file.spec.52 Entry.toURL on directory", function (done) { - var dirName_1 = "num 1", - dirName_2 = "num 2", - rootPath = root.fullPath; - createDirectory(dirName_1, function (entry) { - entry.getDirectory(dirName_2, { - create : true - }, function (entryFile) { - var uri = entryFile.toURL(); - expect(uri).toBeDefined(); - expect(uri).toContain('/num%201/num%202/'); - expect(uri.indexOf(rootPath)).not.toBe(-1); - // cleanup - deleteEntry(dirName_1, done); - }, failed.bind(null, done, 'entry.getDirectory - Error creating directory : ' + dirName_2)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName_1)); - }); - it("file.spec.53 Entry.remove on file", function (done) { - var fileName = "entr .rm.file"; - // create a new file entry - createFile(fileName, function (entry) { - expect(entry).toBeDefined(); - entry.remove(function () { - root.getFile(fileName, null, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get deleted file : ' + fileName), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(fileName, done); - }); - }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + fileName)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + fileName)); - }); - it("file.spec.54 remove on empty directory", function (done) { - var dirName = "entry.rm.dir"; - // create a new directory entry - createDirectory(dirName, function (entry) { - expect(entry).toBeDefined(); - entry.remove(function () { - root.getDirectory(dirName, null, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, it should not get deleted directory : ' + dirName), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(dirName, done); - }); - }, failed.bind(null, done, 'entry.remove - Error removing entry : ' + dirName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.55 remove on non-empty directory", function (done) { - if (isIndexedDBShim) { - /* Both Entry.remove and directoryEntry.removeRecursively don't fail when removing - non-empty directories - directories being removed are cleaned - along with contents instead (Firefox, IE)*/ - pending(); - } - - var dirName = "ent y.rm.dir.not.empty", - fileName = "re ove.txt", - fullPath = joinURL(root.fullPath, dirName); - // create a new directory entry - createDirectory(dirName, function (entry) { - entry.getFile(fileName, { - create : true - }, function (fileEntry) { - entry.remove(succeed.bind(null, done, 'entry.remove - Unexpected success callback, it should not remove a directory that contains files : ' + dirName), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - root.getDirectory(dirName, null, function (entry) { - expect(entry).toBeDefined(); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - // cleanup - deleteEntry(dirName, done); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + dirName)); - }); - }, failed.bind(null, done, 'entry.getFile - Error creating file : ' + fileName + ' inside of ' + dirName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName)); - }); - it("file.spec.56 remove on root file system", function (done) { - - // remove entry that doesn't exist - root.remove(succeed.bind(null, done, 'entry.remove - Unexpected success callback, it should not remove entry that it does not exists'), function (error) { - expect(error).toBeDefined(); - if (isChrome) { - /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of - NO_MODIFICATION_ALLOWED_ERR(code: 6) on trying to call removeRecursively - on the root file system.*/ - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - } else { - expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR); - } - done(); - }); - }); - it("file.spec.57 copyTo: file", function (done) { - var file1 = "entry copy.file1", - file2 = "entry copy.file2", - fullPath = joinURL(root.fullPath, file2); - // create a new file entry to kick off it - deleteEntry(file2, function () { - createFile(file1, function (fileEntry) { - // copy file1 to file2 - fileEntry.copyTo(root, file2, function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - expect(entry.name).toCanonicallyMatch(file2); - root.getFile(file2, { - create : false - }, function (entry2) { - expect(entry2).toBeDefined(); - expect(entry2.isFile).toBe(true); - expect(entry2.isDirectory).toBe(false); - expect(entry2.fullPath).toCanonicallyMatch(fullPath); - expect(entry2.name).toCanonicallyMatch(file2); - // cleanup - deleteEntry(file1, function () { - deleteEntry(file2, done); - }); - }, failed.bind(null, done, 'root.getFile - Error getting copied file : ' + file2)); - }, failed.bind(null, done, 'fileEntry.copyTo - Error copying file : ' + file2)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'deleteEntry - Error removing file : ' + file2)); - }); - it("file.spec.58 copyTo: file onto itself", function (done) { - var file1 = "entry.copy.fos.file1"; - // create a new file entry to kick off it - createFile(file1, function (entry) { - // copy file1 onto itself - entry.copyTo(root, null, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy a null file'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - // cleanup - deleteEntry(file1, done); - }); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }); - it("file.spec.59 copyTo: directory", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.copy.srcDir", - dstDir = "entry.copy.dstDir", - dstPath = joinURL(root.fullPath, dstDir), - filePath = joinURL(dstPath, file1); - // create a new directory entry to kick off it - deleteEntry(dstDir, function () { - createDirectory(srcDir, function (directory) { - // create a file within new directory - directory.getFile(file1, { - create : true - }, function () { - directory.copyTo(root, dstDir, function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.fullPath).toCanonicallyMatch(dstPath); - expect(directory.name).toCanonicallyMatch(dstDir); - root.getDirectory(dstDir, { - create : false - }, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.isFile).toBe(false); - expect(dirEntry.isDirectory).toBe(true); - expect(dirEntry.fullPath).toCanonicallyMatch(dstPath); - expect(dirEntry.name).toCanonicallyMatch(dstDir); - dirEntry.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.isFile).toBe(true); - expect(fileEntry.isDirectory).toBe(false); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - expect(fileEntry.name).toCanonicallyMatch(file1); - // cleanup - deleteEntry(srcDir, function () { - deleteEntry(dstDir, done); - }); - }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1)); - }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory : ' + dstDir)); - }, failed.bind(null, done, 'directory.copyTo - Error copying directory : ' + srcDir + ' to :' + dstDir)); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.60 copyTo: directory to backup at same root directory", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.copy srcDirSame", - dstDir = "entry.copy srcDirSame-backup", - dstPath = joinURL(root.fullPath, dstDir), - filePath = joinURL(dstPath, file1); - // create a new directory entry to kick off it - deleteEntry(dstDir, function () { - createDirectory(srcDir, function (directory) { - directory.getFile(file1, { - create : true - }, function () { - directory.copyTo(root, dstDir, function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.fullPath).toCanonicallyMatch(dstPath); - expect(directory.name).toCanonicallyMatch(dstDir); - root.getDirectory(dstDir, { - create : false - }, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.isFile).toBe(false); - expect(dirEntry.isDirectory).toBe(true); - expect(dirEntry.fullPath).toCanonicallyMatch(dstPath); - expect(dirEntry.name).toCanonicallyMatch(dstDir); - dirEntry.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.isFile).toBe(true); - expect(fileEntry.isDirectory).toBe(false); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - expect(fileEntry.name).toCanonicallyMatch(file1); - // cleanup - deleteEntry(srcDir, function () { - deleteEntry(dstDir, done); - }); - }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1)); - }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory : ' + dstDir)); - }, failed.bind(null, done, 'directory.copyTo - Error copying directory : ' + srcDir + ' to :' + dstDir)); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.61 copyTo: directory onto itself", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.copy.dos.srcDir", - srcPath = joinURL(root.fullPath, srcDir), - filePath = joinURL(srcPath, file1); - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // create a file within new directory - directory.getFile(file1, { - create : true - }, function (fileEntry) { - // copy srcDir onto itself - directory.copyTo(root, null, succeed.bind(null, done, 'directory.copyTo - Unexpected success callback, it should not copy file: ' + srcDir + ' to a null destination'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - root.getDirectory(srcDir, { - create : false - }, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(srcPath); - dirEntry.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(srcDir, done); - }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1)); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir)); - }); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.62 copyTo: directory into itself", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var srcDir = "entry.copy.dis.srcDir", - dstDir = "entry.copy.dis.dstDir", - srcPath = joinURL(root.fullPath, srcDir); - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // copy source directory into itself - directory.copyTo(directory, dstDir, succeed.bind(null, done, 'directory.copyTo - Unexpected success callback, it should not copy a directory ' + srcDir + ' into itself'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - root.getDirectory(srcDir, { - create : false - }, function (dirEntry) { - // returning confirms existence so just check fullPath entry - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(srcPath); - // cleanup - deleteEntry(srcDir, done); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir)); - }); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.63 copyTo: directory that does not exist", function (done) { - var file1 = "entry.copy.dnf.file1", - dirName = 'dir-foo'; - createFile(file1, function (fileEntry) { - createDirectory(dirName, function (dirEntry) { - dirEntry.remove(function () { - fileEntry.copyTo(dirEntry, null, succeed.bind(null, done, 'fileEntry.copyTo - Unexpected success callback, it should not copy a file ' + file1 + ' into a removed directory'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }); - }, failed.bind(null, done, 'dirEntry.remove - Error removing directory : ' + dirName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dirName)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }); - it("file.spec.64 copyTo: invalid target name", function (done) { - if (isBrowser) { - /*The plugin does not follow ["8.3 Naming restrictions"] - (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions*/ - pending(); - } - - var file1 = "entry.copy.itn.file1", - file2 = "bad:file:name"; - // create a new file entry - createFile(file1, function (entry) { - // copy file1 to file2 - entry.copyTo(root, file2, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy a file ' + file1 + ' to an invalid file name: ' + file2), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.ENCODING_ERR); - // cleanup - deleteEntry(file1, done); - }); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }); - it("file.spec.65 moveTo: file to same parent", function (done) { - var file1 = "entry.move.fsp.file1", - file2 = "entry.move.fsp.file2", - dstPath = joinURL(root.fullPath, file2); - // create a new file entry to kick off it - createFile(file1, function (entry) { - // move file1 to file2 - entry.moveTo(root, file2, function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.fullPath).toCanonicallyMatch(dstPath); - expect(entry.name).toCanonicallyMatch(file2); - root.getFile(file2, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(dstPath); - root.getFile(file1, { - create : false - }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) { - //expect(navigator.fileMgr.testFileExists(srcPath) === false, "original file should not exist."); - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(file1, function () { - deleteEntry(file2, done); - }); - }); - }, failed.bind(null, done, 'root.getFile - Error getting file : ' + file2)); - }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to root as: ' + file2)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }); - it("file.spec.66 moveTo: file to new parent", function (done) { - var file1 = "entry.move.fnp.file1", - dir = "entry.move.fnp.dir", - dstPath = joinURL(joinURL(root.fullPath, dir), file1); - // ensure destination directory is cleaned up first - deleteEntry(dir, function () { - // create a new file entry to kick off it - createFile(file1, function (entry) { - // create a parent directory to move file to - root.getDirectory(dir, { - create : true - }, function (directory) { - // move file1 to new directory - // move the file - entry.moveTo(directory, null, function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.fullPath).toCanonicallyMatch(dstPath); - expect(entry.name).toCanonicallyMatch(file1); - // test the moved file exists - directory.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(dstPath); - root.getFile(file1, { - create : false - }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(file1, function () { - deleteEntry(dir, done); - }); - }); - }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + dir)); - }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to: ' + dir + ' with the same name')); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dir)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dir)); - }); - it("file.spec.67 moveTo: directory to same parent", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.move.dsp.srcDir", - dstDir = "entry.move.dsp.dstDir", - srcPath = joinURL(root.fullPath, srcDir), - dstPath = joinURL(root.fullPath, dstDir), - filePath = joinURL(dstPath, file1); - // ensure destination directory is cleaned up before it - deleteEntry(dstDir, function () { - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // create a file within directory - directory.getFile(file1, { - create : true - }, function () { - // move srcDir to dstDir - directory.moveTo(root, dstDir, function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.fullPath).toCanonicallyMatch(dstPath); - expect(directory.name).toCanonicallyMatch(dstDir); - // test that moved file exists in destination dir - directory.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // check that the moved file no longer exists in original dir - root.getFile(file1, { - create : false - }, succeed.bind(null, done, 'directory.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(srcDir, function() { - deleteEntry(dstDir, done); - }); - }); - }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + srcDir)); - }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir)); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.68 moveTo: directory to same parent with same name", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.move.dsp.srcDir", - dstDir = "entry.move.dsp.srcDir-backup", - srcPath = joinURL(root.fullPath, srcDir), - dstPath = joinURL(root.fullPath, dstDir), - filePath = joinURL(dstPath, file1); - // ensure destination directory is cleaned up before it - deleteEntry(dstDir, function () { - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // create a file within directory - directory.getFile(file1, { - create : true - }, function () { - // move srcDir to dstDir - directory.moveTo(root, dstDir, function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.fullPath).toCanonicallyMatch(dstPath); - expect(directory.name).toCanonicallyMatch(dstDir); - // check that moved file exists in destination dir - directory.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // check that the moved file no longer exists in original dir - root.getFile(file1, { - create : false - }, succeed.bind(null, done, 'directory.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(srcDir, function() { - deleteEntry(dstDir, done); - }); - }); - }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + srcDir)); - }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir)); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.69 moveTo: directory to new parent", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.move.dnp.srcDir", - dstDir = "entry.move.dnp.dstDir", - srcPath = joinURL(root.fullPath, srcDir), - dstPath = joinURL(root.fullPath, dstDir), - filePath = joinURL(dstPath, file1); - // ensure destination directory is cleaned up before it - deleteEntry(dstDir, function () { - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // create a file within directory - directory.getFile(file1, { - create : true - }, function () { - // move srcDir to dstDir - directory.moveTo(root, dstDir, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.isFile).toBe(false); - expect(dirEntry.isDirectory).toBe(true); - expect(dirEntry.fullPath).toCanonicallyMatch(dstPath); - expect(dirEntry.name).toCanonicallyMatch(dstDir); - // test that moved file exists in destination dir - dirEntry.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // test that the moved file no longer exists in original dir - root.getFile(file1, { - create : false - }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not get invalid or moved file: ' + file1), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(srcDir, function() { - deleteEntry(dstDir, done); - }); - }); - }, failed.bind(null, done, 'directory.getFile - Error getting file : ' + file1 + ' from: ' + dstDir)); - }, failed.bind(null, done, 'directory.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir)); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.70 moveTo: directory onto itself", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.move.dos.srcDir", - srcPath = joinURL(root.fullPath, srcDir), - filePath = joinURL(srcPath, file1); - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // create a file within new directory - directory.getFile(file1, { - create : true - }, function () { - // move srcDir onto itself - directory.moveTo(root, null, succeed.bind(null, done, 'directory.moveTo - Unexpected success callback, it should not move directory to invalid path'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - // test that original dir still exists - root.getDirectory(srcDir, { - create : false - }, function (dirEntry) { - // returning confirms existence so just check fullPath entry - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(srcPath); - dirEntry.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(srcDir, done); - }, failed.bind(null, done, 'dirEntry.getFile - Error getting file : ' + file1 + ' from: ' + srcDir)); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory : ' + srcDir)); - }); - }, failed.bind(null, done, 'directory.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.71 moveTo: directory into itself", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var srcDir = "entry.move.dis.srcDir", - dstDir = "entry.move.dis.dstDir", - srcPath = joinURL(root.fullPath, srcDir); - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // move source directory into itself - directory.moveTo(directory, dstDir, succeed.bind(null, done, 'directory.moveTo - Unexpected success callback, it should not move a directory into itself: ' + srcDir), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - // make sure original directory still exists - root.getDirectory(srcDir, { - create : false - }, function (entry) { - expect(entry).toBeDefined(); - expect(entry.fullPath).toCanonicallyMatch(srcPath); - // cleanup - deleteEntry(srcDir, done); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir)); - }); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.130 moveTo: directory into similar directory", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var srcDir = "entry.move.dis.srcDir", - dstDir = "entry.move.dis.srcDir-backup", - srcPath = joinURL(root.fullPath, srcDir); - // create a new directory entry to kick off it - createDirectory(srcDir, function (srcDirEntry) { - deleteEntry(dstDir, function () { - createDirectory(dstDir, function (dstDirEntry) { - // move source directory into itself - srcDirEntry.moveTo(dstDirEntry, 'file', function (newDirEntry) { - expect(newDirEntry).toBeDefined(); - deleteEntry(dstDir, done); - }, failed.bind(null, done, 'directory.moveTo - Error moving a directory into a similarly-named directory: ' + srcDir)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + dstDir)); - }, failed.bind(null, done, 'deleteEntry - Error deleting directory : ' + dstDir)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.72 moveTo: file onto itself", function (done) { - var file1 = "entry.move.fos.file1", - filePath = joinURL(root.fullPath, file1); - // create a new file entry to kick off it - createFile(file1, function (entry) { - // move file1 onto itself - entry.moveTo(root, null, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move a file: ' + file1 + ' into the same parent'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - //test that original file still exists - root.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(file1, done); - }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1)); - }); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }); - it("file.spec.73 moveTo: file onto existing directory", function (done) { - var file1 = "entry.move.fod.file1", - dstDir = "entry.move.fod.dstDir", - subDir = "subDir", - dirPath = joinURL(joinURL(root.fullPath, dstDir), subDir), - filePath = joinURL(root.fullPath, file1); - // ensure destination directory is cleaned up before it - deleteEntry(dstDir, function () { - // create a new file entry to kick off it - createFile(file1, function (entry) { - // create top level directory - root.getDirectory(dstDir, { - create : true - }, function (directory) { - // create sub-directory - directory.getDirectory(subDir, { - create : true - }, function (subDirectory) { - // move file1 onto sub-directory - entry.moveTo(directory, subDir, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move a file: ' + file1 + ' into directory: ' + dstDir + '\n' + subDir + ' directory already exists'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - // check that original dir still exists - directory.getDirectory(subDir, { - create : false - }, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(dirPath); - // check that original file still exists - root.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(file1, function () { - deleteEntry(dstDir, done); - }); - }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1)); - }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + subDir)); - }); - }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory : ' + dstDir)); - }, failed.bind(null, done, 'createFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.74 moveTo: directory onto existing file", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "entry.move.dof.file1", - srcDir = "entry.move.dof.srcDir", - dirPath = joinURL(root.fullPath, srcDir), - filePath = joinURL(root.fullPath, file1); - // create a new directory entry to kick off it - createDirectory(srcDir, function (entry) { - // create file - root.getFile(file1, { - create : true - }, function (fileEntry) { - // move directory onto file - entry.moveTo(root, file1, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not move : \n' + srcDir + ' into root directory renamed as ' + file1 + '\n' + file1 + ' file already exists'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - // test that original directory exists - root.getDirectory(srcDir, { - create : false - }, function (dirEntry) { - // returning confirms existence so just check fullPath entry - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(dirPath); - // test that original file exists - root.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(file1, function () { - deleteEntry(srcDir, done); - }); - }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1)); - }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir)); - }); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.75 copyTo: directory onto existing file", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "entry.copy.dof.file1", - srcDir = "entry.copy.dof.srcDir", - dirPath = joinURL(root.fullPath, srcDir), - filePath = joinURL(root.fullPath, file1); - // create a new directory entry to kick off it - createDirectory(srcDir, function (entry) { - // create file - root.getFile(file1, { - create : true - }, function () { - // copy directory onto file - entry.copyTo(root, file1, succeed.bind(null, done, 'entry.copyTo - Unexpected success callback, it should not copy : \n' + srcDir + ' into root directory renamed as ' + file1 + '\n' + file1 + ' file already exists'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - //check that original dir still exists - root.getDirectory(srcDir, { - create : false - }, function (dirEntry) { - // returning confirms existence so just check fullPath entry - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(dirPath); - // test that original file still exists - root.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // cleanup - deleteEntry(file1, function () { - deleteEntry(srcDir, done); - }); - }, failed.bind(null, done, 'root.getFile - Error getting file, making sure that original file still exists: ' + file1)); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir)); - }); - }, failed.bind(null, done, 'root.getFile - Error creating file : ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }); - it("file.spec.76 moveTo: directory onto directory that is not empty", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var srcDir = "entry.move.dod.srcDir", - dstDir = "entry.move.dod.dstDir", - subDir = "subDir", - srcPath = joinURL(root.fullPath, srcDir), - dstPath = joinURL(joinURL(root.fullPath, dstDir), subDir); - // ensure destination directory is cleaned up before it - deleteEntry(dstDir, function () { - // create a new file entry to kick off it - createDirectory(srcDir, function (entry) { - // create top level directory - root.getDirectory(dstDir, { - create : true - }, function (directory) { - // create sub-directory - directory.getDirectory(subDir, { - create : true - }, function () { - // move srcDir onto dstDir (not empty) - entry.moveTo(root, dstDir, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, it should not copy : \n' + srcDir + ' into root directory renamed as ' + dstDir + '\n' + dstDir + ' directory already exists'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - // making sure destination directory still exists - directory.getDirectory(subDir, { - create : false - }, function (dirEntry) { - // returning confirms existence so just check fullPath entry - expect(dirEntry).toBeDefined(); - expect(dirEntry.fullPath).toCanonicallyMatch(dstPath); - // making sure source directory exists - root.getDirectory(srcDir, { - create : false - }, function (srcEntry) { - expect(srcEntry).toBeDefined(); - expect(srcEntry.fullPath).toCanonicallyMatch(srcPath); - // cleanup - deleteEntry(srcDir, function () { - deleteEntry(dstDir, done); - }); - }, failed.bind(null, done, 'root.getDirectory - Error getting directory, making sure that original directory still exists: ' + srcDir)); - }, failed.bind(null, done, 'directory.getDirectory - Error getting directory, making sure that original directory still exists: ' + subDir)); - }); - }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir)); - }, failed.bind(null, done, 'directory.getDirectory - Error creating directory : ' + subDir)); - }, failed.bind(null, done, 'createDirectory - Error creating directory : ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.77 moveTo: file replace existing file", function (done) { - var file1 = "entry.move.frf.file1", - file2 = "entry.move.frf.file2", - file1Path = joinURL(root.fullPath, file1), - file2Path = joinURL(root.fullPath, file2); - // create a new directory entry to kick off it - createFile(file1, function (entry) { - // create file - root.getFile(file2, { - create : true - }, function () { - // replace file2 with file1 - entry.moveTo(root, file2, function (entry2) { - expect(entry2).toBeDefined(); - expect(entry2.isFile).toBe(true); - expect(entry2.isDirectory).toBe(false); - expect(entry2.fullPath).toCanonicallyMatch(file2Path); - expect(entry2.name).toCanonicallyMatch(file2); - // old file should not exists - root.getFile(file1, { - create : false - }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, file: ' + file1 + ' should not exists'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // test that new file exists - root.getFile(file2, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(file2Path); - // cleanup - deleteEntry(file1, function () { - deleteEntry(file2, done); - }); - }, failed.bind(null, done, 'root.getFile - Error getting moved file: ' + file2)); - }); - }, failed.bind(null, done, 'entry.moveTo - Error moving file : ' + file1 + ' to root as: ' + file2)); - }, failed.bind(null, done, 'root.getFile - Error creating file: ' + file2)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + file1)); - }); - it("file.spec.78 moveTo: directory replace empty directory", function (done) { - if (isIndexedDBShim) { - /* `copyTo` and `moveTo` functions do not support directories (Firefox, IE) */ - pending(); - } - - var file1 = "file1", - srcDir = "entry.move.drd.srcDir", - dstDir = "entry.move.drd.dstDir", - srcPath = joinURL(root.fullPath, srcDir), - dstPath = joinURL(root.fullPath, dstDir), - filePath = dstPath + '/' + file1; - // ensure destination directory is cleaned up before it - deleteEntry(dstDir, function () { - // create a new directory entry to kick off it - createDirectory(srcDir, function (directory) { - // create a file within source directory - directory.getFile(file1, { - create : true - }, function () { - // create destination directory - root.getDirectory(dstDir, { - create : true - }, function () { - // move srcDir to dstDir - directory.moveTo(root, dstDir, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.isFile).toBe(false); - expect(dirEntry.isDirectory).toBe(true); - expect(dirEntry.fullPath).toCanonicallyMatch(dstPath); - expect(dirEntry.name).toCanonicallyMatch(dstDir); - // check that old directory contents have been moved - dirEntry.getFile(file1, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.fullPath).toCanonicallyMatch(filePath); - // check that old directory no longer exists - root.getDirectory(srcDir, { - create : false - }, succeed.bind(null, done, 'root.getDirectory - Unexpected success callback, directory: ' + srcDir + ' should not exists'), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - // cleanup - deleteEntry(srcDir, function () { - deleteEntry(dstDir, done); - }); - }); - }, failed.bind(null, done, 'dirEntry.getFile - Error getting moved file: ' + file1)); - }, failed.bind(null, done, 'entry.moveTo - Error moving directory : ' + srcDir + ' to root as: ' + dstDir)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory: ' + dstDir)); - }, failed.bind(null, done, 'root.getFile - Error creating file: ' + file1)); - }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + srcDir)); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }); - it("file.spec.79 moveTo: directory that does not exist", function (done) { - - var file1 = "entry.move.dnf.file1", - dstDir = "entry.move.dnf.dstDir", - dstPath = joinURL(root.fullPath, dstDir); - // create a new file entry to kick off it - createFile(file1, function (entry) { - // move file to directory that does not exist - directory = new DirectoryEntry(); - directory.filesystem = root.filesystem; - directory.fullPath = dstPath; - entry.moveTo(directory, null, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, parent directory: ' + dstPath + ' should not exists'), function (error) { - expect(error).toBeDefined(); - if (isChrome) { - /*INVALID_MODIFICATION_ERR (code: 9) is thrown instead of NOT_FOUND_ERR(code: 1) - on trying to moveTo directory that does not exist.*/ - expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR); - } else { - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - } - // cleanup - deleteEntry(file1, done); - }); - }, failed.bind(null, done, 'createFile - Error creating file: ' + file1)); - }); - it("file.spec.80 moveTo: invalid target name", function (done) { - if (isBrowser) { - /*The plugin does not follow ["8.3 Naming restrictions"] - (http://www.w3.org/TR/2011/WD-file-system-api-20110419/#naming-restrictions*/ - pending(); - } - - var file1 = "entry.move.itn.file1", - file2 = "bad:file:name"; - // create a new file entry to kick off it - createFile(file1, function (entry) { - // move file1 to file2 - entry.moveTo(root, file2, succeed.bind(null, done, 'entry.moveTo - Unexpected success callback, : ' + file1 + ' to root as: ' + file2), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.ENCODING_ERR); - // cleanup - deleteEntry(file1, done); - }); - }, failed.bind(null, done, 'createFile - Error creating file: ' + file1)); - }); - }); - //Entry - describe('FileReader', function () { - it("file.spec.81 should have correct methods", function () { - var reader = new FileReader(); - expect(reader).toBeDefined(); - expect(typeof reader.readAsBinaryString).toBe('function'); - expect(typeof reader.readAsDataURL).toBe('function'); - expect(typeof reader.readAsText).toBe('function'); - expect(typeof reader.readAsArrayBuffer).toBe('function'); - expect(typeof reader.abort).toBe('function'); - expect(reader.result).toBe(null); - }); - }); - //FileReader - describe('Read method', function () { - it("file.spec.82 should error out on non-existent file", function (done) { - var fileName = cordova.platformId === 'windowsphone' ? root.toURL() + "/" + "somefile.txt" : "somefile.txt", - verifier = function (evt) { - expect(evt).toBeDefined(); - expect(evt.target.error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }; - root.getFile(fileName, { - create : true - }, function (entry) { - entry.file(function (file) { - deleteEntry(fileName, function () { - //Create FileReader - var reader = new FileReader(); - reader.onerror = verifier; - reader.onload = succeed.bind(null, done, 'reader.onload - Unexpected success callback, file: ' + fileName + ' it should not exists'); - reader.readAsText(file); - }, failed.bind(null, done, 'deleteEntry - Error removing file: ' + fileName)); - }, failed.bind(null, done, 'entry.file - Error reading file: ' + fileName)); - }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }); - it("file.spec.83 should be able to read native blob objects", function (done) { - // Skip test if blobs are not supported (e.g.: Android 2.3). - if (typeof window.Blob == 'undefined' || typeof window.Uint8Array == 'undefined') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - } - var contents = 'asdf'; - var uint8Array = new Uint8Array(contents.length); - for (var i = 0; i < contents.length; ++i) { - uint8Array[i] = contents.charCodeAt(i); - } - var Builder = window.BlobBuilder || window.WebKitBlobBuilder; - var blob; - if (Builder) { - var builder = new Builder(); - builder.append(uint8Array.buffer); - builder.append(contents); - blob = builder.getBlob("text/plain"); - } else { - try { - // iOS 6 does not support Views, so pass in the buffer. - blob = new Blob([uint8Array.buffer, contents]); - } catch (e) { - // Skip the test if we can't create a blob (e.g.: iOS 5). - if (e instanceof TypeError) { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - } - throw e; - } - } - var verifier = function (evt) { - expect(evt).toBeDefined(); - expect(evt.target.result).toBe('asdfasdf'); - done(); - }; - var reader = new FileReader(); - reader.onloadend = verifier; - reader.readAsText(blob); - }); - function writeDummyFile(writeBinary, callback, done, fileContents) { - var fileName = "dummy.txt", - fileEntry = null, - // use default string if file data is not provided - fileData = fileContents !== undefined ? fileContents : - '\u20AC\xEB - There is an exception to every rule. Except this one.', - fileDataAsBinaryString = fileContents !== undefined ? fileContents : - '\xe2\x82\xac\xc3\xab - There is an exception to every rule. Except this one.', - createWriter = function (fe) { - fileEntry = fe; - fileEntry.createWriter(writeFile, failed.bind(null, done, 'fileEntry.createWriter - Error reading file: ' + fileName)); - }, // writes file and reads it back in - writeFile = function (writer) { - writer.onwriteend = function () { - fileEntry.file(function (f) { - callback(fileEntry, f, fileData, fileDataAsBinaryString); - }, failed.bind(null, done, 'writer.onwriteend - Error writing data on file: ' + fileName)); - }; - writer.write(fileData); - }; - fileData += writeBinary ? 'bin:\x01\x00' : ''; - fileDataAsBinaryString += writeBinary ? 'bin:\x01\x00' : ''; - // create a file, write to it, and read it in again - createFile(fileName, createWriter, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - } - function runReaderTest(funcName, writeBinary, done, verifierFunc, sliceStart, sliceEnd, fileContents) { - writeDummyFile(writeBinary, function (fileEntry, file, fileData, fileDataAsBinaryString) { - var verifier = function (evt) { - expect(evt).toBeDefined(); - verifierFunc(evt, fileData, fileDataAsBinaryString); - }; - var reader = new FileReader(); - reader.onload = verifier; - reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + file + ' using function: ' + funcName); - if (sliceEnd !== undefined) { - // 'type' is specified so that is will be preserved in the resulting file: - // http://www.w3.org/TR/FileAPI/#slice-method-algo -> "6.4.1. The slice method" -> 4. A), 6. c) - file = file.slice(sliceStart, sliceEnd, file.type); - } else if (sliceStart !== undefined) { - file = file.slice(sliceStart, file.size, file.type); - } - reader[funcName](file); - }, done, fileContents); - } - function arrayBufferEqualsString(ab, str) { - var buf = new Uint8Array(ab); - var match = buf.length == str.length; - for (var i = 0; match && i < buf.length; i++) { - match = buf[i] == str.charCodeAt(i); - } - return match; - } - it("file.spec.84 should read file properly, readAsText", function (done) { - runReaderTest('readAsText', false, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(fileData); - done(); - }); - }); - it("file.spec.84.1 should read JSON file properly, readAsText", function (done) { - var testObject = {key1: "value1", key2: 2}; - runReaderTest('readAsText', false, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toEqual(JSON.stringify(testObject)); - done(); - }, undefined, undefined, JSON.stringify(testObject)); - }); - it("file.spec.85 should read file properly, Data URI", function (done) { - runReaderTest('readAsDataURL', true, done, function (evt, fileData, fileDataAsBinaryString) { - /* `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension, - mediatype in IE is always empty (which is the same as `text-plain` according the specification), - the mediatype in Firefox is always `application/octet-stream`. - For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`, - IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. */ - expect(evt.target.result).toBeDataUrl(); - - //The atob function it is completely ignored during mobilespec execution, besides the returned object: evt - //it is encoded and the atob function is aimed to decode a string. Even with btoa (encode) the function it gets stucked - //because of the Unicode characters that contains the fileData object. - //Issue reported at JIRA with all the details: CB-7095 - - //expect(evt.target.result.slice(23)).toBe(atob(fileData)); - - done(); - }); - }); - it("file.spec.86 should read file properly, readAsBinaryString", function (done) { - if (isIE) { - /*`readAsBinaryString` function is not supported by IE and has not the stub.*/ - pending(); - } - - runReaderTest('readAsBinaryString', true, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(fileDataAsBinaryString); - done(); - }); - }); - it("file.spec.87 should read file properly, readAsArrayBuffer", function (done) { - // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3). - if (typeof window.ArrayBuffer == 'undefined') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - } - runReaderTest('readAsArrayBuffer', true, done, function (evt, fileData, fileDataAsBinaryString) { - expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString)).toBe(true); - done(); - }); - }); - it("file.spec.88 should read sliced file: readAsText", function (done) { - runReaderTest('readAsText', false, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(fileDataAsBinaryString.slice(10, 40)); - done(); - }, 10, 40); - }); - it("file.spec.89 should read sliced file: slice past eof", function (done) { - runReaderTest('readAsText', false, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(fileData.slice(-5, 9999)); - done(); - }, -5, 9999); - }); - it("file.spec.90 should read sliced file: slice to eof", function (done) { - runReaderTest('readAsText', false, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(fileData.slice(-5)); - done(); - }, -5); - }); - it("file.spec.91 should read empty slice", function (done) { - runReaderTest('readAsText', false, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(''); - done(); - }, 0, 0); - }); - it("file.spec.92 should read sliced file properly, readAsDataURL", function (done) { - runReaderTest('readAsDataURL', true, done, function (evt, fileData, fileDataAsBinaryString) { - /* `readAsDataURL` function is supported, but the mediatype in Chrome depends on entry name extension, - mediatype in IE is always empty (which is the same as `text-plain` according the specification), - the mediatype in Firefox is always `application/octet-stream`. - For example, if the content is `abcdefg` then Firefox returns `data:application/octet-stream;base64,YWJjZGVmZw==`, - IE returns `data:;base64,YWJjZGVmZw==`, Chrome returns `data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==`. */ - expect(evt.target.result).toBeDataUrl(); - - //The atob function it is completely ignored during mobilespec execution, besides the returned object: evt - //it is encoded and the atob function is aimed to decode a string. Even with btoa (encode) the function it gets stucked - //because of the Unicode characters that contains the fileData object. - //Issue reported at JIRA with all the details: CB-7095 - - //expect(evt.target.result.slice(23)).toBe(atob(fileDataAsBinaryString.slice(10, -3))); - - done(); - }, 10, -3); - }); - it("file.spec.93 should read sliced file properly, readAsBinaryString", function (done) { - if (isIE) { - /*`readAsBinaryString` function is not supported by IE and has not the stub.*/ - pending(); - } - - runReaderTest('readAsBinaryString', true, done, function (evt, fileData, fileDataAsBinaryString) { - expect(evt.target.result).toBe(fileDataAsBinaryString.slice(-10, -5)); - done(); - }, -10, -5); - }); - it("file.spec.94 should read sliced file properly, readAsArrayBuffer", function (done) { - // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3). - if (typeof window.ArrayBuffer == 'undefined') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - } - runReaderTest('readAsArrayBuffer', true, done, function (evt, fileData, fileDataAsBinaryString) { - expect(arrayBufferEqualsString(evt.target.result, fileDataAsBinaryString.slice(0, -1))).toBe(true); - done(); - }, 0, -1); - }); - }); - //Read method - describe('FileWriter', function () { - it("file.spec.95 should have correct methods", function (done) { - // retrieve a FileWriter object - var fileName = "writer.methods"; - // FileWriter - root.getFile(fileName, { - create : true - }, function (fileEntry) { - fileEntry.createWriter(function (writer) { - expect(writer).toBeDefined(); - expect(typeof writer.write).toBe('function'); - expect(typeof writer.seek).toBe('function'); - expect(typeof writer.truncate).toBe('function'); - expect(typeof writer.abort).toBe('function'); - // cleanup - deleteFile(fileName, done); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }); - it("file.spec.96 should be able to write and append to file, createWriter", function (done) { - var fileName = "writer.append.createWriter", // file content - content = "There is an exception to every rule.", // for checkin file length - exception = " Except this one.", - length = content.length; - // create file, then write and append to it - createFile(fileName, function (fileEntry) { - // writes initial file content - fileEntry.createWriter(function (writer) { - //Verifiers declaration - var verifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // Append some more data - writer.onwriteend = secondVerifier; - length += exception.length; - writer.seek(writer.length); - writer.write(exception); - }, - secondVerifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - var reader = new FileReader(); - reader.onloadend = thirdVerifier; - reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName); - fileEntry.file(function(f){reader.readAsText(f);}); - }, - thirdVerifier = function (evt) { - expect(evt.target.result).toBe(content+exception); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.97 should be able to write and append to file, File object", function (done) { - var fileName = "writer.append.File", // file content - content = "There is an exception to every rule.", // for checkin file length - exception = " Except this one.", - length = content.length; - root.getFile(fileName, { - create : true - }, function (fileEntry) { - fileEntry.createWriter(function (writer) { - //Verifiers declaration - var verifier = function () { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // Append some more data - writer.onwriteend = secondVerifier; - length += exception.length; - writer.seek(writer.length); - writer.write(exception); - }, - secondVerifier = function () { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - var reader = new FileReader(); - reader.onloadend = thirdVerifier; - reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName); - fileEntry.file(function(f){reader.readAsText(f);}); - }, - thirdVerifier = function (evt) { - expect(evt.target.result).toBe(content+exception); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'root.getFile - Error creating file: ' + fileName)); - }); - it("file.spec.98 should be able to seek to the middle of the file and write more data than file.length", function (done) { - var fileName = "writer.seek.write", // file content - content = "This is our sentence.", // for checking file length - exception = "newer sentence.", - length = content.length; - // create file, then write and append to it - createFile(fileName, function (fileEntry) { - fileEntry.createWriter(function (writer) { - //Verifiers declaration - var verifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // Append some more data - writer.onwriteend = secondVerifier; - length = 12 + exception.length; - writer.seek(12); - writer.write(exception); - }, - secondVerifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - var reader = new FileReader(); - reader.onloadend = thirdVerifier; - reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName); - fileEntry.file(function(f){reader.readAsText(f);}); - }, - thirdVerifier = function (evt) { - expect(evt.target.result).toBe(content.substr(0,12)+exception); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.99 should be able to seek to the middle of the file and write less data than file.length", function (done) { - if (isChrome) { - /* Chrome (re)writes as follows: "This is our sentence." -> "This is new.sentence.", - i.e. the length is not being changed from content.length and writer length will be equal 21 */ - pending(); - } - - var fileName = "writer.seek.write2", // file content - content = "This is our sentence.", // for checking file length - exception = "new.", - length = content.length; - // create file, then write and append to it - createFile(fileName, function (fileEntry) { - fileEntry.createWriter(function (writer) { - // Verifiers declaration - var verifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // Append some more data - writer.onwriteend = secondVerifier; - length = 8 + exception.length; - writer.seek(8); - writer.write(exception); - }, - secondVerifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - var reader = new FileReader(); - reader.onloadend = thirdVerifier; - reader.onerror = failed.bind(null, done, 'reader.onerror - Error reading file: ' + fileName); - fileEntry.file(function(f){reader.readAsText(f);}); - }, - thirdVerifier = function (evt) { - expect(evt.target.result).toBe(content.substr(0,8)+exception); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.100 should be able to write XML data", function (done) { - var fileName = "writer.xml", // file content - content = '<?xml version="1.0" encoding="UTF-8"?>\n<test prop="ack">\nData\n</test>\n', // for testing file length - length = content.length; - // creates file, then write XML data - createFile(fileName, function (fileEntry) { - fileEntry.createWriter(function (writer) { - //Verifier content - var verifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.101 should be able to write JSON data", function (done) { - var fileName = "writer.json", // file content - content = '{ "name": "Guy Incognito", "email": "here@there.com" }', // for testing file length - length = content.length; - // creates file, then write JSON content - createFile(fileName, function (fileEntry) { - fileEntry.createWriter(function (writer) { - //Verifier declaration - var verifier = function (evt) { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.102 should be able to seek", function (done) { - var fileName = "writer.seek", // file content - content = "There is an exception to every rule. Except this one.", // for testing file length - length = content.length; - // creates file, then write JSON content - createFile(fileName, function (fileEntry) { - // writes file content and tests writer.seek - fileEntry.createWriter(function (writer) { - //Verifier declaration - var verifier = function () { - expect(writer.position).toBe(length); - writer.seek(-5); - expect(writer.position).toBe(length - 5); - writer.seek(length + 100); - expect(writer.position).toBe(length); - writer.seek(10); - expect(writer.position).toBe(10); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.seek(-100); - expect(writer.position).toBe(0); - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.103 should be able to truncate", function (done) { - if (isIndexedDBShim) { - /* `abort` and `truncate` functions are not supported (Firefox, IE) */ - pending(); - } - - var fileName = "writer.truncate", - content = "There is an exception to every rule. Except this one."; - // creates file, writes to it, then truncates it - createFile(fileName, function (fileEntry) { - fileEntry.createWriter(function (writer) { - // Verifier declaration - var verifier = function () { - expect(writer.length).toBe(36); - expect(writer.position).toBe(36); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = function () { - //Truncate process after write - writer.onwriteend = verifier; - writer.truncate(36); - }; - writer.write(content); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.104 should be able to write binary data from an ArrayBuffer", function (done) { - // Skip test if ArrayBuffers are not supported (e.g.: Android 2.3). - if (typeof window.ArrayBuffer == 'undefined') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - return; - } - var fileName = "bufferwriter.bin", // file content - data = new ArrayBuffer(32), - dataView = new Int8Array(data), // for verifying file length - length = 32; - for (i = 0; i < dataView.length; i++) { - dataView[i] = i; - } - // creates file, then write content - createFile(fileName, function (fileEntry) { - // writes file content - fileEntry.createWriter(function (writer) { - //Verifier declaration - var verifier = function () { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(data); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.105 should be able to write binary data from a Blob", function (done) { - // Skip test if Blobs are not supported (e.g.: Android 2.3). - if ((typeof window.Blob == 'undefined' && typeof window.WebKitBlobBuilder == 'undefined') || typeof window.ArrayBuffer == 'undefined') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - return; - } - var fileName = "blobwriter.bin", // file content - data = new ArrayBuffer(32), - dataView = new Int8Array(data), - blob, // for verifying file length - length = 32; - for (i = 0; i < dataView.length; i++) { - dataView[i] = i; - } - try { - // Mobile Safari: Use Blob constructor - blob = new Blob([data], { - "type" : "application/octet-stream" - }); - } catch (e) { - if (window.WebKitBlobBuilder) { - // Android Browser: Use deprecated BlobBuilder - var builder = new WebKitBlobBuilder(); - builder.append(data); - blob = builder.getBlob('application/octet-stream'); - } else { - // We have no way defined to create a Blob, so fail - fail(); - } - } - if (typeof blob !== 'undefined') { - // creates file, then write content - createFile(fileName, function (fileEntry) { - fileEntry.createWriter(function (writer) { - //Verifier declaration - var verifier = function () { - expect(writer.length).toBe(length); - expect(writer.position).toBe(length); - // cleanup - deleteFile(fileName, done); - }; - //Write process - writer.onwriteend = verifier; - writer.write(blob); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - } - }); - it("file.spec.106 should be able to write a File to a FileWriter", function (done) { - var dummyFileName = 'dummy.txt', - outputFileName = 'verify.txt', - dummyFileText = 'This text should be written to two files', - verifier = function (outputFileWriter) { - expect(outputFileWriter.length).toBe(dummyFileText.length); - expect(outputFileWriter.position).toBe(dummyFileText.length); - deleteFile(outputFileName, done); - }, - writeFile = function (fileName, fileData, win) { - var theWriter, - filePath = joinURL(root.fullPath, fileName), // writes file content to new file - write_file = function (fileEntry) { - writerEntry = fileEntry; - fileEntry.createWriter(function (writer) { - theWriter = writer; - writer.onwriteend = function (ev) { - if (typeof fileData.length !== "undefined") { - expect(theWriter.length).toBe(fileData.length); - expect(theWriter.position).toBe(fileData.length); - } - win(theWriter); - }; - writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName); - writer.write(fileData); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }; - createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }, - openFile = function (fileName, callback) { - root.getFile(fileName, { - create : false - }, function (fileEntry) { - fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName)); - }; - writeFile(dummyFileName, dummyFileText, function (dummyFileWriter) { - openFile(dummyFileName, function (file) { - writeFile(outputFileName, file, verifier); - }); - }); - }); - it("file.spec.107 should be able to write a sliced File to a FileWriter", function (done) { - var dummyFileName = 'dummy2.txt', - outputFileName = 'verify2.txt', - dummyFileText = 'This text should be written to two files', - verifier = function (outputFileWriter) { - expect(outputFileWriter.length).toBe(10); - expect(outputFileWriter.position).toBe(10); - deleteFile(outputFileName, done); - }, - writeFile = function (fileName, fileData, win) { - var theWriter, - filePath = joinURL(root.fullPath, fileName), // writes file content to new file - write_file = function (fileEntry) { - writerEntry = fileEntry; - fileEntry.createWriter(function (writer) { - theWriter = writer; - writer.onwriteend = function (ev) { - if (typeof fileData.length !== "undefined") { - expect(theWriter.length).toBe(fileData.length); - expect(theWriter.position).toBe(fileData.length); - } - win(theWriter); - }; - writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName); - writer.write(fileData); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }; - createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }, - openFile = function (fileName, callback) { - root.getFile(fileName, { - create : false - }, function (fileEntry) { - fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName)); - }; - writeFile(dummyFileName, dummyFileText, function (dummyFileWriter) { - openFile(dummyFileName, function (file) { - writeFile(outputFileName, file.slice(10, 20), verifier); - }); - }); - }); - it("file.spec.108 should be able to write binary data from a File", function (done) { - // Skip test if Blobs are not supported (e.g.: Android 2.3). - if (typeof window.Blob == 'undefined' && typeof window.WebKitBlobBuilder == 'undefined') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - } - var dummyFileName = "blobwriter.bin", - outputFileName = 'verify.bin', // file content - data = new ArrayBuffer(32), - dataView = new Int8Array(data), - blob, // for verifying file length - length = 32, - verifier = function (outputFileWriter) { - expect(outputFileWriter.length).toBe(length); - expect(outputFileWriter.position).toBe(length); - // cleanup - deleteFile(outputFileName); - done(); - }, - writeFile = function (fileName, fileData, win) { - var theWriter, - filePath = joinURL(root.fullPath, fileName), // writes file content to new file - write_file = function (fileEntry) { - writerEntry = fileEntry; - fileEntry.createWriter(function (writer) { - theWriter = writer; - writer.onwriteend = function (ev) { - if (typeof fileData.length !== "undefined") { - expect(theWriter.length).toBe(fileData.length); - expect(theWriter.position).toBe(fileData.length); - } - win(theWriter); - }; - writer.onerror = failed.bind(null, done, 'writer.onerror - Error writing content on file: ' + fileName); - writer.write(fileData); - }, failed.bind(null, done, 'fileEntry.createWriter - Error creating writer using fileEntry: ' + fileEntry.name)); - }; - createFile(fileName, write_file, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }, - openFile = function (fileName, callback) { - root.getFile(fileName, { - create : false - }, function (fileEntry) { - fileEntry.file(callback, failed.bind(null, done, 'fileEntry.file - Error reading file using fileEntry: ' + fileEntry.name)); - }, failed.bind(null, done, 'root.getFile - Error getting file: ' + fileName)); - }; - for (i = 0; i < dataView.length; i++) { - dataView[i] = i; - } - try { - // Mobile Safari: Use Blob constructor - blob = new Blob([data], { - "type" : "application/octet-stream" - }); - } catch (e) { - if (window.WebKitBlobBuilder) { - // Android Browser: Use deprecated BlobBuilder - var builder = new WebKitBlobBuilder(); - builder.append(data); - blob = builder.getBlob('application/octet-stream'); - } else { - // We have no way defined to create a Blob, so fail - fail(); - } - } - if (typeof blob !== 'undefined') { - // creates file, then write content - writeFile(dummyFileName, blob, function (dummyFileWriter) { - openFile(dummyFileName, function (file) { - writeFile(outputFileName, file, verifier); - }); - }); - } - }); - }); - //FileWritter - describe('Backwards compatibility', function () { - /* These specs exist to test that the File plugin can still recognize file:/// - * URLs, and can resolve them to FileEntry and DirectoryEntry objects. - * They rely on an undocumented interface to File which provides absolute file - * paths, which are not used internally anymore. - * If that interface is not present, then these tests will silently succeed. - */ - it("file.spec.109 should be able to resolve a file:/// URL", function (done) { - var localFilename = 'file.txt'; - var originalEntry; - root.getFile(localFilename, { - create : true - }, function (entry) { - originalEntry = entry; - /* This is an undocumented interface to File which exists only for testing - * backwards compatibilty. By obtaining the raw filesystem path of the download - * location, we can pass that to ft.download() to make sure that previously-stored - * paths are still valid. - */ - cordova.exec(function (localPath) { - window.resolveLocalFileSystemURL("file://" + encodeURI(localPath), function (fileEntry) { - expect(fileEntry.toURL()).toEqual(originalEntry.toURL()); - // cleanup - deleteFile(localFilename); - done(); - }, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving URI: file://' + encodeURI(localPath))); - }, done, 'File', '_getLocalFilesystemPath', [entry.toURL()]); - }, failed.bind(null, done, 'root.getFile - Error creating file: ' + localFilename)); - }); - }); - //Backwards Compatibility - describe('Parent References', function () { - /* These specs verify that paths with parent references i("..") in them - * work correctly, and do not cause the application to crash. - */ - it("file.spec.110 should not throw exception resolving parent refefences", function (done) { - /* This is a direct copy of file.spec.9, with the filename changed, * as reported in CB-5721. - */ - var fileName = "resolve.file.uri"; - var dirName = "resolve.dir.uri"; - // create a new file entry - createDirectory(dirName, function () { - createFile(dirName+"/../" + fileName, function (entry) { - // lookup file system entry - window.resolveLocalFileSystemURL(entry.toURL(), function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.name).toCanonicallyMatch(fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'window.resolveLocalFileSystemURL - Error resolving URI: ' + entry.toURL())); - }, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + dirName)); - }); - it("file.spec.111 should not traverse above above the root directory", function (done) { - var fileName = "traverse.file.uri"; - // create a new file entry - createFile(fileName, function (entry) { - // lookup file system entry - root.getFile('../' + fileName, { - create : false - }, function (fileEntry) { - // Note: we expect this to still resolve, as the correct behaviour is to ignore the ../, not to fail out. - expect(fileEntry).toBeDefined(); - expect(fileEntry.name).toBe(fileName); - expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath +'/' + fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'root.getFile - Error getting file: ../' + fileName)); - }, failed.bind(null, done, 'createFile - Error creating file: ../' + fileName)); - }); - it("file.spec.112 should traverse above above the current directory", function (done) { - var fileName = "traverse2.file.uri", - dirName = "traverse2.subdir"; - // create a new directory and a file entry - createFile(fileName, function () { - createDirectory(dirName, function (entry) { - // lookup file system entry - entry.getFile('../' + fileName, { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.name).toBe(fileName); - expect(fileEntry.fullPath).toCanonicallyMatch('/' + fileName); - // cleanup - deleteEntry(fileName, function () { - deleteEntry(dirName, done); - }); - }, failed.bind(null, done, 'entry.getFile - Error getting file: ' + fileName + ' recently created above: ' + dirName)); - }, failed.bind(null, done, 'createDirectory - Error creating directory: ' + dirName)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.113 getFile: get Entry should error for missing file above root directory", function (done) { - var fileName = "../missing.file"; - // create:false, exclusive:false, file does not exist - root.getFile(fileName, { - create : false - }, succeed.bind(null, done, 'root.getFile - Unexpected success callback, it should not locate nonexistent file: ' + fileName), function (error) { - expect(error).toBeDefined(); - expect(error).toBeFileError(FileError.NOT_FOUND_ERR); - done(); - }); - }); - }); - //Parent References - describe('toNativeURL interface', function () { - /* These specs verify that FileEntries have a toNativeURL method - * which appears to be sane. - */ - var pathExpect = cordova.platformId === 'windowsphone' ? "//nativ" : "file://"; - if (isChrome) { - pathExpect = 'filesystem:file://'; - } - it("file.spec.114 fileEntry should have a toNativeURL method", function (done) { - var fileName = "native.file.uri"; - if (isWindows) { - var rootPath = root.fullPath; - pathExpect = rootPath.substr(0, rootPath.indexOf(":")); - } - // create a new file entry - createFile(fileName, function (entry) { - expect(entry.toNativeURL).toBeDefined(); - expect(entry.name).toCanonicallyMatch(fileName); - expect(typeof entry.toNativeURL).toBe('function'); - var nativeURL = entry.toNativeURL(); - var indexOfRoot = isWindows ? nativeURL.indexOf(":") : - isChrome ? 'filesystem:file://'.length : // Chrome uses own prefix for all filesystem urls - 7; //default value - length of 'file://' string - expect(typeof nativeURL).toBe("string"); - expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect); - expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.115 DirectoryReader should return entries with toNativeURL method", function (done) { - var dirName = 'nativeEntries.dir', - fileName = 'nativeEntries.file', - checkEntries = function (entries) { - expect(entries).toBeDefined(); - expect(entries instanceof Array).toBe(true); - expect(entries.length).toBe(1); - expect(entries[0].toNativeURL).toBeDefined(); - expect(typeof entries[0].toNativeURL).toBe('function'); - var nativeURL = entries[0].toNativeURL(); - var indexOfRoot = isWindows ? nativeURL.indexOf(":") : - isChrome ? 'filesystem:file://'.length : // Chrome uses own prefix for all filesystem urls - 7; //default value - length of 'file://' string - expect(typeof nativeURL).toBe("string"); - expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect); - expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName); - // cleanup - directory.removeRecursively(null, null); - done(); - }; - // create a new file entry - root.getDirectory(dirName, { - create : true - }, function (directory) { - directory.getFile(fileName, { - create : true - }, function (fileEntry) { - var reader = directory.createReader(); - reader.readEntries(checkEntries, failed.bind(null, done, 'reader.readEntries - Error reading entries from directory: ' + dirName)); - }, failed.bind(null, done, 'directory.getFile - Error creating file: ' + fileName)); - }, failed.bind(null, done, 'root.getDirectory - Error creating directory: ' + dirName)); - }); - it("file.spec.116 resolveLocalFileSystemURL should return entries with toNativeURL method", function (done) { - var fileName = "native.resolve.uri"; - // create a new file entry - createFile(fileName, function (entry) { - resolveLocalFileSystemURL(entry.toURL(), function (entry) { - expect(entry.toNativeURL).toBeDefined(); - expect(entry.name).toCanonicallyMatch(fileName); - expect(typeof entry.toNativeURL).toBe('function'); - var nativeURL = entry.toNativeURL(); - var indexOfRoot = isWindows ? nativeURL.indexOf(":") : - isChrome ? 'filesystem:file://'.length : // Chrome uses own prefix for all filesystem urls - 7; //default value - length of 'file://' string - expect(typeof nativeURL).toBe("string"); - expect(nativeURL.substring(0, pathExpect.length)).toEqual(pathExpect); - expect(nativeURL.substring(nativeURL.length - fileName.length)).toEqual(fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toURL())); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - }); - //toNativeURL interface - describe('resolveLocalFileSystemURL on file://', function () { - /* These specs verify that window.resolveLocalFileSystemURL works correctly on file:// URLs - */ - it("file.spec.117 should not resolve native URLs outside of FS roots", function (done) { - // lookup file system entry - window.resolveLocalFileSystemURL("file:///this.is.an.invalid.url", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file:///this.is.an.invalid.url'), function (error) { - expect(error).toBeDefined(); - done(); - }); - }); - it("file.spec.118 should not resolve native URLs outside of FS roots", function (done) { - // lookup file system entry - window.resolveLocalFileSystemURL("file://localhost/this.is.an.invalid.url", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost/this.is.an.invalid.url'), function (error) { - expect(error).toBeDefined(); - done(); - }); - }); - it("file.spec.119 should not resolve invalid native URLs", function (done) { - // lookup file system entry - window.resolveLocalFileSystemURL("file://localhost", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost'), function (error) { - expect(error).toBeDefined(); - done(); - }); - }); - it("file.spec.120 should not resolve invalid native URLs with query strings", function (done) { - // lookup file system entry - window.resolveLocalFileSystemURL("file://localhost?test/test", succeed.bind(null, done, 'window.resolveLocalFileSystemURL - Unexpected success callback, it should not resolve invalid URL: file://localhost?test/test'), function (error) { - expect(error).toBeDefined(); - done(); - }); - }); - it("file.spec.121 should resolve native URLs returned by API", function (done) { - var fileName = "native.resolve.uri1"; - // create a new file entry - createFile(fileName, function (entry) { - resolveLocalFileSystemURL(entry.toNativeURL(), function (fileEntry) { - expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + entry.toNativeURL())); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.122 should resolve native URLs returned by API with localhost", function (done) { - var fileName = "native.resolve.uri2"; - // create a new file entry - createFile(fileName, function (entry) { - var url = entry.toNativeURL(); - url = url.replace("///", "//localhost/"); - resolveLocalFileSystemURL(url, function (fileEntry) { - expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.123 should resolve native URLs returned by API with query string", function (done) { - var fileName = "native.resolve.uri3"; - // create a new file entry - createFile(fileName, function (entry) { - var url = entry.toNativeURL(); - url = url + "?test/test"; - resolveLocalFileSystemURL(url, function (fileEntry) { - expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - it("file.spec.124 should resolve native URLs returned by API with localhost and query string", function (done) { - var fileName = "native.resolve.uri4"; - // create a new file entry - createFile(fileName, function (entry) { - var url = entry.toNativeURL(); - url = url.replace("///", "//localhost/") + "?test/test"; - resolveLocalFileSystemURL(url, function (fileEntry) { - expect(fileEntry.fullPath).toCanonicallyMatch(root.fullPath + "/" + fileName); - // cleanup - deleteEntry(fileName, done); - }, failed.bind(null, done, 'resolveLocalFileSystemURL - Error resolving file URL: ' + url)); - }, failed.bind(null, done, 'createFile - Error creating file: ' + fileName)); - }); - }); - //resolveLocalFileSystemURL on file:// - describe('cross-file-system copy and move', function () { - /* These specs verify that Entry.copyTo and Entry.moveTo work correctly - * when crossing filesystem boundaries. - */ - it("file.spec.125 copyTo: temporary -> persistent", function (done) { - var file1 = "entry.copy.file1a", - file2 = "entry.copy.file2a", - sourceEntry, - fullPath = joinURL(root.fullPath, file2), - validateFile = function (entry) { - // a bit redundant since copy returned this entry already - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(file2); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - expect(entry.filesystem).toBeDefined(); - isChrome ? expect(entry.filesystem.name).toContain("Persistent") - : expect(entry.filesystem.name).toEqual("persistent"); - // cleanup - deleteEntry(entry.name); - deleteEntry(sourceEntry.name, done); - }, - createSourceAndTransfer = function () { - temp_root.getFile(file1, { - create : true - }, function (entry) { - expect(entry.filesystem).toBeDefined(); - isChrome ? expect(entry.filesystem.name).toContain("Temporary") - : expect(entry.filesystem.name).toEqual("temporary"); - sourceEntry = entry; - // Save for later cleanup - entry.copyTo(persistent_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + file1 + ' to PERSISTENT root as: ' + file2)); - }, failed.bind(null, done, 'temp_root.getFile - Error creating file: ' + file1 + 'at TEMPORAL root')); - }; - // Delete any existing file to start things off - persistent_root.getFile(file2, {}, function (entry) { - entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2)); - }, createSourceAndTransfer); - }); - it("file.spec.126 copyTo: persistent -> temporary", function (done) { - var file1 = "entry.copy.file1b", - file2 = "entry.copy.file2b", - sourceEntry, - fullPath = joinURL(temp_root.fullPath, file2), - validateFile = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(file2); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - isChrome ? expect(entry.filesystem.name).toContain("Temporary") - : expect(entry.filesystem.name).toEqual("temporary"); - // cleanup - deleteEntry(entry.name); - deleteEntry(sourceEntry.name, done); - }, - createSourceAndTransfer = function () { - persistent_root.getFile(file1, { - create : true - }, function (entry) { - expect(entry).toBeDefined(); - expect(entry.filesystem).toBeDefined(); - isChrome ? expect(entry.filesystem.name).toContain("Persistent") - : expect(entry.filesystem.name).toEqual("persistent"); - sourceEntry = entry; - // Save for later cleanup - entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + file1 + ' to TEMPORAL root as: ' + file2)); - }, failed.bind(null, done, 'persistent_root.getFile - Error creating file: ' + file1 + 'at PERSISTENT root')); - }; - // Delete any existing file to start things off - temp_root.getFile(file2, {}, function (entry) { - entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2)); - }, createSourceAndTransfer); - }); - it("file.spec.127 moveTo: temporary -> persistent", function (done) { - var file1 = "entry.copy.file1a", - file2 = "entry.copy.file2a", - sourceEntry, - fullPath = joinURL(root.fullPath, file2), - validateFile = function (entry) { - // a bit redundant since copy returned this entry already - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(file2); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - expect(entry.filesystem).toBeDefined(); - isChrome ? expect(entry.filesystem.name).toContain("Persistent") - : expect(entry.filesystem.name).toEqual("persistent"); - // cleanup - deleteEntry(entry.name); - deleteEntry(sourceEntry.name, done); - }, - createSourceAndTransfer = function () { - temp_root.getFile(file1, { - create : true - }, function (entry) { - expect(entry.filesystem).toBeDefined(); - isChrome ? expect(entry.filesystem.name).toContain("Temporary") - : expect(entry.filesystem.name).toEqual("temporary"); - sourceEntry = entry; - // Save for later cleanup - entry.moveTo(persistent_root, file2, validateFile, failed.bind(null, done, 'entry.moveTo - Error moving file: ' + file1 + ' to PERSISTENT root as: ' + file2)); - }, failed.bind(null, done, 'temp_root.getFile - Error creating file: ' + file1 + 'at TEMPORAL root')); - }; - // Delete any existing file to start things off - persistent_root.getFile(file2, {}, function (entry) { - entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2)); - }, createSourceAndTransfer); - }); - it("file.spec.128 moveTo: persistent -> temporary", function (done) { - var file1 = "entry.copy.file1b", - file2 = "entry.copy.file2b", - sourceEntry, - fullPath = joinURL(temp_root.fullPath, file2), - validateFile = function (entry) { - expect(entry).toBeDefined(); - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(file2); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - isChrome ? expect(entry.filesystem.name).toContain("Temporary") - : expect(entry.filesystem.name).toEqual("temporary"); - // cleanup - deleteEntry(entry.name); - deleteEntry(sourceEntry.name, done); - }, - createSourceAndTransfer = function () { - persistent_root.getFile(file1, { - create : true - }, function (entry) { - expect(entry).toBeDefined(); - expect(entry.filesystem).toBeDefined(); - isChrome ? expect(entry.filesystem.name).toContain("Persistent") - : expect(entry.filesystem.name).toEqual("persistent"); - sourceEntry = entry; - // Save for later cleanup - entry.moveTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.moveTo - Error moving file: ' + file1 + ' to TEMPORAL root as: ' + file2)); - }, failed.bind(null, done, 'persistent_root.getFile - Error creating file: ' + file1 + 'at PERSISTENT root')); - }; - // Delete any existing file to start things off - temp_root.getFile(file2, {}, function (entry) { - entry.remove(createSourceAndTransfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2)); - }, createSourceAndTransfer); - }); - it("file.spec.129 cordova.file.*Directory are set", function () { - var expectedPaths = ['applicationDirectory', 'applicationStorageDirectory', 'dataDirectory', 'cacheDirectory']; - if (cordova.platformId == 'android' || cordova.platformId == 'amazon-fireos') { - expectedPaths.push('externalApplicationStorageDirectory', 'externalRootDirectory', 'externalCacheDirectory', 'externalDataDirectory'); - } else if (cordova.platformId == 'blackberry10') { - expectedPaths.push('externalRootDirectory', 'sharedDirectory'); - } else if (cordova.platformId == 'ios') { - expectedPaths.push('syncedDataDirectory', 'documentsDirectory', 'tempDirectory'); - } else { - console.log('Skipping test due on unsupported platform.'); - return; - } - for (var i = 0; i < expectedPaths.length; ++i) { - expect(typeof cordova.file[expectedPaths[i]]).toBe('string'); - expect(cordova.file[expectedPaths[i]]).toMatch(/\/$/, 'Path should end with a slash'); - } - }); - }); - //cross-file-system copy and move - describe('IndexedDB-based impl', function () { - it("file.spec.131 Nested file or nested directory should be removed when removing a parent directory", function (done) { - var parentDirName = 'deletedDir131', - nestedDirName = 'nestedDir131', - nestedFileName = 'nestedFile131.txt'; - - createDirectory(parentDirName, function (parent) { - parent.getDirectory(nestedDirName, { create: true}, function () { - parent.getFile(nestedFileName, { create: true}, function () { - parent.removeRecursively(function() { - root.getDirectory(parentDirName,{ create: false}, failed.bind(this, done, 'root.getDirectory - unexpected success callback : ' + parentDirName), function(){ - parent.getFile(nestedFileName,{ create: false}, failed.bind(this, done, 'getFile - unexpected success callback : ' + nestedFileName), function(){ - parent.getDirectory(nestedDirName, { create: false}, failed.bind(this, done, 'getDirectory - unexpected success callback : ' + nestedDirName), done); - }); - }); - }, failed.bind(this, done, 'removeRecursively - Error removing directory : ' + parentDirName)); - }, failed.bind(this, done, 'getFile - Error creating file : ' + nestedFileName)); - },failed.bind(this, done, 'getDirectory - Error creating directory : ' + nestedDirName)); - }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + parentDirName)); - }); - it("file.spec.132 Entry should be created succesfully when using relative paths if its parent directory exists", function (done) { - /* Directory entries have to be created successively. - For example, the call `fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback)` - will fail if dir1 did not exist. */ - var parentName = 'parentName132'; - var nestedName = 'nestedName132'; - var path = parentName + '/' + nestedName; - - var win = function(directory){ - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(nestedName); - expect(directory.fullPath).toCanonicallyMatch('/' + path + '/'); - deleteEntry(directory.name); - deleteEntry(parentName, done); - }; - - createDirectory(parentName, function() { - root.getDirectory(parentName + '/' + nestedName, {create:true}, win, - failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + path)); - }, failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + parentName)); - }); - it("file.spec.133 A file being removed should not affect another file with name being a prefix of the removed file name.", function (done) { - - // Names include special symbols so that we check the IndexedDB range used - var deletedFileName = 'deletedFile.0', - secondFileName = 'deletedFile.0.1'; - - var win = function(fileEntry){ - expect(fileEntry).toBeDefined(); - expect(fileEntry.isFile).toBe(true); - expect(fileEntry.isDirectory).toBe(false); - expect(fileEntry.name).toCanonicallyMatch(secondFileName); - deleteEntry(fileEntry.name, done); - }; - - createFile(deletedFileName, function (deletedFile) { - createFile(secondFileName, function () { - deletedFile.remove(function() { - root.getFile(deletedFileName, {create: false}, failed.bind(this, done, 'getFile - unexpected success callback getting deleted file : ' + deletedFileName), function(){ - root.getFile(secondFileName, {create: false}, win, failed.bind(this, done, 'getFile - Error getting file after deleting deletedFile : ' + secondFileName)); - }); - }, failed.bind(this, done, 'remove - Error removing file : ' + deletedFileName)); - }, failed.bind(this, done, 'getFile - Error creating file : ' + secondFileName)); - }, failed.bind(this, done, 'getFile - Error creating file : ' + deletedFileName)); - }); - it("file.spec.134 A directory being removed should not affect another directory with name being a prefix of the removed directory name.", function (done) { - - // Names include special symbols so that we check the IndexedDB range used - var deletedDirName = 'deletedDir.0', - secondDirName = 'deletedDir.0.1'; - - var win = function(directory){ - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(secondDirName); - deleteEntry(directory.name, done); - }; - - createDirectory(deletedDirName, function (deletedDir) { - createDirectory(secondDirName, function () { - deletedDir.remove(function() { - root.getDirectory(deletedDirName, {create: false}, failed.bind(this, done, 'getDirectory - unexpected success callback getting deleted directory : ' + deletedDirName), function() { - root.getDirectory(secondDirName, {create: false}, win, failed.bind(this, done, 'getDirectory - Error getting directory after deleting deletedDirectory : ' + secondDirName)); - }); - }, failed.bind(this, done, 'remove - Error removing directory : ' + deletedDirName)); - }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + secondDirName)); - }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + deletedDirName)); - }); - it("file.spec.135 Deletion of a child directory should not affect the parent directory.", function (done) { - - var parentName = 'parentName135'; - var childName = 'childName135'; - - var win = function(directory){ - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(parentName); - deleteEntry(directory.name, done); - }; - - createDirectory(parentName, function(parent){ - parent.getDirectory(childName, {create: true}, function(child){ - child.removeRecursively(function(){ - root.getDirectory(parentName, {create: false}, win, failed.bind(this, done, 'root.getDirectory - Error getting parent directory : ' + parentName)); - }, - failed.bind(this, done, 'getDirectory - Error removing directory : ' + childName)); - }, failed.bind(this, done, 'getDirectory - Error creating directory : ' + childName)); - }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + parentName)); - }); - it("file.spec.136 Paths should support Unicode symbols.", function (done) { - - var dirName = '文件插件'; - - var win = function(directory){ - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.name).toCanonicallyMatch(dirName); - deleteEntry(directory.name, done); - }; - - createDirectory(dirName, function(){ - root.getDirectory(dirName, {create: false}, win, - failed.bind(this, done, 'root.getDirectory - Error getting directory : ' + dirName)); - }, failed.bind(this, done, 'root.getDirectory - Error creating directory : ' + dirName)); - }); - }); - // Content and Asset URLs - if (cordova.platformId == 'android') { - describe('content: URLs', function() { - function testContentCopy(src, done) { - var file2 = "entry.copy.file2b", - fullPath = joinURL(temp_root.fullPath, file2), - validateFile = function (entry) { - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(file2); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - expect(entry.filesystem.name).toEqual("temporary"); - // cleanup - deleteEntry(entry.name, done); - }, - transfer = function () { - resolveLocalFileSystemURL(src, function(entry) { - expect(entry).toBeDefined(); - expect(entry.filesystem.name).toEqual("content"); - entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2)); - }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider')); - }; - // Delete any existing file to start things off - temp_root.getFile(file2, {}, function (entry) { - entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2)); - }, transfer); - } - it("file.spec.138 copyTo: content", function(done) { - testContentCopy('content://org.apache.cordova.file.testprovider/www/index.html', done); - }); - it("file.spec.139 copyTo: content /w space and query", function(done) { - testContentCopy('content://org.apache.cordova.file.testprovider/?name=foo%20bar&realPath=%2Fwww%2Findex.html', done); - }); - it("file.spec.140 delete: content should fail", function(done) { - resolveLocalFileSystemURL('content://org.apache.cordova.file.testprovider/www/index.html', function(entry) { - entry.remove(failed.bind(null, done, 'expected delete to fail'), done); - }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for content provider')); - }); - }); - describe('asset: URLs', function() { - it("file.spec.141 filePaths.applicationStorage", function() { - expect(cordova.file.applicationDirectory).toEqual('file:///android_asset/'); - }, MEDIUM_TIMEOUT); - it("file.spec.142 assets should be enumerable", function(done) { - resolveLocalFileSystemURL('file:///android_asset/www/', function(entry) { - var reader = entry.createReader(); - reader.readEntries(function (entries) { - expect(entries.length).not.toBe(0); - done(); - }, failed.bind(null, done, 'reader.readEntries - Error during reading of entries from assets directory')); - }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets')); - }, LONG_TIMEOUT); - it("file.spec.143 copyTo: asset -> temporary", function(done) { - var file2 = "entry.copy.file2b", - fullPath = joinURL(temp_root.fullPath, file2), - validateFile = function (entry) { - expect(entry.isFile).toBe(true); - expect(entry.isDirectory).toBe(false); - expect(entry.name).toCanonicallyMatch(file2); - expect(entry.fullPath).toCanonicallyMatch(fullPath); - expect(entry.filesystem.name).toEqual("temporary"); - // cleanup - deleteEntry(entry.name, done); - }, - transfer = function () { - resolveLocalFileSystemURL('file:///android_asset/www/index.html', function(entry) { - expect(entry.filesystem.name).toEqual('assets'); - entry.copyTo(temp_root, file2, validateFile, failed.bind(null, done, 'entry.copyTo - Error copying file: ' + entry.toURL() + ' to TEMPORAL root as: ' + file2)); - }, failed.bind(null, done, 'resolveLocalFileSystemURL failed for assets')); - }; - // Delete any existing file to start things off - temp_root.getFile(file2, {}, function (entry) { - entry.remove(transfer, failed.bind(null, done, 'entry.remove - Error removing file: ' + file2)); - }, transfer); - }, MEDIUM_TIMEOUT); - }); - it("file.spec.144 copyTo: asset directory", function (done) { - var srcUrl = 'file:///android_asset/www/plugins/cordova-plugin-file'; - var dstDir = "entry.copy.dstDir"; - var dstPath = joinURL(root.fullPath, dstDir); - // create a new directory entry to kick off it - deleteEntry(dstDir, function () { - resolveLocalFileSystemURL(srcUrl, function(directory) { - directory.copyTo(root, dstDir, function (directory) { - expect(directory).toBeDefined(); - expect(directory.isFile).toBe(false); - expect(directory.isDirectory).toBe(true); - expect(directory.fullPath).toCanonicallyMatch(dstPath); - expect(directory.name).toCanonicallyMatch(dstDir); - root.getDirectory(dstDir, { - create : false - }, function (dirEntry) { - expect(dirEntry).toBeDefined(); - expect(dirEntry.isFile).toBe(false); - expect(dirEntry.isDirectory).toBe(true); - expect(dirEntry.fullPath).toCanonicallyMatch(dstPath); - expect(dirEntry.name).toCanonicallyMatch(dstDir); - dirEntry.getFile('www/File.js', { - create : false - }, function (fileEntry) { - expect(fileEntry).toBeDefined(); - expect(fileEntry.isFile).toBe(true); - // cleanup - deleteEntry(dstDir, done); - }, failed.bind(null, done, 'dirEntry.getFile - Error getting subfile')); - }, failed.bind(null, done, 'root.getDirectory - Error getting copied directory')); - }, failed.bind(null, done, 'directory.copyTo - Error copying directory')); - }, failed.bind(null, done, 'resolving src dir')); - }, failed.bind(null, done, 'deleteEntry - Error removing directory : ' + dstDir)); - }, LONG_TIMEOUT); - } - }); - -}; -//****************************************************************************************** -//***************************************Manual Tests*************************************** -//****************************************************************************************** - -exports.defineManualTests = function (contentEl, createActionButton) { - - function resolveFs(fsname) { - var fsURL = "cdvfile://localhost/" + fsname + "/"; - logMessage("Resolving URL: " + fsURL); - resolveLocalFileSystemURL(fsURL, function (entry) { - logMessage("Success", 'green'); - logMessage(entry.toURL(), 'blue'); - logMessage(entry.toInternalURL(), 'blue'); - logMessage("Resolving URL: " + entry.toURL()); - resolveLocalFileSystemURL(entry.toURL(), function (entry2) { - logMessage("Success", 'green'); - logMessage(entry2.toURL(), 'blue'); - logMessage(entry2.toInternalURL(), 'blue'); - }, logError("resolveLocalFileSystemURL")); - }, logError("resolveLocalFileSystemURL")); - } - - function testPrivateURL() { - requestFileSystem(TEMPORARY, 0, function (fileSystem) { - logMessage("Temporary root is at " + fileSystem.root.toNativeURL()); - fileSystem.root.getFile("testfile", { - create : true - }, function (entry) { - logMessage("Temporary file is at " + entry.toNativeURL()); - if (entry.toNativeURL().substring(0, 12) == "file:///var/") { - logMessage("File starts with /var/, trying /private/var"); - var newURL = "file://localhost/private/var/" + entry.toNativeURL().substring(12) + "?and=another_thing"; - //var newURL = entry.toNativeURL(); - logMessage(newURL, 'blue'); - resolveLocalFileSystemURL(newURL, function (newEntry) { - logMessage("Successfully resolved.", 'green'); - logMessage(newEntry.toURL(), 'blue'); - logMessage(newEntry.toNativeURL(), 'blue'); - }, logError("resolveLocalFileSystemURL")); - } - }, logError("getFile")); - }, logError("requestFileSystem")); - } - - function clearLog() { - var log = document.getElementById("info"); - log.innerHTML = ""; - } - - function logMessage(message, color) { - var log = document.getElementById("info"); - var logLine = document.createElement('div'); - if (color) { - logLine.style.color = color; - } - logLine.innerHTML = message; - log.appendChild(logLine); - } - - function logError(serviceName) { - return function (err) { - logMessage("ERROR: " + serviceName + " " + JSON.stringify(err), "red"); - }; - } - - var fsRoots = { - "ios" : "library,library-nosync,documents,documents-nosync,cache,bundle,root,private", - "android" : "files,files-external,documents,sdcard,cache,cache-external,root", - "amazon-fireos" : "files,files-external,documents,sdcard,cache,cache-external,root" - }; - - //Add title and align to content - var div = document.createElement('h2'); - div.appendChild(document.createTextNode('File Systems')); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - - div = document.createElement('h3'); - div.appendChild(document.createTextNode('Results are displayed in yellow status box below with expected results noted under that')); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - - div = document.createElement('div'); - div.setAttribute("id", "button"); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - if (fsRoots.hasOwnProperty(cordova.platformId)) { - (fsRoots[cordova.platformId].split(',')).forEach(function (fs) { - if (cordova.platformId === 'ios' && fs === 'private') { - createActionButton("Test private URL (iOS)", function () { - clearLog(); - testPrivateURL(); - }, 'button'); - } else { - createActionButton(fs, function () { - clearLog(); - resolveFs(fs); - }, 'button'); - } - }); - } - - - div = document.createElement('div'); - div.setAttribute("id", "info"); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - - div = document.createElement('h3'); - div.appendChild(document.createTextNode('For each test above, file or directory should be successfully found. ' + - 'Status box should say Resolving URL was Success. The first URL resolved is the internal URL. ' + - 'The second URL resolved is the absolute URL. Blue URLs must match.')); - contentEl.appendChild(div); - - div = document.createElement('h3'); - div.appendChild(document.createTextNode('For Test private URL (iOS), the private URL (first blue URL in status box) ' + - 'should be successfully resolved. Status box should say Successfully resolved. Both blue URLs below ' + - 'that should match.')); - contentEl.appendChild(div); -}; diff --git a/plugins/cordova-plugin-file/www/DirectoryEntry.js b/plugins/cordova-plugin-file/www/DirectoryEntry.js deleted file mode 100644 index 62f468ab..00000000 --- a/plugins/cordova-plugin-file/www/DirectoryEntry.js +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * 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 argscheck = require('cordova/argscheck'), - utils = require('cordova/utils'), - exec = require('cordova/exec'), - Entry = require('./Entry'), - FileError = require('./FileError'), - DirectoryReader = require('./DirectoryReader'); - -/** - * An interface representing a directory on the file system. - * - * {boolean} isFile always false (readonly) - * {boolean} isDirectory always true (readonly) - * {DOMString} name of the directory, excluding the path leading to it (readonly) - * {DOMString} fullPath the absolute full path to the directory (readonly) - * {FileSystem} filesystem on which the directory resides (readonly) - */ -var DirectoryEntry = function(name, fullPath, fileSystem, nativeURL) { - - // add trailing slash if it is missing - if ((fullPath) && !/\/$/.test(fullPath)) { - fullPath += "/"; - } - // add trailing slash if it is missing - if (nativeURL && !/\/$/.test(nativeURL)) { - nativeURL += "/"; - } - DirectoryEntry.__super__.constructor.call(this, false, true, name, fullPath, fileSystem, nativeURL); -}; - -utils.extend(DirectoryEntry, Entry); - -/** - * Creates a new DirectoryReader to read entries from this directory - */ -DirectoryEntry.prototype.createReader = function() { - return new DirectoryReader(this.toInternalURL()); -}; - -/** - * Creates or looks up a directory - * - * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory - * @param {Flags} options to create or exclusively create the directory - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) { - argscheck.checkArgs('sOFF', 'DirectoryEntry.getDirectory', arguments); - var fs = this.filesystem; - var win = successCallback && function(result) { - var entry = new DirectoryEntry(result.name, result.fullPath, fs, result.nativeURL); - successCallback(entry); - }; - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getDirectory", [this.toInternalURL(), path, options]); -}; - -/** - * Deletes a directory and all of it's contents - * - * @param {Function} successCallback is called with no parameters - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) { - argscheck.checkArgs('FF', 'DirectoryEntry.removeRecursively', arguments); - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(successCallback, fail, "File", "removeRecursively", [this.toInternalURL()]); -}; - -/** - * Creates or looks up a file - * - * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file - * @param {Flags} options to create or exclusively create the file - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) { - argscheck.checkArgs('sOFF', 'DirectoryEntry.getFile', arguments); - var fs = this.filesystem; - var win = successCallback && function(result) { - var FileEntry = require('./FileEntry'); - var entry = new FileEntry(result.name, result.fullPath, fs, result.nativeURL); - successCallback(entry); - }; - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getFile", [this.toInternalURL(), path, options]); -}; - -module.exports = DirectoryEntry; diff --git a/plugins/cordova-plugin-file/www/DirectoryReader.js b/plugins/cordova-plugin-file/www/DirectoryReader.js deleted file mode 100644 index 2894c9a3..00000000 --- a/plugins/cordova-plugin-file/www/DirectoryReader.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'), - FileError = require('./FileError') ; - -/** - * An interface that lists the files and directories in a directory. - */ -function DirectoryReader(localURL) { - this.localURL = localURL || null; - this.hasReadEntries = false; -} - -/** - * Returns a list of entries from a directory. - * - * @param {Function} successCallback is called with a list of entries - * @param {Function} errorCallback is called with a FileError - */ -DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) { - // If we've already read and passed on this directory's entries, return an empty list. - if (this.hasReadEntries) { - successCallback([]); - return; - } - var reader = this; - var win = typeof successCallback !== 'function' ? null : function(result) { - var retVal = []; - for (var i=0; i<result.length; i++) { - var entry = null; - if (result[i].isDirectory) { - entry = new (require('./DirectoryEntry'))(); - } - else if (result[i].isFile) { - entry = new (require('./FileEntry'))(); - } - entry.isDirectory = result[i].isDirectory; - entry.isFile = result[i].isFile; - entry.name = result[i].name; - entry.fullPath = result[i].fullPath; - entry.filesystem = new (require('./FileSystem'))(result[i].filesystemName); - entry.nativeURL = result[i].nativeURL; - retVal.push(entry); - } - reader.hasReadEntries = true; - successCallback(retVal); - }; - var fail = typeof errorCallback !== 'function' ? null : function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "readEntries", [this.localURL]); -}; - -module.exports = DirectoryReader; diff --git a/plugins/cordova-plugin-file/www/Entry.js b/plugins/cordova-plugin-file/www/Entry.js deleted file mode 100644 index 9cdc8774..00000000 --- a/plugins/cordova-plugin-file/www/Entry.js +++ /dev/null @@ -1,260 +0,0 @@ -/* - * - * 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 argscheck = require('cordova/argscheck'), - exec = require('cordova/exec'), - FileError = require('./FileError'), - Metadata = require('./Metadata'); - -/** - * Represents a file or directory on the local file system. - * - * @param isFile - * {boolean} true if Entry is a file (readonly) - * @param isDirectory - * {boolean} true if Entry is a directory (readonly) - * @param name - * {DOMString} name of the file or directory, excluding the path - * leading to it (readonly) - * @param fullPath - * {DOMString} the absolute full path to the file or directory - * (readonly) - * @param fileSystem - * {FileSystem} the filesystem on which this entry resides - * (readonly) - * @param nativeURL - * {DOMString} an alternate URL which can be used by native - * webview controls, for example media players. - * (optional, readonly) - */ -function Entry(isFile, isDirectory, name, fullPath, fileSystem, nativeURL) { - this.isFile = !!isFile; - this.isDirectory = !!isDirectory; - this.name = name || ''; - this.fullPath = fullPath || ''; - this.filesystem = fileSystem || null; - this.nativeURL = nativeURL || null; -} - -/** - * Look up the metadata of the entry. - * - * @param successCallback - * {Function} is called with a Metadata object - * @param errorCallback - * {Function} is called with a FileError - */ -Entry.prototype.getMetadata = function(successCallback, errorCallback) { - argscheck.checkArgs('FF', 'Entry.getMetadata', arguments); - var success = successCallback && function(entryMetadata) { - var metadata = new Metadata({ - size: entryMetadata.size, - modificationTime: entryMetadata.lastModifiedDate - }); - successCallback(metadata); - }; - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(success, fail, "File", "getFileMetadata", [this.toInternalURL()]); -}; - -/** - * Set the metadata of the entry. - * - * @param successCallback - * {Function} is called with a Metadata object - * @param errorCallback - * {Function} is called with a FileError - * @param metadataObject - * {Object} keys and values to set - */ -Entry.prototype.setMetadata = function(successCallback, errorCallback, metadataObject) { - argscheck.checkArgs('FFO', 'Entry.setMetadata', arguments); - exec(successCallback, errorCallback, "File", "setMetadata", [this.toInternalURL(), metadataObject]); -}; - -/** - * Move a file or directory to a new location. - * - * @param parent - * {DirectoryEntry} the directory to which to move this entry - * @param newName - * {DOMString} new name of the entry, defaults to the current name - * @param successCallback - * {Function} called with the new DirectoryEntry object - * @param errorCallback - * {Function} called with a FileError - */ -Entry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) { - argscheck.checkArgs('oSFF', 'Entry.moveTo', arguments); - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - var filesystem = this.filesystem, - srcURL = this.toInternalURL(), - // entry name - name = newName || this.name, - success = function(entry) { - if (entry) { - if (successCallback) { - // create appropriate Entry object - var newFSName = entry.filesystemName || (entry.filesystem && entry.filesystem.name); - var fs = newFSName ? new FileSystem(newFSName, { name: "", fullPath: "/" }) : new FileSystem(parent.filesystem.name, { name: "", fullPath: "/" }); - var result = (entry.isDirectory) ? new (require('./DirectoryEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL) : new (require('cordova-plugin-file.FileEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL); - successCallback(result); - } - } - else { - // no Entry object returned - fail && fail(FileError.NOT_FOUND_ERR); - } - }; - - // copy - exec(success, fail, "File", "moveTo", [srcURL, parent.toInternalURL(), name]); -}; - -/** - * Copy a directory to a different location. - * - * @param parent - * {DirectoryEntry} the directory to which to copy the entry - * @param newName - * {DOMString} new name of the entry, defaults to the current name - * @param successCallback - * {Function} called with the new Entry object - * @param errorCallback - * {Function} called with a FileError - */ -Entry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) { - argscheck.checkArgs('oSFF', 'Entry.copyTo', arguments); - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - var filesystem = this.filesystem, - srcURL = this.toInternalURL(), - // entry name - name = newName || this.name, - // success callback - success = function(entry) { - if (entry) { - if (successCallback) { - // create appropriate Entry object - var newFSName = entry.filesystemName || (entry.filesystem && entry.filesystem.name); - var fs = newFSName ? new FileSystem(newFSName, { name: "", fullPath: "/" }) : new FileSystem(parent.filesystem.name, { name: "", fullPath: "/" }); - var result = (entry.isDirectory) ? new (require('./DirectoryEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL) : new (require('cordova-plugin-file.FileEntry'))(entry.name, entry.fullPath, fs, entry.nativeURL); - successCallback(result); - } - } - else { - // no Entry object returned - fail && fail(FileError.NOT_FOUND_ERR); - } - }; - - // copy - exec(success, fail, "File", "copyTo", [srcURL, parent.toInternalURL(), name]); -}; - -/** - * Return a URL that can be passed across the bridge to identify this entry. - */ -Entry.prototype.toInternalURL = function() { - if (this.filesystem && this.filesystem.__format__) { - return this.filesystem.__format__(this.fullPath, this.nativeURL); - } -}; - -/** - * Return a URL that can be used to identify this entry. - * Use a URL that can be used to as the src attribute of a <video> or - * <audio> tag. If that is not possible, construct a cdvfile:// URL. - */ -Entry.prototype.toURL = function() { - if (this.nativeURL) { - return this.nativeURL; - } - // fullPath attribute may contain the full URL in the case that - // toInternalURL fails. - return this.toInternalURL() || "file://localhost" + this.fullPath; -}; - -/** - * Backwards-compatibility: In v1.0.0 - 1.0.2, .toURL would only return a - * cdvfile:// URL, and this method was necessary to obtain URLs usable by the - * webview. - * See CB-6051, CB-6106, CB-6117, CB-6152, CB-6199, CB-6201, CB-6243, CB-6249, - * and CB-6300. - */ -Entry.prototype.toNativeURL = function() { - console.log("DEPRECATED: Update your code to use 'toURL'"); - return this.toURL(); -}; - -/** - * Returns a URI that can be used to identify this entry. - * - * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI. - * @return uri - */ -Entry.prototype.toURI = function(mimeType) { - console.log("DEPRECATED: Update your code to use 'toURL'"); - return this.toURL(); -}; - -/** - * Remove a file or directory. It is an error to attempt to delete a - * directory that is not empty. It is an error to attempt to delete a - * root directory of a file system. - * - * @param successCallback {Function} called with no parameters - * @param errorCallback {Function} called with a FileError - */ -Entry.prototype.remove = function(successCallback, errorCallback) { - argscheck.checkArgs('FF', 'Entry.remove', arguments); - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(successCallback, fail, "File", "remove", [this.toInternalURL()]); -}; - -/** - * Look up the parent DirectoryEntry of this entry. - * - * @param successCallback {Function} called with the parent DirectoryEntry object - * @param errorCallback {Function} called with a FileError - */ -Entry.prototype.getParent = function(successCallback, errorCallback) { - argscheck.checkArgs('FF', 'Entry.getParent', arguments); - var fs = this.filesystem; - var win = successCallback && function(result) { - var DirectoryEntry = require('./DirectoryEntry'); - var entry = new DirectoryEntry(result.name, result.fullPath, fs, result.nativeURL); - successCallback(entry); - }; - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getParent", [this.toInternalURL()]); -}; - -module.exports = Entry; diff --git a/plugins/cordova-plugin-file/www/File.js b/plugins/cordova-plugin-file/www/File.js deleted file mode 100644 index 82ff7a78..00000000 --- a/plugins/cordova-plugin-file/www/File.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * Constructor. - * name {DOMString} name of the file, without path information - * fullPath {DOMString} the full path of the file, including the name - * type {DOMString} mime type - * lastModifiedDate {Date} last modified date - * size {Number} size of the file in bytes - */ - -var File = function(name, localURL, type, lastModifiedDate, size){ - this.name = name || ''; - this.localURL = localURL || null; - this.type = type || null; - this.lastModified = lastModifiedDate || null; - // For backwards compatibility, store the timestamp in lastModifiedDate as well - this.lastModifiedDate = lastModifiedDate || null; - this.size = size || 0; - - // These store the absolute start and end for slicing the file. - this.start = 0; - this.end = this.size; -}; - -/** - * Returns a "slice" of the file. Since Cordova Files don't contain the actual - * content, this really returns a File with adjusted start and end. - * Slices of slices are supported. - * start {Number} The index at which to start the slice (inclusive). - * end {Number} The index at which to end the slice (exclusive). - */ -File.prototype.slice = function(start, end) { - var size = this.end - this.start; - var newStart = 0; - var newEnd = size; - if (arguments.length) { - if (start < 0) { - newStart = Math.max(size + start, 0); - } else { - newStart = Math.min(size, start); - } - } - - if (arguments.length >= 2) { - if (end < 0) { - newEnd = Math.max(size + end, 0); - } else { - newEnd = Math.min(end, size); - } - } - - var newFile = new File(this.name, this.localURL, this.type, this.lastModified, this.size); - newFile.start = this.start + newStart; - newFile.end = this.start + newEnd; - return newFile; -}; - - -module.exports = File; diff --git a/plugins/cordova-plugin-file/www/FileEntry.js b/plugins/cordova-plugin-file/www/FileEntry.js deleted file mode 100644 index 59a9dc37..00000000 --- a/plugins/cordova-plugin-file/www/FileEntry.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * 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 utils = require('cordova/utils'), - exec = require('cordova/exec'), - Entry = require('./Entry'), - FileWriter = require('./FileWriter'), - File = require('./File'), - FileError = require('./FileError'); - -/** - * An interface representing a file on the file system. - * - * {boolean} isFile always true (readonly) - * {boolean} isDirectory always false (readonly) - * {DOMString} name of the file, excluding the path leading to it (readonly) - * {DOMString} fullPath the absolute full path to the file (readonly) - * {FileSystem} filesystem on which the file resides (readonly) - */ -var FileEntry = function(name, fullPath, fileSystem, nativeURL) { - FileEntry.__super__.constructor.apply(this, [true, false, name, fullPath, fileSystem, nativeURL]); -}; - -utils.extend(FileEntry, Entry); - -/** - * Creates a new FileWriter associated with the file that this FileEntry represents. - * - * @param {Function} successCallback is called with the new FileWriter - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.createWriter = function(successCallback, errorCallback) { - this.file(function(filePointer) { - var writer = new FileWriter(filePointer); - - if (writer.localURL === null || writer.localURL === "") { - errorCallback && errorCallback(new FileError(FileError.INVALID_STATE_ERR)); - } else { - successCallback && successCallback(writer); - } - }, errorCallback); -}; - -/** - * Returns a File that represents the current state of the file that this FileEntry represents. - * - * @param {Function} successCallback is called with the new File object - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.file = function(successCallback, errorCallback) { - var localURL = this.toInternalURL(); - var win = successCallback && function(f) { - var file = new File(f.name, localURL, f.type, f.lastModifiedDate, f.size); - successCallback(file); - }; - var fail = errorCallback && function(code) { - errorCallback(new FileError(code)); - }; - exec(win, fail, "File", "getFileMetadata", [localURL]); -}; - - -module.exports = FileEntry; diff --git a/plugins/cordova-plugin-file/www/FileError.js b/plugins/cordova-plugin-file/www/FileError.js deleted file mode 100644 index 6507921f..00000000 --- a/plugins/cordova-plugin-file/www/FileError.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * FileError - */ -function FileError(error) { - this.code = error || null; -} - -// File error codes -// Found in DOMException -FileError.NOT_FOUND_ERR = 1; -FileError.SECURITY_ERR = 2; -FileError.ABORT_ERR = 3; - -// Added by File API specification -FileError.NOT_READABLE_ERR = 4; -FileError.ENCODING_ERR = 5; -FileError.NO_MODIFICATION_ALLOWED_ERR = 6; -FileError.INVALID_STATE_ERR = 7; -FileError.SYNTAX_ERR = 8; -FileError.INVALID_MODIFICATION_ERR = 9; -FileError.QUOTA_EXCEEDED_ERR = 10; -FileError.TYPE_MISMATCH_ERR = 11; -FileError.PATH_EXISTS_ERR = 12; - -module.exports = FileError; diff --git a/plugins/cordova-plugin-file/www/FileReader.js b/plugins/cordova-plugin-file/www/FileReader.js deleted file mode 100644 index 5c523aa9..00000000 --- a/plugins/cordova-plugin-file/www/FileReader.js +++ /dev/null @@ -1,390 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'), - modulemapper = require('cordova/modulemapper'), - utils = require('cordova/utils'), - File = require('./File'), - FileError = require('./FileError'), - ProgressEvent = require('./ProgressEvent'), - origFileReader = modulemapper.getOriginalSymbol(window, 'FileReader'); - -/** - * This class reads the mobile device file system. - * - * For Android: - * The root directory is the root of the file system. - * To read from the SD card, the file name is "sdcard/my_file.txt" - * @constructor - */ -var FileReader = function() { - this._readyState = 0; - this._error = null; - this._result = null; - this._localURL = ''; - this._realReader = origFileReader ? new origFileReader() : {}; -}; - -// States -FileReader.EMPTY = 0; -FileReader.LOADING = 1; -FileReader.DONE = 2; - -utils.defineGetter(FileReader.prototype, 'readyState', function() { - return this._localURL ? this._readyState : this._realReader.readyState; -}); - -utils.defineGetter(FileReader.prototype, 'error', function() { - return this._localURL ? this._error: this._realReader.error; -}); - -utils.defineGetter(FileReader.prototype, 'result', function() { - return this._localURL ? this._result: this._realReader.result; -}); - -function defineEvent(eventName) { - utils.defineGetterSetter(FileReader.prototype, eventName, function() { - return this._realReader[eventName] || null; - }, function(value) { - this._realReader[eventName] = value; - }); -} -defineEvent('onloadstart'); // When the read starts. -defineEvent('onprogress'); // While reading (and decoding) file or fileBlob data, and reporting partial file data (progress.loaded/progress.total) -defineEvent('onload'); // When the read has successfully completed. -defineEvent('onerror'); // When the read has failed (see errors). -defineEvent('onloadend'); // When the request has completed (either in success or failure). -defineEvent('onabort'); // When the read has been aborted. For instance, by invoking the abort() method. - -function initRead(reader, file) { - // Already loading something - if (reader.readyState == FileReader.LOADING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - reader._result = null; - reader._error = null; - reader._readyState = FileReader.LOADING; - - if (typeof file.localURL == 'string') { - reader._localURL = file.localURL; - } else { - reader._localURL = ''; - return true; - } - - reader.onloadstart && reader.onloadstart(new ProgressEvent("loadstart", {target:reader})); -} - -/** - * Abort reading file. - */ -FileReader.prototype.abort = function() { - if (origFileReader && !this._localURL) { - return this._realReader.abort(); - } - this._result = null; - - if (this._readyState == FileReader.DONE || this._readyState == FileReader.EMPTY) { - return; - } - - this._readyState = FileReader.DONE; - - // If abort callback - if (typeof this.onabort === 'function') { - this.onabort(new ProgressEvent('abort', {target:this})); - } - // If load end callback - if (typeof this.onloadend === 'function') { - this.onloadend(new ProgressEvent('loadend', {target:this})); - } -}; - -/** - * Read text file. - * - * @param file {File} File object containing file properties - * @param encoding [Optional] (see http://www.iana.org/assignments/character-sets) - */ -FileReader.prototype.readAsText = function(file, encoding) { - if (initRead(this, file)) { - return this._realReader.readAsText(file, encoding); - } - - // Default encoding is UTF-8 - var enc = encoding ? encoding : "UTF-8"; - var me = this; - var execArgs = [this._localURL, enc, file.start, file.end]; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - // Save result - me._result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - // null result - me._result = null; - - // Save error - me._error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, "File", "readAsText", execArgs); -}; - - -/** - * Read file and return data as a base64 encoded data url. - * A data url is of the form: - * data:[<mediatype>][;base64],<data> - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsDataURL = function(file) { - if (initRead(this, file)) { - return this._realReader.readAsDataURL(file); - } - - var me = this; - var execArgs = [this._localURL, file.start, file.end]; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - // Save result - me._result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - me._result = null; - - // Save error - me._error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, "File", "readAsDataURL", execArgs); -}; - -/** - * Read file and return data as a binary data. - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsBinaryString = function(file) { - if (initRead(this, file)) { - return this._realReader.readAsBinaryString(file); - } - - var me = this; - var execArgs = [this._localURL, file.start, file.end]; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - me._result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - me._result = null; - - // Save error - me._error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, "File", "readAsBinaryString", execArgs); -}; - -/** - * Read file and return data as a binary data. - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsArrayBuffer = function(file) { - if (initRead(this, file)) { - return this._realReader.readAsArrayBuffer(file); - } - - var me = this; - var execArgs = [this._localURL, file.start, file.end]; - - // Read file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - if (r instanceof Array) { - r = new Uint8Array(r).buffer; - } - me._result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload(new ProgressEvent("load", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me._readyState === FileReader.DONE) { - return; - } - - // DONE state - me._readyState = FileReader.DONE; - - me._result = null; - - // Save error - me._error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {target:me})); - } - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend(new ProgressEvent("loadend", {target:me})); - } - }, "File", "readAsArrayBuffer", execArgs); -}; - -module.exports = FileReader; diff --git a/plugins/cordova-plugin-file/www/FileSystem.js b/plugins/cordova-plugin-file/www/FileSystem.js deleted file mode 100644 index 36bffbb0..00000000 --- a/plugins/cordova-plugin-file/www/FileSystem.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * 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 DirectoryEntry = require('./DirectoryEntry'); - -/** - * An interface representing a file system - * - * @constructor - * {DOMString} name the unique name of the file system (readonly) - * {DirectoryEntry} root directory of the file system (readonly) - */ -var FileSystem = function(name, root) { - this.name = name; - if (root) { - this.root = new DirectoryEntry(root.name, root.fullPath, this, root.nativeURL); - } else { - this.root = new DirectoryEntry(this.name, '/', this); - } -}; - -FileSystem.prototype.__format__ = function(fullPath, nativeUrl) { - return fullPath; -}; - -FileSystem.prototype.toJSON = function() { - return "<FileSystem: " + this.name + ">"; -}; - -module.exports = FileSystem; diff --git a/plugins/cordova-plugin-file/www/FileUploadOptions.js b/plugins/cordova-plugin-file/www/FileUploadOptions.js deleted file mode 100644 index b2977de7..00000000 --- a/plugins/cordova-plugin-file/www/FileUploadOptions.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * Options to customize the HTTP request used to upload files. - * @constructor - * @param fileKey {String} Name of file request parameter. - * @param fileName {String} Filename to be used by the server. Defaults to image.jpg. - * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg. - * @param params {Object} Object with key: value params to send to the server. - * @param headers {Object} Keys are header names, values are header values. Multiple - * headers of the same name are not supported. - */ -var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) { - this.fileKey = fileKey || null; - this.fileName = fileName || null; - this.mimeType = mimeType || null; - this.params = params || null; - this.headers = headers || null; - this.httpMethod = httpMethod || null; -}; - -module.exports = FileUploadOptions; diff --git a/plugins/cordova-plugin-file/www/FileUploadResult.js b/plugins/cordova-plugin-file/www/FileUploadResult.js deleted file mode 100644 index 6d74bf23..00000000 --- a/plugins/cordova-plugin-file/www/FileUploadResult.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * FileUploadResult - * @constructor - */ -module.exports = function FileUploadResult(size, code, content) { - this.bytesSent = size; - this.responseCode = code; - this.response = content; - }; diff --git a/plugins/cordova-plugin-file/www/FileWriter.js b/plugins/cordova-plugin-file/www/FileWriter.js deleted file mode 100644 index f5e0f564..00000000 --- a/plugins/cordova-plugin-file/www/FileWriter.js +++ /dev/null @@ -1,302 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'), - FileError = require('./FileError'), - ProgressEvent = require('./ProgressEvent'); - -/** - * This class writes to the mobile device file system. - * - * For Android: - * The root directory is the root of the file system. - * To write to the SD card, the file name is "sdcard/my_file.txt" - * - * @constructor - * @param file {File} File object containing file properties - * @param append if true write to the end of the file, otherwise overwrite the file - */ -var FileWriter = function(file) { - this.fileName = ""; - this.length = 0; - if (file) { - this.localURL = file.localURL || file; - this.length = file.size || 0; - } - // default is to write at the beginning of the file - this.position = 0; - - this.readyState = 0; // EMPTY - - this.result = null; - - // Error - this.error = null; - - // Event handlers - this.onwritestart = null; // When writing starts - this.onprogress = null; // While writing the file, and reporting partial file data - this.onwrite = null; // When the write has successfully completed. - this.onwriteend = null; // When the request has completed (either in success or failure). - this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method. - this.onerror = null; // When the write has failed (see errors). -}; - -// States -FileWriter.INIT = 0; -FileWriter.WRITING = 1; -FileWriter.DONE = 2; - -/** - * Abort writing file. - */ -FileWriter.prototype.abort = function() { - // check for invalid state - if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // set error - this.error = new FileError(FileError.ABORT_ERR); - - this.readyState = FileWriter.DONE; - - // If abort callback - if (typeof this.onabort === "function") { - this.onabort(new ProgressEvent("abort", {"target":this})); - } - - // If write end callback - if (typeof this.onwriteend === "function") { - this.onwriteend(new ProgressEvent("writeend", {"target":this})); - } -}; - -/** - * Writes data to the file - * - * @param data text or blob to be written - */ -FileWriter.prototype.write = function(data) { - - var that=this; - var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined'); - var isProxySupportBlobNatively = (cordova.platformId === "windows8" || cordova.platformId === "windows"); - var isBinary; - - // Check to see if the incoming data is a blob - if (data instanceof File || (!isProxySupportBlobNatively && supportsBinary && data instanceof Blob)) { - var fileReader = new FileReader(); - fileReader.onload = function() { - // Call this method again, with the arraybuffer as argument - FileWriter.prototype.write.call(that, this.result); - }; - if (supportsBinary) { - fileReader.readAsArrayBuffer(data); - } else { - fileReader.readAsText(data); - } - return; - } - - // Mark data type for safer transport over the binary bridge - isBinary = supportsBinary && (data instanceof ArrayBuffer); - if (isBinary && cordova.platformId === "windowsphone") { - // create a plain array, using the keys from the Uint8Array view so that we can serialize it - data = Array.apply(null, new Uint8Array(data)); - } - - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart(new ProgressEvent("writestart", {"target":me})); - } - - // Write file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // position always increases by bytes written because file would be extended - me.position += r; - // The length of the file is now where we are done writing. - - me.length = me.position; - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite(new ProgressEvent("write", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, "File", "write", [this.localURL, data, this.position, isBinary]); -}; - -/** - * Moves the file pointer to the location specified. - * - * If the offset is a negative number the position of the file - * pointer is rewound. If the offset is greater than the file - * size the position is set to the end of the file. - * - * @param offset is the location to move the file pointer to. - */ -FileWriter.prototype.seek = function(offset) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - if (!offset && offset !== 0) { - return; - } - - // See back from end of file. - if (offset < 0) { - this.position = Math.max(offset + this.length, 0); - } - // Offset is bigger than file size so set position - // to the end of the file. - else if (offset > this.length) { - this.position = this.length; - } - // Offset is between 0 and file size so set the position - // to start writing. - else { - this.position = offset; - } -}; - -/** - * Truncates the file to the size specified. - * - * @param size to chop the file at. - */ -FileWriter.prototype.truncate = function(size) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart(new ProgressEvent("writestart", {"target":this})); - } - - // Write file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Update the length of the file - me.length = r; - me.position = Math.min(me.position, r); - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite(new ProgressEvent("write", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, "File", "truncate", [this.localURL, size]); -}; - -module.exports = FileWriter; diff --git a/plugins/cordova-plugin-file/www/Flags.js b/plugins/cordova-plugin-file/www/Flags.js deleted file mode 100644 index a9ae6da3..00000000 --- a/plugins/cordova-plugin-file/www/Flags.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * Supplies arguments to methods that lookup or create files and directories. - * - * @param create - * {boolean} file or directory if it doesn't exist - * @param exclusive - * {boolean} used with create; if true the command will fail if - * target path exists - */ -function Flags(create, exclusive) { - this.create = create || false; - this.exclusive = exclusive || false; -} - -module.exports = Flags; diff --git a/plugins/cordova-plugin-file/www/LocalFileSystem.js b/plugins/cordova-plugin-file/www/LocalFileSystem.js deleted file mode 100644 index 1e8f2eeb..00000000 --- a/plugins/cordova-plugin-file/www/LocalFileSystem.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * - * 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. - * -*/ - -exports.TEMPORARY = 0; -exports.PERSISTENT = 1; diff --git a/plugins/cordova-plugin-file/www/Metadata.js b/plugins/cordova-plugin-file/www/Metadata.js deleted file mode 100644 index f95c44c7..00000000 --- a/plugins/cordova-plugin-file/www/Metadata.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * Information about the state of the file or directory - * - * {Date} modificationTime (readonly) - */ -var Metadata = function(metadata) { - if (typeof metadata == "object") { - this.modificationTime = new Date(metadata.modificationTime); - this.size = metadata.size || 0; - } else if (typeof metadata == "undefined") { - this.modificationTime = null; - this.size = 0; - } else { - /* Backwards compatiblity with platforms that only return a timestamp */ - this.modificationTime = new Date(metadata); - } -}; - -module.exports = Metadata; diff --git a/plugins/cordova-plugin-file/www/ProgressEvent.js b/plugins/cordova-plugin-file/www/ProgressEvent.js deleted file mode 100644 index f176f808..00000000 --- a/plugins/cordova-plugin-file/www/ProgressEvent.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * - * 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. - * -*/ - -// If ProgressEvent exists in global context, use it already, otherwise use our own polyfill -// Feature test: See if we can instantiate a native ProgressEvent; -// if so, use that approach, -// otherwise fill-in with our own implementation. -// -// NOTE: right now we always fill in with our own. Down the road would be nice if we can use whatever is native in the webview. -var ProgressEvent = (function() { - /* - var createEvent = function(data) { - var event = document.createEvent('Events'); - event.initEvent('ProgressEvent', false, false); - if (data) { - for (var i in data) { - if (data.hasOwnProperty(i)) { - event[i] = data[i]; - } - } - if (data.target) { - // TODO: cannot call <some_custom_object>.dispatchEvent - // need to first figure out how to implement EventTarget - } - } - return event; - }; - try { - var ev = createEvent({type:"abort",target:document}); - return function ProgressEvent(type, data) { - data.type = type; - return createEvent(data); - }; - } catch(e){ - */ - return function ProgressEvent(type, dict) { - this.type = type; - this.bubbles = false; - this.cancelBubble = false; - this.cancelable = false; - this.lengthComputable = false; - this.loaded = dict && dict.loaded ? dict.loaded : 0; - this.total = dict && dict.total ? dict.total : 0; - this.target = dict && dict.target ? dict.target : null; - }; - //} -})(); - -module.exports = ProgressEvent; diff --git a/plugins/cordova-plugin-file/www/android/FileSystem.js b/plugins/cordova-plugin-file/www/android/FileSystem.js deleted file mode 100644 index 518e4c42..00000000 --- a/plugins/cordova-plugin-file/www/android/FileSystem.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * 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. - * -*/ - -FILESYSTEM_PROTOCOL = "cdvfile"; - -module.exports = { - __format__: function(fullPath, nativeUrl) { - var path = '/' + this.name + '/' + encodeURI(fullPath); - path = path.replace('//','/'); - var ret = FILESYSTEM_PROTOCOL + '://localhost' + path; - var m = /\?.*/.exec(nativeUrl); - if (m) { - ret += m[0]; - } - return ret; - } -}; - diff --git a/plugins/cordova-plugin-file/www/blackberry10/FileProxy.js b/plugins/cordova-plugin-file/www/blackberry10/FileProxy.js deleted file mode 100644 index bd286cb9..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/FileProxy.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * FileProxy - * - * Register all File exec calls to be handled by proxy - */ - -module.exports = { - copyTo: require('cordova-plugin-file.copyToProxy'), - getDirectory: require('cordova-plugin-file.getDirectoryProxy'), - getFile: require('cordova-plugin-file.getFileProxy'), - getFileMetadata: require('cordova-plugin-file.getFileMetadataProxy'), - getMetadata: require('cordova-plugin-file.getMetadataProxy'), - getParent: require('cordova-plugin-file.getParentProxy'), - moveTo: require('cordova-plugin-file.moveToProxy'), - readAsArrayBuffer: require('cordova-plugin-file.readAsArrayBufferProxy'), - readAsBinaryString: require('cordova-plugin-file.readAsBinaryStringProxy'), - readAsDataURL: require('cordova-plugin-file.readAsDataURLProxy'), - readAsText: require('cordova-plugin-file.readAsTextProxy'), - readEntries: require('cordova-plugin-file.readEntriesProxy'), - remove: require('cordova-plugin-file.removeProxy'), - removeRecursively: require('cordova-plugin-file.removeRecursivelyProxy'), - resolveLocalFileSystemURI: require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAllFileSystems: require('cordova-plugin-file.requestAllFileSystemsProxy'), - requestFileSystem: require('cordova-plugin-file.requestFileSystemProxy'), - setMetadata: require('cordova-plugin-file.setMetadataProxy'), - truncate: require('cordova-plugin-file.truncateProxy'), - write: require('cordova-plugin-file.writeProxy') -}; - -require('cordova/exec/proxy').add('File', module.exports); diff --git a/plugins/cordova-plugin-file/www/blackberry10/FileSystem.js b/plugins/cordova-plugin-file/www/blackberry10/FileSystem.js deleted file mode 100644 index 59a1fac8..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/FileSystem.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * FileSystem - * - * Translate temporary / persistent / root file paths - */ - -var info = require("cordova-plugin-file.bb10FileSystemInfo"); - -module.exports = { - __format__: function(fullPath) { - switch (this.name) { - case 'temporary': - path = info.temporaryPath + fullPath; - break; - case 'persistent': - path = info.persistentPath + fullPath; - break; - case 'root': - path = 'file://' + fullPath; - break; - } - return window.encodeURI(path); - } -}; - diff --git a/plugins/cordova-plugin-file/www/blackberry10/copyTo.js b/plugins/cordova-plugin-file/www/blackberry10/copyTo.js deleted file mode 100644 index f27bf54e..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/copyTo.js +++ /dev/null @@ -1,141 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * copyTo - * - * IN: - * args - * 0 - URL of entry to copy - * 1 - URL of the directory into which to copy/move the entry - * 2 - the new name of the entry, defaults to the current name - * move - if true, delete the entry which was copied - * OUT: - * success - entry for the copied file or directory - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args, move) { - var uri = args[0], - destination = args[1], - fileName = args[2], - copiedEntry, - onSuccess = function () { - resolve( - function (entry) { - if (typeof(success) === 'function') { - success(entry); - } - }, - onFail, - [destination + copiedEntry.name] - ); - }, - onFail = function (error) { - if (typeof(fail) === 'function') { - if (error && error.code) { - //set error codes expected by mobile spec - if (uri === destination) { - fail(FileError.INVALID_MODIFICATION_ERR); - } else if (error.code === FileError.SECURITY_ERR) { - fail(FileError.INVALID_MODIFICATION_ERR); - } else { - fail(error.code); - } - } else { - fail(error); - } - } - }, - writeFile = function (fileEntry, blob, entry) { - copiedEntry = fileEntry; - fileEntry.createWriter(function (fileWriter) { - fileWriter.onwriteend = function () { - if (move) { - entry.nativeEntry.remove(onSuccess, function () { - console.error("Move operation failed. Files may exist at both source and destination"); - }); - } else { - onSuccess(); - } - }; - fileWriter.onerror = onFail; - fileWriter.write(blob); - }, onFail); - }, - copyFile = function (entry) { - if (entry.nativeEntry.file) { - entry.nativeEntry.file(function (file) { - var reader = new FileReader()._realReader; - reader.onloadend = function (e) { - var contents = new Uint8Array(this.result), - blob = new Blob([contents]); - resolve(function (destEntry) { - requestAnimationFrame(function () { - destEntry.nativeEntry.getFile(fileName, {create: true}, function (fileEntry) { - writeFile(fileEntry, blob, entry); - }, onFail); - }); - }, onFail, [destination]); - }; - reader.onerror = onFail; - reader.readAsArrayBuffer(file); - }, onFail); - } else { - onFail(FileError.INVALID_MODIFICATION_ERR); - } - }, - copyDirectory = function (entry) { - resolve(function (destEntry) { - if (entry.filesystemName !== destEntry.filesystemName) { - console.error("Copying directories between filesystems is not supported on BB10"); - onFail(FileError.INVALID_MODIFICATION_ERR); - } else { - entry.nativeEntry.copyTo(destEntry.nativeEntry, fileName, function () { - resolve(function (copiedDir) { - copiedEntry = copiedDir; - if (move) { - entry.nativeEntry.removeRecursively(onSuccess, onFail); - } else { - onSuccess(); - } - }, onFail, [destination + fileName]); - }, onFail); - } - }, onFail, [destination]); - }; - if (destination + fileName === uri) { - onFail(FileError.INVALID_MODIFICATION_ERR); - } else if (fileName.indexOf(':') > -1) { - onFail(FileError.ENCODING_ERR); - } else { - resolve(function (entry) { - if (entry.isDirectory) { - copyDirectory(entry); - } else { - copyFile(entry); - } - }, onFail, [uri]); - } -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/createEntryFromNative.js b/plugins/cordova-plugin-file/www/blackberry10/createEntryFromNative.js deleted file mode 100644 index e1e042ac..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/createEntryFromNative.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * createEntryFromNative - * - * IN - * native - webkit Entry - * OUT - * returns Cordova entry - */ - -var info = require('cordova-plugin-file.bb10FileSystemInfo'), - fileSystems = require('cordova-plugin-file.fileSystems'); - -module.exports = function (native) { - var entry = { - nativeEntry: native, - isDirectory: !!native.isDirectory, - isFile: !!native.isFile, - name: native.name, - fullPath: native.fullPath, - filesystemName: native.filesystem.name, - nativeURL: native.toURL() - }, - persistentPath = info.persistentPath.substring(7), - temporaryPath = info.temporaryPath.substring(7); - //fix bb10 webkit incorrect nativeURL - if (native.filesystem.name === 'root') { - entry.nativeURL = 'file:///' + native.fullPath; - } else if (entry.nativeURL.indexOf('filesystem:local:///persistent/') === 0) { - entry.nativeURL = info.persistentPath + native.fullPath; - } else if (entry.nativeURL.indexOf('filesystem:local:///temporary') === 0) { - entry.nativeURL = info.temporaryPath + native.fullPath; - } - //translate file system name from bb10 webkit - if (entry.filesystemName === 'local__0:Persistent' || entry.fullPath.indexOf(persistentPath) !== -1) { - entry.filesystemName = 'persistent'; - } else if (entry.filesystemName === 'local__0:Temporary' || entry.fullPath.indexOf(temporaryPath) !== -1) { - entry.filesystemName = 'temporary'; - } - //add file system property (will be called sync) - fileSystems.getFs(entry.filesystemName, function (fs) { - entry.filesystem = fs; - }); - //set root on fullPath for persistent / temporary locations - entry.fullPath = entry.fullPath.replace(persistentPath, ""); - entry.fullPath = entry.fullPath.replace(temporaryPath, ""); - //set trailing slash on directory - if (entry.isDirectory && entry.fullPath.substring(entry.fullPath.length - 1) !== '/') { - entry.fullPath += '/'; - } - if (entry.isDirectory && entry.nativeURL.substring(entry.nativeURL.length - 1) !== '/') { - entry.nativeURL += '/'; - } - //encode URL - entry.nativeURL = window.encodeURI(entry.nativeURL); - return entry; -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/getDirectory.js b/plugins/cordova-plugin-file/www/blackberry10/getDirectory.js deleted file mode 100644 index 95c84c7a..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/getDirectory.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * getDirectory - * - * IN: - * args - * 0 - local filesytem URI for the base directory to search - * 1 - directory to be created/returned; may be absolute path or relative path - * 2 - options object - * OUT: - * success - DirectoryEntry - * fail - FileError code - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0] === "/" ? "" : args[0], - dir = args[1], - options = args[2], - onSuccess = function (entry) { - if (typeof(success) === 'function') { - success(entry); - } - }, - onFail = function (error) { - if (typeof(fail) === 'function') { - if (error && error.code) { - //set error codes expected by mobile-spec tests - if (error.code === FileError.INVALID_MODIFICATION_ERR && options.exclusive) { - fail(FileError.PATH_EXISTS_ERR); - } else if ( error.code === FileError.NOT_FOUND_ERR && dir.indexOf(':') > 0) { - fail(FileError.ENCODING_ERR); - } else { - fail(error.code); - } - } else { - fail(error); - } - } - }; - resolve(function (entry) { - requestAnimationFrame(function () { - entry.nativeEntry.getDirectory(dir, options, function (nativeEntry) { - resolve(function (entry) { - onSuccess(entry); - }, onFail, [uri + "/" + dir]); - }, onFail); - }); - }, onFail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/getFile.js b/plugins/cordova-plugin-file/www/blackberry10/getFile.js deleted file mode 100644 index 1a730ae7..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/getFile.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * getFile - * - * IN: - * args - * 0 - local filesytem URI for the base directory to search - * 1 - file to be created/returned; may be absolute path or relative path - * 2 - options object - * OUT: - * success - FileEntry - * fail - FileError code - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'); - -module.exports = function (success, fail, args) { - var uri = args[0] === "/" ? "" : args[0] + "/" + args[1], - options = args[2], - onSuccess = function (entry) { - if (typeof(success) === 'function') { - success(entry); - } - }, - onFail = function (code) { - if (typeof(fail) === 'function') { - fail(code); - } - }; - resolve(function (entry) { - if (!entry.isFile) { - onFail(FileError.TYPE_MISMATCH_ERR); - } else { - onSuccess(entry); - } - }, onFail, [uri, options]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/getFileMetadata.js b/plugins/cordova-plugin-file/www/blackberry10/getFileMetadata.js deleted file mode 100644 index 3383e035..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/getFileMetadata.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * getFileMetadata - * - * IN: - * args - * 0 - local filesytem URI - * OUT: - * success - file - * - name - * - type - * - lastModifiedDate - * - size - * fail - FileError code - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (entry) { - if (typeof(success) === 'function') { - success(entry); - } - }, - onFail = function (error) { - if (typeof(fail) === 'function') { - if (error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (entry) { - requestAnimationFrame(function () { - if (entry.nativeEntry.file) { - entry.nativeEntry.file(onSuccess, onFail); - } else { - entry.nativeEntry.getMetadata(onSuccess, onFail); - } - }); - }, onFail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/getMetadata.js b/plugins/cordova-plugin-file/www/blackberry10/getMetadata.js deleted file mode 100644 index 3dd5c02c..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/getMetadata.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * getMetadata - * - * IN: - * args - * 0 - local filesytem URI - * OUT: - * success - metadata - * fail - FileError code - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (entry) { - if (typeof(success) === 'function') { - success(entry); - } - }, - onFail = function (error) { - if (typeof(fail) === 'function') { - if (error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (entry) { - entry.nativeEntry.getMetadata(onSuccess, onFail); - }, onFail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/getParent.js b/plugins/cordova-plugin-file/www/blackberry10/getParent.js deleted file mode 100644 index dd5e3547..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/getParent.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * getParent - * - * IN: - * args - * 0 - local filesytem URI - * OUT: - * success - DirectoryEntry of parent - * fail - FileError code - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (entry) { - if (typeof(success) === 'function') { - success(entry); - } - }, - onFail = function (error) { - if (typeof(fail) === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (entry) { - requestAnimationFrame(function () { - entry.nativeEntry.getParent(onSuccess, onFail); - }); - }, onFail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/info.js b/plugins/cordova-plugin-file/www/blackberry10/info.js deleted file mode 100644 index feaccd91..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/info.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * info - * - * persistentPath - full path to app sandboxed persistent storage - * temporaryPath - full path to app sandboxed temporary storage - * localPath - full path to app source (www dir) - * MAX_SIZE - maximum size for filesystem request - */ - -var info = { - persistentPath: "", - temporaryPath: "", - localPath: "", - MAX_SIZE: 64 * 1024 * 1024 * 1024 -}; - -cordova.exec( - function (path) { - info.persistentPath = 'file://' + path + '/webviews/webfs/persistent/local__0'; - info.temporaryPath = 'file://' + path + '/webviews/webfs/temporary/local__0'; - info.localPath = path.replace('/data', '/app/native'); - }, - function () { - console.error('Unable to determine local storage file path'); - }, - 'File', - 'getHomePath', - false -); - -module.exports = info; diff --git a/plugins/cordova-plugin-file/www/blackberry10/moveTo.js b/plugins/cordova-plugin-file/www/blackberry10/moveTo.js deleted file mode 100644 index f6560e8a..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/moveTo.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * moveTo - * - * IN: - * args - * 0 - URL of entry to move - * 1 - URL of the directory into which to move the entry - * 2 - the new name of the entry, defaults to the current name - * OUT: - * success - entry for the copied file or directory - * fail - FileError - */ - -var copy = cordova.require('cordova-plugin-file.copyToProxy'); - -module.exports = function (success, fail, args) { - copy(success, fail, args, true); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/readAsArrayBuffer.js b/plugins/cordova-plugin-file/www/blackberry10/readAsArrayBuffer.js deleted file mode 100644 index 41c677a2..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/readAsArrayBuffer.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * readAsArrayBuffer - * - * IN: - * args - * 0 - URL of file to read - * 1 - start position - * 2 - end position - * OUT: - * success - ArrayBuffer of file - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - start = args[1], - end = args[2], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.file(function (file) { - var reader = new FileReader()._realReader; - reader.onloadend = function () { - onSuccess(this.result.slice(start, end)); - }; - reader.onerror = onFail; - reader.readAsArrayBuffer(file); - }, onFail); - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/readAsBinaryString.js b/plugins/cordova-plugin-file/www/blackberry10/readAsBinaryString.js deleted file mode 100644 index 6a70f1a2..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/readAsBinaryString.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * readAsBinaryString - * - * IN: - * args - * 0 - URL of file to read - * 1 - start position - * 2 - end position - * OUT: - * success - BinaryString contents of file - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - start = args[1], - end = args[2], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.file(function (file) { - var reader = new FileReader()._realReader; - reader.onloadend = function () { - onSuccess(this.result.substring(start, end)); - }; - reader.onerror = onFail; - reader.readAsBinaryString(file); - }, onFail); - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/readAsDataURL.js b/plugins/cordova-plugin-file/www/blackberry10/readAsDataURL.js deleted file mode 100644 index 0256c5ec..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/readAsDataURL.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * readAsDataURL - * - * IN: - * args - * 0 - URL of file to read - * OUT: - * success - DataURL representation of file contents - * fail - FileError - */ - - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.file(function (file) { - var reader = new FileReader()._realReader; - reader.onloadend = function () { - onSuccess(this.result); - }; - reader.onerror = onFail; - reader.readAsDataURL(file); - }, onFail); - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/readAsText.js b/plugins/cordova-plugin-file/www/blackberry10/readAsText.js deleted file mode 100644 index 7809a908..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/readAsText.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * readAsText - * - * IN: - * args - * 0 - URL of file to read - * 1 - encoding - * 2 - start position - * 3 - end position - * OUT: - * success - text contents of file - * fail - FileError - */ - - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - start = args[2], - end = args[3], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.file(function (file) { - var reader = new FileReader()._realReader; - reader.onloadend = function () { - var contents = new Uint8Array(this.result).subarray(start, end), - blob = new Blob([contents]), - textReader = new FileReader()._realReader; - textReader.onloadend = function () { - onSuccess(this.result); - }; - textReader.onerror = onFail; - textReader.readAsText(blob); - }; - reader.onerror = onFail; - reader.readAsArrayBuffer(file); - }, onFail); - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/readEntries.js b/plugins/cordova-plugin-file/www/blackberry10/readEntries.js deleted file mode 100644 index 5284d77b..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/readEntries.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * readEntries - * - * IN: - * args - * 0 - URL of directory to list - * OUT: - * success - Array of Entry objects - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - info = require('cordova-plugin-file.bb10FileSystemInfo'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'), - createEntryFromNative = cordova.require('cordova-plugin-file.bb10CreateEntryFromNative'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - var reader = fs.nativeEntry.createReader(), - entries = [], - readEntries = function() { - reader.readEntries(function (results) { - if (!results.length) { - onSuccess(entries.sort().map(createEntryFromNative)); - } else { - entries = entries.concat(Array.prototype.slice.call(results || [], 0)); - readEntries(); - } - }, onFail); - }; - readEntries(); - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/remove.js b/plugins/cordova-plugin-file/www/blackberry10/remove.js deleted file mode 100644 index f57973ae..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/remove.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * remove - * - * IN: - * args - * 0 - URL of Entry to remove - * OUT: - * success - (no args) - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - if (fs.fullPath === '/') { - onFail(FileError.NO_MODIFICATION_ALLOWED_ERR); - } else { - fs.nativeEntry.remove(onSuccess, onFail); - } - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/removeRecursively.js b/plugins/cordova-plugin-file/www/blackberry10/removeRecursively.js deleted file mode 100644 index 93b559bd..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/removeRecursively.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * removeRecursively - * - * IN: - * args - * 0 - URL of DirectoryEntry to remove recursively - * OUT: - * success - (no args) - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error.code) { - if (error.code === FileError.INVALID_MODIFICATION_ERR) { - //mobile-spec expects this error code - fail(FileError.NO_MODIFICATION_ALLOWED_ERR); - } else { - fail(error.code); - } - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.removeRecursively(onSuccess, onFail); - }); - }, fail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/requestAllFileSystems.js b/plugins/cordova-plugin-file/www/blackberry10/requestAllFileSystems.js deleted file mode 100644 index 8354ab1c..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/requestAllFileSystems.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * requestAllFileSystems - * - * IN - no arguments - * OUT - * success - Array of FileSystems - * - filesystemName - * - fullPath - * - name - * - nativeURL - */ - -var info = require('cordova-plugin-file.bb10FileSystemInfo'); - -module.exports = function (success, fail, args) { - success([ - { filesystemName: 'persistent', name: 'persistent', fullPath: '/', nativeURL: info.persistentPath + '/' }, - { filesystemName: 'temporary', name: 'temporary', fullPath: '/', nativeURL: info.temporaryPath + '/' }, - { filesystemName: 'root', name: 'root', fullPath: '/', nativeURL: 'file:///' } - ]); -} diff --git a/plugins/cordova-plugin-file/www/blackberry10/requestAnimationFrame.js b/plugins/cordova-plugin-file/www/blackberry10/requestAnimationFrame.js deleted file mode 100644 index 6c3288cc..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/requestAnimationFrame.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * requestAnimationFrame - * - * This is used throughout the BB10 File implementation to wrap - * native webkit calls. There is a bug in the webkit implementation - * which causes callbacks to never return when multiple file system - * APIs are called in sequence. This should also make the UI more - * responsive during file operations. - * - * Supported on BB10 OS > 10.1 - */ - -var requestAnimationFrame = window.requestAnimationFrame; -if (typeof(requestAnimationFrame) !== 'function') { - requestAnimationFrame = function (cb) { cb(); }; -} -module.exports = requestAnimationFrame; diff --git a/plugins/cordova-plugin-file/www/blackberry10/requestFileSystem.js b/plugins/cordova-plugin-file/www/blackberry10/requestFileSystem.js deleted file mode 100644 index f02edbf5..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/requestFileSystem.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * requestFileSystem - * - * IN: - * args - * 0 - type (TEMPORARY = 0, PERSISTENT = 1) - * 1 - size - * OUT: - * success - FileSystem object - * - name - the human readable directory name - * - root - DirectoryEntry object - * - isDirectory - * - isFile - * - name - * - fullPath - * fail - FileError code - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'); - -module.exports = function (success, fail, args) { - var fsType = args[0] === 0 ? 'temporary' : 'persistent', - size = args[1], - onSuccess = function (fs) { - var directory = { - name: fsType, - root: fs - }; - success(directory); - }; - resolve(onSuccess, fail, ['cdvfile://localhost/' + fsType + '/', undefined, size]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/resolveLocalFileSystemURI.js b/plugins/cordova-plugin-file/www/blackberry10/resolveLocalFileSystemURI.js deleted file mode 100644 index 0fc9c070..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/resolveLocalFileSystemURI.js +++ /dev/null @@ -1,172 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * resolveLocalFileSystemURI - * - * IN - * args - * 0 - escaped local filesystem URI - * 1 - options (standard HTML5 file system options) - * 2 - size - * OUT - * success - Entry object - * - isDirectory - * - isFile - * - name - * - fullPath - * - nativeURL - * - fileSystemName - * fail - FileError code - */ - -var info = require('cordova-plugin-file.bb10FileSystemInfo'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'), - createEntryFromNative = require('cordova-plugin-file.bb10CreateEntryFromNative'), - SANDBOXED = true, - UNSANDBOXED = false; - -module.exports = function (success, fail, args) { - var request = args[0], - options = args[1], - size = args[2]; - if (request) { - request = decodeURIComponent(request); - if (request.indexOf('?') > -1) { - //bb10 does not support params; strip them off - request = request.substring(0, request.indexOf('?')); - } - if (request.indexOf('file://localhost/') === 0) { - //remove localhost prefix - request = request.replace('file://localhost/', 'file:///'); - } - //requests to sandboxed locations should use cdvfile - request = request.replace(info.persistentPath, 'cdvfile://localhost/persistent'); - request = request.replace(info.temporaryPath, 'cdvfile://localhost/temporary'); - //pick appropriate handler - if (request.indexOf('file:///') === 0) { - resolveFile(success, fail, request, options); - } else if (request.indexOf('cdvfile://localhost/') === 0) { - resolveCdvFile(success, fail, request, options, size); - } else if (request.indexOf('local:///') === 0) { - resolveLocal(success, fail, request, options); - } else { - fail(FileError.ENCODING_ERR); - } - } else { - fail(FileError.NOT_FOUND_ERR); - } -}; - -//resolve file:/// -function resolveFile(success, fail, request, options) { - var path = request.substring(7); - resolve(success, fail, path, window.PERSISTENT, UNSANDBOXED, options); -} - -//resolve cdvfile://localhost/filesystemname/ -function resolveCdvFile(success, fail, request, options, size) { - var components = /cdvfile:\/\/localhost\/([^\/]+)\/(.*)/.exec(request), - fsType = components[1], - path = components[2]; - if (fsType === 'persistent') { - resolve(success, fail, path, window.PERSISTENT, SANDBOXED, options, size); - } - else if (fsType === 'temporary') { - resolve(success, fail, path, window.TEMPORARY, SANDBOXED, options, size); - } - else if (fsType === 'root') { - resolve(success, fail, path, window.PERSISTENT, UNSANDBOXED, options); - } - else { - fail(FileError.NOT_FOUND_ERR); - } -} - -//resolve local:/// -function resolveLocal(success, fail, request, options) { - var path = localPath + request.substring(8); - resolve(success, fail, path, window.PERSISTENT, UNSANDBOXED, options); -} - -//validate parameters and set sandbox -function resolve(success, fail, path, fsType, sandbox, options, size) { - options = options || { create: false }; - size = size || info.MAX_SIZE; - if (size > info.MAX_SIZE) { - //bb10 does not respect quota; fail at unreasonably large size - fail(FileError.QUOTA_EXCEEDED_ERR); - } else if (path.indexOf(':') > -1) { - //files with : character are not valid in Cordova apps - fail(FileError.ENCODING_ERR); - } else { - requestAnimationFrame(function () { - cordova.exec(function () { - requestAnimationFrame(function () { - resolveNative(success, fail, path, fsType, options, size); - }); - }, fail, 'File', 'setSandbox', [sandbox], false); - }); - } -} - -//find path using webkit file system -function resolveNative(success, fail, path, fsType, options, size) { - window.webkitRequestFileSystem( - fsType, - size, - function (fs) { - if (path === '') { - //no path provided, call success with root file system - success(createEntryFromNative(fs.root)); - } else { - //otherwise attempt to resolve as file - fs.root.getFile( - path, - options, - function (entry) { - success(createEntryFromNative(entry)); - }, - function (fileError) { - //file not found, attempt to resolve as directory - fs.root.getDirectory( - path, - options, - function (entry) { - success(createEntryFromNative(entry)); - }, - function (dirError) { - //path cannot be resolved - if (fileError.code === FileError.INVALID_MODIFICATION_ERR && - options.exclusive) { - //mobile-spec expects this error code - fail(FileError.PATH_EXISTS_ERR); - } else { - fail(FileError.NOT_FOUND_ERR); - } - } - ); - } - ); - } - } - ); -} diff --git a/plugins/cordova-plugin-file/www/blackberry10/setMetadata.js b/plugins/cordova-plugin-file/www/blackberry10/setMetadata.js deleted file mode 100644 index 5254e868..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/setMetadata.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * setMetadata - * - * BB10 OS does not support setting file metadata via HTML5 File System - */ - -module.exports = function (success, fail, args) { - console.error("setMetadata not supported on BB10", arguments); - if (typeof(fail) === 'function') { - fail(); - } -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/truncate.js b/plugins/cordova-plugin-file/www/blackberry10/truncate.js deleted file mode 100644 index ba7f77f1..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/truncate.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * truncate - * - * IN: - * args - * 0 - URL of file to truncate - * 1 - start position - * OUT: - * success - new length of file - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - length = args[1], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data.loaded); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.file(function (file) { - var reader = new FileReader()._realReader; - reader.onloadend = function () { - var contents = new Uint8Array(this.result).subarray(0, length); - blob = new Blob([contents]); - window.requestAnimationFrame(function () { - fs.nativeEntry.createWriter(function (fileWriter) { - fileWriter.onwriteend = onSuccess; - fileWriter.onerror = onFail; - fileWriter.write(blob); - }, onFail); - }); - }; - reader.onerror = onFail; - reader.readAsArrayBuffer(file); - }, onFail); - }); - }, onFail, [uri]); -}; diff --git a/plugins/cordova-plugin-file/www/blackberry10/write.js b/plugins/cordova-plugin-file/www/blackberry10/write.js deleted file mode 100644 index 386ec670..00000000 --- a/plugins/cordova-plugin-file/www/blackberry10/write.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * 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. - * -*/ - -/* - * write - * - * IN: - * args - * 0 - URL of file to write - * 1 - data to write - * 2 - offset - * 3 - isBinary - * OUT: - * success - bytes written - * fail - FileError - */ - -var resolve = cordova.require('cordova-plugin-file.resolveLocalFileSystemURIProxy'), - requestAnimationFrame = cordova.require('cordova-plugin-file.bb10RequestAnimationFrame'); - -module.exports = function (success, fail, args) { - var uri = args[0], - data = args[1], - offset = args[2], - isBinary = args[3], - onSuccess = function (data) { - if (typeof success === 'function') { - success(data.loaded); - } - }, - onFail = function (error) { - if (typeof fail === 'function') { - if (error && error.code) { - fail(error.code); - } else if (error && error.target && error.target.code) { - fail(error.target.code); - } else { - fail(error); - } - } - }; - resolve(function (fs) { - requestAnimationFrame(function () { - fs.nativeEntry.createWriter(function (writer) { - var blob = new Blob([data]); - if (offset) { - writer.seek(offset); - } - writer.onwriteend = onSuccess; - writer.onerror = onFail; - writer.write(blob); - }, onFail); - }); - }, fail, [uri, { create: true }]); -}; diff --git a/plugins/cordova-plugin-file/www/browser/FileSystem.js b/plugins/cordova-plugin-file/www/browser/FileSystem.js deleted file mode 100644 index 27373d11..00000000 --- a/plugins/cordova-plugin-file/www/browser/FileSystem.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * 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. - * -*/ - -/*global FILESYSTEM_PREFIX: true, module*/ - -FILESYSTEM_PREFIX = "file:///"; - -module.exports = { - __format__: function(fullPath) { - return (FILESYSTEM_PREFIX + this.name + (fullPath[0] === '/' ? '' : '/') + encodeURI(fullPath)); - } -}; - diff --git a/plugins/cordova-plugin-file/www/browser/Preparing.js b/plugins/cordova-plugin-file/www/browser/Preparing.js deleted file mode 100644 index 13957e02..00000000 --- a/plugins/cordova-plugin-file/www/browser/Preparing.js +++ /dev/null @@ -1,187 +0,0 @@ -/* - * - * 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. - * -*/ - -/*global require*/ - -//Only Chrome uses this file. -var isChrome = window.webkitRequestFileSystem && window.webkitResolveLocalFileSystemURL; -if (!isChrome) { - return; -} - -var channel = require('cordova/channel'); -var FileError = require('./FileError'); -var PERSISTENT_FS_QUOTA = 5 * 1024 * 1024; -var filePluginIsReadyEvent = new Event('filePluginIsReady'); - -var entryFunctionsCreated = false; -var quotaWasRequested = false; -var eventWasThrown = false; - -if (!window.requestFileSystem) { - window.requestFileSystem = function(type, size, win, fail) { - if (fail) { - fail("Not supported"); - } - }; -} else { - window.requestFileSystem(window.TEMPORARY, 1, createFileEntryFunctions, function() {}); -} - -if (!window.resolveLocalFileSystemURL) { - window.resolveLocalFileSystemURL = function(url, win, fail) { - if(fail) { - fail("Not supported"); - } - }; -} - -// Resolves a filesystem entry by its path - which is passed either in standard (filesystem:file://) or -// Cordova-specific (cdvfile://) universal way. -// Aligns with specification: http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-LocalFileSystem-resolveLocalFileSystemURL -var nativeResolveLocalFileSystemURL = window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL; -window.resolveLocalFileSystemURL = function(url, win, fail) { - /* If url starts with `cdvfile` then we need convert it to Chrome real url first: - cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file */ - if (url.trim().substr(0,7) === "cdvfile") { - /* Quirk: - Plugin supports cdvfile://localhost (local resources) only. - I.e. external resources are not supported via cdvfile. */ - if (url.indexOf("cdvfile://localhost") !== -1) { - // Browser supports temporary and persistent only - var indexPersistent = url.indexOf('persistent'); - var indexTemporary = url.indexOf('temporary'); - - /* Chrome urls start with 'filesystem:' prefix. See quirk: - toURL function in Chrome returns filesystem:-prefixed path depending on application host. - For example, filesystem:file:///persistent/somefile.txt, - filesystem:http://localhost:8080/persistent/somefile.txt. */ - var prefix = 'filesystem:file:///'; - if (location.protocol !== 'file:') { - prefix = 'filesystem:' + location.origin + '/'; - } - - var result; - if (indexPersistent !== -1) { - // cdvfile://localhost/persistent/path/to/file -> filesystem:file://persistent/path/to/file - // or filesystem:http://localhost:8080/persistent/path/to/file - result = prefix + 'persistent' + url.substr(indexPersistent + 10); - nativeResolveLocalFileSystemURL(result, win, fail); - return; - } - - if (indexTemporary !== -1) { - // cdvfile://localhost/temporary/path/to/file -> filesystem:file://temporary/path/to/file - // or filesystem:http://localhost:8080/temporary/path/to/file - result = prefix + 'temporary' + url.substr(indexTemporary + 9); - nativeResolveLocalFileSystemURL(result, win, fail); - return; - } - } - - // cdvfile other than local file resource is not supported - fail && fail(new FileError(FileError.ENCODING_ERR)); - } else { - nativeResolveLocalFileSystemURL(url, win, fail); - } -}; - -function createFileEntryFunctions(fs) { - fs.root.getFile('todelete_658674_833_4_cdv', {create: true}, function(fileEntry) { - var fileEntryType = Object.getPrototypeOf(fileEntry); - var entryType = Object.getPrototypeOf(fileEntryType); - - // Save the original method - var origToURL = entryType.toURL; - entryType.toURL = function () { - var origURL = origToURL.call(this); - if (this.isDirectory && origURL.substr(-1) !== '/') { - return origURL + '/'; - } - return origURL; - }; - - entryType.toNativeURL = function () { - console.warn("DEPRECATED: Update your code to use 'toURL'"); - return this.toURL(); - }; - - entryType.toInternalURL = function() { - if (this.toURL().indexOf("persistent") > -1) { - return "cdvfile://localhost/persistent" + this.fullPath; - } - - if (this.toURL().indexOf("temporary") > -1) { - return "cdvfile://localhost/temporary" + this.fullPath; - } - }; - - entryType.setMetadata = function(win, fail /*, metadata*/) { - fail && fail("Not supported"); - }; - - fileEntry.createWriter(function(writer) { - var originalWrite = writer.write; - var writerProto = Object.getPrototypeOf(writer); - writerProto.write = function(blob) { - if(blob instanceof Blob) { - originalWrite.apply(this, [blob]); - } else { - var realBlob = new Blob([blob]); - originalWrite.apply(this, [realBlob]); - } - }; - - fileEntry.remove(function(){ entryFunctionsCreated = true; }, function(){ /* empty callback */ }); - }); - }); -} - -window.initPersistentFileSystem = function(size, win, fail) { - if (navigator.webkitPersistentStorage) { - navigator.webkitPersistentStorage.requestQuota(size, win, fail); - return; - } - - fail("This browser does not support this function"); -}; - -window.isFilePluginReadyRaised = function () { return eventWasThrown; }; - -window.initPersistentFileSystem(PERSISTENT_FS_QUOTA, function() { - console.log('Persistent fs quota granted'); - quotaWasRequested = true; -}, function(e){ - console.log('Error occured while trying to request Persistent fs quota: ' + JSON.stringify(e)); -}); - -channel.onCordovaReady.subscribe(function () { - function dispatchEventIfReady() { - if (entryFunctionsCreated && quotaWasRequested) { - window.dispatchEvent(filePluginIsReadyEvent); - eventWasThrown = true; - } else { - setTimeout(dispatchEventIfReady, 100); - } - } - - dispatchEventIfReady(); -}, false); diff --git a/plugins/cordova-plugin-file/www/fileSystemPaths.js b/plugins/cordova-plugin-file/www/fileSystemPaths.js deleted file mode 100644 index c332f481..00000000 --- a/plugins/cordova-plugin-file/www/fileSystemPaths.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'); -var channel = require('cordova/channel'); - -exports.file = { - // Read-only directory where the application is installed. - applicationDirectory: null, - // Root of app's private writable storage - applicationStorageDirectory: null, - // Where to put app-specific data files. - dataDirectory: null, - // Cached files that should survive app restarts. - // Apps should not rely on the OS to delete files in here. - cacheDirectory: null, - // Android: the application space on external storage. - externalApplicationStorageDirectory: null, - // Android: Where to put app-specific data files on external storage. - externalDataDirectory: null, - // Android: the application cache on external storage. - externalCacheDirectory: null, - // Android: the external storage (SD card) root. - externalRootDirectory: null, - // iOS: Temp directory that the OS can clear at will. - tempDirectory: null, - // iOS: Holds app-specific files that should be synced (e.g. to iCloud). - syncedDataDirectory: null, - // iOS: Files private to the app, but that are meaningful to other applciations (e.g. Office files) - documentsDirectory: null, - // BlackBerry10: Files globally available to all apps - sharedDirectory: null -}; - -channel.waitForInitialization('onFileSystemPathsReady'); -channel.onCordovaReady.subscribe(function() { - function after(paths) { - for (var k in paths) { - exports.file[k] = paths[k]; - } - channel.initializationComplete('onFileSystemPathsReady'); - } - exec(after, null, 'File', 'requestAllPaths', []); -}); - diff --git a/plugins/cordova-plugin-file/www/fileSystems-roots.js b/plugins/cordova-plugin-file/www/fileSystems-roots.js deleted file mode 100644 index ff77d944..00000000 --- a/plugins/cordova-plugin-file/www/fileSystems-roots.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * 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. - * -*/ - -// Map of fsName -> FileSystem. -var fsMap = null; -var FileSystem = require('./FileSystem'); -var exec = require('cordova/exec'); - -// Overridden by Android, BlackBerry 10 and iOS to populate fsMap. -require('./fileSystems').getFs = function(name, callback) { - if (fsMap) { - callback(fsMap[name]); - } else { - exec(success, null, "File", "requestAllFileSystems", []); - function success(response) { - fsMap = {}; - for (var i = 0; i < response.length; ++i) { - var fsRoot = response[i]; - var fs = new FileSystem(fsRoot.filesystemName, fsRoot); - fsMap[fs.name] = fs; - } - callback(fsMap[name]); - } - } -}; - diff --git a/plugins/cordova-plugin-file/www/fileSystems.js b/plugins/cordova-plugin-file/www/fileSystems.js deleted file mode 100644 index 8ecdec3e..00000000 --- a/plugins/cordova-plugin-file/www/fileSystems.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * - * 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. - * -*/ - -// Overridden by Android, BlackBerry 10 and iOS to populate fsMap. -module.exports.getFs = function(name, callback) { - callback(null); -}; diff --git a/plugins/cordova-plugin-file/www/firefoxos/FileSystem.js b/plugins/cordova-plugin-file/www/firefoxos/FileSystem.js deleted file mode 100644 index 8ff0ec4b..00000000 --- a/plugins/cordova-plugin-file/www/firefoxos/FileSystem.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * 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. - * -*/ - -FILESYSTEM_PREFIX = "file:///"; - -module.exports = { - __format__: function(fullPath) { - return (FILESYSTEM_PREFIX + this.name + (fullPath[0] === '/' ? '' : '/') + encodeURI(fullPath)); - } -}; - diff --git a/plugins/cordova-plugin-file/www/ios/FileSystem.js b/plugins/cordova-plugin-file/www/ios/FileSystem.js deleted file mode 100644 index b11d58f3..00000000 --- a/plugins/cordova-plugin-file/www/ios/FileSystem.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * 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. - * -*/ - -FILESYSTEM_PROTOCOL = "cdvfile"; - -module.exports = { - __format__: function(fullPath) { - var path = ('/'+this.name+(fullPath[0]==='/'?'':'/')+encodeURI(fullPath)).replace('//','/'); - return FILESYSTEM_PROTOCOL + '://localhost' + path; - } -}; - diff --git a/plugins/cordova-plugin-file/www/requestFileSystem.js b/plugins/cordova-plugin-file/www/requestFileSystem.js deleted file mode 100644 index 84715fa7..00000000 --- a/plugins/cordova-plugin-file/www/requestFileSystem.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * - * 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. - * -*/ - -//For browser platform: not all browsers use this file. -function checkBrowser() { - if (cordova.platformId === "browser" && navigator.userAgent.search(/Chrome/) > 0) { - var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; - module.exports = requestFileSystem; - return; - } -} -checkBrowser(); - -var argscheck = require('cordova/argscheck'), - FileError = require('./FileError'), - FileSystem = require('./FileSystem'), - exec = require('cordova/exec'); -var fileSystems = require('./fileSystems'); - -/** - * Request a file system in which to store application data. - * @param type local file system type - * @param size indicates how much storage space, in bytes, the application expects to need - * @param successCallback invoked with a FileSystem object - * @param errorCallback invoked if error occurs retrieving file system - */ -var requestFileSystem = function(type, size, successCallback, errorCallback) { - argscheck.checkArgs('nnFF', 'requestFileSystem', arguments); - var fail = function(code) { - errorCallback && errorCallback(new FileError(code)); - }; - - if (type < 0) { - fail(FileError.SYNTAX_ERR); - } else { - // if successful, return a FileSystem object - var success = function(file_system) { - if (file_system) { - if (successCallback) { - fileSystems.getFs(file_system.name, function(fs) { - // This should happen only on platforms that haven't implemented requestAllFileSystems (windows) - if (!fs) { - fs = new FileSystem(file_system.name, file_system.root); - } - successCallback(fs); - }); - } - } - else { - // no FileSystem object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - exec(success, fail, "File", "requestFileSystem", [type, size]); - } -}; - -module.exports = requestFileSystem; diff --git a/plugins/cordova-plugin-file/www/resolveLocalFileSystemURI.js b/plugins/cordova-plugin-file/www/resolveLocalFileSystemURI.js deleted file mode 100644 index dd6f90cc..00000000 --- a/plugins/cordova-plugin-file/www/resolveLocalFileSystemURI.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - * 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. - * -*/ - -//For browser platform: not all browsers use overrided `resolveLocalFileSystemURL`. -function checkBrowser() { - if (cordova.platformId === "browser" && navigator.userAgent.search(/Chrome/) > 0) { - var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; - module.exports = requestFileSystem; - return; - } -} -checkBrowser(); - -var argscheck = require('cordova/argscheck'), - DirectoryEntry = require('./DirectoryEntry'), - FileEntry = require('./FileEntry'), - FileError = require('./FileError'), - exec = require('cordova/exec'); -var fileSystems = require('./fileSystems'); - -/** - * Look up file system Entry referred to by local URI. - * @param {DOMString} uri URI referring to a local file or directory - * @param successCallback invoked with Entry object corresponding to URI - * @param errorCallback invoked if error occurs retrieving file system entry - */ -module.exports.resolveLocalFileSystemURL = function(uri, successCallback, errorCallback) { - argscheck.checkArgs('sFF', 'resolveLocalFileSystemURI', arguments); - // error callback - var fail = function(error) { - errorCallback && errorCallback(new FileError(error)); - }; - // sanity check for 'not:valid:filename' or '/not:valid:filename' - // file.spec.12 window.resolveLocalFileSystemURI should error (ENCODING_ERR) when resolving invalid URI with leading /. - if(!uri || uri.split(":").length > 2) { - setTimeout( function() { - fail(FileError.ENCODING_ERR); - },0); - return; - } - // if successful, return either a file or directory entry - var success = function(entry) { - if (entry) { - if (successCallback) { - // create appropriate Entry object - var fsName = entry.filesystemName || (entry.filesystem && entry.filesystem.name) || (entry.filesystem == window.PERSISTENT ? 'persistent' : 'temporary'); - fileSystems.getFs(fsName, function(fs) { - // This should happen only on platforms that haven't implemented requestAllFileSystems (windows) - if (!fs) { - fs = new FileSystem(fsName, {name:"", fullPath:"/"}); - } - var result = (entry.isDirectory) ? new DirectoryEntry(entry.name, entry.fullPath, fs, entry.nativeURL) : new FileEntry(entry.name, entry.fullPath, fs, entry.nativeURL); - successCallback(result); - }); - } - } - else { - // no Entry object returned - fail(FileError.NOT_FOUND_ERR); - } - }; - - exec(success, fail, "File", "resolveLocalFileSystemURI", [uri]); -}; - -module.exports.resolveLocalFileSystemURI = function() { - console.log("resolveLocalFileSystemURI is deprecated. Please call resolveLocalFileSystemURL instead."); - module.exports.resolveLocalFileSystemURL.apply(this, arguments); -}; diff --git a/plugins/cordova-plugin-file/www/ubuntu/FileSystem.js b/plugins/cordova-plugin-file/www/ubuntu/FileSystem.js deleted file mode 100644 index c43da824..00000000 --- a/plugins/cordova-plugin-file/www/ubuntu/FileSystem.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * 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. - * -*/ - -FILESYSTEM_PROTOCOL = "cdvfile"; - -module.exports = { - __format__: function(fullPath) { - if (this.name === 'content') { - return 'content:/' + fullPath; - } - var path = ('/' + this.name + (fullPath[0] === '/' ? '' : '/') + encodeURI(fullPath)).replace('//','/'); - - return FILESYSTEM_PROTOCOL + '://localhost' + path; - } -}; - diff --git a/plugins/cordova-plugin-file/www/ubuntu/FileWriter.js b/plugins/cordova-plugin-file/www/ubuntu/FileWriter.js deleted file mode 100644 index a75506b7..00000000 --- a/plugins/cordova-plugin-file/www/ubuntu/FileWriter.js +++ /dev/null @@ -1,135 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'), - FileError = require('./FileError'), - ProgressEvent = require('./ProgressEvent'); - -function write(data) { - var that=this; - var supportsBinary = (typeof window.Blob !== 'undefined' && typeof window.ArrayBuffer !== 'undefined'); - var isBinary; - - // Check to see if the incoming data is a blob - if (data instanceof File || (supportsBinary && data instanceof Blob)) { - var fileReader = new FileReader(); - fileReader.onload = function() { - // Call this method again, with the arraybuffer as argument - FileWriter.prototype.write.call(that, this.result); - }; - if (supportsBinary) { - fileReader.readAsArrayBuffer(data); - } else { - fileReader.readAsText(data); - } - return; - } - - // Mark data type for safer transport over the binary bridge - isBinary = supportsBinary && (data instanceof ArrayBuffer); - - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw new FileError(FileError.INVALID_STATE_ERR); - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart(new ProgressEvent("writestart", {"target":me})); - } - - if (data instanceof ArrayBuffer || data.buffer instanceof ArrayBuffer) { - data = new Uint8Array(data); - var binary = ""; - for (var i = 0; i < data.byteLength; i++) { - binary += String.fromCharCode(data[i]); - } - data = binary; - } - - var prefix = "file://localhost"; - var path = this.localURL; - if (path.substr(0, prefix.length) == prefix) { - path = path.substr(prefix.length); - } - // Write file - exec( - // Success callback - function(r) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // position always increases by bytes written because file would be extended - me.position += r; - // The length of the file is now where we are done writing. - - me.length = me.position; - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite(new ProgressEvent("write", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, - // Error callback - function(e) { - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // DONE state - me.readyState = FileWriter.DONE; - - // Save error - me.error = new FileError(e); - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror(new ProgressEvent("error", {"target":me})); - } - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend(new ProgressEvent("writeend", {"target":me})); - } - }, "File", "write", [path, data, this.position, isBinary]); -}; - -module.exports = { - write: write -}; - -require("cordova/exec/proxy").add("FileWriter", module.exports); diff --git a/plugins/cordova-plugin-file/www/ubuntu/fileSystems-roots.js b/plugins/cordova-plugin-file/www/ubuntu/fileSystems-roots.js deleted file mode 100644 index e132a959..00000000 --- a/plugins/cordova-plugin-file/www/ubuntu/fileSystems-roots.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * 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 fsMap = null; -var FileSystem = require('./FileSystem'); -var LocalFileSystem = require('./LocalFileSystem'); -var exec = require('cordova/exec'); - -var requestFileSystem = function(type, size, successCallback) { - var success = function(file_system) { - if (file_system) { - if (successCallback) { - fs = new FileSystem(file_system.name, file_system.root); - successCallback(fs); - } - } - }; - exec(success, null, "File", "requestFileSystem", [type, size]); -}; - -require('./fileSystems').getFs = function(name, callback) { - if (fsMap) { - callback(fsMap[name]); - } else { - requestFileSystem(LocalFileSystem.PERSISTENT, 1, function(fs) { - requestFileSystem(LocalFileSystem.TEMPORARY, 1, function(tmp) { - fsMap = {}; - fsMap[tmp.name] = tmp; - fsMap[fs.name] = fs; - callback(fsMap[name]); - }); - }); - } -}; - diff --git a/plugins/cordova-plugin-file/www/wp/FileUploadOptions.js b/plugins/cordova-plugin-file/www/wp/FileUploadOptions.js deleted file mode 100644 index 696573ab..00000000 --- a/plugins/cordova-plugin-file/www/wp/FileUploadOptions.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * Options to customize the HTTP request used to upload files. - * @constructor - * @param fileKey {String} Name of file request parameter. - * @param fileName {String} Filename to be used by the server. Defaults to image.jpg. - * @param mimeType {String} Mimetype of the uploaded file. Defaults to image/jpeg. - * @param params {Object} Object with key: value params to send to the server. - */ -var FileUploadOptions = function(fileKey, fileName, mimeType, params, headers, httpMethod) { - this.fileKey = fileKey || null; - this.fileName = fileName || null; - this.mimeType = mimeType || null; - this.headers = headers || null; - this.httpMethod = httpMethod || null; - - if(params && typeof params != typeof "") { - var arrParams = []; - for(var v in params) { - arrParams.push(v + "=" + params[v]); - } - this.params = encodeURIComponent(arrParams.join("&")); - } - else { - this.params = params || null; - } -}; - -module.exports = FileUploadOptions; diff --git a/plugins/cordova-plugin-inappbrowser/CONTRIBUTING.md b/plugins/cordova-plugin-inappbrowser/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/cordova-plugin-inappbrowser/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/cordova-plugin-inappbrowser/LICENSE b/plugins/cordova-plugin-inappbrowser/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/cordova-plugin-inappbrowser/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/cordova-plugin-inappbrowser/NOTICE b/plugins/cordova-plugin-inappbrowser/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/cordova-plugin-inappbrowser/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/cordova-plugin-inappbrowser/README.md b/plugins/cordova-plugin-inappbrowser/README.md deleted file mode 100644 index 31a3c72f..00000000 --- a/plugins/cordova-plugin-inappbrowser/README.md +++ /dev/null @@ -1,388 +0,0 @@ -<!--- - license: 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. ---> - -# cordova-plugin-inappbrowser - -[](https://travis-ci.org/apache/cordova-plugin-inappbrowser) - -This plugin provides a web browser view that displays when calling `cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - -The `cordova.InAppBrowser.open()` function is defined to be a drop-in replacement -for the `window.open()` function. Existing `window.open()` calls can use the -InAppBrowser window, by replacing window.open: - - window.open = cordova.InAppBrowser.open; - -The InAppBrowser window behaves like a standard web browser, -and can't access Cordova APIs. For this reason, the InAppBrowser is recommended -if you need to load third-party (untrusted) content, instead of loading that -into the main Cordova webview. The InAppBrowser is not subject to the -whitelist, nor is opening links in the system browser. - -The InAppBrowser provides by default its own GUI controls for the user (back, -forward, done). - -For backwards compatibility, this plugin also hooks `window.open`. -However, the plugin-installed hook of `window.open` can have unintended side -effects (especially if this plugin is included only as a dependency of another -plugin). The hook of `window.open` will be removed in a future major release. -Until the hook is removed from the plugin, apps can manually restore the default -behaviour: - - delete window.open // Reverts the call back to it's prototype's default - -Although `window.open` is in the global scope, InAppBrowser is not available until after the `deviceready` event. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - -## Installation - - cordova plugin add cordova-plugin-inappbrowser - -If you want all page loads in your app to go through the InAppBrowser, you can -simply hook `window.open` during initialization. For example: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - -## cordova.InAppBrowser.open - -Opens a URL in a new `InAppBrowser` instance, the current browser -instance, or the system browser. - - var ref = cordova.InAppBrowser.open(url, target, options); - -- __ref__: Reference to the `InAppBrowser` window. _(InAppBrowser)_ - -- __url__: The URL to load _(String)_. Call `encodeURI()` on this if the URL contains Unicode characters. - -- __target__: The target in which to load the URL, an optional parameter that defaults to `_self`. _(String)_ - - - `_self`: Opens in the Cordova WebView if the URL is in the white list, otherwise it opens in the `InAppBrowser`. - - `_blank`: Opens in the `InAppBrowser`. - - `_system`: Opens in the system's web browser. - -- __options__: Options for the `InAppBrowser`. Optional, defaulting to: `location=yes`. _(String)_ - - The `options` string must not contain any blank space, and each feature's name/value pairs must be separated by a comma. Feature names are case insensitive. All platforms support the value below: - - - __location__: Set to `yes` or `no` to turn the `InAppBrowser`'s location bar on or off. - - Android only: - - - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. - - __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened - - __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened - - __zoom__: set to `yes` to show Android browser's zoom controls, set to `no` to hide them. Default value is `yes`. - - __hardwareback__: set to `yes` to use the hardware back button to navigate backwards through the `InAppBrowser`'s history. If there is no previous page, the `InAppBrowser` will close. The default value is `yes`, so you must set it to `no` if you want the back button to simply close the InAppBrowser. - - iOS only: - - - __closebuttoncaption__: set to a string to use as the __Done__ button's caption. Note that you need to localize this value yourself. - - __disallowoverscroll__: Set to `yes` or `no` (default is `no`). Turns on/off the UIWebViewBounce property. - - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. - - __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened - - __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened - - __toolbar__: set to `yes` or `no` to turn the toolbar on or off for the InAppBrowser (defaults to `yes`) - - __enableViewportScale__: Set to `yes` or `no` to prevent viewport scaling through a meta tag (defaults to `no`). - - __mediaPlaybackRequiresUserAction__: Set to `yes` or `no` to prevent HTML5 audio or video from autoplaying (defaults to `no`). - - __allowInlineMediaPlayback__: Set to `yes` or `no` to allow in-line HTML5 media playback, displaying within the browser window rather than a device-specific playback interface. The HTML's `video` element must also include the `webkit-playsinline` attribute (defaults to `no`) - - __keyboardDisplayRequiresUserAction__: Set to `yes` or `no` to open the keyboard when form elements receive focus via JavaScript's `focus()` call (defaults to `yes`). - - __suppressesIncrementalRendering__: Set to `yes` or `no` to wait until all new view content is received before being rendered (defaults to `no`). - - __presentationstyle__: Set to `pagesheet`, `formsheet` or `fullscreen` to set the [presentation style](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (defaults to `fullscreen`). - - __transitionstyle__: Set to `fliphorizontal`, `crossdissolve` or `coververtical` to set the [transition style](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (defaults to `coververtical`). - - __toolbarposition__: Set to `top` or `bottom` (default is `bottom`). Causes the toolbar to be at the top or bottom of the window. - - Windows only: - - - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. - - __fullscreen__: set to `yes` to create the browser control without a border around it. Please note that if __location=no__ is also specified, there will be no control presented to user to close IAB window. - -### Supported Platforms - -- Amazon Fire OS -- Android -- BlackBerry 10 -- Firefox OS -- iOS -- Windows 8 and 8.1 -- Windows Phone 7 and 8 -- Browser - -### Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - -### Firefox OS Quirks - -As plugin doesn't enforce any design there is a need to add some CSS rules if -opened with `target='_blank'`. The rules might look like these - -``` css -.inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); -} -.inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; -} -.inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); -} -.inAppBrowserWrap menu li.disabled { - color: #777; -} -``` - -### Windows Quirks - -Similar to Firefox OS IAB window visual behaviour can be overridden via `inAppBrowserWrap`/`inAppBrowserWrapFullscreen` CSS classes - -### Browser Quirks - -- Plugin is implemented via iframe, - -- Navigation history (`back` and `forward` buttons in LocationBar) is not implemented. - -## InAppBrowser - -The object returned from a call to `cordova.InAppBrowser.open`. - -### Methods - -- addEventListener -- removeEventListener -- close -- show -- executeScript -- insertCSS - -## addEventListener - -> Adds a listener for an event from the `InAppBrowser`. - - ref.addEventListener(eventname, callback); - -- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_ - -- __eventname__: the event to listen for _(String)_ - - - __loadstart__: event fires when the `InAppBrowser` starts to load a URL. - - __loadstop__: event fires when the `InAppBrowser` finishes loading a URL. - - __loaderror__: event fires when the `InAppBrowser` encounters an error when loading a URL. - - __exit__: event fires when the `InAppBrowser` window is closed. - -- __callback__: the function that executes when the event fires. The function is passed an `InAppBrowserEvent` object as a parameter. - -### InAppBrowserEvent Properties - -- __type__: the eventname, either `loadstart`, `loadstop`, `loaderror`, or `exit`. _(String)_ - -- __url__: the URL that was loaded. _(String)_ - -- __code__: the error code, only in the case of `loaderror`. _(Number)_ - -- __message__: the error message, only in the case of `loaderror`. _(String)_ - - -### Supported Platforms - -- Amazon Fire OS -- Android -- iOS -- Windows 8 and 8.1 -- Windows Phone 7 and 8 -- Browser - -### Browser Quirks - -`loadstart` and `loaderror` events are not being fired. - -### Quick Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - -## removeEventListener - -> Removes a listener for an event from the `InAppBrowser`. - - ref.removeEventListener(eventname, callback); - -- __ref__: reference to the `InAppBrowser` window. _(InAppBrowser)_ - -- __eventname__: the event to stop listening for. _(String)_ - - - __loadstart__: event fires when the `InAppBrowser` starts to load a URL. - - __loadstop__: event fires when the `InAppBrowser` finishes loading a URL. - - __loaderror__: event fires when the `InAppBrowser` encounters an error loading a URL. - - __exit__: event fires when the `InAppBrowser` window is closed. - -- __callback__: the function to execute when the event fires. -The function is passed an `InAppBrowserEvent` object. - -### Supported Platforms - -- Amazon Fire OS -- Android -- iOS -- Windows 8 and 8.1 -- Windows Phone 7 and 8 -- Browser - -### Quick Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - -## close - -> Closes the `InAppBrowser` window. - - ref.close(); - -- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_ - -### Supported Platforms - -- Amazon Fire OS -- Android -- Firefox OS -- iOS -- Windows 8 and 8.1 -- Windows Phone 7 and 8 -- Browser - -### Quick Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - -## show - -> Displays an InAppBrowser window that was opened hidden. Calling this has no effect if the InAppBrowser was already visible. - - ref.show(); - -- __ref__: reference to the InAppBrowser window (`InAppBrowser`) - -### Supported Platforms - -- Amazon Fire OS -- Android -- iOS -- Windows 8 and 8.1 -- Browser - -### Quick Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - -## executeScript - -> Injects JavaScript code into the `InAppBrowser` window - - ref.executeScript(details, callback); - -- __ref__: reference to the `InAppBrowser` window. _(InAppBrowser)_ - -- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_ - - __file__: URL of the script to inject. - - __code__: Text of the script to inject. - -- __callback__: the function that executes after the JavaScript code is injected. - - If the injected script is of type `code`, the callback executes - with a single parameter, which is the return value of the - script, wrapped in an `Array`. For multi-line scripts, this is - the return value of the last statement, or the last expression - evaluated. - -### Supported Platforms - -- Amazon Fire OS -- Android -- iOS -- Windows 8 and 8.1 -- Browser - -### Quick Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - -### Browser Quirks - -- only __code__ key is supported. - -### Windows Quirks - -Due to [MSDN docs](https://msdn.microsoft.com/en-us/library/windows.ui.xaml.controls.webview.invokescriptasync.aspx) the invoked script can return only string values, otherwise the parameter, passed to __callback__ will be `[null]`. - -## insertCSS - -> Injects CSS into the `InAppBrowser` window. - - ref.insertCSS(details, callback); - -- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_ - -- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_ - - __file__: URL of the stylesheet to inject. - - __code__: Text of the stylesheet to inject. - -- __callback__: the function that executes after the CSS is injected. - -### Supported Platforms - -- Amazon Fire OS -- Android -- iOS -- Windows - -### Quick Example - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); - diff --git a/plugins/cordova-plugin-inappbrowser/RELEASENOTES.md b/plugins/cordova-plugin-inappbrowser/RELEASENOTES.md deleted file mode 100644 index f7a24cc0..00000000 --- a/plugins/cordova-plugin-inappbrowser/RELEASENOTES.md +++ /dev/null @@ -1,192 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.2.2 (Sept 25, 2013) -* CB-4889 bumping&resetting version -* CB-4788: Modified the onJsPrompt to warn against Cordova calls -* [windows8] commandProxy was moved -* CB-4788: Modified the onJsPrompt to warn against Cordova calls -* [windows8] commandProxy was moved -* CB-4889 renaming core references -* CB-4889 renaming org.apache.cordova.core.inappbrowser to org.apache.cordova.inappbrowser -* CB-4864, CB-4865: Minor improvements to InAppBrowser -* Rename CHANGELOG.md -> RELEASENOTES.md -* [CB-4792] Added keepCallback to the show function. -* [CB-4752] Incremented plugin version on dev branch. - -### 0.2.3 (Oct 9, 2013) -* [CB-4915] Incremented plugin version on dev branch. -* [CB-4926] Fixes inappbrowser plugin loading for windows8 - -### 0.2.4 (Oct 28, 2013) -* CB-5128: added repo + issue tag to plugin.xml for inappbrowser plugin -* CB-4995 Fix crash when WebView is quickly opened then closed. -* CB-4930 - iOS - InAppBrowser should take into account the status bar -* [CB-5010] Incremented plugin version on dev branch. -* [CB-5010] Updated version and RELEASENOTES.md for release 0.2.3 -* CB-4858 - Run IAB methods on the UI thread. -* CB-4858 Convert relative URLs to absolute URLs in JS -* CB-3747 Fix back button having different dismiss logic from the close button. -* CB-5021 Expose closeDialog() as a public function and make it safe to call multiple times. -* CB-5021 Make it safe to call close() multiple times - -### 0.2.5 (Dec 4, 2013) -* Remove merge conflict tag -* [CB-4724] fixed UriFormatException -* add ubuntu platform -* CB-3420 WP feature hidden=yes implemented -* Added amazon-fireos platform. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos' - -### 0.3.0 (Jan 02, 2014) -* CB-5592 Android: Add MIME type to Intent when opening file:/// URLs -* CB-5594 iOS: Add disallowoverscroll option. -* CB-5658 Add doc/index.md for InAppBrowser plugin -* CB-5595 Add toolbarposition=top option. -* Apply CB-5193 to InAppBrowser (Fix DB quota exception) -* CB-5593 iOS: Make InAppBrowser localizable -* CB-5591 Change window.escape to encodeURIComponent - -### 0.3.1 (Feb 05, 2014) -* CB-5756: Android: Use WebView.evaluateJavascript for script injection on Android 4.4+ -* Didn't test on ICS or lower, getDrawable isn't supported until Jellybean -* add ubuntu platform -* Adding drawables to the inAppBrowser. This doesn't look quite right, but it's a HUGE improvement over the previous settings -* CB-5756: Android: Use WebView.evaluateJavascript for script injection on Android 4.4+ -* Remove alive from InAppBrowser.js since it didn't catch the case where the browser is closed by the user. -* CB-5733 Fix IAB.close() not working if called before show() animation is done - -### 0.3.2 (Feb 26, 2014) -* Validate that callbackId is correctly formed -* CB-6035 Move js-module so it is not loaded on unsupported platforms -* Removed some iOS6 Deprecations - -### 0.3.3 (Mar 5, 2014) -* CB-5534 Fix video/audio does not stop playing when browser is closed -* CB-6172 Fix broken install on case-sensitive file-systems - - -### 0.4.0 (Apr 17, 2014) -* CB-6360: [ios] Fix for crash on iOS < 6.0 (closes #37) -* CB-3324: [WP8] Add support for back-button inappbrowser [WP8] if there is no history -> InAppBrowser is closed -* [WP] await async calls, resolve warnings -* [WP] Make InAppBrowser work with embedded files, using system behavior -* CB-6402: [WP8] pass empty string instead of null for [optional] windowFeatures string -* CB-6422: [windows8] use cordova/exec/proxy -* CB-6389 CB-3617: Add clearcache and clearsessioncache options to iOS (like Android) -* Doc update: event name and example param (closes #31) -* CB-6253: [WP] Add Network Capability to WMAppManifest.xml -* CB-6212: [iOS] fix warnings compiled under arm64 64-bit -* CB-6218: Update docs for BB10 -* CB-6460: Update license headers - -### 0.5.0 (Jun 05, 2014) -* CB-6127 Spanish and rench Translations added. Github close #23 -* Clean up whitespace (mainly due to no newline at eof warning) -* Adding permission info -* CB-6806 Add license -* CB-6491 add CONTRIBUTING.md -* Add necessary capability so the plugin works on its own -* CB-6474 InAppBrowser. Add data urls support to WP8 -* CB-6482 InAppBrowser calls incorrect callback on WP8 -* Fixed use of iOS 6 deprecated methods -* CB-6360 - improvement: feature detection instead of iOS version detection -* CB-5649 - InAppBrowser overrides App's orientation -* refactoring fixed -* CB-6396 [Firefox OS] Adding basic support - -### 0.5.1 (Aug 06, 2014) -* ubuntu: support qt 5.2 -* **FFOS** update InAppBrowserProxy.js -* **FFOS** app needs to be privileged -* CB-6127 Updated translations for docs -* CB-6769 ios: Fix statusbar color reset wasn't working on iOS7+ - -### 0.5.2 (Sep 17, 2014) -* CB-7471 cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser -* CB-7490 Fixes InAppBrowser manual tests crash on windows platform -* CB-7249 cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser -* CB-7424 Wrong docs: anchor tags are not supported by the InAppBrowser -* CB-7133 clarify that anchor1 doesn't exist -* CB-7133 more fixup of tests on Android -* CB-7133 fix up the tests for Android -* Add just a bit more logging -* CB-7133 port inappbrowser to plugin-test-framework -* phonegap events supported for \_blank target -* inappbrowser \_blank target position is fixed -* amazon-fireos related changes. - -### 0.5.3 (Oct 03, 2014) -* Windows implementation fixes and improvements -* zIndex fixed -* renamed InAppBrowser back to inappbrowser for case sensitive operating systems -* Update french translation -* Update doc to add Windows 8 -* Update windows proxy to be both compatible with windows 8 and 8.1 -* Rename windows81 by windows8 in src directory -* Append Windows 8.1 platform configuration in plugin.xml -* Append Windows 8.1 proxy using x-ms-webview - -### 0.5.4 (Dec 02, 2014) -* CB-7784 Exit event is not fired after `InAppBrowser` closing -* CB-7697 Add `locationBar` support to `InAppBrowser` **Windows** platform version -* CB-7690 `InAppBrowser` `loadstart/loadstop` events issues -* CB-7695 Fix `InAppBrowser` `injectScriptFile` for **Windows 8.1** / **Windows Phone 8.1** -* CB-7692 `InAppBrowser` local url opening bug in 8.1 -* CB-7688 `Alert` is not supported in `InAppBrowser` on **Windows** platform -* CB-7977 Mention `deviceready` in plugin docs -* CB-7876 change test target to avoid undesired redirects -* CB-7712 remove references to `closebuttoncaption` -* CB-7850 clarify role of whitelist -* CB-7720 check if event is null since OK string from success callback was removed -* CB-7471 cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser - -### 0.6.0 (Feb 04, 2015) -* CB-8270 ios: Remove usage of `[arr JSONString]`, since it's been renamed to `cdv_JSONString` -* ubuntu: implement inject* functions -* ubuntu: port to oxide -* CB-7897 ios, android: Update to work with whilelist plugins in Cordova 4.x - -### 1.0.0 (Apr 15, 2015) -* CB-8746 gave plugin major version bump -* CB-7689 Adds insertCSS support for windows platform -* CB-4930 - (prefix) InAppBrowser should take into account the status bar -* CB-8635 Improves UX on windows platform -* CB-8661 Return executed script result on Windows -* CB-8683 updated wp and browser specific references of old id to new id -* CB-8683 changed plugin-id to pacakge-name -* CB-8653 properly updated translated docs to use new id -* CB-8653 updated translated docs to use new id -* Use TRAVIS_BUILD_DIR, install paramedic by npm -* CB-8432 Correct styles for browser wrapper to display it correctly on some pages -* CB-8659 - Update InAppBrowser to support both cordova-ios 4.0.x and 3.x (closes #93) -* CB-7961 Add cordova-plugin-inappbrowser support for browser platform -* CB-8653 Updated Readme -* Update docs for Android zoom=no option -* Added option to disable/enable zoom controls -* updated docs, set hardwareback default to true -* Add a hardwareback option to allow for the hardware back button to go back. -* CB-8570 Integrate TravisCI -* CB-8438 cordova-plugin-inappbrowser documentation translation: cordova-plugin-inappbrowser -* CB-8538 Added package.json file -* Keep external android pages in a single tab. (close #61) -* CB-8444 Add a clobber for `cordova.InAppBrowser.open` (close #80) -* CB-8444 Don't clobber `window.open` - Add new symbol/clobber to access open function (`cordova.InAppBrowser.open`) - Change existing tests to use new symbol (i.e. don't rely on plugin clobber of `window.open`) - Add tests to use `window.open` via manual replace with new symbol - Update docs to deprecate plugin clobber of `window.open` diff --git a/plugins/cordova-plugin-inappbrowser/doc/de/index.md b/plugins/cordova-plugin-inappbrowser/doc/de/index.md deleted file mode 100644 index d2b29d57..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/de/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -Dieses Plugin bietet eine Web-Browser-Ansicht, die beim Aufruf von `cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -Die `cordova.InAppBrowser.open()` Funktion ist definiert als Ersatz für die `window.open()` Funktion. InAppBrowser Fenster, können vorhandene `window.open()` Aufrufe durch window.open ersetzen: - - window.open = cordova.InAppBrowser.open; - - -Das InAppBrowser-Fenster verhält sich wie einen standard-Webbrowser und Cordova APIs kann nicht zugegriffen werden kann. Aus diesem Grund empfiehlt sich die InAppBrowser Wenn Sie von Drittanbietern (nicht vertrauenswürdige) Inhalte, statt zu laden, die in den wichtigsten Cordova Webview laden müssen. Die InAppBrowser unterliegt nicht der weißen Liste, noch ist Links in der Systembrowser öffnen. - -Die InAppBrowser bietet standardmäßig eine eigene GUI-Steuerelemente für den Benutzer (zurück, vor, erledigt). - -Für rückwärts Kompatibilität, dieses Plugin auch `window.open` Haken. Jedoch kann der Plugin installiert Haken der `window.open` haben unbeabsichtigte Nebenwirkungen (vor allem, wenn dieses Plugin nur als eine Abhängigkeit von einem anderen Plugin enthalten ist). Der Haken der `window.open` wird in einer zukünftigen Version entfernt. Bis der Haken aus dem Plugin entfernt wird, können die Vorgabe von apps manuell wiederherstellen: - - delete window.open // Reverts the call back to it's prototype's default - - -`window.open` im globalen Gültigkeitsbereich ist zwar InAppBrowser nicht verfügbar bis nach dem `deviceready`-Ereignis. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## Installation - - cordova plugin add cordova-plugin-inappbrowser - - -Wenn Sie alle Seite Lasten in Ihrer Anwendung durch die InAppBrowser gehen möchten, können Sie einfach `window.open` während der Initialisierung Haken. Zum Beispiel: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -Öffnet eine URL in eine neue `InAppBrowser`-Instanz, die aktuelle Browserinstanz oder der Systembrowser. - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **Ref**: Bezugnahme auf das `InAppBrowser` Fenster. *(InAppBrowser)* - -* **URL**: die URL um den *(String)* zu laden. Rufen Sie `encodeURI()` auf, wenn die URL Unicode-Zeichen enthält. - -* **target**: das Ziel in welchem die URL geladen werden soll. Standardmäßig entspricht dieser Wert `_self` . *(String)* - - * `_self`: Öffnet sich in der Cordova WebView wenn der URL in der Whitelist ist, andernfalls es öffnet sich in der`InAppBrowser`. - * `_blank`: Öffnet den`InAppBrowser`. - * `_system`: Öffnet in den System-Web-Browser. - -* **options**: Optionen für die `InAppBrowser` . Optional, säumige an: `location=yes` . *(String)* - - Die `options` Zeichenfolge muss keine Leerstelle enthalten, und jede Funktion Name/Wert-Paare müssen durch ein Komma getrennt werden. Featurenamen Groß-/Kleinschreibung. Alle Plattformen unterstützen die anderen Werte: - - * **location**: Legen Sie auf `yes` oder `no` , machen die `InAppBrowser` der Adressleiste ein- oder ausschalten. - - Nur Android: - - * **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben. - * **clearcache**: Legen Sie auf `yes` , der Browser ist Cookiecache gelöscht, bevor das neue Fenster geöffnet wird - * **clearsessioncache**: Legen Sie auf `yes` zu der Session Cookie Cache gelöscht, bevor das neue Fenster geöffnet wird - - iOS nur: - - * **closebuttoncaption**: Legen Sie auf eine Zeichenfolge als Beschriftung der **fertig** -Schaltfläche verwenden. Beachten Sie, dass Sie diesen Wert selbst zu lokalisieren müssen. - * **disallowoverscroll**: Legen Sie auf `yes` oder `no` (Standard ist `no` ). Aktiviert/deaktiviert die UIWebViewBounce-Eigenschaft. - * **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben. - * **clearcache**: Legen Sie auf `yes` , der Browser ist Cookiecache gelöscht, bevor das neue Fenster geöffnet wird - * **clearsessioncache**: Legen Sie auf `yes` zu der Session Cookie Cache gelöscht, bevor das neue Fenster geöffnet wird - * **toolbar**: Legen Sie auf `yes` oder `no` Aktivieren Sie die Symbolleiste ein- oder Ausschalten für InAppBrowser (Standard:`yes`) - * **enableViewportScale**: Legen Sie auf `yes` oder `no` , Viewport Skalierung durch ein Meta-Tag (standardmäßig zu verhindern`no`). - * **mediaPlaybackRequiresUserAction**: Legen Sie auf `yes` oder `no` , HTML5 audio oder video von automatisches Abspielen (standardmäßig zu verhindern`no`). - * **allowInlineMediaPlayback**: Legen Sie auf `yes` oder `no` Inline-HTML5-Media-Wiedergabe, Darstellung im Browser-Fenster, sondern in eine gerätespezifische Wiedergabe-Schnittstelle ermöglichen. Des HTML `video` Element muss auch die `webkit-playsinline` Attribut (Standard:`no`) - * **keyboardDisplayRequiresUserAction**: Legen Sie auf `yes` oder `no` um die Tastatur zu öffnen, wenn Formularelemente Fokus per JavaScript erhalten `focus()` Anruf (Standard:`yes`). - * **suppressesIncrementalRendering**: Legen Sie auf `yes` oder `no` zu warten, bis alle neuen anzeigen-Inhalte empfangen wird, bevor Sie wiedergegeben wird (standardmäßig`no`). - * **presentationstyle**: Legen Sie auf `pagesheet` , `formsheet` oder `fullscreen` [Präsentationsstil][1] (standardmäßig fest`fullscreen`). - * **transitionstyle**: Legen Sie auf `fliphorizontal` , `crossdissolve` oder `coververtical` [Übergangsstil][2] (standardmäßig fest`coververtical`). - * **toolbarposition**: Legen Sie auf `top` oder `bottom` (Standard ist `bottom` ). Bewirkt, dass die Symbolleiste am oberen oder unteren Rand des Fensters sein. - - Nur Windows: - - * **hidden**: Legen Sie auf `yes` um den Browser zu erstellen und laden Sie die Seite, aber nicht zeigen. Das Loadstop-Ereignis wird ausgelöst, wenn der Ladevorgang abgeschlossen ist. Weglassen oder auf `no` (Standard), den Browser öffnen und laden normalerweise zu haben. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows 8 und 8.1 -* Windows Phone 7 und 8 - -### Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Firefox OS Macken - -Als Plugin jedes Design erzwingen nicht besteht die Notwendigkeit, einige CSS-Regeln hinzuzufügen, wenn bei `target='_blank'`. Die Regeln könnte wie diese aussehen. - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -Bei einem Aufruf von `cordova.InAppBrowser.open` zurückgegebene Objekt.. - -### Methoden - -* addEventListener -* removeEventListener -* Schließen -* Karte -* executeScript -* insertCSS - -## addEventListener - -> Fügt einen Listener für eine Veranstaltung aus der`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)* - -* **EventName**: das Ereignis zu warten *(String)* - - * **Loadstart**: Ereignis wird ausgelöst, wenn die `InAppBrowser` beginnt, eine URL zu laden. - * **Loadstop**: Ereignis wird ausgelöst, wenn der `InAppBrowser` beendet ist, eine URL laden. - * **LoadError**: Ereignis wird ausgelöst, wenn der `InAppBrowser` ein Fehler auftritt, wenn Sie eine URL zu laden. - * **Ausfahrt**: Ereignis wird ausgelöst, wenn das `InAppBrowser` -Fenster wird geschlossen. - -* **Rückruf**: die Funktion, die ausgeführt wird, wenn das Ereignis ausgelöst wird. Die Funktion übergeben wird ein `InAppBrowserEvent` -Objekt als Parameter. - -### InAppBrowserEvent Eigenschaften - -* **Typ**: Eventname, entweder `loadstart` , `loadstop` , `loaderror` , oder `exit` . *(String)* - -* **URL**: die URL, die geladen wurde. *(String)* - -* **Code**: der Fehler-Code, nur im Fall von `loaderror` . *(Anzahl)* - -* **Nachricht**: die Fehlermeldung angezeigt, nur im Fall von `loaderror` . *(String)* - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* iOS -* Windows 8 und 8.1 -* Windows Phone 7 und 8 - -### Kurzes Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> Entfernt einen Listener für eine Veranstaltung aus der`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **Ref**: Bezugnahme auf die `InAppBrowser` Fenster. *(InAppBrowser)* - -* **EventName**: das Ereignis zu warten. *(String)* - - * **Loadstart**: Ereignis wird ausgelöst, wenn die `InAppBrowser` beginnt, eine URL zu laden. - * **Loadstop**: Ereignis wird ausgelöst, wenn der `InAppBrowser` beendet ist, eine URL laden. - * **LoadError**: Ereignis wird ausgelöst, wenn die `InAppBrowser` trifft einen Fehler beim Laden einer URLs. - * **Ausfahrt**: Ereignis wird ausgelöst, wenn das `InAppBrowser` -Fenster wird geschlossen. - -* **Rückruf**: die Funktion ausgeführt, wenn das Ereignis ausgelöst wird. Die Funktion übergeben wird ein `InAppBrowserEvent` Objekt. - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* iOS -* Windows 8 und 8.1 -* Windows Phone 7 und 8 - -### Kurzes Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## Schließen - -> Schließt die `InAppBrowser` Fenster. - - ref.close(); - - -* **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)* - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* Firefox OS -* iOS -* Windows 8 und 8.1 -* Windows Phone 7 und 8 - -### Kurzes Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## Karte - -> Zeigt ein InAppBrowser-Fenster, das geöffnet wurde, versteckt. Aufrufen, dies hat keine Auswirkungen, wenn die InAppBrowser schon sichtbar war. - - ref.show(); - - -* **Ref**: Verweis auf die (InAppBrowser) Fenster`InAppBrowser`) - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* iOS -* Windows 8 und 8.1 - -### Kurzes Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> Fügt JavaScript-Code in das `InAppBrowser` Fenster - - ref.executeScript(details, callback); - - -* **Ref**: Bezugnahme auf die `InAppBrowser` Fenster. *(InAppBrowser)* - -* **InjectDetails**: Informationen über das Skript ausgeführt, angeben, entweder ein `file` oder `code` Schlüssel. *(Objekt)* - - * **Datei**: URL des Skripts zu injizieren. - * **Code**: Text des Skripts zu injizieren. - -* **Rückruf**: die Funktion, die ausgeführt wird, nachdem der JavaScript-Code injiziert wird. - - * Wenn das eingefügte Skript vom Typ ist `code` , der Rückruf führt mit einen einzelnen Parameter, der der Rückgabewert des Skripts ist, umwickelt ein `Array` . Bei Multi-Line-Skripten ist der Rückgabewert von der letzten Anweisung oder den letzten Ausdruck ausgewertet. - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* iOS -* Windows 8 und 8.1 - -### Kurzes Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> Injiziert CSS in der `InAppBrowser` Fenster. - - ref.insertCSS(details, callback); - - -* **Ref**: Bezugnahme auf die `InAppBrowser` Fenster *(InAppBrowser)* - -* **InjectDetails**: Informationen über das Skript ausgeführt, angeben, entweder ein `file` oder `code` Schlüssel. *(Objekt)* - - * **Datei**: URL des Stylesheets zu injizieren. - * **Code**: Text des Stylesheets zu injizieren. - -* **Rückruf**: die Funktion, die ausgeführt wird, nachdem die CSS injiziert wird. - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* iOS - -### Kurzes Beispiel - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/es/index.md b/plugins/cordova-plugin-inappbrowser/doc/es/index.md deleted file mode 100644 index fc5b7b13..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/es/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -Este plugin proporciona una vista de navegador web que se muestra cuando se llama a `cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -El `cordova.InAppBrowser.open()` función se define como un reemplazo de sobreponer para la función `window.Open ()`. Llamadas existentes `window.Open ()` pueden utilizar la ventana InAppBrowser, mediante la sustitución de window.open: - - window.open = cordova.InAppBrowser.open; - - -La ventana de InAppBrowser se comporta como un navegador web estándar y no puede acceder a Cordova APIs. Por este motivo, se recomienda la InAppBrowser si necesita cargar contenido de terceros (confianza), en lugar de que cargar en el principal webview Cordova. El InAppBrowser no está sujeta a la lista blanca, ni va a abrir enlaces en el navegador del sistema. - -El InAppBrowser proporciona por defecto sus propios controles GUI para el usuario (atras, adelante, hacer). - -Para atrás compatibilidad, este plugin también ganchos `window.open`. Sin embargo, el gancho de `window.open` plugin instalado puede tener efectos secundarios no deseados (especialmente si este plugin está incluido únicamente como una dependencia de otro plugin). El gancho de `window.open` se quitará en una versión futura de principal. Hasta que el gancho se ha extraído el plugin, aplicaciones pueden restaurar manualmente el comportamiento por defecto: - - delete window.open // Reverts the call back to it's prototype's default - - -Aunque `window.open` es en el ámbito global, InAppBrowser no está disponible hasta después del evento `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## Instalación - - cordova plugin add cordova-plugin-inappbrowser - - -Si quieres todas las cargas de página en su aplicación para ir a través de la InAppBrowser, simplemente puedes conectar `window.open` durante la inicialización. Por ejemplo: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -Se abre una dirección URL en una nueva instancia de `InAppBrowser`, en la instancia actual del navegador o el navegador del sistema. - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **ref**: referencia a la `InAppBrowser` ventana. *(InAppBrowser)* - -* **url**: el URL para cargar *(String)*. Llame a `encodeURI()` en esto si la URL contiene caracteres Unicode. - -* **target**: el objetivo en el que se carga la URL, un parámetro opcional que se utiliza de forma predeterminada `_self`. *(String)* - - * `_self`: se abre en el Cordova WebView si la URL está en la lista blanca, de lo contrario se abre en el `InAppBrowser`. - * `_blank`: abre en el `InAppBrowser`. - * `_system`: se abre en el navegador del sistema. - -* **options**: opciones para el `InAppBrowser`. Opcional, contumaz a: `location=yes`. *(String)* - - La cadena de `options` no debe contener ningún espacio en blanco, y los pares de nombre y valor de cada característica deben estar separados por una coma. Los nombres de función son minúsculas. Todas las plataformas admiten el valor siguiente: - - * **location**: se establece en `yes` o `no` para activar o desactivar la barra de ubicación de la `InAppBrowser`. - - Sólo Android: - - * **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o establecer en `no` (por defecto) para que el navegador abra y carga normalmente. - * **clearcache**: a `yes` para que el navegador es caché de galleta despejado antes de que se abra la nueva ventana - * **clearsessioncache**: a `yes` que la caché de cookie de sesión despejado antes de que se abra la nueva ventana - - Sólo iOS: - - * **closebuttoncaption**: establecer una cadena para usar como título del botón **hecho** . Tenga en cuenta que necesitas localizar este valor por sí mismo. - * **disallowoverscroll**: A `yes` o `no` (valor por defecto es `no` ). Activa/desactiva la propiedad UIWebViewBounce. - * **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente. - * **clearcache**: a `yes` para que el navegador es caché de galleta despejado antes de que se abra la nueva ventana - * **clearsessioncache**: a `yes` que la caché de cookie de sesión despejado antes de que se abra la nueva ventana - * **barra de herramientas**: a `yes` o `no` para activar la barra de herramientas on u off para el InAppBrowser (por defecto`yes`) - * **enableViewportScale**: Set a `yes` o `no` para evitar viewport escalar a través de una etiqueta meta (por defecto a `no`). - * **mediaPlaybackRequiresUserAction**: Set a `yes` o `no` para evitar HTML5 audio o vídeo de reproducción automática (por defecto a `no`). - * **allowInlineMediaPlayback**: A `yes` o `no` para permitir la reproducción de los medios de comunicación en línea HTML5, mostrando en la ventana del navegador en lugar de una interfaz específica del dispositivo de reproducción. Elemento `video` de HTML también debe incluir el atributo de `webkit-playsinline` (por defecto a `no`) - * **keyboardDisplayRequiresUserAction**: se establece en `yes` o `no` para abrir el teclado cuando elementos de formulario reciben el foco mediante llamada de JavaScript de `focus()` (por defecto a `yes`). - * **suppressesIncrementalRendering**: se establece en `yes` o `no` para esperar hasta que todos los nuevos contenidos de vista se recibieron antes de ser prestados (por defecto a `no`). - * **presentationstyle**: se establece en `pagesheet`, `formsheet` o `fullscreen` para definir el [estilo de la presentación][1] (por defecto a `fullscreen`). - * **transitionstyle**: se establece en `fliphorizontal`, `crossdissolve` o `coververtical` para definir el [estilo de transición][2] (por defecto `coververtical`). - * **toolbarposition**: A `top` o `bottom` (valor por defecto es `bottom` ). Hace que la barra de herramientas en la parte superior o inferior de la ventana. - - Sólo Windows: - - * **oculta**: a `yes` para crear el navegador y cargar la página, pero no lo demuestra. El evento loadstop se desencadena cuando termine la carga. Omitir o a `no` (por defecto) para que el navegador abra y carga normalmente. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### Plataformas soportadas - -* Amazon fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows 8 y 8.1 -* Windows Phone 7 y 8 - -### Ejemplo - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Firefox OS rarezas - -Como plugin no cumplir cualquier diseño es necesario añadir algunas reglas CSS si abre con `target = '_blank'`. Las reglas pueden parecerse a estos - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -El objeto devuelto desde una llamada a `cordova.InAppBrowser.open`. - -### Métodos - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> Añade un detector para un evento de la `InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)* - -* **eventName**: el evento para escuchar *(String)* - - * **loadstart**: evento se desencadena cuando el `InAppBrowser` comienza a cargar una dirección URL. - * **loadstop**: evento desencadena cuando los acabados `InAppBrowser` cargar una dirección URL. - * **loaderror**: evento se desencadena cuando el `InAppBrowser` encuentra un error al cargar una dirección URL. - * **exit**: evento se desencadena cuando se cierra la ventana de `InAppBrowser`. - -* **callback**: la función que se ejecuta cuando se desencadene el evento. La función se pasa un objeto `InAppBrowserEvent` como un parámetro. - -### InAppBrowserEvent propiedades - -* **type**: eventname, `loadstart`, `loadstop`, `loaderror` o `exit`. *(String)* - -* **url**: la URL que se cargó. *(String)* - -* **code**: el código de error, sólo en el caso de `loaderror`. *(Número)* - -* **message**: el mensaje de error, sólo en el caso de `loaderror`. *(String)* - -### Plataformas soportadas - -* Amazon fire OS -* Android -* iOS -* Windows 8 y 8.1 -* Windows Phone 7 y 8 - -### Ejemplo rápido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> Elimina un detector para un evento de la `InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **ref**: referencia a la ventana de `InAppBrowser`. *(InAppBrowser)* - -* **eventName**: dejar de escuchar para el evento. *(String)* - - * **loadstart**: evento se desencadena cuando el `InAppBrowser` comienza a cargar una dirección URL. - * **loadstop**: evento desencadena cuando los acabados `InAppBrowser` cargar una dirección URL. - * **loaderror**: evento se desencadena cuando el `InAppBrowser` se encuentra con un error al cargar una dirección URL. - * **exit**: evento se desencadena cuando se cierra la ventana de `InAppBrowser`. - -* **callback**: la función a ejecutar cuando se desencadene el evento. La función se pasa un objeto `InAppBrowserEvent`. - -### Plataformas soportadas - -* Amazon fire OS -* Android -* iOS -* Windows 8 y 8.1 -* Windows Phone 7 y 8 - -### Ejemplo rápido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> Cierra la ventana de `InAppBrowser`. - - ref.close(); - - -* **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)* - -### Plataformas soportadas - -* Amazon fire OS -* Android -* Firefox OS -* iOS -* Windows 8 y 8.1 -* Windows Phone 7 y 8 - -### Ejemplo rápido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> Muestra una ventana InAppBrowser que abrió sus puertas ocultada. Esto no tiene efecto si el InAppBrowser ya era visible. - - ref.show(); - - -* **ref**: referencia a la (ventana) InAppBrowser`InAppBrowser`) - -### Plataformas soportadas - -* Amazon fire OS -* Android -* iOS -* Windows 8 y 8.1 - -### Ejemplo rápido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> Inyecta código JavaScript en la ventana de `InAppBrowser` - - ref.executeScript(details, callback); - - -* **ref**: referencia a la ventana de `InAppBrowser`. *(InAppBrowser)* - -* **injectDetails**: detalles de la secuencia de comandos para ejecutar, o especificar un `file` o `code` clave. *(Objeto)* - - * **file**: URL del script para inyectar. - * **code**: texto de la escritura para inyectar. - -* **devolución de llamada**: la función que se ejecuta después de inyecta el código JavaScript. - - * Si el script inyectado es del tipo de `code`, la devolución de llamada se ejecuta con un solo parámetro, que es el valor devuelto del guión, envuelto en una `Array`. Para scripts multilíneas, este es el valor devuelto de la última declaración, o la última expresión evaluada. - -### Plataformas soportadas - -* Amazon fire OS -* Android -* iOS -* Windows 8 y 8.1 - -### Ejemplo rápido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> Inyecta CSS en la ventana de `InAppBrowser`. - - ref.insertCSS(details, callback); - - -* **ref**: referencia a la ventana de `InAppBrowser` *(InAppBrowser)* - -* **injectDetails**: detalles de la secuencia de comandos para ejecutar, o especificar un `file` o `code` clave. *(Objeto)* - - * **file**: URL de la hoja de estilos para inyectar. - * **code**: texto de la hoja de estilos para inyectar. - -* **callback**: la función que se ejecuta después de inyectar el CSS. - -### Plataformas soportadas - -* Amazon fire OS -* Android -* iOS - -### Ejemplo rápido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/fr/index.md b/plugins/cordova-plugin-inappbrowser/doc/fr/index.md deleted file mode 100644 index 4f22d13b..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/fr/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -Ce module fournit une vue de navigateur web qui s'affiche lorsque vous appelez `cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -Le `cordova.InAppBrowser.open()` fonction est définie pour être un remplacement rapide de la fonction `window.open()`. Les appels existants `window.open()` peuvent utiliser la fenêtre de InAppBrowser, en remplaçant window.open : - - window.open = cordova.InAppBrowser.open; - - -La fenêtre de InAppBrowser se comporte comme un navigateur web standard et ne peut pas accéder aux APIs Cordova. Pour cette raison, le InAppBrowser est recommandé si vous devez charger le contenu de tiers (non approuvé), au lieu de chargement que dans le principaux webview Cordova. Le InAppBrowser n'est pas soumis à la liste blanche, ni s'ouvre les liens dans le navigateur de système. - -Le InAppBrowser fournit par défaut ses propres contrôles de GUI pour l'utilisateur (arrière, avant, fait). - -Pour vers l'arrière la compatibilité, ce plugin crochets également `window.open`. Cependant, le plugin installé crochet de `window.open` peut avoir des effets secondaires involontaires (surtout si ce plugin est inclus uniquement comme une dépendance d'un autre plugin). Le crochet de `window.open` sera supprimé dans une future version majeure. Jusqu'à ce que le crochet est supprimé de la plugin, apps peuvent restaurer manuellement le comportement par défaut : - - delete window.open // Reverts the call back to it's prototype's default - - -Bien que `window.open` est dans la portée globale, InAppBrowser n'est pas disponible jusqu'à ce qu'après l'événement `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## Installation - - cordova plugin add cordova-plugin-inappbrowser - - -Si vous souhaitez que toutes les charges de la page dans votre application de passer par le InAppBrowser, vous pouvez simplement accrocher `window.open` pendant l'initialisation. Par exemple : - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -Ouvre une URL dans une nouvelle instance de `InAppBrowser`, l'instance de navigateur actuelle ou dans l'Explorateur du système. - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)* - -* **url** : l'URL à charger *(String)*. À encoder au préalable via `encodeURI()` si celle-ci contient des caractères Unicode. - -* **target** : la cible du chargement de l'URL, ce paramètre est optionnel, sa valeur par défaut est `_self`. *(String)* - - * `_self` : dirige le chargement vers la WebView Cordova si l'URL figure dans la liste blanche, sinon dans une fenêtre `InAppBrowser`. - * `_blank` : dirige le chargement vers une fenêtre `InAppBrowser`. - * `_system` : dirige le chargement vers le navigateur Web du système. - -* **options** : permet de personnaliser la fenêtre `InAppBrowser`. Paramètre facultatif dont la valeur par défaut est `location=yes`. *(String)* - - La chaîne `options` ne doit contenir aucun caractère vide, chaque paire nom/valeur représentant une fonctionnalité doit être séparée de la précédente par une virgule. Les noms de fonctionnalités sont sensibles à la casse. Toutes les plates-formes prennent en charge la valeur ci-dessous : - - * **location** : régler à `yes` ou `no` afin d'afficher ou masquer la barre d'adresse de la fenêtre `InAppBrowser`. - - Android uniquement : - - * **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement. - * **ClearCache**: la valeur `yes` pour que le navigateur du cache de cookie effacé, avant l'ouverture de la nouvelle fenêtre - * **clearsessioncache**: la valeur `yes` pour avoir le cache de cookie de session autorisé avant l'ouverture de la nouvelle fenêtre - - iOS uniquement : - - * **closebuttoncaption**: affectez une chaîne à utiliser comme la **fait** légende du bouton. Notez que vous devrez localiser cette valeur vous-même. - * **disallowoverscroll**: la valeur `yes` ou `no` (valeur par défaut est `no` ). Active/désactive la propriété UIWebViewBounce. - * **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement. - * **ClearCache**: la valeur `yes` pour que le navigateur du cache de cookie effacé, avant l'ouverture de la nouvelle fenêtre - * **clearsessioncache**: la valeur `yes` pour avoir le cache de cookie de session autorisé avant l'ouverture de la nouvelle fenêtre - * **barre d'outils**: la valeur `yes` ou `no` pour activer la barre d'outils ou désactiver pour le InAppBrowser (par défaut,`yes`) - * **enableViewportScale**: la valeur `yes` ou `no` pour empêcher la fenêtre de mise à l'échelle par une balise meta (par défaut,`no`). - * **mediaPlaybackRequiresUserAction**: la valeur `yes` ou `no` pour empêcher le HTML5 audio ou vidéo de la lecture automatique (par défaut,`no`). - * **allowInlineMediaPlayback**: la valeur `yes` ou `no` pour permettre la lecture du média en ligne HTML5, affichage dans la fenêtre du navigateur plutôt que d'une interface de lecture spécifique au périphérique. L'HTML `video` élément doit également inclure la `webkit-playsinline` attribut (par défaut,`no`) - * **keyboardDisplayRequiresUserAction**: la valeur `yes` ou `no` pour ouvrir le clavier lorsque les éléments reçoivent le focus par l'intermédiaire de JavaScript `focus()` appel (par défaut,`yes`). - * **suppressesIncrementalRendering**: la valeur `yes` ou `no` d'attendre que toutes les nouveautés de vue sont reçue avant d'être restitué (par défaut,`no`). - * **presentationstyle**: la valeur `pagesheet` , `formsheet` ou `fullscreen` pour définir le [style de présentation][1] (par défaut,`fullscreen`). - * **transitionstyle**: la valeur `fliphorizontal` , `crossdissolve` ou `coververtical` pour définir le [style de transition][2] (par défaut,`coververtical`). - * **toolbarposition**: la valeur `top` ou `bottom` (valeur par défaut est `bottom` ). Causes de la barre d'outils être en haut ou en bas de la fenêtre. - - Windows uniquement : - - * **caché**: la valeur `yes` pour créer le navigateur et charger la page, mais ne pas le montrer. L'événement loadstop est déclenché lorsque le chargement est terminé. Omettre ou la valeur `no` (par défaut) pour que le navigateur ouvrir et charger normalement. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows 8 et 8.1 -* Windows Phone 7 et 8 - -### Exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Firefox OS Quirks - -Comme plugin n'est pas appliquer n'importe quelle conception il est nécessaire d'ajouter quelques règles CSS si ouvert avec `target= _blank`. Les règles pourraient ressembler à ces - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -L'objet retourné par un appel à `cordova.InAppBrowser.open`. - -### Méthodes - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> Ajoute un écouteur pour un évènement de la fenêtre `InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)* - -* **eventname** : l'évènement à écouter *(String)* - - * **loadstart** : évènement déclenché lorsque le chargement d'une URL débute dans la fenêtre `InAppBrowser`. - * **loadstop** : évènement déclenché lorsque la fenêtre `InAppBrowser` finit de charger une URL. - * **loaderror** : évènement déclenché si la fenêtre `InAppBrowser` rencontre une erreur lors du chargement d'une URL. - * **exit** : évènement déclenché lorsque la fenêtre `InAppBrowser` est fermée. - -* **callback** : la fonction à exécuter lorsque l'évènement se déclenche. Un objet `InAppBrowserEvent` lui est transmis comme paramètre. - -### Propriétés de InAppBrowserEvent - -* **type** : le nom de l'évènement, soit `loadstart`, `loadstop`, `loaderror` ou `exit`. *(String)* - -* **url** : l'URL ayant été chargée. *(String)* - -* **code** : le code d'erreur, seulement pour `loaderror`. *(Number)* - -* **message** : un message d'erreur, seulement pour `loaderror`. *(String)* - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* iOS -* Windows 8 et 8.1 -* Windows Phone 7 et 8 - -### Petit exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> Supprime un écouteur pour un évènement de la fenêtre `InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **ref** : référence à la fenêtre `InAppBrowser`. *(InAppBrowser)* - -* **eventname** : l'évènement pour lequel arrêter l'écoute. *(String)* - - * **loadstart**: événement déclenche quand le `InAppBrowser` commence à charger une URL. - * **loadstop**: événement déclenche lorsque la `InAppBrowser` finit de charger une URL. - * **loaderror** : évènement déclenché si la fenêtre `InAppBrowser` rencontre une erreur lors du chargement d'une URL. - * **sortie**: événement déclenche quand le `InAppBrowser` fenêtre est fermée. - -* **callback** : la fonction à exécuter lorsque l'évènement se déclenche. Un objet `InAppBrowserEvent` lui est transmis comme paramètre. - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* iOS -* Windows 8 et 8.1 -* Windows Phone 7 et 8 - -### Petit exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> Ferme la fenêtre `InAppBrowser`. - - ref.close(); - - -* **Réf**: référence à la `InAppBrowser` fenêtre *(InAppBrowser)* - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* Firefox OS -* iOS -* Windows 8 et 8.1 -* Windows Phone 7 et 8 - -### Petit exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> Affiche une fenêtre InAppBrowser qui a été ouverte cachée. Appeler cette méthode n'a aucun effet si la fenêtre en question est déjà visible. - - ref.show(); - - -* **Réf**: référence à la fenêtre () InAppBrowser`InAppBrowser`) - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* iOS -* Windows 8 et 8.1 - -### Petit exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> Injecte du code JavaScript dans la fenêtre `InAppBrowser` - - ref.executeScript(details, callback); - - -* **Réf**: référence à la `InAppBrowser` fenêtre. *(InAppBrowser)* - -* **injectDetails** : détails du script à exécuter, requérant une propriété `file` ou `code`. *(Object)* - - * **file** : URL du script à injecter. - * **code** : texte du script à injecter. - -* **callback** : une fonction exécutée après l'injection du code JavaScript. - - * Si le script injecté est de type `code`, un seul paramètre est transmis à la fonction callback, correspondant à la valeur de retour du script enveloppée dans un `Array`. Pour les scripts multilignes, il s'agit de la valeur renvoyée par la dernière instruction ou la dernière expression évaluée. - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* iOS -* Windows 8 et 8.1 - -### Petit exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> Injecte des règles CSS dans la fenêtre `InAppBrowser`. - - ref.insertCSS(details, callback); - - -* **Réf**: référence à la `InAppBrowser` fenêtre *(InAppBrowser)* - -* **injectDetails**: Détails du script à exécuter, spécifiant soit un `file` ou `code` clés. *(Objet)* - - * **file** : URL de la feuille de style à injecter. - * **code** : contenu de la feuille de style à injecter. - -* **callback** : une fonction exécutée après l'injection du fichier CSS. - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* iOS - -### Petit exemple - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/it/index.md b/plugins/cordova-plugin-inappbrowser/doc/it/index.md deleted file mode 100644 index 73654628..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/it/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -Questo plugin fornisce una vista di browser web che viene visualizzato quando si chiama `di cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -Il `cordova.InAppBrowser.open()` funzione è definita per essere un rimpiazzo per la funzione `window.open`. Esistenti chiamate `Window` possono utilizzare la finestra di InAppBrowser, sostituendo window.open(): - - window.open = cordova.InAppBrowser.open; - - -La finestra di InAppBrowser si comporta come un browser web standard e non può accedere a Cordova APIs. Per questo motivo, è consigliabile la InAppBrowser se è necessario caricare il contenuto (non attendibile) di terze parti, invece di caricamento che in webview Cordova principale. Il InAppBrowser non è soggetto alla whitelist, né sta aprendo il link nel browser di sistema. - -La InAppBrowser fornisce di default propri controlli GUI per l'utente (indietro, avanti, fatto). - -Per indietro la compatibilità, questo plugin ganci anche `window.open`. Tuttavia, il plugin installato gancio di `window.open` può avere effetti collaterali indesiderati (soprattutto se questo plugin è incluso solo come dipendenza di un altro plugin). Il gancio di `window. open` verrà rimosso in una futura release principale. Fino a quando il gancio è rimosso dal plugin, apps può ripristinare manualmente il comportamento predefinito: - - delete window.open // Reverts the call back to it's prototype's default - - -Sebbene `window.open` sia in ambito globale, InAppBrowser non è disponibile fino a dopo l'evento `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## Installazione - - cordova plugin add cordova-plugin-inappbrowser - - -Se si desidera che tutti i carichi di pagina nell'app di passare attraverso il InAppBrowser, si può semplicemente collegare `window.open` durante l'inizializzazione. Per esempio: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -Apre un URL in una nuova istanza di `InAppBrowser`, l'istanza corrente del browser o il browser di sistema. - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **ref**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)* - -* **url**: l'URL da caricare *(String)*. Chiamare `encodeURI()` su questo, se l'URL contiene caratteri Unicode. - -* **target**: la destinazione in cui caricare l'URL, un parametro facoltativo che il valore predefinito è `_self` . *(String)* - - * `_self`: Si apre in Cordova WebView se l'URL è nella lista bianca, altrimenti si apre nella`InAppBrowser`. - * `_blank`: Apre il`InAppBrowser`. - * `_system`: Si apre nel browser web del sistema. - -* **options**: opzioni per il `InAppBrowser` . Opzionale, inadempiente a: `location=yes` . *(String)* - - Il `options` stringa non deve contenere alcun spazio vuoto, e coppie nome/valore ogni funzionalità devono essere separate da una virgola. Caratteristica nomi sono tra maiuscole e minuscole. Tutte le piattaforme supportano il valore riportato di seguito: - - * **posizione**: impostata su `yes` o `no` per trasformare il `InAppBrowser` di barra di posizione on o off. - - Solo su Android: - - * **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente. - * **ClearCache**: impostare su `yes` per avere il browser cache cookie ha lasciata prima dell'apertura della nuova finestra - * **clearsessioncache**: impostare su `yes` per avere la cache cookie di sessione cancellata prima dell'apertura della nuova finestra - - solo iOS: - - * **closebuttoncaption**: impostare una stringa da utilizzare come didascalia del pulsante **fatto** . Si noti che è necessario localizzare questo valore a te stesso. - * **disallowoverscroll**: impostare su `yes` o `no` (default è `no` ). Attiva/disattiva la proprietà UIWebViewBounce. - * **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente. - * **ClearCache**: impostare su `yes` per avere il browser cache cookie ha lasciata prima dell'apertura della nuova finestra - * **clearsessioncache**: impostare su `yes` per avere la cache cookie di sessione cancellata prima dell'apertura della nuova finestra - * **Toolbar**: impostare su `yes` o `no` per attivare la barra degli strumenti o disattivare per il InAppBrowser (default`yes`) - * **enableViewportScale**: impostare su `yes` o `no` per impedire la viewport ridimensionamento tramite un tag meta (default`no`). - * **mediaPlaybackRequiresUserAction**: impostare su `yes` o `no` per impedire HTML5 audio o video da AutoPlay (default`no`). - * **allowInlineMediaPlayback**: impostare su `yes` o `no` per consentire la riproduzione dei supporti HTML5 in linea, visualizzare all'interno della finestra del browser, piuttosto che un'interfaccia specifica del dispositivo di riproduzione. L'HTML `video` elemento deve includere anche il `webkit-playsinline` (default di attributo`no`) - * **keyboardDisplayRequiresUserAction**: impostare su `yes` o `no` per aprire la tastiera quando elementi form ricevano lo stato attivo tramite di JavaScript `focus()` chiamata (default`yes`). - * **suppressesIncrementalRendering**: impostare su `yes` o `no` aspettare fino a quando tutti i nuovi contenuti di vista viene ricevuto prima il rendering (default`no`). - * **presentationstyle**: impostare su `pagesheet` , `formsheet` o `fullscreen` per impostare lo [stile di presentazione][1] (default`fullscreen`). - * **transitionstyle**: impostare su `fliphorizontal` , `crossdissolve` o `coververtical` per impostare lo [stile di transizione][2] (default`coververtical`). - * **toolbarposition**: impostare su `top` o `bottom` (default è `bottom` ). Provoca la barra degli strumenti sia nella parte superiore o inferiore della finestra. - - Solo per Windows: - - * **nascosti**: impostare su `yes` per creare il browser e caricare la pagina, ma non mostrarlo. L'evento loadstop viene generato quando il caricamento è completato. Omettere o impostata su `no` (impostazione predefinita) per avere il browser aperto e caricare normalmente. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows 8 e 8.1 -* Windows Phone 7 e 8 - -### Esempio - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Firefox OS stranezze - -Come plugin non imporre alcun disegno c'è bisogno di aggiungere alcune regole CSS se aperto con `target='_blank'`. Le regole potrebbero apparire come questi - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -L'oggetto restituito da una chiamata a `di cordova.InAppBrowser.open`. - -### Metodi - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> Aggiunge un listener per un evento dal`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)* - -* **EventName**: l'evento per l'ascolto *(String)* - - * **loadstart**: evento viene generato quando il `InAppBrowser` comincia a caricare un URL. - * **loadstop**: evento viene generato quando il `InAppBrowser` termina il caricamento di un URL. - * **LoadError**: evento viene generato quando il `InAppBrowser` rileva un errore durante il caricamento di un URL. - * **uscita**: evento viene generato quando il `InAppBrowser` finestra è chiusa. - -* **richiamata**: la funzione che viene eseguito quando viene generato l'evento. La funzione viene passata un `InAppBrowserEvent` oggetto come parametro. - -### Proprietà InAppBrowserEvent - -* **tipo**: il eventname, o `loadstart` , `loadstop` , `loaderror` , o `exit` . *(String)* - -* **URL**: l'URL che è stato caricato. *(String)* - -* **codice**: il codice di errore, solo nel caso di `loaderror` . *(Numero)* - -* **messaggio**: il messaggio di errore, solo nel caso di `loaderror` . *(String)* - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* iOS -* Windows 8 e 8.1 -* Windows Phone 7 e 8 - -### Esempio rapido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> Rimuove un listener per un evento dal`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **Rif**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)* - -* **EventName**: interrompere l'attesa per l'evento. *(String)* - - * **loadstart**: evento viene generato quando il `InAppBrowser` comincia a caricare un URL. - * **loadstop**: evento viene generato quando il `InAppBrowser` termina il caricamento di un URL. - * **LoadError**: evento viene generato quando il `InAppBrowser` rileva un errore di caricamento di un URL. - * **uscita**: evento viene generato quando il `InAppBrowser` finestra è chiusa. - -* **richiamata**: la funzione da eseguire quando viene generato l'evento. La funzione viene passata un `InAppBrowserEvent` oggetto. - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* iOS -* Windows 8 e 8.1 -* Windows Phone 7 e 8 - -### Esempio rapido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> Chiude la `InAppBrowser` finestra. - - ref.close(); - - -* **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)* - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* Firefox OS -* iOS -* Windows 8 e 8.1 -* Windows Phone 7 e 8 - -### Esempio rapido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> Visualizza una finestra di InAppBrowser che è stato aperto nascosta. Questa chiamata non ha effetto se la InAppBrowser era già visibile. - - ref.show(); - - -* **Rif**: riferimento per il InAppBrowser finestra (`InAppBrowser`) - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* iOS -* Windows 8 e 8.1 - -### Esempio rapido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> Inserisce il codice JavaScript nella `InAppBrowser` finestra - - ref.executeScript(details, callback); - - -* **Rif**: fare riferimento alla `InAppBrowser` finestra. *(InAppBrowser)* - -* **injectDetails**: dettagli dello script da eseguire, specificando un `file` o `code` chiave. *(Oggetto)* - - * **file**: URL dello script da iniettare. - * **codice**: testo dello script da iniettare. - -* **richiamata**: la funzione che viene eseguito dopo che il codice JavaScript viene iniettato. - - * Se lo script iniettato è di tipo `code` , il callback viene eseguita con un singolo parametro, che è il valore restituito del copione, avvolto in un `Array` . Per gli script multi-linea, questo è il valore restituito dell'ultima istruzione, o l'ultima espressione valutata. - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* iOS -* Windows 8 e 8.1 - -### Esempio rapido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> Inietta CSS nella `InAppBrowser` finestra. - - ref.insertCSS(details, callback); - - -* **Rif**: fare riferimento alla `InAppBrowser` finestra *(InAppBrowser)* - -* **injectDetails**: dettagli dello script da eseguire, specificando un `file` o `code` chiave. *(Oggetto)* - - * **file**: URL del foglio di stile per iniettare. - * **codice**: testo del foglio di stile per iniettare. - -* **richiamata**: la funzione che viene eseguito dopo che il CSS viene iniettato. - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* iOS - -### Esempio rapido - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/ja/index.md b/plugins/cordova-plugin-inappbrowser/doc/ja/index.md deleted file mode 100644 index a1b68544..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/ja/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -このプラグインは `コルドバを呼び出すときに表示される web ブラウザーのビューを提供します。InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -`コルドバ。InAppBrowser.open()` `window.open()` 関数との交換を定義する関数。 既存の `window.open()` 呼び出しは、window.open を置き換えることによって InAppBrowser ウィンドウを使用できます。 - - window.open = cordova.InAppBrowser.open; - - -InAppBrowser ウィンドウは標準的な web ブラウザーのように動作し、コルドバ Api にアクセスできません。 この理由から、InAppBrowser お勧めする場合はメインのコルドバの webview を読み込むのではなくサード パーティ (信頼されていない) コンテンツをロードする必要があります。 InAppBrowser、ホワイト リストの対象ではないも、システムのブラウザーでリンクを開くです。 - -InAppBrowser を提供しますデフォルトで GUI コントロール (戻る、進む、行う)。 - -後方互換性、このプラグインは、また `window.open` をフックのため。 ただし、`window.open` のプラグイン インストール フックを持つことができます意図しない副作用 (特に場合は、このプラグインは別のプラグインの依存関係としてのみ含まれています)。 `window.open` のフックは、将来のメジャー リリースで削除されます。 プラグインから、フックが削除されるまでアプリはデフォルトの動作を手動で復元できます。 - - delete window.open // Reverts the call back to it's prototype's default - - -`window.open` はグローバル スコープでは、InAppBrowser は、`deviceready` イベントの後まで利用できません。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## インストール - - cordova plugin add cordova-plugin-inappbrowser - - -InAppBrowser を通過するアプリですべてのページの読み込みをする場合は初期化中に `window.open` を単にフックできます。たとえば。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -新しい `InAppBrowser` インスタンスを現在のブラウザー インスタンスまたはシステムのブラウザーで URL を開きます。 - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)* - -* **url**: *(文字列)*をロードする URL。電話 `encodeURI()` 場合は、この上の URL は Unicode 文字を含みます。 - -* **ターゲット**: ターゲット URL は、既定値は、省略可能なパラメーターをロードするを `_self` 。*(文字列)* - - * `_self`: コルドバ WebView URL がホワイト リストにある場合で開きます、それ以外の場合で開きます、`InAppBrowser`. - * `_blank`: で開きます、`InAppBrowser`. - * `_system`: システムの web ブラウザーで開きます。 - -* **オプション**: おぷしょん、 `InAppBrowser` 。省略可能にする: `location=yes` 。*(文字列)* - - `options`文字列にはする必要があります任意の空白スペースが含まれていないと、各機能の名前と値のペアをコンマで区切る必要があります。 機能名では大文字小文字を区別します。 以下の値をサポートするプラットフォーム。 - - * **場所**: に設定 `yes` または `no` を有効にする、 `InAppBrowser` の場所バー オンまたはオフにします。 - - アンドロイドのみ: - - * **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。 - * **clearcache**: に設定されている `yes` 、ブラウザーのクッキー キャッシュ クリア新しいウィンドウが開く前に - * **clearsessioncache**: に設定されている `yes` はセッション cookie のキャッシュをオフにすると、新しいウィンドウが開く前に - - iOS のみ: - - * **closebuttoncaption**: [**完了**] ボタンのキャプションとして使用する文字列に設定します。自分でこの値をローカライズする必要があることに注意してください。 - * **disallowoverscroll**: に設定されている `yes` または `no` (既定値は `no` )。/UIWebViewBounce プロパティをオフにします。 - * **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。 - * **clearcache**: に設定されている `yes` 、ブラウザーのクッキー キャッシュ クリア新しいウィンドウが開く前に - * **clearsessioncache**: に設定されている `yes` はセッション cookie のキャッシュをオフにすると、新しいウィンドウが開く前に - * **ツールバー**: に設定されている `yes` または `no` InAppBrowser (デフォルトのツールバーのオンまたはオフを有効にするには`yes`) - * **enableViewportScale**: に設定されている `yes` または `no` を (デフォルトではメタタグを介してスケーリング ビューポートを防ぐために`no`). - * **mediaPlaybackRequiresUserAction**: に設定されている `yes` または `no` を HTML5 オーディオまたはビデオを自動再生 (初期設定から防ぐために`no`). - * **allowInlineMediaPlayback**: に設定されている `yes` または `no` ラインで HTML5 メディア再生には、デバイス固有再生インターフェイスではなく、ブラウザー ウィンドウ内に表示するようにします。 HTML の `video` 要素を含める必要がありますまた、 `webkit-playsinline` 属性 (デフォルトは`no`) - * **keyboardDisplayRequiresUserAction**: に設定されている `yes` または `no` をフォーム要素の JavaScript を介してフォーカスを受け取るときに、キーボードを開く `focus()` コール (デフォルトは`yes`). - * **suppressesIncrementalRendering**: に設定されている `yes` または `no` (デフォルトでは表示される前にビューのすべての新しいコンテンツを受信するまで待機するには`no`). - * **presentationstyle**: に設定されている `pagesheet` 、 `formsheet` または `fullscreen` (デフォルトでは、[プレゼンテーション スタイル][1]を設定するには`fullscreen`). - * **transitionstyle**: に設定されている `fliphorizontal` 、 `crossdissolve` または `coververtical` (デフォルトでは、[トランジションのスタイル][2]を設定するには`coververtical`). - * **toolbarposition**: に設定されている `top` または `bottom` (既定値は `bottom` )。上部またはウィンドウの下部にツールバーが発生します。 - - Windows のみ: - - * **非表示**: 設定 `yes` ブラウザーを作成して、ページの読み込みが表示されません。 Loadstop イベントは、読み込みが完了すると発生します。 省略するか設定 `no` (既定値) を開くし、通常読み込みブラウザーを持っています。 - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* ブラックベリー 10 -* Firefox の OS -* iOS -* Windows 8 および 8.1 -* Windows Phone 7 と 8 - -### 例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Firefox OS 癖 - -開かれた場合にいくつかの CSS ルールを追加する必要があるプラグインは任意のデザインを適用しないと `target ='_blank'`。これらのような規則になります。 - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -`コルドバへの呼び出しから返されるオブジェクト。InAppBrowser.open`. - -### メソッド - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> イベントのリスナーを追加します、`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)* - -* **eventname**: *(文字列)*をリッスンするイベント - - * ****: イベントが発生するとき、 `InAppBrowser` の URL の読み込みが開始します。 - * **loadstop**: イベントが発生するとき、 `InAppBrowser` URL の読み込みが完了します。 - * **loaderror**: イベントが発生するとき、 `InAppBrowser` URL の読み込みでエラーが発生します。 - * **終了**: イベントが発生するとき、 `InAppBrowser` ウィンドウが閉じられます。 - -* **コールバック**: イベントが発生したときに実行される関数。関数に渡されますが、 `InAppBrowserEvent` オブジェクトをパラメーターとして。 - -### InAppBrowserEvent プロパティ - -* **タイプ**: eventname どちらか `loadstart` 、 `loadstop` 、 `loaderror` 、または `exit` 。*(文字列)* - -* **url**: URL が読み込まれました。*(文字列)* - -* **コード**: の場合にのみ、エラー コード `loaderror` 。*(数)* - -* **メッセージ**: の場合にのみ、エラー メッセージ `loaderror` 。*(文字列)* - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* iOS -* Windows 8 および 8.1 -* Windows Phone 7 と 8 - -### 簡単な例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> イベントのリスナーを削除します、`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)* - -* **eventname**: イベントのリッスンを停止します。*(文字列)* - - * ****: イベントが発生するとき、 `InAppBrowser` の URL の読み込みが開始します。 - * **loadstop**: イベントが発生するとき、 `InAppBrowser` URL の読み込みが完了します。 - * **loaderror**: イベントが発生するとき、 `InAppBrowser` URL の読み込みエラーが発生します。 - * **終了**: イベントが発生するとき、 `InAppBrowser` ウィンドウが閉じられます。 - -* **コールバック**: イベントが発生するときに実行する関数。関数に渡されますが、 `InAppBrowserEvent` オブジェクト。 - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* iOS -* Windows 8 および 8.1 -* Windows Phone 7 と 8 - -### 簡単な例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> 閉じる、 `InAppBrowser` ウィンドウ。 - - ref.close(); - - -* **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)* - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* Firefox の OS -* iOS -* Windows 8 および 8.1 -* Windows Phone 7 と 8 - -### 簡単な例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> 隠された開かれた InAppBrowser ウィンドウが表示されます。この関数を呼び出すは影響しません、InAppBrowser が既に表示されている場合。 - - ref.show(); - - -* **ref**: InAppBrowser ウィンドウ (への参照`InAppBrowser`) - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* iOS -* Windows 8 および 8.1 - -### 簡単な例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> JavaScript コードに挿入します、 `InAppBrowser` ウィンドウ - - ref.executeScript(details, callback); - - -* **ref**: への参照を `InAppBrowser` ウィンドウ。*(InAppBrowser)* - -* **injectDetails**: 詳細を実行するスクリプトのいずれかを指定する、 `file` または `code` キー。*(オブジェクト)* - - * **ファイル**: スクリプトの URL を注入します。 - * **コード**: スクリプトのテキストを挿入します。 - -* **コールバック**: JavaScript コードを注入した後に実行される関数。 - - * 挿入されたスクリプトが型の場合 `code` 、スクリプトの戻り値は、1 つのパラメーターでコールバックを実行するのに包まれて、 `Array` 。 マルチライン スクリプトについては、最後のステートメントでは、または評価した最後の式の戻り値です。 - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* iOS -* Windows 8 および 8.1 - -### 簡単な例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> CSS に注入する、 `InAppBrowser` ウィンドウ。 - - ref.insertCSS(details, callback); - - -* **ref**: への参照を `InAppBrowser` ウィンドウ*(InAppBrowser)* - -* **injectDetails**: 詳細を実行するスクリプトのいずれかを指定する、 `file` または `code` キー。*(オブジェクト)* - - * **ファイル**: 注入するスタイル シートの URL。 - * **コード**: 注入するスタイル シートのテキスト。 - -* **コールバック**: CSS の注入後に実行される関数。 - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* iOS - -### 簡単な例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/ko/index.md b/plugins/cordova-plugin-inappbrowser/doc/ko/index.md deleted file mode 100644 index d1b3ddbd..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/ko/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -이 플러그인 `코르도바를 호출할 때 표시 하는 웹 브라우저 보기를 제공 합니다.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -`코르도바입니다.InAppBrowser.open()` 함수 `window.open ()` 함수에 대 한 대체품 정의 됩니다. 기존의 `window.open ()` 호출 window.open을 대체 하 여 InAppBrowser 윈도우를 사용할 수 있습니다. - - window.open = cordova.InAppBrowser.open; - - -InAppBrowser 창 표준 웹 브라우저 처럼 동작 및 코르도바 Api에 액세스할 수 없습니다. 이 이유는 InAppBrowser는 것이 좋습니다는 주요 코르도바 webview로 로드 하는 대신 제 3 자 (신뢰할 수 없는) 콘텐츠를 로드 해야 할 경우. InAppBrowser는 허용 될 수도 시스템 브라우저에서 링크를 여는. - -사용자에 대 한 자체 GUI 컨트롤에서 기본적으로 제공 된 InAppBrowser (뒤로, 앞으로, 완료). - -대 한 뒤 호환성,이 플러그인도 `window.open` 후크. 그러나, `window.open`의 플러그인 설치 후크를 가질 수 있습니다 의도 하지 않은 부작용 (특히 경우이 플러그인이 다른 플러그인 종속성 으로만 포함). `window.open` 후크 주요 릴리스에서 제거 됩니다. 후크 플러그인에서 제거 될 때까지 애플 리 케이 션 수 있습니다 수동으로 기본 동작을 복원 하 게 됩니다. - - delete window.open // Reverts the call back to it's prototype's default - - -`window.open` 전역 범위에 있지만 InAppBrowser 제공 되지 않습니다 때까지 `deviceready` 이벤트 후. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## 설치 - - cordova plugin add cordova-plugin-inappbrowser - - -InAppBrowser를 통해가 서 당신의 애플 리 케이 션에서 모든 페이지를 로드 하려는 경우 초기화 하는 동안 `window.open` 간단 하 게 연결할 수 있습니다. 예를 들어: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -새 `InAppBrowser` 인스턴스, 현재 브라우저 인스턴스 또는 시스템 브라우저에서 URL을 엽니다. - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)* - -* **url**: *(문자열)를*로드 하는 URL. 전화 `encodeURI()` 이 경우에는 URL 유니코드 문자를 포함 합니다. - -* **대상**: 대상 URL, 기본적으로 선택적 매개 변수를 로드 하는 `_self` . *(문자열)* - - * `_self`: URL 화이트 리스트에 있으면 코르도바 WebView에서 열리고, 그렇지 않으면 열에`InAppBrowser`. - * `_blank`: 준공에`InAppBrowser`. - * `_system`: 시스템의 웹 브라우저에서 엽니다. - -* **옵션**: 옵션은 `InAppBrowser` . 선택적, 디폴트에: `location=yes` . *(문자열)* - - `options`문자열 텅 빈 어떤 스페이스 포함 해서는 안 그리고 쉼표 각 기능의 이름/값 쌍을 구분 합니다. 기능 이름은 대/소문자입니다. 모든 플랫폼 지원 아래 값: - - * **위치**: 설정 `yes` 또는 `no` 설정 하는 `InAppBrowser` 의 위치 표시줄 켜거나 끕니다. - - 안 드 로이드만: - - * **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다. - * **clearcache**: 설정 `yes` 브라우저를 쿠키 캐시 삭제 하기 전에 새 창이 열립니다 - * **clearsessioncache**: 설정 `yes` 세션 쿠키 캐시를 삭제 하기 전에 새 창이 열립니다 - - iOS만: - - * **closebuttoncaption**: **수행** 하는 단추의 캡션으로 사용할 문자열을 설정 합니다. 참고 직접이 값을 지역화 해야 합니다. - * **disallowoverscroll**: 설정 `yes` 또는 `no` (기본값은 `no` ). 회전 온/오프 UIWebViewBounce 속성입니다. - * **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다. - * **clearcache**: 설정 `yes` 브라우저를 쿠키 캐시 삭제 하기 전에 새 창이 열립니다 - * **clearsessioncache**: 설정 `yes` 세션 쿠키 캐시를 삭제 하기 전에 새 창이 열립니다 - * **도구 모음**: 설정 `yes` 또는 `no` InAppBrowser (기본값:에 대 한 도구 모음 온 / 오프를 돌기 위하여`yes`) - * **enableViewportScale**: 설정 `yes` 또는 `no` 뷰포트 메타 태그 (기본값:를 통해 확장을 방지 하기 위해`no`). - * **mediaPlaybackRequiresUserAction**: 설정 `yes` 또는 `no` HTML5 오디오 또는 비디오 자동 재생 (기본값에서에서 방지 하기 위해`no`). - * **allowInlineMediaPlayback**: 설정 `yes` 또는 `no` 인라인 HTML5 미디어 재생, 장치 전용 재생 인터페이스 보다는 브라우저 창 내에서 표시할 수 있도록 합니다. HTML의 `video` 요소가 포함 되어야 합니다는 `webkit-playsinline` 특성 (기본값:`no`) - * **keyboardDisplayRequiresUserAction**: 설정 `yes` 또는 `no` 양식 요소는 자바 스크립트를 통해 포커스를 받을 때 키보드를 열고 `focus()` 전화 (기본값:`yes`). - * **suppressesIncrementalRendering**: 설정 `yes` 또는 `no` (기본값을 렌더링 하기 전에 모든 새로운 보기 콘텐츠를 받을 때까지 기다려야`no`). - * **presentationstyle**: 설정 `pagesheet` , `formsheet` 또는 `fullscreen` [프레 젠 테이 션 스타일][1] (기본값을 설정 하려면`fullscreen`). - * **transitionstyle**: 설정 `fliphorizontal` , `crossdissolve` 또는 `coververtical` [전환 스타일][2] (기본값을 설정 하려면`coververtical`). - * **toolbarposition**: 설정 `top` 또는 `bottom` (기본값은 `bottom` ). 위쪽 또는 아래쪽 창에 도구 모음을 발생 합니다. - - Windows에만 해당: - - * **숨겨진**: 설정 `yes` 브라우저를 만들 페이지를 로드 하면, 하지만 그것을 보여주지. Loadstop 이벤트는 로드가 완료 되 면 발생 합니다. 생략 하거나 설정 `no` (기본값) 브라우저 열고 정상적으로 로드 해야 합니다. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* 블랙베리 10 -* Firefox 운영 체제 -* iOS -* 윈도우 8과 8.1 -* Windows Phone 7과 8 - -### 예를 들어 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### 파이어 폭스 OS 단점 - -플러그인 어떤 디자인을 적용 하지 않는 경우 열 일부 CSS의 규칙을 추가할 필요가 있다 `target='_blank'`. 이 같이 규칙 - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -`Cordova에 대 한 호출에서 반환 하는 개체.InAppBrowser.open`. - -### 메서드 - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> 이벤트에 대 한 수신기를 추가 합니다`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)* - -* **eventname**: *(문자열)를* 수신 하도록 이벤트 - - * **loadstart**: 이벤트 발생 때는 `InAppBrowser` URL 로드를 시작 합니다. - * **loadstop**: 이벤트가 발생 시기는 `InAppBrowser` URL 로드 완료. - * **loaderror**: 이벤트 발생 때는 `InAppBrowser` URL을 로드할 때 오류가 발생 합니다. - * **종료**: 이벤트가 발생 시기는 `InAppBrowser` 창이 닫힙니다. - -* **콜백**: 이벤트가 발생 될 때 실행 되는 함수. 함수는 전달 된 `InAppBrowserEvent` 개체를 매개 변수로 합니다. - -### InAppBrowserEvent 속성 - -* **유형**: eventname, 중 `loadstart` , `loadstop` , `loaderror` , 또는 `exit` . *(문자열)* - -* **url**: URL 로드 된. *(문자열)* - -* **코드**: 오류 코드의 경우에만 `loaderror` . *(수)* - -* **메시지**: 오류 메시지의 경우에만 `loaderror` . *(문자열)* - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* iOS -* 윈도우 8과 8.1 -* Windows Phone 7과 8 - -### 빠른 예제 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> 이벤트에 대 한 수신기를 제거 합니다`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)* - -* **eventname**: 이벤트 수신 대기를 중지 합니다. *(문자열)* - - * **loadstart**: 이벤트 발생 때는 `InAppBrowser` URL 로드를 시작 합니다. - * **loadstop**: 이벤트가 발생 시기는 `InAppBrowser` URL 로드 완료. - * **loaderror**: 이벤트 발생 때는 `InAppBrowser` URL 로드 오류가 발생 합니다. - * **종료**: 이벤트가 발생 시기는 `InAppBrowser` 창이 닫힙니다. - -* **콜백**: 이벤트가 발생 하면 실행할 함수. 함수는 전달 된 `InAppBrowserEvent` 개체. - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* iOS -* 윈도우 8과 8.1 -* Windows Phone 7과 8 - -### 빠른 예제 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> 종료는 `InAppBrowser` 창. - - ref.close(); - - -* **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)* - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* Firefox 운영 체제 -* iOS -* 윈도우 8과 8.1 -* Windows Phone 7과 8 - -### 빠른 예제 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> 숨겨진 열은 한 InAppBrowser 창을 표시 합니다. 전화는 InAppBrowser가 이미 보이는 경우는 효과가 없습니다. - - ref.show(); - - -* **ref**: InAppBrowser 창 (참조`InAppBrowser`) - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* iOS -* 윈도우 8과 8.1 - -### 빠른 예제 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> 에 자바 스크립트 코드를 삽입는 `InAppBrowser` 창 - - ref.executeScript(details, callback); - - -* **심판**:에 대 한 참조는 `InAppBrowser` 창. *(InAppBrowser)* - -* **injectDetails**: 스크립트 실행의 세부 사항 중 하나를 지정 하는 `file` 또는 `code` 키. *(개체)* - - * **파일**: 삽입 하는 스크립트의 URL. - * **코드**: 스크립트 텍스트를 삽입 합니다. - -* **콜백**: 자바 스크립트 코드를 주입 후 실행 기능. - - * 삽입 된 스크립트 유형의 경우 `code` , 스크립트의 반환 값은 단일 매개 변수는 콜백 실행에 싸여 있는 `Array` . 여러 줄 스크립트에 대 한 마지막 문 또는 평가 마지막 식의 반환 값입니다. - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* iOS -* 윈도우 8과 8.1 - -### 빠른 예제 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> 주사로 CSS는 `InAppBrowser` 창. - - ref.insertCSS(details, callback); - - -* **심판**:에 대 한 참조는 `InAppBrowser` 창 *(InAppBrowser)* - -* **injectDetails**: 스크립트 실행의 세부 사항 중 하나를 지정 하는 `file` 또는 `code` 키. *(개체)* - - * **파일**: 삽입 하는 스타일 시트의 URL. - * **코드**: 삽입 하는 스타일 시트의 텍스트. - -* **콜백**: CSS 주입 후 실행 기능. - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* iOS - -### 빠른 예제 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/pl/index.md b/plugins/cordova-plugin-inappbrowser/doc/pl/index.md deleted file mode 100644 index dff9bf0f..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/pl/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -Plugin daje widok przeglądarki sieci web, które są wyświetlane podczas wywoływania `cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -`cordova.InAppBrowser.open()` funkcja jest definiowana jako zamiennik dla funkcji `window.open()`. Istniejące wywołania `window.open()` służy okno InAppBrowser, zastępując window.open: - - window.open = cordova.InAppBrowser.open; - - -Okna InAppBrowser zachowuje się jak standardowe przeglądarki i nie ma dostępu do API Cordova. Z tego powodu zaleca się InAppBrowser jeśli ty potrzebować wobec ciężar (niezaufanej) treści osób trzecich, a nie że wczytywanie głównym webview Cordova. InAppBrowser nie jest biała, ani nie jest otwieranie linków w przeglądarce systemu. - -InAppBrowser zawiera domyślnie kontrole GUI dla użytkownika (tył, przód, zrobić). - -Do tyłu zgodności, ten plugin również haki `window.open`. Jednak może mieć zainstalowane wtyczki haka `window.open` niezamierzone skutki uboczne (zwłaszcza, jeśli ten plugin jest włączone tylko jako część innej wtyczki). Hak `window.open` zostaną usunięte w przyszłej wersji głównych. Dopóki hak jest usuwany z wtyczki, aplikacje można ręcznie przywrócić domyślne zachowanie: - - delete window.open // Reverts the call back to it's prototype's default - - -Chociaż `window.open` w globalnym zasięgu, InAppBrowser nie jest dostępne dopiero po zdarzeniu `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## Instalacja - - cordova plugin add cordova-plugin-inappbrowser - - -Jeśli chcesz wszystko stronica ładunki w swojej aplikacji, aby przejść przez InAppBrowser, można po prostu podłączyć `window.open` podczas inicjowania. Na przykład: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -Otwiera URL w nowe wystąpienie `InAppBrowser`, bieżące wystąpienie przeglądarki lub przeglądarki systemu. - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)* - -* **adres**: adres URL do ładowania *(ciąg)*. Wywołanie `encodeURI()` na to, czy adres URL zawiera znaki Unicode. - -* **miejsce docelowe**: miejsce docelowe, w którym wobec ciężar ten URL parametr opcjonalny, który domyślnie `_self` . *(String)* - - * `_self`: Otwiera w Cordova WebView, jeśli adres URL jest na białej liście, inaczej ono otwiera w`InAppBrowser`. - * `_blank`: Otwiera w`InAppBrowser`. - * `_system`: Otwiera w przeglądarce internetowej systemu. - -* **Opcje**: opcje dla `InAppBrowser` . Opcjonalnie, nie stawiła się: `location=yes` . *(String)* - - `options`Ciąg nie może zawierać żadnych spacji, i pary nazwa/wartość każdej funkcji muszą być oddzielone przecinkami. Nazwy funkcji jest rozróżniana. Wszystkich platform obsługuje wartości poniżej: - - * **Lokalizacja**: zestaw `yes` lub `no` Aby włączyć `InAppBrowser` na pasek lub wyłączyć. - - Android: - - * **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie. - * **ClearCache**: zestaw `yes` do przeglądarki w pamięci podręcznej plików cookie wyczyszczone zanim otworzy się nowe okno - * **clearsessioncache**: zestaw `yes` mieć w pamięci podręcznej plików cookie sesji wyczyszczone zanim otworzy się nowe okno - - tylko iOS: - - * **closebuttoncaption**: aby użyć jak **zrobić** przycisk Podpis ustawiona na ciąg. Należy pamiętać, że trzeba zlokalizować tę wartość siebie. - * **disallowoverscroll**: zestaw `yes` lub `no` (domyślnie `no` ). Włącza/wyłącza właściwość UIWebViewBounce. - * **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie. - * **ClearCache**: zestaw `yes` do przeglądarki w pamięci podręcznej plików cookie wyczyszczone zanim otworzy się nowe okno - * **clearsessioncache**: zestaw `yes` mieć w pamięci podręcznej plików cookie sesji wyczyszczone zanim otworzy się nowe okno - * **pasek narzędzi**: zestaw `yes` lub `no` Aby włączyć pasek narzędzi lub wyłączyć dla InAppBrowser (domyślnie`yes`) - * **enableViewportScale**: zestaw `yes` lub `no` Aby zapobiec rzutni skalowanie za pomocą tagu meta (domyślnie`no`). - * **mediaPlaybackRequiresUserAction**: zestaw `yes` lub `no` Aby zapobiec HTML5 audio lub wideo z Autoodtwarzanie (domyślnie`no`). - * **allowInlineMediaPlayback**: zestaw `yes` lub `no` Aby w linii HTML5 odtwarzanie, wyświetlanie w oknie przeglądarki, a nie interfejs odtwarzanie specyficzne dla urządzenia. HTML `video` również musi zawierać element `webkit-playsinline` atrybut (domyślnie`no`) - * **keyboardDisplayRequiresUserAction**: zestaw `yes` lub `no` Aby otworzyć klawiaturę ekranową, gdy elementy formularza ostrości za pomocą JavaScript `focus()` połączenia (domyślnie`yes`). - * **suppressesIncrementalRendering**: zestaw `yes` lub `no` czekać, aż wszystkie nowe widok zawartości jest otrzymane przed renderowany (domyślnie`no`). - * **presentationstyle**: zestaw `pagesheet` , `formsheet` lub `fullscreen` Aby ustawić [styl prezentacji][1] (domyślnie`fullscreen`). - * **transitionstyle**: zestaw `fliphorizontal` , `crossdissolve` lub `coververtical` Aby ustawić [styl przejścia][2] (domyślnie`coververtical`). - * **toolbarposition**: zestaw `top` lub `bottom` (domyślnie `bottom` ). Powoduje, że pasek ma być na górze lub na dole okna. - - Windows tylko: - - * **ukryte**: zestaw `yes` do stworzenia przeglądarki i ładowania strony, ale nie pokazuje go. Loadstop zdarzenie fires po zakończeniu ładowania. Pominąć lub zestaw `no` (domyślnie) do przeglądarki otworzyć i załadować normalnie. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows 8 i 8.1 -* Windows Phone 7 i 8 - -### Przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Firefox OS dziwactwa - -Jak plugin nie wymuszać każdy projekt to trzeba dodać pewne reguły CSS jeśli otwarty z `target = "_blank"`. Zasady może wyglądać jak te - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -Obiekt zwrócony z wywołania `cordova.InAppBrowser.open`. - -### Metody - -* metody addEventListener -* removeEventListener -* Zamknij -* Pokaż -* executeScript -* insertCSS - -## metody addEventListener - -> Dodaje detektor zdarzenia z`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)* - -* **EventName**: zdarzenie słuchać *(String)* - - * **loadstart**: zdarzenie gdy odpalam `InAppBrowser` zaczyna się ładować adresu URL. - * **loadstop**: zdarzenie gdy odpalam `InAppBrowser` zakończeniu ładowania adresu URL. - * **LoadError**: zdarzenie odpala gdy `InAppBrowser` napotka błąd podczas ładowania adresu URL. - * **wyjście**: zdarzenie gdy odpalam `InAppBrowser` okno jest zamknięte. - -* **wywołania zwrotnego**: funkcja, która wykonuje, gdy zdarzenie. Funkcja jest przekazywany `InAppBrowserEvent` obiektu jako parametr. - -### Właściwości InAppBrowserEvent - -* **Typ**: eventname, albo `loadstart` , `loadstop` , `loaderror` , lub `exit` . *(String)* - -* **adres**: adres URL, który został załadowany. *(String)* - -* **Kod**: kod błędu, tylko w przypadku `loaderror` . *(Liczba)* - -* **wiadomość**: komunikat o błędzie, tylko w przypadku `loaderror` . *(String)* - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* iOS -* Windows 8 i 8.1 -* Windows Phone 7 i 8 - -### Szybki przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> Usuwa detektor zdarzenia z`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)* - -* **EventName**: zdarzenie przestanie słuchać. *(String)* - - * **loadstart**: zdarzenie gdy odpalam `InAppBrowser` zaczyna się ładować adresu URL. - * **loadstop**: zdarzenie gdy odpalam `InAppBrowser` zakończeniu ładowania adresu URL. - * **LoadError**: zdarzenie odpala gdy `InAppBrowser` napotka błąd ładowania adresu URL. - * **wyjście**: zdarzenie gdy odpalam `InAppBrowser` okno jest zamknięte. - -* **wywołania zwrotnego**: funkcja do wykonania, gdy zdarzenie. Funkcja jest przekazywany `InAppBrowserEvent` obiektu. - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* iOS -* Windows 8 i 8.1 -* Windows Phone 7 i 8 - -### Szybki przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## Zamknij - -> Zamyka `InAppBrowser` okna. - - ref.close(); - - -* **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)* - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* Firefox OS -* iOS -* Windows 8 i 8.1 -* Windows Phone 7 i 8 - -### Szybki przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## Pokaż - -> Wyświetla InAppBrowser okno, który został otwarty ukryte. Zawód ten jest ignorowany, jeśli InAppBrowser już był widoczny. - - ref.show(); - - -* **ref**: odwołanie do InAppBrowser (okno`InAppBrowser`) - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* iOS -* Windows 8 i 8.1 - -### Szybki przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> Wstrzykuje kod JavaScript w `InAppBrowser` okna - - ref.executeScript(details, callback); - - -* **ref**: odniesienie do `InAppBrowser` okna. *(InAppBrowser)* - -* **injectDetails**: Szczegóły dotyczące skryptu, określając albo `file` lub `code` klucz. *(Obiekt)* - - * **plik**: adres URL skryptu, aby wstrzyknąć. - * **Kod**: tekst skryptu, aby wstrzyknąć. - -* **wywołania zwrotnego**: funkcja, która wykonuje po kod JavaScript jest wstrzykiwany. - - * Jeśli taki skrypt jest typu `code` , wykonuje wywołanie zwrotne z pojedynczym parametrem, który jest wartość zwracana przez skrypt, owinięte w `Array` . Dla wielu linii skrypty to wartość zwracana ostatniej instrukcja, lub ostatni wyrażenie oceniane. - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* iOS -* Windows 8 i 8.1 - -### Szybki przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> Wstrzykuje CSS w `InAppBrowser` okna. - - ref.insertCSS(details, callback); - - -* **ref**: odniesienie do `InAppBrowser` okna *(InAppBrowser)* - -* **injectDetails**: Szczegóły dotyczące skryptu, określając albo `file` lub `code` klucz. *(Obiekt)* - - * **plik**: URL arkusza stylów do wsuwania. - * **Kod**: tekst z arkusza stylów do wstrzykiwania. - -* **wywołania zwrotnego**: funkcja, która wykonuje po CSS jest wstrzykiwany. - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* iOS - -### Szybki przykład - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/ru/index.md b/plugins/cordova-plugin-inappbrowser/doc/ru/index.md deleted file mode 100644 index 3b4e967d..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/ru/index.md +++ /dev/null @@ -1,330 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -Этот плагин обеспечивает представление веб-браузера, что показывает при вызове`window.open()`. - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - - -**Примечание**: InAppBrowser окно ведет себя как стандартный веб-браузер и не может доступ API Cordova. - -## Установка - - cordova plugin add cordova-plugin-inappbrowser - - -## window.open - -Открывает URL-адрес в новом `InAppBrowser` например, текущий экземпляр браузера или браузера системы. - - var ref = window.open(url, target, options); - - -* **ссылка**: ссылка для `InAppBrowser` окно. *(InAppBrowser)* - -* **URL**: URL-адрес для загрузки *(String)*. Вызвать `encodeURI()` на это, если URL-адрес содержит символы Unicode. - -* **Цель**: цель для загрузки URL-адреса, необязательный параметр, по умолчанию `_self` . *(Строка)* - - * `_self`: Открывается в Cordova WebView, если URL-адрес в белый список, в противном случае он открывается в`InAppBrowser`. - * `_blank`: Открывает в`InAppBrowser`. - * `_system`: Открывается в веб-браузера системы. - -* **опции**: параметры для `InAppBrowser` . Необязательный параметр, виновная в: `location=yes` . *(Строка)* - - `options`Строка не должна содержать каких-либо пустое пространство, и каждая функция пар имя/значение должны быть разделены запятой. Функция имена нечувствительны к регистру. Все платформы поддерживают исходное значение: - - * **Расположение**: равным `yes` или `no` превратить `InAppBrowser` в адресную строку или выключить. - - Только андроид: - - * **closebuttoncaption**: задайте строку для использования в качестве заголовка кнопки **сделали** . - * **скрытые**: значение `yes` для создания браузера и загрузки страницы, но не показать его. Событие loadstop возникает, когда загрузка завершена. Опустить или набор `no` (по умолчанию), чтобы браузер открыть и загрузить нормально. - * **ClearCache**: набор `yes` иметь браузера куки кэш очищен перед открытием нового окна - * **clearsessioncache**: значение `yes` иметь кэш cookie сеанса очищается перед открытием нового окна - - только iOS: - - * **closebuttoncaption**: задайте строку для использования в качестве заголовка кнопки **сделали** . Обратите внимание, что вам нужно самостоятельно локализовать это значение. - * **disallowoverscroll**: значение `yes` или `no` (по умолчанию `no` ). Включает/отключает свойство UIWebViewBounce. - * **скрытые**: значение `yes` для создания браузера и загрузки страницы, но не показать его. Событие loadstop возникает, когда загрузка завершена. Опустить или набор `no` (по умолчанию), чтобы браузер открыть и загрузить нормально. - * **ClearCache**: набор `yes` иметь браузера куки кэш очищен перед открытием нового окна - * **clearsessioncache**: значение `yes` иметь кэш cookie сеанса очищается перед открытием нового окна - * **панели инструментов**: набор `yes` или `no` для включения панели инструментов или выключить InAppBrowser (по умолчанию`yes`) - * **enableViewportScale**: значение `yes` или `no` для предотвращения просмотра, масштабирования через тег meta (по умолчанию`no`). - * **mediaPlaybackRequiresUserAction**: значение `yes` или `no` для предотвращения HTML5 аудио или видео от Автовоспроизведение (по умолчанию`no`). - * **allowInlineMediaPlayback**: значение `yes` или `no` чтобы разрешить воспроизведение мультимедиа HTML5 в строки, отображения в окне браузера, а не конкретного устройства воспроизведения интерфейс. HTML `video` элемент должен также включать `webkit-playsinline` атрибут (по умолчанию`no`) - * **keyboardDisplayRequiresUserAction**: значение `yes` или `no` чтобы открыть клавиатуру, когда формы элементы получают фокус через JavaScript в `focus()` вызов (по умолчанию`yes`). - * **suppressesIncrementalRendering**: значение `yes` или `no` ждать, пока все новое содержание представление получено до визуализации (по умолчанию`no`). - * **presentationstyle**: набор `pagesheet` , `formsheet` или `fullscreen` чтобы задать [стиль презентации][1] (по умолчанию`fullscreen`). - * **transitionstyle**: набор `fliphorizontal` , `crossdissolve` или `coververtical` чтобы задать [стиль перехода][2] (по умолчанию`coververtical`). - * **toolbarposition**: значение `top` или `bottom` (по умолчанию `bottom` ). Вызывает панели инструментов, чтобы быть в верхней или нижней части окна. - - Windows только: - - * **скрытые**: значение `yes` для создания браузера и загрузки страницы, но не показать его. Событие loadstop возникает, когда загрузка завершена. Опустить или набор `no` (по умолчанию), чтобы браузер открыть и загрузить нормально. - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Firefox OS -* iOS -* Windows 8 и 8.1 -* Windows Phone 7 и 8 - -### Пример - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = window.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### Особенности Firefox OS - -Как плагин не применять любой дизайн есть необходимость добавить некоторые правила CSS, если открыт с `target='_blank'` . Правила может выглядеть как эти - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## Внутренний браузер - -Объект, возвращаемый из вызова`window.open`. - -### Методы - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> Добавляет прослушиватель для события от`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **ссылка**: ссылка для `InAppBrowser` окно *(InAppBrowser)* - -* **EventName**: событие для прослушивания *(String)* - - * **loadstart**: событие возникает, когда `InAppBrowser` начинает для загрузки URL-адреса. - * **loadstop**: событие возникает, когда `InAppBrowser` завершит загрузку URL-адреса. - * **loaderror**: событие возникает, когда `InAppBrowser` обнаруживает ошибку при загрузке URL-адреса. - * **выход**: возникает событие, когда `InAppBrowser` окно закрыто. - -* **обратного вызова**: функция, которая выполняется, когда возникает событие. Функция передается `InAppBrowserEvent` объект в качестве параметра. - -### InAppBrowserEvent свойства - -* **тип**: eventname, либо `loadstart` , `loadstop` , `loaderror` , или `exit` . *(Строка)* - -* **URL**: URL-адрес, который был загружен. *(Строка)* - -* **код**: код ошибки, только в случае `loaderror` . *(Число)* - -* **сообщение**: сообщение об ошибке, только в случае `loaderror` . *(Строка)* - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* iOS -* Windows 8 и 8.1 -* Windows Phone 7 и 8 - -### Краткий пример - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## метод removeEventListener - -> Удаляет прослушиватель для события от`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **ссылка**: ссылка для `InAppBrowser` окно. *(InAppBrowser)* - -* **EventName**: событие прекратить прослушивание. *(Строка)* - - * **loadstart**: событие возникает, когда `InAppBrowser` начинает для загрузки URL-адреса. - * **loadstop**: событие возникает, когда `InAppBrowser` завершит загрузку URL-адреса. - * **loaderror**: событие возникает, когда `InAppBrowser` обнаруживает ошибку загрузки URL-адреса. - * **выход**: возникает событие, когда `InAppBrowser` окно закрывается. - -* **обратного вызова**: функция, выполняемая когда это событие наступает. Функция передается `InAppBrowserEvent` объект. - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* iOS -* Windows 8 и 8.1 -* Windows Phone 7 и 8 - -### Краткий пример - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> Закрывает `InAppBrowser` окно. - - Ref.Close(); - - -* **ссылка**: ссылка на `InAppBrowser` окно *(InAppBrowser)* - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* Firefox OS -* iOS -* Windows 8 и 8.1 -* Windows Phone 7 и 8 - -### Краткий пример - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> Отображается окно InAppBrowser, был открыт скрытые. Вызов это не имеет эффекта при InAppBrowser уже был виден. - - Ref.Show(); - - -* **ссылка**: ссылка на окно (InAppBrowser`InAppBrowser`) - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* iOS -* Windows 8 и 8.1 - -### Краткий пример - - var ref = window.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> Вставляет код JavaScript в `InAppBrowser` окно - - ref.executeScript(details, callback); - - -* **ссылка**: ссылка на `InAppBrowser` окно. *(InAppBrowser)* - -* **injectDetails**: подробности сценария для запуска, указав либо `file` или `code` ключ. *(Объект)* - - * **файл**: URL-адрес сценария вставки. - * **код**: текст сценария для вставки. - -* **обратного вызова**: функция, которая выполняет после вводят JavaScript-код. - - * Если введенный скрипт имеет тип `code` , обратный вызов выполняется с одним параметром, который является возвращаемое значение сценария, завернутые в `Array` . Для многострочных сценариев это возвращаемое значение последнего оператора, или последнее вычисленное выражение. - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* iOS -* Windows 8 и 8.1 - -### Краткий пример - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> Внедряет CSS в `InAppBrowser` окно. - - ref.insertCSS(details, callback); - - -* **ссылка**: ссылка на `InAppBrowser` окно *(InAppBrowser)* - -* **injectDetails**: детали сценария для запуска, указав либо `file` или `code` ключ. *(Объект)* - - * **файл**: URL-адрес таблицы стилей для вставки. - * **код**: текст таблицы стилей для вставки. - -* **обратного вызова**: функция, которая выполняет после вводят CSS. - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* iOS - -### Краткий пример - - var ref = window.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/doc/zh/index.md b/plugins/cordova-plugin-inappbrowser/doc/zh/index.md deleted file mode 100644 index c12c0461..00000000 --- a/plugins/cordova-plugin-inappbrowser/doc/zh/index.md +++ /dev/null @@ -1,357 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-inappbrowser - -這個外掛程式提供了一個 web 瀏覽器視圖,顯示在調用 `cordova.InAppBrowser.open()`. - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - - -`cordova.InAppBrowser.open()` 函數被定義為一個臨時替代 `window.open ()` 函數。 現有 `window.open ()` 調用,可以通過替換 window.open 使用 InAppBrowser 視窗: - - window.open = cordova.InAppBrowser.open; - - -InAppBrowser 視窗像一個標準的 web 瀏覽器中,並且無法訪問科爾多瓦 Api。 為此,建議 InAppBrowser 如果您需要載入協力廠商 (不可信) 的內容,而不是載入,進入主要的科爾多瓦 web 視圖。 InAppBrowser 是不受白名單中,也不在系統瀏覽器中打開的連結。 - -InAppBrowser 預設情況下它自己的 GUI 控制項為使用者提供 (後退、 前進、 完成)。 - -為向後相容性,此外掛程式還鉤 `window.open`。 然而,`window.open` 外掛程式安裝鉤子可以有副作用 (尤其是如果這個外掛程式是只列為另一個外掛程式的依賴項)。 在未來的主要發行版本中,將刪除 `window.open` 鉤。 一直至從該外掛程式鉤子後,應用程式可以手動還原預設行為: - - delete window.open // Reverts the call back to it's prototype's default - - -雖然 `window.open` 在全球範圍內,InAppBrowser 不可用直到 `deviceready` 事件之後。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("window.open works well"); - } - - -## 安裝 - - cordova plugin add cordova-plugin-inappbrowser - - -如果您希望所有頁面載入中您的應用程式要通過 InAppBrowser,你可以簡單地在初始化過程中鉤 `window.open`。舉個例子: - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - window.open = cordova.InAppBrowser.open; - } - - -## cordova.InAppBrowser.open - -在新的 `InAppBrowser` 實例,當前的瀏覽器實例或系統瀏覽器中打開的 URL。 - - var ref = cordova.InAppBrowser.open(url, target, options); - - -* **ref**: 參考 `InAppBrowser` 視窗。*() InAppBrowser* - -* **url**: 要載入*(字串)*的 URL。調用 `encodeURI()` 這個如果 URL 包含 Unicode 字元。 - -* **target**: 目標在其中載入的 URL,可選參數,預設值為 `_self` 。*(字串)* - - * `_self`: 打開在科爾多瓦 web 視圖如果 URL 是在白名單中,否則它在打開`InAppBrowser`. - * `_blank`: 在打開`InAppBrowser`. - * `_system`: 在該系統的 web 瀏覽器中打開。 - -* **options**: 選項為 `InAppBrowser` 。可選,拖欠到: `location=yes` 。*(字串)* - - `options`字串必須不包含任何空白的空間,和必須用逗號分隔每個功能的名稱/值對。 功能名稱區分大小寫。 所有平臺都支援下面的值: - - * **location**: 設置為 `yes` 或 `no` ,打開 `InAppBrowser` 的位置欄打開或關閉。 - - Android 系統只有: - - * **hidden**: 將設置為 `yes` ,創建瀏覽器和載入頁面,但不是顯示它。 載入完成時,將觸發 loadstop 事件。 省略或設置為 `no` (預設值),有的瀏覽器打開,然後以正常方式載入。 - * **clearcache**: 將設置為 `yes` 有瀏覽器的 cookie 清除緩存之前打開新視窗 - * **clearsessioncache**: 將設置為 `yes` 有會話 cookie 緩存清除之前打開新視窗 - - 只有 iOS: - - * **closebuttoncaption**: 設置為一個字串,以用作**做**按鈕的標題。請注意您需要對此值進行當地語系化你自己。 - * **disallowoverscroll**: 將設置為 `yes` 或 `no` (預設值是 `no` )。打開/關閉的 UIWebViewBounce 屬性。 - * **hidden**: 將設置為 `yes` ,創建瀏覽器和載入頁面,但不是顯示它。 載入完成時,將觸發 loadstop 事件。 省略或設置為 `no` (預設值),有的瀏覽器打開,然後以正常方式載入。 - * **clearcache**: 將設置為 `yes` 有瀏覽器的 cookie 清除緩存之前打開新視窗 - * **clearsessioncache**: 將設置為 `yes` 有會話 cookie 緩存清除之前打開新視窗 - * **toolbar**: 設置為 `yes` 或 `no` ,為 InAppBrowser (預設為打開或關閉工具列`yes`) - * **enableViewportScale**: 將設置為 `yes` 或 `no` ,防止通過 meta 標記 (預設為縮放的視區`no`). - * **mediaPlaybackRequiresUserAction**: 將設置為 `yes` 或 `no` ,防止 HTML5 音訊或視頻從 autoplaying (預設為`no`). - * **allowInlineMediaPlayback**: 將設置為 `yes` 或 `no` ,讓線在 HTML5 播放媒體,在瀏覽器視窗中,而不是特定于設備播放介面內顯示。 HTML 的 `video` 元素還必須包括 `webkit-playsinline` 屬性 (預設為`no`) - * **keyboardDisplayRequiresUserAction**: 將設置為 `yes` 或 `no` 時,要打開鍵盤表單元素接收焦點通過 JavaScript 的 `focus()` 調用 (預設為`yes`). - * **suppressesIncrementalRendering**: 將設置為 `yes` 或 `no` 等待,直到所有新查看的內容正在呈現 (預設為前收到`no`). - * **presentationstyle**: 將設置為 `pagesheet` , `formsheet` 或 `fullscreen` 來設置[演示文稿樣式][1](預設為`fullscreen`). - * **transitionstyle**: 將設置為 `fliphorizontal` , `crossdissolve` 或 `coververtical` 設置[過渡樣式][2](預設為`coververtical`). - * **toolbarposition**: 將設置為 `top` 或 `bottom` (預設值是 `bottom` )。使工具列,則在頂部或底部的視窗。 - - 僅限 Windows: - - * **hidden**: 將設置為 `yes` ,創建瀏覽器並載入頁面,但不是顯示它。 載入完成時,將觸發 loadstop 事件。 省略或被設置為 `no` (預設值),有的瀏覽器打開,以正常方式載入。 - - [1]: http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle - [2]: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* 黑莓 10 -* 火狐瀏覽器的作業系統 -* iOS -* Windows 8 和 8.1 -* Windows Phone 7 和 8 - -### 示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var ref2 = cordova.InAppBrowser.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); - - -### 火狐瀏覽器作業系統的怪癖 - -外掛程式不會強制任何設計是需要添加一些 CSS 規則,如果打開與 `target=_blank`。規則 》 可能看起來像這些 - - css - .inAppBrowserWrap { - background-color: rgba(0,0,0,0.75); - color: rgba(235,235,235,1.0); - } - .inAppBrowserWrap menu { - overflow: auto; - list-style-type: none; - padding-left: 0; - } - .inAppBrowserWrap menu li { - font-size: 25px; - height: 25px; - float: left; - margin: 0 10px; - padding: 3px 10px; - text-decoration: none; - color: #ccc; - display: block; - background: rgba(30,30,30,0.50); - } - .inAppBrowserWrap menu li.disabled { - color: #777; - } - - -## InAppBrowser - -對 `科爾多瓦的調用返回的物件。InAppBrowser.open`. - -### 方法 - -* addEventListener -* removeEventListener -* close -* show -* executeScript -* insertCSS - -## addEventListener - -> 為事件添加一個攔截器`InAppBrowser`. - - ref.addEventListener(eventname, callback); - - -* **ref**: 參考 `InAppBrowser` 視窗*(InAppBrowser)* - -* **eventname**: 事件偵聽*(字串)* - - * **loadstart**: 當觸發事件 `InAppBrowser` 開始載入一個 URL。 - * **loadstop**: 當觸發事件 `InAppBrowser` 完成載入一個 URL。 - * **loaderror**: 當觸發事件 `InAppBrowser` 載入 URL 時遇到錯誤。 - * **exit**: 當觸發事件 `InAppBrowser` 關閉視窗。 - -* **callback**: 執行時觸發該事件的函數。該函數通過 `InAppBrowserEvent` 物件作為參數。 - -### InAppBrowserEvent 屬性 - -* **type**: eventname,或者 `loadstart` , `loadstop` , `loaderror` ,或 `exit` 。*(字串)* - -* **url**: 已載入的 URL。*(字串)* - -* **code**: 僅中的情況的錯誤代碼 `loaderror` 。*(人數)* - -* **message**: 該錯誤訊息,只有在的情況下 `loaderror` 。*(字串)* - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* iOS -* Windows 8 和 8.1 -* Windows Phone 7 和 8 - -### 快速的示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstart', function(event) { alert(event.url); }); - - -## removeEventListener - -> 移除的事件攔截器`InAppBrowser`. - - ref.removeEventListener(eventname, callback); - - -* **ref**: 參考 `InAppBrowser` 視窗。*() InAppBrowser* - -* **eventname**: 要停止偵聽的事件。*(字串)* - - * **loadstart**: 當觸發事件 `InAppBrowser` 開始載入一個 URL。 - * **loadstop**: 當觸發事件 `InAppBrowser` 完成載入一個 URL。 - * **loaderror**: 當觸發事件 `InAppBrowser` 遇到錯誤載入一個 URL。 - * **exit**: 當觸發事件 `InAppBrowser` 關閉視窗。 - -* **callback**: 要在事件觸發時執行的函數。該函數通過 `InAppBrowserEvent` 物件。 - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* iOS -* Windows 8 和 8.1 -* Windows Phone 7 和 8 - -### 快速的示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - var myCallback = function(event) { alert(event.url); } - ref.addEventListener('loadstart', myCallback); - ref.removeEventListener('loadstart', myCallback); - - -## close - -> 關閉 `InAppBrowser` 視窗。 - - ref.close(); - - -* **ref**: 參考 `InAppBrowser` 視窗*(InAppBrowser)* - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* 火狐瀏覽器的作業系統 -* iOS -* Windows 8 和 8.1 -* Windows Phone 7 和 8 - -### 快速的示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.close(); - - -## show - -> 顯示打開了隱藏的 InAppBrowser 視窗。調用這沒有任何影響,如果 InAppBrowser 是已經可見。 - - ref.show(); - - -* **ref**: InAppBrowser 視窗 (參考`InAppBrowser`) - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* iOS -* Windows 8 和 8.1 - -### 快速的示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'hidden=yes'); - // some time later... - ref.show(); - - -## executeScript - -> 注入到 JavaScript 代碼 `InAppBrowser` 視窗 - - ref.executeScript(details, callback); - - -* **ref**: 參考 `InAppBrowser` 視窗。*() InAppBrowser* - -* **injectDetails**: 要運行的腳本的詳細資訊或指定 `file` 或 `code` 的關鍵。*(物件)* - - * **檔**: 腳本的 URL 來注入。 - * **代碼**: 要注入腳本的文本。 - -* **回檔**: 執行後注入的 JavaScript 代碼的函數。 - - * 如果插入的腳本的類型 `code` ,回檔執行使用單個參數,這是該腳本的傳回值,裹在 `Array` 。 對於多行腳本,這是最後一條語句或最後計算的運算式的傳回值。 - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* iOS -* Windows 8 和 8.1 - -### 快速的示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.executeScript({file: "myscript.js"}); - }); - - -## insertCSS - -> 注入到 CSS `InAppBrowser` 視窗。 - - ref.insertCSS(details, callback); - - -* **ref**: 參考 `InAppBrowser` 視窗*(InAppBrowser)* - -* **injectDetails**: 要運行的腳本的詳細資訊或指定 `file` 或 `code` 的關鍵。*(物件)* - - * **file**: 樣式表的 URL 來注入。 - * **code**: 文本樣式表的注入。 - -* **callback**: 在 CSS 注射後執行的函數。 - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* iOS - -### 快速的示例 - - var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes'); - ref.addEventListener('loadstop', function() { - ref.insertCSS({file: "mystyles.css"}); - }); diff --git a/plugins/cordova-plugin-inappbrowser/package.json b/plugins/cordova-plugin-inappbrowser/package.json deleted file mode 100644 index e35e1dc3..00000000 --- a/plugins/cordova-plugin-inappbrowser/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "cordova-plugin-inappbrowser", - "version": "1.0.0", - "description": "Cordova InAppBrowser Plugin", - "cordova": { - "id": "cordova-plugin-inappbrowser", - "platforms": [ - "android", - "amazon-fireos", - "ubuntu", - "ios", - "wp7", - "wp8", - "windows8", - "windows", - "firefoxos" - ] - }, - "repository": { - "type": "git", - "url": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git" - }, - "keywords": [ - "cordova", - "in", - "app", - "browser", - "inappbrowser", - "ecosystem:cordova", - "cordova-android", - "cordova-amazon-fireos", - "cordova-ubuntu", - "cordova-ios", - "cordova-wp7", - "cordova-wp8", - "cordova-windows8", - "cordova-windows", - "cordova-firefoxos" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.1.0" - } - ], - "author": "Apache Software Foundation", - "license": "Apache 2.0" -} diff --git a/plugins/cordova-plugin-inappbrowser/plugin.xml b/plugins/cordova-plugin-inappbrowser/plugin.xml deleted file mode 100644 index 16ac0d19..00000000 --- a/plugins/cordova-plugin-inappbrowser/plugin.xml +++ /dev/null @@ -1,227 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-inappbrowser" - version="1.0.0"> - - <name>InAppBrowser</name> - <description>Cordova InAppBrowser Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,in,app,browser,inappbrowser</keywords> - <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git</repo> - <issue>https://issues.apache.org/jira/browse/CB/component/12320641</issue> - - <engines> - <engine name="cordova" version=">=3.1.0" /><!-- Needs cordova/urlutil --> - </engines> - - <!-- android --> - <platform name="android"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="InAppBrowser"> - <param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/> - </feature> - </config-file> - - <source-file src="src/android/InAppBrowser.java" target-dir="src/org/apache/cordova/inappbrowser" /> - <source-file src="src/android/InAppBrowserDialog.java" target-dir="src/org/apache/cordova/inappbrowser" /> - <source-file src="src/android/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" /> - - <!-- drawable src/android/resources --> - <resource-file src="src/android/res/drawable-hdpi/ic_action_next_item.png" target="res/drawable-hdpi/ic_action_next_item.png" /> - <resource-file src="src/android/res/drawable-mdpi/ic_action_next_item.png" target="res/drawable-mdpi/ic_action_next_item.png" /> - <resource-file src="src/android/res/drawable-xhdpi/ic_action_next_item.png" target="res/drawable-xhdpi/ic_action_next_item.png" /> - <resource-file src="src/android/res/drawable-xxhdpi/ic_action_next_item.png" target="res/drawable-xxhdpi/ic_action_next_item.png" /> - - <resource-file src="src/android/res/drawable-hdpi/ic_action_previous_item.png" target="res/drawable-hdpi/ic_action_previous_item.png" /> - <resource-file src="src/android/res/drawable-mdpi/ic_action_previous_item.png" target="res/drawable-mdpi/ic_action_previous_item.png" /> - <resource-file src="src/android/res/drawable-xhdpi/ic_action_previous_item.png" target="res/drawable-xhdpi/ic_action_previous_item.png" /> - <resource-file src="src/android/res/drawable-xxhdpi/ic_action_previous_item.png" target="res/drawable-xxhdpi/ic_action_previous_item.png" /> - - <resource-file src="src/android/res/drawable-hdpi/ic_action_remove.png" target="res/drawable-hdpi/ic_action_remove.png" /> - <resource-file src="src/android/res/drawable-mdpi/ic_action_remove.png" target="res/drawable-mdpi/ic_action_remove.png" /> - <resource-file src="src/android/res/drawable-xhdpi/ic_action_remove.png" target="res/drawable-xhdpi/ic_action_remove.png" /> - <resource-file src="src/android/res/drawable-xxhdpi/ic_action_remove.png" target="res/drawable-xxhdpi/ic_action_remove.png" /> - - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="InAppBrowser"> - <param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/> - </feature> - </config-file> - - <source-file src="src/amazon/InAppBrowser.java" target-dir="src/org/apache/cordova/inappbrowser" /> - <source-file src="src/android/InAppBrowserDialog.java" target-dir="src/org/apache/cordova/inappbrowser" /> - <source-file src="src/amazon/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" /> - - <!-- drawable src/android/resources --> - <resource-file src="src/android/res/drawable-hdpi/ic_action_next_item.png" target="res/drawable-hdpi/ic_action_next_item.png" /> - <resource-file src="src/android/res/drawable-mdpi/ic_action_next_item.png" target="res/drawable-mdpi/ic_action_next_item.png" /> - <resource-file src="src/android/res/drawable-xhdpi/ic_action_next_item.png" target="res/drawable-xhdpi/ic_action_next_item.png" /> - <resource-file src="src/android/res/drawable-xxhdpi/ic_action_next_item.png" target="res/drawable-xxhdpi/ic_action_next_item.png" /> - - <resource-file src="src/android/res/drawable-hdpi/ic_action_previous_item.png" target="res/drawable-hdpi/ic_action_previous_item.png" /> - <resource-file src="src/android/res/drawable-mdpi/ic_action_previous_item.png" target="res/drawable-mdpi/ic_action_previous_item.png" /> - <resource-file src="src/android/res/drawable-xhdpi/ic_action_previous_item.png" target="res/drawable-xhdpi/ic_action_previous_item.png" /> - <resource-file src="src/android/res/drawable-xxhdpi/ic_action_previous_item.png" target="res/drawable-xxhdpi/ic_action_previous_item.png" /> - - <resource-file src="src/android/res/drawable-hdpi/ic_action_remove.png" target="res/drawable-hdpi/ic_action_remove.png" /> - <resource-file src="src/android/res/drawable-mdpi/ic_action_remove.png" target="res/drawable-mdpi/ic_action_remove.png" /> - <resource-file src="src/android/res/drawable-xhdpi/ic_action_remove.png" target="res/drawable-xhdpi/ic_action_remove.png" /> - <resource-file src="src/android/res/drawable-xxhdpi/ic_action_remove.png" target="res/drawable-xxhdpi/ic_action_remove.png" /> - </platform> - - <!-- ubuntu --> - <platform name="ubuntu"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <header-file src="src/ubuntu/inappbrowser.h" /> - <source-file src="src/ubuntu/inappbrowser.cpp" /> - <resource-file src="src/ubuntu/InAppBrowser.qml" /> - <resource-file src="src/ubuntu/InAppBrowser_escapeScript.js" /> - <resource-file src="src/ubuntu/close.png" /> - </platform> - - <!-- ios --> - <platform name="ios"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <config-file target="config.xml" parent="/*"> - <feature name="InAppBrowser"> - <param name="ios-package" value="CDVInAppBrowser" /> - </feature> - </config-file> - - <header-file src="src/ios/CDVInAppBrowser.h" /> - <source-file src="src/ios/CDVInAppBrowser.m" /> - - <framework src="CoreGraphics.framework" /> - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_NETWORKING"/> - </config-file> - - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <config-file target="config.xml" parent="/*"> - <feature name="InAppBrowser"> - <param name="wp-package" value="InAppBrowser"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_NETWORKING" /> - </config-file> - - <source-file src="src/wp/InAppBrowser.cs" /> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_NETWORKING"/> - </config-file> - - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <config-file target="config.xml" parent="/*"> - <feature name="InAppBrowser"> - <param name="wp-package" value="InAppBrowser"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_NETWORKING" /> - </config-file> - - <source-file src="src/wp/InAppBrowser.cs" /> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <js-module src="www/windows8/InAppBrowserProxy.js" name="InAppBrowserProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- windows universal apps (Windows 8.1, Windows Phone 8.1, Windows 8.0) --> - <platform name="windows"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <js-module src="src/windows/InAppBrowserProxy.js" name="InAppBrowserProxy"> - <merges target="" /> - </js-module> - <asset src="www/inappbrowser.css" target="css/inappbrowser.css" /> - </platform> - - <!-- firefoxos --> - <platform name="firefoxos"> - <config-file target="config.xml" parent="/*"> - <permission name="browser" description="Enables the app to implement a browser in an iframe." privileged="true"/> - </config-file> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <js-module src="src/firefoxos/InAppBrowserProxy.js" name="InAppBrowserProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- browser --> - <platform name="browser"> - <js-module src="www/inappbrowser.js" name="inappbrowser"> - <clobbers target="cordova.InAppBrowser.open" /> - <clobbers target="window.open" /> - </js-module> - <js-module src="src/browser/InAppBrowserProxy.js" name="InAppBrowserProxy"> - <merges target="" /> - </js-module> - </platform> -</plugin> diff --git a/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java b/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java deleted file mode 100644 index 0263ea2c..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java +++ /dev/null @@ -1,846 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.inappbrowser; - -import android.annotation.SuppressLint; -import org.apache.cordova.inappbrowser.InAppBrowserDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.InputType; -import android.util.Log; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.view.WindowManager.LayoutParams; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import com.amazon.android.webkit.AmazonWebChromeClient; -import com.amazon.android.webkit.AmazonGeolocationPermissions.Callback; -import com.amazon.android.webkit.AmazonJsPromptResult; -import com.amazon.android.webkit.AmazonWebSettings; -import com.amazon.android.webkit.AmazonWebStorage; -import com.amazon.android.webkit.AmazonWebView; -import com.amazon.android.webkit.AmazonWebViewClient; -import com.amazon.android.webkit.AmazonCookieManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.Config; -import org.apache.cordova.CordovaArgs; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.LOG; -import org.apache.cordova.PluginResult; -import org.apache.cordova.CordovaActivity; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.StringTokenizer; - -@SuppressLint("SetJavaScriptEnabled") -public class InAppBrowser extends CordovaPlugin { - - private static final String NULL = "null"; - protected static final String LOG_TAG = "InAppBrowser"; - private static final String SELF = "_self"; - private static final String SYSTEM = "_system"; - // private static final String BLANK = "_blank"; - private static final String EXIT_EVENT = "exit"; - private static final String LOCATION = "location"; - private static final String HIDDEN = "hidden"; - private static final String ZOOM = "zoom"; - private static final String LOAD_START_EVENT = "loadstart"; - private static final String LOAD_STOP_EVENT = "loadstop"; - private static final String LOAD_ERROR_EVENT = "loaderror"; - private static final String CLEAR_ALL_CACHE = "clearcache"; - private static final String CLEAR_SESSION_CACHE = "clearsessioncache"; - - private InAppBrowserDialog dialog; - private AmazonWebView inAppWebView; - private EditText edittext; - private CallbackContext callbackContext; - private boolean showLocationBar = true; - private boolean showZoomControls = true; - private boolean openWindowHidden = false; - private boolean clearAllCache= false; - private boolean clearSessionCache=false; - - /** - * Executes the request and returns PluginResult. - * - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackId The callback id used when calling back into JavaScript. - * @return A PluginResult object with a status and message. - */ - public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException { - if (action.equals("open")) { - this.callbackContext = callbackContext; - final String url = args.getString(0); - String t = args.optString(1); - if (t == null || t.equals("") || t.equals(NULL)) { - t = SELF; - } - final String target = t; - final HashMap<String, Boolean> features = parseFeature(args.optString(2)); - - Log.d(LOG_TAG, "target = " + target); - - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - String result = ""; - // SELF - if (SELF.equals(target)) { - Log.d(LOG_TAG, "in self"); - // load in webview - if (url.startsWith("file://") || url.startsWith("javascript:") - || Config.isUrlWhiteListed(url)) { - Log.d(LOG_TAG, "loading in webview"); - webView.loadUrl(url); - } - //Load the dialer - else if (url.startsWith(AmazonWebView.SCHEME_TEL)) - { - try { - Log.d(LOG_TAG, "loading in dialer"); - Intent intent = new Intent(Intent.ACTION_DIAL); - intent.setData(Uri.parse(url)); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); - } - } - // load in InAppBrowser - else { - Log.d(LOG_TAG, "loading in InAppBrowser"); - result = showWebPage(url, features); - } - } - // SYSTEM - else if (SYSTEM.equals(target)) { - Log.d(LOG_TAG, "in system"); - result = openExternal(url); - } - // BLANK - or anything else - else { - Log.d(LOG_TAG, "in blank"); - result = showWebPage(url, features); - } - - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result); - pluginResult.setKeepCallback(true); - callbackContext.sendPluginResult(pluginResult); - } - }); - } - else if (action.equals("close")) { - closeDialog(); - } - else if (action.equals("injectScriptCode")) { - String jsWrapper = null; - if (args.getBoolean(1)) { - jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId()); - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectScriptFile")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectStyleCode")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectStyleFile")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("show")) { - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - dialog.show(); - } - }); - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK); - pluginResult.setKeepCallback(true); - this.callbackContext.sendPluginResult(pluginResult); - } - else { - return false; - } - return true; - } - - /** - * Called when the view navigates. - */ - @Override - public void onReset() { - closeDialog(); - } - - /** - * Called by AccelBroker when listener is to be shut down. - * Stop listener. - */ - public void onDestroy() { - closeDialog(); - } - - /** - * Inject an object (script or style) into the InAppBrowser AmazonWebView. - * - * This is a helper method for the inject{Script|Style}{Code|File} API calls, which - * provides a consistent method for injecting JavaScript code into the document. - * - * If a wrapper string is supplied, then the source string will be JSON-encoded (adding - * quotes) and wrapped using string formatting. (The wrapper string should have a single - * '%s' marker) - * - * @param source The source object (filename or script/style text) to inject into - * the document. - * @param jsWrapper A JavaScript string to wrap the source string in, so that the object - * is properly injected, or null if the source string is JavaScript text - * which should be executed directly. - */ - private void injectDeferredObject(String source, String jsWrapper) { - final String scriptToInject; - if (jsWrapper != null) { - org.json.JSONArray jsonEsc = new org.json.JSONArray(); - jsonEsc.put(source); - String jsonRepr = jsonEsc.toString(); - String jsonSourceString = jsonRepr.substring(1, jsonRepr.length()-1); - scriptToInject = String.format(jsWrapper, jsonSourceString); - } else { - scriptToInject = source; - } - final String finalScriptToInject = scriptToInject; - this.cordova.getActivity().runOnUiThread(new Runnable() { - @SuppressLint("NewApi") - @Override - public void run() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - // This action will have the side-effect of blurring the currently focused element - inAppWebView.loadUrl("javascript:" + finalScriptToInject); - } /*else { - inAppWebView.evaluateJavascript(finalScriptToInject, null); - }*/ - } - }); - } - - /** - * Put the list of features into a hash map - * - * @param optString - * @return - */ - private HashMap<String, Boolean> parseFeature(String optString) { - if (optString.equals(NULL)) { - return null; - } else { - HashMap<String, Boolean> map = new HashMap<String, Boolean>(); - StringTokenizer features = new StringTokenizer(optString, ","); - StringTokenizer option; - while(features.hasMoreElements()) { - option = new StringTokenizer(features.nextToken(), "="); - if (option.hasMoreElements()) { - String key = option.nextToken(); - Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE; - map.put(key, value); - } - } - return map; - } - } - - /** - * Display a new browser with the specified URL. - * - * @param url The url to load. - * @param usePhoneGap Load url in PhoneGap webview - * @return "" if ok, or error message. - */ - public String openExternal(String url) { - try { - Intent intent = null; - intent = new Intent(Intent.ACTION_VIEW); - // Omitting the MIME type for file: URLs causes "No Activity found to handle Intent". - // Adding the MIME type to http: URLs causes them to not be handled by the downloader. - Uri uri = Uri.parse(url); - if ("file".equals(uri.getScheme())) { - intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri)); - } else { - intent.setData(uri); - } - this.cordova.getActivity().startActivity(intent); - return ""; - } catch (android.content.ActivityNotFoundException e) { - Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString()); - return e.toString(); - } - } - - /** - * Closes the dialog - */ - public void closeDialog() { - final AmazonWebView childView = this.inAppWebView; - // The JS protects against multiple calls, so this should happen only when - // closeDialog() is called by other native code. - if (childView == null) { - return; - } - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - childView.setWebViewClient(new AmazonWebViewClient() { - // NB: wait for about:blank before dismissing - public void onPageFinished(AmazonWebView view, String url) { - if (dialog != null) { - dialog.dismiss(); - } - } - }); - // NB: From SDK 19: "If you call methods on WebView from any thread - // other than your app's UI thread, it can cause unexpected results." - // http://developer.android.com/guide/webapps/migrating.html#Threads - childView.loadUrl("about:blank"); - } - }); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", EXIT_EVENT); - sendUpdate(obj, false); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - /** - * Checks to see if it is possible to go back one page in history, then does so. - */ - private void goBack() { - this.cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - if (InAppBrowser.this.inAppWebView.canGoBack()) { - InAppBrowser.this.inAppWebView.goBack(); - } - } - }); - } - - /** - * Checks to see if it is possible to go forward one page in history, then does so. - */ - private void goForward() { - this.cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - if (InAppBrowser.this.inAppWebView.canGoForward()) { - InAppBrowser.this.inAppWebView.goForward(); - } - } - }); - } - - /** - * Navigate to the new page - * - * @param url to load - */ - private void navigate(final String url) { - InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0); - - this.cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - if (!url.startsWith("http") && !url.startsWith("file:")) { - InAppBrowser.this.inAppWebView.loadUrl("http://" + url); - } else { - InAppBrowser.this.inAppWebView.loadUrl(url); - } - InAppBrowser.this.inAppWebView.requestFocus(); - } - }); - } - - - /** - * Should we show the location bar? - * - * @return boolean - */ - private boolean getShowLocationBar() { - return this.showLocationBar; - } - - /** - * Should we show the zoom controls? - * - * @return boolean - */ - private boolean getShowZoomControls() { - return this.showZoomControls; - } - - private InAppBrowser getInAppBrowser(){ - return this; - } - - /** - * Display a new browser with the specified URL. - * - * @param url The url to load. - * @param jsonObject - */ - public String showWebPage(final String url, HashMap<String, Boolean> features) { - // Determine if we should hide the location bar. - showLocationBar = true; - showZoomControls = true; - openWindowHidden = false; - if (features != null) { - Boolean show = features.get(LOCATION); - if (show != null) { - showLocationBar = show.booleanValue(); - } - Boolean zoom = features.get(ZOOM); - if (zoom != null) { - showZoomControls = zoom.booleanValue(); - } - Boolean hidden = features.get(HIDDEN); - if (hidden != null) { - openWindowHidden = hidden.booleanValue(); - } - Boolean cache = features.get(CLEAR_ALL_CACHE); - if (cache != null) { - clearAllCache = cache.booleanValue(); - } else { - cache = features.get(CLEAR_SESSION_CACHE); - if (cache != null) { - clearSessionCache = cache.booleanValue(); - } - } - } - - final CordovaWebView thatWebView = this.webView; - - // Create dialog in new thread - Runnable runnable = new Runnable() { - /** - * Convert our DIP units to Pixels - * - * @return int - */ - private int dpToPixels(int dipValue) { - int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, - (float) dipValue, - cordova.getActivity().getResources().getDisplayMetrics() - ); - - return value; - } - - @SuppressLint("NewApi") - public void run() { - // Let's create the main dialog - dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar); - dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog; - dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - dialog.setCancelable(true); - dialog.setInAppBroswer(getInAppBrowser()); - - // Main container layout - LinearLayout main = new LinearLayout(cordova.getActivity()); - main.setOrientation(LinearLayout.VERTICAL); - - // Toolbar layout - RelativeLayout toolbar = new RelativeLayout(cordova.getActivity()); - //Please, no more black! - toolbar.setBackgroundColor(android.graphics.Color.LTGRAY); - toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44))); - toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2)); - toolbar.setHorizontalGravity(Gravity.LEFT); - toolbar.setVerticalGravity(Gravity.TOP); - - // Action Button Container layout - RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity()); - actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - actionButtonContainer.setHorizontalGravity(Gravity.LEFT); - actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); - actionButtonContainer.setId(1); - - // Back button - Button back = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT); - back.setLayoutParams(backLayoutParams); - back.setContentDescription("Back Button"); - back.setId(2); - Resources activityRes = cordova.getActivity().getResources(); - int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName()); - Drawable backIcon = activityRes.getDrawable(backResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - back.setBackgroundDrawable(backIcon); - } - else - { - back.setBackground(backIcon); - } - - back.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - goBack(); - } - }); - - // Forward button - Button forward = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2); - forward.setLayoutParams(forwardLayoutParams); - forward.setContentDescription("Forward Button"); - forward.setId(3); - int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName()); - Drawable fwdIcon = activityRes.getDrawable(fwdResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - forward.setBackgroundDrawable(fwdIcon); - } - else - { - forward.setBackground(fwdIcon); - } - forward.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - goForward(); - } - }); - - // Edit Text Box - edittext = new EditText(cordova.getActivity()); - RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1); - textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5); - edittext.setLayoutParams(textLayoutParams); - edittext.setId(4); - edittext.setSingleLine(true); - edittext.setText(url); - edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI); - edittext.setImeOptions(EditorInfo.IME_ACTION_GO); - edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE - edittext.setOnKeyListener(new View.OnKeyListener() { - public boolean onKey(View v, int keyCode, KeyEvent event) { - // If the event is a key-down event on the "enter" button - if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { - navigate(edittext.getText().toString()); - return true; - } - return false; - } - }); - - // Close/Done button - Button close = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); - close.setLayoutParams(closeLayoutParams); - forward.setContentDescription("Close Button"); - close.setId(5); - int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName()); - Drawable closeIcon = activityRes.getDrawable(closeResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - close.setBackgroundDrawable(closeIcon); - } - else - { - close.setBackground(closeIcon); - } - close.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - closeDialog(); - } - }); - - // WebView - inAppWebView = new AmazonWebView(cordova.getActivity()); - - CordovaActivity app = (CordovaActivity) cordova.getActivity(); - cordova.getFactory().initializeWebView(inAppWebView, 0x00FF00, false, null); - - inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView)); - AmazonWebViewClient client = new InAppBrowserClient(thatWebView, edittext); - inAppWebView.setWebViewClient(client); - AmazonWebSettings settings = inAppWebView.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setJavaScriptCanOpenWindowsAutomatically(true); - settings.setBuiltInZoomControls(getShowZoomControls()); - settings.setPluginState(com.amazon.android.webkit.AmazonWebSettings.PluginState.ON); - - //Toggle whether this is enabled or not! - Bundle appSettings = cordova.getActivity().getIntent().getExtras(); - boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true); - if (enableDatabase) { - String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath(); - settings.setDatabasePath(databasePath); - settings.setDatabaseEnabled(true); - } - settings.setDomStorageEnabled(true); - - if (clearAllCache) { - AmazonCookieManager.getInstance().removeAllCookie(); - } else if (clearSessionCache) { - AmazonCookieManager.getInstance().removeSessionCookie(); - } - - inAppWebView.loadUrl(url); - inAppWebView.setId(6); - inAppWebView.getSettings().setLoadWithOverviewMode(true); - inAppWebView.getSettings().setUseWideViewPort(true); - inAppWebView.requestFocus(); - inAppWebView.requestFocusFromTouch(); - - // Add the back and forward buttons to our action button container layout - actionButtonContainer.addView(back); - actionButtonContainer.addView(forward); - - // Add the views to our toolbar - toolbar.addView(actionButtonContainer); - toolbar.addView(edittext); - toolbar.addView(close); - - // Don't add the toolbar if its been disabled - if (getShowLocationBar()) { - // Add our toolbar to our main view/layout - main.addView(toolbar); - } - - // Add our webview to our main view/layout - main.addView(inAppWebView); - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); - lp.copyFrom(dialog.getWindow().getAttributes()); - lp.width = WindowManager.LayoutParams.MATCH_PARENT; - lp.height = WindowManager.LayoutParams.MATCH_PARENT; - - dialog.setContentView(main); - dialog.show(); - dialog.getWindow().setAttributes(lp); - // the goal of openhidden is to load the url and not display it - // Show() needs to be called to cause the URL to be loaded - if(openWindowHidden) { - dialog.hide(); - } - } - }; - this.cordova.getActivity().runOnUiThread(runnable); - return ""; - } - - /** - * Create a new plugin success result and send it back to JavaScript - * - * @param obj a JSONObject contain event payload information - */ - private void sendUpdate(JSONObject obj, boolean keepCallback) { - sendUpdate(obj, keepCallback, PluginResult.Status.OK); - } - - /** - * Create a new plugin result and send it back to JavaScript - * - * @param obj a JSONObject contain event payload information - * @param status the status code to return to the JavaScript environment - */ - private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) { - if (callbackContext != null) { - PluginResult result = new PluginResult(status, obj); - result.setKeepCallback(keepCallback); - callbackContext.sendPluginResult(result); - if (!keepCallback) { - callbackContext = null; - } - } - } - - /** - * The webview client receives notifications about appView - */ - public class InAppBrowserClient extends AmazonWebViewClient { - EditText edittext; - CordovaWebView webView; - - /** - * Constructor. - * - * @param mContext - * @param edittext - */ - public InAppBrowserClient(CordovaWebView webView, EditText mEditText) { - this.webView = webView; - this.edittext = mEditText; - } - - /** - * Notify the host application that a page has started loading. - * - * @param view The webview initiating the callback. - * @param url The url of the page. - */ - @Override - public void onPageStarted(AmazonWebView view, String url, Bitmap favicon) { - super.onPageStarted(view, url, favicon); - String newloc = ""; - if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) { - newloc = url; - } - // If dialing phone (tel:5551212) - else if (url.startsWith(AmazonWebView.SCHEME_TEL)) { - try { - Intent intent = new Intent(Intent.ACTION_DIAL); - intent.setData(Uri.parse(url)); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); - } - } - - else if (url.startsWith("geo:") || url.startsWith(AmazonWebView.SCHEME_MAILTO) || url.startsWith("market:")) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString()); - } - } - // If sms:5551212?body=This is the message - else if (url.startsWith("sms:")) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - - // Get address - String address = null; - int parmIndex = url.indexOf('?'); - if (parmIndex == -1) { - address = url.substring(4); - } - else { - address = url.substring(4, parmIndex); - - // If body, then set sms body - Uri uri = Uri.parse(url); - String query = uri.getQuery(); - if (query != null) { - if (query.startsWith("body=")) { - intent.putExtra("sms_body", query.substring(5)); - } - } - } - intent.setData(Uri.parse("sms:" + address)); - intent.putExtra("address", address); - intent.setType("vnd.android-dir/mms-sms"); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString()); - } - } - else { - newloc = "http://" + url; - } - - if (!newloc.equals(edittext.getText().toString())) { - edittext.setText(newloc); - } - - try { - JSONObject obj = new JSONObject(); - obj.put("type", LOAD_START_EVENT); - obj.put("url", newloc); - - sendUpdate(obj, true); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - - public void onPageFinished(AmazonWebView view, String url) { - super.onPageFinished(view, url); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", LOAD_STOP_EVENT); - obj.put("url", url); - - sendUpdate(obj, true); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - - public void onReceivedError(AmazonWebView view, int errorCode, String description, String failingUrl) { - super.onReceivedError(view, errorCode, description, failingUrl); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", LOAD_ERROR_EVENT); - obj.put("url", failingUrl); - obj.put("code", errorCode); - obj.put("message", description); - - sendUpdate(obj, true, PluginResult.Status.ERROR); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - } -} diff --git a/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java b/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java deleted file mode 100644 index 37cf101f..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.inappbrowser; - -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.LOG; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; - -import com.amazon.android.webkit.AmazonWebChromeClient; -import com.amazon.android.webkit.AmazonGeolocationPermissions.Callback; -import com.amazon.android.webkit.AmazonJsPromptResult; -import com.amazon.android.webkit.AmazonWebStorage; -import com.amazon.android.webkit.AmazonWebView; -import com.amazon.android.webkit.AmazonWebViewClient; - -public class InAppChromeClient extends AmazonWebChromeClient { - - private CordovaWebView webView; - private String LOG_TAG = "InAppChromeClient"; - private long MAX_QUOTA = 100 * 1024 * 1024; - - public InAppChromeClient(CordovaWebView webView) { - super(); - this.webView = webView; - } - /** - * Handle database quota exceeded notification. - * - * @param url - * @param databaseIdentifier - * @param currentQuota - * @param estimatedSize - * @param totalUsedQuota - * @param quotaUpdater - */ - @Override - public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, - long totalUsedQuota, AmazonWebStorage.QuotaUpdater quotaUpdater) - { - LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota); - - if (estimatedSize < MAX_QUOTA) - { - //increase for 1Mb - long newQuota = estimatedSize; - LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota); - quotaUpdater.updateQuota(newQuota); - } - else - { - // Set the quota to whatever it is and force an error - // TODO: get docs on how to handle this properly - quotaUpdater.updateQuota(currentQuota); - } - } - - /** - * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin. - * - * @param origin - * @param callback - */ - @Override - public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { - super.onGeolocationPermissionsShowPrompt(origin, callback); - callback.invoke(origin, true, false); - } - - /** - * Tell the client to display a prompt dialog to the user. - * If the client returns true, WebView will assume that the client will - * handle the prompt dialog and call the appropriate JsPromptResult method. - * - * The prompt bridge provided for the InAppBrowser is capable of executing any - * oustanding callback belonging to the InAppBrowser plugin. Care has been - * taken that other callbacks cannot be triggered, and that no other code - * execution is possible. - * - * To trigger the bridge, the prompt default value should be of the form: - * - * gap-iab://<callbackId> - * - * where <callbackId> is the string id of the callback to trigger (something - * like "InAppBrowser0123456789") - * - * If present, the prompt message is expected to be a JSON-encoded value to - * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid. - * - * @param view - * @param url - * @param message - * @param defaultValue - * @param result - */ - @Override - public boolean onJsPrompt(AmazonWebView view, String url, String message, String defaultValue, AmazonJsPromptResult result) { - // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute. - if (defaultValue != null && defaultValue.startsWith("gap")) { - if(defaultValue.startsWith("gap-iab://")) { - PluginResult scriptResult; - String scriptCallbackId = defaultValue.substring(10); - if (scriptCallbackId.startsWith("InAppBrowser")) { - if(message == null || message.length() == 0) { - scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray()); - } else { - try { - scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message)); - } catch(JSONException e) { - scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage()); - } - } - this.webView.sendPluginResult(scriptResult, scriptCallbackId); - result.confirm(""); - return true; - } - } - else - { - // Anything else with a gap: prefix should get this message - LOG.w(LOG_TAG, "InAppBrowser does not support Cordova API calls: " + url + " " + defaultValue); - result.cancel(); - return true; - } - } - return false; - } - -} diff --git a/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java b/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java deleted file mode 100644 index 217e48e1..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java +++ /dev/null @@ -1,879 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.inappbrowser; - -import android.annotation.SuppressLint; -import org.apache.cordova.inappbrowser.InAppBrowserDialog; -import android.content.Context; -import android.content.Intent; -import android.provider.Browser; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.InputType; -import android.util.Log; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.view.WindowManager.LayoutParams; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.webkit.CookieManager; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.Button; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.Config; -import org.apache.cordova.CordovaArgs; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.LOG; -import org.apache.cordova.PluginManager; -import org.apache.cordova.PluginResult; -import org.json.JSONException; -import org.json.JSONObject; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.StringTokenizer; - -@SuppressLint("SetJavaScriptEnabled") -public class InAppBrowser extends CordovaPlugin { - - private static final String NULL = "null"; - protected static final String LOG_TAG = "InAppBrowser"; - private static final String SELF = "_self"; - private static final String SYSTEM = "_system"; - // private static final String BLANK = "_blank"; - private static final String EXIT_EVENT = "exit"; - private static final String LOCATION = "location"; - private static final String ZOOM = "zoom"; - private static final String HIDDEN = "hidden"; - private static final String LOAD_START_EVENT = "loadstart"; - private static final String LOAD_STOP_EVENT = "loadstop"; - private static final String LOAD_ERROR_EVENT = "loaderror"; - private static final String CLEAR_ALL_CACHE = "clearcache"; - private static final String CLEAR_SESSION_CACHE = "clearsessioncache"; - private static final String HARDWARE_BACK_BUTTON = "hardwareback"; - - private InAppBrowserDialog dialog; - private WebView inAppWebView; - private EditText edittext; - private CallbackContext callbackContext; - private boolean showLocationBar = true; - private boolean showZoomControls = true; - private boolean openWindowHidden = false; - private boolean clearAllCache= false; - private boolean clearSessionCache=false; - private boolean hadwareBackButton=true; - - /** - * Executes the request and returns PluginResult. - * - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackId The callback id used when calling back into JavaScript. - * @return A PluginResult object with a status and message. - */ - public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException { - if (action.equals("open")) { - this.callbackContext = callbackContext; - final String url = args.getString(0); - String t = args.optString(1); - if (t == null || t.equals("") || t.equals(NULL)) { - t = SELF; - } - final String target = t; - final HashMap<String, Boolean> features = parseFeature(args.optString(2)); - - Log.d(LOG_TAG, "target = " + target); - - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - String result = ""; - // SELF - if (SELF.equals(target)) { - Log.d(LOG_TAG, "in self"); - /* This code exists for compatibility between 3.x and 4.x versions of Cordova. - * Previously the Config class had a static method, isUrlWhitelisted(). That - * responsibility has been moved to the plugins, with an aggregating method in - * PluginManager. - */ - Boolean shouldAllowNavigation = null; - if (url.startsWith("javascript:")) { - shouldAllowNavigation = true; - } - if (shouldAllowNavigation == null) { - try { - Method iuw = Config.class.getMethod("isUrlWhiteListed", String.class); - shouldAllowNavigation = (Boolean)iuw.invoke(null, url); - } catch (NoSuchMethodException e) { - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { - } - } - if (shouldAllowNavigation == null) { - try { - Method gpm = webView.getClass().getMethod("getPluginManager"); - PluginManager pm = (PluginManager)gpm.invoke(webView); - Method san = pm.getClass().getMethod("shouldAllowNavigation", String.class); - shouldAllowNavigation = (Boolean)san.invoke(pm, url); - } catch (NoSuchMethodException e) { - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { - } - } - // load in webview - if (Boolean.TRUE.equals(shouldAllowNavigation)) { - Log.d(LOG_TAG, "loading in webview"); - webView.loadUrl(url); - } - //Load the dialer - else if (url.startsWith(WebView.SCHEME_TEL)) - { - try { - Log.d(LOG_TAG, "loading in dialer"); - Intent intent = new Intent(Intent.ACTION_DIAL); - intent.setData(Uri.parse(url)); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); - } - } - // load in InAppBrowser - else { - Log.d(LOG_TAG, "loading in InAppBrowser"); - result = showWebPage(url, features); - } - } - // SYSTEM - else if (SYSTEM.equals(target)) { - Log.d(LOG_TAG, "in system"); - result = openExternal(url); - } - // BLANK - or anything else - else { - Log.d(LOG_TAG, "in blank"); - result = showWebPage(url, features); - } - - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result); - pluginResult.setKeepCallback(true); - callbackContext.sendPluginResult(pluginResult); - } - }); - } - else if (action.equals("close")) { - closeDialog(); - } - else if (action.equals("injectScriptCode")) { - String jsWrapper = null; - if (args.getBoolean(1)) { - jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId()); - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectScriptFile")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectStyleCode")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("injectStyleFile")) { - String jsWrapper; - if (args.getBoolean(1)) { - jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId()); - } else { - jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)"; - } - injectDeferredObject(args.getString(0), jsWrapper); - } - else if (action.equals("show")) { - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - dialog.show(); - } - }); - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK); - pluginResult.setKeepCallback(true); - this.callbackContext.sendPluginResult(pluginResult); - } - else { - return false; - } - return true; - } - - /** - * Called when the view navigates. - */ - @Override - public void onReset() { - closeDialog(); - } - - /** - * Called by AccelBroker when listener is to be shut down. - * Stop listener. - */ - public void onDestroy() { - closeDialog(); - } - - /** - * Inject an object (script or style) into the InAppBrowser WebView. - * - * This is a helper method for the inject{Script|Style}{Code|File} API calls, which - * provides a consistent method for injecting JavaScript code into the document. - * - * If a wrapper string is supplied, then the source string will be JSON-encoded (adding - * quotes) and wrapped using string formatting. (The wrapper string should have a single - * '%s' marker) - * - * @param source The source object (filename or script/style text) to inject into - * the document. - * @param jsWrapper A JavaScript string to wrap the source string in, so that the object - * is properly injected, or null if the source string is JavaScript text - * which should be executed directly. - */ - private void injectDeferredObject(String source, String jsWrapper) { - String scriptToInject; - if (jsWrapper != null) { - org.json.JSONArray jsonEsc = new org.json.JSONArray(); - jsonEsc.put(source); - String jsonRepr = jsonEsc.toString(); - String jsonSourceString = jsonRepr.substring(1, jsonRepr.length()-1); - scriptToInject = String.format(jsWrapper, jsonSourceString); - } else { - scriptToInject = source; - } - final String finalScriptToInject = scriptToInject; - this.cordova.getActivity().runOnUiThread(new Runnable() { - @SuppressLint("NewApi") - @Override - public void run() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - // This action will have the side-effect of blurring the currently focused element - inAppWebView.loadUrl("javascript:" + finalScriptToInject); - } else { - inAppWebView.evaluateJavascript(finalScriptToInject, null); - } - } - }); - } - - /** - * Put the list of features into a hash map - * - * @param optString - * @return - */ - private HashMap<String, Boolean> parseFeature(String optString) { - if (optString.equals(NULL)) { - return null; - } else { - HashMap<String, Boolean> map = new HashMap<String, Boolean>(); - StringTokenizer features = new StringTokenizer(optString, ","); - StringTokenizer option; - while(features.hasMoreElements()) { - option = new StringTokenizer(features.nextToken(), "="); - if (option.hasMoreElements()) { - String key = option.nextToken(); - Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE; - map.put(key, value); - } - } - return map; - } - } - - /** - * Display a new browser with the specified URL. - * - * @param url The url to load. - * @param usePhoneGap Load url in PhoneGap webview - * @return "" if ok, or error message. - */ - public String openExternal(String url) { - try { - Intent intent = null; - intent = new Intent(Intent.ACTION_VIEW); - // Omitting the MIME type for file: URLs causes "No Activity found to handle Intent". - // Adding the MIME type to http: URLs causes them to not be handled by the downloader. - Uri uri = Uri.parse(url); - if ("file".equals(uri.getScheme())) { - intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri)); - } else { - intent.setData(uri); - } - intent.putExtra(Browser.EXTRA_APPLICATION_ID, cordova.getActivity().getPackageName()); - this.cordova.getActivity().startActivity(intent); - return ""; - } catch (android.content.ActivityNotFoundException e) { - Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString()); - return e.toString(); - } - } - - /** - * Closes the dialog - */ - public void closeDialog() { - final WebView childView = this.inAppWebView; - // The JS protects against multiple calls, so this should happen only when - // closeDialog() is called by other native code. - if (childView == null) { - return; - } - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - childView.setWebViewClient(new WebViewClient() { - // NB: wait for about:blank before dismissing - public void onPageFinished(WebView view, String url) { - if (dialog != null) { - dialog.dismiss(); - } - } - }); - // NB: From SDK 19: "If you call methods on WebView from any thread - // other than your app's UI thread, it can cause unexpected results." - // http://developer.android.com/guide/webapps/migrating.html#Threads - childView.loadUrl("about:blank"); - } - }); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", EXIT_EVENT); - sendUpdate(obj, false); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - - /** - * Checks to see if it is possible to go back one page in history, then does so. - */ - public void goBack() { - if (this.inAppWebView.canGoBack()) { - this.inAppWebView.goBack(); - } - } - - /** - * Can the web browser go back? - * @return boolean - */ - public boolean canGoBack() { - return this.inAppWebView.canGoBack(); - } - - /** - * Has the user set the hardware back button to go back - * @return boolean - */ - public boolean hardwareBack() { - return hadwareBackButton; - } - - /** - * Checks to see if it is possible to go forward one page in history, then does so. - */ - private void goForward() { - if (this.inAppWebView.canGoForward()) { - this.inAppWebView.goForward(); - } - } - - /** - * Navigate to the new page - * - * @param url to load - */ - private void navigate(String url) { - InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0); - - if (!url.startsWith("http") && !url.startsWith("file:")) { - this.inAppWebView.loadUrl("http://" + url); - } else { - this.inAppWebView.loadUrl(url); - } - this.inAppWebView.requestFocus(); - } - - - /** - * Should we show the location bar? - * - * @return boolean - */ - private boolean getShowLocationBar() { - return this.showLocationBar; - } - - /** - * Should we show the zoom controls? - * - * @return boolean - */ - private boolean getShowZoomControls() { - return this.showZoomControls; - } - - private InAppBrowser getInAppBrowser(){ - return this; - } - - /** - * Display a new browser with the specified URL. - * - * @param url The url to load. - * @param jsonObject - */ - public String showWebPage(final String url, HashMap<String, Boolean> features) { - // Determine if we should hide the location bar. - showLocationBar = true; - showZoomControls = true; - openWindowHidden = false; - if (features != null) { - Boolean show = features.get(LOCATION); - if (show != null) { - showLocationBar = show.booleanValue(); - } - Boolean zoom = features.get(ZOOM); - if (zoom != null) { - showZoomControls = zoom.booleanValue(); - } - Boolean hidden = features.get(HIDDEN); - if (hidden != null) { - openWindowHidden = hidden.booleanValue(); - } - Boolean hardwareBack = features.get(HARDWARE_BACK_BUTTON); - if (hardwareBack != null) { - hadwareBackButton = hardwareBack.booleanValue(); - } - Boolean cache = features.get(CLEAR_ALL_CACHE); - if (cache != null) { - clearAllCache = cache.booleanValue(); - } else { - cache = features.get(CLEAR_SESSION_CACHE); - if (cache != null) { - clearSessionCache = cache.booleanValue(); - } - } - } - - final CordovaWebView thatWebView = this.webView; - - // Create dialog in new thread - Runnable runnable = new Runnable() { - /** - * Convert our DIP units to Pixels - * - * @return int - */ - private int dpToPixels(int dipValue) { - int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, - (float) dipValue, - cordova.getActivity().getResources().getDisplayMetrics() - ); - - return value; - } - - @SuppressLint("NewApi") - public void run() { - // Let's create the main dialog - dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar); - dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog; - dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - dialog.setCancelable(true); - dialog.setInAppBroswer(getInAppBrowser()); - - // Main container layout - LinearLayout main = new LinearLayout(cordova.getActivity()); - main.setOrientation(LinearLayout.VERTICAL); - - // Toolbar layout - RelativeLayout toolbar = new RelativeLayout(cordova.getActivity()); - //Please, no more black! - toolbar.setBackgroundColor(android.graphics.Color.LTGRAY); - toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44))); - toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2)); - toolbar.setHorizontalGravity(Gravity.LEFT); - toolbar.setVerticalGravity(Gravity.TOP); - - // Action Button Container layout - RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity()); - actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - actionButtonContainer.setHorizontalGravity(Gravity.LEFT); - actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); - actionButtonContainer.setId(1); - - // Back button - Button back = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT); - back.setLayoutParams(backLayoutParams); - back.setContentDescription("Back Button"); - back.setId(2); - Resources activityRes = cordova.getActivity().getResources(); - int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName()); - Drawable backIcon = activityRes.getDrawable(backResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - back.setBackgroundDrawable(backIcon); - } - else - { - back.setBackground(backIcon); - } - back.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - goBack(); - } - }); - - // Forward button - Button forward = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2); - forward.setLayoutParams(forwardLayoutParams); - forward.setContentDescription("Forward Button"); - forward.setId(3); - int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName()); - Drawable fwdIcon = activityRes.getDrawable(fwdResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - forward.setBackgroundDrawable(fwdIcon); - } - else - { - forward.setBackground(fwdIcon); - } - forward.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - goForward(); - } - }); - - // Edit Text Box - edittext = new EditText(cordova.getActivity()); - RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1); - textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5); - edittext.setLayoutParams(textLayoutParams); - edittext.setId(4); - edittext.setSingleLine(true); - edittext.setText(url); - edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI); - edittext.setImeOptions(EditorInfo.IME_ACTION_GO); - edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE - edittext.setOnKeyListener(new View.OnKeyListener() { - public boolean onKey(View v, int keyCode, KeyEvent event) { - // If the event is a key-down event on the "enter" button - if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { - navigate(edittext.getText().toString()); - return true; - } - return false; - } - }); - - // Close/Done button - Button close = new Button(cordova.getActivity()); - RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); - close.setLayoutParams(closeLayoutParams); - forward.setContentDescription("Close Button"); - close.setId(5); - int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName()); - Drawable closeIcon = activityRes.getDrawable(closeResId); - if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) - { - close.setBackgroundDrawable(closeIcon); - } - else - { - close.setBackground(closeIcon); - } - close.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - closeDialog(); - } - }); - - // WebView - inAppWebView = new WebView(cordova.getActivity()); - inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView)); - WebViewClient client = new InAppBrowserClient(thatWebView, edittext); - inAppWebView.setWebViewClient(client); - WebSettings settings = inAppWebView.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setJavaScriptCanOpenWindowsAutomatically(true); - settings.setBuiltInZoomControls(getShowZoomControls()); - settings.setPluginState(android.webkit.WebSettings.PluginState.ON); - - //Toggle whether this is enabled or not! - Bundle appSettings = cordova.getActivity().getIntent().getExtras(); - boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true); - if (enableDatabase) { - String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath(); - settings.setDatabasePath(databasePath); - settings.setDatabaseEnabled(true); - } - settings.setDomStorageEnabled(true); - - if (clearAllCache) { - CookieManager.getInstance().removeAllCookie(); - } else if (clearSessionCache) { - CookieManager.getInstance().removeSessionCookie(); - } - - inAppWebView.loadUrl(url); - inAppWebView.setId(6); - inAppWebView.getSettings().setLoadWithOverviewMode(true); - inAppWebView.getSettings().setUseWideViewPort(true); - inAppWebView.requestFocus(); - inAppWebView.requestFocusFromTouch(); - - // Add the back and forward buttons to our action button container layout - actionButtonContainer.addView(back); - actionButtonContainer.addView(forward); - - // Add the views to our toolbar - toolbar.addView(actionButtonContainer); - toolbar.addView(edittext); - toolbar.addView(close); - - // Don't add the toolbar if its been disabled - if (getShowLocationBar()) { - // Add our toolbar to our main view/layout - main.addView(toolbar); - } - - // Add our webview to our main view/layout - main.addView(inAppWebView); - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); - lp.copyFrom(dialog.getWindow().getAttributes()); - lp.width = WindowManager.LayoutParams.MATCH_PARENT; - lp.height = WindowManager.LayoutParams.MATCH_PARENT; - - dialog.setContentView(main); - dialog.show(); - dialog.getWindow().setAttributes(lp); - // the goal of openhidden is to load the url and not display it - // Show() needs to be called to cause the URL to be loaded - if(openWindowHidden) { - dialog.hide(); - } - } - }; - this.cordova.getActivity().runOnUiThread(runnable); - return ""; - } - - /** - * Create a new plugin success result and send it back to JavaScript - * - * @param obj a JSONObject contain event payload information - */ - private void sendUpdate(JSONObject obj, boolean keepCallback) { - sendUpdate(obj, keepCallback, PluginResult.Status.OK); - } - - /** - * Create a new plugin result and send it back to JavaScript - * - * @param obj a JSONObject contain event payload information - * @param status the status code to return to the JavaScript environment - */ - private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) { - if (callbackContext != null) { - PluginResult result = new PluginResult(status, obj); - result.setKeepCallback(keepCallback); - callbackContext.sendPluginResult(result); - if (!keepCallback) { - callbackContext = null; - } - } - } - - /** - * The webview client receives notifications about appView - */ - public class InAppBrowserClient extends WebViewClient { - EditText edittext; - CordovaWebView webView; - - /** - * Constructor. - * - * @param mContext - * @param edittext - */ - public InAppBrowserClient(CordovaWebView webView, EditText mEditText) { - this.webView = webView; - this.edittext = mEditText; - } - - /** - * Notify the host application that a page has started loading. - * - * @param view The webview initiating the callback. - * @param url The url of the page. - */ - @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { - super.onPageStarted(view, url, favicon); - String newloc = ""; - if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) { - newloc = url; - } - // If dialing phone (tel:5551212) - else if (url.startsWith(WebView.SCHEME_TEL)) { - try { - Intent intent = new Intent(Intent.ACTION_DIAL); - intent.setData(Uri.parse(url)); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString()); - } - } - - else if (url.startsWith("geo:") || url.startsWith(WebView.SCHEME_MAILTO) || url.startsWith("market:")) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString()); - } - } - // If sms:5551212?body=This is the message - else if (url.startsWith("sms:")) { - try { - Intent intent = new Intent(Intent.ACTION_VIEW); - - // Get address - String address = null; - int parmIndex = url.indexOf('?'); - if (parmIndex == -1) { - address = url.substring(4); - } - else { - address = url.substring(4, parmIndex); - - // If body, then set sms body - Uri uri = Uri.parse(url); - String query = uri.getQuery(); - if (query != null) { - if (query.startsWith("body=")) { - intent.putExtra("sms_body", query.substring(5)); - } - } - } - intent.setData(Uri.parse("sms:" + address)); - intent.putExtra("address", address); - intent.setType("vnd.android-dir/mms-sms"); - cordova.getActivity().startActivity(intent); - } catch (android.content.ActivityNotFoundException e) { - LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString()); - } - } - else { - newloc = "http://" + url; - } - - if (!newloc.equals(edittext.getText().toString())) { - edittext.setText(newloc); - } - - try { - JSONObject obj = new JSONObject(); - obj.put("type", LOAD_START_EVENT); - obj.put("url", newloc); - - sendUpdate(obj, true); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - - public void onPageFinished(WebView view, String url) { - super.onPageFinished(view, url); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", LOAD_STOP_EVENT); - obj.put("url", url); - - sendUpdate(obj, true); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - - public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { - super.onReceivedError(view, errorCode, description, failingUrl); - - try { - JSONObject obj = new JSONObject(); - obj.put("type", LOAD_ERROR_EVENT); - obj.put("url", failingUrl); - obj.put("code", errorCode); - obj.put("message", description); - - sendUpdate(obj, true, PluginResult.Status.ERROR); - } catch (JSONException ex) { - Log.d(LOG_TAG, "Should never happen"); - } - } - } -} diff --git a/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java b/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java deleted file mode 100644 index d7017202..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.inappbrowser; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Created by Oliver on 22/11/2013. - */ -public class InAppBrowserDialog extends Dialog { - Context context; - InAppBrowser inAppBrowser = null; - - public InAppBrowserDialog(Context context, int theme) { - super(context, theme); - this.context = context; - } - - public void setInAppBroswer(InAppBrowser browser) { - this.inAppBrowser = browser; - } - - public void onBackPressed () { - if (this.inAppBrowser == null) { - this.dismiss(); - } else { - // better to go through the in inAppBrowser - // because it does a clean up - if (this.inAppBrowser.hardwareBack() && this.inAppBrowser.canGoBack()) { - this.inAppBrowser.goBack(); - } else { - this.inAppBrowser.closeDialog(); - } - } - } -} diff --git a/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java b/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java deleted file mode 100644 index a2145e6a..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.inappbrowser; - -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.LOG; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; - -import android.webkit.JsPromptResult; -import android.webkit.WebChromeClient; -import android.webkit.WebStorage; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.webkit.GeolocationPermissions.Callback; - -public class InAppChromeClient extends WebChromeClient { - - private CordovaWebView webView; - private String LOG_TAG = "InAppChromeClient"; - private long MAX_QUOTA = 100 * 1024 * 1024; - - public InAppChromeClient(CordovaWebView webView) { - super(); - this.webView = webView; - } - /** - * Handle database quota exceeded notification. - * - * @param url - * @param databaseIdentifier - * @param currentQuota - * @param estimatedSize - * @param totalUsedQuota - * @param quotaUpdater - */ - @Override - public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, - long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) - { - LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota); - quotaUpdater.updateQuota(MAX_QUOTA); - } - - /** - * Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin. - * - * @param origin - * @param callback - */ - @Override - public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) { - super.onGeolocationPermissionsShowPrompt(origin, callback); - callback.invoke(origin, true, false); - } - - /** - * Tell the client to display a prompt dialog to the user. - * If the client returns true, WebView will assume that the client will - * handle the prompt dialog and call the appropriate JsPromptResult method. - * - * The prompt bridge provided for the InAppBrowser is capable of executing any - * oustanding callback belonging to the InAppBrowser plugin. Care has been - * taken that other callbacks cannot be triggered, and that no other code - * execution is possible. - * - * To trigger the bridge, the prompt default value should be of the form: - * - * gap-iab://<callbackId> - * - * where <callbackId> is the string id of the callback to trigger (something - * like "InAppBrowser0123456789") - * - * If present, the prompt message is expected to be a JSON-encoded value to - * pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid. - * - * @param view - * @param url - * @param message - * @param defaultValue - * @param result - */ - @Override - public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) { - // See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute. - if (defaultValue != null && defaultValue.startsWith("gap")) { - if(defaultValue.startsWith("gap-iab://")) { - PluginResult scriptResult; - String scriptCallbackId = defaultValue.substring(10); - if (scriptCallbackId.startsWith("InAppBrowser")) { - if(message == null || message.length() == 0) { - scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray()); - } else { - try { - scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message)); - } catch(JSONException e) { - scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage()); - } - } - this.webView.sendPluginResult(scriptResult, scriptCallbackId); - result.confirm(""); - return true; - } - } - else - { - // Anything else with a gap: prefix should get this message - LOG.w(LOG_TAG, "InAppBrowser does not support Cordova API calls: " + url + " " + defaultValue); - result.cancel(); - return true; - } - } - return false; - } - -} diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index fa469d88..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index e861ecce..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index f889617e..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index 47365a30..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index 4ad2df42..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index e84853e4..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index 5f304742..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index ed8ac91d..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index 4cd0458b..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index 51479d8d..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index bc8ff124..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index 331c545b..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md b/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md deleted file mode 100644 index f0fa8607..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md +++ /dev/null @@ -1,43 +0,0 @@ -<!--- - license: 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. ---> -# BlackBerry 10 In-App-Browser Plugin - -The in app browser functionality is entirely contained within common js. There is no native implementation required. -To install this plugin, follow the [Command-line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface). - -If you are not using the Cordova Command-line Interface, follow [Using Plugman to Manage Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). -./cordova-plugin-battery-status/README.md -./cordova-plugin-camera/README.md -./cordova-plugin-console/README.md -./cordova-plugin-contacts/README.md -./cordova-plugin-device/README.md -./cordova-plugin-device-motion/README.md -./cordova-plugin-device-orientation/README.md -./cordova-plugin-device-orientation/src/blackberry10/README.md -./cordova-plugin-file/README.md -./cordova-plugin-file-transfer/README.md -./cordova-plugin-geolocation/README.md -./cordova-plugin-globalization/README.md -./cordova-plugin-inappbrowser/README.md -./cordova-plugin-inappbrowser/src/blackberry10/README.md -./cordova-plugin-media/README.md -./cordova-plugin-media-capture/README.md -./cordova-plugin-network-information/README.md -./cordova-plugin-splashscreen/README.md -./cordova-plugin-vibration/README.md diff --git a/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js deleted file mode 100644 index 33fbe476..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js +++ /dev/null @@ -1,221 +0,0 @@ -/* - * - * 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 cordova = require('cordova'), - channel = require('cordova/channel'), - urlutil = require('cordova/urlutil'); - -var browserWrap, - popup, - navigationButtonsDiv, - navigationButtonsDivInner, - backButton, - forwardButton, - closeButton; - -function attachNavigationEvents(element, callback) { - var onError = function () { - callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true}); - }; - - element.addEventListener("pageshow", function () { - callback({ type: "loadstart", url: this.contentWindow.location}, {keepCallback: true}); - }); - - element.addEventListener("load", function () { - callback({ type: "loadstop", url: this.contentWindow.location}, {keepCallback: true}); - }); - - element.addEventListener("error", onError); - element.addEventListener("abort", onError); -} - -var IAB = { - close: function (win, lose) { - if (browserWrap) { - if (win) win({ type: "exit" }); - - browserWrap.parentNode.removeChild(browserWrap); - browserWrap = null; - popup = null; - } - }, - - show: function (win, lose) { - if (browserWrap) { - browserWrap.style.display = "block"; - } - }, - - open: function (win, lose, args) { - var strUrl = args[0], - target = args[1], - features = args[2], - url; - - if (target === "_system" || target === "_self" || !target) { - window.location = strUrl; - } else { - // "_blank" or anything else - if (!browserWrap) { - browserWrap = document.createElement("div"); - browserWrap.style.position = "absolute"; - browserWrap.style.borderWidth = "40px"; - browserWrap.style.width = "calc(100% - 80px)"; - browserWrap.style.height = "calc(100% - 80px)"; - browserWrap.style.borderStyle = "solid"; - browserWrap.style.borderColor = "rgba(0,0,0,0.25)"; - - browserWrap.onclick = function () { - setTimeout(function () { - IAB.close(win); - }, 0); - }; - - document.body.appendChild(browserWrap); - } - - if (features.indexOf("hidden=yes") !== -1) { - browserWrap.style.display = "none"; - } - - popup = document.createElement("iframe"); - popup.style.borderWidth = "0px"; - popup.style.width = "100%"; - - browserWrap.appendChild(popup); - - if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) { - popup.style.height = "calc(100% - 60px)"; - - navigationButtonsDiv = document.createElement("div"); - navigationButtonsDiv.style.height = "60px"; - navigationButtonsDiv.style.backgroundColor = "#404040"; - navigationButtonsDiv.style.zIndex = "999"; - navigationButtonsDiv.onclick = function (e) { - e.cancelBubble = true; - }; - - navigationButtonsDivInner = document.createElement("div"); - navigationButtonsDivInner.style.paddingTop = "10px"; - navigationButtonsDivInner.style.height = "50px"; - navigationButtonsDivInner.style.width = "160px"; - navigationButtonsDivInner.style.margin = "0 auto"; - navigationButtonsDivInner.style.backgroundColor = "#404040"; - navigationButtonsDivInner.style.zIndex = "999"; - navigationButtonsDivInner.onclick = function (e) { - e.cancelBubble = true; - }; - - - backButton = document.createElement("button"); - backButton.style.width = "40px"; - backButton.style.height = "40px"; - backButton.style.borderRadius = "40px"; - - backButton.innerHTML = "←"; - backButton.addEventListener("click", function (e) { - if (popup.canGoBack) - popup.goBack(); - }); - - forwardButton = document.createElement("button"); - forwardButton.style.marginLeft = "20px"; - forwardButton.style.width = "40px"; - forwardButton.style.height = "40px"; - forwardButton.style.borderRadius = "40px"; - - forwardButton.innerHTML = "→"; - forwardButton.addEventListener("click", function (e) { - if (popup.canGoForward) - popup.goForward(); - }); - - closeButton = document.createElement("button"); - closeButton.style.marginLeft = "20px"; - closeButton.style.width = "40px"; - closeButton.style.height = "40px"; - closeButton.style.borderRadius = "40px"; - - closeButton.innerHTML = "✖"; - closeButton.addEventListener("click", function (e) { - setTimeout(function () { - IAB.close(win); - }, 0); - }); - - // iframe navigation is not yet supported - backButton.disabled = true; - forwardButton.disabled = true; - - navigationButtonsDivInner.appendChild(backButton); - navigationButtonsDivInner.appendChild(forwardButton); - navigationButtonsDivInner.appendChild(closeButton); - navigationButtonsDiv.appendChild(navigationButtonsDivInner); - - browserWrap.appendChild(navigationButtonsDiv); - } else { - popup.style.height = "100%"; - } - - // start listening for navigation events - attachNavigationEvents(popup, win); - - popup.src = strUrl; - } - }, - - injectScriptCode: function (win, fail, args) { - var code = args[0], - hasCallback = args[1]; - - if (browserWrap && popup) { - try { - popup.contentWindow.eval(code); - hasCallback && win([]); - } catch(e) { - console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e)); - } - } - }, - - injectScriptFile: function (win, fail, args) { - var msg = 'Browser cordova-plugin-inappbrowser injectScriptFile is not yet implemented'; - console.warn(msg); - fail && fail(msg); - }, - - injectStyleCode: function (win, fail, args) { - var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented'; - console.warn(msg); - fail && fail(msg); - }, - - injectStyleFile: function (win, fail, args) { - var msg = 'Browser cordova-plugin-inappbrowser injectStyleFile is not yet implemented'; - console.warn(msg); - fail && fail(msg); - } -}; - -module.exports = IAB; - -require("cordova/exec/proxy").add("InAppBrowser", module.exports); diff --git a/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js deleted file mode 100644 index f0d44c12..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js +++ /dev/null @@ -1,191 +0,0 @@ -/* - * - * 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. - * -*/ - -// https://developer.mozilla.org/en-US/docs/WebAPI/Browser - -var cordova = require('cordova'), - channel = require('cordova/channel'), - modulemapper = require('cordova/modulemapper'); - -var origOpenFunc = modulemapper.getOriginalSymbol(window, 'window.open'); -var browserWrap; - -var IABExecs = { - - close: function (win, lose) { - if (browserWrap) { - browserWrap.parentNode.removeChild(browserWrap); - browserWrap = null; - if (typeof(win) == "function") win({type:'exit'}); - } - }, - - /* - * Reveal browser if opened hidden - */ - show: function (win, lose) { - console.error('[FirefoxOS] show not implemented'); - }, - - open: function (win, lose, args) { - var strUrl = args[0], - target = args[1], - features_string = args[2] || "location=yes", //location=yes is default - features = {}, - url, - elem; - - var features_list = features_string.split(','); - features_list.forEach(function(feature) { - var tup = feature.split('='); - if (tup[1] == 'yes') { - tup[1] = true; - } else if (tup[1] == 'no') { - tup[1] = false; - } else { - var number = parseInt(tup[1]); - if (!isNaN(number)) { - tup[1] = number; - } - } - features[tup[0]] = tup[1]; - }); - - function updateIframeSizeNoLocation() { - browserWrap.style.width = window.innerWidth + 'px'; - browserWrap.style.height = window.innerHeight + 'px'; - browserWrap.style.zIndex = '999999999'; - browserWrap.browser.style.height = (window.innerHeight - 60) + 'px'; - browserWrap.browser.style.width = browserWrap.style.width; - } - - if (target === '_system') { - origOpenFunc.apply(window, [strUrl, '_blank']); - } else if (target === '_blank') { - var browserElem = document.createElement('iframe'); - browserElem.setAttribute('mozbrowser', true); - // make this loaded in its own child process - browserElem.setAttribute('remote', true); - browserElem.setAttribute('src', strUrl); - if (browserWrap) { - document.body.removeChild(browserWrap); - } - browserWrap = document.createElement('div'); - // assign browser element to browserWrap for future reference - browserWrap.browser = browserElem; - - browserWrap.classList.add('inAppBrowserWrap'); - // position fixed so that it works even when page is scrolled - browserWrap.style.position = 'fixed'; - browserElem.style.position = 'absolute'; - browserElem.style.border = 0; - browserElem.style.top = '60px'; - browserElem.style.left = '0px'; - updateIframeSizeNoLocation(); - - var menu = document.createElement('menu'); - menu.setAttribute('type', 'toolbar'); - var close = document.createElement('li'); - var back = document.createElement('li'); - var forward = document.createElement('li'); - - close.appendChild(document.createTextNode('×')); - back.appendChild(document.createTextNode('<')); - forward.appendChild(document.createTextNode('>')); - - close.classList.add('inAppBrowserClose'); - back.classList.add('inAppBrowserBack'); - forward.classList.add('inAppBrowserForward'); - - function checkForwardBackward() { - var backReq = browserElem.getCanGoBack(); - backReq.onsuccess = function() { - if (this.result) { - back.classList.remove('disabled'); - } else { - back.classList.add('disabled'); - } - } - var forwardReq = browserElem.getCanGoForward(); - forwardReq.onsuccess = function() { - if (this.result) { - forward.classList.remove('disabled'); - } else { - forward.classList.add('disabled'); - } - } - }; - - browserElem.addEventListener('mozbrowserloadend', checkForwardBackward); - - close.addEventListener('click', function () { - setTimeout(function () { - IABExecs.close(win, lose); - }, 0); - }, false); - - back.addEventListener('click', function () { - browserElem.goBack(); - }, false); - - forward.addEventListener('click', function () { - browserElem.goForward(); - }, false); - - menu.appendChild(back); - menu.appendChild(forward); - menu.appendChild(close); - - browserWrap.appendChild(menu); - browserWrap.appendChild(browserElem); - document.body.appendChild(browserWrap); - - //we use mozbrowserlocationchange instead of mozbrowserloadstart to get the url - browserElem.addEventListener('mozbrowserlocationchange', function(e){ - win({ - type:'loadstart', - url : e.detail - }) - }, false); - browserElem.addEventListener('mozbrowserloadend', function(e){ - win({type:'loadstop'}) - }, false); - browserElem.addEventListener('mozbrowsererror', function(e){ - win({type:'loaderror'}) - }, false); - browserElem.addEventListener('mozbrowserclose', function(e){ - win({type:'exit'}) - }, false); - } else { - window.location = strUrl; - } - }, - injectScriptCode: function (code, bCB) { - console.error('[FirefoxOS] injectScriptCode not implemented'); - }, - injectScriptFile: function (file, bCB) { - console.error('[FirefoxOS] injectScriptFile not implemented'); - } -}; - -module.exports = IABExecs; - -require('cordova/exec/proxy').add('InAppBrowser', module.exports); diff --git a/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h b/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h deleted file mode 100644 index 1ccc7b14..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> -#import <Cordova/CDVInvokedUrlCommand.h> -#import <Cordova/CDVScreenOrientationDelegate.h> - -#ifdef __CORDOVA_4_0_0 - #import <Cordova/CDVUIWebViewDelegate.h> -#else - #import <Cordova/CDVWebViewDelegate.h> -#endif - -@class CDVInAppBrowserViewController; - -@interface CDVInAppBrowser : CDVPlugin { - BOOL _injectedIframeBridge; -} - -@property (nonatomic, retain) CDVInAppBrowserViewController* inAppBrowserViewController; -@property (nonatomic, copy) NSString* callbackId; -@property (nonatomic, copy) NSRegularExpression *callbackIdPattern; - -- (void)open:(CDVInvokedUrlCommand*)command; -- (void)close:(CDVInvokedUrlCommand*)command; -- (void)injectScriptCode:(CDVInvokedUrlCommand*)command; -- (void)show:(CDVInvokedUrlCommand*)command; - -@end - -@interface CDVInAppBrowserOptions : NSObject {} - -@property (nonatomic, assign) BOOL location; -@property (nonatomic, assign) BOOL toolbar; -@property (nonatomic, copy) NSString* closebuttoncaption; -@property (nonatomic, copy) NSString* toolbarposition; -@property (nonatomic, assign) BOOL clearcache; -@property (nonatomic, assign) BOOL clearsessioncache; - -@property (nonatomic, copy) NSString* presentationstyle; -@property (nonatomic, copy) NSString* transitionstyle; - -@property (nonatomic, assign) BOOL enableviewportscale; -@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction; -@property (nonatomic, assign) BOOL allowinlinemediaplayback; -@property (nonatomic, assign) BOOL keyboarddisplayrequiresuseraction; -@property (nonatomic, assign) BOOL suppressesincrementalrendering; -@property (nonatomic, assign) BOOL hidden; -@property (nonatomic, assign) BOOL disallowoverscroll; - -+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options; - -@end - -@interface CDVInAppBrowserViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate>{ - @private - NSString* _userAgent; - NSString* _prevUserAgent; - NSInteger _userAgentLockToken; - CDVInAppBrowserOptions *_browserOptions; - -#ifdef __CORDOVA_4_0_0 - CDVUIWebViewDelegate* _webViewDelegate; -#else - CDVWebViewDelegate* _webViewDelegate; -#endif - -} - -@property (nonatomic, strong) IBOutlet UIWebView* webView; -@property (nonatomic, strong) IBOutlet UIBarButtonItem* closeButton; -@property (nonatomic, strong) IBOutlet UILabel* addressLabel; -@property (nonatomic, strong) IBOutlet UIBarButtonItem* backButton; -@property (nonatomic, strong) IBOutlet UIBarButtonItem* forwardButton; -@property (nonatomic, strong) IBOutlet UIActivityIndicatorView* spinner; -@property (nonatomic, strong) IBOutlet UIToolbar* toolbar; - -@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate; -@property (nonatomic, weak) CDVInAppBrowser* navigationDelegate; -@property (nonatomic) NSURL* currentURL; - -- (void)close; -- (void)navigateTo:(NSURL*)url; -- (void)showLocationBar:(BOOL)show; -- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition; -- (void)setCloseButtonTitle:(NSString*)title; - -- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions; - -@end - -@interface CDVInAppBrowserNavigationController : UINavigationController - -@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate; - -@end - diff --git a/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m b/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m deleted file mode 100644 index 24f56c49..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m +++ /dev/null @@ -1,1022 +0,0 @@ -/* - 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 "CDVInAppBrowser.h" -#import <Cordova/CDVPluginResult.h> -#import <Cordova/CDVUserAgentUtil.h> - -#define kInAppBrowserTargetSelf @"_self" -#define kInAppBrowserTargetSystem @"_system" -#define kInAppBrowserTargetBlank @"_blank" - -#define kInAppBrowserToolbarBarPositionBottom @"bottom" -#define kInAppBrowserToolbarBarPositionTop @"top" - -#define TOOLBAR_HEIGHT 44.0 -#define LOCATIONBAR_HEIGHT 21.0 -#define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT)) - -#pragma mark CDVInAppBrowser - -@interface CDVInAppBrowser () { - NSInteger _previousStatusBarStyle; -} -@end - -@implementation CDVInAppBrowser - -- (void)pluginInitialize -{ - _previousStatusBarStyle = -1; - _callbackIdPattern = nil; -} - -- (void)onReset -{ - [self close:nil]; -} - -- (void)close:(CDVInvokedUrlCommand*)command -{ - if (self.inAppBrowserViewController == nil) { - NSLog(@"IAB.close() called but it was already closed."); - return; - } - // Things are cleaned up in browserExit. - [self.inAppBrowserViewController close]; -} - -- (BOOL) isSystemUrl:(NSURL*)url -{ - if ([[url host] isEqualToString:@"itunes.apple.com"]) { - return YES; - } - - return NO; -} - -- (void)open:(CDVInvokedUrlCommand*)command -{ - CDVPluginResult* pluginResult; - - NSString* url = [command argumentAtIndex:0]; - NSString* target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf]; - NSString* options = [command argumentAtIndex:2 withDefault:@"" andClass:[NSString class]]; - - self.callbackId = command.callbackId; - - if (url != nil) { -#ifdef __CORDOVA_4_0_0 - NSURL* baseUrl = [self.webViewEngine URL]; -#else - NSURL* baseUrl = [self.webView.request URL]; -#endif - NSURL* absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL]; - - if ([self isSystemUrl:absoluteUrl]) { - target = kInAppBrowserTargetSystem; - } - - if ([target isEqualToString:kInAppBrowserTargetSelf]) { - [self openInCordovaWebView:absoluteUrl withOptions:options]; - } else if ([target isEqualToString:kInAppBrowserTargetSystem]) { - [self openInSystem:absoluteUrl]; - } else { // _blank or anything else - [self openInInAppBrowser:absoluteUrl withOptions:options]; - } - - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"incorrect number of arguments"]; - } - - [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options -{ - CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options]; - - if (browserOptions.clearcache) { - NSHTTPCookie *cookie; - NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - for (cookie in [storage cookies]) - { - if (![cookie.domain isEqual: @".^filecookies^"]) { - [storage deleteCookie:cookie]; - } - } - } - - if (browserOptions.clearsessioncache) { - NSHTTPCookie *cookie; - NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - for (cookie in [storage cookies]) - { - if (![cookie.domain isEqual: @".^filecookies^"] && cookie.isSessionOnly) { - [storage deleteCookie:cookie]; - } - } - } - - if (self.inAppBrowserViewController == nil) { - NSString* originalUA = [CDVUserAgentUtil originalUserAgent]; - self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:originalUA prevUserAgent:[self.commandDelegate userAgent] browserOptions: browserOptions]; - self.inAppBrowserViewController.navigationDelegate = self; - - if ([self.viewController conformsToProtocol:@protocol(CDVScreenOrientationDelegate)]) { - self.inAppBrowserViewController.orientationDelegate = (UIViewController <CDVScreenOrientationDelegate>*)self.viewController; - } - } - - [self.inAppBrowserViewController showLocationBar:browserOptions.location]; - [self.inAppBrowserViewController showToolBar:browserOptions.toolbar :browserOptions.toolbarposition]; - if (browserOptions.closebuttoncaption != nil) { - [self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption]; - } - // Set Presentation Style - UIModalPresentationStyle presentationStyle = UIModalPresentationFullScreen; // default - if (browserOptions.presentationstyle != nil) { - if ([[browserOptions.presentationstyle lowercaseString] isEqualToString:@"pagesheet"]) { - presentationStyle = UIModalPresentationPageSheet; - } else if ([[browserOptions.presentationstyle lowercaseString] isEqualToString:@"formsheet"]) { - presentationStyle = UIModalPresentationFormSheet; - } - } - self.inAppBrowserViewController.modalPresentationStyle = presentationStyle; - - // Set Transition Style - UIModalTransitionStyle transitionStyle = UIModalTransitionStyleCoverVertical; // default - if (browserOptions.transitionstyle != nil) { - if ([[browserOptions.transitionstyle lowercaseString] isEqualToString:@"fliphorizontal"]) { - transitionStyle = UIModalTransitionStyleFlipHorizontal; - } else if ([[browserOptions.transitionstyle lowercaseString] isEqualToString:@"crossdissolve"]) { - transitionStyle = UIModalTransitionStyleCrossDissolve; - } - } - self.inAppBrowserViewController.modalTransitionStyle = transitionStyle; - - // prevent webView from bouncing - if (browserOptions.disallowoverscroll) { - if ([self.inAppBrowserViewController.webView respondsToSelector:@selector(scrollView)]) { - ((UIScrollView*)[self.inAppBrowserViewController.webView scrollView]).bounces = NO; - } else { - for (id subview in self.inAppBrowserViewController.webView.subviews) { - if ([[subview class] isSubclassOfClass:[UIScrollView class]]) { - ((UIScrollView*)subview).bounces = NO; - } - } - } - } - - // UIWebView options - self.inAppBrowserViewController.webView.scalesPageToFit = browserOptions.enableviewportscale; - self.inAppBrowserViewController.webView.mediaPlaybackRequiresUserAction = browserOptions.mediaplaybackrequiresuseraction; - self.inAppBrowserViewController.webView.allowsInlineMediaPlayback = browserOptions.allowinlinemediaplayback; - if (IsAtLeastiOSVersion(@"6.0")) { - self.inAppBrowserViewController.webView.keyboardDisplayRequiresUserAction = browserOptions.keyboarddisplayrequiresuseraction; - self.inAppBrowserViewController.webView.suppressesIncrementalRendering = browserOptions.suppressesincrementalrendering; - } - - [self.inAppBrowserViewController navigateTo:url]; - if (!browserOptions.hidden) { - [self show:nil]; - } -} - -- (void)show:(CDVInvokedUrlCommand*)command -{ - if (self.inAppBrowserViewController == nil) { - NSLog(@"Tried to show IAB after it was closed."); - return; - } - if (_previousStatusBarStyle != -1) { - NSLog(@"Tried to show IAB while already shown"); - return; - } - - _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle; - - CDVInAppBrowserNavigationController* nav = [[CDVInAppBrowserNavigationController alloc] - initWithRootViewController:self.inAppBrowserViewController]; - nav.orientationDelegate = self.inAppBrowserViewController; - nav.navigationBarHidden = YES; - // Run later to avoid the "took a long time" log message. - dispatch_async(dispatch_get_main_queue(), ^{ - if (self.inAppBrowserViewController != nil) { - [self.viewController presentViewController:nav animated:YES completion:nil]; - } - }); -} - -- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options -{ - if ([self.commandDelegate URLIsWhitelisted:url]) { - NSURLRequest* request = [NSURLRequest requestWithURL:url]; -#ifdef __CORDOVA_4_0_0 - [self.webViewEngine loadRequest:request]; -#else - [self.webView loadRequest:request]; -#endif - } else { // this assumes the InAppBrowser can be excepted from the white-list - [self openInInAppBrowser:url withOptions:options]; - } -} - -- (void)openInSystem:(NSURL*)url -{ - if ([[UIApplication sharedApplication] canOpenURL:url]) { - [[UIApplication sharedApplication] openURL:url]; - } else { // handle any custom schemes to plugins - [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]]; - } -} - -// This is a helper method for the inject{Script|Style}{Code|File} API calls, which -// provides a consistent method for injecting JavaScript code into the document. -// -// If a wrapper string is supplied, then the source string will be JSON-encoded (adding -// quotes) and wrapped using string formatting. (The wrapper string should have a single -// '%@' marker). -// -// If no wrapper is supplied, then the source string is executed directly. - -- (void)injectDeferredObject:(NSString*)source withWrapper:(NSString*)jsWrapper -{ - if (!_injectedIframeBridge) { - _injectedIframeBridge = YES; - // Create an iframe bridge in the new document to communicate with the CDVInAppBrowserViewController - [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:@"(function(d){var e = _cdvIframeBridge = d.createElement('iframe');e.style.display='none';d.body.appendChild(e);})(document)"]; - } - - if (jsWrapper != nil) { - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@[source] options:0 error:nil]; - NSString* sourceArrayString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - if (sourceArrayString) { - NSString* sourceString = [sourceArrayString substringWithRange:NSMakeRange(1, [sourceArrayString length] - 2)]; - NSString* jsToInject = [NSString stringWithFormat:jsWrapper, sourceString]; - [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:jsToInject]; - } - } else { - [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:source]; - } -} - -- (void)injectScriptCode:(CDVInvokedUrlCommand*)command -{ - NSString* jsWrapper = nil; - - if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) { - jsWrapper = [NSString stringWithFormat:@"_cdvIframeBridge.src='gap-iab://%@/'+encodeURIComponent(JSON.stringify([eval(%%@)]));", command.callbackId]; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (void)injectScriptFile:(CDVInvokedUrlCommand*)command -{ - NSString* jsWrapper; - - if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) { - jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('script'); c.src = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)", command.callbackId]; - } else { - jsWrapper = @"(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)"; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (void)injectStyleCode:(CDVInvokedUrlCommand*)command -{ - NSString* jsWrapper; - - if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) { - jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('style'); c.innerHTML = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)", command.callbackId]; - } else { - jsWrapper = @"(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document)"; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (void)injectStyleFile:(CDVInvokedUrlCommand*)command -{ - NSString* jsWrapper; - - if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) { - jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)", command.callbackId]; - } else { - jsWrapper = @"(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)"; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (BOOL)isValidCallbackId:(NSString *)callbackId -{ - NSError *err = nil; - // Initialize on first use - if (self.callbackIdPattern == nil) { - self.callbackIdPattern = [NSRegularExpression regularExpressionWithPattern:@"^InAppBrowser[0-9]{1,10}$" options:0 error:&err]; - if (err != nil) { - // Couldn't initialize Regex; No is safer than Yes. - return NO; - } - } - if ([self.callbackIdPattern firstMatchInString:callbackId options:0 range:NSMakeRange(0, [callbackId length])]) { - return YES; - } - return NO; -} - -/** - * The iframe bridge provided for the InAppBrowser is capable of executing any oustanding callback belonging - * to the InAppBrowser plugin. Care has been taken that other callbacks cannot be triggered, and that no - * other code execution is possible. - * - * To trigger the bridge, the iframe (or any other resource) should attempt to load a url of the form: - * - * gap-iab://<callbackId>/<arguments> - * - * where <callbackId> is the string id of the callback to trigger (something like "InAppBrowser0123456789") - * - * If present, the path component of the special gap-iab:// url is expected to be a URL-escaped JSON-encoded - * value to pass to the callback. [NSURL path] should take care of the URL-unescaping, and a JSON_EXCEPTION - * is returned if the JSON is invalid. - */ -- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType -{ - NSURL* url = request.URL; - BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]]; - - // See if the url uses the 'gap-iab' protocol. If so, the host should be the id of a callback to execute, - // and the path, if present, should be a JSON-encoded value to pass to the callback. - if ([[url scheme] isEqualToString:@"gap-iab"]) { - NSString* scriptCallbackId = [url host]; - CDVPluginResult* pluginResult = nil; - - if ([self isValidCallbackId:scriptCallbackId]) { - NSString* scriptResult = [url path]; - NSError* __autoreleasing error = nil; - - // The message should be a JSON-encoded array of the result of the script which executed. - if ((scriptResult != nil) && ([scriptResult length] > 1)) { - scriptResult = [scriptResult substringFromIndex:1]; - NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error]; - if ((error == nil) && [decodedResult isKindOfClass:[NSArray class]]) { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:(NSArray*)decodedResult]; - } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION]; - } - } else { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:@[]]; - } - [self.commandDelegate sendPluginResult:pluginResult callbackId:scriptCallbackId]; - return NO; - } - } else if ((self.callbackId != nil) && isTopLevelNavigation) { - // Send a loadstart event for each top-level navigation (includes redirects). - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDictionary:@{@"type":@"loadstart", @"url":[url absoluteString]}]; - [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; - - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; - } - - return YES; -} - -- (void)webViewDidStartLoad:(UIWebView*)theWebView -{ - _injectedIframeBridge = NO; -} - -- (void)webViewDidFinishLoad:(UIWebView*)theWebView -{ - if (self.callbackId != nil) { - // TODO: It would be more useful to return the URL the page is actually on (e.g. if it's been redirected). - NSString* url = [self.inAppBrowserViewController.currentURL absoluteString]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDictionary:@{@"type":@"loadstop", @"url":url}]; - [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; - - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; - } -} - -- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error -{ - if (self.callbackId != nil) { - NSString* url = [self.inAppBrowserViewController.currentURL absoluteString]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR - messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInteger:error.code], @"message": error.localizedDescription}]; - [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; - - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; - } -} - -- (void)browserExit -{ - if (self.callbackId != nil) { - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDictionary:@{@"type":@"exit"}]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; - self.callbackId = nil; - } - // Set navigationDelegate to nil to ensure no callbacks are received from it. - self.inAppBrowserViewController.navigationDelegate = nil; - // Don't recycle the ViewController since it may be consuming a lot of memory. - // Also - this is required for the PDF/User-Agent bug work-around. - self.inAppBrowserViewController = nil; - - if (IsAtLeastiOSVersion(@"7.0")) { - [[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle]; - } - - _previousStatusBarStyle = -1; // this value was reset before reapplying it. caused statusbar to stay black on ios7 -} - -@end - -#pragma mark CDVInAppBrowserViewController - -@implementation CDVInAppBrowserViewController - -@synthesize currentURL; - -- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions -{ - self = [super init]; - if (self != nil) { - _userAgent = userAgent; - _prevUserAgent = prevUserAgent; - _browserOptions = browserOptions; -#ifdef __CORDOVA_4_0_0 - _webViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:self]; -#else - _webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self]; -#endif - - [self createViews]; - } - - return self; -} - -- (void)createViews -{ - // We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included - - CGRect webViewBounds = self.view.bounds; - BOOL toolbarIsAtBottom = ![_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop]; - webViewBounds.size.height -= _browserOptions.location ? FOOTER_HEIGHT : TOOLBAR_HEIGHT; - self.webView = [[UIWebView alloc] initWithFrame:webViewBounds]; - - self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); - - [self.view addSubview:self.webView]; - [self.view sendSubviewToBack:self.webView]; - - self.webView.delegate = _webViewDelegate; - self.webView.backgroundColor = [UIColor whiteColor]; - - self.webView.clearsContextBeforeDrawing = YES; - self.webView.clipsToBounds = YES; - self.webView.contentMode = UIViewContentModeScaleToFill; - self.webView.multipleTouchEnabled = YES; - self.webView.opaque = YES; - self.webView.scalesPageToFit = NO; - self.webView.userInteractionEnabled = YES; - - self.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - self.spinner.alpha = 1.000; - self.spinner.autoresizesSubviews = YES; - self.spinner.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; - self.spinner.clearsContextBeforeDrawing = NO; - self.spinner.clipsToBounds = NO; - self.spinner.contentMode = UIViewContentModeScaleToFill; - self.spinner.frame = CGRectMake(454.0, 231.0, 20.0, 20.0); - self.spinner.hidden = YES; - self.spinner.hidesWhenStopped = YES; - self.spinner.multipleTouchEnabled = NO; - self.spinner.opaque = NO; - self.spinner.userInteractionEnabled = NO; - [self.spinner stopAnimating]; - - self.closeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)]; - self.closeButton.enabled = YES; - - UIBarButtonItem* flexibleSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; - - UIBarButtonItem* fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; - fixedSpaceButton.width = 20; - - float toolbarY = toolbarIsAtBottom ? self.view.bounds.size.height - TOOLBAR_HEIGHT : 0.0; - CGRect toolbarFrame = CGRectMake(0.0, toolbarY, self.view.bounds.size.width, TOOLBAR_HEIGHT); - - self.toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame]; - self.toolbar.alpha = 1.000; - self.toolbar.autoresizesSubviews = YES; - self.toolbar.autoresizingMask = toolbarIsAtBottom ? (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin) : UIViewAutoresizingFlexibleWidth; - self.toolbar.barStyle = UIBarStyleBlackOpaque; - self.toolbar.clearsContextBeforeDrawing = NO; - self.toolbar.clipsToBounds = NO; - self.toolbar.contentMode = UIViewContentModeScaleToFill; - self.toolbar.hidden = NO; - self.toolbar.multipleTouchEnabled = NO; - self.toolbar.opaque = NO; - self.toolbar.userInteractionEnabled = YES; - - CGFloat labelInset = 5.0; - float locationBarY = toolbarIsAtBottom ? self.view.bounds.size.height - FOOTER_HEIGHT : self.view.bounds.size.height - LOCATIONBAR_HEIGHT; - - self.addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelInset, locationBarY, self.view.bounds.size.width - labelInset, LOCATIONBAR_HEIGHT)]; - self.addressLabel.adjustsFontSizeToFitWidth = NO; - self.addressLabel.alpha = 1.000; - self.addressLabel.autoresizesSubviews = YES; - self.addressLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin; - self.addressLabel.backgroundColor = [UIColor clearColor]; - self.addressLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; - self.addressLabel.clearsContextBeforeDrawing = YES; - self.addressLabel.clipsToBounds = YES; - self.addressLabel.contentMode = UIViewContentModeScaleToFill; - self.addressLabel.enabled = YES; - self.addressLabel.hidden = NO; - self.addressLabel.lineBreakMode = NSLineBreakByTruncatingTail; - - if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumScaleFactor:")]) { - [self.addressLabel setValue:@(10.0/[UIFont labelFontSize]) forKey:@"minimumScaleFactor"]; - } else if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumFontSize:")]) { - [self.addressLabel setValue:@(10.0) forKey:@"minimumFontSize"]; - } - - self.addressLabel.multipleTouchEnabled = NO; - self.addressLabel.numberOfLines = 1; - self.addressLabel.opaque = NO; - self.addressLabel.shadowOffset = CGSizeMake(0.0, -1.0); - self.addressLabel.text = NSLocalizedString(@"Loading...", nil); - self.addressLabel.textAlignment = NSTextAlignmentLeft; - self.addressLabel.textColor = [UIColor colorWithWhite:1.000 alpha:1.000]; - self.addressLabel.userInteractionEnabled = NO; - - NSString* frontArrowString = NSLocalizedString(@"►", nil); // create arrow from Unicode char - self.forwardButton = [[UIBarButtonItem alloc] initWithTitle:frontArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goForward:)]; - self.forwardButton.enabled = YES; - self.forwardButton.imageInsets = UIEdgeInsetsZero; - - NSString* backArrowString = NSLocalizedString(@"◄", nil); // create arrow from Unicode char - self.backButton = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goBack:)]; - self.backButton.enabled = YES; - self.backButton.imageInsets = UIEdgeInsetsZero; - - [self.toolbar setItems:@[self.closeButton, flexibleSpaceButton, self.backButton, fixedSpaceButton, self.forwardButton]]; - - self.view.backgroundColor = [UIColor grayColor]; - [self.view addSubview:self.toolbar]; - [self.view addSubview:self.addressLabel]; - [self.view addSubview:self.spinner]; -} - -- (void) setWebViewFrame : (CGRect) frame { - NSLog(@"Setting the WebView's frame to %@", NSStringFromCGRect(frame)); - [self.webView setFrame:frame]; -} - -- (void)setCloseButtonTitle:(NSString*)title -{ - // the advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically - // but, if you want to set this yourself, knock yourself out (we can't set the title for a system Done button, so we have to create a new one) - self.closeButton = nil; - self.closeButton = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStyleBordered target:self action:@selector(close)]; - self.closeButton.enabled = YES; - self.closeButton.tintColor = [UIColor colorWithRed:60.0 / 255.0 green:136.0 / 255.0 blue:230.0 / 255.0 alpha:1]; - - NSMutableArray* items = [self.toolbar.items mutableCopy]; - [items replaceObjectAtIndex:0 withObject:self.closeButton]; - [self.toolbar setItems:items]; -} - -- (void)showLocationBar:(BOOL)show -{ - CGRect locationbarFrame = self.addressLabel.frame; - - BOOL toolbarVisible = !self.toolbar.hidden; - - // prevent double show/hide - if (show == !(self.addressLabel.hidden)) { - return; - } - - if (show) { - self.addressLabel.hidden = NO; - - if (toolbarVisible) { - // toolBar at the bottom, leave as is - // put locationBar on top of the toolBar - - CGRect webViewBounds = self.view.bounds; - webViewBounds.size.height -= FOOTER_HEIGHT; - [self setWebViewFrame:webViewBounds]; - - locationbarFrame.origin.y = webViewBounds.size.height; - self.addressLabel.frame = locationbarFrame; - } else { - // no toolBar, so put locationBar at the bottom - - CGRect webViewBounds = self.view.bounds; - webViewBounds.size.height -= LOCATIONBAR_HEIGHT; - [self setWebViewFrame:webViewBounds]; - - locationbarFrame.origin.y = webViewBounds.size.height; - self.addressLabel.frame = locationbarFrame; - } - } else { - self.addressLabel.hidden = YES; - - if (toolbarVisible) { - // locationBar is on top of toolBar, hide locationBar - - // webView take up whole height less toolBar height - CGRect webViewBounds = self.view.bounds; - webViewBounds.size.height -= TOOLBAR_HEIGHT; - [self setWebViewFrame:webViewBounds]; - } else { - // no toolBar, expand webView to screen dimensions - [self setWebViewFrame:self.view.bounds]; - } - } -} - -- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition -{ - CGRect toolbarFrame = self.toolbar.frame; - CGRect locationbarFrame = self.addressLabel.frame; - - BOOL locationbarVisible = !self.addressLabel.hidden; - - // prevent double show/hide - if (show == !(self.toolbar.hidden)) { - return; - } - - if (show) { - self.toolbar.hidden = NO; - CGRect webViewBounds = self.view.bounds; - - if (locationbarVisible) { - // locationBar at the bottom, move locationBar up - // put toolBar at the bottom - webViewBounds.size.height -= FOOTER_HEIGHT; - locationbarFrame.origin.y = webViewBounds.size.height; - self.addressLabel.frame = locationbarFrame; - self.toolbar.frame = toolbarFrame; - } else { - // no locationBar, so put toolBar at the bottom - CGRect webViewBounds = self.view.bounds; - webViewBounds.size.height -= TOOLBAR_HEIGHT; - self.toolbar.frame = toolbarFrame; - } - - if ([toolbarPosition isEqualToString:kInAppBrowserToolbarBarPositionTop]) { - toolbarFrame.origin.y = 0; - webViewBounds.origin.y += toolbarFrame.size.height; - [self setWebViewFrame:webViewBounds]; - } else { - toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT); - } - [self setWebViewFrame:webViewBounds]; - - } else { - self.toolbar.hidden = YES; - - if (locationbarVisible) { - // locationBar is on top of toolBar, hide toolBar - // put locationBar at the bottom - - // webView take up whole height less locationBar height - CGRect webViewBounds = self.view.bounds; - webViewBounds.size.height -= LOCATIONBAR_HEIGHT; - [self setWebViewFrame:webViewBounds]; - - // move locationBar down - locationbarFrame.origin.y = webViewBounds.size.height; - self.addressLabel.frame = locationbarFrame; - } else { - // no locationBar, expand webView to screen dimensions - [self setWebViewFrame:self.view.bounds]; - } - } -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; -} - -- (void)viewDidUnload -{ - [self.webView loadHTMLString:nil baseURL:nil]; - [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; - [super viewDidUnload]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return UIStatusBarStyleDefault; -} - -- (void)close -{ - [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; - self.currentURL = nil; - - if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) { - [self.navigationDelegate browserExit]; - } - - // Run later to avoid the "took a long time" log message. - dispatch_async(dispatch_get_main_queue(), ^{ - if ([self respondsToSelector:@selector(presentingViewController)]) { - [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil]; - } else { - [[self parentViewController] dismissViewControllerAnimated:YES completion:nil]; - } - }); -} - -- (void)navigateTo:(NSURL*)url -{ - NSURLRequest* request = [NSURLRequest requestWithURL:url]; - - if (_userAgentLockToken != 0) { - [self.webView loadRequest:request]; - } else { - [CDVUserAgentUtil acquireLock:^(NSInteger lockToken) { - _userAgentLockToken = lockToken; - [CDVUserAgentUtil setUserAgent:_userAgent lockToken:lockToken]; - [self.webView loadRequest:request]; - }]; - } -} - -- (void)goBack:(id)sender -{ - [self.webView goBack]; -} - -- (void)goForward:(id)sender -{ - [self.webView goForward]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - if (IsAtLeastiOSVersion(@"7.0")) { - [[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]]; - } - [self rePositionViews]; - - [super viewWillAppear:animated]; -} - -// -// On iOS 7 the status bar is part of the view's dimensions, therefore it's height has to be taken into account. -// The height of it could be hardcoded as 20 pixels, but that would assume that the upcoming releases of iOS won't -// change that value. -// -- (float) getStatusBarOffset { - CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; - float statusBarOffset = IsAtLeastiOSVersion(@"7.0") ? MIN(statusBarFrame.size.width, statusBarFrame.size.height) : 0.0; - return statusBarOffset; -} - -- (void) rePositionViews { - if ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop]) { - [self.webView setFrame:CGRectMake(self.webView.frame.origin.x, TOOLBAR_HEIGHT, self.webView.frame.size.width, self.webView.frame.size.height)]; - [self.toolbar setFrame:CGRectMake(self.toolbar.frame.origin.x, [self getStatusBarOffset], self.toolbar.frame.size.width, self.toolbar.frame.size.height)]; - } -} - -#pragma mark UIWebViewDelegate - -- (void)webViewDidStartLoad:(UIWebView*)theWebView -{ - // loading url, start spinner, update back/forward - - self.addressLabel.text = NSLocalizedString(@"Loading...", nil); - self.backButton.enabled = theWebView.canGoBack; - self.forwardButton.enabled = theWebView.canGoForward; - - [self.spinner startAnimating]; - - return [self.navigationDelegate webViewDidStartLoad:theWebView]; -} - -- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType -{ - BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]]; - - if (isTopLevelNavigation) { - self.currentURL = request.URL; - } - return [self.navigationDelegate webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType]; -} - -- (void)webViewDidFinishLoad:(UIWebView*)theWebView -{ - // update url, stop spinner, update back/forward - - self.addressLabel.text = [self.currentURL absoluteString]; - self.backButton.enabled = theWebView.canGoBack; - self.forwardButton.enabled = theWebView.canGoForward; - - [self.spinner stopAnimating]; - - // Work around a bug where the first time a PDF is opened, all UIWebViews - // reload their User-Agent from NSUserDefaults. - // This work-around makes the following assumptions: - // 1. The app has only a single Cordova Webview. If not, then the app should - // take it upon themselves to load a PDF in the background as a part of - // their start-up flow. - // 2. That the PDF does not require any additional network requests. We change - // the user-agent here back to that of the CDVViewController, so requests - // from it must pass through its white-list. This *does* break PDFs that - // contain links to other remote PDF/websites. - // More info at https://issues.apache.org/jira/browse/CB-2225 - BOOL isPDF = [@"true" isEqualToString :[theWebView stringByEvaluatingJavaScriptFromString:@"document.body==null"]]; - if (isPDF) { - [CDVUserAgentUtil setUserAgent:_prevUserAgent lockToken:_userAgentLockToken]; - } - - [self.navigationDelegate webViewDidFinishLoad:theWebView]; -} - -- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error -{ - // log fail message, stop spinner, update back/forward - NSLog(@"webView:didFailLoadWithError - %ld: %@", (long)error.code, [error localizedDescription]); - - self.backButton.enabled = theWebView.canGoBack; - self.forwardButton.enabled = theWebView.canGoForward; - [self.spinner stopAnimating]; - - self.addressLabel.text = NSLocalizedString(@"Load Error", nil); - - [self.navigationDelegate webView:theWebView didFailLoadWithError:error]; -} - -#pragma mark CDVScreenOrientationDelegate - -- (BOOL)shouldAutorotate -{ - if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) { - return [self.orientationDelegate shouldAutorotate]; - } - return YES; -} - -- (NSUInteger)supportedInterfaceOrientations -{ - if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) { - return [self.orientationDelegate supportedInterfaceOrientations]; - } - - return 1 << UIInterfaceOrientationPortrait; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) { - return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation]; - } - - return YES; -} - -@end - -@implementation CDVInAppBrowserOptions - -- (id)init -{ - if (self = [super init]) { - // default values - self.location = YES; - self.toolbar = YES; - self.closebuttoncaption = nil; - self.toolbarposition = kInAppBrowserToolbarBarPositionBottom; - self.clearcache = NO; - self.clearsessioncache = NO; - - self.enableviewportscale = NO; - self.mediaplaybackrequiresuseraction = NO; - self.allowinlinemediaplayback = NO; - self.keyboarddisplayrequiresuseraction = YES; - self.suppressesincrementalrendering = NO; - self.hidden = NO; - self.disallowoverscroll = NO; - } - - return self; -} - -+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options -{ - CDVInAppBrowserOptions* obj = [[CDVInAppBrowserOptions alloc] init]; - - // NOTE: this parsing does not handle quotes within values - NSArray* pairs = [options componentsSeparatedByString:@","]; - - // parse keys and values, set the properties - for (NSString* pair in pairs) { - NSArray* keyvalue = [pair componentsSeparatedByString:@"="]; - - if ([keyvalue count] == 2) { - NSString* key = [[keyvalue objectAtIndex:0] lowercaseString]; - NSString* value = [keyvalue objectAtIndex:1]; - NSString* value_lc = [value lowercaseString]; - - BOOL isBoolean = [value_lc isEqualToString:@"yes"] || [value_lc isEqualToString:@"no"]; - NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init]; - [numberFormatter setAllowsFloats:YES]; - BOOL isNumber = [numberFormatter numberFromString:value_lc] != nil; - - // set the property according to the key name - if ([obj respondsToSelector:NSSelectorFromString(key)]) { - if (isNumber) { - [obj setValue:[numberFormatter numberFromString:value_lc] forKey:key]; - } else if (isBoolean) { - [obj setValue:[NSNumber numberWithBool:[value_lc isEqualToString:@"yes"]] forKey:key]; - } else { - [obj setValue:value forKey:key]; - } - } - } - } - - return obj; -} - -@end - -@implementation CDVInAppBrowserNavigationController : UINavigationController - -- (void) viewDidLoad { - - CGRect frame = [UIApplication sharedApplication].statusBarFrame; - - // simplified from: http://stackoverflow.com/a/25669695/219684 - - UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:frame]; - bgToolbar.barStyle = UIBarStyleDefault; - [self.view addSubview:bgToolbar]; - - [super viewDidLoad]; -} - - -#pragma mark CDVScreenOrientationDelegate - -- (BOOL)shouldAutorotate -{ - if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) { - return [self.orientationDelegate shouldAutorotate]; - } - return YES; -} - -- (NSUInteger)supportedInterfaceOrientations -{ - if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) { - return [self.orientationDelegate supportedInterfaceOrientations]; - } - - return 1 << UIInterfaceOrientationPortrait; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -{ - if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) { - return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation]; - } - - return YES; -} - - -@end - diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml b/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml deleted file mode 100644 index 781e8a6e..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Copyright 2013 Canonical Ltd. - * - * 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 QtQuick 2.0 -import Ubuntu.Components.Popups 0.1 -import Ubuntu.Components 0.1 -import com.canonical.Oxide 1.0 - -Rectangle { - anchors.fill: parent - id: inappbrowser - property string url1 - Rectangle { - border.color: "black" - width: parent.width - height: urlEntry.height - color: "gray" - TextInput { - id: urlEntry - width: parent.width - closeButton.width - text: url1 - activeFocusOnPress: false - } - Image { - id: closeButton - width: height - x: parent.width - width - height: parent.height - source: "close.png" - MouseArea { - anchors.fill: parent - onClicked: { - root.exec("InAppBrowser", "close", [0, 0]) - } - } - } - } - - property string usContext: "oxide://main-world/2" - - function executeJS(scId, code) { - var req = _view.rootFrame.sendMessage(usContext, "EXECUTE", {code: code}); - - req.onreply = function(response) { - var code = 'cordova.callback(' + scId + ', JSON.parse(\'' + JSON.stringify(response.result) + '\'))'; - console.warn(code); - cordova.javaScriptExecNeeded(code); - console.warn("RESP:" + JSON.stringify(response)); - }; - } - - WebView { - width: parent.width - y: urlEntry.height - height: parent.height - y - url: url1 - id: _view - onLoadingStateChanged: { - root.exec("InAppBrowser", "loadFinished", [_view.loading]) - } - context: WebContext { - id: webcontext - - userScripts: [ - UserScript { - context: usContext - emulateGreasemonkey: true - url: "InAppBrowser_escapeScript.js" - } - ] - } - } -} diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js b/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js deleted file mode 100644 index 07661bb6..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * 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. - * -*/ - -oxide.addMessageHandler("EXECUTE", function(msg) { - var code = msg.args.code; - try { - msg.reply({result: eval(code)}); - } catch(e) { - msg.error("Code threw exception: \"" + e + "\""); - } -}); diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png b/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png Binary files differdeleted file mode 100644 index 56373d1f..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp b/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp deleted file mode 100644 index c5a9e64a..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * - * Copyright 2013 Canonical Ltd. - * - * 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 <QQuickView> -#include <QQuickItem> - -#include "inappbrowser.h" -#include <cordova.h> - -Inappbrowser::Inappbrowser(Cordova *cordova): CPlugin(cordova), _eventCb(0) { -} - -const char code[] = "\ -var component; \ -function createObject() { \ - component = Qt.createComponent(%1); \ - if (component.status == Component.Ready) \ - finishCreation(); \ - else \ - component.statusChanged.connect(finishCreation); \ -} \ -function finishCreation() { \ - CordovaWrapper.global.inappbrowser = component.createObject(root, \ - {root: root, cordova: cordova, url1: %2}); \ -} \ -createObject()"; - -const char EXIT_EVENT[] = "{type: 'exit'}"; -const char LOADSTART_EVENT[] = "{type: 'loadstart'}"; -const char LOADSTOP_EVENT[] = "{type: 'loadstop'}"; -const char LOADERROR_EVENT[] = "{type: 'loaderror'}"; - -void Inappbrowser::open(int cb, int, const QString &url, const QString &, const QString &) { - assert(_eventCb == 0); - - _eventCb = cb; - - QString path = m_cordova->get_app_dir() + "/../qml/InAppBrowser.qml"; - QString qml = QString(code) - .arg(CordovaInternal::format(path)).arg(CordovaInternal::format(url)); - m_cordova->execQML(qml); -} - -void Inappbrowser::show(int, int) { - m_cordova->execQML("CordovaWrapper.global.inappbrowser.visible = true"); -} - -void Inappbrowser::close(int, int) { - m_cordova->execQML("CordovaWrapper.global.inappbrowser.destroy()"); - this->callbackWithoutRemove(_eventCb, EXIT_EVENT); - _eventCb = 0; -} - -void Inappbrowser::injectStyleFile(int scId, int ecId, const QString& src, bool b) { - QString code("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %1; d.head.appendChild(c);})(document)"); - code = code.arg(CordovaInternal::format(src)); - - injectScriptCode(scId, ecId, code, b); -} - -void Inappbrowser::injectStyleCode(int scId, int ecId, const QString& src, bool b) { - QString code("(function(d) { var c = d.createElement('style'); c.innerHTML = %1; d.body.appendChild(c); })(document)"); - code = code.arg(CordovaInternal::format(src)); - - injectScriptCode(scId, ecId, code, b); -} - -void Inappbrowser::injectScriptFile(int scId, int ecId, const QString& src, bool b) { - QString code("(function(d) { var c = d.createElement('script'); c.src = %1; d.body.appendChild(c);})(document)"); - code = code.arg(CordovaInternal::format(src)); - - injectScriptCode(scId, ecId, code, b); -} - -void Inappbrowser::injectScriptCode(int scId, int, const QString& code, bool) { - m_cordova->execQML(QString("CordovaWrapper.global.inappbrowser.executeJS(%2, %1)").arg(CordovaInternal::format(code)).arg(scId)); -} - -void Inappbrowser::loadFinished(bool status) { - if (!status) { - this->callbackWithoutRemove(_eventCb, LOADSTOP_EVENT); - } else { - this->callbackWithoutRemove(_eventCb, LOADSTART_EVENT); - } -} diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h b/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h deleted file mode 100644 index 1da4e033..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * - * Copyright 2013 Canonical Ltd. - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ -#ifndef INAPPBROWSER_H -#define INAPPBROWSER_H - -#include <QtCore> -#include <cplugin.h> - -class Inappbrowser: public CPlugin { - Q_OBJECT -public: - Inappbrowser(Cordova *cordova); - - virtual const QString fullName() override { - return Inappbrowser::fullID(); - } - - virtual const QString shortName() override { - return "InAppBrowser"; - } - - static const QString fullID() { - return "InAppBrowser"; - } - -public slots: - void open(int cb, int, const QString &url, const QString &windowName, const QString &windowFeatures); - void show(int, int); - void close(int, int); - void injectStyleFile(int cb, int, const QString&, bool); - void injectStyleCode(int cb, int, const QString&, bool); - void injectScriptFile(int cb, int, const QString&, bool); - void injectScriptCode(int cb, int, const QString&, bool); - - void loadFinished(bool status); - -private: - int _eventCb; -}; - -#endif diff --git a/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js deleted file mode 100644 index 817516e5..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js +++ /dev/null @@ -1,326 +0,0 @@ -/* - * - * 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. - * -*/ - -/*jslint sloppy:true */ -/*global Windows:true, require, document, setTimeout, window, module */ - - - -var cordova = require('cordova'), - channel = require('cordova/channel'), - urlutil = require('cordova/urlutil'); - -var browserWrap, - popup, - navigationButtonsDiv, - navigationButtonsDivInner, - backButton, - forwardButton, - closeButton, - bodyOverflowStyle; - -// x-ms-webview is available starting from Windows 8.1 (platformId is 'windows') -// http://msdn.microsoft.com/en-us/library/windows/apps/dn301831.aspx -var isWebViewAvailable = cordova.platformId == 'windows'; - -function attachNavigationEvents(element, callback) { - if (isWebViewAvailable) { - element.addEventListener("MSWebViewNavigationStarting", function (e) { - callback({ type: "loadstart", url: e.uri}, {keepCallback: true} ); - }); - - element.addEventListener("MSWebViewNavigationCompleted", function (e) { - callback({ type: e.isSuccess ? "loadstop" : "loaderror", url: e.uri}, {keepCallback: true}); - }); - - element.addEventListener("MSWebViewUnviewableContentIdentified", function (e) { - // WebView found the content to be not HTML. - // http://msdn.microsoft.com/en-us/library/windows/apps/dn609716.aspx - callback({ type: "loaderror", url: e.uri}, {keepCallback: true}); - }); - - element.addEventListener("MSWebViewContentLoading", function (e) { - if (navigationButtonsDiv) { - backButton.disabled = !popup.canGoBack; - forwardButton.disabled = !popup.canGoForward; - } - }); - } else { - var onError = function () { - callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true}); - }; - - element.addEventListener("unload", function () { - callback({ type: "loadstart", url: this.contentWindow.location}, {keepCallback: true}); - }); - - element.addEventListener("load", function () { - callback({ type: "loadstop", url: this.contentWindow.location}, {keepCallback: true}); - }); - - element.addEventListener("error", onError); - element.addEventListener("abort", onError); - } -} - -var IAB = { - close: function (win, lose) { - if (browserWrap) { - if (win) win({ type: "exit" }); - - browserWrap.parentNode.removeChild(browserWrap); - // Reset body overflow style to initial value - document.body.style.msOverflowStyle = bodyOverflowStyle; - browserWrap = null; - popup = null; - } - }, - show: function (win, lose) { - if (browserWrap) { - browserWrap.style.display = "block"; - } - }, - open: function (win, lose, args) { - var strUrl = args[0], - target = args[1], - features = args[2], - url; - - if (target === "_system") { - url = new Windows.Foundation.Uri(strUrl); - Windows.System.Launcher.launchUriAsync(url); - } else if (target === "_self" || !target) { - window.location = strUrl; - } else { - // "_blank" or anything else - if (!browserWrap) { - var browserWrapStyle = document.createElement('link'); - browserWrapStyle.rel = "stylesheet"; - browserWrapStyle.type = "text/css"; - browserWrapStyle.href = urlutil.makeAbsolute("/www/css/inappbrowser.css"); - - document.head.appendChild(browserWrapStyle); - - browserWrap = document.createElement("div"); - browserWrap.className = "inAppBrowserWrap"; - - if (features.indexOf("fullscreen=yes") > -1) { - browserWrap.classList.add("inAppBrowserWrapFullscreen"); - } - - // Save body overflow style to be able to reset it back later - bodyOverflowStyle = document.body.style.msOverflowStyle; - - browserWrap.onclick = function () { - setTimeout(function () { - IAB.close(win); - }, 0); - }; - - document.body.appendChild(browserWrap); - // Hide scrollbars for the whole body while inappbrowser's window is open - document.body.style.msOverflowStyle = "none"; - } - - if (features.indexOf("hidden=yes") !== -1) { - browserWrap.style.display = "none"; - } - - popup = document.createElement(isWebViewAvailable ? "x-ms-webview" : "iframe"); - if (popup instanceof HTMLIFrameElement) { - // For iframe we need to override bacground color of parent element here - // otherwise pages without background color set will have transparent background - popup.style.backgroundColor = "white"; - } - popup.style.borderWidth = "0px"; - popup.style.width = "100%"; - - browserWrap.appendChild(popup); - - if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) { - popup.style.height = "calc(100% - 60px)"; - - navigationButtonsDiv = document.createElement("div"); - navigationButtonsDiv.style.height = "60px"; - navigationButtonsDiv.style.backgroundColor = "#404040"; - navigationButtonsDiv.style.zIndex = "999"; - navigationButtonsDiv.onclick = function (e) { - e.cancelBubble = true; - }; - - navigationButtonsDivInner = document.createElement("div"); - navigationButtonsDivInner.style.paddingTop = "10px"; - navigationButtonsDivInner.style.height = "50px"; - navigationButtonsDivInner.style.width = "160px"; - navigationButtonsDivInner.style.margin = "0 auto"; - navigationButtonsDivInner.style.backgroundColor = "#404040"; - navigationButtonsDivInner.style.zIndex = "999"; - navigationButtonsDivInner.onclick = function (e) { - e.cancelBubble = true; - }; - - - backButton = document.createElement("button"); - backButton.style.width = "40px"; - backButton.style.height = "40px"; - backButton.style.borderRadius = "40px"; - - backButton.innerText = "<-"; - backButton.addEventListener("click", function (e) { - if (popup.canGoBack) - popup.goBack(); - }); - - forwardButton = document.createElement("button"); - forwardButton.style.marginLeft = "20px"; - forwardButton.style.width = "40px"; - forwardButton.style.height = "40px"; - forwardButton.style.borderRadius = "40px"; - - forwardButton.innerText = "->"; - forwardButton.addEventListener("click", function (e) { - if (popup.canGoForward) - popup.goForward(); - }); - - closeButton = document.createElement("button"); - closeButton.style.marginLeft = "20px"; - closeButton.style.width = "40px"; - closeButton.style.height = "40px"; - closeButton.style.borderRadius = "40px"; - - closeButton.innerText = "x"; - closeButton.addEventListener("click", function (e) { - setTimeout(function () { - IAB.close(win); - }, 0); - }); - - if (!isWebViewAvailable) { - // iframe navigation is not yet supported - backButton.disabled = true; - forwardButton.disabled = true; - } - - navigationButtonsDivInner.appendChild(backButton); - navigationButtonsDivInner.appendChild(forwardButton); - navigationButtonsDivInner.appendChild(closeButton); - navigationButtonsDiv.appendChild(navigationButtonsDivInner); - - browserWrap.appendChild(navigationButtonsDiv); - } else { - popup.style.height = "100%"; - } - - // start listening for navigation events - attachNavigationEvents(popup, win); - - if (isWebViewAvailable) { - strUrl = strUrl.replace("ms-appx://", "ms-appx-web://"); - } - popup.src = strUrl; - } - }, - - injectScriptCode: function (win, fail, args) { - var code = args[0], - hasCallback = args[1]; - - if (isWebViewAvailable && browserWrap && popup) { - var op = popup.invokeScriptAsync("eval", code); - op.oncomplete = function (e) { - var result = [e.target.result]; - hasCallback && win(result); - }; - op.onerror = function () { }; - op.start(); - } - }, - - injectScriptFile: function (win, fail, args) { - var filePath = args[0], - hasCallback = args[1]; - - if (!!filePath) { - filePath = urlutil.makeAbsolute(filePath); - } - - if (isWebViewAvailable && browserWrap && popup) { - var uri = new Windows.Foundation.Uri(filePath); - Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).done(function (file) { - Windows.Storage.FileIO.readTextAsync(file).done(function (code) { - var op = popup.invokeScriptAsync("eval", code); - op.oncomplete = function(e) { - var result = [e.target.result]; - hasCallback && win(result); - }; - op.onerror = function () { }; - op.start(); - }); - }); - } - }, - - injectStyleCode: function (win, fail, args) { - var code = args[0], - hasCallback = args[1]; - - if (isWebViewAvailable && browserWrap && popup) { - injectCSS(popup, code, hasCallback && win); - } - }, - - injectStyleFile: function (win, fail, args) { - var filePath = args[0], - hasCallback = args[1]; - - filePath = filePath && urlutil.makeAbsolute(filePath); - - if (isWebViewAvailable && browserWrap && popup) { - var uri = new Windows.Foundation.Uri(filePath); - Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) { - return Windows.Storage.FileIO.readTextAsync(file); - }).done(function (code) { - injectCSS(popup, code, hasCallback && win); - }, function () { - // no-op, just catch an error - }); - } - } -}; - -function injectCSS (webView, cssCode, callback) { - // This will automatically escape all thing that we need (quotes, slashes, etc.) - var escapedCode = JSON.stringify(cssCode); - var evalWrapper = "(function(d){var c=d.createElement('style');c.innerHTML=%s;d.head.appendChild(c);})(document)" - .replace('%s', escapedCode); - - var op = webView.invokeScriptAsync("eval", evalWrapper); - op.oncomplete = function() { - callback && callback([]); - }; - op.onerror = function () { }; - op.start(); -} - -module.exports = IAB; - -require("cordova/exec/proxy").add("InAppBrowser", module.exports); diff --git a/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs b/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs deleted file mode 100644 index ddb51227..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs +++ /dev/null @@ -1,515 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.Serialization; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using Microsoft.Phone.Controls; -using Microsoft.Phone.Shell; - -#if WP8 -using System.Threading.Tasks; -using Windows.ApplicationModel; -using Windows.Storage; -using Windows.System; - -//Use alias in case Cordova File Plugin is enabled. Then the File class will be declared in both and error will occur. -using IOFile = System.IO.File; -#else -using Microsoft.Phone.Tasks; -#endif - -namespace WPCordovaClassLib.Cordova.Commands -{ - [DataContract] - public class BrowserOptions - { - [DataMember] - public string url; - - [DataMember] - public bool isGeolocationEnabled; - } - - public class InAppBrowser : BaseCommand - { - - private static WebBrowser browser; - private static ApplicationBarIconButton backButton; - private static ApplicationBarIconButton fwdButton; - - protected ApplicationBar AppBar; - - protected bool ShowLocation {get;set;} - protected bool StartHidden {get;set;} - - protected string NavigationCallbackId { get; set; } - - public void open(string options) - { - // reset defaults on ShowLocation + StartHidden features - ShowLocation = true; - StartHidden = false; - - string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options); - string urlLoc = args[0]; - string target = args[1]; - string featString = args[2]; - this.NavigationCallbackId = args[3]; - - if (!string.IsNullOrEmpty(featString)) - { - string[] features = featString.Split(','); - foreach (string str in features) - { - try - { - string[] split = str.Split('='); - switch (split[0]) - { - case "location": - ShowLocation = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase); - break; - case "hidden": - StartHidden = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase); - break; - } - } - catch (Exception) - { - // some sort of invalid param was passed, moving on ... - } - } - } - /* - _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser - _blank - always open in the InAppBrowser - _system - always open in the system web browser - */ - switch (target) - { - case "_blank": - ShowInAppBrowser(urlLoc); - break; - case "_self": - ShowCordovaBrowser(urlLoc); - break; - case "_system": - ShowSystemBrowser(urlLoc); - break; - } - } - - public void show(string options) - { - string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - - - if (browser != null) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - browser.Visibility = Visibility.Visible; - AppBar.IsVisible = true; - }); - } - } - - public void injectScriptCode(string options) - { - string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - - bool bCallback = false; - if (bool.TryParse(args[1], out bCallback)) { }; - - string callbackId = args[2]; - - if (browser != null) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - var res = browser.InvokeScript("eval", new string[] { args[0] }); - - if (bCallback) - { - PluginResult result = new PluginResult(PluginResult.Status.OK, res.ToString()); - result.KeepCallback = false; - this.DispatchCommandResult(result); - } - - }); - } - } - - public void injectScriptFile(string options) - { - Debug.WriteLine("Error : Windows Phone cordova-plugin-inappbrowser does not currently support executeScript"); - string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - // throw new NotImplementedException("Windows Phone does not currently support 'executeScript'"); - } - - public void injectStyleCode(string options) - { - Debug.WriteLine("Error : Windows Phone cordova-plugin-inappbrowser does not currently support insertCSS"); - return; - - //string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - //bool bCallback = false; - //if (bool.TryParse(args[1], out bCallback)) { }; - - //string callbackId = args[2]; - - //if (browser != null) - //{ - //Deployment.Current.Dispatcher.BeginInvoke(() => - //{ - // if (bCallback) - // { - // string cssInsertString = "try{(function(doc){var c = '<style>body{background-color:#ffff00;}</style>'; doc.head.innerHTML += c;})(document);}catch(ex){alert('oops : ' + ex.message);}"; - // //cssInsertString = cssInsertString.Replace("_VALUE_", args[0]); - // Debug.WriteLine("cssInsertString = " + cssInsertString); - // var res = browser.InvokeScript("eval", new string[] { cssInsertString }); - // if (bCallback) - // { - // PluginResult result = new PluginResult(PluginResult.Status.OK, res.ToString()); - // result.KeepCallback = false; - // this.DispatchCommandResult(result); - // } - // } - - //}); - //} - } - - public void injectStyleFile(string options) - { - Debug.WriteLine("Error : Windows Phone cordova-plugin-inappbrowser does not currently support insertCSS"); - return; - - //string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - //throw new NotImplementedException("Windows Phone does not currently support 'insertCSS'"); - } - - private void ShowCordovaBrowser(string url) - { - Uri loc = new Uri(url, UriKind.RelativeOrAbsolute); - Deployment.Current.Dispatcher.BeginInvoke(() => - { - PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame; - if (frame != null) - { - PhoneApplicationPage page = frame.Content as PhoneApplicationPage; - if (page != null) - { - CordovaView cView = page.FindName("CordovaView") as CordovaView; - if (cView != null) - { - WebBrowser br = cView.Browser; - br.Navigate2(loc); - } - } - - } - }); - } - -#if WP8 - private async void ShowSystemBrowser(string url) - { - var pathUri = new Uri(url, UriKind.Absolute); - if (pathUri.Scheme == Uri.UriSchemeHttp || pathUri.Scheme == Uri.UriSchemeHttps) - { - await Launcher.LaunchUriAsync(pathUri); - return; - } - - var file = await GetFile(pathUri.AbsolutePath.Replace('/', Path.DirectorySeparatorChar)); - if (file != null) - { - await Launcher.LaunchFileAsync(file); - } - else - { - Debug.WriteLine("File not found."); - } - } - - private async Task<StorageFile> GetFile(string fileName) - { - //first try to get the file from the isolated storage - var localFolder = ApplicationData.Current.LocalFolder; - if (IOFile.Exists(Path.Combine(localFolder.Path, fileName))) - { - return await localFolder.GetFileAsync(fileName); - } - - //if file is not found try to get it from the xap - var filePath = Path.Combine(Package.Current.InstalledLocation.Path, fileName); - if (IOFile.Exists(filePath)) - { - return await StorageFile.GetFileFromPathAsync(filePath); - } - - return null; - } -#else - private void ShowSystemBrowser(string url) - { - WebBrowserTask webBrowserTask = new WebBrowserTask(); - webBrowserTask.Uri = new Uri(url, UriKind.Absolute); - webBrowserTask.Show(); - } -#endif - - private void ShowInAppBrowser(string url) - { - Uri loc = new Uri(url, UriKind.RelativeOrAbsolute); - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - if (browser != null) - { - //browser.IsGeolocationEnabled = opts.isGeolocationEnabled; - browser.Navigate2(loc); - } - else - { - PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame; - if (frame != null) - { - PhoneApplicationPage page = frame.Content as PhoneApplicationPage; - - string baseImageUrl = "Images/"; - - if (page != null) - { - Grid grid = page.FindName("LayoutRoot") as Grid; - if (grid != null) - { - browser = new WebBrowser(); - browser.IsScriptEnabled = true; - browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted); - - browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating); - browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed); - browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated); - browser.Navigate2(loc); - - if (StartHidden) - { - browser.Visibility = Visibility.Collapsed; - } - - //browser.IsGeolocationEnabled = opts.isGeolocationEnabled; - grid.Children.Add(browser); - } - - ApplicationBar bar = new ApplicationBar(); - bar.BackgroundColor = Colors.Gray; - bar.IsMenuEnabled = false; - - backButton = new ApplicationBarIconButton(); - backButton.Text = "Back"; - - backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative); - backButton.Click += new EventHandler(backButton_Click); - bar.Buttons.Add(backButton); - - - fwdButton = new ApplicationBarIconButton(); - fwdButton.Text = "Forward"; - fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative); - fwdButton.Click += new EventHandler(fwdButton_Click); - bar.Buttons.Add(fwdButton); - - ApplicationBarIconButton closeBtn = new ApplicationBarIconButton(); - closeBtn.Text = "Close"; - closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative); - closeBtn.Click += new EventHandler(closeBtn_Click); - bar.Buttons.Add(closeBtn); - - page.ApplicationBar = bar; - bar.IsVisible = !StartHidden; - AppBar = bar; - - page.BackKeyPress += page_BackKeyPress; - - } - - } - } - }); - } - - void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e) - { -#if WP8 - if (browser.CanGoBack) - { - browser.GoBack(); - } - else - { - close(); - } - e.Cancel = true; -#else - browser.InvokeScript("execScript", "history.back();"); -#endif - } - - void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e) - { - - } - - void fwdButton_Click(object sender, EventArgs e) - { - if (browser != null) - { - try - { -#if WP8 - browser.GoForward(); -#else - browser.InvokeScript("execScript", "history.forward();"); -#endif - } - catch (Exception) - { - - } - } - } - - void backButton_Click(object sender, EventArgs e) - { - if (browser != null) - { - try - { -#if WP8 - browser.GoBack(); -#else - browser.InvokeScript("execScript", "history.back();"); -#endif - } - catch (Exception) - { - - } - } - } - - void closeBtn_Click(object sender, EventArgs e) - { - this.close(); - } - - - public void close(string options = "") - { - if (browser != null) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame; - if (frame != null) - { - PhoneApplicationPage page = frame.Content as PhoneApplicationPage; - if (page != null) - { - Grid grid = page.FindName("LayoutRoot") as Grid; - if (grid != null) - { - grid.Children.Remove(browser); - } - page.ApplicationBar = null; - page.BackKeyPress -= page_BackKeyPress; - } - } - - browser = null; - string message = "{\"type\":\"exit\"}"; - PluginResult result = new PluginResult(PluginResult.Status.OK, message); - result.KeepCallback = false; - this.DispatchCommandResult(result, NavigationCallbackId); - }); - } - } - - void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e) - { -#if WP8 - if (browser != null) - { - backButton.IsEnabled = browser.CanGoBack; - fwdButton.IsEnabled = browser.CanGoForward; - - } -#endif - string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.OriginalString + "\"}"; - PluginResult result = new PluginResult(PluginResult.Status.OK, message); - result.KeepCallback = true; - this.DispatchCommandResult(result, NavigationCallbackId); - } - - void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e) - { - string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.OriginalString + "\"}"; - PluginResult result = new PluginResult(PluginResult.Status.ERROR, message); - result.KeepCallback = true; - this.DispatchCommandResult(result, NavigationCallbackId); - } - - void browser_Navigating(object sender, NavigatingEventArgs e) - { - string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.OriginalString + "\"}"; - PluginResult result = new PluginResult(PluginResult.Status.OK, message); - result.KeepCallback = true; - this.DispatchCommandResult(result, NavigationCallbackId); - } - - } - - internal static class WebBrowserExtensions - { - /// <summary> - /// Improved method to initiate request to the provided URI. Supports 'data:text/html' urls. - /// </summary> - /// <param name="browser">The browser instance</param> - /// <param name="uri">The requested uri</param> - internal static void Navigate2(this WebBrowser browser, Uri uri) - { - // IE10 does not support data uri so we use NavigateToString method instead - if (uri.Scheme == "data") - { - // we should remove the scheme identifier and unescape the uri - string uriString = Uri.UnescapeDataString(uri.AbsoluteUri); - // format is 'data:text/html, ...' - string html = new System.Text.RegularExpressions.Regex("^data:text/html,").Replace(uriString, ""); - browser.NavigateToString(html); - } - else - { - browser.Navigate(uri); - } - } - } -} diff --git a/plugins/cordova-plugin-inappbrowser/tests/plugin.xml b/plugins/cordova-plugin-inappbrowser/tests/plugin.xml deleted file mode 100644 index 2993fa8c..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/plugin.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-inappbrowser-tests" - version="1.0.0"> - <name>Cordova InAppBrowser Plugin Tests</name> - <license>Apache 2.0</license> - - <js-module src="tests.js" name="tests"> - </js-module> - - <asset src="resources" target="cdvtests/iab-resources" /> -</plugin> diff --git a/plugins/cordova-plugin-inappbrowser/tests/resources/inject.css b/plugins/cordova-plugin-inappbrowser/tests/resources/inject.css deleted file mode 100644 index 3f6e41c8..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/resources/inject.css +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. -*/ -#style-update-file { - display: block !important; -} diff --git a/plugins/cordova-plugin-inappbrowser/tests/resources/inject.html b/plugins/cordova-plugin-inappbrowser/tests/resources/inject.html deleted file mode 100644 index 3004b358..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/resources/inject.html +++ /dev/null @@ -1,44 +0,0 @@ -<!DOCTYPE html> -<!-- - - 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. - ---> - - -<html> - <head> - <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" /> - <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 --> - <title>Cordova Mobile Spec</title> - <link rel="stylesheet" href="../../master.css" type="text/css" media="screen" title="no title" charset="utf-8"> - </head> - <body id="stage" class="theme"> - <h1 id="header">InAppBrowser - Script / Style Injection Test</h1> - <h2 id="style-update-file" style="display:none">Style updated from file</h2> - <h2 id="style-update-literal" style="display:none">Style updated from literal</h2> - <div>User-Agent: <cite id="u-a"></cite></div> - </body> - <script> - function updateUserAgent() { - document.getElementById("u-a").textContent = navigator.userAgent; - } - updateUserAgent(); - window.setInterval(updateUserAgent, 1500); - </script> -</html> diff --git a/plugins/cordova-plugin-inappbrowser/tests/resources/inject.js b/plugins/cordova-plugin-inappbrowser/tests/resources/inject.js deleted file mode 100644 index 6f254939..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/resources/inject.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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 d = document.getElementById("header") -d.innerHTML = "Script file successfully injected"; diff --git a/plugins/cordova-plugin-inappbrowser/tests/resources/local.html b/plugins/cordova-plugin-inappbrowser/tests/resources/local.html deleted file mode 100644 index d23a7144..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/resources/local.html +++ /dev/null @@ -1,67 +0,0 @@ -<!DOCTYPE html> -<!-- - - 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. - ---> - - -<html> - <head> - <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" /> - <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 --> - <title>IAB test page</title> - <script type="text/javascript" charset="utf-8" src="../../cordova-incl.js"></script> - <script type="text/javascript" charset="utf-8"> - function onDeviceReady() { - document.getElementById("hint").textContent = "Running CordovaWebView, deviceVersion=" + device.version + ", no toolbar should be present, Back link should work, logcat should NOT have failed 'gap:' calls."; - } - document.addEventListener("deviceready", onDeviceReady, false); - </script> - <style> - body {background-color: #ffffff;} - </style> - </head> - <body id="stage" class="theme"> - <h1>Local URL</h1> - <div id="info"> - You have successfully loaded a local URL: - <script>document.write(location.href)</script> - </div> - <hr /> - <div>User-Agent = <span id="u-a"></span></div> - <hr /> - <div id="hint">Likely running inAppBrowser: Device version from Cordova=not found, Back link should not work, toolbar may be present, logcat should show failed 'gap:' calls.</div> - <hr /> - <div><a href="http://www.google.com">Visit Google</a> (whitelisted)</div> - <div><a href="http://www.yahoo.com">Visit Yahoo</a> (not whitelisted)</div> - <div><a href="http://www.stluciadance.com/prospectus_file/sample.pdf">Check out my remote PDF</a></div> - <div><a href="local.pdf">Check out my local PDF</a></div> - <p /><a href="javascript:;" onclick="history.back();">Back</a> - <p /> - <a name="anchor2"></a> - <div style="height: 1000px;border:1px solid red;">tall div with border</div> - </body> - <script> - function updateUserAgent() { - document.getElementById("u-a").textContent = navigator.userAgent; - } - updateUserAgent(); - window.setInterval(updateUserAgent, 1500); - </script> -</html> diff --git a/plugins/cordova-plugin-inappbrowser/tests/resources/local.pdf b/plugins/cordova-plugin-inappbrowser/tests/resources/local.pdf Binary files differdeleted file mode 100644 index b54f1b75..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/resources/local.pdf +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/tests/resources/video.html b/plugins/cordova-plugin-inappbrowser/tests/resources/video.html deleted file mode 100644 index 64ea3d11..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/resources/video.html +++ /dev/null @@ -1,42 +0,0 @@ -<!DOCTYPE html> -<!-- - - 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. - ---> - - -<html> - <head> - <meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" /> - <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 --> - <title>Cordova Mobile Spec</title> - - </head> - <body> - <video width=100% height=100% id="player"> - <source src="http://m.comptoir-info.com/app/beta/sample.mp4"> - <meta property="og:video:secure_url" content="http://m.comptoir-info.com/app/beta/sample.mp4"> - <meta property="og:video:type" content="video/mp4"> - </video> - <div> - <button onclick="document.getElementById('player').play()"> play </button> - <button onclick="document.getElementById('player').pause()"> pause </button> - </div> - </body> -</html> diff --git a/plugins/cordova-plugin-inappbrowser/tests/tests.js b/plugins/cordova-plugin-inappbrowser/tests/tests.js deleted file mode 100644 index a8279868..00000000 --- a/plugins/cordova-plugin-inappbrowser/tests/tests.js +++ /dev/null @@ -1,519 +0,0 @@ -/* - * - * 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 cordova = require('cordova'); -var isWindows = cordova.platformId == 'windows'; - -window.alert = window.alert || navigator.notification.alert; - -exports.defineManualTests = function (contentEl, createActionButton) { - - function doOpen(url, target, params, numExpectedRedirects, useWindowOpen) { - numExpectedRedirects = numExpectedRedirects || 0; - useWindowOpen = useWindowOpen || false; - console.log("Opening " + url); - - var counts; - var lastLoadStartURL; - var wasReset = false; - function reset() { - counts = { - 'loaderror': 0, - 'loadstart': 0, - 'loadstop': 0, - 'exit': 0 - }; - lastLoadStartURL = ''; - } - reset(); - - var iab; - var callbacks = { - loaderror: logEvent, - loadstart: logEvent, - loadstop: logEvent, - exit: logEvent - }; - if (useWindowOpen) { - console.log('Use window.open() for url'); - iab = window.open(url, target, params, callbacks); - } - else { - iab = cordova.InAppBrowser.open(url, target, params, callbacks); - } - if (!iab) { - alert('open returned ' + iab); - return; - } - - function logEvent(e) { - console.log('IAB event=' + JSON.stringify(e)); - counts[e.type]++; - // Verify that event.url gets updated on redirects. - if (e.type == 'loadstart') { - if (e.url == lastLoadStartURL) { - alert('Unexpected: loadstart fired multiple times for the same URL.'); - } - lastLoadStartURL = e.url; - } - // Verify the right number of loadstart events were fired. - if (e.type == 'loadstop' || e.type == 'loaderror') { - if (e.url != lastLoadStartURL) { - alert('Unexpected: ' + e.type + ' event.url != loadstart\'s event.url'); - } - if (numExpectedRedirects === 0 && counts['loadstart'] !== 1) { - // Do allow a loaderror without a loadstart (e.g. in the case of an invalid URL). - if (!(e.type == 'loaderror' && counts['loadstart'] === 0)) { - alert('Unexpected: got multiple loadstart events. (' + counts['loadstart'] + ')'); - } - } else if (numExpectedRedirects > 0 && counts['loadstart'] < (numExpectedRedirects + 1)) { - alert('Unexpected: should have got at least ' + (numExpectedRedirects + 1) + ' loadstart events, but got ' + counts['loadstart']); - } - wasReset = true; - numExpectedRedirects = 0; - reset(); - } - // Verify that loadend / loaderror was called. - if (e.type == 'exit') { - var numStopEvents = counts['loadstop'] + counts['loaderror']; - if (numStopEvents === 0 && !wasReset) { - alert('Unexpected: browser closed without a loadstop or loaderror.'); - } else if (numStopEvents > 1) { - alert('Unexpected: got multiple loadstop/loaderror events.'); - } - } - } - - return iab; - } - - function doHookOpen(url, target, params, numExpectedRedirects) { - var originalFunc = window.open; - var wasClobbered = window.hasOwnProperty('open'); - window.open = cordova.InAppBrowser.open; - - try { - doOpen(url, target, params, numExpectedRedirects, true); - } - finally { - if (wasClobbered) { - window.open = originalFunc; - } - else { - console.log('just delete, to restore open from prototype'); - delete window.open; - } - } - } - - function openWithStyle(url, cssUrl, useCallback) { - var iab = doOpen(url, '_blank', 'location=yes'); - var callback = function (results) { - if (results && results.length === 0) { - alert('Results verified'); - } else { - console.log(results); - alert('Got: ' + typeof (results) + '\n' + JSON.stringify(results)); - } - }; - if (cssUrl) { - iab.addEventListener('loadstop', function (event) { - iab.insertCSS({ file: cssUrl }, useCallback && callback); - }); - } else { - iab.addEventListener('loadstop', function (event) { - iab.insertCSS({ code: '#style-update-literal { \ndisplay: block !important; \n}' }, - useCallback && callback); - }); - } - } - - function openWithScript(url, jsUrl, useCallback) { - var iab = doOpen(url, '_blank', 'location=yes'); - if (jsUrl) { - iab.addEventListener('loadstop', function (event) { - iab.executeScript({ file: jsUrl }, useCallback && function (results) { - if (results && results.length === 0) { - alert('Results verified'); - } else { - console.log(results); - alert('Got: ' + typeof (results) + '\n' + JSON.stringify(results)); - } - }); - }); - } else { - iab.addEventListener('loadstop', function (event) { - var code = '(function(){\n' + - ' var header = document.getElementById("header");\n' + - ' header.innerHTML = "Script literal successfully injected";\n' + - ' return "abc";\n' + - '})()'; - iab.executeScript({ code: code }, useCallback && function (results) { - if (results && results.length === 1 && results[0] === 'abc') { - alert('Results verified'); - } else { - console.log(results); - alert('Got: ' + typeof (results) + '\n' + JSON.stringify(results)); - } - }); - }); - } - } - var hiddenwnd = null; - var loadlistener = function (event) { alert('background window loaded '); }; - function openHidden(url, startHidden) { - var shopt = (startHidden) ? 'hidden=yes' : ''; - hiddenwnd = cordova.InAppBrowser.open(url, 'random_string', shopt); - if (!hiddenwnd) { - alert('cordova.InAppBrowser.open returned ' + hiddenwnd); - return; - } - if (startHidden) hiddenwnd.addEventListener('loadstop', loadlistener); - } - function showHidden() { - if (!!hiddenwnd) { - hiddenwnd.show(); - } - } - function closeHidden() { - if (!!hiddenwnd) { - hiddenwnd.removeEventListener('loadstop', loadlistener); - hiddenwnd.close(); - hiddenwnd = null; - } - } - - var info_div = '<h1>InAppBrowser</h1>' + - '<div id="info">' + - 'Make sure http://cordova.apache.org and http://google.co.uk and https://www.google.co.uk are white listed. </br>' + - 'Make sure http://www.apple.com is not in the white list.</br>' + - 'In iOS, starred <span style="vertical-align:super">*</span> tests will put the app in a state with no way to return. </br>' + - '<h4>User-Agent: <span id="user-agent"> </span></hr>' + - '</div>'; - - var local_tests = '<h1>Local URL</h1>' + - '<div id="openLocal"></div>' + - 'Expected result: opens successfully in CordovaWebView.' + - '<p/> <div id="openLocalHook"></div>' + - 'Expected result: opens successfully in CordovaWebView (using hook of window.open()).' + - '<p/> <div id="openLocalSelf"></div>' + - 'Expected result: opens successfully in CordovaWebView.' + - '<p/> <div id="openLocalSystem"></div>' + - 'Expected result: fails to open' + - '<p/> <div id="openLocalBlank"></div>' + - 'Expected result: opens successfully in InAppBrowser with locationBar at top.' + - '<p/> <div id="openLocalRandomNoLocation"></div>' + - 'Expected result: opens successfully in InAppBrowser without locationBar.' + - '<p/> <div id="openLocalRandomToolBarBottom"></div>' + - 'Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the bottom.' + - '<p/> <div id="openLocalRandomToolBarTop"></div>' + - 'Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the top.' + - '<p/><div id="openLocalRandomToolBarTopNoLocation"></div>' + - 'Expected result: open successfully in InAppBrowser with no locationBar. On iOS the toolbar is at the top.'; - - var white_listed_tests = '<h1>White Listed URL</h1>' + - '<div id="openWhiteListed"></div>' + - 'Expected result: open successfully in CordovaWebView to cordova.apache.org' + - '<p/> <div id="openWhiteListedHook"></div>' + - 'Expected result: open successfully in CordovaWebView to cordova.apache.org (using hook of window.open())' + - '<p/> <div id="openWhiteListedSelf"></div>' + - 'Expected result: open successfully in CordovaWebView to cordova.apache.org' + - '<p/> <div id="openWhiteListedSystem"></div>' + - 'Expected result: open successfully in system browser to cordova.apache.org' + - '<p/> <div id="openWhiteListedBlank"></div>' + - 'Expected result: open successfully in InAppBrowser to cordova.apache.org' + - '<p/> <div id="openWhiteListedRandom"></div>' + - 'Expected result: open successfully in InAppBrowser to cordova.apache.org' + - '<p/> <div id="openWhiteListedRandomNoLocation"></div>' + - 'Expected result: open successfully in InAppBrowser to cordova.apache.org with no location bar.'; - - var non_white_listed_tests = '<h1>Non White Listed URL</h1>' + - '<div id="openNonWhiteListed"></div>' + - 'Expected result: open successfully in InAppBrowser to apple.com.' + - '<p/> <div id="openNonWhiteListedHook"></div>' + - 'Expected result: open successfully in InAppBrowser to apple.com (using hook of window.open()).' + - '<p/> <div id="openNonWhiteListedSelf"></div>' + - 'Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).' + - '<p/> <div id="openNonWhiteListedSystem"></div>' + - 'Expected result: open successfully in system browser to apple.com.' + - '<p/> <div id="openNonWhiteListedBlank"></div>' + - 'Expected result: open successfully in InAppBrowser to apple.com.' + - '<p/> <div id="openNonWhiteListedRandom"></div>' + - 'Expected result: open successfully in InAppBrowser to apple.com.' + - '<p/> <div id="openNonWhiteListedRandomNoLocation"></div>' + - 'Expected result: open successfully in InAppBrowser to apple.com without locationBar.'; - - var page_with_redirects_tests = '<h1>Page with redirect</h1>' + - '<div id="openRedirect301"></div>' + - 'Expected result: should 301 and open successfully in InAppBrowser to https://www.google.co.uk.' + - '<p/> <div id="openRedirect302"></div>' + - 'Expected result: should 302 and open successfully in InAppBrowser to www.zhihu.com/answer/16714076.'; - - var pdf_url_tests = '<h1>PDF URL</h1>' + - '<div id="openPDF"></div>' + - 'Expected result: InAppBrowser opens. PDF should render on iOS.' + - '<p/> <div id="openPDFBlank"></div>' + - 'Expected result: InAppBrowser opens. PDF should render on iOS.'; - - var invalid_url_tests = '<h1>Invalid URL</h1>' + - '<div id="openInvalidScheme"></div>' + - 'Expected result: fail to load in InAppBrowser.' + - '<p/> <div id="openInvalidHost"></div>' + - 'Expected result: fail to load in InAppBrowser.' + - '<p/> <div id="openInvalidMissing"></div>' + - 'Expected result: fail to load in InAppBrowser (404).'; - - var css_js_injection_tests = '<h1>CSS / JS Injection</h1>' + - '<div id="openOriginalDocument"></div>' + - 'Expected result: open successfully in InAppBrowser without text "Style updated from..."' + - '<p/> <div id="openCSSInjection"></div>' + - 'Expected result: open successfully in InAppBrowser with "Style updated from file".' + - '<p/> <div id="openCSSInjectionCallback"></div>' + - 'Expected result: open successfully in InAppBrowser with "Style updated from file", and alert dialog with text "Results verified".' + - '<p/> <div id="openCSSLiteralInjection"></div>' + - 'Expected result: open successfully in InAppBrowser with "Style updated from literal".' + - '<p/> <div id="openCSSLiteralInjectionCallback"></div>' + - 'Expected result: open successfully in InAppBrowser with "Style updated from literal", and alert dialog with text "Results verified".' + - '<p/> <div id="openScriptInjection"></div>' + - 'Expected result: open successfully in InAppBrowser with text "Script file successfully injected".' + - '<p/> <div id="openScriptInjectionCallback"></div>' + - 'Expected result: open successfully in InAppBrowser with text "Script file successfully injected" and alert dialog with the text "Results verified".' + - '<p/> <div id="openScriptLiteralInjection"></div>' + - 'Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" .' + - '<p/> <div id="openScriptLiteralInjectionCallback"></div>' + - 'Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" and alert dialog with the text "Results verified".'; - - var open_hidden_tests = '<h1>Open Hidden </h1>' + - '<div id="openHidden"></div>' + - 'Expected result: no additional browser window. Alert appears with the text "background window loaded".' + - '<p/> <div id="showHidden"></div>' + - 'Expected result: after first clicking on previous test "create hidden", open successfully in InAppBrowser to https://www.google.co.uk.' + - '<p/> <div id="closeHidden"></div>' + - 'Expected result: no output. But click on "show hidden" again and nothing should be shown.' + - '<p/> <div id="openHiddenShow"></div>' + - 'Expected result: open successfully in InAppBrowser to https://www.google.co.uk'; - - var clearing_cache_tests = '<h1>Clearing Cache</h1>' + - '<div id="openClearCache"></div>' + - 'Expected result: ?' + - '<p/> <div id="openClearSessionCache"></div>' + - 'Expected result: ?'; - - var video_tag_tests = '<h1>Video tag</h1>' + - '<div id="openRemoteVideo"></div>' + - 'Expected result: open successfully in InAppBrowser with an embedded video that works after clicking the "play" button.'; - - var local_with_anchor_tag_tests = '<h1>Local with anchor tag</h1>' + - '<div id="openAnchor1"></div>' + - 'Expected result: open successfully in InAppBrowser to the local page, scrolled to the top as normal.' + - '<p/> <div id="openAnchor2"></div>' + - 'Expected result: open successfully in InAppBrowser to the local page, scrolled to the beginning of the tall div with border.'; - - // CB-7490 We need to wrap this code due to Windows security restrictions - // see http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences for details - if (window.MSApp && window.MSApp.execUnsafeLocalFunction) { - MSApp.execUnsafeLocalFunction(function() { - contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests + - css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests; - }); - } else { - contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests + - css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests; - } - - document.getElementById("user-agent").textContent = navigator.userAgent; - - // we are already in cdvtests directory - var basePath = 'iab-resources/'; - var localhtml = basePath + 'local.html', - localpdf = basePath + 'local.pdf', - injecthtml = basePath + 'inject.html', - injectjs = isWindows ? basePath + 'inject.js' : 'inject.js', - injectcss = isWindows ? basePath + 'inject.css' : 'inject.css', - videohtml = basePath + 'video.html'; - - //Local - createActionButton('target=Default', function () { - doOpen(localhtml); - }, 'openLocal'); - createActionButton('target=Default (window.open)', function () { - doHookOpen(localhtml); - }, 'openLocalHook'); - createActionButton('target=_self', function () { - doOpen(localhtml, '_self'); - }, 'openLocalSelf'); - createActionButton('target=_system', function () { - doOpen(localhtml, '_system'); - }, 'openLocalSystem'); - createActionButton('target=_blank', function () { - doOpen(localhtml, '_blank'); - }, 'openLocalBlank'); - createActionButton('target=Random, location=no, disallowoverscroll=yes', function () { - doOpen(localhtml, 'random_string', 'location=no, disallowoverscroll=yes'); - }, 'openLocalRandomNoLocation'); - createActionButton('target=Random, toolbarposition=bottom', function () { - doOpen(localhtml, 'random_string', 'toolbarposition=bottom'); - }, 'openLocalRandomToolBarBottom'); - createActionButton('target=Random, toolbarposition=top', function () { - doOpen(localhtml, 'random_string', 'toolbarposition=top'); - }, 'openLocalRandomToolBarTop'); - createActionButton('target=Random, toolbarposition=top, location=no', function () { - doOpen(localhtml, 'random_string', 'toolbarposition=top,location=no'); - }, 'openLocalRandomToolBarTopNoLocation'); - - //White Listed - createActionButton('* target=Default', function () { - doOpen('http://cordova.apache.org'); - }, 'openWhiteListed'); - createActionButton('* target=Default (window.open)', function () { - doHookOpen('http://cordova.apache.org'); - }, 'openWhiteListedHook'); - createActionButton('* target=_self', function () { - doOpen('http://cordova.apache.org', '_self'); - }, 'openWhiteListedSelf'); - createActionButton('target=_system', function () { - doOpen('http://cordova.apache.org', '_system'); - }, 'openWhiteListedSystem'); - createActionButton('target=_blank', function () { - doOpen('http://cordova.apache.org', '_blank'); - }, 'openWhiteListedBlank'); - createActionButton('target=Random', function () { - doOpen('http://cordova.apache.org', 'random_string'); - }, 'openWhiteListedRandom'); - createActionButton('* target=Random, no location bar', function () { - doOpen('http://cordova.apache.org', 'random_string', 'location=no'); - }, 'openWhiteListedRandomNoLocation'); - - //Non White Listed - createActionButton('target=Default', function () { - doOpen('http://www.apple.com'); - }, 'openNonWhiteListed'); - createActionButton('target=Default (window.open)', function () { - doHookOpen('http://www.apple.com'); - }, 'openNonWhiteListedHook'); - createActionButton('target=_self', function () { - doOpen('http://www.apple.com', '_self'); - }, 'openNonWhiteListedSelf'); - createActionButton('target=_system', function () { - doOpen('http://www.apple.com', '_system'); - }, 'openNonWhiteListedSystem'); - createActionButton('target=_blank', function () { - doOpen('http://www.apple.com', '_blank'); - }, 'openNonWhiteListedBlank'); - createActionButton('target=Random', function () { - doOpen('http://www.apple.com', 'random_string'); - }, 'openNonWhiteListedRandom'); - createActionButton('* target=Random, no location bar', function () { - doOpen('http://www.apple.com', 'random_string', 'location=no'); - }, 'openNonWhiteListedRandomNoLocation'); - - //Page with redirect - createActionButton('http://google.co.uk', function () { - doOpen('http://google.co.uk', 'random_string', '', 1); - }, 'openRedirect301'); - createActionButton('http://goo.gl/pUFqg', function () { - doOpen('http://goo.gl/pUFqg', 'random_string', '', 2); - }, 'openRedirect302'); - - //PDF URL - createActionButton('Remote URL', function () { - doOpen('http://www.stluciadance.com/prospectus_file/sample.pdf'); - }, 'openPDF'); - createActionButton('Local URL', function () { - doOpen(localpdf, '_blank'); - }, 'openPDFBlank'); - - //Invalid URL - createActionButton('Invalid Scheme', function () { - doOpen('x-ttp://www.invalid.com/', '_blank'); - }, 'openInvalidScheme'); - createActionButton('Invalid Host', function () { - doOpen('http://www.inv;alid.com/', '_blank'); - }, 'openInvalidHost'); - createActionButton('Missing Local File', function () { - doOpen('nonexistent.html', '_blank'); - }, 'openInvalidMissing'); - - //CSS / JS injection - createActionButton('Original Document', function () { - doOpen(injecthtml, '_blank'); - }, 'openOriginalDocument'); - createActionButton('CSS File Injection', function () { - openWithStyle(injecthtml, injectcss); - }, 'openCSSInjection'); - createActionButton('CSS File Injection (callback)', function () { - openWithStyle(injecthtml, injectcss, true); - }, 'openCSSInjectionCallback'); - createActionButton('CSS Literal Injection', function () { - openWithStyle(injecthtml); - }, 'openCSSLiteralInjection'); - createActionButton('CSS Literal Injection (callback)', function () { - openWithStyle(injecthtml, null, true); - }, 'openCSSLiteralInjectionCallback'); - createActionButton('Script File Injection', function () { - openWithScript(injecthtml, injectjs); - }, 'openScriptInjection'); - createActionButton('Script File Injection (callback)', function () { - openWithScript(injecthtml, injectjs, true); - }, 'openScriptInjectionCallback'); - createActionButton('Script Literal Injection', function () { - openWithScript(injecthtml); - }, 'openScriptLiteralInjection'); - createActionButton('Script Literal Injection (callback)', function () { - openWithScript(injecthtml, null, true); - }, 'openScriptLiteralInjectionCallback'); - - //Open hidden - createActionButton('Create Hidden', function () { - openHidden('https://www.google.co.uk', true); - }, 'openHidden'); - createActionButton('Show Hidden', function () { - showHidden(); - }, 'showHidden'); - createActionButton('Close Hidden', function () { - closeHidden(); - }, 'closeHidden'); - createActionButton('google.co.uk Not Hidden', function () { - openHidden('https://www.google.co.uk', false); - }, 'openHiddenShow'); - - //Clearing cache - createActionButton('Clear Browser Cache', function () { - doOpen('https://www.google.co.uk', '_blank', 'clearcache=yes'); - }, 'openClearCache'); - createActionButton('Clear Session Cache', function () { - doOpen('https://www.google.co.uk', '_blank', 'clearsessioncache=yes'); - }, 'openClearSessionCache'); - - //Video tag - createActionButton('Remote Video', function () { - doOpen(videohtml, '_blank'); - }, 'openRemoteVideo'); - - //Local With Anchor Tag - createActionButton('Anchor1', function () { - doOpen(localhtml + '#bogusanchor', '_blank'); - }, 'openAnchor1'); - createActionButton('Anchor2', function () { - doOpen(localhtml + '#anchor2', '_blank'); - }, 'openAnchor2'); -}; - diff --git a/plugins/cordova-plugin-inappbrowser/www/inappbrowser.css b/plugins/cordova-plugin-inappbrowser/www/inappbrowser.css deleted file mode 100644 index 4dfb503e..00000000 --- a/plugins/cordova-plugin-inappbrowser/www/inappbrowser.css +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -.inAppBrowserWrap { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - vertical-align: baseline; - background: 0 0; - position: fixed; - top: 0; - left: 0; - width: calc(100% - 80px); - height: calc(100% - 80px); - z-index: 9999999; - border: 40px solid #bfbfbf; - border: 40px solid rgba(0, 0, 0, 0.25); -} - -.inAppBrowserWrapFullscreen { - width: 100%; - height: 100%; - border: 0; -} diff --git a/plugins/cordova-plugin-inappbrowser/www/inappbrowser.js b/plugins/cordova-plugin-inappbrowser/www/inappbrowser.js deleted file mode 100644 index a85f27e9..00000000 --- a/plugins/cordova-plugin-inappbrowser/www/inappbrowser.js +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'); -var channel = require('cordova/channel'); -var modulemapper = require('cordova/modulemapper'); -var urlutil = require('cordova/urlutil'); - -function InAppBrowser() { - this.channels = { - 'loadstart': channel.create('loadstart'), - 'loadstop' : channel.create('loadstop'), - 'loaderror' : channel.create('loaderror'), - 'exit' : channel.create('exit') - }; -} - -InAppBrowser.prototype = { - _eventHandler: function (event) { - if (event && (event.type in this.channels)) { - this.channels[event.type].fire(event); - } - }, - close: function (eventname) { - exec(null, null, "InAppBrowser", "close", []); - }, - show: function (eventname) { - exec(null, null, "InAppBrowser", "show", []); - }, - addEventListener: function (eventname,f) { - if (eventname in this.channels) { - this.channels[eventname].subscribe(f); - } - }, - removeEventListener: function(eventname, f) { - if (eventname in this.channels) { - this.channels[eventname].unsubscribe(f); - } - }, - - executeScript: function(injectDetails, cb) { - if (injectDetails.code) { - exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]); - } else if (injectDetails.file) { - exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]); - } else { - throw new Error('executeScript requires exactly one of code or file to be specified'); - } - }, - - insertCSS: function(injectDetails, cb) { - if (injectDetails.code) { - exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]); - } else if (injectDetails.file) { - exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]); - } else { - throw new Error('insertCSS requires exactly one of code or file to be specified'); - } - } -}; - -module.exports = function(strUrl, strWindowName, strWindowFeatures, callbacks) { - // Don't catch calls that write to existing frames (e.g. named iframes). - if (window.frames && window.frames[strWindowName]) { - var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open'); - return origOpenFunc.apply(window, arguments); - } - - strUrl = urlutil.makeAbsolute(strUrl); - var iab = new InAppBrowser(); - - callbacks = callbacks || {}; - for (var callbackName in callbacks) { - iab.addEventListener(callbackName, callbacks[callbackName]); - } - - var cb = function(eventname) { - iab._eventHandler(eventname); - }; - - strWindowFeatures = strWindowFeatures || ""; - - exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]); - return iab; -}; - diff --git a/plugins/cordova-plugin-inappbrowser/www/windows8/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/www/windows8/InAppBrowserProxy.js deleted file mode 100644 index 944284e5..00000000 --- a/plugins/cordova-plugin-inappbrowser/www/windows8/InAppBrowserProxy.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * 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. - * -*/ - -/*jslint sloppy:true */ -/*global Windows:true, require, document, setTimeout, window, module */ - - - -var cordova = require('cordova'), - channel = require('cordova/channel'); - -var browserWrap; - -var IAB = { - - close: function (win, lose) { - if (browserWrap) { - browserWrap.parentNode.removeChild(browserWrap); - browserWrap = null; - } - }, - show: function (win, lose) { - /* empty block, ran out of bacon? - if (browserWrap) { - - }*/ - }, - open: function (win, lose, args) { - var strUrl = args[0], - target = args[1], - features = args[2], - url, - elem; - - if (target === "_system") { - url = new Windows.Foundation.Uri(strUrl); - Windows.System.Launcher.launchUriAsync(url); - } else if (target === "_blank") { - if (!browserWrap) { - browserWrap = document.createElement("div"); - browserWrap.style.position = "absolute"; - browserWrap.style.width = (window.innerWidth - 80) + "px"; - browserWrap.style.height = (window.innerHeight - 80) + "px"; - browserWrap.style.borderWidth = "40px"; - browserWrap.style.borderStyle = "solid"; - browserWrap.style.borderColor = "rgba(0,0,0,0.25)"; - - browserWrap.onclick = function () { - setTimeout(function () { - IAB.close(); - }, 0); - }; - - document.body.appendChild(browserWrap); - } - - elem = document.createElement("iframe"); - elem.style.width = (window.innerWidth - 80) + "px"; - elem.style.height = (window.innerHeight - 80) + "px"; - elem.style.borderWidth = "0px"; - elem.name = "targetFrame"; - elem.src = strUrl; - - window.addEventListener("resize", function () { - if (browserWrap && elem) { - elem.style.width = (window.innerWidth - 80) + "px"; - elem.style.height = (window.innerHeight - 80) + "px"; - } - }); - - browserWrap.appendChild(elem); - } else { - window.location = strUrl; - } - - //var object = new WinJS.UI.HtmlControl(elem, { uri: strUrl }); - - }, - - injectScriptCode: function (code, bCB) { - - // "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)" - }, - - injectScriptFile: function (file, bCB) { - - } -}; - -module.exports = IAB; - - -require("cordova/exec/proxy").add("InAppBrowser", module.exports); diff --git a/plugins/cordova-plugin-ios-longpress-fix/LICENSE b/plugins/cordova-plugin-ios-longpress-fix/LICENSE deleted file mode 100644 index 02389508..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Telerik - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE.
\ No newline at end of file diff --git a/plugins/cordova-plugin-ios-longpress-fix/README.md b/plugins/cordova-plugin-ios-longpress-fix/README.md deleted file mode 100644 index 77f620a8..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Cordova iOS LongPress Fix Plugin -by [Eddy Verbruggen](http://twitter.com/eddyverbruggen) - - -## Description - -Apple thought it'd be nice to show a magnifying glass when longpressing the webview on iOS9. - -Don't like it? This plugin removes it! - -<img src="screenshots/magnifying-glass.png" width="375px" height="333px"/> - - -## Installation - -Cordova CLI -``` -$ cordova plugin add cordova-plugin-ios-longpress-fix -``` - -PhoneGap Build -```xml -<gap:plugin id="cordova-plugin-ios-longpress-fix" source="npm" /> -``` - - -## Usage -It just works, and will proudly shout that at the XCode console when it does. - - -## Limitations -Currently only works with UIWebView, not WKWebView, but you should be able to -suppress the magnifying glass on WKWebView with a few lines of CSS. - - -## Future -I'm working with Cordova guys to get this in their distribution as standard.
\ No newline at end of file diff --git a/plugins/cordova-plugin-ios-longpress-fix/package.json b/plugins/cordova-plugin-ios-longpress-fix/package.json deleted file mode 100644 index 085c61f9..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "cordova-plugin-ios-longpress-fix", - "version": "1.0.1", - "description": "Suppresses the silly magnifying glass when longpressing your app on iOS9", - "cordova": { - "id": "cordova-plugin-ios-longpress-fix", - "platforms": [ - "ios" - ] - }, - "repository": { - "type": "git", - "url": "git+https://github.com/EddyVerbruggen/cordova-plugin-ios-longpress-fix.git" - }, - "keywords": [ - "LongPress", - "LongTap", - "Zoom", - "Magnification", - "Magnifying glass", - "iOS9", - "ecosystem:cordova", - "cordova-ios" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ], - "author": "Eddy Verbruggen <eddyverbruggen@gmail.com> (https://github.com/EddyVerbruggen)", - "license": "MIT", - "bugs": { - "url": "https://github.com/EddyVerbruggen/cordova-plugin-ios-longpress-fix/issues" - }, - "homepage": "https://github.com/EddyVerbruggen/cordova-plugin-ios-longpress-fix#readme" -}
\ No newline at end of file diff --git a/plugins/cordova-plugin-ios-longpress-fix/plugin.xml b/plugins/cordova-plugin-ios-longpress-fix/plugin.xml deleted file mode 100755 index 228eec60..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/plugin.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-ios-longpress-fix" - version="1.0.1"> - - <name>iOS LongPress Fix</name> - - <description> - Suppresses the silly magnifying glass when longpressing your app on iOS9 - </description> - - <author>Eddy Verbruggen</author> - - <license>MIT</license> - - <keywords>LongPress, LongTap, Zoom, Magnification, Magnifying glass, iOS9</keywords> - - <repo>https://github.com/EddyVerbruggen/cordova-plugin-ios-longpress-fix.git</repo> - - <issue>https://github.com/EddyVerbruggen/cordova-plugin-ios-longpress-fix/issues</issue> - - <engines> - <engine name="cordova" version=">=3.0.0"/> - </engines> - - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="LongPressFix"> - <param name="ios-package" value="LongPressFix"/> - <param name="onload" value="true"/> - </feature> - </config-file> - - <header-file src="src/ios/LongPressFix.h"/> - <source-file src="src/ios/LongPressFix.m"/> - </platform> - -</plugin> diff --git a/plugins/cordova-plugin-ios-longpress-fix/screenshots/magnifying-glass.png b/plugins/cordova-plugin-ios-longpress-fix/screenshots/magnifying-glass.png Binary files differdeleted file mode 100644 index 5ab7c70e..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/screenshots/magnifying-glass.png +++ /dev/null diff --git a/plugins/cordova-plugin-ios-longpress-fix/src/ios/LongPressFix.h b/plugins/cordova-plugin-ios-longpress-fix/src/ios/LongPressFix.h deleted file mode 100755 index 132bb8ad..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/src/ios/LongPressFix.h +++ /dev/null @@ -1,7 +0,0 @@ -#import <Cordova/CDVPlugin.h> - -@interface LongPressFix : CDVPlugin - -@property (nonatomic,strong) UILongPressGestureRecognizer *lpgr; - -@end
\ No newline at end of file diff --git a/plugins/cordova-plugin-ios-longpress-fix/src/ios/LongPressFix.m b/plugins/cordova-plugin-ios-longpress-fix/src/ios/LongPressFix.m deleted file mode 100755 index 9f3d8521..00000000 --- a/plugins/cordova-plugin-ios-longpress-fix/src/ios/LongPressFix.m +++ /dev/null @@ -1,35 +0,0 @@ -#import "LongPressFix.h" - -@implementation LongPressFix - -- (void)pluginInitialize { - self.lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGestures:)]; - self.lpgr.minimumPressDuration = 0.45f; - self.lpgr.allowableMovement = 100.0f; - - 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]; - NSLog(@"Applied longpress fix"); - 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 (iOS9 quirk)"); - } - } -} - -@end
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/CONTRIBUTING.md b/plugins/cordova-plugin-splashscreen/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/cordova-plugin-splashscreen/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/cordova-plugin-splashscreen/LICENSE b/plugins/cordova-plugin-splashscreen/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/cordova-plugin-splashscreen/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/NOTICE b/plugins/cordova-plugin-splashscreen/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/cordova-plugin-splashscreen/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/cordova-plugin-splashscreen/README.md b/plugins/cordova-plugin-splashscreen/README.md deleted file mode 100644 index b43c2c59..00000000 --- a/plugins/cordova-plugin-splashscreen/README.md +++ /dev/null @@ -1,131 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -This plugin displays and hides a splash screen during application launch. - -## Installation - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - -## Supported Platforms - -- Amazon Fire OS -- Android -- BlackBerry 10 -- iOS -- Windows Phone 7 and 8 -- Windows 8 -- Windows -- Browser - - -## Methods - -- splashscreen.show -- splashscreen.hide - -### Android Quirks - -In your `config.xml`, you need to add the following preferences: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - -Where foo is the name of the splashscreen file, preferably a 9 patch file. Make sure to add your splashcreen files to your res/xml directory under the appropriate folders. The second parameter represents how long the splashscreen will appear in milliseconds. It defaults to 3000 ms. See [Icons and Splash Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) -for more information. - -"SplashMaintainAspectRatio" preference is optional. If set to true, splash screen drawable is not stretched to fit screen, but instead simply "covers" the screen, like CSS "background-size:cover". This is very useful when splash screen images cannot be distorted in any way, for example when they contain scenery or text. This setting works best with images that have large margins (safe areas) that can be safely cropped on screens with different aspect ratios. - -The plugin reloads splash drawable whenever orientation changes, so you can specify different drawables for portrait and landscape orientations. - -### Browser Quirks - -You can use the following preferences in your `config.xml`: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS Quirks - -- `FadeSplashScreen` (boolean, defaults to `true`): Set to `false` to - prevent the splash screen from fading in and out when its display - state changes. - - <preference name="FadeSplashScreen" value="false"/> - -- `FadeSplashScreenDuration` (float, defaults to `2`): Specifies the - number of seconds for the splash screen fade effect to execute. - - <preference name="FadeSplashScreenDuration" value="4"/> - -- `ShowSplashScreenSpinner` (boolean, defaults to `true`): Set to `false` - to hide the splash-screen spinner. - - <preference name="ShowSplashScreenSpinner" value="false"/> - -## splashscreen.hide - -Dismiss the splash screen. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -The `config.xml` file's `AutoHideSplashScreen` setting must be -`false`. To delay hiding the splash screen for two seconds, add a -timer such as the following in the `deviceready` event handler: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - -## splashscreen.show - -Displays the splash screen. - - navigator.splashscreen.show(); - - -Your application cannot call `navigator.splashscreen.show()` until the app has -started and the `deviceready` event has fired. But since typically the splash -screen is meant to be visible before your app has started, that would seem to -defeat the purpose of the splash screen. Providing some configuration in -`config.xml` will automatically `show` the splash screen immediately after your -app launch and before it has fully started and received the `deviceready` -event. See [Icons and Splash Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) -for more information on doing this configuration. For this reason, it is -unlikely you need to call `navigator.splashscreen.show()` to make the splash -screen visible for app startup. - diff --git a/plugins/cordova-plugin-splashscreen/RELEASENOTES.md b/plugins/cordova-plugin-splashscreen/RELEASENOTES.md deleted file mode 100644 index 2c6b0013..00000000 --- a/plugins/cordova-plugin-splashscreen/RELEASENOTES.md +++ /dev/null @@ -1,143 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.2.2 (Sept 25, 2013) -* CB-4889 bumping&resetting version -* CB-4889 renaming org.apache.cordova.core.splashscreen to org.apache.cordova.splashscreen -* Rename CHANGELOG.md -> RELEASENOTES.md -* [CB-4806] Update splashscreen image bounds for iOS 7 -* [CB-4752] Incremented plugin version on dev branch. - -### 0.2.3 (Oct 9, 2013) -* [CB-4806] Re-fix Update splashscreen image bounds for iOS 7 -* [CB-4934] plugin-splashscreen should not show by default on Windows8 -* [CB-4929] plugin-splashscreen not loading proxy windows8 -* [CB-4915] Incremented plugin version on dev branch. - -### 0.2.4 (Oct 28, 2013) -* CB-5128: add repo + issue tag to plugin.xml for splashscreen plugin -* [CB-5010] Incremented plugin version on dev branch. - -### 0.2.5 (Dec 4, 2013) -* add ubuntu platform -* Added amazon-fireos platform. Change to use amazon-fireos as a platform if the user agent string contains 'cordova-amazon-fireos' -* CB-5124 - Remove splashscreen config.xml values from iOS Configuration Docs, move to plugin docs - -### 0.2.6 (Jan 02, 2014) -* CB-5658 Add doc/index.md for Splashscreen plugin -* Handle error when splash image is missing. - -### 0.2.7 (Feb 05, 2014) -* [CB-3562] Fix aspect ratio on landscape-only iPhone applications -* CB-4051 fix for splashscreen rotation problem - -### 0.3.0 (Apr 17, 2014) -* Add Tizen support to plugin -* CB-6422: [windows8] use cordova/exec/proxy -* CB-4051: [ios] - Re-fix - Splashscreen rotation problem (closes #13) -* CB-6460: Update license headers -* CB-6465: Add license headers to Tizen code -* Add NOTICE file - -### 0.3.1 (Jun 05, 2014) -* documentation translation: cordova-plugin-splashscreen -* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen -* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen -* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen -* Lisa testing pulling in plugins for plugin: cordova-plugin-splashscreen -* CB-6810 Add license to CONTRIBUTING.md -* [wp8] updated quirk for and combined iOS,WP8,BB10 quirks as they are all the same -* [wp] implemented OnInit so splash screen can be shown before cordova page is loaded -* [wp] plugin must be autoloaded for AutoHideSplashScreen preference to work -* CB-6483 Use splash screen image from manifest on Windows8 -* CB-6491 add CONTRIBUTING.md -* Revert "Merge branch 'tizen' of http://github.com/siovene/cordova-plugin-splashscreen" - -### 0.3.2 (Aug 06, 2014) -* CB-6127 Updated translations for docs -* CB-7041 ios: Fix image filename logic when setting the iPad splash screen -* fixes Splashscreen crash on WP8 -* Remove outdated doc - -### 0.3.3 (Sep 17, 2014) -* CB-7249 cordova-plugin-splashscreen documentation translation -* Renamed test dir, added nested plugin.xml -* added documentation for manual tests -* CB-7196 port splashscreen tests to framework - -### 0.3.4 (Oct 03, 2014) -* Finalized iOS splash screen (image name) tests. 176 tests in all, 44 for each type of device (iPad, iPhone, iPhone5, iPhone6, iPhone 6 Plus). -* CB-7633 - (Re-fix based on updated unit tests) iPhone 6 Plus support -* Updated iOS tests for locked orientations -* Added more iOS splash screen tests. -* CB-7633 - Add support for iPhone 6/6+ -* Added failing iPhone 6/6 Plus tests. -* Added 'npm test' -* CB-7663 - iOS unit tests for splash screen -* Properly formatted splashscreen preference docs. - -### 0.3.5 (Dec 02, 2014) -* CB-7204 - Race condition when hiding and showing spinner (closes #21) -* CB-7700 cordova-plugin-splashscreen documentation translation: cordova-plugin-splashscreen - -### 1.0.0 (Feb 04, 2015) -* CB-8351 ios: Stop using deprecated IsIpad macro -* CB-3679 Add engine tag for Android >= 3.6.0 due to use of `preferences` -* CB-3679 Make SplashScreen plugin compatible with cordova-android@4.0.x - -### 2.0.0 (Apr 15, 2015) -* give users a way to install the bleeding edge. -* CB-8746 gave plugin major version bump -* CB-8797 - Splashscreen preferences FadeSplashScreenDuration and FadeSplashScreen (iOS) are missing -* CB-8836 - Crashes after animating splashscreen -* CB-8753 android: Fix missing import in previous commit -* CB-8753 android: Adds `SplashMaintainAspectRatio` preference (close #43) -* CB-8683 changed plugin-id to pacakge-name -* CB-8653 properly updated translated docs to use new id -* CB-8653 updated translated docs to use new id -* CB-8345 Make default for splashscreen resource "screen" (which is what template and CLI assume it to be) -* Revert "CB-8345 android: Make "splash" the default resource ID instead of null" -* Use TRAVIS_BUILD_DIR, install paramedic by npm -* CB-8345 android: Make "splash" the default resource ID instead of null -* docs: added Windows to supported platforms -* CB-7964 Add cordova-plugin-splashscreen support for browser platform -* CB-8653 Updated Readme -* [wp8] oops, Added back config parse result checks -* [WP8] code cleanup, minor refactors, comments to clarify some stuff. -* Extend WP8 Splash Screen to respect SplashScreen and SplashScreenDelay preferences from config file -* CB-8574 Integrate TravisCI -* CB-8438 cordova-plugin-splashscreen documentation translation: cordova-plugin-splashscreen -* CB-8538 Added package.json file -* CB-8397 Add support to 'windows' for showing the Windows Phone splashscreen - -### 2.1.0 (Jun 17, 2015) -* added missing license headers -* CB-9128 cordova-plugin-splashscreen documentation translation: cordova-plugin-splashscreen -* fix npm md issue -* Fixed iOS unit tests. -* CB-3562: Disable screen rotation for iPhone when splash screen is shown. (closes #47) -* CB-8988: Fix rotation on iOS/iPad (closes #46) -* CB-8904: Don't reset the static variable when it's destroyed, otherwise we might as well just have a member variable -* Removed wp7 from plugin.xml and package.json -* CB-8750 [wp8]: Rewrite resoultion helper -* CB-8750 [wp8]: Allow resolution-specific splashscreen images -* CB-8758 [wp8]: UnauthorizedAccessException on hide() diff --git a/plugins/cordova-plugin-splashscreen/doc/de/README.md b/plugins/cordova-plugin-splashscreen/doc/de/README.md deleted file mode 100644 index f876eff8..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/de/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -Dieses Plugin zeigt und verbirgt einen Splash-Screen beim Start der Anwendung. - -## Installation - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## Unterstützte Plattformen - - * Amazon Fire OS - * Android - * BlackBerry 10 - * iOS - * Windows Phone 7 und 8 - * Windows 8 - * Windows - * Browser - -## Methoden - - * SplashScreen.Show - * SplashScreen.Hide - -### Android Eigenarten - -Sie müssen in Ihrem `"config.xml"`fügen Sie die folgenden Einstellungen: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -Wo Foo ist der Name der Datei Splashscreen, vorzugsweise eine 9-Patch-Datei. Stellen Sie sicher, Splashcreen Dateien zu Ihrem res/xml-Verzeichnis unter den entsprechenden Ordnern hinzuzufügen. Der zweite Parameter stellt dar, wie lange das Splashscreen in Millisekunden angezeigt werden. Es wird standardmäßig auf 3000 ms. Weitere Informationen finden Sie unter [Symbole und Splash-Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). - -"SplashMaintainAspectRatio" Präferenz ist optional. Wenn wahr, Splash-Screen zeichenbaren nicht gestreckt wird, um den Bildschirm passen, sondern stattdessen einfach "" den Bildschirm, wie CSS abdeckt "Hintergrund-Größe: Schutz vor". Dies ist sehr nützlich, wenn Splash-Bildschirm Bilder können nicht, in keiner Weise, zum Beispiel verzerrt werden wenn sie Landschaft oder Text enthalten. Diese Einstellung funktioniert am besten mit Bildern, die große Margen (sichere Bereiche) haben, die sicher auf Bildschirme mit unterschiedlichen Seitenverhältnissen zugeschnitten werden können. - -Das Plugin lädt platsch zeichenbaren wenn Ausrichtung ändert, sodass Sie verschiedene Drawables für hoch- und Querformat Ausrichtungen angeben können. - -### Browser-Eigenheiten - -In Ihrem `"config.xml"`können Sie die folgenden Einstellungen: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS Macken - - * `FadeSplashScreen` (Boolean, standardmäßig auf `true festgelegt`): um zu verhindern, dass den Begrüßungsbildschirm ein-und ausblenden bei ihrer Anzeige Statusänderungen auf `false` festgelegt. - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration` (float, Standardwert ist `2`): gibt die Anzahl der Sekunden für den Begrüßungsbildschirm fade Effekt ausgeführt. - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner` (Boolean, standardmäßig auf `true festgelegt`): auf `false` festgelegt wird, um den Begrüßungsbildschirm Spinner auszublenden. - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## SplashScreen.Hide - -Schließen Sie den Splash-Screen. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Eigenarten - -Die Datei `config.xml` `AutoHideSplashScreen` Einstellung muss `false` sein. Verstecken des Begrüßungsbildschirms für zwei Sekunden Verzögerung, fügen Sie einen Timer wie die folgende in der `deviceready`-Ereignishandler: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## SplashScreen.Show - -Zeigt den Begrüßungsbildschirm. - - navigator.splashscreen.show(); - - -Ihre Anwendung kann nicht `navigator.splashscreen.show()` aufrufen, bis die app begonnen hat und das `deviceready`-Ereignis ausgelöst hat. Aber da in der Regel der Splash-Screen soll sichtbar sein, bevor die Anwendung gestartet wurde, scheint die Niederlage der Zweck des Begrüßungsbildschirms. Somit einige Konfiguration in der Datei `config.xml` werden automatisch die Splash `show` sofort nach Ihrer app-Start und Bildschirm bevor es voll begonnen hat, und das `deviceready`-Ereignis empfangen. Weitere Informationen zu dieser Konfiguration finden Sie unter [Symbole und Splash-Screens](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). Aus diesem Grund ist es unwahrscheinlich, dass Sie `navigator.splashscreen.show()` damit den Splash-Screen sichtbar ist für app-Start aufrufen müssen.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/de/index.md b/plugins/cordova-plugin-splashscreen/doc/de/index.md deleted file mode 100644 index b9fc40d2..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/de/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -Dieses Plugin zeigt und verbirgt einen Splash-Screen beim Start der Anwendung. - -## Installation - - cordova plugin add cordova-plugin-splashscreen - - -## Unterstützte Plattformen - -* Amazon Fire OS -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 und 8 -* Windows 8 - -## Methoden - -* SplashScreen.Show -* SplashScreen.Hide - -### Android Eigenarten - -Sie müssen in der config.xml folgende Einstellungen vornehmen: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -Wo Foo ist der Name der Datei Splashscreen, vorzugsweise eine 9-Patch-Datei. Stellen Sie sicher, Splashcreen Dateien zu Ihrem res/xml-Verzeichnis unter den entsprechenden Ordnern hinzuzufügen. Der zweite Parameter stellt dar, wie lange das Splashscreen in Millisekunden angezeigt werden. Es wird standardmäßig auf 3000 ms. Weitere Informationen finden Sie unter [Symbole und Splash-Screens][1]. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## SplashScreen.Hide - -Schließen Sie den Splash-Screen. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Eigenarten - -Die Datei `config.xml` `AutoHideSplashScreen` Einstellung muss `false` sein. Verstecken des Begrüßungsbildschirms für zwei Sekunden Verzögerung, fügen Sie einen Timer wie die folgende in der `deviceready`-Ereignishandler: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## SplashScreen.Show - -Zeigt den Begrüßungsbildschirm. - - navigator.splashscreen.show(); - - -Ihre Anwendung kann nicht `navigator.splashscreen.show()` aufrufen, bis die app begonnen hat und das `deviceready`-Ereignis ausgelöst hat. Aber da in der Regel der Splash-Screen soll sichtbar sein, bevor die Anwendung gestartet wurde, scheint die Niederlage der Zweck des Begrüßungsbildschirms. Somit einige Konfiguration in der Datei `config.xml` werden automatisch die Splash `show` sofort nach Ihrer app-Start und Bildschirm bevor es voll begonnen hat, und das `deviceready`-Ereignis empfangen. Weitere Informationen zu dieser Konfiguration finden Sie unter [Symbole und Splash-Screens][1]. Aus diesem Grund ist es unwahrscheinlich, dass Sie `navigator.splashscreen.show()` damit den Splash-Screen sichtbar ist für app-Start aufrufen müssen. diff --git a/plugins/cordova-plugin-splashscreen/doc/es/README.md b/plugins/cordova-plugin-splashscreen/doc/es/README.md deleted file mode 100644 index 1a94161a..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/es/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -Este plugin muestra y esconde una pantalla de bienvenida durante el inicio de la aplicación. - -## Instalación - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## Plataformas soportadas - - * Amazon fire OS - * Android - * BlackBerry 10 - * iOS - * Windows Phone 7 y 8 - * Windows 8 - * Windows - * Explorador - -## Métodos - - * splashscreen.show - * splashscreen.hide - -### Rarezas Android - -En el `archivo config.xml`, es necesario agregar las siguientes preferencias: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -Donde foo es el nombre del archivo splashscreen, preferiblemente un archivo de 9 parche. Asegúrese de agregar tus archivos splashcreen en tu directorio res/xml bajo las carpetas apropiadas. El segundo parámetro representa cuánto aparecerán el splashscreen en milisegundos. Valor predeterminado es ms 3000. Ver [los iconos y salpicadura pantallas](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) para obtener más información. - -Preferencia "SplashMaintainAspectRatio" es opcional. Si establece en true, pantalla dibujable no es estirado para caber la pantalla, pero en su lugar simplemente "cover" la pantalla, como CSS "background-size: cover". Esto es muy útil cuando las imágenes de pantallas splash no distorsionadas de cualquier manera, por ejemplo cuando contienen texto o paisaje. Esta opción funciona mejor con imágenes que tienen bordes grandes (zonas seguras) que pueden ser recortadas con seguridad en pantallas con diferentes relaciones de aspecto. - -El plugin recarga splash dibujable cuando cambia de orientación, por lo que puede especificar diferente dibujo para orientaciones vertical y horizontal. - -### Navegador rarezas - -Puede utilizar las siguientes preferencias en el `archivo config.xml`: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS rarezas - - * `FadeSplashScreen` (booleano, por defecto `true`): establecida en `false` para evitar que la pantalla de bienvenida de descolorarse adentro y hacia fuera cuando cambia su estado de presentación. - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration` (float, por defecto es `2`): especifica el número de segundos para que la pantalla se descolora efecto para ejecutar. - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner` (booleano, por defecto `true`): establecida en `false` para ocultar la ruleta de la pantalla de bienvenida. - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.hide - -Despedir a la pantalla de bienvenida. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -El `config.xml` del archivo `AutoHideSplashScreen` la configuración debe ser `false` . Para retrasar oculta la pantalla splash durante dos segundos, agregue un temporizador como la siguiente en el `deviceready` controlador de eventos: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -Muestra la pantalla de bienvenida. - - navigator.splashscreen.show(); - - -La aplicación no se puede llamar `navigator.splashscreen.show()` hasta que haya iniciado la aplicación y el `deviceready` evento ha despedido. Pero puesto que normalmente la pantalla está destinada a ser visible antes de que comience su aplicación, que parecería que el propósito de la pantalla de bienvenida. Proporcionar cierta configuración en `config.xml` automáticamente `show` la pantalla de presentación inmediatamente después de su lanzamiento de la aplicación y antes de ser completamente ha iniciado y recibió el `deviceready` evento. Ver [los iconos y salpicadura pantallas](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) para obtener más información sobre haciendo esta configuración. Por esta razón, es poco probable que necesitas llamar a `navigator.splashscreen.show()` para hacer la pantalla visible para el inicio de la aplicación.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/es/index.md b/plugins/cordova-plugin-splashscreen/doc/es/index.md deleted file mode 100644 index 3295c27f..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/es/index.md +++ /dev/null @@ -1,76 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -Este plugin muestra y esconde una pantalla de bienvenida durante el inicio de la aplicación. - -## Instalación - - cordova plugin add cordova-plugin-splashscreen - - -## Plataformas soportadas - -* Amazon fire OS -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 y 8 -* Windows 8 - -## Métodos - -* splashscreen.show -* splashscreen.hide - -### Rarezas Android - -En el archivo config.xml, tienes que añadir las siguientes preferencias: - - < nombre de preferencia = "SplashScreen" value = "foo" / >< nombre de preferencia = "SplashScreenDelay" value = "10000" / > - - -Donde foo es el nombre del archivo splashscreen, preferiblemente un archivo de 9 parche. Asegúrese de agregar tus archivos splashcreen en tu directorio res/xml bajo las carpetas apropiadas. El segundo parámetro representa cuánto aparecerán el splashscreen en milisegundos. Valor predeterminado es ms 3000. Ver [los iconos y salpicadura pantallas][1] para obtener más información. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.hide - -Despedir a la pantalla de bienvenida. - - Navigator.SplashScreen.Hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -El `config.xml` del archivo `AutoHideSplashScreen` la configuración debe ser `false` . Para retrasar oculta la pantalla splash durante dos segundos, agregue un temporizador como la siguiente en el `deviceready` controlador de eventos: - - setTimeout(function() {navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -Muestra la pantalla de bienvenida. - - Navigator.SplashScreen.Show(); - - -La aplicación no se puede llamar `navigator.splashscreen.show()` hasta que haya iniciado la aplicación y el `deviceready` evento ha despedido. Pero puesto que normalmente la pantalla está destinada a ser visible antes de que comience su aplicación, que parecería que el propósito de la pantalla de bienvenida. Proporcionar cierta configuración en `config.xml` automáticamente `show` la pantalla de presentación inmediatamente después de su lanzamiento de la aplicación y antes de ser completamente ha iniciado y recibió el `deviceready` evento. Ver [los iconos y salpicadura pantallas][1] para obtener más información sobre haciendo esta configuración. Por esta razón, es poco probable que necesitas llamar a `navigator.splashscreen.show()` para hacer la pantalla visible para el inicio de la aplicación. diff --git a/plugins/cordova-plugin-splashscreen/doc/fr/README.md b/plugins/cordova-plugin-splashscreen/doc/fr/README.md deleted file mode 100644 index 65f58803..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/fr/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -Ce plugin affiche et masque un écran de démarrage lors du lancement de l'application. - -## Installation - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## Plates-formes supportées - - * Amazon Fire OS - * Android - * BlackBerry 10 - * iOS - * Windows Phone 7 et 8 - * Windows 8 - * Windows - * Navigateur - -## Méthodes - - * splashscreen.Show - * splashscreen.Hide - -### Quirks Android - -Dans votre `fichier config.xml`, vous devez ajouter les préférences suivantes : - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -Où foo est le nom du fichier splashscreen, préférablement un fichier de 9 correctif. Assurez-vous d'ajouter vos fichiers splashcreen dans votre répertoire res/xml dans les dossiers appropriés. Le deuxième paramètre représente combien de temps le splashscreen apparaîtra en millisecondes. Il est par défaut à 3000 ms. Pour plus d'informations, consultez [icônes et écrans de démarrage](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). - -Préférence de « SplashMaintainAspectRatio » est facultative. Si défini à true, écran de démarrage drawable n'est pas étirée pour s'adapter écran, mais plutôt simplement « couvre » l'écran, comme CSS "fond-taille : couverture". Ceci est très utile lorsque images écran de démarrage ne peut pas être déformées en quelque sorte, par exemple lorsqu'ils contiennent des décors ou texte. Ce paramètre fonctionne mieux avec des images qui ont des marges importantes (zones de sécurité) qui peuvent être recadrées en toute sécurité sur les écrans avec des proportions différentes. - -Le plugin recharge splash drawable chaque fois que l'orientation change, donc vous pouvez spécifier différents drawables pour les orientations portrait et paysage. - -### Bizarreries navigateur - -Vous pouvez utiliser les préférences suivantes dans votre `fichier config.xml`: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### Notes au sujet d'iOS - - * `FadeSplashScreen` (boolean, par défaut est `true`): la valeur `false` pour empêcher l'écran de démarrage de fading in et out lorsque son état d'affichage est modifié. - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration` (float, la valeur par défaut `2`): spécifie le nombre de secondes que l'écran de démarrage s'estomper l'effet d'exécuter. - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner` (boolean, par défaut est `true`): la valeur `false` pour masquer le cône de l'écran de démarrage. - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.Hide - -Faire disparaître de l'écran de démarrage. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -Paramètre `AutoHideSplashScreen` du fichier `config.xml` doit avoir la valeur `false`. Pour retarder la cacher l'écran de démarrage pendant deux secondes, ajouter un minuteur semblable à la suivante dans le gestionnaire d'événements `deviceready` : - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.Show - -Affiche l'écran de démarrage. - - navigator.splashscreen.show(); - - -Votre application ne peut pas appeler `navigator.splashscreen.show()` jusqu'à ce que l'application a commencé et l'événement `deviceready` est déclenché. Mais puisqu'en général, l'écran de démarrage est destiné à être visible avant que votre application a commencé, qui semblerait à l'encontre des objectifs de l'écran de démarrage. Fournir une configuration dans le fichier `config.xml` automatiquement `show` le splash projettera immédiatement après votre lancement de l'app et avant qu'il a complètement démarré et a reçu l'événement `deviceready`. Voir les [icônes et les écrans de démarrage](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) pour plus d'informations sur la conduite de cette configuration. Pour cette raison, il est peu probable que vous devez appeler `navigator.splashscreen.show()` pour rendre l'écran de démarrage visible pour le démarrage de l'application.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/fr/index.md b/plugins/cordova-plugin-splashscreen/doc/fr/index.md deleted file mode 100644 index 6d2fd088..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/fr/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -Ce plugin affiche et masque un écran de démarrage lors du lancement de l'application. - -## Installation - - cordova plugin add cordova-plugin-splashscreen - - -## Plates-formes prises en charge - -* Amazon Fire OS -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 et 8 -* Windows 8 - -## Méthodes - -* splashscreen.Show -* splashscreen.Hide - -### Quirks Android - -Dans votre fichier config.xml, vous devez ajouter les préférences suivantes : - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -Où foo est le nom du fichier splashscreen, préférablement un fichier de 9 correctif. Assurez-vous d'ajouter vos fichiers splashcreen dans votre répertoire res/xml dans les dossiers appropriés. Le deuxième paramètre représente combien de temps le splashscreen apparaîtra en millisecondes. Il est par défaut à 3000 ms. Pour plus d'informations, consultez [icônes et écrans de démarrage][1]. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.Hide - -Faire disparaître de l'écran de démarrage. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -Paramètre `AutoHideSplashScreen` du fichier `config.xml` doit avoir la valeur `false`. Pour retarder la cacher l'écran de démarrage pendant deux secondes, ajouter un minuteur semblable à la suivante dans le gestionnaire d'événements `deviceready` : - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.Show - -Affiche l'écran de démarrage. - - navigator.splashscreen.show(); - - -Votre application ne peut pas appeler `navigator.splashscreen.show()` jusqu'à ce que l'application a commencé et l'événement `deviceready` est déclenché. Mais puisqu'en général, l'écran de démarrage est destiné à être visible avant que votre application a commencé, qui semblerait à l'encontre des objectifs de l'écran de démarrage. Fournir une configuration dans le fichier `config.xml` automatiquement `show` le splash projettera immédiatement après votre lancement de l'app et avant qu'il a complètement démarré et a reçu l'événement `deviceready`. Voir les [icônes et les écrans de démarrage][1] pour plus d'informations sur la conduite de cette configuration. Pour cette raison, il est peu probable que vous devez appeler `navigator.splashscreen.show()` pour rendre l'écran de démarrage visible pour le démarrage de l'application. diff --git a/plugins/cordova-plugin-splashscreen/doc/it/README.md b/plugins/cordova-plugin-splashscreen/doc/it/README.md deleted file mode 100644 index 2a6c6ba4..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/it/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -Questo plugin Visualizza e nasconde una schermata iniziale durante l'avvio dell'applicazione. - -## Installazione - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## Piattaforme supportate - - * Amazon fuoco OS - * Android - * BlackBerry 10 - * iOS - * Windows Phone 7 e 8 - * Windows 8 - * Windows - * Browser - -## Metodi - - * splashscreen - * splashscreen.Hide - -### Stranezze Android - -Nel vostro `config. XML`, è necessario aggiungere le seguenti preferenze: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -Dove foo è il nome del file splashscreen, preferibilmente un file 9 patch. Assicurati di aggiungere i tuoi file splashcreen res/xml nella directory sotto cartelle appropriate. Il secondo parametro rappresenta quanto tempo lo splashscreen apparirà in millisecondi. Il valore predefinito è 3000 ms. Per ulteriori informazioni, vedere [icone e schermate iniziali](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). - -"SplashMaintainAspectRatio" preferenza è facoltativo. Se impostato su true, schermata iniziale drawable non viene adattata per misura lo schermo, ma invece semplicemente "copre" lo schermo, come CSS "sfondo-dimensione: copertina". Questo è molto utile quando immagini schermata iniziale non possono essere distorta in qualche modo, per esempio quando contengono testo o scenario. Questa impostazione funziona meglio con immagini che hanno grandi margini (zone sicure) che possono essere ritagliati in modo sicuro su schermi con proporzioni diverse. - -Il plugin viene ricaricata splash drawable ogni volta che cambia orientamento, è possibile specificare diversi parte per orientamento verticale e orizzontale. - -### Stranezze browser - -Nel vostro `config. XML`, è possibile utilizzare le seguenti preferenze: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS stranezze - - * `FadeSplashScreen` (boolean, impostazioni predefinite a `true`): impostare su `false` per impedire che la schermata iniziale e scompaiono quando cambia il relativo stato di visualizzazione. - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration` (float, il valore predefinito è `2`): specifica il numero di secondi per la schermata iniziale dissolvenza effetto da eseguire. - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner` (boolean, impostazioni predefinite a `true`): impostare su `false` per nascondere la filatrice schermata iniziale. - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.Hide - -Respingere la schermata iniziale. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -Impostazione `AutoHideSplashScreen` del file `config.xml` deve essere `false`. Per ritardare nascondendo la schermata iniziale per due secondi, aggiungere un timer ad esempio nel gestore eventi `deviceready`: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen - -Visualizza la schermata iniziale. - - navigator.splashscreen.show(); - - -L'applicazione non può chiamare `navigator.splashscreen.show()` fino a quando l'app ha iniziato e ha generato l'evento `deviceready`. Ma poiché in genere la schermata iniziale è destinata ad essere visibile prima app ha iniziato, che sembrerebbe per sconfiggere lo scopo della schermata iniziale. Fornendo qualche configurazione nel `file config.xml` sarà automaticamente `show` il tonfo schermo subito dopo il lancio dell'app e prima che completamente ha iniziato e ha ricevuto l'evento `deviceready`. Per ulteriori informazioni su facendo questa configurazione, vedere [icone e schermate iniziali](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). Per questo motivo, è improbabile che dovete chiamare `navigator.splashscreen.show()` per rendere la schermata visibile per avvio di app.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/it/index.md b/plugins/cordova-plugin-splashscreen/doc/it/index.md deleted file mode 100644 index 70435415..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/it/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -Questo plugin Visualizza e nasconde una schermata iniziale durante l'avvio dell'applicazione. - -## Installazione - - cordova plugin add cordova-plugin-splashscreen - - -## Piattaforme supportate - -* Amazon fuoco OS -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 e 8 -* Windows 8 - -## Metodi - -* splashscreen -* splashscreen.Hide - -### Stranezze Android - -Nel vostro config. xml, è necessario aggiungere le seguenti preferenze: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -Dove foo è il nome del file splashscreen, preferibilmente un file 9 patch. Assicurati di aggiungere i tuoi file splashcreen res/xml nella directory sotto cartelle appropriate. Il secondo parametro rappresenta quanto tempo lo splashscreen apparirà in millisecondi. Il valore predefinito è 3000 ms. Per ulteriori informazioni, vedere [icone e schermate iniziali][1]. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.Hide - -Respingere la schermata iniziale. - - navigator.splashscreen.hide(); - - -### BlackBerry 10, WP8, iOS Quirk - -Impostazione `AutoHideSplashScreen` del file `config.xml` deve essere `false`. Per ritardare nascondendo la schermata iniziale per due secondi, aggiungere un timer ad esempio nel gestore eventi `deviceready`: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen - -Visualizza la schermata iniziale. - - navigator.splashscreen.show(); - - -L'applicazione non può chiamare `navigator.splashscreen.show()` fino a quando l'app ha iniziato e ha generato l'evento `deviceready`. Ma poiché in genere la schermata iniziale è destinata ad essere visibile prima app ha iniziato, che sembrerebbe per sconfiggere lo scopo della schermata iniziale. Fornendo qualche configurazione nel `file config.xml` sarà automaticamente `show` il tonfo schermo subito dopo il lancio dell'app e prima che completamente ha iniziato e ha ricevuto l'evento `deviceready`. Per ulteriori informazioni su facendo questa configurazione, vedere [icone e schermate iniziali][1]. Per questo motivo, è improbabile che dovete chiamare `navigator.splashscreen.show()` per rendere la schermata visibile per avvio di app. diff --git a/plugins/cordova-plugin-splashscreen/doc/ja/README.md b/plugins/cordova-plugin-splashscreen/doc/ja/README.md deleted file mode 100644 index a688b279..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/ja/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -このプラグインが表示され、アプリケーションの起動中にスプラッシュ スクリーンを非表示にします。 - -## インストール - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## サポートされているプラットフォーム - - * アマゾン火 OS - * アンドロイド - * ブラックベリー 10 - * iOS - * Windows Phone 7 と 8 - * Windows 8 - * Windows - * ブラウザー - -## メソッド - - * splashscreen.show - * splashscreen.hide - -### Android の癖 - -あなたの`config.xml`内の次の設定を追加する必要があります。 - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -Foo ができれば 9 パッチファイル splashscreen ファイルの名前です。 解像度/xml ディレクトリの適切なフォルダーの下に splashcreen ファイルを追加することを確認します。 2 番目のパラメーターは、スプラッシュ ・ スクリーンがの表示時間 (ミリ秒単位) を表します。 デフォルトでは 3000 ミリ秒です。 詳細については、[アイコンとスプラッシュ画面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) を参照してください。 - -"SplashMaintainAspectRatio"の設定はオプションです。 True の場合、スプラッシュ画面描画に設定画面を埋めるために拡大されませんが、代わりに単に「カバー」画面では、CSS のような場合「背景-サイズ: カバー」. これは、たとえば風景またはテキストが含まれている場合、任意の方法でスプラッシュ画面画像が歪むことができない非常に便利です。 この設定は、画面と異なる縦横比で安全にトリミングすることができます大規模なマージン (安全な地域) の画像に適しています。 - -縦長と横長の異なるドロウアブルを指定できるように、プラグインは向きを変更するたびにスプラッシュ ドロウアブルをリロードします。 - -### ブラウザーの癖 - -あなたの`config.xml`で次の設定を使用できます。 - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS の癖 - - * `FadeSplashScreen`(ブール値、既定で [ `true`): スプラッシュ画面がフェードインとフェードアウトの表示状態が変更されたときすることを防ぐために`false`に設定します。 - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration`(float, デフォルトは`2`): スプラッシュ画面の秒数のフェードを実行する効果を指定します。 - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner`(ブール値、既定で [ `true`): スプラッシュ スクリーン スピナーを非表示にするを`false`に設定します。 - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.hide - -スプラッシュ スクリーンを閉じます。 - - navigator.splashscreen.hide(); - - -### ブラックベリー 10、WP8、iOS の気まぐれ - -`config.xml` ファイルの `AutoHideSplashScreen` の設定は `false` である必要があります。 遅延を 2 秒間スプラッシュ スクリーンを非表示に `deviceready` イベント ハンドラーで、次のようタイマーを追加します。 - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -スプラッシュ画面が表示されます。 - - navigator.splashscreen.show(); - - -アプリが開始され、`deviceready` イベントが発生するまで、アプリケーションは `navigator.splashscreen.show()` を呼び出すことはできません。 しかし、以来、通常スプラッシュ画面アプリ開始前に表示するものですと思われる、スプラッシュ スクリーンの目的の敗北します。 `config.xml` にいくつかの構成を提供するは自動的に `表示` スプラッシュ画面、アプリを起動後すぐに、それが完全に起動し、`deviceready` イベントを受信する前に。 詳細についてはこの構成を行うには、[アイコンとスプラッシュ画面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) を参照してください。 この理由のためにアプリ起動時のスプラッシュ スクリーンを確認 `navigator.splashscreen.show()` をコールする必要がある可能性が高いです。
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/ja/index.md b/plugins/cordova-plugin-splashscreen/doc/ja/index.md deleted file mode 100644 index 24e72e5a..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/ja/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -このプラグインが表示され、アプリケーションの起動中にスプラッシュ スクリーンを非表示にします。 - -## インストール - - cordova plugin add cordova-plugin-splashscreen - - -## サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* ブラックベリー 10 -* iOS -* Windows Phone 7 と 8 -* Windows 8 - -## メソッド - -* splashscreen.show -* splashscreen.hide - -### Android の癖 - -あなたの config.xml を以下の設定を追加する必要があります。 - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -Foo ができれば 9 パッチファイル splashscreen ファイルの名前です。 解像度/xml ディレクトリの適切なフォルダーの下に splashcreen ファイルを追加することを確認します。 2 番目のパラメーターは、スプラッシュ ・ スクリーンがの表示時間 (ミリ秒単位) を表します。 デフォルトでは 3000 ミリ秒です。 詳細については、[アイコンとスプラッシュ画面][1] を参照してください。 - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.hide - -スプラッシュ スクリーンを閉じます。 - - navigator.splashscreen.hide(); - - -### ブラックベリー 10、WP8、iOS の気まぐれ - -`config.xml` ファイルの `AutoHideSplashScreen` の設定は `false` である必要があります。 遅延を 2 秒間スプラッシュ スクリーンを非表示に `deviceready` イベント ハンドラーで、次のようタイマーを追加します。 - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -スプラッシュ画面が表示されます。 - - navigator.splashscreen.show(); - - -アプリが開始され、`deviceready` イベントが発生するまで、アプリケーションは `navigator.splashscreen.show()` を呼び出すことはできません。 しかし、以来、通常スプラッシュ画面アプリ開始前に表示するものですと思われる、スプラッシュ スクリーンの目的の敗北します。 `config.xml` にいくつかの構成を提供するは自動的に `表示` スプラッシュ画面、アプリを起動後すぐに、それが完全に起動し、`deviceready` イベントを受信する前に。 詳細についてはこの構成を行うには、[アイコンとスプラッシュ画面][1] を参照してください。 この理由のためにアプリ起動時のスプラッシュ スクリーンを確認 `navigator.splashscreen.show()` をコールする必要がある可能性が高いです。 diff --git a/plugins/cordova-plugin-splashscreen/doc/ko/README.md b/plugins/cordova-plugin-splashscreen/doc/ko/README.md deleted file mode 100644 index 5e10d207..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/ko/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -이 플러그인은 표시 하 고 응용 프로그램 실행 하는 동안 시작 화면을 숨깁니다. - -## 설치 - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## 지원 되는 플랫폼 - - * 아마존 화재 운영 체제 - * 안 드 로이드 - * 블랙베리 10 - * iOS - * Windows Phone 7과 8 - * 윈도우 8 - * 윈도우 - * 브라우저 - -## 메서드 - - * splashscreen.show - * splashscreen.hide - -### 안 드 로이드 단점 - -`Config.xml`에 다음 환경 설정에 추가 해야 합니다. - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -여기서 foo splashscreen 파일, 선호 9 패치 파일의 이름입니다. 적절 한 폴더 아래 res/xml 디렉토리에 splashcreen 파일을 추가 해야 합니다. 두 번째 매개 변수는 splashscreen 얼마나 밀리초 단위로 표시 됩니다 나타냅니다. 3000 ms 기본값으로 사용 됩니다. 자세한 내용은 [아이콘 및 시작 화면을](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) 참조 하십시오. - -"SplashMaintainAspectRatio" 취향은 선택 사항입니다. Drawable, 시작 화면 설정 화면에 맞게 확장 되지 하지만 대신 단순히 "커버" CSS 같은 화면 "배경-크기: 덮개". 시작 화면 이미지 예: 풍경 또는 텍스트를 포함 하는 경우 어떤 식으로든에서 왜곡 될 수 없는 경우에 매우 유용 합니다. 이 설정은 큰 여백 (안전 지역) 안전 하 게 다른 종횡비와 화면에 자를 수 있는 이미지에 가장 적합 합니다. - -플러그인 다시 로드 스플래시 drawable 방향이 변경 될 때마다 세로 및 가로 방향에 대 한 다른 drawables를 지정할 수 있도록 합니다. - -### 브라우저 만지면 - -`Config.xml`에 다음 기본 설정을 사용할 수 있습니다. - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS 단점 - - * `FadeSplashScreen` (부울 `true`로 기본값): 시작 화면 표시 상태로 변경 될 때 밖으로 퇴색 하지 않도록 하려면 `false` 로 설정. - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration` (부동, `2`기본값): 시작 화면에 대 한 초 페이드 효과를 실행 하는 지정 합니다. - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner` (부울 `true`로 기본값): 스플래시 화면 회전자를 숨기려면 `false` 로 설정. - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.hide - -시작 화면을 닫습니다. - - navigator.splashscreen.hide(); - - -### 블랙베리 10, WP8, iOS 특질 - -`config.xml` 파일의 `AutoHideSplashScreen` 설정을 `false` 여야 합니다. 2 초 동안 시작 화면을 숨기고 지연, `deviceready` 이벤트 처리기에서 다음과 같은 타이머를 추가: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -시작 화면을 표시합니다. - - navigator.splashscreen.show(); - - -응용 프로그램 시작 및 `deviceready` 이벤트는 발생 될 때까지 응용 프로그램이 `navigator.splashscreen.show()`을 호출할 수 없습니다. 하지만 그 스플래시 스크린의 목적 것 같다 일반적으로 시작 화면이 당신의 애플 리 케이 션 시작 하기 전에 표시 될 운명이 다, 이후. `config.xml에서` 몇 가지 구성을 제공 하 자동으로 스플래시 `표시` 화면 애플 리 케이 션 출시 직후와 그것은 완벽 하 게 시작 하 고 `deviceready` 이벤트를 받은 전에. 이 구성 하 고 자세한 내용은 [아이콘 및 시작 화면을](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html) 참조 하십시오. 이러한 이유로, 그것은 가능성이 시작 화면은 응용 프로그램 시작에 대 한 표시 되도록 `navigator.splashscreen.show()`를 호출 해야입니다.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/ko/index.md b/plugins/cordova-plugin-splashscreen/doc/ko/index.md deleted file mode 100644 index 6a0ea989..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/ko/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -이 플러그인은 표시 하 고 응용 프로그램 실행 하는 동안 시작 화면을 숨깁니다. - -## 설치 - - cordova plugin add cordova-plugin-splashscreen - - -## 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* 블랙베리 10 -* iOS -* Windows Phone 7과 8 -* 윈도우 8 - -## 메서드 - -* splashscreen.show -* splashscreen.hide - -### 안 드 로이드 단점 - -당신의 config.xml에 다음 환경 설정에 추가 해야 합니다. - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -여기서 foo splashscreen 파일, 선호 9 패치 파일의 이름입니다. 적절 한 폴더 아래 res/xml 디렉토리에 splashcreen 파일을 추가 해야 합니다. 두 번째 매개 변수는 splashscreen 얼마나 밀리초 단위로 표시 됩니다 나타냅니다. 3000 ms 기본값으로 사용 됩니다. 자세한 내용은 [아이콘 및 시작 화면을][1] 참조 하십시오. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.hide - -시작 화면을 닫습니다. - - navigator.splashscreen.hide(); - - -### 블랙베리 10, WP8, iOS 특질 - -`config.xml` 파일의 `AutoHideSplashScreen` 설정을 `false` 여야 합니다. 2 초 동안 시작 화면을 숨기고 지연, `deviceready` 이벤트 처리기에서 다음과 같은 타이머를 추가: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -시작 화면을 표시합니다. - - navigator.splashscreen.show(); - - -응용 프로그램 시작 및 `deviceready` 이벤트는 발생 될 때까지 응용 프로그램이 `navigator.splashscreen.show()`을 호출할 수 없습니다. 하지만 그 스플래시 스크린의 목적 것 같다 일반적으로 시작 화면이 당신의 애플 리 케이 션 시작 하기 전에 표시 될 운명이 다, 이후. `config.xml에서` 몇 가지 구성을 제공 하 자동으로 스플래시 `표시` 화면 애플 리 케이 션 출시 직후와 그것은 완벽 하 게 시작 하 고 `deviceready` 이벤트를 받은 전에. 이 구성 하 고 자세한 내용은 [아이콘 및 시작 화면을][1] 참조 하십시오. 이러한 이유로, 그것은 가능성이 시작 화면은 응용 프로그램 시작에 대 한 표시 되도록 `navigator.splashscreen.show()`를 호출 해야입니다. diff --git a/plugins/cordova-plugin-splashscreen/doc/pl/README.md b/plugins/cordova-plugin-splashscreen/doc/pl/README.md deleted file mode 100644 index 0156be56..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/pl/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -Ten plugin wyświetla i ukrywa ekran powitalny podczas uruchamiania aplikacji. - -## Instalacja - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## Obsługiwane platformy - - * Amazon Fire OS - * Android - * BlackBerry 10 - * iOS - * Windows Phone 7 i 8 - * Windows 8 - * Windows - * Przeglądarka - -## Metody - - * splashscreen.show - * splashscreen.Hide - -### Dziwactwa Androida - -W pliku `config.xml`musisz dodać następujące preferencje: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -Gdzie foo jest nazwą pliku ekranu powitalnego, najlepiej 9 łatce. Upewnij się dodać pliki splashcreen do katalogu res/xml w odpowiednich folderach. Drugi parametr reprezentuje, jak długo ekranu powitalnego pojawi się w milisekundach. Domyślnie 3000 ms. Aby uzyskać więcej informacji, zobacz [ikony i ekrany powitalne w aplikacjach](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). - -"SplashMaintainAspectRatio" preferencji jest opcjonalne. Jeśli zestaw na wartość true, ekran powitalny dolarowe nie jest rozciągnięty do ekranów, ale zamiast po prostu "obejmuje" ekranu, jak CSS "tło-rozmiar: okładka". Jest to bardzo przydatne, kiedy opryskać tęcza obrazy nie zniekształcony w jakikolwiek sposób, na przykład, gdy zawierają one dekoracje lub tekst. To ustawienie działa najlepiej z obrazów, które mają duże marginesy (bezpiecznych obszarów), które mogą być bezpiecznie przycięte na ekrany z różnych proporcji. - -Plugin ładuje rozchlapać dolarowe, gdy zmienia orientację, tak można określić różnych drawables do orientacji pionowej i poziomej. - -### Quirks przeglądarki - -W pliku `config.xml`można użyć następujące preferencje: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### Dziwactwa iOS - - * `FadeSplashScreen` (wartość logiczna, domyślnie `true`): zestaw na `false` , aby zapobiec Znikająca i odkładane po zmianie stanu wyświetlania ekranu powitalnego. - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration` (float, domyślnie `2`): określa liczbę sekund dla ekranu powitalnego zanikanie efekt do wykonać. - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner` (wartość logiczna, domyślnie `true`): zestaw na `false` , aby ukryć pokrętła ekran powitalny. - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.Hide - -Odrzucić ten opryskaæ têcza. - - navigator.splashscreen.hide(); - - -### Jeżyna 10, WP8, iOS dziwactwo - -Plik `config.xml` `AutoHideSplashScreen` ustawienie musi być `false`. Opóźnienia, ukrywanie ekranu powitalnego przez dwie sekundy, dodać timer następujących w `deviceready` obsługa zdarzeń: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -Wyświetla ekran powitalny. - - navigator.splashscreen.show(); - - -Aplikacja nie można wywołać `navigator.splashscreen.show()`, aż aplikacja została uruchomiona i zdarzenie `deviceready` został zwolniony. Ale ponieważ zazwyczaj opryskać tęcza ma być widoczne przed rozpoczęciem aplikacji, wydaje się sprzeczne z celem ekranu powitalnego. Dostarczanie niektórych konfiguracji w `pliku config.xml` będzie automatycznie `show` splash na ekranie natychmiast po uruchomienie aplikacji i przed pełni rozpoczął i odebrał zdarzenie `deviceready`. Aby uzyskać więcej informacji na robienie tej konfiguracji, zobacz [ikony i ekrany powitalne w aplikacjach](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html). Z tego powodu jest mało prawdopodobne, należy zadzwonić `navigator.splashscreen.show()`, aby wyświetlić ekran powitalny dla uruchamiania aplikacji.
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/pl/index.md b/plugins/cordova-plugin-splashscreen/doc/pl/index.md deleted file mode 100644 index 33045cb7..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/pl/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -Ten plugin wyświetla i ukrywa ekran powitalny podczas uruchamiania aplikacji. - -## Instalacja - - cordova plugin add cordova-plugin-splashscreen - - -## Obsługiwane platformy - -* Amazon Fire OS -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 i 8 -* Windows 8 - -## Metody - -* splashscreen.show -* splashscreen.Hide - -### Dziwactwa Androida - -W pliku config.xml musisz dodać następujące preferencje: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -Gdzie foo jest nazwą pliku ekranu powitalnego, najlepiej 9 łatce. Upewnij się dodać pliki splashcreen do katalogu res/xml w odpowiednich folderach. Drugi parametr reprezentuje, jak długo ekranu powitalnego pojawi się w milisekundach. Domyślnie 3000 ms. Aby uzyskać więcej informacji, zobacz [ikony i ekrany powitalne w aplikacjach][1]. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.Hide - -Odrzucić ten opryskaæ têcza. - - navigator.splashscreen.hide(); - - -### Jeżyna 10, WP8, iOS dziwactwo - -Plik `config.xml` `AutoHideSplashScreen` ustawienie musi być `false`. Opóźnienia, ukrywanie ekranu powitalnego przez dwie sekundy, dodać timer następujących w `deviceready` obsługa zdarzeń: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -Wyświetla ekran powitalny. - - navigator.splashscreen.show(); - - -Aplikacja nie można wywołać `navigator.splashscreen.show()`, aż aplikacja została uruchomiona i zdarzenie `deviceready` został zwolniony. Ale ponieważ zazwyczaj opryskać tęcza ma być widoczne przed rozpoczęciem aplikacji, wydaje się sprzeczne z celem ekranu powitalnego. Dostarczanie niektórych konfiguracji w `pliku config.xml` będzie automatycznie `show` splash na ekranie natychmiast po uruchomienie aplikacji i przed pełni rozpoczął i odebrał zdarzenie `deviceready`. Aby uzyskać więcej informacji na robienie tej konfiguracji, zobacz [ikony i ekrany powitalne w aplikacjach][1]. Z tego powodu jest mało prawdopodobne, należy zadzwonić `navigator.splashscreen.show()`, aby wyświetlić ekran powitalny dla uruchamiania aplikacji. diff --git a/plugins/cordova-plugin-splashscreen/doc/ru/index.md b/plugins/cordova-plugin-splashscreen/doc/ru/index.md deleted file mode 100644 index 635c22d8..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/ru/index.md +++ /dev/null @@ -1,75 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -Этот плагин отображает и скрывает экран-заставку при запуске приложения. - -## Установка - - cordova plugin add cordova-plugin-splashscreen - - -## Поддерживаемые платформы - -* Amazon Fire OS -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 и 8 -* Windows 8 - -## Методы - -* splashscreen.show -* splashscreen.hide - -### Особенности Android - -В вашем файле config.xml необходимо добавить следующие настройки: - -`<preference name="SplashScreen" value="foo" />` `<preference name="SplashScreenDelay" value="10000" />` - -Где foo это имя файла splashscreen, желательно 9 заплатку. Убедитесь в том добавить ваши splashcreen файлы в папку res/xml в соответствующие папки. Второй параметр представляет, как долго splashscreen появится в миллисекундах. По умолчанию он 3000 МС. Увидеть [иконки и заставки][1] для получения дополнительной информации. - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.hide - -Закройте экран-заставка. - - Navigator.SplashScreen.Hide(); - - -### Особенности BlackBerry 10, WP8, iOS - -`config.xml`Файла `AutoHideSplashScreen` должен быть `false` . Для задержки скрытия заставки на две секунды, добавить таймер, например в `deviceready` обработчик событий: - - setTimeout(function() {navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -Отображает экран-заставку. - - Navigator.SplashScreen.Show(); - - -Ваше приложение не может вызвать `navigator.splashscreen.show()` до тех пор, пока приложение началась и `deviceready` событие инициировано. Но поскольку обычно экран-заставка должен быть видимым до начала вашего приложения, что казалось бы поражение цели экрана-заставки. Предоставление некоторых конфигурации в `config.xml` будет автоматически `show` экран-заставку сразу же после запуска вашего приложения и перед его полностью запущен и получил `deviceready` событие. Увидеть [иконки и заставки][1] для получения дополнительной информации на делать этой конфигурации. По этой причине маловероятно, вам нужно вызвать `navigator.splashscreen.show()` для отображения экрана-заставки для запуска приложения. diff --git a/plugins/cordova-plugin-splashscreen/doc/zh/README.md b/plugins/cordova-plugin-splashscreen/doc/zh/README.md deleted file mode 100644 index da37405b..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/zh/README.md +++ /dev/null @@ -1,119 +0,0 @@ -<!-- -# license: 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. ---> - -# cordova-plugin-splashscreen - -[](https://travis-ci.org/apache/cordova-plugin-splashscreen) - -這個外掛程式顯示和隱藏在應用程式啟動期間的初始螢幕。 - -## 安裝 - - // npm hosted (new) id - cordova plugin add cordova-plugin-splashscreen - // you may also install directly from this repo - cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git - - -## 支援的平臺 - - * 亞馬遜火 OS - * Android 系統 - * 黑莓 10 - * iOS - * Windows Phone 7 和 8 - * Windows 8 - * Windows - * 瀏覽器 - -## 方法 - - * splashscreen.show - * splashscreen.hide - -### Android 的怪癖 - -在你的`config.xml`,您需要添加以下優惠: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - <preference name="SplashMaintainAspectRatio" value="true|false" /> - - -美孚在哪裡閃屏檔,最好是 9 修補程式檔的名稱。 請確保您的 splashcreen 檔添加到 res/xml 目錄下相應的資料夾。 第二個參數表示多久閃屏會顯示以毫秒為單位。 它將預設為 3000 毫秒。 有關更多資訊,請參見 [圖示和啟動畫面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)。 - -"SplashMaintainAspectRatio"首選項是可選的。 如果設置為 true,可繪製的初始螢幕不會拉伸以適合螢幕,但相反只是"覆蓋"螢幕,像 CSS"背景-大小: 蓋"。 這是非常有用的不能以任何方式,例如當他們包含文本或風景畸變閃屏圖像時。 此設置適用于有大利潤 (安全區),可以安全地裁剪不同長寬比與螢幕上的圖像。 - -該外掛程式重新載入初始可繪製只要方向發生變化,所以您可以指定不同的畫板為縱向和橫向方向。 - -### 瀏覽器的怪癖 - -你可以用你的`config.xml`下列優先選項: - - <platform name="browser"> - <preference name="SplashScreen" value="images/browser/splashscreen.jpg" /> <!-- defaults to "img/logo.png" --> - <preference name="SplashScreenDelay" value="10000" /> <!-- defaults to "3000" --> - <preference name="SplashScreenBackgroundColor" value="green" /> <!-- defaults to "#464646" --> - <preference name="ShowSplashScreen" value="false" /> <!-- defaults to "true" --> - <preference name="SplashScreenWidth" value="600" /> <!-- defaults to "170" --> - <preference name="SplashScreenHeight" value="300" /> <!-- defaults to "200" --> - </platform> - - -### iOS 的怪癖 - - * `FadeSplashScreen`(預設為`true`的布林值): 設置為`false` ,以防止出現閃屏衰落和退出其顯示狀態發生變化時。 - - <preference name="FadeSplashScreen" value="false"/> - - - * `FadeSplashScreenDuration`(float,預設為`2`): 指定的閃屏秒數淡出效果來執行。 - - <preference name="FadeSplashScreenDuration" value="4"/> - - - * `ShowSplashScreenSpinner`(boolean, `true`的布林值): 設置為`false`來隱藏初始螢幕微調框。 - - <preference name="ShowSplashScreenSpinner" value="false"/> - - -## splashscreen.hide - -解雇的閃屏。 - - navigator.splashscreen.hide(); - - -### 黑莓 10,WP8,iOS 怪癖 - -`config.xml` 檔 `AutoHideSplashScreen` 設置必須是 `假` 的。 若要延遲兩秒鐘隱藏的閃屏,`deviceready` 事件處理常式中添加一個計時器,如下所示: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -顯示初始螢幕。 - - navigator.splashscreen.show(); - - -您的應用程式無法調用 `navigator.splashscreen.show()`,直到該應用程式已啟動,且觸發了 `deviceready` 事件。 但是,由於通常的閃屏為了是可見的在您的應用程式啟動之前,這似乎會打敗閃屏的目的。 提供一些配置在 `config.xml` 中的會自動 `show` 初始螢幕您的應用程式啟動後立即和之前它已經完全起步並收到 `deviceready` 事件。 做這種配置的詳細資訊,請參閱 [圖示和啟動畫面](http://cordova.apache.org/docs/en/edge/config_ref_images.md.html)。 出於此原因,不太可能您需要調用 `navigator.splashscreen.show()`,使初始螢幕可見為應用程式啟動。
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/doc/zh/index.md b/plugins/cordova-plugin-splashscreen/doc/zh/index.md deleted file mode 100644 index efb309d0..00000000 --- a/plugins/cordova-plugin-splashscreen/doc/zh/index.md +++ /dev/null @@ -1,78 +0,0 @@ -<!--- - 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. ---> - -# cordova-plugin-splashscreen - -這個外掛程式顯示和隱藏在應用程式啟動期間的初始螢幕。 - -## 安裝 - - cordova plugin add cordova-plugin-splashscreen - - -## 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* 黑莓 10 -* iOS -* Windows Phone 7 和 8 -* Windows 8 - -## 方法 - -* splashscreen.show -* splashscreen.hide - -### Android 的怪癖 - -在你的 config.xml,您需要添加以下優惠: - - <preference name="SplashScreen" value="foo" /> - <preference name="SplashScreenDelay" value="10000" /> - - -美孚在哪裡閃屏檔,最好是 9 修補程式檔的名稱。 請確保您的 splashcreen 檔添加到 res/xml 目錄下相應的資料夾。 第二個參數表示多久閃屏會顯示以毫秒為單位。 它將預設為 3000 毫秒。 有關更多資訊,請參見 [圖示和啟動畫面][1]。 - - [1]: http://cordova.apache.org/docs/en/edge/config_ref_images.md.html - -## splashscreen.hide - -解雇的閃屏。 - - navigator.splashscreen.hide(); - - -### 黑莓 10,WP8,iOS 怪癖 - -`config.xml` 檔 `AutoHideSplashScreen` 設置必須是 `假` 的。 若要延遲兩秒鐘隱藏的閃屏,`deviceready` 事件處理常式中添加一個計時器,如下所示: - - setTimeout(function() { - navigator.splashscreen.hide(); - }, 2000); - - -## splashscreen.show - -顯示初始螢幕。 - - navigator.splashscreen.show(); - - -您的應用程式無法調用 `navigator.splashscreen.show()`,直到該應用程式已啟動,且觸發了 `deviceready` 事件。 但是,由於通常的閃屏為了是可見的在您的應用程式啟動之前,這似乎會打敗閃屏的目的。 提供一些配置在 `config.xml` 中的會自動 `show` 初始螢幕您的應用程式啟動後立即和之前它已經完全起步並收到 `deviceready` 事件。 做這種配置的詳細資訊,請參閱 [圖示和啟動畫面][1]。 出於此原因,不太可能您需要調用 `navigator.splashscreen.show()`,使初始螢幕可見為應用程式啟動。 diff --git a/plugins/cordova-plugin-splashscreen/package.json b/plugins/cordova-plugin-splashscreen/package.json deleted file mode 100644 index 447ac7e9..00000000 --- a/plugins/cordova-plugin-splashscreen/package.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "name": "cordova-plugin-splashscreen", - "version": "2.1.0", - "description": "Cordova Splashscreen Plugin", - "cordova": { - "id": "cordova-plugin-splashscreen", - "platforms": [ - "android", - "amazon-fireos", - "ubuntu", - "ios", - "blackberry10", - "wp8", - "windows8", - "windows", - "tizen" - ] - }, - "repository": { - "type": "git", - "url": "https://github.com/apache/cordova-plugin-splashscreen" - }, - "keywords": [ - "cordova", - "splashscreen", - "ecosystem:cordova", - "cordova-android", - "cordova-amazon-fireos", - "cordova-ubuntu", - "cordova-ios", - "cordova-blackberry10", - "cordova-wp8", - "cordova-windows8", - "cordova-windows", - "cordova-tizen" - ], - "engines": [ - { - "name": "cordova-android", - "version": ">=3.6.0" - } - ], - "author": "Apache Software Foundation", - "license": "Apache 2.0" -} diff --git a/plugins/cordova-plugin-splashscreen/plugin.xml b/plugins/cordova-plugin-splashscreen/plugin.xml deleted file mode 100644 index e6370fa9..00000000 --- a/plugins/cordova-plugin-splashscreen/plugin.xml +++ /dev/null @@ -1,134 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-splashscreen" - version="2.1.0"> - <name>Splashscreen</name> - <description>Cordova Splashscreen Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,splashscreen</keywords> - <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git</repo> - <issue>https://issues.apache.org/jira/browse/CB/component/12320653</issue> - - <engines> - <engine name="cordova-android" version=">=3.6.0" /><!-- Requires CordovaPlugin.preferences --> - </engines> - - <js-module src="www/splashscreen.js" name="SplashScreen"> - <clobbers target="navigator.splashscreen" /> - </js-module> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="SplashScreen"> - <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen"/> - <param name="onload" value="true"/> - </feature> - </config-file> - - <source-file src="src/android/SplashScreen.java" target-dir="src/org/apache/cordova/splashscreen" /> - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="SplashScreen"> - <param name="android-package" value="org.apache.cordova.splashscreen.SplashScreen"/> - </feature> - </config-file> - - <source-file src="src/android/SplashScreen.java" target-dir="src/org/apache/cordova/splashscreen" /> - </platform> - - <!-- ubuntu --> - <platform name="ubuntu"> - <header-file src="src/ubuntu/splashscreen.h" /> - <source-file src="src/ubuntu/splashscreen.cpp" /> - </platform> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="SplashScreen"> - <param name="ios-package" value="CDVSplashScreen"/> - <param name="onload" value="true"/> - </feature> - </config-file> - - <header-file src="src/ios/CDVSplashScreen.h" /> - <source-file src="src/ios/CDVSplashScreen.m" /> - <header-file src="src/ios/CDVViewController+SplashScreen.h" /> - <source-file src="src/ios/CDVViewController+SplashScreen.m" /> - - <framework src="CoreGraphics.framework" /> - </platform> - - <!-- blackberry10 --> - <platform name="blackberry10"> - <source-file src="src/blackberry10/index.js" target-dir="SplashScreen" /> - <config-file target="www/config.xml" parent="/widget"> - <feature name="SplashScreen" value="SplashScreen"/> - </config-file> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="SplashScreen"> - <param name="wp-package" value="SplashScreen"/> - <param name="onload" value="true"/> - </feature> - </config-file> - - <source-file src="src/wp/SplashScreen.cs" /> - <source-file src="src/wp/ResolutionHelper.cs" /> - - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="www/windows/SplashScreenProxy.js" name="SplashScreenProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- windows --> - <platform name="windows"> - <js-module src="www/windows/SplashScreenProxy.js" name="SplashScreenProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- tizen --> - <platform name="tizen"> - <js-module src="src/tizen/SplashScreenProxy.js" name="SplashScreenProxy"> - <runs /> - </js-module> - </platform> - - <!-- browser --> - <platform name="browser"> - <js-module src="src/browser/SplashScreenProxy.js" name="SplashScreenProxy"> - <runs /> - </js-module> - </platform> -</plugin> diff --git a/plugins/cordova-plugin-splashscreen/src/android/SplashScreen.java b/plugins/cordova-plugin-splashscreen/src/android/SplashScreen.java deleted file mode 100644 index 75ad724c..00000000 --- a/plugins/cordova-plugin-splashscreen/src/android/SplashScreen.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - 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. -*/ - -package org.apache.cordova.splashscreen; - -import android.app.Dialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.res.Configuration; -import android.graphics.Color; -import android.os.Handler; -import android.view.Display; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; -import android.widget.ImageView; -import android.widget.LinearLayout; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.json.JSONArray; -import org.json.JSONException; - -public class SplashScreen extends CordovaPlugin { - private static final String LOG_TAG = "SplashScreen"; - // Cordova 3.x.x has a copy of this plugin bundled with it (SplashScreenInternal.java). - // Enable functionality only if running on 4.x.x. - private static final boolean HAS_BUILT_IN_SPLASH_SCREEN = Integer.valueOf(CordovaWebView.CORDOVA_VERSION.split("\\.")[0]) < 4; - private static Dialog splashDialog; - private static ProgressDialog spinnerDialog; - private static boolean firstShow = true; - - /** - * Displays the splash drawable. - */ - private ImageView splashImageView; - - /** - * Remember last device orientation to detect orientation changes. - */ - private int orientation; - - // Helper to be compile-time compatible with both Cordova 3.x and 4.x. - private View getView() { - try { - return (View)webView.getClass().getMethod("getView").invoke(webView); - } catch (Exception e) { - return (View)webView; - } - } - - @Override - protected void pluginInitialize() { - if (HAS_BUILT_IN_SPLASH_SCREEN || !firstShow) { - return; - } - // Make WebView invisible while loading URL - getView().setVisibility(View.INVISIBLE); - int drawableId = preferences.getInteger("SplashDrawableId", 0); - if (drawableId == 0) { - String splashResource = preferences.getString("SplashScreen", "screen"); - if (splashResource != null) { - drawableId = cordova.getActivity().getResources().getIdentifier(splashResource, "drawable", cordova.getActivity().getClass().getPackage().getName()); - if (drawableId == 0) { - drawableId = cordova.getActivity().getResources().getIdentifier(splashResource, "drawable", cordova.getActivity().getPackageName()); - } - preferences.set("SplashDrawableId", drawableId); - } - } - - // Save initial orientation. - orientation = cordova.getActivity().getResources().getConfiguration().orientation; - - firstShow = false; - loadSpinner(); - showSplashScreen(true); - } - - /** - * Shorter way to check value of "SplashMaintainAspectRatio" preference. - */ - private boolean isMaintainAspectRatio () { - return preferences.getBoolean("SplashMaintainAspectRatio", false); - } - - @Override - public void onPause(boolean multitasking) { - if (HAS_BUILT_IN_SPLASH_SCREEN) { - return; - } - // hide the splash screen to avoid leaking a window - this.removeSplashScreen(); - } - - @Override - public void onDestroy() { - if (HAS_BUILT_IN_SPLASH_SCREEN) { - return; - } - // hide the splash screen to avoid leaking a window - this.removeSplashScreen(); - // If we set this to true onDestroy, we lose track when we go from page to page! - //firstShow = true; - } - - @Override - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - if (action.equals("hide")) { - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - webView.postMessage("splashscreen", "hide"); - } - }); - } else if (action.equals("show")) { - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - webView.postMessage("splashscreen", "show"); - } - }); - } else if (action.equals("spinnerStart")) { - if (!HAS_BUILT_IN_SPLASH_SCREEN) { - final String title = args.getString(0); - final String message = args.getString(1); - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - spinnerStart(title, message); - } - }); - } - } else { - return false; - } - - callbackContext.success(); - return true; - } - - @Override - public Object onMessage(String id, Object data) { - if (HAS_BUILT_IN_SPLASH_SCREEN) { - return null; - } - if ("splashscreen".equals(id)) { - if ("hide".equals(data.toString())) { - this.removeSplashScreen(); - } else { - this.showSplashScreen(false); - } - } else if ("spinner".equals(id)) { - if ("stop".equals(data.toString())) { - this.spinnerStop(); - getView().setVisibility(View.VISIBLE); - } - } else if ("onReceivedError".equals(id)) { - spinnerStop(); - } - return null; - } - - // Don't add @Override so that plugin still compiles on 3.x.x for a while - public void onConfigurationChanged(Configuration newConfig) { - if (newConfig.orientation != orientation) { - orientation = newConfig.orientation; - - // Splash drawable may change with orientation, so reload it. - if (splashImageView != null) { - int drawableId = preferences.getInteger("SplashDrawableId", 0); - if (drawableId != 0) { - splashImageView.setImageDrawable(cordova.getActivity().getResources().getDrawable(drawableId)); - } - } - } - } - - private void removeSplashScreen() { - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - if (splashDialog != null && splashDialog.isShowing()) { - splashDialog.dismiss(); - splashDialog = null; - splashImageView = null; - } - } - }); - } - - /** - * Shows the splash screen over the full Activity - */ - @SuppressWarnings("deprecation") - private void showSplashScreen(final boolean hideAfterDelay) { - final int splashscreenTime = preferences.getInteger("SplashScreenDelay", 3000); - final int drawableId = preferences.getInteger("SplashDrawableId", 0); - - // If the splash dialog is showing don't try to show it again - if (splashDialog != null && splashDialog.isShowing()) { - return; - } - if (drawableId == 0 || (splashscreenTime <= 0 && hideAfterDelay)) { - return; - } - - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - // Get reference to display - Display display = cordova.getActivity().getWindowManager().getDefaultDisplay(); - Context context = webView.getContext(); - - // Use an ImageView to render the image because of its flexible scaling options. - splashImageView = new ImageView(context); - splashImageView.setImageResource(drawableId); - LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - splashImageView.setLayoutParams(layoutParams); - - splashImageView.setMinimumHeight(display.getHeight()); - splashImageView.setMinimumWidth(display.getWidth()); - - // TODO: Use the background color of the webView's parent instead of using the preference. - splashImageView.setBackgroundColor(preferences.getInteger("backgroundColor", Color.BLACK)); - - if (isMaintainAspectRatio()) { - // CENTER_CROP scale mode is equivalent to CSS "background-size:cover" - splashImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); - } - else { - // FIT_XY scales image non-uniformly to fit into image view. - splashImageView.setScaleType(ImageView.ScaleType.FIT_XY); - } - - // Create and show the dialog - splashDialog = new Dialog(context, android.R.style.Theme_Translucent_NoTitleBar); - // check to see if the splash screen should be full screen - if ((cordova.getActivity().getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) - == WindowManager.LayoutParams.FLAG_FULLSCREEN) { - splashDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - } - splashDialog.setContentView(splashImageView); - splashDialog.setCancelable(false); - splashDialog.show(); - - // Set Runnable to remove splash screen just in case - if (hideAfterDelay) { - final Handler handler = new Handler(); - handler.postDelayed(new Runnable() { - public void run() { - removeSplashScreen(); - } - }, splashscreenTime); - } - } - }); - } - - /* - * Load the spinner - */ - private void loadSpinner() { - // If loadingDialog property, then show the App loading dialog for first page of app - String loading = null; - if (webView.canGoBack()) { - loading = preferences.getString("LoadingDialog", null); - } - else { - loading = preferences.getString("LoadingPageDialog", null); - } - if (loading != null) { - String title = ""; - String message = "Loading Application..."; - - if (loading.length() > 0) { - int comma = loading.indexOf(','); - if (comma > 0) { - title = loading.substring(0, comma); - message = loading.substring(comma + 1); - } - else { - title = ""; - message = loading; - } - } - spinnerStart(title, message); - } - } - - private void spinnerStart(final String title, final String message) { - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - spinnerStop(); - spinnerDialog = ProgressDialog.show(webView.getContext(), title, message, true, true, - new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface dialog) { - spinnerDialog = null; - } - }); - } - }); - } - - private void spinnerStop() { - cordova.getActivity().runOnUiThread(new Runnable() { - public void run() { - if (spinnerDialog != null && spinnerDialog.isShowing()) { - spinnerDialog.dismiss(); - spinnerDialog = null; - } - } - }); - } -} diff --git a/plugins/cordova-plugin-splashscreen/src/blackberry10/index.js b/plugins/cordova-plugin-splashscreen/src/blackberry10/index.js deleted file mode 100644 index bd7e48c8..00000000 --- a/plugins/cordova-plugin-splashscreen/src/blackberry10/index.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013 Research In Motion Limited. - * - * Licensed 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. - */ - -module.exports = { - show: function (success, fail, args, env) { - var result = new PluginResult(args, env); - result.error("Not supported on platform", false); - }, - - hide: function (success, fail, args, env) { - var result = new PluginResult(args, env); - window.qnx.webplatform.getApplication().windowVisible = true; - result.ok(undefined, false); - } -}; diff --git a/plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js b/plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js deleted file mode 100644 index d19f8c87..00000000 --- a/plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js +++ /dev/null @@ -1,138 +0,0 @@ -/* - * - * 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. - * -*/ -// Default parameter values including image size can be changed in `config.xml` -var splashImageWidth = 170; -var splashImageHeight = 200; -var position = { x: 0, y: 0, width: splashImageWidth, height: splashImageHeight }; -var splash = null; // -var localSplash; // the image to display -var localSplashImage; -var bgColor = "#464646"; -var imageSrc = 'img/logo.png'; -var splashScreenDelay = 3000; // in milliseconds -var showSplashScreen = true; // show splashcreen by default -var configHelper = cordova.require('cordova/confighelper'); - -function updateImageLocation() { - position.width = Math.min(splashImageWidth, window.innerWidth); - position.height = position.width * (splashImageHeight / splashImageWidth); - - localSplash.style.width = window.innerWidth + "px"; - localSplash.style.height = window.innerHeight + "px"; - localSplash.style.top = "0px"; - localSplash.style.left = "0px"; - - localSplashImage.style.top = "50%"; - localSplashImage.style.left = "50%"; - localSplashImage.style.height = position.height + "px"; - localSplashImage.style.width = position.width + "px"; - localSplashImage.style.marginTop = (-position.height / 2) + "px"; - localSplashImage.style.marginLeft = (-position.width / 2) + "px"; -} - -function onResize() { - updateImageLocation(); -} - -var SplashScreen = { - setBGColor: function (cssBGColor) { - bgColor = cssBGColor; - if (localSplash) { - localSplash.style.backgroundColor = bgColor; - } - }, - show: function () { - if(!localSplash) { - window.addEventListener("resize", onResize, false); - localSplash = document.createElement("div"); - localSplash.style.backgroundColor = bgColor; - localSplash.style.position = "absolute"; - - localSplashImage = document.createElement("img"); - localSplashImage.src = imageSrc; - localSplashImage.style.position = "absolute"; - - updateImageLocation(); - - localSplash.appendChild(localSplashImage); - document.body.appendChild(localSplash); - } - }, - hide: function () { - if(localSplash) { - window.removeEventListener("resize", onResize, false); - document.body.removeChild(localSplash); - localSplash = null; - } - } -}; - -/** - * Reads preferences via ConfigHelper and substitutes default parameters. - */ -function readPreferencesFromCfg(cfg) { - try { - var value = cfg.getPreferenceValue('ShowSplashScreen'); - if(typeof value != 'undefined') { - showSplashScreen = value === 'true'; - } - - splashScreenDelay = cfg.getPreferenceValue('SplashScreenDelay') || splashScreenDelay; - imageSrc = cfg.getPreferenceValue('SplashScreen') || imageSrc; - bgColor = cfg.getPreferenceValue('SplashScreenBackgroundColor') || bgColor; - splashImageWidth = cfg.getPreferenceValue('SplashScreenWidth') || splashImageWidth; - splashImageHeight = cfg.getPreferenceValue('SplashScreenHeight') || splashImageHeight; - } catch(e) { - var msg = '[Browser][SplashScreen] Error occured on loading preferences from config.xml: ' + JSON.stringify(e); - console.error(msg); - error(msg); - } -} - -/** - * Shows and hides splashscreen if it is enabled, with a delay according the current preferences. - */ -function showAndHide() { - if(showSplashScreen) { - SplashScreen.show(); - - window.setTimeout(function() { - SplashScreen.hide(); - }, splashScreenDelay); - } -} - -/** - * Tries to read config.xml and override default properties and then shows and hides splashcreen if it is enabled. - */ -(function initAndShow() { - configHelper.readConfig(function(config) { - readPreferencesFromCfg(config); - showAndHide(); - }, function(err) { - console.error(err); - }); -})(); - -module.exports = SplashScreen; - -require("cordova/exec/proxy").add("SplashScreen", SplashScreen); - diff --git a/plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.h b/plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.h deleted file mode 100644 index 0d6ae397..00000000 --- a/plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> - -typedef struct { - BOOL iPhone; - BOOL iPad; - BOOL iPhone5; - BOOL iPhone6; - BOOL iPhone6Plus; - BOOL retina; - -} CDV_iOSDevice; - -@interface CDVSplashScreen : CDVPlugin { - UIActivityIndicatorView* _activityView; - UIImageView* _imageView; - NSString* _curImageName; - BOOL _visible; -} - -- (void)show:(CDVInvokedUrlCommand*)command; -- (void)hide:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.m b/plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.m deleted file mode 100644 index 43b356ad..00000000 --- a/plugins/cordova-plugin-splashscreen/src/ios/CDVSplashScreen.m +++ /dev/null @@ -1,330 +0,0 @@ -/* - 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 "CDVSplashScreen.h" -#import <Cordova/CDVViewController.h> -#import <Cordova/CDVScreenOrientationDelegate.h> -#import "CDVViewController+SplashScreen.h" - -#define kSplashScreenDurationDefault 0.25f - - -@implementation CDVSplashScreen - -- (void)pluginInitialize -{ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:self.webView]; - - [self setVisible:YES]; -} - -- (void)show:(CDVInvokedUrlCommand*)command -{ - [self setVisible:YES]; -} - -- (void)hide:(CDVInvokedUrlCommand*)command -{ - [self setVisible:NO]; -} - -- (void)pageDidLoad -{ - id autoHideSplashScreenValue = [self.commandDelegate.settings objectForKey:[@"AutoHideSplashScreen" lowercaseString]]; - - // if value is missing, default to yes - if ((autoHideSplashScreenValue == nil) || [autoHideSplashScreenValue boolValue]) { - [self setVisible:NO]; - } -} - -- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context -{ - [self updateImage]; -} - -- (void)createViews -{ - /* - * The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style. - * - * whiteLarge = UIActivityIndicatorViewStyleWhiteLarge - * white = UIActivityIndicatorViewStyleWhite - * gray = UIActivityIndicatorViewStyleGray - * - */ - - // Determine whether rotation should be enabled for this device - // Per iOS HIG, landscape is only supported on iPad and iPhone 6+ - CDV_iOSDevice device = [self getCurrentDevice]; - BOOL autorotateValue = (device.iPad || device.iPhone6Plus) ? - [(CDVViewController *)self.viewController shouldAutorotateDefaultValue] : - NO; - - [(CDVViewController *)self.viewController setEnabledAutorotation:autorotateValue]; - - NSString* topActivityIndicator = [self.commandDelegate.settings objectForKey:[@"TopActivityIndicator" lowercaseString]]; - UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray; - - if ([topActivityIndicator isEqualToString:@"whiteLarge"]) { - topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge; - } else if ([topActivityIndicator isEqualToString:@"white"]) { - topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite; - } else if ([topActivityIndicator isEqualToString:@"gray"]) { - topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray; - } - - UIView* parentView = self.viewController.view; - parentView.userInteractionEnabled = NO; // disable user interaction while splashscreen is shown - _activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle]; - _activityView.center = CGPointMake(parentView.bounds.size.width / 2, parentView.bounds.size.height / 2); - _activityView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin - | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin; - [_activityView startAnimating]; - - // Set the frame & image later. - _imageView = [[UIImageView alloc] init]; - [parentView addSubview:_imageView]; - - id showSplashScreenSpinnerValue = [self.commandDelegate.settings objectForKey:[@"ShowSplashScreenSpinner" lowercaseString]]; - // backwards compatibility - if key is missing, default to true - if ((showSplashScreenSpinnerValue == nil) || [showSplashScreenSpinnerValue boolValue]) { - [parentView addSubview:_activityView]; - } - - // Frame is required when launching in portrait mode. - // Bounds for landscape since it captures the rotation. - [parentView addObserver:self forKeyPath:@"frame" options:0 context:nil]; - [parentView addObserver:self forKeyPath:@"bounds" options:0 context:nil]; - - [self updateImage]; -} - -- (void)destroyViews -{ - [(CDVViewController *)self.viewController setEnabledAutorotation:[(CDVViewController *)self.viewController shouldAutorotateDefaultValue]]; - - [_imageView removeFromSuperview]; - [_activityView removeFromSuperview]; - _imageView = nil; - _activityView = nil; - _curImageName = nil; - - self.viewController.view.userInteractionEnabled = YES; // re-enable user interaction upon completion - [self.viewController.view removeObserver:self forKeyPath:@"frame"]; - [self.viewController.view removeObserver:self forKeyPath:@"bounds"]; -} - -- (CDV_iOSDevice) getCurrentDevice -{ - CDV_iOSDevice device; - - UIScreen* mainScreen = [UIScreen mainScreen]; - CGFloat mainScreenHeight = mainScreen.bounds.size.height; - CGFloat mainScreenWidth = mainScreen.bounds.size.width; - - int limit = MAX(mainScreenHeight,mainScreenWidth); - - device.iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad); - device.iPhone = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone); - device.retina = ([mainScreen scale] == 2.0); - device.iPhone5 = (device.iPhone && limit == 568.0); - // note these below is not a true device detect, for example if you are on an - // iPhone 6/6+ but the app is scaled it will prob set iPhone5 as true, but - // this is appropriate for detecting the runtime screen environment - device.iPhone6 = (device.iPhone && limit == 667.0); - device.iPhone6Plus = (device.iPhone && limit == 736.0); - - return device; -} - -- (NSString*)getImageName:(UIInterfaceOrientation)currentOrientation delegate:(id<CDVScreenOrientationDelegate>)orientationDelegate device:(CDV_iOSDevice)device -{ - // Use UILaunchImageFile if specified in plist. Otherwise, use Default. - NSString* imageName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchImageFile"]; - - NSUInteger supportedOrientations = [orientationDelegate supportedInterfaceOrientations]; - - // Checks to see if the developer has locked the orientation to use only one of Portrait or Landscape - BOOL supportsLandscape = (supportedOrientations & UIInterfaceOrientationMaskLandscape); - BOOL supportsPortrait = (supportedOrientations & UIInterfaceOrientationMaskPortrait || supportedOrientations & UIInterfaceOrientationMaskPortraitUpsideDown); - // this means there are no mixed orientations in there - BOOL isOrientationLocked = !(supportsPortrait && supportsLandscape); - - if (imageName) { - imageName = [imageName stringByDeletingPathExtension]; - } else { - imageName = @"Default"; - } - - if (device.iPhone5) { // does not support landscape - imageName = [imageName stringByAppendingString:@"-568h"]; - } else if (device.iPhone6) { // does not support landscape - imageName = [imageName stringByAppendingString:@"-667h"]; - } else if (device.iPhone6Plus) { // supports landscape - if (isOrientationLocked) { - imageName = [imageName stringByAppendingString:(supportsLandscape ? @"-Landscape" : @"")]; - } else { - switch (currentOrientation) { - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - imageName = [imageName stringByAppendingString:@"-Landscape"]; - break; - default: - break; - } - } - imageName = [imageName stringByAppendingString:@"-736h"]; - - } else if (device.iPad) { // supports landscape - if (isOrientationLocked) { - imageName = [imageName stringByAppendingString:(supportsLandscape ? @"-Landscape" : @"-Portrait")]; - } else { - switch (currentOrientation) { - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - imageName = [imageName stringByAppendingString:@"-Landscape"]; - break; - - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - default: - imageName = [imageName stringByAppendingString:@"-Portrait"]; - break; - } - } - } - - return imageName; -} - -// Sets the view's frame and image. -- (void)updateImage -{ - NSString* imageName = [self getImageName:[[UIApplication sharedApplication] statusBarOrientation] delegate:(id<CDVScreenOrientationDelegate>)self.viewController device:[self getCurrentDevice]]; - - if (![imageName isEqualToString:_curImageName]) { - UIImage* img = [UIImage imageNamed:imageName]; - _imageView.image = img; - _curImageName = imageName; - } - - // Check that splash screen's image exists before updating bounds - if (_imageView.image) { - [self updateBounds]; - } else { - NSLog(@"WARNING: The splashscreen image named %@ was not found", imageName); - } -} - -- (void)updateBounds -{ - UIImage* img = _imageView.image; - CGRect imgBounds = (img) ? CGRectMake(0, 0, img.size.width, img.size.height) : CGRectZero; - - CGSize screenSize = [self.viewController.view convertRect:[UIScreen mainScreen].bounds fromView:nil].size; - UIInterfaceOrientation orientation = self.viewController.interfaceOrientation; - CGAffineTransform imgTransform = CGAffineTransformIdentity; - - /* If and only if an iPhone application is landscape-only as per - * UISupportedInterfaceOrientations, the view controller's orientation is - * landscape. In this case the image must be rotated in order to appear - * correctly. - */ - BOOL isIPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad; - if (UIInterfaceOrientationIsLandscape(orientation) && !isIPad) { - imgTransform = CGAffineTransformMakeRotation(M_PI / 2); - imgBounds.size = CGSizeMake(imgBounds.size.height, imgBounds.size.width); - } - - // There's a special case when the image is the size of the screen. - if (CGSizeEqualToSize(screenSize, imgBounds.size)) { - CGRect statusFrame = [self.viewController.view convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil]; - if (!(IsAtLeastiOSVersion(@"7.0"))) { - imgBounds.origin.y -= statusFrame.size.height; - } - } else if (imgBounds.size.width > 0) { - CGRect viewBounds = self.viewController.view.bounds; - CGFloat imgAspect = imgBounds.size.width / imgBounds.size.height; - CGFloat viewAspect = viewBounds.size.width / viewBounds.size.height; - // This matches the behaviour of the native splash screen. - CGFloat ratio; - if (viewAspect > imgAspect) { - ratio = viewBounds.size.width / imgBounds.size.width; - } else { - ratio = viewBounds.size.height / imgBounds.size.height; - } - imgBounds.size.height *= ratio; - imgBounds.size.width *= ratio; - } - - _imageView.transform = imgTransform; - _imageView.frame = imgBounds; -} - -- (void)setVisible:(BOOL)visible -{ - if (visible == _visible) { - return; - } - _visible = visible; - - id fadeSplashScreenValue = [self.commandDelegate.settings objectForKey:[@"FadeSplashScreen" lowercaseString]]; - id fadeSplashScreenDuration = [self.commandDelegate.settings objectForKey:[@"FadeSplashScreenDuration" lowercaseString]]; - - float fadeDuration = fadeSplashScreenDuration == nil ? kSplashScreenDurationDefault : [fadeSplashScreenDuration floatValue]; - - if ((fadeSplashScreenValue == nil) || ![fadeSplashScreenValue boolValue]) { - fadeDuration = 0; - } - - // Never animate the showing of the splash screen. - if (visible) { - if (_imageView == nil) { - [self createViews]; - } - } else if (fadeDuration == 0) { - [self destroyViews]; - } else { - __weak __typeof(self) weakSelf = self; - - [UIView transitionWithView:self.viewController.view - duration:fadeDuration - options:UIViewAnimationOptionTransitionNone - animations:^(void) { - __typeof(self) strongSelf = weakSelf; - if (strongSelf != nil) { - dispatch_async(dispatch_get_main_queue(), ^{ - [strongSelf->_activityView setAlpha:0]; - [strongSelf->_imageView setAlpha:0]; - }); - } - } - completion:^(BOOL finished) { - if (finished) { - dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf destroyViews]; - }); - } - } - ]; - } -} - -@end diff --git a/plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.h b/plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.h deleted file mode 100644 index a948ea31..00000000 --- a/plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - 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 <Cordova/CDVViewController.h> - -@interface CDVViewController (SplashScreen) - -@property (nonatomic, assign) BOOL enabledAutorotation; -@property (nonatomic, readonly) BOOL shouldAutorotateDefaultValue; - - -@end diff --git a/plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.m b/plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.m deleted file mode 100644 index 5736b6f2..00000000 --- a/plugins/cordova-plugin-splashscreen/src/ios/CDVViewController+SplashScreen.m +++ /dev/null @@ -1,82 +0,0 @@ -/* - 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 "CDVViewController+SplashScreen.h" -#import <objc/runtime.h> - -@implementation CDVViewController (SplashScreen) - -@dynamic enabledAutorotation; - -- (void)setEnabledAutorotation:(BOOL)value -{ - objc_setAssociatedObject(self, - @selector(enabledAutorotation), - [NSNumber numberWithBool:value], - OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (BOOL)enabledAutorotation -{ - NSNumber *number = (NSNumber *)objc_getAssociatedObject(self, @selector(enabledAutorotation)); - return [number boolValue]; -} - -+ (void)load -{ - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class class = [self class]; - - SEL originalSelector = @selector(shouldAutorotate); - SEL swizzledSelector = @selector(splash_shouldAutorotate); - - Method originalMethod = class_getInstanceMethod(class, originalSelector); - Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); - - BOOL didAddMethod = class_addMethod(class, - originalSelector, - method_getImplementation(swizzledMethod), - method_getTypeEncoding(swizzledMethod)); - - if (didAddMethod) { - class_replaceMethod(class, - swizzledSelector, - method_getImplementation(originalMethod), - method_getTypeEncoding(originalMethod)); - } else { - method_exchangeImplementations(originalMethod, swizzledMethod); - } - }); -} - -#pragma mark - Method Swizzling - -- (BOOL)splash_shouldAutorotate -{ - return self.enabledAutorotation; -} - - -- (BOOL)shouldAutorotateDefaultValue -{ - return [self splash_shouldAutorotate]; -} - -@end diff --git a/plugins/cordova-plugin-splashscreen/src/tizen/SplashScreenProxy.js b/plugins/cordova-plugin-splashscreen/src/tizen/SplashScreenProxy.js deleted file mode 100644 index fbd9f35f..00000000 --- a/plugins/cordova-plugin-splashscreen/src/tizen/SplashScreenProxy.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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. - * -*/ - -( function() { - -win = null; - -module.exports = { - show: function() { - if ( win === null ) { - win = window.open('splashscreen.html'); - } - }, - - hide: function() { - if ( win !== null ) { - win.close(); - win = null; - } - } -}; - -require("cordova/tizen/commandProxy").add("SplashScreen", module.exports); - -})(); diff --git a/plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.cpp b/plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.cpp deleted file mode 100644 index 1c9ecac8..00000000 --- a/plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2013 Canonical Ltd. - * - * 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 <QQuickItem> - -#include "splashscreen.h" -#include <cordova.h> - -#define SPLASHSCREEN_STATE_NAME "splashscreen" - -Splashscreen::Splashscreen(Cordova *cordova): CPlugin(cordova) { -} - -void Splashscreen::show(int, int) { - m_cordova->rootObject()->setProperty("splashscreenPath", m_cordova->getSplashscreenPath()); - - m_cordova->pushViewState(SPLASHSCREEN_STATE_NAME); -} - -void Splashscreen::hide(int, int) { - m_cordova->popViewState(SPLASHSCREEN_STATE_NAME); -} diff --git a/plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.h b/plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.h deleted file mode 100644 index 1d437f84..00000000 --- a/plugins/cordova-plugin-splashscreen/src/ubuntu/splashscreen.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2013 Canonical Ltd. - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -#ifndef SPLASHSCREEN_H -#define SPLASHSCREEN_H - -#include <QtCore> -#include <cplugin.h> - -class Splashscreen: public CPlugin { - Q_OBJECT -public: - explicit Splashscreen(Cordova *cordova); - - virtual const QString fullName() override { - return Splashscreen::fullID(); - } - - virtual const QString shortName() override { - return "SplashScreen"; - } - - static const QString fullID() { - return "SplashScreen"; - } - -public slots: - void show(int, int); - void hide(int, int); -}; - -#endif // SPLASHSCREEN_H diff --git a/plugins/cordova-plugin-splashscreen/src/wp/ResolutionHelper.cs b/plugins/cordova-plugin-splashscreen/src/wp/ResolutionHelper.cs deleted file mode 100644 index 050c3927..00000000 --- a/plugins/cordova-plugin-splashscreen/src/wp/ResolutionHelper.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - Licensed 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. -*/ - -using Microsoft.Phone.Info; -using System; -using System.Windows; - -namespace WPCordovaClassLib.Cordova.Commands -{ - public enum Resolutions { WVGA, WXGA, HD }; - - public static class ResolutionHelper - { - public static Resolutions CurrentResolution - { - get - { - switch (Application.Current.Host.Content.ScaleFactor) - { - case 100: return Resolutions.WVGA; - case 160: return Resolutions.WXGA; - case 150: return Resolutions.HD; - } - throw new InvalidOperationException("Unknown resolution"); - } - } - } -}
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/src/wp/SplashScreen.cs b/plugins/cordova-plugin-splashscreen/src/wp/SplashScreen.cs deleted file mode 100644 index 680a8058..00000000 --- a/plugins/cordova-plugin-splashscreen/src/wp/SplashScreen.cs +++ /dev/null @@ -1,252 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using Microsoft.Phone.Info; -using System.Windows.Controls.Primitives; -using System.Diagnostics; -using System.Windows.Media.Imaging; -using System.Windows.Resources; -using System.IO; -using System.Xml.Linq; -using System.Linq; -using System.Windows.Threading; - -namespace WPCordovaClassLib.Cordova.Commands -{ - /// <summary> - /// Listens for changes to the state of the battery on the device. - /// Currently only the "isPlugged" parameter available via native APIs. - /// </summary> - public class SplashScreen : BaseCommand - { - private Popup popup; - - // Time until we dismiss the splashscreen - private int prefDelay = 3000; - - // Whether we hide it by default - private bool prefAutoHide = true; - - // Path to image to use - private string prefImagePath = "SplashScreenImage.jpg"; - - // static because autodismiss is only ever applied once, at app launch - // subsequent page loads should not cause the SplashScreen to be shown. - private static bool WasShown = false; - - public SplashScreen() - { - LoadConfigPrefs(); - - Image SplashScreen = new Image() - { - Height = Application.Current.Host.Content.ActualHeight, - Width = Application.Current.Host.Content.ActualWidth, - Stretch = Stretch.Fill - }; - - var imageResource = GetSplashScreenImageResource(); - if (imageResource != null) - { - BitmapImage splash_image = new BitmapImage(); - splash_image.SetSource(imageResource.Stream); - SplashScreen.Source = splash_image; - } - - // Instansiate the popup and set the Child property of Popup to SplashScreen - popup = new Popup() { IsOpen = false, - Child = SplashScreen, - HorizontalAlignment = HorizontalAlignment.Stretch, - VerticalAlignment = VerticalAlignment.Center - - }; - } - - public override void OnInit() - { - // we only want to autoload on the first page load. - // but OnInit is called for every page load. - if (!SplashScreen.WasShown) - { - SplashScreen.WasShown = true; - show(); - } - } - - private void LoadConfigPrefs() - { - StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("config.xml", UriKind.Relative)); - if (streamInfo != null) - { - using (StreamReader sr = new StreamReader(streamInfo.Stream)) - { - //This will Read Keys Collection for the xml file - XDocument configFile = XDocument.Parse(sr.ReadToEnd()); - - string configAutoHide = configFile.Descendants() - .Where(x => (string)x.Attribute("name") == "AutoHideSplashScreen") - .Select(x => (string)x.Attribute("value")) - .FirstOrDefault(); - - bool bVal; - prefAutoHide = bool.TryParse(configAutoHide, out bVal) ? bVal : prefAutoHide; - - string configDelay = configFile.Descendants() - .Where(x => (string)x.Attribute("name") == "SplashScreenDelay") - .Select(x => (string)x.Attribute("value")) - .FirstOrDefault(); - int nVal; - prefDelay = int.TryParse(configDelay, out nVal) ? nVal : prefDelay; - - string configImage = configFile.Descendants() - .Where(x => (string)x.Attribute("name") == "SplashScreen") - .Select(x => (string)x.Attribute("value")) - .FirstOrDefault(); - - if (!String.IsNullOrEmpty(configImage)) - { - prefImagePath = configImage; - } - } - } - } - - private StreamResourceInfo GetSplashScreenImageResource() - { - // Get the base filename for the splash screen images - string imageName = System.IO.Path.GetFileNameWithoutExtension(prefImagePath); - Uri imageUri = null; - StreamResourceInfo imageResource = null; - - // First, try to get a resolution-specific splashscreen - try - { - // Determine the device's resolution - switch (ResolutionHelper.CurrentResolution) - { - case Resolutions.HD: - imageUri = new Uri(imageName + ".screen-720p.jpg", UriKind.Relative); - break; - - case Resolutions.WVGA: - imageUri = new Uri(imageName + ".screen-WVGA.jpg", UriKind.Relative); - break; - - case Resolutions.WXGA: - default: - imageUri = new Uri(imageName + ".screen-WXGA.jpg", UriKind.Relative); - break; - } - - imageResource = Application.GetResourceStream(imageUri); - } - catch (Exception) - { - // It's OK if we didn't get a resolution-specific image - } - - // Fallback to the default image name without decoration - if (imageResource == null) - { - imageUri = new Uri(prefImagePath, UriKind.Relative); - imageResource = Application.GetResourceStream(imageUri); - } - - if (imageUri != null) Debug.WriteLine("INFO :: SplashScreen: using image {0}", imageUri.OriginalString); - - return imageResource; - } - - public void show(string options = null) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - if (!popup.IsOpen) - { - popup.Child.Opacity = 0; - - Storyboard story = new Storyboard(); - DoubleAnimation animation = new DoubleAnimation() - { - From = 0.0, - To = 1.0, - Duration = new Duration(TimeSpan.FromSeconds(0.2)) - }; - - Storyboard.SetTarget(animation, popup.Child); - Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")); - story.Children.Add(animation); - - story.Begin(); - - popup.IsOpen = true; - - if (prefAutoHide) - { - StartAutoHideTimer(); - } - } - }); - } - - public void hide(string options = null) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - if (popup.IsOpen) - { - popup.Child.Opacity = 1.0; - - Storyboard story = new Storyboard(); - DoubleAnimation animation = new DoubleAnimation() - { - From = 1.0, - To = 0.0, - Duration = new Duration(TimeSpan.FromSeconds(0.4)) - }; - - Storyboard.SetTarget(animation, popup.Child); - Storyboard.SetTargetProperty(animation, new PropertyPath("Opacity")); - story.Children.Add(animation); - story.Completed += (object sender, EventArgs e) => - { - popup.IsOpen = false; - }; - story.Begin(); - } - }); - } - - private void StartAutoHideTimer() - { - var timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(prefDelay) }; - timer.Tick += (object sender, EventArgs e) => - { - hide(); - timer.Stop(); - }; - timer.Start(); - } - } -} diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/contents.xcworkspacedata b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 2dd325a0..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Workspace - version = "1.0"> - <FileRef - location = "container:CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj"> - </FileRef> -</Workspace> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/CDVSplashScreenTest.xccheckout b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/CDVSplashScreenTest.xccheckout deleted file mode 100644 index 7e4cdb93..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/CDVSplashScreenTest.xccheckout +++ /dev/null @@ -1,41 +0,0 @@ -<?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>IDESourceControlProjectFavoriteDictionaryKey</key> - <false/> - <key>IDESourceControlProjectIdentifier</key> - <string>6BE9AD73-1B9F-4362-98D7-DC631BEC6185</string> - <key>IDESourceControlProjectName</key> - <string>CDVSplashScreenTest</string> - <key>IDESourceControlProjectOriginsDictionary</key> - <dict> - <key>BEF5A5D0FF64801E558286389440357A9233D7DB</key> - <string>https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git</string> - </dict> - <key>IDESourceControlProjectPath</key> - <string>tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj</string> - <key>IDESourceControlProjectRelativeInstallPathDictionary</key> - <dict> - <key>BEF5A5D0FF64801E558286389440357A9233D7DB</key> - <string>../../../../..</string> - </dict> - <key>IDESourceControlProjectURL</key> - <string>https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git</string> - <key>IDESourceControlProjectVersion</key> - <integer>111</integer> - <key>IDESourceControlProjectWCCIdentifier</key> - <string>BEF5A5D0FF64801E558286389440357A9233D7DB</string> - <key>IDESourceControlProjectWCConfigurations</key> - <array> - <dict> - <key>IDESourceControlRepositoryExtensionIdentifierKey</key> - <string>public.vcs.git</string> - <key>IDESourceControlWCCIdentifierKey</key> - <string>BEF5A5D0FF64801E558286389440357A9233D7DB</string> - <key>IDESourceControlWCCName</key> - <string>cordova-plugin-splashscreen</string> - </dict> - </array> -</dict> -</plist> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/xcschemes/CordovaLib.xcscheme b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/xcschemes/CordovaLib.xcscheme deleted file mode 100644 index 13f9a157..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest.xcworkspace/xcshareddata/xcschemes/CordovaLib.xcscheme +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0600" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "D2AAC07D0554694100DB518D" - BuildableName = "libCordova.a" - BlueprintName = "CordovaLib" - ReferencedContainer = "container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <Testables> - </Testables> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - allowLocationSimulation = "YES"> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "D2AAC07D0554694100DB518D" - BuildableName = "libCordova.a" - BlueprintName = "CordovaLib" - ReferencedContainer = "container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj"> - </BuildableReference> - </MacroExpansion> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" - debugDocumentVersioning = "YES"> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "D2AAC07D0554694100DB518D" - BuildableName = "libCordova.a" - BlueprintName = "CordovaLib" - ReferencedContainer = "container:node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/.npmignore b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/.npmignore deleted file mode 100644 index c795b054..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/.npmignore +++ /dev/null @@ -1 +0,0 @@ -build
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTest.m b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTest.m deleted file mode 100644 index 1637d247..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTest.m +++ /dev/null @@ -1,702 +0,0 @@ -/* - 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 <XCTest/XCTest.h> -#import <Cordova/CDVScreenOrientationDelegate.h> -#import "CDVSplashScreen.h" -#import "ImageNameTestDelegates.h" - -const CDV_iOSDevice CDV_iOSDeviceZero = { 0, 0, 0, 0, 0, 0 }; - -@interface ImageNameTest : XCTestCase - -@property (nonatomic, strong) CDVSplashScreen* plugin; - -@end - -@interface CDVSplashScreen () - -// expose private interface -- (NSString*)getImageName:(UIInterfaceOrientation)currentOrientation delegate:(id<CDVScreenOrientationDelegate>)orientationDelegate device:(CDV_iOSDevice)device; - -@end - -@implementation ImageNameTest - -- (void)setUp { - [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. - - self.plugin = [[CDVSplashScreen alloc] init]; -} - -- (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. - [super tearDown]; -} - -- (void) orientationHelper:(id<CDVScreenOrientationDelegate>)delegate expectedImageNameDictionary:(NSDictionary*)expectedImageNameDictionary device:(CDV_iOSDevice)device{ - - NSString* name = nil; - NSString* expectedImageName = nil; - UIInterfaceOrientation currentOrientation; - NSString* deviceName = device.iPad? @"iPad" : device.iPhone6Plus? @"iPhone6Plus": device.iPhone6? @"iPhone6": device.iPhone5? @"iPhone5" : @"iPhone"; - - // LandscapeLeft, should always return expectedImageName - currentOrientation = UIInterfaceOrientationLandscapeLeft; - name = [self.plugin getImageName:currentOrientation delegate:delegate device:device]; - expectedImageName = [expectedImageNameDictionary objectForKey:@"landscapeLeft"]; - XCTAssertTrue([expectedImageName isEqualToString:name], @"%@ - %@ failed (%@)", @"Landscape", deviceName, name); - - // LandscapeRight - should always return expectedImageName - currentOrientation = UIInterfaceOrientationLandscapeRight; - name = [self.plugin getImageName:currentOrientation delegate:delegate device:device]; - expectedImageName = [expectedImageNameDictionary objectForKey:@"landscapeRight"]; - XCTAssertTrue([expectedImageName isEqualToString:name], @"%@ - %@ failed (%@)", @"Landscape", deviceName, name); - - // Portrait - should always return expectedImageName - currentOrientation = UIInterfaceOrientationPortrait; - name = [self.plugin getImageName:currentOrientation delegate:delegate device:device]; - expectedImageName = [expectedImageNameDictionary objectForKey:@"portrait"]; - XCTAssertTrue([expectedImageName isEqualToString:name], @"%@ - %@ failed (%@)", @"Portrait", deviceName, name); - - // PortraitUpsideDown - should always return expectedImageName - currentOrientation = UIInterfaceOrientationPortraitUpsideDown; - name = [self.plugin getImageName:currentOrientation delegate:delegate device:device]; - expectedImageName = [expectedImageNameDictionary objectForKey:@"portraitUpsideDown"]; - XCTAssertTrue([expectedImageName isEqualToString:name], @"%@ - %@ failed (%@)", @"Portrait", deviceName, name); -} - -- (void)testiPadOrientation { - - CDV_iOSDevice device = CDV_iOSDeviceZero; - device.iPad = YES; - - // One orientation - - PortraitOnly* delegate = [[PortraitOnly alloc] init]; - [self orientationHelper:delegate expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Portrait", - @"landscapeRight" : @"Default-Portrait", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init]; - [self orientationHelper:delegate2 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Portrait", - @"landscapeRight" : @"Default-Portrait", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate3 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Landscape", - @"portraitUpsideDown" : @"Default-Landscape" - } - device:device]; - - LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init]; - [self orientationHelper:delegate4 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Landscape", - @"portraitUpsideDown" : @"Default-Landscape" - } - device:device]; - - // All Portrait - - AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init]; - [self orientationHelper:delegate5 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Portrait", - @"landscapeRight" : @"Default-Portrait", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - // All Landscape - - AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init]; - [self orientationHelper:delegate6 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Landscape", - @"portraitUpsideDown" : @"Default-Landscape" - } - device:device]; - - - // All orientations - - AllOrientations* delegate7 = [[AllOrientations alloc] init]; - [self orientationHelper:delegate7 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - // Portrait and Landscape Left - - PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate8 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - // Portrait and Landscape Right - - PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate9 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - // PortraitUpsideDown and Landscape Left - - PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate10 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; - - // PortraitUpsideDown and Landscape Right - - PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate11 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape", - @"landscapeRight" : @"Default-Landscape", - @"portrait" : @"Default-Portrait", - @"portraitUpsideDown" : @"Default-Portrait" - } - device:device]; -} - -- (void)testiPhoneOrientation { - - CDV_iOSDevice device = CDV_iOSDeviceZero; - device.iPhone = YES; - - // One orientation - - PortraitOnly* delegate = [[PortraitOnly alloc] init]; - [self orientationHelper:delegate expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init]; - [self orientationHelper:delegate2 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate3 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init]; - [self orientationHelper:delegate4 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - // All Portrait - - AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init]; - [self orientationHelper:delegate5 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - // All Landscape - - AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init]; - [self orientationHelper:delegate6 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - - // All orientations - - AllOrientations* delegate7 = [[AllOrientations alloc] init]; - [self orientationHelper:delegate7 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - // Portrait and Landscape Left - - PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate8 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - // Portrait and Landscape Right - - PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate9 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - // PortraitUpsideDown and Landscape Left - - PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate10 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; - - // PortraitUpsideDown and Landscape Right - - PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate11 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default", - @"landscapeRight" : @"Default", - @"portrait" : @"Default", - @"portraitUpsideDown" : @"Default" - } - device:device]; -} - -- (void)testiPhone5Orientation { - - CDV_iOSDevice device = CDV_iOSDeviceZero; - device.iPhone = YES; - device.iPhone5 = YES; - - // One orientation - - PortraitOnly* delegate = [[PortraitOnly alloc] init]; - [self orientationHelper:delegate expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init]; - [self orientationHelper:delegate2 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate3 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init]; - [self orientationHelper:delegate4 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - // All Portrait - - AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init]; - [self orientationHelper:delegate5 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - // All Landscape - - AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init]; - [self orientationHelper:delegate6 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - - // All orientations - - AllOrientations* delegate7 = [[AllOrientations alloc] init]; - [self orientationHelper:delegate7 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - // Portrait and Landscape Left - - PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate8 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - // Portrait and Landscape Right - - PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate9 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - // PortraitUpsideDown and Landscape Left - - PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate10 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; - - // PortraitUpsideDown and Landscape Right - - PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate11 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-568h", - @"landscapeRight" : @"Default-568h", - @"portrait" : @"Default-568h", - @"portraitUpsideDown" : @"Default-568h" - } - device:device]; -} - -- (void)testiPhone6Orientation { - - CDV_iOSDevice device = CDV_iOSDeviceZero; - device.iPhone = YES; - device.iPhone6 = YES; - - // One orientation - - PortraitOnly* delegate = [[PortraitOnly alloc] init]; - [self orientationHelper:delegate expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init]; - [self orientationHelper:delegate2 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate3 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init]; - [self orientationHelper:delegate4 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - // All Portrait - - AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init]; - [self orientationHelper:delegate5 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - // All Landscape - - AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init]; - [self orientationHelper:delegate6 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - - // All orientations - - AllOrientations* delegate7 = [[AllOrientations alloc] init]; - [self orientationHelper:delegate7 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - // Portrait and Landscape Left - - PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate8 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - // Portrait and Landscape Right - - PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate9 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - // PortraitUpsideDown and Landscape Left - - PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate10 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; - - // PortraitUpsideDown and Landscape Right - - PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate11 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-667h", - @"landscapeRight" : @"Default-667h", - @"portrait" : @"Default-667h", - @"portraitUpsideDown" : @"Default-667h" - } - device:device]; -} - -- (void)testiPhone6PlusOrientation { - - CDV_iOSDevice device = CDV_iOSDeviceZero; - device.iPhone = YES; - device.iPhone6Plus = YES; - - // One orientation - - PortraitOnly* delegate = [[PortraitOnly alloc] init]; - [self orientationHelper:delegate expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-736h", - @"landscapeRight" : @"Default-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - PortraitUpsideDownOnly* delegate2 = [[PortraitUpsideDownOnly alloc] init]; - [self orientationHelper:delegate2 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-736h", - @"landscapeRight" : @"Default-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - LandscapeLeftOnly* delegate3 = [[LandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate3 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-Landscape-736h", - @"portraitUpsideDown" : @"Default-Landscape-736h" - } - device:device]; - - LandscapeRightOnly* delegate4 = [[LandscapeRightOnly alloc] init]; - [self orientationHelper:delegate4 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-Landscape-736h", - @"portraitUpsideDown" : @"Default-Landscape-736h" - } - device:device]; - - // All Portrait - - AllPortraitOnly* delegate5 = [[AllPortraitOnly alloc] init]; - [self orientationHelper:delegate5 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-736h", - @"landscapeRight" : @"Default-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - // All Landscape - - AllLandscapeOnly* delegate6 = [[AllLandscapeOnly alloc] init]; - [self orientationHelper:delegate6 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-Landscape-736h", - @"portraitUpsideDown" : @"Default-Landscape-736h" - } - device:device]; - - - // All orientations - - AllOrientations* delegate7 = [[AllOrientations alloc] init]; - [self orientationHelper:delegate7 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - // Portrait and Landscape Left - - PortraitAndLandscapeLeftOnly* delegate8 = [[PortraitAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate8 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - // Portrait and Landscape Right - - PortraitAndLandscapeRightOnly* delegate9 = [[PortraitAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate9 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - // PortraitUpsideDown and Landscape Left - - PortraitUpsideDownAndLandscapeLeftOnly* delegate10 = [[PortraitUpsideDownAndLandscapeLeftOnly alloc] init]; - [self orientationHelper:delegate10 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; - - // PortraitUpsideDown and Landscape Right - - PortraitUpsideDownAndLandscapeRightOnly* delegate11 = [[PortraitUpsideDownAndLandscapeRightOnly alloc] init]; - [self orientationHelper:delegate11 expectedImageNameDictionary:@{ - @"landscapeLeft" : @"Default-Landscape-736h", - @"landscapeRight" : @"Default-Landscape-736h", - @"portrait" : @"Default-736h", - @"portraitUpsideDown" : @"Default-736h" - } - device:device]; -} - - - -@end diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.h b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.h deleted file mode 100644 index be4a7883..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - 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 <Cordova/CDVScreenOrientationDelegate.h> - -@interface PortraitOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface PortraitUpsideDownOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface AllPortraitOnly : NSObject <CDVScreenOrientationDelegate> -@end - - -@interface LandscapeLeftOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface LandscapeRightOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface AllLandscapeOnly : NSObject <CDVScreenOrientationDelegate> -@end - - -@interface AllOrientations : NSObject <CDVScreenOrientationDelegate> -@end - -@interface PortraitAndLandscapeLeftOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface PortraitAndLandscapeRightOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface PortraitUpsideDownAndLandscapeLeftOnly : NSObject <CDVScreenOrientationDelegate> -@end - -@interface PortraitUpsideDownAndLandscapeRightOnly : NSObject <CDVScreenOrientationDelegate> -@end - diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.m b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.m deleted file mode 100644 index b5a1b23e..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/ImageNameTestDelegates.m +++ /dev/null @@ -1,200 +0,0 @@ -/* - 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 "ImageNameTestDelegates.h" - -@implementation PortraitOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation PortraitUpsideDownOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortraitUpsideDown; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation AllPortraitOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - - -@implementation LandscapeLeftOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskLandscapeLeft; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation LandscapeRightOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskLandscapeRight; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation AllLandscapeOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - - -@implementation AllOrientations - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskAll; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation PortraitAndLandscapeLeftOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation PortraitAndLandscapeRightOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeRight; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation PortraitUpsideDownAndLandscapeLeftOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortraitUpsideDown | UIInterfaceOrientationMaskLandscapeLeft; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - -@implementation PortraitUpsideDownAndLandscapeRightOnly - -- (NSUInteger)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortraitUpsideDown | UIInterfaceOrientationMaskLandscapeRight; -} - -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { - return [self supportedInterfaceOrientations] & (1 << interfaceOrientation) ; -} - -- (BOOL)shouldAutorotate { - return YES; -} - -@end - diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/Info.plist b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/Info.plist deleted file mode 100644 index 95c8addb..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenLibTests/Info.plist +++ /dev/null @@ -1,44 +0,0 @@ -<?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"> -<!-- -# -# 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. -# ---> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>org.apache.cordova.$(PRODUCT_NAME:rfc1034identifier)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>BNDL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.pbxproj b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.pbxproj deleted file mode 100644 index ce820d81..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.pbxproj +++ /dev/null @@ -1,505 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 7E9F51AB19DA10AE00DA31AC /* CDVSplashScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51A919DA10AE00DA31AC /* CDVSplashScreen.m */; }; - 7E9F51B119DA114400DA31AC /* ImageNameTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51B019DA114400DA31AC /* ImageNameTest.m */; }; - 7E9F51B319DA116500DA31AC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F51B219DA116500DA31AC /* Foundation.framework */; }; - 7E9F51B519DA127E00DA31AC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F51B419DA127E00DA31AC /* UIKit.framework */; }; - 7E9F51B819DA14FD00DA31AC /* ImageNameTestDelegates.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9F51B719DA14FD00DA31AC /* ImageNameTestDelegates.m */; }; - 7E9F51B919DA1B1600DA31AC /* libCDVSplashScreenLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */; }; - 7E9F51BA19DA1B2000DA31AC /* libCordova.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E9F519019DA0F8300DA31AC /* libCordova.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 7E9F518F19DA0F8300DA31AC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 68A32D7114102E1C006B237C; - remoteInfo = CordovaLib; - }; - 7E9F51AC19DA10DE00DA31AC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 7E9F517219DA09CE00DA31AC /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7E9F519419DA102000DA31AC; - remoteInfo = CDVSplashScreenLib; - }; - 7E9F51AE19DA10E100DA31AC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = D2AAC07D0554694100DB518D; - remoteInfo = CordovaLib; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 7E9F519319DA102000DA31AC /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = "../node_modules/cordova-ios/CordovaLib/CordovaLib.xcodeproj"; sourceTree = "<group>"; }; - 7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCDVSplashScreenLib.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 7E9F519F19DA102000DA31AC /* CDVSplashScreenLibTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CDVSplashScreenLibTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 7E9F51A219DA102000DA31AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; - 7E9F51A919DA10AE00DA31AC /* CDVSplashScreen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVSplashScreen.m; path = ../../../src/ios/CDVSplashScreen.m; sourceTree = SOURCE_ROOT; }; - 7E9F51AA19DA10AE00DA31AC /* CDVSplashScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVSplashScreen.h; path = ../../../src/ios/CDVSplashScreen.h; sourceTree = SOURCE_ROOT; }; - 7E9F51B019DA114400DA31AC /* ImageNameTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageNameTest.m; sourceTree = "<group>"; }; - 7E9F51B219DA116500DA31AC /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 7E9F51B419DA127E00DA31AC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - 7E9F51B619DA12C600DA31AC /* ImageNameTestDelegates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageNameTestDelegates.h; sourceTree = "<group>"; }; - 7E9F51B719DA14FD00DA31AC /* ImageNameTestDelegates.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageNameTestDelegates.m; sourceTree = "<group>"; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 7E9F519219DA102000DA31AC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 7E9F519C19DA102000DA31AC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 7E9F51BA19DA1B2000DA31AC /* libCordova.a in Frameworks */, - 7E9F51B919DA1B1600DA31AC /* libCDVSplashScreenLib.a in Frameworks */, - 7E9F51B519DA127E00DA31AC /* UIKit.framework in Frameworks */, - 7E9F51B319DA116500DA31AC /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 7E9F517119DA09CE00DA31AC = { - isa = PBXGroup; - children = ( - 7E9F51B419DA127E00DA31AC /* UIKit.framework */, - 7E9F51B219DA116500DA31AC /* Foundation.framework */, - 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */, - 7E9F519619DA102000DA31AC /* CDVSplashScreenLib */, - 7E9F51A019DA102000DA31AC /* CDVSplashScreenLibTests */, - 7E9F517D19DA0A0A00DA31AC /* Products */, - ); - sourceTree = "<group>"; - }; - 7E9F517D19DA0A0A00DA31AC /* Products */ = { - isa = PBXGroup; - children = ( - 7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */, - 7E9F519F19DA102000DA31AC /* CDVSplashScreenLibTests.xctest */, - ); - name = Products; - sourceTree = "<group>"; - }; - 7E9F518C19DA0F8300DA31AC /* Products */ = { - isa = PBXGroup; - children = ( - 7E9F519019DA0F8300DA31AC /* libCordova.a */, - ); - name = Products; - sourceTree = "<group>"; - }; - 7E9F519619DA102000DA31AC /* CDVSplashScreenLib */ = { - isa = PBXGroup; - children = ( - 7E9F51A919DA10AE00DA31AC /* CDVSplashScreen.m */, - 7E9F51AA19DA10AE00DA31AC /* CDVSplashScreen.h */, - ); - path = CDVSplashScreenLib; - sourceTree = SOURCE_ROOT; - }; - 7E9F51A019DA102000DA31AC /* CDVSplashScreenLibTests */ = { - isa = PBXGroup; - children = ( - 7E9F51A119DA102000DA31AC /* Supporting Files */, - 7E9F51B019DA114400DA31AC /* ImageNameTest.m */, - 7E9F51B619DA12C600DA31AC /* ImageNameTestDelegates.h */, - 7E9F51B719DA14FD00DA31AC /* ImageNameTestDelegates.m */, - ); - path = CDVSplashScreenLibTests; - sourceTree = "<group>"; - }; - 7E9F51A119DA102000DA31AC /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 7E9F51A219DA102000DA31AC /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = "<group>"; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7E9F519419DA102000DA31AC /* CDVSplashScreenLib */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7E9F51A319DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVSplashScreenLib" */; - buildPhases = ( - 7E9F519119DA102000DA31AC /* Sources */, - 7E9F519219DA102000DA31AC /* Frameworks */, - 7E9F519319DA102000DA31AC /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = CDVSplashScreenLib; - productName = CDVSplashScreenLib; - productReference = 7E9F519519DA102000DA31AC /* libCDVSplashScreenLib.a */; - productType = "com.apple.product-type.library.static"; - }; - 7E9F519E19DA102000DA31AC /* CDVSplashScreenLibTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7E9F51A619DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVSplashScreenLibTests" */; - buildPhases = ( - 7E9F519B19DA102000DA31AC /* Sources */, - 7E9F519C19DA102000DA31AC /* Frameworks */, - 7E9F519D19DA102000DA31AC /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 7E9F51AF19DA10E100DA31AC /* PBXTargetDependency */, - 7E9F51AD19DA10DE00DA31AC /* PBXTargetDependency */, - ); - name = CDVSplashScreenLibTests; - productName = CDVSplashScreenLibTests; - productReference = 7E9F519F19DA102000DA31AC /* CDVSplashScreenLibTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7E9F517219DA09CE00DA31AC /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0600; - TargetAttributes = { - 7E9F519419DA102000DA31AC = { - CreatedOnToolsVersion = 6.0; - }; - 7E9F519E19DA102000DA31AC = { - CreatedOnToolsVersion = 6.0; - }; - }; - }; - buildConfigurationList = 7E9F517519DA09CE00DA31AC /* Build configuration list for PBXProject "CDVSplashScreenTest" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 7E9F517119DA09CE00DA31AC; - productRefGroup = 7E9F517D19DA0A0A00DA31AC /* Products */; - projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 7E9F518C19DA0F8300DA31AC /* Products */; - ProjectRef = 7E9F518B19DA0F8300DA31AC /* CordovaLib.xcodeproj */; - }, - ); - projectRoot = ""; - targets = ( - 7E9F519419DA102000DA31AC /* CDVSplashScreenLib */, - 7E9F519E19DA102000DA31AC /* CDVSplashScreenLibTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXReferenceProxy section */ - 7E9F519019DA0F8300DA31AC /* libCordova.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libCordova.a; - remoteRef = 7E9F518F19DA0F8300DA31AC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 7E9F519D19DA102000DA31AC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7E9F519119DA102000DA31AC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7E9F51AB19DA10AE00DA31AC /* CDVSplashScreen.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 7E9F519B19DA102000DA31AC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 7E9F51B119DA114400DA31AC /* ImageNameTest.m in Sources */, - 7E9F51B819DA14FD00DA31AC /* ImageNameTestDelegates.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 7E9F51AD19DA10DE00DA31AC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 7E9F519419DA102000DA31AC /* CDVSplashScreenLib */; - targetProxy = 7E9F51AC19DA10DE00DA31AC /* PBXContainerItemProxy */; - }; - 7E9F51AF19DA10E100DA31AC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = CordovaLib; - targetProxy = 7E9F51AE19DA10E100DA31AC /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 7E9F517619DA09CE00DA31AC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Debug; - }; - 7E9F517719DA09CE00DA31AC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - }; - name = Release; - }; - 7E9F51A419DA102000DA31AC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", - "\"$(OBJROOT)/UninstalledProducts/include\"", - "\"$(BUILT_PRODUCTS_DIR)\"", - ); - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 7E9F51A519DA102000DA31AC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"", - "\n\"$(OBJROOT)/UninstalledProducts/include\"\n\"$(BUILT_PRODUCTS_DIR)\"", - ); - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7E9F51A719DA102000DA31AC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = CDVSplashScreenLibTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 7E9F51A819DA102000DA31AC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = CDVSplashScreenLibTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7E9F517519DA09CE00DA31AC /* Build configuration list for PBXProject "CDVSplashScreenTest" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7E9F517619DA09CE00DA31AC /* Debug */, - 7E9F517719DA09CE00DA31AC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7E9F51A319DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVSplashScreenLib" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7E9F51A419DA102000DA31AC /* Debug */, - 7E9F51A519DA102000DA31AC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7E9F51A619DA102000DA31AC /* Build configuration list for PBXNativeTarget "CDVSplashScreenLibTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7E9F51A719DA102000DA31AC /* Debug */, - 7E9F51A819DA102000DA31AC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7E9F517219DA09CE00DA31AC /* Project object */; -} diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 8f912784..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Workspace - version = "1.0"> - <FileRef - location = "self:CDVSplashScreenTest.xcodeproj"> - </FileRef> -</Workspace> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/xcshareddata/CDVSplashScreenTest.xccheckout b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/xcshareddata/CDVSplashScreenTest.xccheckout deleted file mode 100644 index 7e4cdb93..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/project.xcworkspace/xcshareddata/CDVSplashScreenTest.xccheckout +++ /dev/null @@ -1,41 +0,0 @@ -<?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>IDESourceControlProjectFavoriteDictionaryKey</key> - <false/> - <key>IDESourceControlProjectIdentifier</key> - <string>6BE9AD73-1B9F-4362-98D7-DC631BEC6185</string> - <key>IDESourceControlProjectName</key> - <string>CDVSplashScreenTest</string> - <key>IDESourceControlProjectOriginsDictionary</key> - <dict> - <key>BEF5A5D0FF64801E558286389440357A9233D7DB</key> - <string>https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git</string> - </dict> - <key>IDESourceControlProjectPath</key> - <string>tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj</string> - <key>IDESourceControlProjectRelativeInstallPathDictionary</key> - <dict> - <key>BEF5A5D0FF64801E558286389440357A9233D7DB</key> - <string>../../../../..</string> - </dict> - <key>IDESourceControlProjectURL</key> - <string>https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git</string> - <key>IDESourceControlProjectVersion</key> - <integer>111</integer> - <key>IDESourceControlProjectWCCIdentifier</key> - <string>BEF5A5D0FF64801E558286389440357A9233D7DB</string> - <key>IDESourceControlProjectWCConfigurations</key> - <array> - <dict> - <key>IDESourceControlRepositoryExtensionIdentifierKey</key> - <string>public.vcs.git</string> - <key>IDESourceControlWCCIdentifierKey</key> - <string>BEF5A5D0FF64801E558286389440357A9233D7DB</string> - <key>IDESourceControlWCCName</key> - <string>cordova-plugin-splashscreen</string> - </dict> - </array> -</dict> -</plist> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLib.xcscheme b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLib.xcscheme deleted file mode 100644 index b97b8633..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLib.xcscheme +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0600" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519419DA102000DA31AC" - BuildableName = "libCDVSplashScreenLib.a" - BlueprintName = "CDVSplashScreenLib" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <Testables> - </Testables> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - allowLocationSimulation = "YES"> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519419DA102000DA31AC" - BuildableName = "libCDVSplashScreenLib.a" - BlueprintName = "CDVSplashScreenLib" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" - debugDocumentVersioning = "YES"> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519419DA102000DA31AC" - BuildableName = "libCDVSplashScreenLib.a" - BlueprintName = "CDVSplashScreenLib" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLibTests.xcscheme b/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLibTests.xcscheme deleted file mode 100644 index 6a2a5261..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/CDVSplashScreenTest/CDVSplashScreenTest.xcodeproj/xcshareddata/xcschemes/CDVSplashScreenLibTests.xcscheme +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0600" - version = "1.3"> - <BuildAction - parallelizeBuildables = "YES" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "NO" - buildForArchiving = "NO" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519E19DA102000DA31AC" - BuildableName = "CDVSplashScreenLibTests.xctest" - BlueprintName = "CDVSplashScreenLibTests" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - buildConfiguration = "Debug"> - <Testables> - <TestableReference - skipped = "NO"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519E19DA102000DA31AC" - BuildableName = "CDVSplashScreenLibTests.xctest" - BlueprintName = "CDVSplashScreenLibTests" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </TestableReference> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519E19DA102000DA31AC" - BuildableName = "CDVSplashScreenLibTests.xctest" - BlueprintName = "CDVSplashScreenLibTests" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </TestAction> - <LaunchAction - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Debug" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - allowLocationSimulation = "YES"> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519E19DA102000DA31AC" - BuildableName = "CDVSplashScreenLibTests.xctest" - BlueprintName = "CDVSplashScreenLibTests" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - buildConfiguration = "Release" - debugDocumentVersioning = "YES"> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "7E9F519E19DA102000DA31AC" - BuildableName = "CDVSplashScreenLibTests.xctest" - BlueprintName = "CDVSplashScreenLibTests" - ReferencedContainer = "container:CDVSplashScreenTest.xcodeproj"> - </BuildableReference> - </MacroExpansion> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/README.md deleted file mode 100644 index 97ee9dff..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/README.md +++ /dev/null @@ -1,40 +0,0 @@ -<!-- -# license: 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. ---> - -# iOS Tests for CDVSplashScreen - -You need to install `node.js` to pull in `cordova-ios`. - -First install cordova-ios: - - npm install - -... in the current folder. - - -# Testing from Xcode - -1. Launch the `CDVSplashScreenTest.xcworkspace` file. -2. Choose "CDVSplashScreenLibTests" from the scheme drop-down menu -3. Click and hold on the `Play` button, and choose the `Wrench` icon to run the tests - - -# Testing from the command line - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/de/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/de/README.md deleted file mode 100644 index 9c7f0a4f..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/de/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# iOS-Tests für CDVSplashScreen - -Sie müssen installieren `node.js` in `Cordova-Ios` zu ziehen. - -Installieren Sie Cordova-Ios zum ersten Mal: - - npm install - - -... im aktuellen Ordner. - -# Testen von Xcode - - 1. Starten Sie die Datei `CDVSplashScreenTest.xcworkspace` . - 2. Wählen Sie im Dropdown-Schema "CDVSplashScreenLibTests" - 3. Klicken Sie und halten Sie auf den `Play` -Button und wählen Sie das `Schraubenschlüssel` -Symbol zum Ausführen der tests - -# Tests von der Befehlszeile aus - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/es/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/es/README.md deleted file mode 100644 index 2176c921..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/es/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# Pruebas de iOS para CDVSplashScreen - -Necesita instalar `node.js` en `Córdoba-ios`. - -Primero instalar cordova-ios: - - npm install - - -... en la carpeta actual. - -# Prueba de Xcode - - 1. Iniciar el archivo `CDVSplashScreenTest.xcworkspace` . - 2. Elija "CDVSplashScreenLibTests" en el menú de lista desplegable esquema - 3. Haga clic y mantenga el botón de `Play` y elegir el icono de `llave inglesa` para ejecutar las pruebas - -# Pruebas desde la línea de comandos - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/fr/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/fr/README.md deleted file mode 100644 index 0dbbd0d2..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/fr/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# Tests d'iOS pour CDVSplashScreen - -Vous devez installer `node.js` à `cordova-ios`. - -Commencez par installer cordova-ios : - - npm install - - -... dans le dossier actuel. - -# Tests de Xcode - - 1. Lancez le fichier `CDVSplashScreenTest.xcworkspace` . - 2. Choisissez « CDVSplashScreenLibTests » dans le menu déroulant de régime - 3. Cliquez et maintenez sur la touche `Play` et cliquez sur l'icône de `clé` pour exécuter les tests - -# Test de la ligne de commande - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/it/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/it/README.md deleted file mode 100644 index 2a42df67..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/it/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# Test di iOS per CDVSplashScreen - -È necessario installare `node. js` per tirare in `cordova-ios`. - -In primo luogo installare cordova-ios: - - npm install - - -... nella cartella corrente. - -# Test da Xcode - - 1. Lanciare il file `CDVSplashScreenTest.xcworkspace` . - 2. Scegli "CDVSplashScreenLibTests" dal menu a discesa Schema - 3. Fare clic e tenere premuto il pulsante `Play` e scegliere l'icona della `chiave inglese` per eseguire i test - -# Test dalla riga di comando - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/ja/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/ja/README.md deleted file mode 100644 index 011b8242..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/ja/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# CDVSplashScreen の iOS のテスト - -`Node.js` `コルドバ`ios をプルするをインストールする必要があります。. - -コルドバ ios をインストールします。 - - npm install - - -現在のフォルダーに. - -# Xcode からテスト - - 1. `CDVSplashScreenTest.xcworkspace`ファイルを起動します。 - 2. スキーム] ドロップダウン メニューから"CDVSplashScreenLibTests"を選択します。 - 3. クリックし、`再生`ボタンを押し、テストを実行する`レンチ`のアイコンを選択 - -# コマンドラインからテスト - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/ko/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/ko/README.md deleted file mode 100644 index 6981207a..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/ko/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# CDVSplashScreen에 대 한 iOS 테스트 - -`Node.js` `코르도바` ios에서를 설치 해야. - -코르도바-ios를 설치 하는 첫번째는: - - npm install - - -현재 폴더에.... - -# Xcode에서 테스트 - - 1. `CDVSplashScreenTest.xcworkspace` 파일을 시작 합니다. - 2. 구성표 드롭 다운 메뉴에서 "CDVSplashScreenLibTests"를 선택 - 3. 클릭 하 고 `재생` 버튼에는 테스트를 실행 하려면 `공구 모양` 아이콘을 선택 - -# 명령줄에서 테스트 - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/pl/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/pl/README.md deleted file mode 100644 index f13828fe..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/pl/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# iOS testy dla CDVSplashScreen - -Musisz zainstalować `node.js` ciągnąć w `cordova-ios`. - -Najpierw zainstalować cordova-ios: - - npm install - - -... w folderze bieżącym. - -# Badania z Xcode - - 1. Uruchom plik `CDVSplashScreenTest.xcworkspace` . - 2. Wybierz z menu rozwijanego systemu "CDVSplashScreenLibTests" - 3. Kliknij i przytrzymaj przycisk `Play` i wybrać ikonę `klucz` do testów - -# Badania z wiersza polecenia - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/doc/zh/README.md b/plugins/cordova-plugin-splashscreen/tests/ios/doc/zh/README.md deleted file mode 100644 index 3a04bcd1..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/doc/zh/README.md +++ /dev/null @@ -1,39 +0,0 @@ -<!-- -# license: 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. ---> - -# CDVSplashScreen 的 iOS 測試 - -您需要安裝`node.js`拉`科爾多瓦 ios`中. - -第一次安裝科爾多瓦 ios: - - npm install - - -在當前資料夾中。 - -# 從 Xcode 測試 - - 1. 啟動`CDVSplashScreenTest.xcworkspace`檔。 - 2. 從方案下拉式功能表中選擇"CDVSplashScreenLibTests" - 3. 按一下並堅持`播放`按鈕,然後選擇要運行的測試的`扳手`圖示 - -# 從命令列測試 - - npm test diff --git a/plugins/cordova-plugin-splashscreen/tests/ios/package.json b/plugins/cordova-plugin-splashscreen/tests/ios/package.json deleted file mode 100644 index d8b23857..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/ios/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "cordova-plugin-splashscreen-test-ios", - "version": "1.0.0", - "description": "iOS Unit Tests for Splashscreen Plugin", - "author": "Apache Software Foundation", - "license": "Apache Version 2.0", - "dependencies": { - "cordova-ios": "^3.6.0" - }, - "scripts": { - "test": "xcodebuild test -workspace CDVSplashScreenTest.xcworkspace -scheme CDVSplashScreenLibTests -destination 'platform=iOS Simulator,name=iPhone 5' CONFIGURATION_BUILD_DIR='/tmp'" - } -}
\ No newline at end of file diff --git a/plugins/cordova-plugin-splashscreen/tests/plugin.xml b/plugins/cordova-plugin-splashscreen/tests/plugin.xml deleted file mode 100644 index bf9cb0ac..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/plugin.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-splashscreen-tests" - version="2.1.0"> - <name>Cordova Splashscreen Plugin Tests</name> - <license>Apache 2.0</license> - - <js-module src="tests.js" name="tests"> - </js-module> -</plugin> diff --git a/plugins/cordova-plugin-splashscreen/tests/tests.js b/plugins/cordova-plugin-splashscreen/tests/tests.js deleted file mode 100644 index 8c4d22b4..00000000 --- a/plugins/cordova-plugin-splashscreen/tests/tests.js +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * 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. - * -*/ - -exports.defineAutoTest = function () { - describe('Splashscreen (cordova)', function () { - it("splashscreen.spec.1 should exist", function () { - expect(navigator.splashscreen).toBeDefined(); - }); - - it("splashscreen.spec.2 exec method should exist", function () { - expect(navigator.splashscreen.show).toBeDefined(); - expect(typeof navigator.splashscreen.show).toBe('function'); - }); - - it("splashscreen.spec.3 exec method should exist", function () { - expect(navigator.splashscreen.hide).toBeDefined(); - expect(typeof navigator.splashscreen.hide).toBe('function'); - }); - }); -}; - -exports.defineManualTests = function (contentEl, createActionButton) { - function showFor(duration) { - navigator.splashscreen.show(); - window.setTimeout(function () { - navigator.splashscreen.hide(); - }, 1000 * duration); - } - - contentEl.innerHTML = '<h1>Splashscreen Tests</h1>' + - '<h3>Note for WP: AutoHideSplashScreen must be set to false in config.xml</h3>' + - '<div id="show1"></div>' + - 'Expected result: Will show the Cordova splashscreen for 1 second' + - '</p> <div id="show5"></div>' + - 'Expected result: Will show the Cordova splashscreen for 5 seconds'; - - createActionButton('Show for 1 second', function () { - showFor(1); - }, 'show1'); - - createActionButton('Show for 5 seconds', function () { - showFor(5); - }, 'show5'); -}; diff --git a/plugins/cordova-plugin-splashscreen/www/splashscreen.js b/plugins/cordova-plugin-splashscreen/www/splashscreen.js deleted file mode 100644 index 7cb48bdd..00000000 --- a/plugins/cordova-plugin-splashscreen/www/splashscreen.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'); - -var splashscreen = { - show:function() { - exec(null, null, "SplashScreen", "show", []); - }, - hide:function() { - exec(null, null, "SplashScreen", "hide", []); - } -}; - -module.exports = splashscreen; diff --git a/plugins/cordova-plugin-splashscreen/www/windows/SplashScreenProxy.js b/plugins/cordova-plugin-splashscreen/www/windows/SplashScreenProxy.js deleted file mode 100644 index dab72381..00000000 --- a/plugins/cordova-plugin-splashscreen/www/windows/SplashScreenProxy.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * - * 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. - * -*/ - -/*jslint sloppy:true */ -/*global Windows:true, require, module, window, document, WinJS */ - -var cordova = require('cordova'), - channel = require('cordova/channel'); - -var isPhone = (cordova.platformId == "windows") && WinJS.Utilities.isPhone; -var localSplash = null; -var bgColor = "#464646"; // default backgrond color; TDOO - read it from .appxmanifest -var splashImageSrc = isPhone ? "ms-appx:///images/splashscreenphone.png" : "ms-appx:///images/splashscreen.png"; - -var SplashScreen = { - setBGColor: function (cssBGColor) { - bgColor = cssBGColor; - if (localSplash) { - localSplash.style.backgroundColor = bgColor; - } - }, - show: function () { - if (localSplash) { - return; // already showed - } - - localSplash = document.createElement("div"); - localSplash.style.backgroundColor = bgColor; - localSplash.style.position = "fixed"; - localSplash.style.top = "0"; - localSplash.style.width = "100%"; - localSplash.style.height = "100%"; - - localSplashImage = document.createElement("img"); - localSplashImage.src = splashImageSrc; - localSplashImage.style.maxWidth = "100%"; - localSplashImage.style.maxHeight = "100%"; - // center horizontally - localSplashImage.style.margin = "0 auto"; - localSplashImage.style.display = "block"; - // center vertically - localSplashImage.style.position = "relative"; - localSplashImage.style.top = "50%"; - localSplashImage.style.transform = "translateY(-50%)"; - - localSplash.appendChild(localSplashImage); - document.body.appendChild(localSplash); - }, - hide: function () { - if (localSplash) { - document.body.removeChild(localSplash); - localSplash = null; - } - } -}; - -module.exports = SplashScreen; - -require("cordova/exec/proxy").add("SplashScreen", SplashScreen); diff --git a/plugins/cordova-plugin-touchid/README.md b/plugins/cordova-plugin-touchid/README.md deleted file mode 100644 index 2001972a..00000000 --- a/plugins/cordova-plugin-touchid/README.md +++ /dev/null @@ -1,58 +0,0 @@ -## Touch ID Plugin for Apache Cordova - -Cordova Plugin to leverage the iOS local authentication framework to allow in-app user authentication using Touch ID. - -**Important:** You must target a real device when building. If you target the simulator, the build will fail. - -## 1 step install - -#### Latest published version on npm (with Cordova CLI >= 5.0.0) - -``` -cordova plugin add cordova-plugin-touchid -``` - -#### Latest version from GitHub - -``` -cordova plugin add https://github.com/leecrossley/cordova-plugin-touchid.git -``` - -## Usage - -You **do not** need to reference any JavaScript, the Cordova plugin architecture will add a touchid object to your root automatically when you build. - -Ensure you use the plugin after your deviceready event has been fired. - -### Authenticate - -Pass the following arguments to the `authenticate()` function, to prompt the user to authenticate via TouchID: - -1. Success callback (called on successful authentication) -2. Failure callback (called on error or if authentication fails) -3. Localised text explaining why the app needs authentication* - -``` -touchid.authenticate(successCallback, failureCallback, text); -``` - -*NOTE: The localised text you present to the user should provide a clear reason for why you are requesting they authenticate themselves, and what action you will be taking based on that authentication. - -### Check support - -Although the `authenticate()` function will return an error if the user is unable to authenticate via Touch ID, you may wish to check support without prompting the user to authenticate. This can be done by passing following arguments to the `checkSupport()` function: - -1. Success callback (called if authentication is possible) -2. Not supported callback (called if policy can not be evaluated, with error message) - -``` -touchid.checkSupport(successCallback, notSupportedCallback); -``` - -## Platforms - -iOS 8+ - -## License - -[MIT License](http://ilee.mit-license.org) diff --git a/plugins/cordova-plugin-touchid/package.json b/plugins/cordova-plugin-touchid/package.json deleted file mode 100644 index 3b6a77c5..00000000 --- a/plugins/cordova-plugin-touchid/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "cordova-plugin-touchid", - "version": "0.3.0", - "author": "Lee Crossley <leee@hotmail.co.uk> (http://ilee.co.uk/)", - "description": "Cordova Plugin to leverage the iOS local authentication framework to allow in-app user authentication using Touch ID.", - "cordova": { - "id": "cordova-plugin-touchid", - "platforms": [ - "ios" - ] - }, - "repository": { - "type": "git", - "url": "git+https://github.com/leecrossley/cordova-plugin-touchid.git" - }, - "keywords": [ - "cordova", - "touch id", - "touchid", - "authentication", - "fingerprint", - "id", - "login", - "passcode", - "ecosystem:cordova", - "cordova-ios" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/leecrossley/cordova-plugin-touchid/issues" - }, - "homepage": "https://github.com/leecrossley/cordova-plugin-touchid#readme" -} diff --git a/plugins/cordova-plugin-touchid/plugin.xml b/plugins/cordova-plugin-touchid/plugin.xml deleted file mode 100644 index 1331453d..00000000 --- a/plugins/cordova-plugin-touchid/plugin.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="cordova-plugin-touchid" version="0.3.0"> - <name>Touch ID</name> - <author>Lee Crossley (http://ilee.co.uk/)</author> - <description>Cordova Plugin to leverage the iOS local authentication framework to allow in-app user authentication using Touch ID.</description> - <keywords>cordova, touch id, touchid, authentication, fingerprint, id, login, passcode</keywords> - <license>MIT</license> - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - <js-module src="www/touchid.js" name="TouchID"> - <clobbers target="touchid" /> - </js-module> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="TouchID"> - <param name="ios-package" value="TouchID" /> - </feature> - </config-file> - <header-file src="src/ios/TouchID.h" /> - <source-file src="src/ios/TouchID.m" /> - <framework src="LocalAuthentication.framework" /> - <framework src="Security.framework" /> - </platform> -</plugin> diff --git a/plugins/cordova-plugin-touchid/src/ios/TouchID.h b/plugins/cordova-plugin-touchid/src/ios/TouchID.h deleted file mode 100644 index d971a080..00000000 --- a/plugins/cordova-plugin-touchid/src/ios/TouchID.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// TouchID.h -// Copyright (c) 2014 Lee Crossley - http://ilee.co.uk -// - -#import <Cordova/CDVPlugin.h> - -@interface TouchID : CDVPlugin - -- (void) authenticate:(CDVInvokedUrlCommand*)command; -- (void) checkSupport:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/cordova-plugin-touchid/src/ios/TouchID.m b/plugins/cordova-plugin-touchid/src/ios/TouchID.m deleted file mode 100644 index 0d39f7e2..00000000 --- a/plugins/cordova-plugin-touchid/src/ios/TouchID.m +++ /dev/null @@ -1,79 +0,0 @@ -// -// TouchID.m -// Copyright (c) 2014 Lee Crossley - http://ilee.co.uk -// - -#import "TouchID.h" - -#import <LocalAuthentication/LocalAuthentication.h> - -@implementation TouchID - -- (void) authenticate:(CDVInvokedUrlCommand*)command; -{ - NSString *text = [command.arguments objectAtIndex:0]; - - __block CDVPluginResult* pluginResult = nil; - - if (NSClassFromString(@"LAContext") != nil) - { - LAContext *laContext = [[LAContext alloc] init]; - NSError *authError = nil; - - if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) - { - [laContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:text reply:^(BOOL success, NSError *error) - { - if (success) - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } - else - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[error localizedDescription]]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - }]; - } - else - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[authError localizedDescription]]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } - } - else - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; - } -} - -- (void) checkSupport:(CDVInvokedUrlCommand*)command; -{ - - __block CDVPluginResult* pluginResult = nil; - - if (NSClassFromString(@"LAContext") != nil) - { - LAContext *laContext = [[LAContext alloc] init]; - NSError *authError = nil; - - if ([laContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - } - else - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:[authError localizedDescription]]; - } - } - else - { - pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR]; - } - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -@end diff --git a/plugins/cordova-plugin-touchid/www/touchid.js b/plugins/cordova-plugin-touchid/www/touchid.js deleted file mode 100644 index 020d5f89..00000000 --- a/plugins/cordova-plugin-touchid/www/touchid.js +++ /dev/null @@ -1,19 +0,0 @@ - -var exec = require("cordova/exec"); - -var TouchID = function () { - this.name = "TouchID"; -}; - -TouchID.prototype.authenticate = function (successCallback, errorCallback, text) { - if (!text) { - text = "Please authenticate via TouchID to proceed"; - } - exec(successCallback, errorCallback, "TouchID", "authenticate", [text]); -}; - -TouchID.prototype.checkSupport = function (successCallback, errorCallback) { - exec(successCallback, errorCallback, "TouchID", "checkSupport"); -}; - -module.exports = new TouchID(); diff --git a/plugins/cordova-plugin-websocket/CHANGELOG.md b/plugins/cordova-plugin-websocket/CHANGELOG.md deleted file mode 100644 index 43569330..00000000 --- a/plugins/cordova-plugin-websocket/CHANGELOG.md +++ /dev/null @@ -1,97 +0,0 @@ -## Change Log -#### 0.11.0 -* permessage-deflate support -* deleted unused code (further shrank about 20%) -* performance improvement (further about 15% to 25% faster than previous versions) - -#### 0.10.0 -* permessage-deflate support (experimental) -* fixed multiple subprotocol bug -* improved finalization -* deleted unused code (shrank about 20%) - -#### 0.9.2 -* fixed lack of trailing zeros (0x00) when receiving binary (thanks to @lemoncola) - -#### 0.9.1 -* updated only documents - -#### 0.9.0 -* integrated with jetty-8.1.17.v20150415 -* performance improvement (about 10% to 25% faster than previous versions) -* added `agent` option -* changed default value of `origin` option -* restored `maxTextMessageSize`/`maxBinaryMessageSize` options -* Crosswalk support -* Android 2.2 (Froyo) support end -* refactor - -#### 0.8.3 -* fixed that difference between packages and directories structure (thanks to @digigm) - -#### 0.8.2 -* fixed the constructor error on 4.4 and later (thanks to @digigm) - -#### 0.8.1 -* fixed the frame aggregation error (thanks to @Atsyn) -* fixed the binary transmission for the case of using the plugin on 4.4 and later - -#### 0.8.0 -* performance improvement (about 5% to 15% faster than previous versions) -* deployed source of Jetty directly (instead the jar file) -* abolished `maxTextMessageSize`/`maxBinaryMessageSize` options -* added `override` option -* refactor - -#### 0.7.0 -* resolved the issue of SSL on 4.0 and 2.3 (thanks to @agalazis and koush/AndroidAsync) - -#### 0.6.3 -* fixed a bug of a receiving binary size - -#### 0.6.2a -* limit installation target to Android (thanks to @peli44) - -#### 0.6.2 -* updated Jetty WebSocket library - -#### 0.6.1 -* added escaping of special characters (thanks to @odbol) - -#### 0.6.0 -* cookie support (thanks to @ericfong) -* removed a second argument from the send() method - -#### 0.5.2 -* clobbered buggy websockets on 4.3 or lower (thanks to @rpastorvargas and @punj) -* bug fix - -#### 0.5.1 -* bug fix - -#### 0.5.0 -* change the way to set plugin options -* multiple subprotocol support -* readyState property support (thanks to @jrpereirajr) - -#### 0.4.0 -* Cordova/Phonegap 3 support -* binary support -* event listener support -* more compliant with the WebSocket API requirements -* license change from MIT to Apache v2.0 - -#### 0.3.2 -* bug fix - -#### 0.3.1 -* bug fix - -#### 0.3.0 -* `origin` support (thanks to @rgillan) - -#### 0.2.0 -* comply with the WebSocket API requirements - -#### 0.1.0 -* first release diff --git a/plugins/cordova-plugin-websocket/LICENSE b/plugins/cordova-plugin-websocket/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/cordova-plugin-websocket/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/cordova-plugin-websocket/NOTICE b/plugins/cordova-plugin-websocket/NOTICE deleted file mode 100644 index 0555240d..00000000 --- a/plugins/cordova-plugin-websocket/NOTICE +++ /dev/null @@ -1,31 +0,0 @@ -============================================================== - Jetty Web Container - Copyright 1995-2015 Mort Bay Consulting Pty Ltd. -============================================================== - -The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd -unless otherwise noted. - -Jetty is dual licensed under both - - * The Apache 2.0 License - http://www.apache.org/licenses/LICENSE-2.0.html - - and - - * The Eclipse Public 1.0 License - http://www.eclipse.org/legal/epl-v10.html - -Jetty may be distributed under either license. - -The javax.servlet package used was sourced from the Apache -Software Foundation and is distributed under the apache 2.0 -license. - -The UnixCrypt.java code implements the one way cryptography used by -Unix systems for simple password protection. Copyright 1996 Aki Yoshida, -modified April 2001 by Iris Van den Broeke, Daniel Deville. -Permission to use, copy, modify and distribute UnixCrypt -for non-commercial or commercial purposes and without fee is -granted provided that the copyright notice appears in all copies. - diff --git a/plugins/cordova-plugin-websocket/README.md b/plugins/cordova-plugin-websocket/README.md deleted file mode 100644 index 3c2e7eac..00000000 --- a/plugins/cordova-plugin-websocket/README.md +++ /dev/null @@ -1,152 +0,0 @@ -# WebSocket for Android [](http://badge.fury.io/gh/knowledgecode%2FWebSocket-for-Android)
-WebSocket for Android is a Cordova plugin that makes WebSocket (RFC 6455) available on Android.
-This is based on [Jetty 8](https://github.com/eclipse/jetty.project/tree/jetty-8) under the terms of the Apache License v2.0.
-
-## Requirements
- - Android 2.3 or later (recommended 4.1 or later)
- - `cordova-android@3.0.0` or later or compatible framework
- - `cordova-plugin-whitelist` or `cordova-plugin-legacy-whitelist` if using `cordova-android@4.0.0` and later
-
-The plugin for Cordova 2.x can be found [here](https://github.com/knowledgecode/WebSocket-for-Android/tree/2.x).
-
-## Supported Features
-| version | WS protocol | WSS protocol | text message | binary message |
-|:--------------:|:-----------:|:------------:|:------------:|:--------------:|
-| 2.3.3 (API 10) | ✓ | ✓ | ✓ | |
-| 4.0 (API 14) | ✓ | ✓ | ✓ | ✓ |
-| 4.0.3 (API 15) | ✓ | ✓ | ✓ | ✓ |
-| 4.1.2 (API 16) | ✓ | ✓ | ✓ | ✓ |
-| 4.2.2 (API 17) | ✓ | ✓ | ✓ | ✓ |
-| 4.3.1 (API 18) | ✓ | ✓ | ✓ | ✓ |
-| 4.4.2 (API 19) | - | - | - | - |
-| 5.0.1 (API 21) | - | - | - | - |
-| 5.1.1 (API 22) | - | - | - | - |
-
-#### Notes
- - WSS protocol is only supported TLS. SSLv3 is not.
- - Android 3.x (Honeycomb) are not supported (might work but is not tested).
- - A new WebView based on Chromium supports WebSocket. Specifically Android 4.4 (KitKat) and later support them, so this plugin is **NOT** used on them by default.
- - In `cordova-android@4.0.0` and later, this plugin can be used together with [Crosswalk](https://crosswalk-project.org/). In this case also it is not used by default because Crosswalk supports WebSocket.
- - To support Android 5.x (Lollipop), would be better to build with `cordova-android@3.7.1` or later.
-
-## Installation
-Use Cordova Command-Line Interface (CLI). At first, check Cordova version:
-```sh
-$ cordova --version
-```
-If using 5.0.0 or later, you can install it via npm:
-```sh
-$ cordova plugin add cordova-plugin-websocket
-```
-If using other old versions, you can install it via GitHub:
-```sh
-$ cordova plugin add https://github.com/knowledgecode/WebSocket-for-Android.git
-```
-
-#### Caveats
-Cordova core plugins have been moved to npm from Cordova plugins registry (CPR). This plugin has been moved as well. It will be **no longer updated** in CPR. Not recommended even if you can still install it from there:
-```sh
-$ cordova plugin add com.knowledgecode.cordova.websocket
-```
-
-#### Setting a Content-Security-Policy (CSP)
-`cordova-android@4.0.0` supports SCP. In order to permit WebSocket access using `cordova-plugin-whitelist`, append `connect-src` directive in `index.html`:
-```html
-connect-src ws://example.com wss://example.com
-```
-For example:
-```html
-<head>
- <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src ws://example.com wss://example.com">
-```
-
-## Upgrading from previous versions
-Check the plugin id:
-```sh
-$ cordova plugin
-```
-Remove and reinstall:
-```sh
-$ cordova plugin rm <PLUGIN ID>
-$ cordova plugin add cordova-plugin-websocket
-```
-Also will need to install `cordova-plugin-whitelist` or `cordova-plugin-legacy-whitelist` if using `cordova-android@4.0.0` and later.
-
-#### Caveats
-When install this plugin, it adds `INTERNET` permission to `platforms/android/AndroidManifest.xml`. If remove this plugin, the permission is also removed at the same time even if it is required for other plugins.
-
-## Usage
-### *WebSocket(url[, protocols])*
-The WebSocket(url, protocols) constructor takes one or two arguments. The first argument, url, specifies the URL to which to connect. The second, protocols, is either a string or an array of strings.
-A simple code is as follows:
-```javascript
-document.addEventListener('deviceready', function () {
- var ws = new WebSocket('ws://echo.websocket.org');
-
- ws.onopen = function () {
- console.log('open');
- this.send('hello'); // transmit "hello" after connecting
- };
-
- ws.onmessage = function (event) {
- console.log(event.data); // will be "hello"
- this.close();
- };
-
- ws.onerror = function () {
- console.log('error occurred!');
- };
-
- ws.onclose = function (event) {
- console.log('close code=' + event.code);
- };
-}, false);
-```
-#### Options
-This plugin has the following options. All these parameters are optional. Of course these don't affect built-in WebSocket.
-
-| key | type | default value | supported version |
-|:---------------------|:--------|:--------------------|:-------------------------|
-| origin | String | file:// (usually) | v0.3.0 ~ |
-| maxConnectTime | Number | 75000 | v0.4.0 ~ |
-| maxTextMessageSize | Number | -1 | v0.4.0 ~ (except v0.8.x) |
-| maxBinaryMessageSize | Number | -1 | v0.4.0 ~ (except v0.8.x) |
-| override | Boolean | false | v0.8.0 ~ |
-| agent | String | (depends on device) | v0.9.0 ~ |
-| perMessageDeflate | Boolean | true | v0.10.0 ~ |
-
-`origin` is a value to set the request header field. Default value is usually `file://`. This is the same value as when using built-in WebSocket.
-
-`maxConnectTime` is time to wait for connection. A unit is millisecond.
-
-`maxTextMessageSize` and `maxBinaryMessageSize` are receivable maximum size from the server. Default value is -1 (unlimited. depends on heap size of devices). A unit is byte.
-
-`override` is a flag to force WebView to use this plugin even if it supports WebSocket. However in most cases it will be slower than built-in WebSocket.
-
-`agent` is user-agent to set the request header field. Default value depends on devices. This is the same value as when using built-in WebSocket.
-
-`perMessageDeflate` is a flag whether to use permessage-deflate extension or not. Default value is true (but as of v0.10 was false). Sends data with compression if the server also supports permessage-deflate. However if mainly sending compressed binary like JPEG images, recommended to set to false.
-
-If change these parameters, need to do before creating a instance:
-```javascript
-WebSocket.pluginOptions = {
- origin: 'http://example.com',
- maxConnectTime: 5000,
- override: true
-};
-
-var ws = new WebSocket('ws://echo.websocket.org');
-```
-### *send(data)*
-Transmits data to the server over the WebSocket connection. The data takes a string, a blob, or an arraybuffer.
-
-#### Notes
-An upper limit of the message size depends on heap size of devices. It would be better to consider a way to split the message if it is quite large.
-### *close([code[, reason]])*
-Closes the WebSocket connection or connection attempt, if any.
-
-## Change Log
-See [CHANGELOG.md](https://github.com/knowledgecode/WebSocket-for-Android/blob/master/CHANGELOG.md).
-
-## License
-This plugin is available under the terms of the Apache License Version 2.0.
diff --git a/plugins/cordova-plugin-websocket/package.json b/plugins/cordova-plugin-websocket/package.json deleted file mode 100644 index cdeef009..00000000 --- a/plugins/cordova-plugin-websocket/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "cordova-plugin-websocket", - "version": "0.11.0", - "description": "Cordova WebSocket Plugin for Android", - "cordova": { - "id": "cordova-plugin-websocket", - "platforms": [ - "android" - ] - }, - "repository": { - "type": "git", - "url": "git+https://github.com/knowledgecode/WebSocket-for-Android.git" - }, - "keywords": [ - "cordova", - "phonegap", - "websocket", - "android", - "ecosystem:cordova", - "cordova-android" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ], - "author": "KNOWLEDGECODE", - "license": "Apache 2.0", - "bugs": { - "url": "https://github.com/knowledgecode/WebSocket-for-Android/issues" - }, - "homepage": "https://github.com/knowledgecode/WebSocket-for-Android#readme" -} diff --git a/plugins/cordova-plugin-websocket/plugin.xml b/plugins/cordova-plugin-websocket/plugin.xml deleted file mode 100644 index 8d610e68..00000000 --- a/plugins/cordova-plugin-websocket/plugin.xml +++ /dev/null @@ -1,112 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="cordova-plugin-websocket" - version="0.11.0"> - <name>WebSocket for Android</name> - <description>Cordova WebSocket Plugin for Android</description> - <license>Apache 2.0</license> - <keywords>cordova,phonegap,websocket,android</keywords> - - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <platform name="android"> - <js-module src="www/websocket.js" name="websocket"> - <clobbers target="WebSocket" /> - </js-module> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="WebSocket"> - <param name="android-package" value="com.knowledgecode.cordova.websocket.WebSocket" /> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/*"> - <uses-permission android:name="android.permission.INTERNET" /> - </config-file> - - <source-file src="src/android/com/knowledgecode/cordova/websocket/ConnectionTask.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/DestroyTask.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/DisconnectionTask.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/ResetTask.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/SendingTask.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/TaskBean.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/TaskRunner.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/WebSocket.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/com/knowledgecode/cordova/websocket/WebSocketGenerator.java" target-dir="src/com/knowledgecode/cordova/websocket" /> - <source-file src="src/android/org/eclipse/jetty/http/HttpException.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/http/HttpHeaders.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/http/HttpHeaderValues.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/http/HttpMethods.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/http/HttpParser.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/http/HttpVersions.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/http/Parser.java" target-dir="src/org/eclipse/jetty/http" /> - <source-file src="src/android/org/eclipse/jetty/io/AbstractBuffer.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/AbstractBuffers.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/AbstractConnection.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/AsyncEndPoint.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/Buffer.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/BufferCache.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/Buffers.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/BufferUtil.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/ByteArrayBuffer.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/ConnectedEndPoint.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/Connection.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/EndPoint.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/EofException.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/SimpleBuffers.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/ThreadLocalBuffers.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/View.java" target-dir="src/org/eclipse/jetty/io" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/AsyncConnection.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/ChannelEndPoint.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/DirectNIOBuffer.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/NIOBuffer.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/SelectorManager.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/io/nio/SslConnection.java" target-dir="src/org/eclipse/jetty/io/nio" /> - <source-file src="src/android/org/eclipse/jetty/util/BlockingArrayQueue.java" target-dir="src/org/eclipse/jetty/util" /> - <source-file src="src/android/org/eclipse/jetty/util/ConcurrentHashSet.java" target-dir="src/org/eclipse/jetty/util" /> - <source-file src="src/android/org/eclipse/jetty/util/IO.java" target-dir="src/org/eclipse/jetty/util" /> - <source-file src="src/android/org/eclipse/jetty/util/QuotedStringTokenizer.java" target-dir="src/org/eclipse/jetty/util" /> - <source-file src="src/android/org/eclipse/jetty/util/StringMap.java" target-dir="src/org/eclipse/jetty/util" /> - <source-file src="src/android/org/eclipse/jetty/util/thread/QueuedThreadPool.java" target-dir="src/org/eclipse/jetty/util/thread" /> - <source-file src="src/android/org/eclipse/jetty/util/thread/ThreadPool.java" target-dir="src/org/eclipse/jetty/util/thread" /> - <source-file src="src/android/org/eclipse/jetty/util/thread/Timeout.java" target-dir="src/org/eclipse/jetty/util/thread" /> - <source-file src="src/android/org/eclipse/jetty/util/TypeUtil.java" target-dir="src/org/eclipse/jetty/util" /> - <source-file src="src/android/org/eclipse/jetty/util/component/AbstractLifeCycle.java" target-dir="src/org/eclipse/jetty/util/component" /> - <source-file src="src/android/org/eclipse/jetty/util/component/AggregateLifeCycle.java" target-dir="src/org/eclipse/jetty/util/component" /> - <source-file src="src/android/org/eclipse/jetty/util/component/Dumpable.java" target-dir="src/org/eclipse/jetty/util/component" /> - <source-file src="src/android/org/eclipse/jetty/util/component/LifeCycle.java" target-dir="src/org/eclipse/jetty/util/component" /> - <!-- <source-file src="src/android/org/eclipse/jetty/util/log/AndroidLogger.java" target-dir="src/org/eclipse/jetty/util/log" /> --> - <source-file src="src/android/org/eclipse/jetty/util/log/Log.java" target-dir="src/org/eclipse/jetty/util/log" /> - <source-file src="src/android/org/eclipse/jetty/util/log/Logger.java" target-dir="src/org/eclipse/jetty/util/log" /> - <source-file src="src/android/org/eclipse/jetty/util/resource/Resource.java" target-dir="src/org/eclipse/jetty/util/resource" /> - <source-file src="src/android/org/eclipse/jetty/util/resource/URLResource.java" target-dir="src/org/eclipse/jetty/util/resource" /> - <source-file src="src/android/org/eclipse/jetty/util/security/CertificateUtils.java" target-dir="src/org/eclipse/jetty/util/security" /> - <source-file src="src/android/org/eclipse/jetty/util/security/CertificateValidator.java" target-dir="src/org/eclipse/jetty/util/security" /> - <source-file src="src/android/org/eclipse/jetty/util/security/Password.java" target-dir="src/org/eclipse/jetty/util/security" /> - <source-file src="src/android/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java" target-dir="src/org/eclipse/jetty/util/ssl" /> - <source-file src="src/android/org/eclipse/jetty/util/ssl/SslContextFactory.java" target-dir="src/org/eclipse/jetty/util/ssl" /> - <source-file src="src/android/org/eclipse/jetty/websocket/Extension.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/MaskGen.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/PerMessageDeflateExtension.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/RandomMaskGen.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocket.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketBuffer.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketBuffers.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketClient.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketClientFactory.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketConnection.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketGenerator.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketParser.java" target-dir="src/org/eclipse/jetty/websocket" /> - <source-file src="src/android/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java" target-dir="src/org/eclipse/jetty/websocket" /> - </platform> - -</plugin> - diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/ConnectionTask.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/ConnectionTask.java deleted file mode 100644 index f2a3b138..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/ConnectionTask.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import java.net.URI; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; -import org.apache.cordova.PluginResult.Status; -import org.eclipse.jetty.websocket.PerMessageDeflateExtension; -import org.eclipse.jetty.websocket.WebSocket.Connection; -import org.eclipse.jetty.websocket.WebSocketClient; -import org.eclipse.jetty.websocket.WebSocketClientFactory; -import org.json.JSONArray; -import org.json.JSONObject; - -import com.knowledgecode.cordova.websocket.TaskRunner.Task; -import com.knowledgecode.cordova.websocket.WebSocketGenerator.OnCloseListener; -import com.knowledgecode.cordova.websocket.WebSocketGenerator.OnOpenListener; - -import android.util.SparseArray; -import android.webkit.CookieManager; - -/** - * Connect to server. - */ -class ConnectionTask implements Task { - - private static final long MAX_CONNECT_TIME = 75000; - private static final int MAX_TEXT_MESSAGE_SIZE = -1; - private static final int MAX_BINARY_MESSAGE_SIZE = -1; - - private final WebSocketClientFactory _factory; - private final SparseArray<Connection> _map; - - /** - * Constructor - * - * @param factory - * @param map - */ - public ConnectionTask(WebSocketClientFactory factory, SparseArray<Connection> map) { - _factory = factory; - _map = map; - - if (!_factory.isRunning()) { - try { - _factory.start(); - } catch (Exception e) { - } - } - } - - /** - * Set cookies, if any. - * - * @param cookies - * @param url - */ - private static void setCookie(Map<String, String> cookies, String url) { - String cookie = CookieManager.getInstance().getCookie(url); - - if (cookie != null) { - for (String c : cookie.split(";")) { - String[] pair = c.split("="); - - if (pair.length == 2) { - cookies.put(pair[0], pair[1]); - } - } - } - } - - @Override - public void execute(String rawArgs, CallbackContext ctx) { - try { - WebSocketClient client = _factory.newWebSocketClient(); - - JSONArray args = new JSONArray(rawArgs); - int id = Integer.parseInt(args.getString(0), 16); - URI uri = new URI(args.getString(1)); - String protocol = args.getString(2); - JSONObject options = args.getJSONObject(5); - String origin = options.optString("origin", args.getString(3)); - String agent = options.optString("agent", args.getString(4)); - boolean deflate = options.optBoolean("perMessageDeflate", true); - long maxConnectTime = options.optLong("maxConnectTime", MAX_CONNECT_TIME); - - client.setMaxTextMessageSize(options.optInt("maxTextMessageSize", MAX_TEXT_MESSAGE_SIZE)); - client.setMaxBinaryMessageSize(options.optInt("maxBinaryMessageSize", MAX_BINARY_MESSAGE_SIZE)); - if (protocol.length() > 0) { - client.setProtocol(protocol); - } - if (origin.length() > 0) { - client.setOrigin(origin); - } - if (agent.length() > 0) { - client.setAgent(agent); - } - if (deflate) { - client.getExtensions().add(new PerMessageDeflateExtension()); - } - - setCookie(client.getCookies(), uri.getHost()); - - WebSocketGenerator gen = new WebSocketGenerator(id, ctx); - - gen.setOnOpenListener(new OnOpenListener() { - @Override - public void onOpen(int id, Connection conn) { - _map.put(id, conn); - } - }); - gen.setOnCloseListener(new OnCloseListener() { - @Override - public void onClose(int id) { - if (_map.indexOfKey(id) >= 0) { - _map.remove(id); - } - } - }); - client.open(uri, gen, maxConnectTime, TimeUnit.MILLISECONDS); - } catch (Exception e) { - if (!ctx.isFinished()) { - PluginResult result = new PluginResult(Status.ERROR); - result.setKeepCallback(true); - ctx.sendPluginResult(result); - } - } - } -} - diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/DestroyTask.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/DestroyTask.java deleted file mode 100644 index dcf13445..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/DestroyTask.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import org.apache.cordova.CallbackContext; -import org.eclipse.jetty.websocket.WebSocket.Connection; -import org.eclipse.jetty.websocket.WebSocketClientFactory; - -import com.knowledgecode.cordova.websocket.TaskRunner.Task; - -import android.util.SparseArray; - -/** - * Stop WebSocket client. - */ -class DestroyTask implements Task { - - private final WebSocketClientFactory _factory; - private final SparseArray<Connection> _map; - - /** - * Constructor - * - * @param factory - * @param map - */ - public DestroyTask(WebSocketClientFactory factory, SparseArray<Connection> map) { - _factory = factory; - _map = map; - } - - @Override - public void execute(String rawArgs, CallbackContext ctx) { - for (int i = 0; i < _map.size(); i++) { - int key = _map.keyAt(i); - - if (_map.get(key).isOpen()) { - _map.get(key).close(); - } - } - _map.clear(); - - if (_factory.isRunning()) { - try { - _factory.stop(); - } catch (Exception e) { - } - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/DisconnectionTask.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/DisconnectionTask.java deleted file mode 100644 index 18502488..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/DisconnectionTask.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; -import org.apache.cordova.PluginResult.Status; -import org.eclipse.jetty.websocket.WebSocket.Connection; -import org.json.JSONArray; - -import com.knowledgecode.cordova.websocket.TaskRunner.Task; - -import android.util.SparseArray; - -/** - * Close a connection. - */ -class DisconnectionTask implements Task { - - private final SparseArray<Connection> _map; - - /** - * Constructor - * - * @param map - */ - public DisconnectionTask(SparseArray<Connection> map) { - _map = map; - } - - @Override - public void execute(String rawArgs, CallbackContext ctx) { - try { - JSONArray args = new JSONArray(rawArgs); - int id = Integer.parseInt(args.getString(0), 16); - int code = args.getInt(1); - String reason = args.getString(2); - Connection conn = _map.get(id); - - if (conn != null) { - if (code > 0) { - conn.close(code, reason); - } else { - conn.close(); - } - } - } catch (Exception e) { - if (!ctx.isFinished()) { - PluginResult result = new PluginResult(Status.ERROR); - result.setKeepCallback(true); - ctx.sendPluginResult(result); - } - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/ResetTask.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/ResetTask.java deleted file mode 100644 index 16d4267b..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/ResetTask.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import org.apache.cordova.CallbackContext; -import org.eclipse.jetty.websocket.WebSocket.Connection; - -import com.knowledgecode.cordova.websocket.TaskRunner.Task; - -import android.util.SparseArray; - -/** - * Close all connections. - */ -class ResetTask implements Task { - - private final SparseArray<Connection> _map; - - /** - * Constructor - * - * @param map - */ - public ResetTask(SparseArray<Connection> map) { - _map = map; - } - - @Override - public void execute(String rawArgs, CallbackContext ctx) { - for (int i = 0; i < _map.size(); i++) { - int key = _map.keyAt(i); - - if (_map.get(key).isOpen()) { - _map.get(key).close(); - } - } - _map.clear(); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/SendingTask.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/SendingTask.java deleted file mode 100644 index ae73da2b..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/SendingTask.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; -import org.apache.cordova.PluginResult.Status; -import org.eclipse.jetty.websocket.WebSocket.Connection; - -import com.knowledgecode.cordova.websocket.TaskRunner.Task; - -import android.util.Base64; -import android.util.SparseArray; - -/** - * Send text/binary data. - */ -class SendingTask implements Task { - - private final SparseArray<Connection> _map; - - /** - * Constructor - * - * @param map - */ - public SendingTask(SparseArray<Connection> map) { - _map = map; - } - - @Override - public void execute(String rawArgs, CallbackContext ctx) { - try { - Connection conn = _map.get(Integer.parseInt(rawArgs.substring(2, 10), 16)); - - if (conn != null) { - if (rawArgs.charAt(10) == '1') { - byte[] binary = Base64.decode(rawArgs.substring(rawArgs.indexOf(',') + 1, rawArgs.length() - 2), - Base64.NO_WRAP); - conn.sendMessage(binary, 0, binary.length); - } else { - conn.sendMessage(rawArgs.substring(11, rawArgs.length() - 2)); - } - } - } catch (Exception e) { - if (!ctx.isFinished()) { - PluginResult result = new PluginResult(Status.ERROR); - result.setKeepCallback(true); - ctx.sendPluginResult(result); - } - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/TaskBean.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/TaskBean.java deleted file mode 100644 index 444f3824..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/TaskBean.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.knowledgecode.cordova.websocket; - -import org.apache.cordova.CallbackContext; - -class TaskBean { - private final String _action; - private final String _rawArgs; - private final CallbackContext _ctx; - - public TaskBean(final String action) { - _action = action; - _rawArgs = "[]"; - _ctx = null; - } - - public TaskBean(final String action, final String rawArgs, final CallbackContext ctx) { - _action = action; - _rawArgs = rawArgs; - _ctx = ctx; - } - - public String getAction() { - return _action; - } - - public String getRawArgs() { - return _rawArgs; - } - - public CallbackContext getCtx() { - return _ctx; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/TaskRunner.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/TaskRunner.java deleted file mode 100644 index 9fe2ad59..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/TaskRunner.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -import org.apache.cordova.CallbackContext; - -class TaskRunner implements Runnable { - - interface Task { - public void execute(String rawArgs, CallbackContext ctx); - } - - private BlockingQueue<TaskBean> _queue; - private Map<String, Task> _map; - - public TaskRunner() { - _queue = new LinkedBlockingQueue<TaskBean>(); - _map = new HashMap<String, Task>(); - } - - public void setTask(String action, Task task) { - _map.put(action, task); - } - - public boolean addTaskQueue(TaskBean bean) { - try { - _queue.put(bean); - } catch (InterruptedException e) { - return false; - } - return true; - } - - @Override - public void run() { - while (true) { - TaskBean task; - - try { - task = _queue.take(); - } catch (InterruptedException e) { - break; - } - String action = task.getAction(); - - _map.get(action).execute(task.getRawArgs(), task.getCtx()); - if (WebSocket.DESTROY_TASK.equals(action)) { - break; - } - } - _queue.clear(); - _map.clear(); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/WebSocket.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/WebSocket.java deleted file mode 100644 index 479de7ee..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/WebSocket.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.eclipse.jetty.websocket.WebSocket.Connection; -import org.eclipse.jetty.websocket.WebSocketClientFactory; - -import android.util.SparseArray; - -/** - * Cordova WebSocket Plugin for Android - * This plugin is using Jetty under the terms of the Apache License v2.0. - * - * @author KNOWLEDGECODE <knowledgecode@gmail.com> - * @version 0.11.0 - */ -public class WebSocket extends CordovaPlugin { - - static final String CREATE_TASK = "create"; - static final String SEND_TASK = "send"; - static final String CLOSE_TASK = "close"; - static final String RESET_TASK = "reset"; - static final String DESTROY_TASK = "destroy"; - - private WebSocketClientFactory _factory; - private SparseArray<Connection> _conn; - private ExecutorService _executor; - private TaskRunner _runner; - - @Override - public void initialize(CordovaInterface cordova, final CordovaWebView webView) { - super.initialize(cordova, webView); - _factory = new WebSocketClientFactory(); - _conn = new SparseArray<Connection>(); - _executor = Executors.newSingleThreadExecutor(); - _runner = new TaskRunner(); - _runner.setTask(CREATE_TASK, new ConnectionTask(_factory, _conn)); - _runner.setTask(SEND_TASK, new SendingTask(_conn)); - _runner.setTask(CLOSE_TASK, new DisconnectionTask(_conn)); - _runner.setTask(RESET_TASK, new ResetTask(_conn)); - _runner.setTask(DESTROY_TASK, new DestroyTask(_factory, _conn)); - _executor.execute(_runner); - } - - @Override - public boolean execute(String action, String rawArgs, CallbackContext ctx) { - return _runner.addTaskQueue(new TaskBean(action, rawArgs, ctx)); - }; - - @Override - public void onReset() { - _runner.addTaskQueue(new TaskBean(RESET_TASK)); - super.onReset(); - } - - @Override - public void onDestroy() { - _runner.addTaskQueue(new TaskBean(DESTROY_TASK)); - _executor.shutdown(); - try { - _executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - } - super.onDestroy(); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/WebSocketGenerator.java b/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/WebSocketGenerator.java deleted file mode 100644 index 3132240a..00000000 --- a/plugins/cordova-plugin-websocket/src/android/com/knowledgecode/cordova/websocket/WebSocketGenerator.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - */ -package com.knowledgecode.cordova.websocket; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; -import org.apache.cordova.PluginResult.Status; - -import android.util.Base64; - -class WebSocketGenerator implements - org.eclipse.jetty.websocket.WebSocket.OnTextMessage, - org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage { - - interface OnOpenListener { - public void onOpen(int id, Connection conn); - } - - interface OnCloseListener { - public void onClose(int id); - } - - private final int _id; - private final CallbackContext _ctx; - private OnOpenListener _openListener; - private OnCloseListener _closeListener; - - /** - * Constructor - * - * @param id - * @param ctx - */ - public WebSocketGenerator(int id, CallbackContext ctx) { - _id = id; - _ctx = ctx; - _openListener = new OnOpenListener() { - @Override - public void onOpen(int id, Connection conn) { - // NOP - } - }; - _closeListener = new OnCloseListener() { - @Override - public void onClose(int id) { - // NOP - } - }; - } - - /** - * Set OnOpen listener. - * - * @param l - */ - public void setOnOpenListener(OnOpenListener l) { - _openListener = l; - } - - /** - * Set OnClose listener. - * - * @param l - */ - public void setOnCloseListener(OnCloseListener l) { - _closeListener = l; - } - - @Override - public void onOpen(Connection conn) { - _openListener.onOpen(_id, conn); - - String protocol = conn.getProtocol(); - String extensions = conn.getExtensions(); - protocol = protocol == null ? "" : protocol; - extensions = extensions == null ? "" : extensions; - sendCallback(String.format("O[\"%s\",\"%s\"]", protocol, extensions), true); - } - - @Override - public void onMessage(String data) { - sendCallback("T" + data, true); - } - - @Override - public void onMessage(byte[] data, int offset, int length) { - sendCallback("B" + Base64.encodeToString(data, offset, length, Base64.NO_WRAP), true); - } - - @Override - public void onClose(int code, String reason) { - _closeListener.onClose(_id); - - String wasClean = code == 1000 ? "1" : "0"; - reason = reason == null ? "" : reason; - sendCallback(String.format("C%s%4d%s", wasClean, code, reason), false); - } - - /** - * Send plugin result. - * - * @param callbackString - * @param keepCallback - */ - private void sendCallback(String callbackString, boolean keepCallback) { - if (!_ctx.isFinished()) { - PluginResult result = new PluginResult(Status.OK, callbackString); - result.setKeepCallback(keepCallback); - _ctx.sendPluginResult(result); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpException.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpException.java deleted file mode 100644 index 4ae60c02..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpException.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; - -@SuppressWarnings("serial") -public class HttpException extends IOException -{ - int _status; - String _reason; - - /* ------------------------------------------------------------ */ - public HttpException(int status) - { - _status=status; - _reason=null; - } - - /* ------------------------------------------------------------ */ - public HttpException(int status,String reason) - { - _status=status; - _reason=reason; - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return ("HttpException("+_status+","+_reason+","+super.getCause()+")"); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpHeaderValues.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpHeaderValues.java deleted file mode 100644 index c8d5ed58..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpHeaderValues.java +++ /dev/null @@ -1,75 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.BufferCache; -import org.eclipse.jetty.io.ByteArrayBuffer; - -/** - * Cached HTTP Header values. - * This class caches the conversion of common HTTP Header values to and from {@link ByteArrayBuffer} instances. - * The resource "/org/eclipse/jetty/useragents" is checked for a list of common user agents, so that repeated - * creation of strings for these agents can be avoided. - * - * - */ -public class HttpHeaderValues extends BufferCache -{ - public final static String - CLOSE="close", - CHUNKED="chunked", - GZIP="gzip", - IDENTITY="identity", - KEEP_ALIVE="keep-alive", - CONTINUE="100-continue", - PROCESSING="102-processing", - TE="TE", - BYTES="bytes", - NO_CACHE="no-cache", - UPGRADE="Upgrade"; - - public final static int - CLOSE_ORDINAL=1, - CHUNKED_ORDINAL=2, - GZIP_ORDINAL=3, - IDENTITY_ORDINAL=4, - KEEP_ALIVE_ORDINAL=5, - CONTINUE_ORDINAL=6, - PROCESSING_ORDINAL=7, - TE_ORDINAL=8, - BYTES_ORDINAL=9, - NO_CACHE_ORDINAL=10, - UPGRADE_ORDINAL=11; - - public final static HttpHeaderValues CACHE= new HttpHeaderValues(); - - public final static Buffer - CLOSE_BUFFER=CACHE.add(CLOSE,CLOSE_ORDINAL), - CHUNKED_BUFFER=CACHE.add(CHUNKED,CHUNKED_ORDINAL), - GZIP_BUFFER=CACHE.add(GZIP,GZIP_ORDINAL), - IDENTITY_BUFFER=CACHE.add(IDENTITY,IDENTITY_ORDINAL), - KEEP_ALIVE_BUFFER=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL), - CONTINUE_BUFFER=CACHE.add(CONTINUE, CONTINUE_ORDINAL), - PROCESSING_BUFFER=CACHE.add(PROCESSING, PROCESSING_ORDINAL), - TE_BUFFER=CACHE.add(TE,TE_ORDINAL), - BYTES_BUFFER=CACHE.add(BYTES,BYTES_ORDINAL), - NO_CACHE_BUFFER=CACHE.add(NO_CACHE,NO_CACHE_ORDINAL), - UPGRADE_BUFFER=CACHE.add(UPGRADE,UPGRADE_ORDINAL); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpHeaders.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpHeaders.java deleted file mode 100644 index 87f5d1e3..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpHeaders.java +++ /dev/null @@ -1,238 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.BufferCache; - -/* ------------------------------------------------------------------------------- */ -/** - */ -public class HttpHeaders extends BufferCache -{ - /* ------------------------------------------------------------ */ - /** General Fields. - */ - public final static String - CONNECTION= "Connection", - CACHE_CONTROL= "Cache-Control", - DATE= "Date", - PRAGMA= "Pragma", - PROXY_CONNECTION = "Proxy-Connection", - TRAILER= "Trailer", - TRANSFER_ENCODING= "Transfer-Encoding", - UPGRADE= "Upgrade", - VIA= "Via", - WARNING= "Warning", - NEGOTIATE= "Negotiate"; - - /* ------------------------------------------------------------ */ - /** Entity Fields. - */ - public final static String ALLOW= "Allow", - CONTENT_ENCODING= "Content-Encoding", - CONTENT_LANGUAGE= "Content-Language", - CONTENT_LENGTH= "Content-Length", - CONTENT_LOCATION= "Content-Location", - CONTENT_MD5= "Content-MD5", - CONTENT_RANGE= "Content-Range", - CONTENT_TYPE= "Content-Type", - EXPIRES= "Expires", - LAST_MODIFIED= "Last-Modified"; - - /* ------------------------------------------------------------ */ - /** Request Fields. - */ - public final static String ACCEPT= "Accept", - ACCEPT_CHARSET= "Accept-Charset", - ACCEPT_ENCODING= "Accept-Encoding", - ACCEPT_LANGUAGE= "Accept-Language", - AUTHORIZATION= "Authorization", - EXPECT= "Expect", - FORWARDED= "Forwarded", - FROM= "From", - HOST= "Host", - IF_MATCH= "If-Match", - IF_MODIFIED_SINCE= "If-Modified-Since", - IF_NONE_MATCH= "If-None-Match", - IF_RANGE= "If-Range", - IF_UNMODIFIED_SINCE= "If-Unmodified-Since", - KEEP_ALIVE= "Keep-Alive", - MAX_FORWARDS= "Max-Forwards", - PROXY_AUTHORIZATION= "Proxy-Authorization", - RANGE= "Range", - REQUEST_RANGE= "Request-Range", - REFERER= "Referer", - TE= "TE", - USER_AGENT= "User-Agent", - X_FORWARDED_FOR= "X-Forwarded-For", - X_FORWARDED_PROTO= "X-Forwarded-Proto", - X_FORWARDED_SERVER= "X-Forwarded-Server", - X_FORWARDED_HOST= "X-Forwarded-Host"; - - /* ------------------------------------------------------------ */ - /** Response Fields. - */ - public final static String ACCEPT_RANGES= "Accept-Ranges", - AGE= "Age", - ETAG= "ETag", - LOCATION= "Location", - PROXY_AUTHENTICATE= "Proxy-Authenticate", - RETRY_AFTER= "Retry-After", - SERVER= "Server", - SERVLET_ENGINE= "Servlet-Engine", - VARY= "Vary", - WWW_AUTHENTICATE= "WWW-Authenticate"; - - /* ------------------------------------------------------------ */ - /** Other Fields. - */ - public final static String COOKIE= "Cookie", - SET_COOKIE= "Set-Cookie", - SET_COOKIE2= "Set-Cookie2", - MIME_VERSION= "MIME-Version", - IDENTITY= "identity"; - - public final static int CONNECTION_ORDINAL= 1, - DATE_ORDINAL= 2, - PRAGMA_ORDINAL= 3, - TRAILER_ORDINAL= 4, - TRANSFER_ENCODING_ORDINAL= 5, - UPGRADE_ORDINAL= 6, - VIA_ORDINAL= 7, - WARNING_ORDINAL= 8, - ALLOW_ORDINAL= 9, - CONTENT_ENCODING_ORDINAL= 10, - CONTENT_LANGUAGE_ORDINAL= 11, - CONTENT_LENGTH_ORDINAL= 12, - CONTENT_LOCATION_ORDINAL= 13, - CONTENT_MD5_ORDINAL= 14, - CONTENT_RANGE_ORDINAL= 15, - CONTENT_TYPE_ORDINAL= 16, - EXPIRES_ORDINAL= 17, - LAST_MODIFIED_ORDINAL= 18, - ACCEPT_ORDINAL= 19, - ACCEPT_CHARSET_ORDINAL= 20, - ACCEPT_ENCODING_ORDINAL= 21, - ACCEPT_LANGUAGE_ORDINAL= 22, - AUTHORIZATION_ORDINAL= 23, - EXPECT_ORDINAL= 24, - FORWARDED_ORDINAL= 25, - FROM_ORDINAL= 26, - HOST_ORDINAL= 27, - IF_MATCH_ORDINAL= 28, - IF_MODIFIED_SINCE_ORDINAL= 29, - IF_NONE_MATCH_ORDINAL= 30, - IF_RANGE_ORDINAL= 31, - IF_UNMODIFIED_SINCE_ORDINAL= 32, - KEEP_ALIVE_ORDINAL= 33, - MAX_FORWARDS_ORDINAL= 34, - PROXY_AUTHORIZATION_ORDINAL= 35, - RANGE_ORDINAL= 36, - REQUEST_RANGE_ORDINAL= 37, - REFERER_ORDINAL= 38, - TE_ORDINAL= 39, - USER_AGENT_ORDINAL= 40, - X_FORWARDED_FOR_ORDINAL= 41, - ACCEPT_RANGES_ORDINAL= 42, - AGE_ORDINAL= 43, - ETAG_ORDINAL= 44, - LOCATION_ORDINAL= 45, - PROXY_AUTHENTICATE_ORDINAL= 46, - RETRY_AFTER_ORDINAL= 47, - SERVER_ORDINAL= 48, - SERVLET_ENGINE_ORDINAL= 49, - VARY_ORDINAL= 50, - WWW_AUTHENTICATE_ORDINAL= 51, - COOKIE_ORDINAL= 52, - SET_COOKIE_ORDINAL= 53, - SET_COOKIE2_ORDINAL= 54, - MIME_VERSION_ORDINAL= 55, - IDENTITY_ORDINAL= 56, - CACHE_CONTROL_ORDINAL=57, - PROXY_CONNECTION_ORDINAL=58, - X_FORWARDED_PROTO_ORDINAL=59, - X_FORWARDED_SERVER_ORDINAL=60, - X_FORWARDED_HOST_ORDINAL=61; - - public final static HttpHeaders CACHE= new HttpHeaders(); - - public final static Buffer - HOST_BUFFER=CACHE.add(HOST,HOST_ORDINAL), - ACCEPT_BUFFER=CACHE.add(ACCEPT,ACCEPT_ORDINAL), - ACCEPT_CHARSET_BUFFER=CACHE.add(ACCEPT_CHARSET,ACCEPT_CHARSET_ORDINAL), - ACCEPT_ENCODING_BUFFER=CACHE.add(ACCEPT_ENCODING,ACCEPT_ENCODING_ORDINAL), - ACCEPT_LANGUAGE_BUFFER=CACHE.add(ACCEPT_LANGUAGE,ACCEPT_LANGUAGE_ORDINAL), - CONTENT_LENGTH_BUFFER=CACHE.add(CONTENT_LENGTH,CONTENT_LENGTH_ORDINAL), - CONNECTION_BUFFER=CACHE.add(CONNECTION,CONNECTION_ORDINAL), - CACHE_CONTROL_BUFFER=CACHE.add(CACHE_CONTROL,CACHE_CONTROL_ORDINAL), - DATE_BUFFER=CACHE.add(DATE,DATE_ORDINAL), - PRAGMA_BUFFER=CACHE.add(PRAGMA,PRAGMA_ORDINAL), - TRAILER_BUFFER=CACHE.add(TRAILER,TRAILER_ORDINAL), - TRANSFER_ENCODING_BUFFER=CACHE.add(TRANSFER_ENCODING,TRANSFER_ENCODING_ORDINAL), - UPGRADE_BUFFER=CACHE.add(UPGRADE,UPGRADE_ORDINAL), - VIA_BUFFER=CACHE.add(VIA,VIA_ORDINAL), - WARNING_BUFFER=CACHE.add(WARNING,WARNING_ORDINAL), - ALLOW_BUFFER=CACHE.add(ALLOW,ALLOW_ORDINAL), - CONTENT_ENCODING_BUFFER=CACHE.add(CONTENT_ENCODING,CONTENT_ENCODING_ORDINAL), - CONTENT_LANGUAGE_BUFFER=CACHE.add(CONTENT_LANGUAGE,CONTENT_LANGUAGE_ORDINAL), - CONTENT_LOCATION_BUFFER=CACHE.add(CONTENT_LOCATION,CONTENT_LOCATION_ORDINAL), - CONTENT_MD5_BUFFER=CACHE.add(CONTENT_MD5,CONTENT_MD5_ORDINAL), - CONTENT_RANGE_BUFFER=CACHE.add(CONTENT_RANGE,CONTENT_RANGE_ORDINAL), - CONTENT_TYPE_BUFFER=CACHE.add(CONTENT_TYPE,CONTENT_TYPE_ORDINAL), - EXPIRES_BUFFER=CACHE.add(EXPIRES,EXPIRES_ORDINAL), - LAST_MODIFIED_BUFFER=CACHE.add(LAST_MODIFIED,LAST_MODIFIED_ORDINAL), - AUTHORIZATION_BUFFER=CACHE.add(AUTHORIZATION,AUTHORIZATION_ORDINAL), - EXPECT_BUFFER=CACHE.add(EXPECT,EXPECT_ORDINAL), - FORWARDED_BUFFER=CACHE.add(FORWARDED,FORWARDED_ORDINAL), - FROM_BUFFER=CACHE.add(FROM,FROM_ORDINAL), - IF_MATCH_BUFFER=CACHE.add(IF_MATCH,IF_MATCH_ORDINAL), - IF_MODIFIED_SINCE_BUFFER=CACHE.add(IF_MODIFIED_SINCE,IF_MODIFIED_SINCE_ORDINAL), - IF_NONE_MATCH_BUFFER=CACHE.add(IF_NONE_MATCH,IF_NONE_MATCH_ORDINAL), - IF_RANGE_BUFFER=CACHE.add(IF_RANGE,IF_RANGE_ORDINAL), - IF_UNMODIFIED_SINCE_BUFFER=CACHE.add(IF_UNMODIFIED_SINCE,IF_UNMODIFIED_SINCE_ORDINAL), - KEEP_ALIVE_BUFFER=CACHE.add(KEEP_ALIVE,KEEP_ALIVE_ORDINAL), - MAX_FORWARDS_BUFFER=CACHE.add(MAX_FORWARDS,MAX_FORWARDS_ORDINAL), - PROXY_AUTHORIZATION_BUFFER=CACHE.add(PROXY_AUTHORIZATION,PROXY_AUTHORIZATION_ORDINAL), - RANGE_BUFFER=CACHE.add(RANGE,RANGE_ORDINAL), - REQUEST_RANGE_BUFFER=CACHE.add(REQUEST_RANGE,REQUEST_RANGE_ORDINAL), - REFERER_BUFFER=CACHE.add(REFERER,REFERER_ORDINAL), - TE_BUFFER=CACHE.add(TE,TE_ORDINAL), - USER_AGENT_BUFFER=CACHE.add(USER_AGENT,USER_AGENT_ORDINAL), - X_FORWARDED_FOR_BUFFER=CACHE.add(X_FORWARDED_FOR,X_FORWARDED_FOR_ORDINAL), - X_FORWARDED_PROTO_BUFFER=CACHE.add(X_FORWARDED_PROTO,X_FORWARDED_PROTO_ORDINAL), - X_FORWARDED_SERVER_BUFFER=CACHE.add(X_FORWARDED_SERVER,X_FORWARDED_SERVER_ORDINAL), - X_FORWARDED_HOST_BUFFER=CACHE.add(X_FORWARDED_HOST,X_FORWARDED_HOST_ORDINAL), - ACCEPT_RANGES_BUFFER=CACHE.add(ACCEPT_RANGES,ACCEPT_RANGES_ORDINAL), - AGE_BUFFER=CACHE.add(AGE,AGE_ORDINAL), - ETAG_BUFFER=CACHE.add(ETAG,ETAG_ORDINAL), - LOCATION_BUFFER=CACHE.add(LOCATION,LOCATION_ORDINAL), - PROXY_AUTHENTICATE_BUFFER=CACHE.add(PROXY_AUTHENTICATE,PROXY_AUTHENTICATE_ORDINAL), - RETRY_AFTER_BUFFER=CACHE.add(RETRY_AFTER,RETRY_AFTER_ORDINAL), - SERVER_BUFFER=CACHE.add(SERVER,SERVER_ORDINAL), - SERVLET_ENGINE_BUFFER=CACHE.add(SERVLET_ENGINE,SERVLET_ENGINE_ORDINAL), - VARY_BUFFER=CACHE.add(VARY,VARY_ORDINAL), - WWW_AUTHENTICATE_BUFFER=CACHE.add(WWW_AUTHENTICATE,WWW_AUTHENTICATE_ORDINAL), - COOKIE_BUFFER=CACHE.add(COOKIE,COOKIE_ORDINAL), - SET_COOKIE_BUFFER=CACHE.add(SET_COOKIE,SET_COOKIE_ORDINAL), - SET_COOKIE2_BUFFER=CACHE.add(SET_COOKIE2,SET_COOKIE2_ORDINAL), - MIME_VERSION_BUFFER=CACHE.add(MIME_VERSION,MIME_VERSION_ORDINAL), - IDENTITY_BUFFER=CACHE.add(IDENTITY,IDENTITY_ORDINAL), - PROXY_CONNECTION_BUFFER=CACHE.add(PROXY_CONNECTION,PROXY_CONNECTION_ORDINAL); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpMethods.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpMethods.java deleted file mode 100644 index 2c91fde9..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpMethods.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.BufferCache; - -/* ------------------------------------------------------------------------------- */ -/** - * - * - */ -public class HttpMethods -{ - public final static String GET= "GET", - POST= "POST", - HEAD= "HEAD", - PUT= "PUT", - OPTIONS= "OPTIONS", - DELETE= "DELETE", - TRACE= "TRACE", - CONNECT= "CONNECT", - MOVE= "MOVE"; - - public final static int GET_ORDINAL= 1, - POST_ORDINAL= 2, - HEAD_ORDINAL= 3, - PUT_ORDINAL= 4, - OPTIONS_ORDINAL= 5, - DELETE_ORDINAL= 6, - TRACE_ORDINAL= 7, - CONNECT_ORDINAL= 8, - MOVE_ORDINAL= 9; - - public final static BufferCache CACHE= new BufferCache(); - - public final static Buffer - GET_BUFFER= CACHE.add(GET, GET_ORDINAL), - POST_BUFFER= CACHE.add(POST, POST_ORDINAL), - HEAD_BUFFER= CACHE.add(HEAD, HEAD_ORDINAL), - PUT_BUFFER= CACHE.add(PUT, PUT_ORDINAL), - OPTIONS_BUFFER= CACHE.add(OPTIONS, OPTIONS_ORDINAL), - DELETE_BUFFER= CACHE.add(DELETE, DELETE_ORDINAL), - TRACE_BUFFER= CACHE.add(TRACE, TRACE_ORDINAL), - CONNECT_BUFFER= CACHE.add(CONNECT, CONNECT_ORDINAL), - MOVE_BUFFER= CACHE.add(MOVE, MOVE_ORDINAL); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpParser.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpParser.java deleted file mode 100644 index 0547ea93..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpParser.java +++ /dev/null @@ -1,1033 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Locale; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.BufferCache.CachedBuffer; -import org.eclipse.jetty.io.BufferUtil; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.ByteArrayBuffer; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.io.View; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public class HttpParser implements Parser -{ - private static final Logger LOG = Log.getLogger(HttpParser.class); - - // States - public static final int STATE_START=-14; - public static final int STATE_FIELD0=-13; - public static final int STATE_SPACE1=-12; - public static final int STATE_STATUS=-11; - public static final int STATE_URI=-10; - public static final int STATE_SPACE2=-9; - public static final int STATE_END0=-8; - public static final int STATE_END1=-7; - public static final int STATE_FIELD2=-6; - public static final int STATE_HEADER=-5; - public static final int STATE_HEADER_NAME=-4; - public static final int STATE_HEADER_IN_NAME=-3; - public static final int STATE_HEADER_VALUE=-2; - public static final int STATE_HEADER_IN_VALUE=-1; - public static final int STATE_END=0; - public static final int STATE_EOF_CONTENT=1; - public static final int STATE_CONTENT=2; - public static final int STATE_CHUNKED_CONTENT=3; - public static final int STATE_CHUNK_SIZE=4; - public static final int STATE_CHUNK_PARAMS=5; - public static final int STATE_CHUNK=6; - public static final int STATE_SEEKING_EOF=7; - - public static final Charset __ISO_8859_1 = Charset.forName("ISO-8859-1"); - - public static final int BAD_REQUEST_400 = 400; - public static final int REQUEST_ENTITY_TOO_LARGE_413 = 413; - - static final byte COLON= (byte)':'; - static final byte SPACE= 0x20; - static final byte CARRIAGE_RETURN= 0x0D; - static final byte LINE_FEED= 0x0A; - static final byte SEMI_COLON= (byte)';'; - static final byte TAB= 0x09; - - public static final int UNKNOWN_CONTENT= -3; - public static final int CHUNKED_CONTENT= -2; - public static final int EOF_CONTENT= -1; - public static final int NO_CONTENT= 0; - - private final EventHandler _handler; - private final Buffers _buffers; // source of buffers - private final EndPoint _endp; - private Buffer _header; // Buffer for header data (and small _content) - private Buffer _body; // Buffer for large content - private Buffer _buffer; // The current buffer in use (either _header or _content) - private CachedBuffer _cached; - private final View.CaseInsensitive _tok0; // Saved token: header name, request method or response version - private final View.CaseInsensitive _tok1; // Saved token: header value, request URI or response code - private String _multiLineValue; - private int _responseStatus; // If >0 then we are parsing a response - private boolean _forceContentBuffer; - private boolean _persistent; - - /* ------------------------------------------------------------------------------- */ - protected final View _contentView=new View(); // View of the content in the buffer for {@link Input} - protected int _state=STATE_START; - protected byte _eol; - protected int _length; - protected long _contentLength; - protected long _contentPosition; - protected int _chunkLength; - protected int _chunkPosition; - private boolean _headResponse; - - /* ------------------------------------------------------------------------------- */ - /** - * Constructor. - * @param buffers the buffers to use - * @param endp the endpoint - * @param handler the even handler - */ - public HttpParser(Buffers buffers, EndPoint endp, EventHandler handler) - { - _buffers=buffers; - _endp=endp; - _handler=handler; - _tok0=new View.CaseInsensitive(); - _tok1=new View.CaseInsensitive(); - } - - /* ------------------------------------------------------------ */ - public boolean isIdle() - { - return isState(STATE_START); - } - - /* ------------------------------------------------------------ */ - public boolean isComplete() - { - if (_responseStatus > 0) - return isState(STATE_END) || isState(STATE_SEEKING_EOF); - return isState(STATE_END); - } - - /* ------------------------------------------------------------------------------- */ - public boolean isState(int state) - { - return _state == state; - } - - /* ------------------------------------------------------------------------------- */ - /** - * Parse until END state. - * This method will parse any remaining content in the current buffer as long as there is - * no unconsumed content. It does not care about the {@link #getState current state} of the parser. - * @see #parse - * @see #parseNext - */ - public boolean parseAvailable() throws IOException - { - boolean progress=parseNext()>0; - - // continue parsing - while (!isComplete() && _buffer!=null && _buffer.length()>0 && !_contentView.hasContent()) - { - progress |= parseNext()>0; - } - return progress; - } - - /* ------------------------------------------------------------------------------- */ - /** - * Parse until next Event. - * @return an indication of progress <0 EOF, 0 no progress, >0 progress. - */ - public int parseNext() throws IOException - { - try - { - int progress=0; - - if (_state == STATE_END) - return 0; - - if (_buffer==null) - _buffer=getHeaderBuffer(); - - - if (_state == STATE_CONTENT && _contentPosition == _contentLength) - { - _state=STATE_END; - _handler.messageComplete(_contentPosition); - return 1; - } - - int length=_buffer.length(); - - // Fill buffer if we can - if (length == 0) - { - int filled=-1; - IOException ex=null; - try - { - filled=fill(); - LOG.debug("filled {}/{}",filled,_buffer.length()); - } - catch(IOException e) - { - LOG.debug(this.toString(),e); - ex=e; - } - - if (filled > 0 ) - progress++; - else if (filled < 0 ) - { - _persistent=false; - - // do we have content to deliver? - if (_state>STATE_END) - { - if (_buffer.length()>0 && !_headResponse) - { - Buffer chunk=_buffer.get(_buffer.length()); - _contentPosition += chunk.length(); - _contentView.update(chunk); - _handler.content(chunk); // May recurse here - } - } - - // was this unexpected? - switch(_state) - { - case STATE_END: - case STATE_SEEKING_EOF: - _state=STATE_END; - break; - - case STATE_EOF_CONTENT: - _state=STATE_END; - _handler.messageComplete(_contentPosition); - break; - - default: - _state=STATE_END; - if (!_headResponse) - _handler.earlyEOF(); - _handler.messageComplete(_contentPosition); - } - - if (ex!=null) - throw ex; - - if (!isComplete() && !isIdle()) - throw new EofException(); - - return -1; - } - length=_buffer.length(); - } - - - // Handle header states - byte ch; - byte[] array=_buffer.array(); - int last=_state; - while (_state<STATE_END && length-->0) - { - if (last!=_state) - { - progress++; - last=_state; - } - - ch=_buffer.get(); - - if (_eol == CARRIAGE_RETURN) - { - if (ch == LINE_FEED) - { - _eol=LINE_FEED; - continue; - } - throw new HttpException(BAD_REQUEST_400); - } - _eol=0; - - switch (_state) - { - case STATE_START: - _contentLength=UNKNOWN_CONTENT; - _cached=null; - if (ch > SPACE || ch<0) - { - _buffer.mark(); - _state=STATE_FIELD0; - } - break; - - case STATE_FIELD0: - if (ch == SPACE) - { - _tok0.update(_buffer.markIndex(), _buffer.getIndex() - 1); - _responseStatus=HttpVersions.CACHE.get(_tok0)==null?-1:0; - _state=STATE_SPACE1; - continue; - } - else if (ch < SPACE && ch>=0) - { - throw new HttpException(BAD_REQUEST_400); - } - break; - - case STATE_SPACE1: - if (ch > SPACE || ch<0) - { - _buffer.mark(); - if (_responseStatus>=0) - { - _state=STATE_STATUS; - _responseStatus=ch-'0'; - } - else - _state=STATE_URI; - } - else if (ch < SPACE) - { - throw new HttpException(BAD_REQUEST_400); - } - break; - - case STATE_STATUS: - if (ch == SPACE) - { - _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1); - _state=STATE_SPACE2; - continue; - } - else if (ch>='0' && ch<='9') - { - _responseStatus=_responseStatus*10+(ch-'0'); - continue; - } - else if (ch < SPACE && ch>=0) - { - _handler.startResponse(HttpMethods.CACHE.lookup(_tok0), _responseStatus, null); - _eol=ch; - _state=STATE_HEADER; - _tok0.setPutIndex(_tok0.getIndex()); - _tok1.setPutIndex(_tok1.getIndex()); - _multiLineValue=null; - continue; - } - // not a digit, so must be a URI - _state=STATE_URI; - _responseStatus=-1; - break; - - case STATE_URI: - if (ch == SPACE) - { - _tok1.update(_buffer.markIndex(), _buffer.getIndex() - 1); - _state=STATE_SPACE2; - continue; - } - else if (ch < SPACE && ch>=0) - { - // HTTP/0.9 - _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _buffer.sliceFromMark(), null); - _persistent=false; - _state=STATE_SEEKING_EOF; - _handler.headerComplete(); - _handler.messageComplete(_contentPosition); - return 1; - } - break; - - case STATE_SPACE2: - if (ch > SPACE || ch<0) - { - _buffer.mark(); - _state=STATE_FIELD2; - } - else if (ch < SPACE) - { - if (_responseStatus>0) - { - _handler.startResponse(HttpMethods.CACHE.lookup(_tok0), _responseStatus, null); - _eol=ch; - _state=STATE_HEADER; - _tok0.setPutIndex(_tok0.getIndex()); - _tok1.setPutIndex(_tok1.getIndex()); - _multiLineValue=null; - } - else - { - // HTTP/0.9 - _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _tok1, null); - _persistent=false; - _state=STATE_SEEKING_EOF; - _handler.headerComplete(); - _handler.messageComplete(_contentPosition); - return 1; - } - } - break; - - case STATE_FIELD2: - if (ch == CARRIAGE_RETURN || ch == LINE_FEED) - { - Buffer version; - if (_responseStatus>0) - _handler.startResponse(version=HttpVersions.CACHE.lookup(_tok0), _responseStatus,_buffer.sliceFromMark()); - else - _handler.startRequest(HttpMethods.CACHE.lookup(_tok0), _tok1, version=HttpVersions.CACHE.lookup(_buffer.sliceFromMark())); - _eol=ch; - _persistent=HttpVersions.CACHE.getOrdinal(version)>=HttpVersions.HTTP_1_1_ORDINAL; - _state=STATE_HEADER; - _tok0.setPutIndex(_tok0.getIndex()); - _tok1.setPutIndex(_tok1.getIndex()); - _multiLineValue=null; - continue; - } - break; - - case STATE_HEADER: - switch(ch) - { - case COLON: - case SPACE: - case TAB: - { - // header value without name - continuation? - _length=-1; - _state=STATE_HEADER_VALUE; - break; - } - - default: - { - // handler last header if any - if (_cached!=null || _tok0.length() > 0 || _tok1.length() > 0 || _multiLineValue != null) - { - Buffer header=_cached!=null?_cached:HttpHeaders.CACHE.lookup(_tok0); - _cached=null; - Buffer value=_multiLineValue == null ? _tok1 : new ByteArrayBuffer(_multiLineValue); - - int ho=HttpHeaders.CACHE.getOrdinal(header); - if (ho >= 0) - { - int vo; - - switch (ho) - { - case HttpHeaders.CONTENT_LENGTH_ORDINAL: - if (_contentLength != CHUNKED_CONTENT ) - { - try - { - _contentLength=BufferUtil.toLong(value); - } - catch(NumberFormatException e) - { - LOG.ignore(e); - throw new HttpException(BAD_REQUEST_400); - } - if (_contentLength <= 0) - _contentLength=NO_CONTENT; - } - break; - - case HttpHeaders.TRANSFER_ENCODING_ORDINAL: - value=HttpHeaderValues.CACHE.lookup(value); - vo=HttpHeaderValues.CACHE.getOrdinal(value); - if (HttpHeaderValues.CHUNKED_ORDINAL == vo) - _contentLength=CHUNKED_CONTENT; - else - { - String c=value.toString(__ISO_8859_1); - if (c.endsWith(HttpHeaderValues.CHUNKED)) - _contentLength=CHUNKED_CONTENT; - - else if (c.indexOf(HttpHeaderValues.CHUNKED) >= 0) - throw new HttpException(400,null); - } - break; - - case HttpHeaders.CONNECTION_ORDINAL: - switch(HttpHeaderValues.CACHE.getOrdinal(value)) - { - case HttpHeaderValues.CLOSE_ORDINAL: - _persistent=false; - break; - - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - _persistent=true; - break; - - case -1: // No match, may be multi valued - { - for (String v : value.toString().split(",")) - { - switch(HttpHeaderValues.CACHE.getOrdinal(v.trim())) - { - case HttpHeaderValues.CLOSE_ORDINAL: - _persistent=false; - break; - - case HttpHeaderValues.KEEP_ALIVE_ORDINAL: - _persistent=true; - break; - } - } - break; - } - } - } - } - - _handler.parsedHeader(header, value); - _tok0.setPutIndex(_tok0.getIndex()); - _tok1.setPutIndex(_tok1.getIndex()); - _multiLineValue=null; - } - _buffer.setMarkIndex(-1); - - // now handle ch - if (ch == CARRIAGE_RETURN || ch == LINE_FEED) - { - // is it a response that cannot have a body? - if (_responseStatus > 0 && // response - (_responseStatus == 304 || // not-modified response - _responseStatus == 204 || // no-content response - _responseStatus < 200)) // 1xx response - _contentLength=NO_CONTENT; // ignore any other headers set - // else if we don't know framing - else if (_contentLength == UNKNOWN_CONTENT) - { - if (_responseStatus == 0 // request - || _responseStatus == 304 // not-modified response - || _responseStatus == 204 // no-content response - || _responseStatus < 200) // 1xx response - _contentLength=NO_CONTENT; - else - _contentLength=EOF_CONTENT; - } - - _contentPosition=0; - _eol=ch; - if (_eol==CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==LINE_FEED) - _eol=_buffer.get(); - - // We convert _contentLength to an int for this switch statement because - // we don't care about the amount of data available just whether there is some. - switch (_contentLength > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) _contentLength) - { - case EOF_CONTENT: - _state=STATE_EOF_CONTENT; - _handler.headerComplete(); // May recurse here ! - break; - - case CHUNKED_CONTENT: - _state=STATE_CHUNKED_CONTENT; - _handler.headerComplete(); // May recurse here ! - break; - - case NO_CONTENT: - _handler.headerComplete(); - _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - - default: - _state=STATE_CONTENT; - _handler.headerComplete(); // May recurse here ! - break; - } - return 1; - } - else - { - // New header - _length=1; - _buffer.mark(); - _state=STATE_HEADER_NAME; - - // try cached name! - if (array!=null) - { - _cached=HttpHeaders.CACHE.getBest(array, _buffer.markIndex(), length+1); - - if (_cached!=null) - { - _length=_cached.length(); - _buffer.setGetIndex(_buffer.markIndex()+_length); - length=_buffer.length(); - } - } - } - } - } - - break; - - case STATE_HEADER_NAME: - switch(ch) - { - case CARRIAGE_RETURN: - case LINE_FEED: - if (_length > 0) - _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); - _eol=ch; - _state=STATE_HEADER; - break; - case COLON: - if (_length > 0 && _cached==null) - _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); - _length=-1; - _state=STATE_HEADER_VALUE; - break; - case SPACE: - case TAB: - break; - default: - { - _cached=null; - if (_length == -1) - _buffer.mark(); - _length=_buffer.getIndex() - _buffer.markIndex(); - _state=STATE_HEADER_IN_NAME; - } - } - - break; - - case STATE_HEADER_IN_NAME: - switch(ch) - { - case CARRIAGE_RETURN: - case LINE_FEED: - if (_length > 0) - _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); - _eol=ch; - _state=STATE_HEADER; - break; - case COLON: - if (_length > 0 && _cached==null) - _tok0.update(_buffer.markIndex(), _buffer.markIndex() + _length); - _length=-1; - _state=STATE_HEADER_VALUE; - break; - case SPACE: - case TAB: - _state=STATE_HEADER_NAME; - break; - default: - { - _cached=null; - _length++; - } - } - break; - - case STATE_HEADER_VALUE: - switch(ch) - { - case CARRIAGE_RETURN: - case LINE_FEED: - if (_length > 0) - { - if (_tok1.length() == 0) - _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); - else - { - // Continuation line! - if (_multiLineValue == null) _multiLineValue=_tok1.toString(__ISO_8859_1); - _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); - _multiLineValue += " " + _tok1.toString(__ISO_8859_1); - } - } - _eol=ch; - _state=STATE_HEADER; - break; - case SPACE: - case TAB: - break; - default: - { - if (_length == -1) - _buffer.mark(); - _length=_buffer.getIndex() - _buffer.markIndex(); - _state=STATE_HEADER_IN_VALUE; - } - } - break; - - case STATE_HEADER_IN_VALUE: - switch(ch) - { - case CARRIAGE_RETURN: - case LINE_FEED: - if (_length > 0) - { - if (_tok1.length() == 0) - _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); - else - { - // Continuation line! - if (_multiLineValue == null) _multiLineValue=_tok1.toString(__ISO_8859_1); - _tok1.update(_buffer.markIndex(), _buffer.markIndex() + _length); - _multiLineValue += " " + _tok1.toString(__ISO_8859_1); - } - } - _eol=ch; - _state=STATE_HEADER; - break; - case SPACE: - case TAB: - _state=STATE_HEADER_VALUE; - break; - default: - _length++; - } - break; - } - } // end of HEADER states loop - - // ========================== - - // Handle HEAD response - if (_responseStatus>0 && _headResponse) - { - _state=_persistent||(_responseStatus>=100&&_responseStatus<200)?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentLength); - } - - - // ========================== - - // Handle _content - length=_buffer.length(); - Buffer chunk; - last=_state; - while (_state > STATE_END && length > 0) - { - if (last!=_state) - { - progress++; - last=_state; - } - - if (_eol == CARRIAGE_RETURN && _buffer.peek() == LINE_FEED) - { - _eol=_buffer.get(); - length=_buffer.length(); - continue; - } - _eol=0; - switch (_state) - { - case STATE_EOF_CONTENT: - chunk=_buffer.get(_buffer.length()); - _contentPosition += chunk.length(); - _contentView.update(chunk); - _handler.content(chunk); // May recurse here - // TODO adjust the _buffer to keep unconsumed content - return 1; - - case STATE_CONTENT: - { - long remaining=_contentLength - _contentPosition; - if (remaining == 0) - { - _state=_persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - } - - if (length > remaining) - { - // We can cast reamining to an int as we know that it is smaller than - // or equal to length which is already an int. - length=(int)remaining; - } - - chunk=_buffer.get(length); - _contentPosition += chunk.length(); - _contentView.update(chunk); - _handler.content(chunk); // May recurse here - - if(_contentPosition == _contentLength) - { - _state=_persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - } - // TODO adjust the _buffer to keep unconsumed content - return 1; - } - - case STATE_CHUNKED_CONTENT: - { - ch=_buffer.peek(); - if (ch == CARRIAGE_RETURN || ch == LINE_FEED) - _eol=_buffer.get(); - else if (ch <= SPACE) - _buffer.get(); - else - { - _chunkLength=0; - _chunkPosition=0; - _state=STATE_CHUNK_SIZE; - } - break; - } - - case STATE_CHUNK_SIZE: - { - ch=_buffer.get(); - if (ch == CARRIAGE_RETURN || ch == LINE_FEED) - { - _eol=ch; - - if (_chunkLength == 0) - { - if (_eol==CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==LINE_FEED) - _eol=_buffer.get(); - _state=_persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - } - else - _state=STATE_CHUNK; - } - else if (ch <= SPACE || ch == SEMI_COLON) - _state=STATE_CHUNK_PARAMS; - else if (ch >= '0' && ch <= '9') - _chunkLength=_chunkLength * 16 + (ch - '0'); - else if (ch >= 'a' && ch <= 'f') - _chunkLength=_chunkLength * 16 + (10 + ch - 'a'); - else if (ch >= 'A' && ch <= 'F') - _chunkLength=_chunkLength * 16 + (10 + ch - 'A'); - else - throw new IOException("bad chunk char: " + ch); - break; - } - - case STATE_CHUNK_PARAMS: - { - ch=_buffer.get(); - if (ch == CARRIAGE_RETURN || ch == LINE_FEED) - { - _eol=ch; - if (_chunkLength == 0) - { - if (_eol==CARRIAGE_RETURN && _buffer.hasContent() && _buffer.peek()==LINE_FEED) - _eol=_buffer.get(); - _state=_persistent?STATE_END:STATE_SEEKING_EOF; - _handler.messageComplete(_contentPosition); - return 1; - } - else - _state=STATE_CHUNK; - } - break; - } - - case STATE_CHUNK: - { - int remaining=_chunkLength - _chunkPosition; - if (remaining == 0) - { - _state=STATE_CHUNKED_CONTENT; - break; - } - else if (length > remaining) - length=remaining; - chunk=_buffer.get(length); - _contentPosition += chunk.length(); - _chunkPosition += chunk.length(); - _contentView.update(chunk); - _handler.content(chunk); // May recurse here - // TODO adjust the _buffer to keep unconsumed content - return 1; - } - - case STATE_SEEKING_EOF: - { - // Close if there is more data than CRLF - if (_buffer.length()>2) - { - _state=STATE_END; - _endp.close(); - } - else - { - // or if the data is not white space - while (_buffer.length()>0) - if (!Character.isWhitespace(_buffer.get())) - { - _state=STATE_END; - _endp.close(); - _buffer.clear(); - } - } - - _buffer.clear(); - break; - } - } - - length=_buffer.length(); - } - - return progress; - } - catch(HttpException e) - { - _persistent=false; - _state=STATE_SEEKING_EOF; - throw e; - } - } - - /* ------------------------------------------------------------------------------- */ - /** fill the buffers from the endpoint - * - */ - protected int fill() throws IOException - { - // Do we have a buffer? - if (_buffer==null) - _buffer=getHeaderBuffer(); - - // Is there unconsumed content in body buffer - if (_state>STATE_END && _buffer==_header && _header!=null && !_header.hasContent() && _body!=null && _body.hasContent()) - { - _buffer=_body; - return _buffer.length(); - } - - // Shall we switch to a body buffer? - if (_buffer==_header && _state>STATE_END && _header.length()==0 && (_forceContentBuffer || (_contentLength-_contentPosition)>_header.capacity()) && (_body!=null||_buffers!=null)) - { - if (_body==null) - _body=_buffers.getBuffer(); - _buffer=_body; - } - - // Do we have somewhere to fill from? - if (_endp != null ) - { - // Shall we compact the body? - if (_buffer==_body || _state>STATE_END) - { - _buffer.compact(); - } - - // Are we full? - if (_buffer.space() == 0) - { - LOG.warn("HttpParser Full for {} ",_endp); - _buffer.clear(); - throw new HttpException(REQUEST_ENTITY_TOO_LARGE_413, "Request Entity Too Large: "+(_buffer==_body?"body":"head")); - } - - try - { - int filled = _endp.fill(_buffer); - return filled; - } - catch(IOException e) - { - LOG.debug(e); - throw (e instanceof EofException) ? e:new EofException(e); - } - } - - return -1; - } - - /* ------------------------------------------------------------------------------- */ - @Override - public String toString() - { - return String.format(Locale.getDefault(), "%s{s=%d,l=%d,c=%d}", - getClass().getSimpleName(), - _state, - _length, - _contentLength); - } - - /* ------------------------------------------------------------ */ - public Buffer getHeaderBuffer() - { - if (_header == null) - { - _header=_buffers.getHeader(); - _tok0.update(_header); - _tok1.update(_header); - } - return _header; - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public static abstract class EventHandler - { - public abstract void content(Buffer ref) throws IOException; - - public void headerComplete() throws IOException - { - } - - public void messageComplete(long contentLength) throws IOException - { - } - - /** - * This is the method called by parser when a HTTP Header name and value is found - */ - public void parsedHeader(Buffer name, Buffer value) throws IOException - { - } - - /** - * This is the method called by parser when the HTTP request line is parsed - */ - public abstract void startRequest(Buffer method, Buffer url, Buffer version) - throws IOException; - - /** - * This is the method called by parser when the HTTP request line is parsed - */ - public abstract void startResponse(Buffer version, int status, Buffer reason) - throws IOException; - - public void earlyEOF() - {} - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpVersions.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpVersions.java deleted file mode 100644 index 95d21ceb..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/HttpVersions.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.BufferCache; - -/* ------------------------------------------------------------------------------- */ -/** - * - * - */ -public class HttpVersions -{ - public final static String - HTTP_0_9 = "", - HTTP_1_0 = "HTTP/1.0", - HTTP_1_1 = "HTTP/1.1"; - - public final static int - HTTP_0_9_ORDINAL=9, - HTTP_1_0_ORDINAL=10, - HTTP_1_1_ORDINAL=11; - - public final static BufferCache CACHE = new BufferCache(); - - public final static Buffer - HTTP_0_9_BUFFER=CACHE.add(HTTP_0_9,HTTP_0_9_ORDINAL), - HTTP_1_0_BUFFER=CACHE.add(HTTP_1_0,HTTP_1_0_ORDINAL), - HTTP_1_1_BUFFER=CACHE.add(HTTP_1_1,HTTP_1_1_ORDINAL); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/Parser.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/Parser.java deleted file mode 100644 index 68b433b9..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/http/Parser.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.http; - -import java.io.IOException; - -/** - * Abstract interface for a connection Parser for use by Jetty. - */ -public interface Parser -{ - boolean isComplete(); - - /** - * @return True if progress made - * @throws IOException - */ - boolean parseAvailable() throws IOException; - - boolean isIdle(); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractBuffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractBuffer.java deleted file mode 100644 index 400c088e..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractBuffer.java +++ /dev/null @@ -1,557 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.nio.charset.Charset; - -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * - * - */ -public abstract class AbstractBuffer implements Buffer -{ - private static final Logger LOG = Log.getLogger(AbstractBuffer.class); - - protected final static String - __IMMUTABLE = "IMMUTABLE", - __READONLY = "READONLY", - __READWRITE = "READWRITE", - __VOLATILE = "VOLATILE"; - - protected int _access; - protected boolean _volatile; - - protected int _get; - protected int _put; - protected int _hash; - protected int _hashGet; - protected int _hashPut; - protected int _mark; - protected String _string; - protected View _view; - - /** - * Constructor for BufferView - * - * @param access 0==IMMUTABLE, 1==READONLY, 2==READWRITE - */ - public AbstractBuffer(int access, boolean isVolatile) - { - if (access == IMMUTABLE && isVolatile) - throw new IllegalArgumentException("IMMUTABLE && VOLATILE"); - setMarkIndex(-1); - _access = access; - _volatile = isVolatile; - } - - /* - * @see org.eclipse.io.Buffer#toArray() - */ - public byte[] asArray() - { - byte[] bytes = new byte[length()]; - byte[] array = array(); - if (array != null) - System.arraycopy(array, getIndex(), bytes, 0, bytes.length); - else - peek(getIndex(), bytes, 0, length()); - return bytes; - } - - public ByteArrayBuffer duplicate(int access) - { - Buffer b=this.buffer(); - if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve) - return new ByteArrayBuffer.CaseInsensitive(asArray(), 0, length(),access); - else - return new ByteArrayBuffer(asArray(), 0, length(), access); - } - - public Buffer asMutableBuffer() - { - if (!isImmutable()) return this; - - Buffer b=this.buffer(); - if (b.isReadOnly()) - { - return duplicate(READWRITE); - } - return new View(b, markIndex(), getIndex(), putIndex(), _access); - } - - public Buffer buffer() - { - return this; - } - - public void clear() - { - setMarkIndex(-1); - setGetIndex(0); - setPutIndex(0); - } - - public void compact() - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); - int s = markIndex() >= 0 ? markIndex() : getIndex(); - if (s > 0) - { - byte array[] = array(); - int length = putIndex() - s; - if (length > 0) - { - if (array != null) - System.arraycopy(array(), s, array(), 0, length); - else - poke(0, peek(s, length)); - } - if (markIndex() > 0) setMarkIndex(markIndex() - s); - setGetIndex(getIndex() - s); - setPutIndex(putIndex() - s); - } - } - - @Override - public boolean equals(Object obj) - { - if (obj==this) - return true; - - // reject non buffers; - if (obj == null || !(obj instanceof Buffer)) return false; - Buffer b = (Buffer) obj; - - if (this instanceof Buffer.CaseInsensitve || b instanceof Buffer.CaseInsensitve) - return equalsIgnoreCase(b); - - // reject different lengths - if (b.length() != length()) return false; - - // reject AbstractBuffer with different hash value - if (_hash != 0 && obj instanceof AbstractBuffer) - { - AbstractBuffer ab = (AbstractBuffer) obj; - if (ab._hash != 0 && _hash != ab._hash) return false; - } - - // Nothing for it but to do the hard grind. - int get=getIndex(); - int bi=b.putIndex(); - for (int i = putIndex(); i-->get;) - { - byte b1 = peek(i); - byte b2 = b.peek(--bi); - if (b1 != b2) return false; - } - return true; - } - - public boolean equalsIgnoreCase(Buffer b) - { - if (b==this) - return true; - - // reject different lengths - if (b.length() != length()) return false; - - // reject AbstractBuffer with different hash value - if (_hash != 0 && b instanceof AbstractBuffer) - { - AbstractBuffer ab = (AbstractBuffer) b; - if (ab._hash != 0 && _hash != ab._hash) return false; - } - - // Nothing for it but to do the hard grind. - int get=getIndex(); - int bi=b.putIndex(); - - byte[] array = array(); - byte[] barray= b.array(); - if (array!=null && barray!=null) - { - for (int i = putIndex(); i-->get;) - { - byte b1 = array[i]; - byte b2 = barray[--bi]; - if (b1 != b2) - { - if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); - if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); - if (b1 != b2) return false; - } - } - } - else - { - for (int i = putIndex(); i-->get;) - { - byte b1 = peek(i); - byte b2 = b.peek(--bi); - if (b1 != b2) - { - if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); - if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); - if (b1 != b2) return false; - } - } - } - return true; - } - - public byte get() - { - return peek(_get++); - } - - public int get(byte[] b, int offset, int length) - { - int gi = getIndex(); - int l=length(); - if (l==0) - return -1; - - if (length>l) - length=l; - - length = peek(gi, b, offset, length); - if (length>0) - setGetIndex(gi + length); - return length; - } - - public Buffer get(int length) - { - int gi = getIndex(); - Buffer view = peek(gi, length); - setGetIndex(gi + length); - return view; - } - - public final int getIndex() - { - return _get; - } - - public boolean hasContent() - { - return _put > _get; - } - - @Override - public int hashCode() - { - if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) - { - int get=getIndex(); - byte[] array = array(); - if (array==null) - { - for (int i = putIndex(); i-- >get;) - { - byte b = peek(i); - if ('a' <= b && b <= 'z') - b = (byte) (b - 'a' + 'A'); - _hash = 31 * _hash + b; - } - } - else - { - for (int i = putIndex(); i-- >get;) - { - byte b = array[i]; - if ('a' <= b && b <= 'z') - b = (byte) (b - 'a' + 'A'); - _hash = 31 * _hash + b; - } - } - if (_hash == 0) - _hash = -1; - _hashGet=_get; - _hashPut=_put; - - } - return _hash; - } - - public boolean isImmutable() - { - return _access <= IMMUTABLE; - } - - public boolean isReadOnly() - { - return _access <= READONLY; - } - - public boolean isVolatile() - { - return _volatile; - } - - public int length() - { - return _put - _get; - } - - public void mark() - { - setMarkIndex(_get - 1); - } - - public int markIndex() - { - return _mark; - } - - public byte peek() - { - return peek(_get); - } - - public Buffer peek(int index, int length) - { - if (_view == null) - { - _view = new View(this, -1, index, index + length, isReadOnly() ? READONLY : READWRITE); - } - else - { - _view.update(this.buffer()); - _view.setMarkIndex(-1); - _view.setGetIndex(0); - _view.setPutIndex(index + length); - _view.setGetIndex(index); - - } - return _view; - } - - public int poke(int index, Buffer src) - { - _hash=0; - - int length=src.length(); - if (index + length > capacity()) - { - length=capacity()-index; - } - - byte[] src_array = src.array(); - byte[] dst_array = array(); - if (src_array != null && dst_array != null) - System.arraycopy(src_array, src.getIndex(), dst_array, index, length); - else if (src_array != null) - { - int s=src.getIndex(); - for (int i=0;i<length;i++) - poke(index++,src_array[s++]); - } - else if (dst_array != null) - { - int s=src.getIndex(); - for (int i=0;i<length;i++) - dst_array[index++]=src.peek(s++); - } - else - { - int s=src.getIndex(); - for (int i=0;i<length;i++) - poke(index++,src.peek(s++)); - } - - return length; - } - - - public int poke(int index, byte[] b, int offset, int length) - { - _hash=0; - if (index + length > capacity()) - { - length=capacity()-index; - } - - byte[] dst_array = array(); - if (dst_array != null) - System.arraycopy(b, offset, dst_array, index, length); - else - { - int s=offset; - for (int i=0;i<length;i++) - poke(index++,b[s++]); - } - return length; - } - - public int put(Buffer src) - { - int pi = putIndex(); - int l=poke(pi, src); - setPutIndex(pi + l); - return l; - } - - public void put(byte b) - { - int pi = putIndex(); - poke(pi, b); - setPutIndex(pi + 1); - } - - public int put(byte[] b, int offset, int length) - { - int pi = putIndex(); - int l = poke(pi, b, offset, length); - setPutIndex(pi + l); - return l; - } - - public int put(byte[] b) - { - int pi = putIndex(); - int l = poke(pi, b, 0, b.length); - setPutIndex(pi + l); - return l; - } - - public final int putIndex() - { - return _put; - } - - public void setGetIndex(int getIndex) - { - _get = getIndex; - _hash=0; - } - - public void setMarkIndex(int index) - { - _mark = index; - } - - public void setPutIndex(int putIndex) - { - _put = putIndex; - _hash=0; - } - - public int skip(int n) - { - if (length() < n) n = length(); - setGetIndex(getIndex() + n); - return n; - } - - public Buffer sliceFromMark() - { - return sliceFromMark(getIndex() - markIndex() - 1); - } - - public Buffer sliceFromMark(int length) - { - if (markIndex() < 0) return null; - Buffer view = peek(markIndex(), length); - setMarkIndex(-1); - return view; - } - - public int space() - { - return capacity() - _put; - } - - public String toDetailString() - { - StringBuilder buf = new StringBuilder(); - buf.append("["); - buf.append(super.hashCode()); - buf.append(","); - buf.append(this.buffer().hashCode()); - buf.append(",m="); - buf.append(markIndex()); - buf.append(",g="); - buf.append(getIndex()); - buf.append(",p="); - buf.append(putIndex()); - buf.append(",c="); - buf.append(capacity()); - buf.append("]={"); - if (markIndex() >= 0) - { - for (int i = markIndex(); i < getIndex(); i++) - { - byte b = peek(i); - TypeUtil.toHex(b,buf); - } - buf.append("}{"); - } - int count = 0; - for (int i = getIndex(); i < putIndex(); i++) - { - byte b = peek(i); - TypeUtil.toHex(b,buf); - if (count++ == 50) - { - if (putIndex() - i > 20) - { - buf.append(" ... "); - i = putIndex() - 20; - } - } - } - buf.append('}'); - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - if (isImmutable()) - { - if (_string == null) - _string = new String(asArray(), 0, length()); - return _string; - } - return new String(asArray(), 0, length()); - } - - /* ------------------------------------------------------------ */ - public String toString(Charset charset) - { - try - { - byte[] bytes=array(); - if (bytes!=null) - return new String(bytes,getIndex(),length(),charset); - return new String(asArray(), 0, length(),charset); - } - catch(Exception e) - { - LOG.warn(e); - return new String(asArray(), 0, length()); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractBuffers.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractBuffers.java deleted file mode 100644 index ebbd13d4..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractBuffers.java +++ /dev/null @@ -1,148 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import org.eclipse.jetty.io.nio.DirectNIOBuffer; -import org.eclipse.jetty.io.nio.IndirectNIOBuffer; - -public abstract class AbstractBuffers implements Buffers -{ - protected final Buffers.Type _headerType; - protected final int _headerSize; - protected final Buffers.Type _bufferType; - protected final int _bufferSize; - protected final Buffers.Type _otherType; - - /* ------------------------------------------------------------ */ - public AbstractBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType) - { - _headerType=headerType; - _headerSize=headerSize; - _bufferType=bufferType; - _bufferSize=bufferSize; - _otherType=otherType; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the buffer size in bytes. - */ - public int getBufferSize() - { - return _bufferSize; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the header size in bytes. - */ - public int getHeaderSize() - { - return _headerSize; - } - - - /* ------------------------------------------------------------ */ - /** - * Create a new header Buffer - * @return new Buffer - */ - final protected Buffer newHeader() - { - switch(_headerType) - { - case BYTE_ARRAY: - return new ByteArrayBuffer(_headerSize); - case DIRECT: - return new DirectNIOBuffer(_headerSize); - case INDIRECT: - return new IndirectNIOBuffer(_headerSize); - } - throw new IllegalStateException(); - } - - /* ------------------------------------------------------------ */ - /** - * Create a new content Buffer - * @return new Buffer - */ - final protected Buffer newBuffer() - { - switch(_bufferType) - { - case BYTE_ARRAY: - return new ByteArrayBuffer(_bufferSize); - case DIRECT: - return new DirectNIOBuffer(_bufferSize); - case INDIRECT: - return new IndirectNIOBuffer(_bufferSize); - } - throw new IllegalStateException(); - } - - /* ------------------------------------------------------------ */ - /** - * @param buffer - * @return True if the buffer is the correct type to be a Header buffer - */ - public final boolean isHeader(Buffer buffer) - { - if (buffer.capacity()==_headerSize) - { - switch(_headerType) - { - case BYTE_ARRAY: - return buffer instanceof ByteArrayBuffer && !(buffer instanceof IndirectNIOBuffer); - case DIRECT: - return buffer instanceof DirectNIOBuffer; - case INDIRECT: - return buffer instanceof IndirectNIOBuffer; - } - } - return false; - } - - /* ------------------------------------------------------------ */ - /** - * @param buffer - * @return True if the buffer is the correct type to be a Header buffer - */ - public final boolean isBuffer(Buffer buffer) - { - if (buffer.capacity()==_bufferSize) - { - switch(_bufferType) - { - case BYTE_ARRAY: - return buffer instanceof ByteArrayBuffer && !(buffer instanceof IndirectNIOBuffer); - case DIRECT: - return buffer instanceof DirectNIOBuffer; - case INDIRECT: - return buffer instanceof IndirectNIOBuffer; - } - } - return false; - } - - /* ------------------------------------------------------------ */ - public String toString() - { - return String.format("%s [%d,%d]", getClass().getSimpleName(), _headerSize, _bufferSize); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractConnection.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractConnection.java deleted file mode 100644 index 2acbffb7..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AbstractConnection.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -public abstract class AbstractConnection implements Connection -{ - private static final Logger LOG = Log.getLogger(AbstractConnection.class); - - protected final EndPoint _endp; - - public AbstractConnection(EndPoint endp,long timestamp) - { - _endp=(EndPoint)endp; - } - - public void onIdleExpired(long idleForMs) - { - try - { - LOG.debug("onIdleExpired {}ms {} {}",idleForMs,this,_endp); - if (_endp.isInputShutdown() || _endp.isOutputShutdown()) - _endp.close(); - else - _endp.shutdownOutput(); - } - catch(IOException e) - { - LOG.ignore(e); - - try - { - _endp.close(); - } - catch(IOException e2) - { - LOG.ignore(e2); - } - } - } - - public String toString() - { - return String.format("%s@%x", getClass().getSimpleName(), hashCode()); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AsyncEndPoint.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AsyncEndPoint.java deleted file mode 100644 index 904d9cbe..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/AsyncEndPoint.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -public interface AsyncEndPoint extends ConnectedEndPoint -{ - /* ------------------------------------------------------------ */ - /** - * Dispatch the endpoint if it is not already dispatched - * - */ - public void dispatch(); - - /* ------------------------------------------------------------ */ - /** Schedule a write dispatch. - * Set the endpoint to not be writable and schedule a dispatch when - * it becomes writable. - */ - public void scheduleWrite(); - - /* ------------------------------------------------------------ */ - /** - * @return True if IO has been successfully performed since the last call to {@link #hasProgressed()} - */ - public boolean hasProgressed(); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Buffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Buffer.java deleted file mode 100644 index d5aa765f..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Buffer.java +++ /dev/null @@ -1,313 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.nio.charset.Charset; - - -/** - * Byte Buffer interface. - * - * This is a byte buffer that is designed to work like a FIFO for bytes. Puts and Gets operate on different - * pointers into the buffer and the valid _content of the buffer is always between the getIndex and the putIndex. - * - * This buffer interface is designed to be similar, but not dependent on the java.nio buffers, which may - * be used to back an implementation of this Buffer. The main difference is that NIO buffer after a put have - * their valid _content before the position and a flip is required to access that data. - * - * For this buffer it is always true that: - * markValue <= getIndex <= putIndex <= capacity - * - * - * @version 1.0 - */ -public interface Buffer extends Cloneable -{ - public final static int - IMMUTABLE=0, // neither indexes or contexts can be changed - READONLY=1, // indexes may be changed, but not content - READWRITE=2; // anything can be changed - public final boolean VOLATILE=true; // The buffer may change outside of current scope. - public final boolean NON_VOLATILE=false; - - /** - * Get the underlying array, if one exists. - * @return a <code>byte[]</code> backing this buffer or null if none exists. - */ - byte[] array(); - - /** - * - * @return a <code>byte[]</code> value of the bytes from the getIndex to the putIndex. - */ - byte[] asArray(); - - /** - * Get the underlying buffer. If this buffer wraps a backing buffer. - * @return The root backing buffer or this if there is no backing buffer; - */ - Buffer buffer(); - - /** - * - * @return an immutable version of this <code>Buffer</code>. - */ - Buffer asMutableBuffer(); - - /** - * - * The capacity of the buffer. This is the maximum putIndex that may be set. - * @return an <code>int</code> value - */ - int capacity(); - - /** - * the space remaining in the buffer. - * @return capacity - putIndex - */ - int space(); - - /** - * Clear the buffer. getIndex=0, putIndex=0. - */ - void clear(); - - /** - * Compact the buffer by discarding bytes before the postion (or mark if set). - * Bytes from the getIndex (or mark) to the putIndex are moved to the beginning of - * the buffer and the values adjusted accordingly. - */ - void compact(); - - /** - * Get the byte at the current getIndex and increment it. - * @return The <code>byte</code> value from the current getIndex. - */ - byte get(); - - /** - * Get bytes from the current postion and put them into the passed byte array. - * The getIndex is incremented by the number of bytes copied into the array. - * @param b The byte array to fill. - * @param offset Offset in the array. - * @param length The max number of bytes to read. - * @return The number of bytes actually read. - */ - int get(byte[] b, int offset, int length); - - /** - * - * @param length an <code>int</code> value - * @return a <code>Buffer</code> value - */ - Buffer get(int length); - - /** - * The index within the buffer that will next be read or written. - * @return an <code>int</code> value >=0 <= putIndex() - */ - int getIndex(); - - /** - * @return true of putIndex > getIndex - */ - boolean hasContent(); - - /** - * - * @return a <code>boolean</code> value true if case sensitive comparison on this buffer - */ - boolean equalsIgnoreCase(Buffer buffer); - - /** - * - * @return a <code>boolean</code> value true if the buffer is immutable and that neither - * the buffer contents nor the indexes may be changed. - */ - boolean isImmutable(); - - /** - * - * @return a <code>boolean</code> value true if the buffer is readonly. The buffer indexes may - * be modified, but the buffer contents may not. For example a View onto an immutable Buffer will be - * read only. - */ - boolean isReadOnly(); - - /** - * - * @return a <code>boolean</code> value true if the buffer contents may change - * via alternate paths than this buffer. If the contents of this buffer are to be used outside of the - * current context, then a copy must be made. - */ - boolean isVolatile(); - - /** - * The number of bytes from the getIndex to the putIndex - * @return an <code>int</code> == putIndex()-getIndex() - */ - int length(); - - /** - * Set the mark to the current getIndex. - */ - void mark(); - - /** - * The current index of the mark. - * @return an <code>int</code> index in the buffer or -1 if the mark is not set. - */ - int markIndex(); - - /** - * Get the byte at the current getIndex without incrementing the getIndex. - * @return The <code>byte</code> value from the current getIndex. - */ - byte peek(); - - /** - * Get the byte at a specific index in the buffer. - * @param index an <code>int</code> value - * @return a <code>byte</code> value - */ - byte peek(int index); - - /** - * - * @param index an <code>int</code> value - * @param b The byte array to peek into - * @param offset The offset into the array to start peeking - * @param length an <code>int</code> value - * @return The number of bytes actually peeked - */ - int peek(int index, byte[] b, int offset, int length); - - /** - * Put the contents of the buffer at the specific index. - * @param index an <code>int</code> value - * @param src a <code>Buffer</code>. If the source buffer is not modified - - * @return The number of bytes actually poked - */ - int poke(int index, Buffer src); - - /** - * Put a specific byte to a specific getIndex. - * @param index an <code>int</code> value - * @param b a <code>byte</code> value - */ - void poke(int index, byte b); - - /** - * Put a specific byte to a specific getIndex. - * @param index an <code>int</code> value - * @param b a <code>byte array</code> value - * @return The number of bytes actually poked - */ - int poke(int index, byte b[], int offset, int length); - - /** - * Write the bytes from the source buffer to the current getIndex. - * @param src The source <code>Buffer</code> it is not modified. - * @return The number of bytes actually poked - */ - int put(Buffer src); - - /** - * Put a byte to the current getIndex and increment the getIndex. - * @param b a <code>byte</code> value - */ - void put(byte b); - - /** - * Put a byte to the current getIndex and increment the getIndex. - * @param b a <code>byte</code> value - * @return The number of bytes actually poked - */ - int put(byte[] b,int offset, int length); - - /** - * Put a byte to the current getIndex and increment the getIndex. - * @param b a <code>byte</code> value - * @return The number of bytes actually poked - */ - int put(byte[] b); - - /** - * The index of the first element that should not be read. - * @return an <code>int</code> value >= getIndex() - */ - int putIndex(); - - /** - * Set the buffers start getIndex. - * @param newStart an <code>int</code> value - */ - void setGetIndex(int newStart); - - /** - * Set a specific value for the mark. - * @param newMark an <code>int</code> value - */ - void setMarkIndex(int newMark); - - /** - * - * @param newLimit an <code>int</code> value - */ - void setPutIndex(int newLimit); - - /** - * Skip _content. The getIndex is updated by min(remaining(), n) - * @param n The number of bytes to skip - * @return the number of bytes skipped. - */ - int skip(int n); - - /** - * - * - * @return a volitile <code>Buffer</code> value from the mark to the putIndex - */ - Buffer sliceFromMark(); - - /** - * - * - * @param length an <code>int</code> value - * @return a valitile <code>Buffer</code> value from the mark of the length requested. - */ - Buffer sliceFromMark(int length); - - /** - * - * @return a <code>String</code> value describing the state and contents of the buffer. - */ - String toDetailString(); - - /* ------------------------------------------------------------ */ - String toString(Charset charset); - - /* - * Buffers implementing this interface should be compared with case insensitive equals - * - */ - public interface CaseInsensitve - {} -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/BufferCache.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/BufferCache.java deleted file mode 100644 index 03e81a8d..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/BufferCache.java +++ /dev/null @@ -1,130 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map.Entry; - -import org.eclipse.jetty.util.StringMap; - -/* ------------------------------------------------------------------------------- */ -/** - * Stores a collection of {@link Buffer} objects. - * Buffers are stored in an ordered collection and can retreived by index or value - * - */ -public class BufferCache -{ - private final HashMap<CachedBuffer, CachedBuffer> _bufferMap=new HashMap<CachedBuffer, CachedBuffer>(); - private final StringMap _stringMap=new StringMap(StringMap.CASE_INSENSTIVE); - private final ArrayList<CachedBuffer> _index= new ArrayList<CachedBuffer>(); - - /* ------------------------------------------------------------------------------- */ - /** Add a buffer to the cache at the specified index. - * @param value The content of the buffer. - */ - public CachedBuffer add(String value, int ordinal) - { - CachedBuffer buffer= new CachedBuffer(value, ordinal); - _bufferMap.put(buffer, buffer); - _stringMap.put(value, buffer); - while ((ordinal - _index.size()) >= 0) - _index.add(null); - if (_index.get(ordinal)==null) - _index.add(ordinal, buffer); - return buffer; - } - - public CachedBuffer get(Buffer buffer) - { - return (CachedBuffer)_bufferMap.get(buffer); - } - - public CachedBuffer get(String value) - { - return (CachedBuffer)_stringMap.get(value); - } - - public Buffer lookup(Buffer buffer) - { - if (buffer instanceof CachedBuffer) - return buffer; - - Buffer b= get(buffer); - if (b == null) - { - if (buffer instanceof Buffer.CaseInsensitve) - return buffer; - return new ByteArrayBuffer.CaseInsensitive(buffer.asArray(),0,buffer.length(),Buffer.IMMUTABLE); - } - - return b; - } - - public CachedBuffer getBest(byte[] value, int offset, int maxLength) - { - Entry<?, ?> entry = _stringMap.getBestEntry(value, offset, maxLength); - if (entry!=null) - return (CachedBuffer)entry.getValue(); - return null; - } - - public int getOrdinal(String value) - { - CachedBuffer buffer = (CachedBuffer)_stringMap.get(value); - return buffer==null?-1:buffer.getOrdinal(); - } - - public int getOrdinal(Buffer buffer) - { - if (buffer instanceof CachedBuffer) - return ((CachedBuffer)buffer).getOrdinal(); - buffer=lookup(buffer); - if (buffer!=null && buffer instanceof CachedBuffer) - return ((CachedBuffer)buffer).getOrdinal(); - return -1; - } - - public static class CachedBuffer extends ByteArrayBuffer.CaseInsensitive - { - private final int _ordinal; - - public CachedBuffer(String value, int ordinal) - { - super(value); - _ordinal= ordinal; - } - - public int getOrdinal() - { - return _ordinal; - } - } - - @Override - public String toString() - { - return "CACHE["+ - "bufferMap="+_bufferMap+ - ",stringMap="+_stringMap+ - ",index="+_index+ - "]"; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/BufferUtil.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/BufferUtil.java deleted file mode 100644 index e213c225..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/BufferUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -/* ------------------------------------------------------------------------------- */ -/** Buffer utility methods. - * - * - */ -public class BufferUtil -{ - static final byte SPACE= 0x20; - static final byte MINUS= '-'; - - /** - * Convert buffer to an long. - * Parses up to the first non-numeric character. If no number is found an - * IllegalArgumentException is thrown - * @param buffer A buffer containing an integer. The position is not changed. - * @return an int - */ - public static long toLong(Buffer buffer) - { - long val= 0; - boolean started= false; - boolean minus= false; - for (int i= buffer.getIndex(); i < buffer.putIndex(); i++) - { - byte b= buffer.peek(i); - if (b <= SPACE) - { - if (started) - break; - } - else if (b >= '0' && b <= '9') - { - val= val * 10L + (b - '0'); - started= true; - } - else if (b == MINUS && !started) - { - minus= true; - } - else - break; - } - - if (started) - return minus ? (-val) : val; - throw new NumberFormatException(buffer.toString()); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Buffers.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Buffers.java deleted file mode 100644 index 85170540..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Buffers.java +++ /dev/null @@ -1,37 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - - -/* ------------------------------------------------------------ */ -/** BufferSource. - * Represents a pool or other source of buffers and abstracts the creation - * of specific types of buffers (eg NIO). The concept of big and little buffers - * is supported, but these terms have no absolute meaning and must be determined by context. - * - */ -public interface Buffers -{ - enum Type { BYTE_ARRAY, DIRECT, INDIRECT } ; - - Buffer getHeader(); - Buffer getBuffer(); - - void returnBuffer(Buffer buffer); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ByteArrayBuffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ByteArrayBuffer.java deleted file mode 100644 index da4bf4f5..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ByteArrayBuffer.java +++ /dev/null @@ -1,325 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.nio.charset.Charset; - -/* ------------------------------------------------------------------------------- */ -/** - * - */ -public class ByteArrayBuffer extends AbstractBuffer -{ - static final Charset __ISO_8859_1 = Charset.forName("ISO-8859-1"); - final protected byte[] _bytes; - - protected ByteArrayBuffer(int size, int access, boolean isVolatile) - { - this(new byte[size],0,0,access, isVolatile); - } - - public ByteArrayBuffer(byte[] bytes, int index, int length, int access) - { - super(READWRITE, NON_VOLATILE); - _bytes = bytes; - setPutIndex(index + length); - setGetIndex(index); - _access = access; - } - - public ByteArrayBuffer(byte[] bytes, int index, int length, int access, boolean isVolatile) - { - super(READWRITE, isVolatile); - _bytes = bytes; - setPutIndex(index + length); - setGetIndex(index); - _access = access; - } - - public ByteArrayBuffer(int size) - { - this(new byte[size], 0, 0, READWRITE); - setPutIndex(0); - } - - public ByteArrayBuffer(String value) - { - super(READWRITE,NON_VOLATILE); - _bytes = value.getBytes(__ISO_8859_1); - setGetIndex(0); - setPutIndex(_bytes.length); - _access=IMMUTABLE; - _string = value; - } - - public ByteArrayBuffer(String value,boolean immutable) - { - super(READWRITE,NON_VOLATILE); - _bytes = value.getBytes(__ISO_8859_1); - setGetIndex(0); - setPutIndex(_bytes.length); - if (immutable) - { - _access=IMMUTABLE; - _string = value; - } - } - - public byte[] array() - { - return _bytes; - } - - public int capacity() - { - return _bytes.length; - } - - @Override - public void compact() - { - if (isReadOnly()) - throw new IllegalStateException(__READONLY); - int s = markIndex() >= 0 ? markIndex() : getIndex(); - if (s > 0) - { - int length = putIndex() - s; - if (length > 0) - { - System.arraycopy(_bytes, s,_bytes, 0, length); - } - if (markIndex() > 0) setMarkIndex(markIndex() - s); - setGetIndex(getIndex() - s); - setPutIndex(putIndex() - s); - } - } - - @Override - public boolean equals(Object obj) - { - if (obj==this) - return true; - - if (obj == null || !(obj instanceof Buffer)) - return false; - - if (obj instanceof Buffer.CaseInsensitve) - return equalsIgnoreCase((Buffer)obj); - - - Buffer b = (Buffer) obj; - - // reject different lengths - if (b.length() != length()) - return false; - - // reject AbstractBuffer with different hash value - if (_hash != 0 && obj instanceof AbstractBuffer) - { - AbstractBuffer ab = (AbstractBuffer) obj; - if (ab._hash != 0 && _hash != ab._hash) - return false; - } - - // Nothing for it but to do the hard grind. - int get=getIndex(); - int bi=b.putIndex(); - for (int i = putIndex(); i-->get;) - { - byte b1 = _bytes[i]; - byte b2 = b.peek(--bi); - if (b1 != b2) return false; - } - return true; - } - - @Override - public boolean equalsIgnoreCase(Buffer b) - { - if (b==this) - return true; - - // reject different lengths - if (b==null || b.length() != length()) - return false; - - // reject AbstractBuffer with different hash value - if (_hash != 0 && b instanceof AbstractBuffer) - { - AbstractBuffer ab = (AbstractBuffer) b; - if (ab._hash != 0 && _hash != ab._hash) return false; - } - - // Nothing for it but to do the hard grind. - int get=getIndex(); - int bi=b.putIndex(); - byte[] barray=b.array(); - if (barray==null) - { - for (int i = putIndex(); i-->get;) - { - byte b1 = _bytes[i]; - byte b2 = b.peek(--bi); - if (b1 != b2) - { - if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); - if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); - if (b1 != b2) return false; - } - } - } - else - { - for (int i = putIndex(); i-->get;) - { - byte b1 = _bytes[i]; - byte b2 = barray[--bi]; - if (b1 != b2) - { - if ('a' <= b1 && b1 <= 'z') b1 = (byte) (b1 - 'a' + 'A'); - if ('a' <= b2 && b2 <= 'z') b2 = (byte) (b2 - 'a' + 'A'); - if (b1 != b2) return false; - } - } - } - return true; - } - - @Override - public byte get() - { - return _bytes[_get++]; - } - - @Override - public int hashCode() - { - if (_hash == 0 || _hashGet!=_get || _hashPut!=_put) - { - int get=getIndex(); - for (int i = putIndex(); i-- >get;) - { - byte b = _bytes[i]; - if ('a' <= b && b <= 'z') - b = (byte) (b - 'a' + 'A'); - _hash = 31 * _hash + b; - } - if (_hash == 0) - _hash = -1; - _hashGet=_get; - _hashPut=_put; - } - return _hash; - } - - public byte peek(int index) - { - return _bytes[index]; - } - - public int peek(int index, byte[] b, int offset, int length) - { - int l = length; - if (index + l > capacity()) - { - l = capacity() - index; - if (l==0) - return -1; - } - - if (l < 0) - return -1; - - System.arraycopy(_bytes, index, b, offset, l); - return l; - } - - public void poke(int index, byte b) - { - _bytes[index] = b; - } - - @Override - public int poke(int index, Buffer src) - { - _hash=0; - - int length=src.length(); - if (index + length > capacity()) - { - length=capacity()-index; - } - - byte[] src_array = src.array(); - if (src_array != null) - System.arraycopy(src_array, src.getIndex(), _bytes, index, length); - else - { - int s=src.getIndex(); - for (int i=0;i<length;i++) - _bytes[index++]=src.peek(s++); - } - - return length; - } - - @Override - public int poke(int index, byte[] b, int offset, int length) - { - _hash=0; - - if (index + length > capacity()) - { - length=capacity()-index; - } - - System.arraycopy(b, offset, _bytes, index, length); - - return length; - } - - /* ------------------------------------------------------------ */ - @Override - public int space() - { - return _bytes.length - _put; - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public static class CaseInsensitive extends ByteArrayBuffer implements Buffer.CaseInsensitve - { - public CaseInsensitive(String s) - { - super(s); - } - - public CaseInsensitive(byte[] b, int o, int l, int rw) - { - super(b,o,l,rw); - } - - @Override - public boolean equals(Object obj) - { - return obj instanceof Buffer && equalsIgnoreCase((Buffer)obj); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ConnectedEndPoint.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ConnectedEndPoint.java deleted file mode 100644 index 8959c0b7..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ConnectedEndPoint.java +++ /dev/null @@ -1,25 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -public interface ConnectedEndPoint extends EndPoint -{ - Connection getConnection(); - void setConnection(Connection connection); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Connection.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Connection.java deleted file mode 100644 index 8795f5e3..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/Connection.java +++ /dev/null @@ -1,66 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; - -/* ------------------------------------------------------------ */ -/** Abstract Connection used by Jetty Connectors. - * <p> - * Jetty will call the handle method of a connection when there is work - * to be done on the connection. For blocking connections, this is soon - * as the connection is open and handle will keep being called until the - * connection is closed. For non-blocking connections, handle will only - * be called if there are bytes to be read or the connection becomes writable - * after being write blocked. - * - * @see org.eclipse.jetty.io.nio.SelectorManager - */ -public interface Connection -{ - /* ------------------------------------------------------------ */ - /** - * Handle the connection. - * @return The Connection to use for the next handling of the connection. - * This allows protocol upgrades and support for CONNECT. - * @throws IOException if the handling of I/O operations fail - */ - Connection handle() throws IOException; - - /** - * <p>The semantic of this method is to return true to indicate interest in further reads, - * or false otherwise, but it is misnamed and should be really called <code>isReadInterested()</code>.</p> - * - * @return true to indicate interest in further reads, false otherwise - */ - // TODO: rename to isReadInterested() in the next release - boolean isSuspended(); - - /** - * Called after the connection is closed - */ - void onClose(); - - /** - * Called when the connection idle timeout expires - * @param idleForMs how long the connection has been idle - * @see #isIdle() - */ - void onIdleExpired(long idleForMs); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/EndPoint.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/EndPoint.java deleted file mode 100644 index 5c183fdc..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/EndPoint.java +++ /dev/null @@ -1,131 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.IOException; - -/** - * - * A transport EndPoint - */ -public interface EndPoint -{ - /** - * Shutdown any backing output stream associated with the endpoint - */ - void shutdownOutput() throws IOException; - - boolean isOutputShutdown(); - - /** - * Shutdown any backing input stream associated with the endpoint - */ - void shutdownInput() throws IOException; - - boolean isInputShutdown(); - - /** - * Close any backing stream associated with the endpoint - */ - void close() throws IOException; - - /** - * Fill the buffer from the current putIndex to it's capacity from whatever - * byte source is backing the buffer. The putIndex is increased if bytes filled. - * The buffer may chose to do a compact before filling. - * @return an <code>int</code> value indicating the number of bytes - * filled or -1 if EOF is reached. - * @throws EofException If input is shutdown or the endpoint is closed. - */ - int fill(Buffer buffer) throws IOException; - - /** - * Flush the buffer from the current getIndex to it's putIndex using whatever byte - * sink is backing the buffer. The getIndex is updated with the number of bytes flushed. - * Any mark set is cleared. - * If the entire contents of the buffer are flushed, then an implicit empty() is done. - * - * @param buffer The buffer to flush. This buffers getIndex is updated. - * @return the number of bytes written - * @throws EofException If the endpoint is closed or output is shutdown. - */ - int flush(Buffer buffer) throws IOException; - - /* ------------------------------------------------------------ */ - /** - * @return The local IP address to which this <code>EndPoint</code> is bound, or <code>null</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public String getLocalAddr(); - - /* ------------------------------------------------------------ */ - /** - * @return The local port number on which this <code>EndPoint</code> is listening, or <code>0</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public int getLocalPort(); - - /* ------------------------------------------------------------ */ - /** - * @return The remote IP address to which this <code>EndPoint</code> is connected, or <code>null</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public String getRemoteAddr(); - - /* ------------------------------------------------------------ */ - /** - * @return The remote port number to which this <code>EndPoint</code> is connected, or <code>0</code> - * if this <code>EndPoint</code> does not represent a network connection. - */ - public int getRemotePort(); - - /* ------------------------------------------------------------ */ - public boolean isBlocking(); - - /* ------------------------------------------------------------ */ - public boolean blockWritable(long millisecs) throws IOException; - - /* ------------------------------------------------------------ */ - public boolean isOpen(); - - /* ------------------------------------------------------------ */ - /** Flush any buffered output. - * May fail to write all data if endpoint is non-blocking - * @throws EofException If the endpoint is closed or output is shutdown. - */ - public void flush() throws IOException; - - /* ------------------------------------------------------------ */ - /** Get the max idle time in ms. - * <p>The max idle time is the time the endpoint can be idle before - * extraordinary handling takes place. This loosely corresponds to - * the {@link java.net.Socket#getSoTimeout()} for blocking connections, - * but {@link AsyncEndPoint} implementations must use other mechanisms - * to implement the max idle time. - * @return the max idle time in ms or if ms <= 0 implies an infinite timeout - */ - public int getMaxIdleTime(); - - /* ------------------------------------------------------------ */ - /** Set the max idle time. - * @param timeMs the max idle time in MS. Timeout <= 0 implies an infinite timeout - * @throws IOException if the timeout cannot be set. - */ - public void setMaxIdleTime(int timeMs) throws IOException; -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/EofException.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/EofException.java deleted file mode 100644 index 0e6722a1..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/EofException.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.io.EOFException; - - -/* ------------------------------------------------------------ */ -/** A Jetty specialization of EOFException. - * <p> This is thrown by Jetty to distinguish between EOF received from - * the connection, vs and EOF thrown by some application talking to some other file/socket etc. - * The only difference in handling is that Jetty EOFs are logged less verbosely. - */ -@SuppressWarnings("serial") -public class EofException extends EOFException -{ - public EofException() - { - } - - public EofException(String reason) - { - super(reason); - } - - public EofException(Throwable th) - { - if (th!=null) - initCause(th); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/SimpleBuffers.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/SimpleBuffers.java deleted file mode 100644 index 7d95d473..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/SimpleBuffers.java +++ /dev/null @@ -1,102 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -/* ------------------------------------------------------------ */ -/** SimpleBuffers. - * Simple implementation of Buffers holder. - * - * - */ -public class SimpleBuffers implements Buffers -{ - final Buffer _header; - final Buffer _buffer; - boolean _headerOut; - boolean _bufferOut; - - /* ------------------------------------------------------------ */ - /** - * - */ - public SimpleBuffers(Buffer header, Buffer buffer) - { - _header=header; - _buffer=buffer; - } - - /* ------------------------------------------------------------ */ - public Buffer getBuffer() - { - synchronized(this) - { - if (_buffer!=null && !_bufferOut) - { - _bufferOut=true; - return _buffer; - } - - if (_buffer!=null && _header!=null && _header.capacity()==_buffer.capacity() && !_headerOut) - { - _headerOut=true; - return _header; - } - - if (_buffer!=null) - return new ByteArrayBuffer(_buffer.capacity()); - return new ByteArrayBuffer(4096); - } - } - - /* ------------------------------------------------------------ */ - public Buffer getHeader() - { - synchronized(this) - { - if (_header!=null && !_headerOut) - { - _headerOut=true; - return _header; - } - - if (_buffer!=null && _header!=null && _header.capacity()==_buffer.capacity() && !_bufferOut) - { - _bufferOut=true; - return _buffer; - } - - if (_header!=null) - return new ByteArrayBuffer(_header.capacity()); - return new ByteArrayBuffer(4096); - } - } - - /* ------------------------------------------------------------ */ - public void returnBuffer(Buffer buffer) - { - synchronized(this) - { - buffer.clear(); - if (buffer==_header) - _headerOut=false; - if (buffer==_buffer) - _bufferOut=false; - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ThreadLocalBuffers.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ThreadLocalBuffers.java deleted file mode 100644 index c5e518b1..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/ThreadLocalBuffers.java +++ /dev/null @@ -1,120 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - - - -/* ------------------------------------------------------------ */ -/** Abstract Buffer pool. - * simple unbounded pool of buffers for header, request and response sizes. - * - */ -public class ThreadLocalBuffers extends AbstractBuffers -{ - /* ------------------------------------------------------------ */ - private final ThreadLocal<ThreadBuffers> _buffers=new ThreadLocal<ThreadBuffers>() - { - @Override - protected ThreadBuffers initialValue() - { - return new ThreadBuffers(); - } - }; - - /* ------------------------------------------------------------ */ - public ThreadLocalBuffers(Buffers.Type headerType, int headerSize, Buffers.Type bufferType, int bufferSize, Buffers.Type otherType) - { - super(headerType,headerSize,bufferType,bufferSize,otherType); - } - - /* ------------------------------------------------------------ */ - public Buffer getBuffer() - { - ThreadBuffers buffers = _buffers.get(); - if (buffers._buffer!=null) - { - Buffer b=buffers._buffer; - buffers._buffer=null; - return b; - } - - if (buffers._other!=null && isBuffer(buffers._other)) - { - Buffer b=buffers._other; - buffers._other=null; - return b; - } - - return newBuffer(); - } - - /* ------------------------------------------------------------ */ - public Buffer getHeader() - { - ThreadBuffers buffers = _buffers.get(); - if (buffers._header!=null) - { - Buffer b=buffers._header; - buffers._header=null; - return b; - } - - if (buffers._other!=null && isHeader(buffers._other)) - { - Buffer b=buffers._other; - buffers._other=null; - return b; - } - - return newHeader(); - } - - /* ------------------------------------------------------------ */ - public void returnBuffer(Buffer buffer) - { - buffer.clear(); - if (buffer.isVolatile() || buffer.isImmutable()) - return; - - ThreadBuffers buffers = _buffers.get(); - - if (buffers._header==null && isHeader(buffer)) - buffers._header=buffer; - else if (buffers._buffer==null && isBuffer(buffer)) - buffers._buffer=buffer; - else - buffers._other=buffer; - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return "{{"+getHeaderSize()+","+getBufferSize()+"}}"; - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - protected static class ThreadBuffers - { - Buffer _buffer; - Buffer _header; - Buffer _other; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/View.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/View.java deleted file mode 100644 index 0ad7200f..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/View.java +++ /dev/null @@ -1,232 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io; - -/** - * A View on another buffer. Allows operations that do not change the _content or - * indexes of the backing buffer. - * - * - * - */ -public class View extends AbstractBuffer -{ - Buffer _buffer; - - /** - * @param buffer The <code>Buffer</code> on which we are presenting a <code>View</code>. - * @param mark The initial value of the {@link Buffer#markIndex mark index} - * @param get The initial value of the {@link Buffer#getIndex get index} - * @param put The initial value of the {@link Buffer#putIndex put index} - * @param access The access level - one of the constants from {@link Buffer}. - */ - public View(Buffer buffer, int mark, int get, int put,int access) - { - super(READWRITE,!buffer.isImmutable()); - _buffer=buffer.buffer(); - setPutIndex(put); - setGetIndex(get); - setMarkIndex(mark); - _access=access; - } - - public View(Buffer buffer) - { - super(READWRITE,!buffer.isImmutable()); - _buffer=buffer.buffer(); - setPutIndex(buffer.putIndex()); - setGetIndex(buffer.getIndex()); - setMarkIndex(buffer.markIndex()); - _access=buffer.isReadOnly()?READONLY:READWRITE; - } - - public View() - { - super(READWRITE,true); - } - - /** - * Update view to buffer - */ - public void update(Buffer buffer) - { - _access=READWRITE; - _buffer=buffer.buffer(); - setGetIndex(0); - setPutIndex(buffer.putIndex()); - setGetIndex(buffer.getIndex()); - setMarkIndex(buffer.markIndex()); - _access=buffer.isReadOnly()?READONLY:READWRITE; - } - - public void update(int get, int put) - { - int a=_access; - _access=READWRITE; - setGetIndex(0); - setPutIndex(put); - setGetIndex(get); - setMarkIndex(-1); - _access=a; - } - - /** - * @return The {@link Buffer#array()} from the underlying buffer. - */ - public byte[] array() - { - return _buffer.array(); - } - - /** - * @return The {@link Buffer#buffer()} from the underlying buffer. - */ - @Override - public Buffer buffer() - { - return _buffer.buffer(); - } - - /** - * @return The {@link Buffer#capacity} of the underlying buffer. - */ - public int capacity() - { - return _buffer.capacity(); - } - - /** - * - */ - @Override - public void clear() - { - setMarkIndex(-1); - setGetIndex(0); - setPutIndex(_buffer.getIndex()); - setGetIndex(_buffer.getIndex()); - } - - /** - * - */ - @Override - public void compact() - { - // TODO - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) - { - return this==obj ||((obj instanceof Buffer)&& obj.equals(this)) || super.equals(obj); - } - - /** - * @return Whether the underlying buffer is {@link Buffer#isReadOnly read only} - */ - @Override - public boolean isReadOnly() - { - return _buffer.isReadOnly(); - } - - /** - * @return Whether the underlying buffer is {@link Buffer#isVolatile volatile} - */ - @Override - public boolean isVolatile() - { - return true; - } - - /** - * @return The result of calling {@link Buffer#peek(int)} on the underlying buffer - */ - public byte peek(int index) - { - return _buffer.peek(index); - } - - /** - * @return The result of calling {@link Buffer#peek(int, byte[], int, int)} on the underlying buffer - */ - public int peek(int index, byte[] b, int offset, int length) - { - return _buffer.peek(index,b,offset,length); - } - - /** - * @param index - * @param src - */ - @Override - public int poke(int index, Buffer src) - { - return _buffer.poke(index,src); - } - - /** - * @param index - * @param b - */ - public void poke(int index, byte b) - { - _buffer.poke(index,b); - } - - /** - * @param index - * @param b - * @param offset - * @param length - */ - @Override - public int poke(int index, byte[] b, int offset, int length) - { - return _buffer.poke(index,b,offset,length); - } - - @Override - public String toString() - { - if (_buffer==null) - return "INVALID"; - return super.toString(); - } - - public static class CaseInsensitive extends View implements Buffer.CaseInsensitve - { - public CaseInsensitive() - { - super(); - } - - @Override - public boolean equals(Object obj) - { - return this==obj ||((obj instanceof Buffer)&&((Buffer)obj).equalsIgnoreCase(this)) || super.equals(obj); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/AsyncConnection.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/AsyncConnection.java deleted file mode 100644 index 3282fe51..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/AsyncConnection.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; - -import org.eclipse.jetty.io.Connection; - -public interface AsyncConnection extends Connection -{ - void onInputShutdown() throws IOException; -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/ChannelEndPoint.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/ChannelEndPoint.java deleted file mode 100644 index baf456d5..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/ChannelEndPoint.java +++ /dev/null @@ -1,478 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketException; -import java.nio.ByteBuffer; -import java.nio.channels.ByteChannel; -import java.nio.channels.GatheringByteChannel; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SocketChannel; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * Channel End Point. - * <p>Holds the channel and socket for an NIO endpoint. - * - */ -public class ChannelEndPoint implements EndPoint -{ - private static final Logger LOG = Log.getLogger(ChannelEndPoint.class); - - private static final String ALL_INTERFACES = "0.0.0.0"; - - protected final ByteChannel _channel; - protected final ByteBuffer[] _gather2=new ByteBuffer[2]; - protected final Socket _socket; - protected final InetSocketAddress _local; - protected final InetSocketAddress _remote; - protected volatile int _maxIdleTime; - private volatile boolean _ishut; - private volatile boolean _oshut; - - protected ChannelEndPoint(ByteChannel channel, int maxIdleTime) throws IOException - { - this._channel = channel; - _maxIdleTime=maxIdleTime; - _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null; - if (_socket!=null) - { - _local=(InetSocketAddress)_socket.getLocalSocketAddress(); - _remote=(InetSocketAddress)_socket.getRemoteSocketAddress(); - _socket.setSoTimeout(_maxIdleTime); - } - else - { - _local=_remote=null; - } - } - - public boolean isBlocking() - { - return !(_channel instanceof SelectableChannel) || ((SelectableChannel)_channel).isBlocking(); - } - - public boolean blockReadable(long millisecs) throws IOException - { - return true; - } - - public boolean blockWritable(long millisecs) throws IOException - { - return true; - } - - /* - * @see org.eclipse.io.EndPoint#isOpen() - */ - public boolean isOpen() - { - return _channel.isOpen(); - } - - /** Shutdown the channel Input. - * Cannot be overridden. To override, see {@link #shutdownInput()} - * @throws IOException - */ - protected final void shutdownChannelInput() throws IOException - { - LOG.debug("ishut {}", this); - _ishut = true; - if (_channel.isOpen()) - { - if (_socket != null) - { - try - { - if (!_socket.isInputShutdown()) - { - _socket.shutdownInput(); - } - } - catch (SocketException e) - { - LOG.debug(e.toString()); - LOG.ignore(e); - } - finally - { - if (_oshut) - { - close(); - } - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.io.EndPoint#close() - */ - public void shutdownInput() throws IOException - { - shutdownChannelInput(); - } - - protected final void shutdownChannelOutput() throws IOException - { - LOG.debug("oshut {}",this); - _oshut = true; - if (_channel.isOpen()) - { - if (_socket != null) - { - try - { - if (!_socket.isOutputShutdown()) - { - _socket.shutdownOutput(); - } - } - catch (SocketException e) - { - LOG.debug(e.toString()); - LOG.ignore(e); - } - finally - { - if (_ishut) - { - close(); - } - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.io.EndPoint#close() - */ - public void shutdownOutput() throws IOException - { - shutdownChannelOutput(); - } - - public boolean isOutputShutdown() - { - return _oshut || !_channel.isOpen() || _socket != null && _socket.isOutputShutdown(); - } - - public boolean isInputShutdown() - { - return _ishut || !_channel.isOpen() || _socket != null && _socket.isInputShutdown(); - } - - /* (non-Javadoc) - * @see org.eclipse.io.EndPoint#close() - */ - public void close() throws IOException - { - LOG.debug("close {}",this); - _channel.close(); - } - - /* (non-Javadoc) - * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer) - */ - public int fill(Buffer buffer) throws IOException - { - if (_ishut) - return -1; - Buffer buf = buffer.buffer(); - int len=0; - if (buf instanceof NIOBuffer) - { - final NIOBuffer nbuf = (NIOBuffer)buf; - final ByteBuffer bbuf=nbuf.getByteBuffer(); - - //noinspection SynchronizationOnLocalVariableOrMethodParameter - try - { - synchronized(bbuf) - { - try - { - bbuf.position(buffer.putIndex()); - len=_channel.read(bbuf); - } - finally - { - buffer.setPutIndex(bbuf.position()); - bbuf.position(0); - } - } - - if (len<0 && isOpen()) - { - if (!isInputShutdown()) - shutdownInput(); - if (isOutputShutdown()) - _channel.close(); - } - } - catch (IOException x) - { - LOG.debug("Exception while filling", x); - try - { - if (_channel.isOpen()) - _channel.close(); - } - catch (Exception xx) - { - LOG.ignore(xx); - } - - if (len>0) - throw x; - len=-1; - } - } - else - { - throw new IOException("Not Implemented"); - } - - return len; - } - - /* (non-Javadoc) - * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer) - */ - public int flush(Buffer buffer) throws IOException - { - Buffer buf = buffer.buffer(); - int len=0; - if (buf instanceof NIOBuffer) - { - final NIOBuffer nbuf = (NIOBuffer)buf; - final ByteBuffer bbuf=nbuf.getByteBuffer().asReadOnlyBuffer(); - try - { - bbuf.position(buffer.getIndex()); - bbuf.limit(buffer.putIndex()); - len=_channel.write(bbuf); - } - finally - { - if (len>0) - buffer.skip(len); - } - } - else if (buffer.array()!=null) - { - ByteBuffer b = ByteBuffer.wrap(buffer.array(), buffer.getIndex(), buffer.length()); - len=_channel.write(b); - if (len>0) - buffer.skip(len); - } - else - { - throw new IOException("Not Implemented"); - } - return len; - } - - /* (non-Javadoc) - * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer) - */ - public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException - { - int length=0; - - Buffer buf0 = header==null?null:header.buffer(); - Buffer buf1 = buffer==null?null:buffer.buffer(); - - if (_channel instanceof GatheringByteChannel && - header!=null && header.length()!=0 && buf0 instanceof NIOBuffer && - buffer!=null && buffer.length()!=0 && buf1 instanceof NIOBuffer) - { - length = gatheringFlush(header,((NIOBuffer)buf0).getByteBuffer(),buffer,((NIOBuffer)buf1).getByteBuffer()); - } - else - { - // flush header - if (header!=null && header.length()>0) - length=flush(header); - - // flush buffer - if ((header==null || header.length()==0) && - buffer!=null && buffer.length()>0) - length+=flush(buffer); - - // flush trailer - if ((header==null || header.length()==0) && - (buffer==null || buffer.length()==0) && - trailer!=null && trailer.length()>0) - length+=flush(trailer); - } - - return length; - } - - protected int gatheringFlush(Buffer header, ByteBuffer bbuf0, Buffer buffer, ByteBuffer bbuf1) throws IOException - { - int length; - - synchronized(this) - { - // Adjust position indexs of buf0 and buf1 - bbuf0=bbuf0.asReadOnlyBuffer(); - bbuf0.position(header.getIndex()); - bbuf0.limit(header.putIndex()); - bbuf1=bbuf1.asReadOnlyBuffer(); - bbuf1.position(buffer.getIndex()); - bbuf1.limit(buffer.putIndex()); - - _gather2[0]=bbuf0; - _gather2[1]=bbuf1; - - // do the gathering write. - length=(int)((GatheringByteChannel)_channel).write(_gather2); - - int hl=header.length(); - if (length>hl) - { - header.clear(); - buffer.skip(length-hl); - } - else if (length>0) - { - header.skip(length); - } - } - return length; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the channel. - */ - public ByteChannel getChannel() - { - return _channel; - } - - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.EndPoint#getLocalAddr() - */ - public String getLocalAddr() - { - if (_socket==null) - return null; - if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress()) - return ALL_INTERFACES; - return _local.getAddress().getHostAddress(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.EndPoint#getLocalHost() - */ - public String getLocalHost() - { - if (_socket==null) - return null; - if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress()) - return ALL_INTERFACES; - return _local.getAddress().getCanonicalHostName(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.EndPoint#getLocalPort() - */ - public int getLocalPort() - { - if (_socket==null) - return 0; - if (_local==null) - return -1; - return _local.getPort(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.EndPoint#getRemoteAddr() - */ - public String getRemoteAddr() - { - if (_socket==null) - return null; - if (_remote==null) - return null; - return _remote.getAddress().getHostAddress(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.EndPoint#getRemoteHost() - */ - public String getRemoteHost() - { - if (_socket==null) - return null; - if (_remote==null) - return null; - return _remote.getAddress().getCanonicalHostName(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.EndPoint#getRemotePort() - */ - public int getRemotePort() - { - if (_socket==null) - return 0; - return _remote==null?-1:_remote.getPort(); - } - - /* ------------------------------------------------------------ */ - public void flush() - throws IOException - { - } - - /* ------------------------------------------------------------ */ - public int getMaxIdleTime() - { - return _maxIdleTime; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int) - */ - public void setMaxIdleTime(int timeMs) throws IOException - { - if (_socket!=null && timeMs!=_maxIdleTime) - _socket.setSoTimeout(timeMs>0?timeMs:0); - _maxIdleTime=timeMs; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/DirectNIOBuffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/DirectNIOBuffer.java deleted file mode 100644 index 4bd61b2e..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/DirectNIOBuffer.java +++ /dev/null @@ -1,226 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; - -import org.eclipse.jetty.io.AbstractBuffer; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ------------------------------------------------------------------------------- */ -/** - * - * - */ -public class DirectNIOBuffer extends AbstractBuffer implements NIOBuffer -{ - private static final Logger LOG = Log.getLogger(DirectNIOBuffer.class); - - protected final ByteBuffer _buf; - - public DirectNIOBuffer(int size) - { - super(READWRITE,NON_VOLATILE); - _buf = ByteBuffer.allocateDirect(size); - _buf.position(0); - _buf.limit(_buf.capacity()); - } - - public DirectNIOBuffer(ByteBuffer buffer,boolean immutable) - { - super(immutable?IMMUTABLE:READWRITE,NON_VOLATILE); - if (!buffer.isDirect()) - throw new IllegalArgumentException(); - _buf = buffer; - setGetIndex(buffer.position()); - setPutIndex(buffer.limit()); - } - - /** - * @param file - */ - public DirectNIOBuffer(File file) throws IOException - { - super(READONLY,NON_VOLATILE); - FileInputStream fis = null; - FileChannel fc = null; - try - { - fis = new FileInputStream(file); - fc = fis.getChannel(); - _buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); - setGetIndex(0); - setPutIndex((int)file.length()); - _access=IMMUTABLE; - } - finally - { - if (fc != null) try {fc.close();} catch (IOException e){LOG.ignore(e);} - IO.close(fis); - } - } - - /* ------------------------------------------------------------ */ - public boolean isDirect() - { - return true; - } - - /* ------------------------------------------------------------ */ - public byte[] array() - { - return null; - } - - /* ------------------------------------------------------------ */ - public int capacity() - { - return _buf.capacity(); - } - - /* ------------------------------------------------------------ */ - public byte peek(int position) - { - return _buf.get(position); - } - - public int peek(int index, byte[] b, int offset, int length) - { - int l = length; - if (index+l > capacity()) - { - l=capacity()-index; - if (l==0) - return -1; - } - - if (l < 0) - return -1; - try - { - _buf.position(index); - _buf.get(b,offset,l); - } - finally - { - _buf.position(0); - } - - return l; - } - - public void poke(int index, byte b) - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); - if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0"); - if (index > capacity()) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - _buf.put(index,b); - } - - @Override - public int poke(int index, Buffer src) - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); - - byte[] array=src.array(); - if (array!=null) - { - return poke(index,array,src.getIndex(),src.length()); - } - else - { - Buffer src_buf=src.buffer(); - if (src_buf instanceof DirectNIOBuffer) - { - ByteBuffer src_bytebuf = ((DirectNIOBuffer)src_buf)._buf; - if (src_bytebuf==_buf) - src_bytebuf=_buf.duplicate(); - try - { - _buf.position(index); - int space = _buf.remaining(); - - int length=src.length(); - if (length>space) - length=space; - - src_bytebuf.position(src.getIndex()); - src_bytebuf.limit(src.getIndex()+length); - - _buf.put(src_bytebuf); - return length; - } - finally - { - _buf.position(0); - src_bytebuf.limit(src_bytebuf.capacity()); - src_bytebuf.position(0); - } - } - else - return super.poke(index,src); - } - } - - @Override - public int poke(int index, byte[] b, int offset, int length) - { - if (isReadOnly()) throw new IllegalStateException(__READONLY); - - if (index < 0) throw new IllegalArgumentException("index<0: " + index + "<0"); - - if (index + length > capacity()) - { - length=capacity()-index; - if (length<0) - throw new IllegalArgumentException("index>capacity(): " + index + ">" + capacity()); - } - - try - { - _buf.position(index); - - int space=_buf.remaining(); - - if (length>space) - length=space; - if (length>0) - _buf.put(b,offset,length); - return length; - } - finally - { - _buf.position(0); - } - } - - /* ------------------------------------------------------------ */ - public ByteBuffer getByteBuffer() - { - return _buf; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java deleted file mode 100644 index e9500f06..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/IndirectNIOBuffer.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.io.ByteArrayBuffer; - -public class IndirectNIOBuffer extends ByteArrayBuffer implements NIOBuffer -{ - protected final ByteBuffer _buf; - - /* ------------------------------------------------------------ */ - public IndirectNIOBuffer(int size) - { - super(size,READWRITE,NON_VOLATILE); - _buf = ByteBuffer.wrap(_bytes); - _buf.position(0); - _buf.limit(_buf.capacity()); - } - - /* ------------------------------------------------------------ */ - public ByteBuffer getByteBuffer() - { - return _buf; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/NIOBuffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/NIOBuffer.java deleted file mode 100644 index ba4f4b60..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/NIOBuffer.java +++ /dev/null @@ -1,34 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.nio.ByteBuffer; - -import org.eclipse.jetty.io.Buffer; - -/* ------------------------------------------------------------------------------- */ -/** - * - * - */ -public interface NIOBuffer extends Buffer -{ - /* ------------------------------------------------------------ */ - public ByteBuffer getByteBuffer(); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java deleted file mode 100644 index 88d7ff7c..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SelectChannelEndPoint.java +++ /dev/null @@ -1,802 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.SocketChannel; -import java.util.Locale; - -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.ConnectedEndPoint; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EofException; -import org.eclipse.jetty.io.nio.SelectorManager.SelectSet; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Timeout.Task; - -/* ------------------------------------------------------------ */ -/** - * An Endpoint that can be scheduled by {@link SelectorManager}. - */ -public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPoint, ConnectedEndPoint -{ - public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio"); - - private final boolean WORK_AROUND_JVM_BUG_6346658 = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win"); - private final SelectorManager.SelectSet _selectSet; - private final SelectorManager _manager; - private SelectionKey _key; - private final Runnable _handler = new Runnable() - { - public void run() { handle(); } - }; - - /** The desired value for {@link SelectionKey#interestOps()} */ - private int _interestOps; - - /** - * The connection instance is the handler for any IO activity on the endpoint. - * There is a different type of connection for HTTP, AJP, WebSocket and - * ProxyConnect. The connection may change for an SCEP as it is upgraded - * from HTTP to proxy connect or websocket. - */ - private volatile AsyncConnection _connection; - - private static final int STATE_NEEDS_DISPATCH=-1; - private static final int STATE_UNDISPATCHED=0; - private static final int STATE_DISPATCHED=1; - private static final int STATE_ASYNC=2; - private int _state; - - private boolean _onIdle; - - /** true if the last write operation succeed and wrote all offered bytes */ - private volatile boolean _writable = true; - - - /** True if a thread has is blocked in {@link #blockReadable(long)} */ - private boolean _readBlocked; - - /** True if a thread has is blocked in {@link #blockWritable(long)} */ - private boolean _writeBlocked; - - /** true if {@link SelectSet#destroyEndPoint(SelectChannelEndPoint)} has not been called */ - private boolean _open; - - private volatile long _idleTimestamp; - private volatile boolean _checkIdle; - - private boolean _interruptable; - - private boolean _ishut; - - /* ------------------------------------------------------------ */ - public SelectChannelEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key, int maxIdleTime) - throws IOException - { - super(channel, maxIdleTime); - - _manager = selectSet.getManager(); - _selectSet = selectSet; - _state=STATE_UNDISPATCHED; - _onIdle=false; - _open=true; - _key = key; - - setCheckForIdle(true); - } - - /* ------------------------------------------------------------ */ - public Connection getConnection() - { - return _connection; - } - - /* ------------------------------------------------------------ */ - public void setConnection(Connection connection) - { - Connection old=_connection; - _connection=(AsyncConnection)connection; - if (old!=null && old!=_connection) - _manager.endPointUpgraded(this,old); - } - - /* ------------------------------------------------------------ */ - /** Called by selectSet to schedule handling - * - */ - public void schedule() - { - synchronized (this) - { - // If there is no key, then do nothing - if (_key == null || !_key.isValid()) - { - _readBlocked=false; - _writeBlocked=false; - this.notifyAll(); - return; - } - - // If there are threads dispatched reading and writing - if (_readBlocked || _writeBlocked) - { - // assert _dispatched; - if (_readBlocked && _key.isReadable()) - _readBlocked=false; - if (_writeBlocked && _key.isWritable()) - _writeBlocked=false; - - // wake them up is as good as a dispatched. - this.notifyAll(); - - // we are not interested in further selecting - _key.interestOps(0); - if (_state<STATE_DISPATCHED) - updateKey(); - return; - } - - // Remove writeable op - if ((_key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && (_key.interestOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) - { - // Remove writeable op - _interestOps = _key.interestOps() & ~SelectionKey.OP_WRITE; - _key.interestOps(_interestOps); - _writable = true; // Once writable is in ops, only removed with dispatch. - } - - // If dispatched, then deregister interest - if (_state>=STATE_DISPATCHED) - _key.interestOps(0); - else - { - // other wise do the dispatch - dispatch(); - if (_state>=STATE_DISPATCHED && !_selectSet.getManager().isDeferringInterestedOps0()) - { - _key.interestOps(0); - } - } - } - } - - /* ------------------------------------------------------------ */ - public void asyncDispatch() - { - synchronized(this) - { - switch(_state) - { - case STATE_NEEDS_DISPATCH: - case STATE_UNDISPATCHED: - dispatch(); - break; - - case STATE_DISPATCHED: - case STATE_ASYNC: - _state=STATE_ASYNC; - break; - } - } - } - - /* ------------------------------------------------------------ */ - public void dispatch() - { - synchronized(this) - { - if (_state<=STATE_UNDISPATCHED) - { - if (_onIdle) - _state = STATE_NEEDS_DISPATCH; - else - { - _state = STATE_DISPATCHED; - boolean dispatched = _manager.dispatch(_handler); - if(!dispatched) - { - _state = STATE_NEEDS_DISPATCH; - LOG.warn("Dispatched Failed! "+this+" to "+_manager); - updateKey(); - } - } - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Called when a dispatched thread is no longer handling the endpoint. - * The selection key operations are updated. - * @return If false is returned, the endpoint has been redispatched and - * thread must keep handling the endpoint. - */ - protected boolean undispatch() - { - synchronized (this) - { - switch(_state) - { - case STATE_ASYNC: - _state=STATE_DISPATCHED; - return false; - - default: - _state=STATE_UNDISPATCHED; - updateKey(); - return true; - } - } - } - - /* ------------------------------------------------------------ */ - public void cancelTimeout(Task task) - { - getSelectSet().cancelTimeout(task); - } - - /* ------------------------------------------------------------ */ - public void scheduleTimeout(Task task, long timeoutMs) - { - getSelectSet().scheduleTimeout(task,timeoutMs); - } - - /* ------------------------------------------------------------ */ - public void setCheckForIdle(boolean check) - { - if (check) - { - _idleTimestamp=System.currentTimeMillis(); - _checkIdle=true; - } - else - _checkIdle=false; - } - - /* ------------------------------------------------------------ */ - public boolean isCheckForIdle() - { - return _checkIdle; - } - - /* ------------------------------------------------------------ */ - protected void notIdle() - { - _idleTimestamp=System.currentTimeMillis(); - } - - /* ------------------------------------------------------------ */ - public void checkIdleTimestamp(long now) - { - if (isCheckForIdle() && _maxIdleTime>0) - { - final long idleForMs=now-_idleTimestamp; - - if (idleForMs>_maxIdleTime) - { - // Don't idle out again until onIdleExpired task completes. - setCheckForIdle(false); - _manager.dispatch(new Runnable() - { - public void run() - { - try - { - onIdleExpired(idleForMs); - } - finally - { - setCheckForIdle(true); - } - } - }); - } - } - } - - /* ------------------------------------------------------------ */ - public void onIdleExpired(long idleForMs) - { - try - { - synchronized (this) - { - _onIdle=true; - } - - _connection.onIdleExpired(idleForMs); - } - finally - { - synchronized (this) - { - _onIdle=false; - if (_state==STATE_NEEDS_DISPATCH) - dispatch(); - } - } - } - - /* ------------------------------------------------------------ */ - @Override - public int fill(Buffer buffer) throws IOException - { - int fill=super.fill(buffer); - if (fill>0) - notIdle(); - return fill; - } - - /* ------------------------------------------------------------ */ - /* - */ - @Override - public int flush(Buffer buffer) throws IOException - { - int l = super.flush(buffer); - - // If there was something to write and it wasn't written, then we are not writable. - if (l==0 && buffer!=null && buffer.hasContent()) - { - synchronized (this) - { - _writable=false; - if (_state<STATE_DISPATCHED) - updateKey(); - } - } - else if (l>0) - { - _writable=true; - notIdle(); - } - - return l; - } - - /* ------------------------------------------------------------ */ - /* - * Allows thread to block waiting for further events. - */ - @SuppressWarnings("serial") - @Override - public boolean blockReadable(long timeoutMs) throws IOException - { - synchronized (this) - { - if (isInputShutdown()) - throw new EofException(); - - long now=_selectSet.getNow(); - long end=now+timeoutMs; - boolean check=isCheckForIdle(); - setCheckForIdle(true); - try - { - _readBlocked=true; - while (!isInputShutdown() && _readBlocked) - { - try - { - updateKey(); - this.wait(timeoutMs>0?(end-now):10000); - } - catch (final InterruptedException e) - { - LOG.warn(e); - if (_interruptable) - throw new InterruptedIOException(){{this.initCause(e);}}; - } - finally - { - now=_selectSet.getNow(); - } - - if (_readBlocked && timeoutMs>0 && now>=end) - return false; - } - } - finally - { - _readBlocked=false; - setCheckForIdle(check); - } - } - return true; - } - - /* ------------------------------------------------------------ */ - /* - * Allows thread to block waiting for further events. - */ - @SuppressWarnings("serial") - @Override - public boolean blockWritable(long timeoutMs) throws IOException - { - synchronized (this) - { - if (isOutputShutdown()) - throw new EofException(); - - long now=_selectSet.getNow(); - long end=now+timeoutMs; - boolean check=isCheckForIdle(); - setCheckForIdle(true); - try - { - _writeBlocked=true; - while (_writeBlocked && !isOutputShutdown()) - { - try - { - updateKey(); - this.wait(timeoutMs>0?(end-now):10000); - } - catch (final InterruptedException e) - { - LOG.warn(e); - if (_interruptable) - throw new InterruptedIOException(){{this.initCause(e);}}; - } - finally - { - now=_selectSet.getNow(); - } - if (_writeBlocked && timeoutMs>0 && now>=end) - return false; - } - } - finally - { - _writeBlocked=false; - setCheckForIdle(check); - } - } - return true; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.io.AsyncEndPoint#scheduleWrite() - */ - public void scheduleWrite() - { - if (_writable) - LOG.debug("Required scheduleWrite {}",this); - - _writable=false; - updateKey(); - } - - /* ------------------------------------------------------------ */ - public boolean isWritable() - { - return _writable; - } - - /* ------------------------------------------------------------ */ - public boolean hasProgressed() - { - return false; - } - - /* ------------------------------------------------------------ */ - /** - * Updates selection key. Adds operations types to the selection key as needed. No operations - * are removed as this is only done during dispatch. This method records the new key and - * schedules a call to doUpdateKey to do the keyChange - */ - private void updateKey() - { - final boolean changed; - synchronized (this) - { - int current_ops=-1; - if (getChannel().isOpen()) - { - boolean read_interest = _readBlocked || (_state<STATE_DISPATCHED && !_connection.isSuspended()); - boolean write_interest= _writeBlocked || (_state<STATE_DISPATCHED && !_writable); - - _interestOps = - ((!_socket.isInputShutdown() && read_interest ) ? SelectionKey.OP_READ : 0) - | ((!_socket.isOutputShutdown()&& write_interest) ? SelectionKey.OP_WRITE : 0); - try - { - current_ops = ((_key!=null && _key.isValid())?_key.interestOps():-1); - } - catch(Exception e) - { - _key=null; - LOG.ignore(e); - } - } - changed=_interestOps!=current_ops; - } - - if(changed) - { - _selectSet.addChange(this); - _selectSet.wakeup(); - } - } - - /* ------------------------------------------------------------ */ - /** - * Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey - */ - void doUpdateKey() - { - synchronized (this) - { - if (getChannel().isOpen()) - { - if (_interestOps>0) - { - if (_key==null || !_key.isValid()) - { - SelectableChannel sc = (SelectableChannel)getChannel(); - if (sc.isRegistered()) - { - updateKey(); - } - else - { - try - { - _key=((SelectableChannel)getChannel()).register(_selectSet.getSelector(),_interestOps,this); - } - catch (Exception e) - { - LOG.ignore(e); - if (_key!=null && _key.isValid()) - { - _key.cancel(); - } - - if (_open) - { - _selectSet.destroyEndPoint(this); - } - _open=false; - _key = null; - } - } - } - else - { - _key.interestOps(_interestOps); - } - } - else - { - if (_key!=null && _key.isValid()) - _key.interestOps(0); - else - _key=null; - } - } - else - { - if (_key!=null && _key.isValid()) - _key.cancel(); - - if (_open) - { - _open=false; - _selectSet.destroyEndPoint(this); - } - _key = null; - } - } - } - - /* ------------------------------------------------------------ */ - /* - */ - protected void handle() - { - boolean dispatched=true; - try - { - while(dispatched) - { - try - { - while(true) - { - final AsyncConnection next = (AsyncConnection)_connection.handle(); - if (next!=_connection) - { - LOG.debug("{} replaced {}",next,_connection); - Connection old=_connection; - _connection=next; - _manager.endPointUpgraded(this,old); - continue; - } - break; - } - } - catch (ClosedChannelException e) - { - LOG.ignore(e); - } - catch (EofException e) - { - LOG.debug("EOF", e); - try{close();} - catch(IOException e2){LOG.ignore(e2);} - } - catch (IOException e) - { - LOG.warn(e.toString()); - try{close();} - catch(IOException e2){LOG.ignore(e2);} - } - catch (Throwable e) - { - LOG.warn("handle failed", e); - try{close();} - catch(IOException e2){LOG.ignore(e2);} - } - finally - { - if (!_ishut && isInputShutdown() && isOpen()) - { - _ishut=true; - try - { - _connection.onInputShutdown(); - } - catch(Throwable x) - { - LOG.warn("onInputShutdown failed", x); - try{close();} - catch(IOException e2){LOG.ignore(e2);} - } - finally - { - updateKey(); - } - } - dispatched=!undispatch(); - } - } - } - finally - { - if (dispatched) - { - dispatched=!undispatch(); - while (dispatched) - { - LOG.warn("SCEP.run() finally DISPATCHED"); - dispatched=!undispatch(); - } - } - } - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.io.nio.ChannelEndPoint#close() - */ - @Override - public void close() throws IOException - { - // On unix systems there is a JVM issue that if you cancel before closing, it can - // cause the selector to block waiting for a channel to close and that channel can - // block waiting for the remote end. But on windows, if you don't cancel before a - // close, then the selector can block anyway! - // https://bugs.eclipse.org/bugs/show_bug.cgi?id=357318 - if (WORK_AROUND_JVM_BUG_6346658) - { - try - { - SelectionKey key = _key; - if (key!=null) - key.cancel(); - } - catch (Throwable e) - { - LOG.ignore(e); - } - } - - try - { - super.close(); - } - catch (IOException e) - { - LOG.ignore(e); - } - finally - { - updateKey(); - } - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - // Do NOT use synchronized (this) - // because it's very easy to deadlock when debugging is enabled. - // We do a best effort to print the right toString() and that's it. - SelectionKey key = _key; - String keyString = ""; - if (key != null) - { - if (key.isValid()) - { - if (key.isReadable()) - keyString += "r"; - if (key.isWritable()) - keyString += "w"; - } - else - { - keyString += "!"; - } - } - else - { - keyString += "-"; - } - return String.format(Locale.getDefault(), - "SCEP@%x{l(%s)<->r(%s),s=%d,open=%b,ishut=%b,oshut=%b,rb=%b,wb=%b,w=%b,i=%d%s}-{%s}", - hashCode(), - _socket.getRemoteSocketAddress(), - _socket.getLocalSocketAddress(), - _state, - isOpen(), - isInputShutdown(), - isOutputShutdown(), - _readBlocked, - _writeBlocked, - _writable, - _interestOps, - keyString, - _connection); - } - - /* ------------------------------------------------------------ */ - public SelectSet getSelectSet() - { - return _selectSet; - } - - /* ------------------------------------------------------------ */ - /** - * Don't set the SoTimeout - * @see org.eclipse.jetty.io.nio.ChannelEndPoint#setMaxIdleTime(int) - */ - @Override - public void setMaxIdleTime(int timeMs) throws IOException - { - _maxIdleTime=timeMs; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SelectorManager.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SelectorManager.java deleted file mode 100644 index dd4e6816..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SelectorManager.java +++ /dev/null @@ -1,891 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import java.io.IOException; -import java.nio.channels.CancelledKeyException; -import java.nio.channels.Channel; -import java.nio.channels.ClosedSelectorException; -import java.nio.channels.SelectableChannel; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.ServerSocketChannel; -import java.nio.channels.SocketChannel; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.ConnectedEndPoint; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.thread.Timeout; -import org.eclipse.jetty.util.thread.Timeout.Task; - - -/* ------------------------------------------------------------ */ -/** - * The Selector Manager manages and number of SelectSets to allow - * NIO scheduling to scale to large numbers of connections. - * <p> - */ -public abstract class SelectorManager extends AbstractLifeCycle implements Dumpable -{ - public static final Logger LOG=Log.getLogger("org.eclipse.jetty.io.nio"); - - private static final int __MONITOR_PERIOD=Integer.getInteger("org.eclipse.jetty.io.nio.MONITOR_PERIOD",1000).intValue(); - private static final int __MAX_SELECTS=Integer.getInteger("org.eclipse.jetty.io.nio.MAX_SELECTS",100000).intValue(); - private static final int __BUSY_PAUSE=Integer.getInteger("org.eclipse.jetty.io.nio.BUSY_PAUSE",50).intValue(); - private static final int __IDLE_TICK=Integer.getInteger("org.eclipse.jetty.io.nio.IDLE_TICK",400).intValue(); - - private int _maxIdleTime; - private int _lowResourcesMaxIdleTime; - private long _lowResourcesConnections; - private SelectSet[] _selectSet; - private int _selectSets=1; - private volatile int _set=0; - private boolean _deferringInterestedOps0=true; - private int _selectorPriorityDelta=0; - - /* ------------------------------------------------------------ */ - /** - * @return the max idle time - */ - public long getMaxIdleTime() - { - return _maxIdleTime; - } - - /* ------------------------------------------------------------ */ - /** - * @return the number of select sets in use - */ - public int getSelectSets() - { - return _selectSets; - } - - /* ------------------------------------------------------------ */ - /** Register a channel - * @param channel - * @param att Attached Object - */ - public void register(SocketChannel channel, Object att) - { - // The ++ increment here is not atomic, but it does not matter. - // so long as the value changes sometimes, then connections will - // be distributed over the available sets. - - int s=_set++; - if (s<0) - s=-s; - s=s%_selectSets; - SelectSet[] sets=_selectSet; - if (sets!=null) - { - SelectSet set=sets[s]; - set.addChange(channel,att); - set.wakeup(); - } - } - - /* ------------------------------------------------------------ */ - /** - * @return delta The value to add to the selector thread priority. - */ - public int getSelectorPriorityDelta() - { - return _selectorPriorityDelta; - } - - /* ------------------------------------------------------------------------------- */ - public abstract boolean dispatch(Runnable task); - - /* ------------------------------------------------------------ */ - /* (non-Javadoc) - * @see org.eclipse.component.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - _selectSet = new SelectSet[_selectSets]; - for (int i=0;i<_selectSet.length;i++) - _selectSet[i]= new SelectSet(i); - - super.doStart(); - - // start a thread to Select - for (int i=0;i<getSelectSets();i++) - { - final int id=i; - boolean selecting=dispatch(new Runnable() - { - public void run() - { - String name=Thread.currentThread().getName(); - int priority=Thread.currentThread().getPriority(); - try - { - SelectSet[] sets=_selectSet; - if (sets==null) - return; - SelectSet set=sets[id]; - - Thread.currentThread().setName(name+" Selector"+id); - if (getSelectorPriorityDelta()!=0) - Thread.currentThread().setPriority(Thread.currentThread().getPriority()+getSelectorPriorityDelta()); - LOG.debug("Starting {} on {}",Thread.currentThread(),this); - while (isRunning()) - { - try - { - set.doSelect(); - } - catch(IOException e) - { - LOG.ignore(e); - } - catch(Exception e) - { - LOG.warn(e); - } - } - } - finally - { - LOG.debug("Stopped {} on {}",Thread.currentThread(),this); - Thread.currentThread().setName(name); - if (getSelectorPriorityDelta()!=0) - Thread.currentThread().setPriority(priority); - } - } - - }); - - if (!selecting) - throw new IllegalStateException("!Selecting"); - } - } - - /* ------------------------------------------------------------------------------- */ - @Override - protected void doStop() throws Exception - { - SelectSet[] sets= _selectSet; - _selectSet=null; - if (sets!=null) - { - for (SelectSet set : sets) - { - if (set!=null) - set.stop(); - } - } - super.doStop(); - } - - /* ------------------------------------------------------------ */ - /** - * @param endpoint - */ - protected abstract void endPointClosed(SelectChannelEndPoint endpoint); - - /* ------------------------------------------------------------ */ - /** - * @param endpoint - */ - protected abstract void endPointOpened(SelectChannelEndPoint endpoint); - - /* ------------------------------------------------------------ */ - protected abstract void endPointUpgraded(ConnectedEndPoint endpoint,Connection oldConnection); - - /* ------------------------------------------------------------------------------- */ - public abstract AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment); - - /* ------------------------------------------------------------ */ - /** - * Create a new end point - * @param channel - * @param selectSet - * @param sKey the selection key - * @return the new endpoint {@link SelectChannelEndPoint} - * @throws IOException - */ - protected abstract SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey sKey) throws IOException; - - /* ------------------------------------------------------------------------------- */ - protected void connectionFailed(SocketChannel channel,Throwable ex,Object attachment) - { - LOG.warn(ex+","+channel+","+attachment); - LOG.debug(ex); - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - AggregateLifeCycle.dumpObject(out,this); - AggregateLifeCycle.dump(out,indent,Arrays.asList(_selectSet)); - } - - /* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ - /* ------------------------------------------------------------------------------- */ - public class SelectSet implements Dumpable - { - private final int _setID; - private final Timeout _timeout; - - private final ConcurrentLinkedQueue<Object> _changes = new ConcurrentLinkedQueue<Object>(); - - private volatile Selector _selector; - - private volatile Thread _selecting; - private int _busySelects; - private long _monitorNext; - private boolean _pausing; - private boolean _paused; - private volatile long _idleTick; - private ConcurrentMap<SelectChannelEndPoint,Object> _endPoints = new ConcurrentHashMap<SelectChannelEndPoint, Object>(); - - /* ------------------------------------------------------------ */ - SelectSet(int acceptorID) throws Exception - { - _setID=acceptorID; - - _idleTick = System.currentTimeMillis(); - _timeout = new Timeout(this); - _timeout.setDuration(0L); - - // create a selector; - _selector = Selector.open(); - _monitorNext=System.currentTimeMillis()+__MONITOR_PERIOD; - } - - /* ------------------------------------------------------------ */ - public void addChange(Object change) - { - _changes.add(change); - } - - /* ------------------------------------------------------------ */ - public void addChange(SelectableChannel channel, Object att) - { - if (att==null) - addChange(channel); - else if (att instanceof EndPoint) - addChange(att); - else - addChange(new ChannelAndAttachment(channel,att)); - } - - /* ------------------------------------------------------------ */ - /** - * Select and dispatch tasks found from changes and the selector. - * - * @throws IOException - */ - public void doSelect() throws IOException - { - try - { - _selecting=Thread.currentThread(); - final Selector selector=_selector; - // Stopped concurrently ? - if (selector == null) - return; - - // Make any key changes required - Object change; - int changes=_changes.size(); - while (changes-->0 && (change=_changes.poll())!=null) - { - Channel ch=null; - SelectionKey key=null; - - try - { - if (change instanceof EndPoint) - { - // Update the operations for a key. - SelectChannelEndPoint endpoint = (SelectChannelEndPoint)change; - ch=endpoint.getChannel(); - endpoint.doUpdateKey(); - } - else if (change instanceof ChannelAndAttachment) - { - // finish accepting/connecting this connection - final ChannelAndAttachment asc = (ChannelAndAttachment)change; - final SelectableChannel channel=asc._channel; - ch=channel; - final Object att = asc._attachment; - - if ((channel instanceof SocketChannel) && ((SocketChannel)channel).isConnected()) - { - key = channel.register(selector,SelectionKey.OP_READ,att); - SelectChannelEndPoint endpoint = createEndPoint((SocketChannel)channel,key); - key.attach(endpoint); - endpoint.schedule(); - } - else if (channel.isOpen()) - { - key = channel.register(selector,SelectionKey.OP_CONNECT,att); - } - } - else if (change instanceof SocketChannel) - { - // Newly registered channel - final SocketChannel channel=(SocketChannel)change; - ch=channel; - key = channel.register(selector,SelectionKey.OP_READ,null); - SelectChannelEndPoint endpoint = createEndPoint(channel,key); - key.attach(endpoint); - endpoint.schedule(); - } - else if (change instanceof ChangeTask) - { - ((Runnable)change).run(); - } - else if (change instanceof Runnable) - { - dispatch((Runnable)change); - } - else - throw new IllegalArgumentException(change.toString()); - } - catch (CancelledKeyException e) - { - LOG.ignore(e); - } - catch (Throwable e) - { - if (isRunning()) - LOG.warn(e); - else - LOG.debug(e); - - try - { - if (ch!=null) - ch.close(); - } - catch(IOException e2) - { - LOG.debug(e2); - } - } - } - - - // Do and instant select to see if any connections can be handled. - int selected=selector.selectNow(); - - long now=System.currentTimeMillis(); - - // if no immediate things to do - if (selected==0 && selector.selectedKeys().isEmpty()) - { - // If we are in pausing mode - if (_pausing) - { - try - { - Thread.sleep(__BUSY_PAUSE); // pause to reduce impact of busy loop - } - catch(InterruptedException e) - { - LOG.ignore(e); - } - now=System.currentTimeMillis(); - } - - // workout how long to wait in select - _timeout.setNow(now); - long to_next_timeout=_timeout.getTimeToNext(); - - long wait = _changes.size()==0?__IDLE_TICK:0L; - if (wait > 0 && to_next_timeout >= 0 && wait > to_next_timeout) - wait = to_next_timeout; - - // If we should wait with a select - if (wait>0) - { - long before=now; - selector.select(wait); - now = System.currentTimeMillis(); - _timeout.setNow(now); - - // If we are monitoring for busy selector - // and this select did not wait more than 1ms - if (__MONITOR_PERIOD>0 && now-before <=1) - { - // count this as a busy select and if there have been too many this monitor cycle - if (++_busySelects>__MAX_SELECTS) - { - // Start injecting pauses - _pausing=true; - - // if this is the first pause - if (!_paused) - { - // Log and dump some status - _paused=true; - LOG.warn("Selector {} is too busy, pausing!",this); - } - } - } - } - } - - // have we been destroyed while sleeping - if (_selector==null || !selector.isOpen()) - return; - - // Look for things to do - for (SelectionKey key: selector.selectedKeys()) - { - SocketChannel channel=null; - - try - { - if (!key.isValid()) - { - key.cancel(); - SelectChannelEndPoint endpoint = (SelectChannelEndPoint)key.attachment(); - if (endpoint != null) - endpoint.doUpdateKey(); - continue; - } - - Object att = key.attachment(); - if (att instanceof SelectChannelEndPoint) - { - if (key.isReadable()||key.isWritable()) - ((SelectChannelEndPoint)att).schedule(); - } - else if (key.isConnectable()) - { - // Complete a connection of a registered channel - channel = (SocketChannel)key.channel(); - boolean connected=false; - try - { - connected=channel.finishConnect(); - } - catch(Exception e) - { - connectionFailed(channel,e,att); - } - finally - { - if (connected) - { - key.interestOps(SelectionKey.OP_READ); - SelectChannelEndPoint endpoint = createEndPoint(channel,key); - key.attach(endpoint); - endpoint.schedule(); - } - else - { - key.cancel(); - channel.close(); - } - } - } - else - { - // Wrap readable registered channel in an endpoint - channel = (SocketChannel)key.channel(); - SelectChannelEndPoint endpoint = createEndPoint(channel,key); - key.attach(endpoint); - if (key.isReadable()) - endpoint.schedule(); - } - key = null; - } - catch (CancelledKeyException e) - { - LOG.ignore(e); - } - catch (Exception e) - { - if (isRunning()) - LOG.warn(e); - else - LOG.ignore(e); - - try - { - if (channel!=null) - channel.close(); - } - catch(IOException e2) - { - LOG.debug(e2); - } - - if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid()) - key.cancel(); - } - } - - // Everything always handled - selector.selectedKeys().clear(); - - now=System.currentTimeMillis(); - _timeout.setNow(now); - Task task = _timeout.expired(); - while (task!=null) - { - if (task instanceof Runnable) - dispatch((Runnable)task); - task = _timeout.expired(); - } - - // Idle tick - if (now-_idleTick>__IDLE_TICK) - { - _idleTick=now; - - final long idle_now=((_lowResourcesConnections>0 && selector.keys().size()>_lowResourcesConnections)) - ?(now+_maxIdleTime-_lowResourcesMaxIdleTime) - :now; - - dispatch(new Runnable() - { - public void run() - { - for (SelectChannelEndPoint endp:_endPoints.keySet()) - { - endp.checkIdleTimestamp(idle_now); - } - } - public String toString() {return "Idle-"+super.toString();} - }); - - } - - // Reset busy select monitor counts - if (__MONITOR_PERIOD>0 && now>_monitorNext) - { - _busySelects=0; - _pausing=false; - _monitorNext=now+__MONITOR_PERIOD; - - } - } - catch (ClosedSelectorException e) - { - if (isRunning()) - LOG.warn(e); - else - LOG.ignore(e); - } - catch (CancelledKeyException e) - { - LOG.ignore(e); - } - finally - { - _selecting=null; - } - } - - /* ------------------------------------------------------------ */ - private void renewSelector() - { - try - { - synchronized (this) - { - Selector selector=_selector; - if (selector==null) - return; - final Selector new_selector = Selector.open(); - for (SelectionKey k: selector.keys()) - { - if (!k.isValid() || k.interestOps()==0) - continue; - - final SelectableChannel channel = k.channel(); - final Object attachment = k.attachment(); - - if (attachment==null) - addChange(channel); - else - addChange(channel,attachment); - } - _selector.close(); - _selector=new_selector; - } - } - catch(IOException e) - { - throw new RuntimeException("recreating selector",e); - } - } - - /* ------------------------------------------------------------ */ - public SelectorManager getManager() - { - return SelectorManager.this; - } - - /* ------------------------------------------------------------ */ - public long getNow() - { - return _timeout.getNow(); - } - - /* ------------------------------------------------------------ */ - /** - * @param task The task to timeout. If it implements Runnable, then - * expired will be called from a dispatched thread. - * - * @param timeoutMs - */ - public void scheduleTimeout(Timeout.Task task, long timeoutMs) - { - if (!(task instanceof Runnable)) - throw new IllegalArgumentException("!Runnable"); - _timeout.schedule(task, timeoutMs); - } - - /* ------------------------------------------------------------ */ - public void cancelTimeout(Timeout.Task task) - { - task.cancel(); - } - - /* ------------------------------------------------------------ */ - public void wakeup() - { - try - { - Selector selector = _selector; - if (selector!=null) - selector.wakeup(); - } - catch(Exception e) - { - addChange(new ChangeTask() - { - public void run() - { - renewSelector(); - } - }); - - renewSelector(); - } - } - - /* ------------------------------------------------------------ */ - private SelectChannelEndPoint createEndPoint(SocketChannel channel, SelectionKey sKey) throws IOException - { - SelectChannelEndPoint endp = newEndPoint(channel,this,sKey); - LOG.debug("created {}",endp); - endPointOpened(endp); - _endPoints.put(endp,this); - return endp; - } - - /* ------------------------------------------------------------ */ - public void destroyEndPoint(SelectChannelEndPoint endp) - { - LOG.debug("destroyEndPoint {}",endp); - _endPoints.remove(endp); - endPointClosed(endp); - } - - /* ------------------------------------------------------------ */ - Selector getSelector() - { - return _selector; - } - - /* ------------------------------------------------------------ */ - void stop() throws Exception - { - // Spin for a while waiting for selector to complete - // to avoid unneccessary closed channel exceptions - try - { - for (int i=0;i<100 && _selecting!=null;i++) - { - wakeup(); - Thread.sleep(10); - } - } - catch(Exception e) - { - LOG.ignore(e); - } - - // close endpoints and selector - synchronized (this) - { - Selector selector=_selector; - for (SelectionKey key:selector.keys()) - { - if (key==null) - continue; - Object att=key.attachment(); - if (att instanceof EndPoint) - { - EndPoint endpoint = (EndPoint)att; - try - { - endpoint.close(); - } - catch(IOException e) - { - LOG.ignore(e); - } - } - } - - - _timeout.cancelAll(); - try - { - selector=_selector; - if (selector != null) - selector.close(); - } - catch (IOException e) - { - LOG.ignore(e); - } - _selector=null; - } - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(this)).append(" id=").append(String.valueOf(_setID)).append("\n"); - - Thread selecting = _selecting; - - Object where = "not selecting"; - StackTraceElement[] trace =selecting==null?null:selecting.getStackTrace(); - if (trace!=null) - { - for (StackTraceElement t:trace) - if (t.getClassName().startsWith("org.eclipse.jetty.")) - { - where=t; - break; - } - } - - Selector selector=_selector; - if (selector!=null) - { - final ArrayList<Object> dump = new ArrayList<Object>(selector.keys().size()*2); - dump.add(where); - - final CountDownLatch latch = new CountDownLatch(1); - - addChange(new ChangeTask() - { - public void run() - { - dumpKeyState(dump); - latch.countDown(); - } - }); - - try - { - latch.await(5,TimeUnit.SECONDS); - } - catch(InterruptedException e) - { - LOG.ignore(e); - } - - AggregateLifeCycle.dump(out,indent,dump); - } - } - - /* ------------------------------------------------------------ */ - public void dumpKeyState(List<Object> dumpto) - { - Selector selector=_selector; - Set<SelectionKey> keys = selector.keys(); - dumpto.add(selector + " keys=" + keys.size()); - for (SelectionKey key: keys) - { - if (key.isValid()) - dumpto.add(key.attachment()+" iOps="+key.interestOps()+" rOps="+key.readyOps()); - else - dumpto.add(key.attachment()+" iOps=-1 rOps=-1"); - } - } - - /* ------------------------------------------------------------ */ - public String toString() - { - Selector selector=_selector; - return String.format(Locale.getDefault(), "%s keys=%d selected=%d", - super.toString(), - selector != null && selector.isOpen() ? selector.keys().size() : -1, - selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1); - } - } - - /* ------------------------------------------------------------ */ - private static class ChannelAndAttachment - { - final SelectableChannel _channel; - final Object _attachment; - - public ChannelAndAttachment(SelectableChannel channel, Object attachment) - { - super(); - _channel = channel; - _attachment = attachment; - } - } - - /* ------------------------------------------------------------ */ - public boolean isDeferringInterestedOps0() - { - return _deferringInterestedOps0; - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - private interface ChangeTask extends Runnable - {} -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SslConnection.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SslConnection.java deleted file mode 100755 index 711716ed..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/io/nio/SslConnection.java +++ /dev/null @@ -1,775 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.io.nio; - -import android.annotation.SuppressLint; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Locale; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLEngineResult; -import javax.net.ssl.SSLEngineResult.HandshakeStatus; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSession; - -import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ------------------------------------------------------------ */ -/** SSL Connection. - * An AysyncConnection that acts as an interceptor between and EndPoint and another - * Connection, that implements TLS encryption using an {@link SSLEngine}. - * <p> - * The connector uses an {@link AsyncEndPoint} (like {@link SelectChannelEndPoint}) as - * it's source/sink of encrypted data. It then provides {@link #getSslEndPoint()} to - * expose a source/sink of unencrypted data to another connection (eg HttpConnection). - */ -public class SslConnection extends AbstractConnection implements AsyncConnection -{ - private final Logger _logger = Log.getLogger("org.eclipse.jetty.io.nio.ssl"); - - private static final NIOBuffer __ZERO_BUFFER=new IndirectNIOBuffer(0); - - private static final ThreadLocal<SslBuffers> __buffers = new ThreadLocal<SslBuffers>(); - private final SSLEngine _engine; - private final SSLSession _session; - private AsyncConnection _connection; - private final SslEndPoint _sslEndPoint; - private int _allocations; - private SslBuffers _buffers; - private NIOBuffer _inbound; - private NIOBuffer _unwrapBuf; - private NIOBuffer _outbound; - private AsyncEndPoint _aEndp; - private boolean _allowRenegotiate=true; - private boolean _handshook; - private boolean _ishut; - private boolean _oshut; - private final AtomicBoolean _progressed = new AtomicBoolean(); - - /* ------------------------------------------------------------ */ - /* this is a half baked buffer pool - */ - private static class SslBuffers - { - final NIOBuffer _in; - final NIOBuffer _out; - final NIOBuffer _unwrap; - - SslBuffers(int packetSize, int appSize) - { - _in=new IndirectNIOBuffer(packetSize); - _out=new IndirectNIOBuffer(packetSize); - _unwrap=new IndirectNIOBuffer(appSize); - } - } - - /* ------------------------------------------------------------ */ - public SslConnection(SSLEngine engine,EndPoint endp) - { - this(engine,endp,System.currentTimeMillis()); - } - - /* ------------------------------------------------------------ */ - public SslConnection(SSLEngine engine,EndPoint endp, long timeStamp) - { - super(endp,timeStamp); - _engine=engine; - _session=_engine.getSession(); - _aEndp=(AsyncEndPoint)endp; - _sslEndPoint = newSslEndPoint(); - } - - /* ------------------------------------------------------------ */ - protected SslEndPoint newSslEndPoint() - { - return new SslEndPoint(); - } - - /* ------------------------------------------------------------ */ - private void allocateBuffers() - { - synchronized (this) - { - if (_allocations++==0) - { - if (_buffers==null) - { - _buffers=__buffers.get(); - if (_buffers==null) - _buffers=new SslBuffers(_session.getPacketBufferSize()*2,_session.getApplicationBufferSize()*2); - _inbound=_buffers._in; - _outbound=_buffers._out; - _unwrapBuf=_buffers._unwrap; - __buffers.set(null); - } - } - } - } - - /* ------------------------------------------------------------ */ - private void releaseBuffers() - { - synchronized (this) - { - if (--_allocations==0) - { - if (_buffers!=null && - _inbound.length()==0 && - _outbound.length()==0 && - _unwrapBuf.length()==0) - { - _inbound=null; - _outbound=null; - _unwrapBuf=null; - __buffers.set(_buffers); - _buffers=null; - } - } - } - } - - /* ------------------------------------------------------------ */ - public Connection handle() throws IOException - { - try - { - allocateBuffers(); - - boolean progress=true; - - while (progress) - { - progress=false; - - // If we are handshook let the delegate connection - if (_engine.getHandshakeStatus()!=HandshakeStatus.NOT_HANDSHAKING) - progress=process(null,null); - - // handle the delegate connection - AsyncConnection next = (AsyncConnection)_connection.handle(); - if (next!=_connection && next!=null) - { - _connection=next; - progress=true; - } - - _logger.debug("{} handle {} progress={}", _session, this, progress); - } - } - finally - { - releaseBuffers(); - - if (!_ishut && _sslEndPoint.isInputShutdown() && _sslEndPoint.isOpen()) - { - _ishut=true; - try - { - _connection.onInputShutdown(); - } - catch(Throwable x) - { - _logger.warn("onInputShutdown failed", x); - try{_sslEndPoint.close();} - catch(IOException e2){ - _logger.ignore(e2);} - } - } - } - - return this; - } - - /* ------------------------------------------------------------ */ - public boolean isSuspended() - { - return false; - } - - /* ------------------------------------------------------------ */ - public void onClose() - { - Connection connection = _sslEndPoint.getConnection(); - if (connection != null && connection != this) - connection.onClose(); - } - - /* ------------------------------------------------------------ */ - @Override - public void onIdleExpired(long idleForMs) - { - try - { - _logger.debug("onIdleExpired {}ms on {}",idleForMs,this); - if (_endp.isOutputShutdown()) - _sslEndPoint.close(); - else - _sslEndPoint.shutdownOutput(); - } - catch (IOException e) - { - _logger.warn(e); - super.onIdleExpired(idleForMs); - } - } - - /* ------------------------------------------------------------ */ - public void onInputShutdown() throws IOException - { - - } - - /* ------------------------------------------------------------ */ - private synchronized boolean process(Buffer toFill, Buffer toFlush) throws IOException - { - boolean some_progress=false; - try - { - // We need buffers to progress - allocateBuffers(); - - // if we don't have a buffer to put received data into - if (toFill==null) - { - // use the unwrapbuffer to hold received data. - _unwrapBuf.compact(); - toFill=_unwrapBuf; - } - // Else if the fill buffer is too small for the SSL session - else if (toFill.capacity()<_session.getApplicationBufferSize()) - { - // fill to the temporary unwrapBuffer - boolean progress=process(null,toFlush); - - // if we received any data, - if (_unwrapBuf!=null && _unwrapBuf.hasContent()) - { - // transfer from temp buffer to fill buffer - _unwrapBuf.skip(toFill.put(_unwrapBuf)); - return true; - } - else - // return progress from recursive call - return progress; - } - // Else if there is some temporary data - else if (_unwrapBuf!=null && _unwrapBuf.hasContent()) - { - // transfer from temp buffer to fill buffer - _unwrapBuf.skip(toFill.put(_unwrapBuf)); - return true; - } - - // If we are here, we have a buffer ready into which we can put some read data. - - // If we have no data to flush, flush the empty buffer - if (toFlush==null) - toFlush=__ZERO_BUFFER; - - // While we are making progress processing SSL engine - boolean progress=true; - while (progress) - { - progress=false; - - // Do any real IO - int filled=0,flushed=0; - try - { - // Read any available data - if (_inbound.space() > 0 && (filled = _endp.fill(_inbound)) > 0) - progress = true; - - // flush any output data - if (_outbound.hasContent() && (flushed=_endp.flush(_outbound)) > 0) - progress = true; - } - catch (IOException e) - { - _endp.close(); - throw e; - } - finally - { - _logger.debug("{} {} {} filled={}/{} flushed={}/{}",_session,this,_engine.getHandshakeStatus(),filled,_inbound.length(),flushed,_outbound.length()); - } - - // handle the current hand share status - switch(_engine.getHandshakeStatus()) - { - case FINISHED: - throw new IllegalStateException(); - - case NOT_HANDSHAKING: - { - // Try unwrapping some application data - if (toFill.space()>0 && _inbound.hasContent() && unwrap(toFill)) - progress=true; - - // Try wrapping some application data - if (toFlush.hasContent() && _outbound.space()>0 && wrap(toFlush)) - progress=true; - } - break; - - case NEED_TASK: - { - // A task needs to be run, so run it! - Runnable task; - while ((task=_engine.getDelegatedTask())!=null) - { - progress=true; - task.run(); - } - - } - break; - - case NEED_WRAP: - { - // The SSL needs to send some handshake data to the other side - if (_handshook && !_allowRenegotiate) - _endp.close(); - else if (wrap(toFlush)) - progress=true; - } - break; - - case NEED_UNWRAP: - { - // The SSL needs to receive some handshake data from the other side - if (_handshook && !_allowRenegotiate) - _endp.close(); - else if (!_inbound.hasContent()&&filled==-1) - { - // No more input coming - _endp.shutdownInput(); - } - else if (unwrap(toFill)) - progress=true; - } - break; - } - - // pass on ishut/oshut state - if (_endp.isOpen() && _endp.isInputShutdown() && !_inbound.hasContent()) - closeInbound(); - - if (_endp.isOpen() && _engine.isOutboundDone() && !_outbound.hasContent()) - _endp.shutdownOutput(); - - // remember if any progress has been made - some_progress|=progress; - } - - // If we are reading into the temp buffer and it has some content, then we should be dispatched. - if (toFill==_unwrapBuf && _unwrapBuf.hasContent() && !_connection.isSuspended()) - _aEndp.dispatch(); - } - finally - { - releaseBuffers(); - if (some_progress) - _progressed.set(true); - } - return some_progress; - } - - private void closeInbound() - { - try - { - _engine.closeInbound(); - } - catch (SSLException x) - { - _logger.debug(x); - } - } - - @SuppressLint("TrulyRandom") - private synchronized boolean wrap(final Buffer buffer) throws IOException - { - ByteBuffer bbuf=extractByteBuffer(buffer); - final SSLEngineResult result; - int encrypted_produced = 0; - int decrypted_consumed = 0; - synchronized(bbuf) - { - _outbound.compact(); - ByteBuffer out_buffer=_outbound.getByteBuffer(); - synchronized(out_buffer) - { - try - { - bbuf.position(buffer.getIndex()); - bbuf.limit(buffer.putIndex()); - int decrypted_position = bbuf.position(); - - out_buffer.position(_outbound.putIndex()); - out_buffer.limit(out_buffer.capacity()); - int encrypted_position = out_buffer.position(); - - result=_engine.wrap(bbuf,out_buffer); - if (_logger.isDebugEnabled()) - _logger.debug("{} wrap {} {} consumed={} produced={}", - _session, - result.getStatus(), - result.getHandshakeStatus(), - result.bytesConsumed(), - result.bytesProduced()); - - decrypted_consumed = bbuf.position() - decrypted_position; - buffer.skip(decrypted_consumed); - - encrypted_produced = out_buffer.position() - encrypted_position; - _outbound.setPutIndex(_outbound.putIndex() + encrypted_produced); - } - catch(SSLException e) - { - _logger.debug(String.valueOf(_endp), e); - _endp.close(); - throw e; - } - catch (Exception x) - { - throw new IOException(x); - } - finally - { - out_buffer.position(0); - out_buffer.limit(out_buffer.capacity()); - bbuf.position(0); - bbuf.limit(bbuf.capacity()); - } - } - } - - switch(result.getStatus()) - { - case BUFFER_UNDERFLOW: - throw new IllegalStateException(); - - case BUFFER_OVERFLOW: - break; - - case OK: - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _handshook=true; - break; - - case CLOSED: - _logger.debug("wrap CLOSE {} {}",this,result); - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _endp.close(); - break; - - default: - _logger.debug("{} wrap default {}",_session,result); - throw new IOException(result.toString()); - } - - return decrypted_consumed > 0 || encrypted_produced > 0; - } - - private synchronized boolean unwrap(final Buffer buffer) throws IOException - { - if (!_inbound.hasContent()) - return false; - - ByteBuffer bbuf=extractByteBuffer(buffer); - final SSLEngineResult result; - int encrypted_consumed = 0; - int decrypted_produced = 0; - synchronized(bbuf) - { - ByteBuffer in_buffer=_inbound.getByteBuffer(); - synchronized(in_buffer) - { - try - { - bbuf.position(buffer.putIndex()); - bbuf.limit(buffer.capacity()); - int decrypted_position = bbuf.position(); - - in_buffer.position(_inbound.getIndex()); - in_buffer.limit(_inbound.putIndex()); - int encrypted_position = in_buffer.position(); - - result=_engine.unwrap(in_buffer,bbuf); - if (_logger.isDebugEnabled()) - _logger.debug("{} unwrap {} {} consumed={} produced={}", - _session, - result.getStatus(), - result.getHandshakeStatus(), - result.bytesConsumed(), - result.bytesProduced()); - - encrypted_consumed = in_buffer.position() - encrypted_position; - _inbound.skip(encrypted_consumed); - _inbound.compact(); - - decrypted_produced = bbuf.position() - decrypted_position; - buffer.setPutIndex(buffer.putIndex() + decrypted_produced); - } - catch(SSLException e) - { - _logger.debug(String.valueOf(_endp), e); - _endp.close(); - throw e; - } - catch (Exception x) - { - throw new IOException(x); - } - finally - { - in_buffer.position(0); - in_buffer.limit(in_buffer.capacity()); - bbuf.position(0); - bbuf.limit(bbuf.capacity()); - } - } - } - - switch(result.getStatus()) - { - case BUFFER_UNDERFLOW: - if (_endp.isInputShutdown()) - _inbound.clear(); - break; - - case BUFFER_OVERFLOW: - if (_logger.isDebugEnabled()) _logger.debug("{} unwrap {} {}->{}",_session,result.getStatus(),_inbound.toDetailString(),buffer.toDetailString()); - break; - - case OK: - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _handshook=true; - break; - - case CLOSED: - _logger.debug("unwrap CLOSE {} {}",this,result); - if (result.getHandshakeStatus()==HandshakeStatus.FINISHED) - _endp.close(); - break; - - default: - _logger.debug("{} wrap default {}",_session,result); - throw new IOException(result.toString()); - } - - return encrypted_consumed > 0 || decrypted_produced > 0; - } - - /* ------------------------------------------------------------ */ - private ByteBuffer extractByteBuffer(Buffer buffer) - { - if (buffer.buffer() instanceof NIOBuffer) - return ((NIOBuffer)buffer.buffer()).getByteBuffer(); - return ByteBuffer.wrap(buffer.array()); - } - - /* ------------------------------------------------------------ */ - public AsyncEndPoint getSslEndPoint() - { - return _sslEndPoint; - } - - /* ------------------------------------------------------------ */ - public String toString() - { - return String.format("%s %s", super.toString(), _sslEndPoint); - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public class SslEndPoint implements AsyncEndPoint - { - public void shutdownOutput() throws IOException - { - synchronized (SslConnection.this) - { - try - { - _logger.debug("{} ssl endp.oshut {}",_session,this); - _oshut=true; - _engine.closeOutbound(); - } - catch (Exception x) - { - throw new IOException(x); - } - } - flush(); - } - - public boolean isOutputShutdown() - { - synchronized (SslConnection.this) - { - return _oshut||!isOpen()||_engine.isOutboundDone(); - } - } - - public void shutdownInput() throws IOException - { - _logger.debug("{} ssl endp.ishut!",_session); - // We do not do a closeInput here, as SSL does not support half close. - // isInputShutdown works it out itself from buffer state and underlying endpoint state. - } - - public boolean isInputShutdown() - { - synchronized (SslConnection.this) - { - return _endp.isInputShutdown() && - !(_unwrapBuf!=null&&_unwrapBuf.hasContent()) && - !(_inbound!=null&&_inbound.hasContent()); - } - } - - public void close() throws IOException - { - _logger.debug("{} ssl endp.close",_session); - _endp.close(); - } - - public int fill(Buffer buffer) throws IOException - { - int size=buffer.length(); - process(buffer, null); - - int filled=buffer.length()-size; - - if (filled==0 && isInputShutdown()) - return -1; - return filled; - } - - public int flush(Buffer buffer) throws IOException - { - int size = buffer.length(); - process(null, buffer); - return size-buffer.length(); - } - - public boolean blockWritable(long millisecs) throws IOException - { - return _endp.blockWritable(millisecs); - } - - public boolean isOpen() - { - return _endp.isOpen(); - } - - public void flush() throws IOException - { - process(null, null); - } - - public void dispatch() - { - _aEndp.dispatch(); - } - - public void scheduleWrite() - { - _aEndp.scheduleWrite(); - } - - public boolean hasProgressed() - { - return _progressed.getAndSet(false); - } - - public String getLocalAddr() - { - return _aEndp.getLocalAddr(); - } - - public int getLocalPort() - { - return _aEndp.getLocalPort(); - } - - public String getRemoteAddr() - { - return _aEndp.getRemoteAddr(); - } - - public int getRemotePort() - { - return _aEndp.getRemotePort(); - } - - public boolean isBlocking() - { - return false; - } - - public int getMaxIdleTime() - { - return _aEndp.getMaxIdleTime(); - } - - public void setMaxIdleTime(int timeMs) throws IOException - { - _aEndp.setMaxIdleTime(timeMs); - } - - public Connection getConnection() - { - return _connection; - } - - public void setConnection(Connection connection) - { - _connection=(AsyncConnection)connection; - } - - public String toString() - { - // Do NOT use synchronized (SslConnection.this) - // because it's very easy to deadlock when debugging is enabled. - // We do a best effort to print the right toString() and that's it. - Buffer inbound = _inbound; - Buffer outbound = _outbound; - Buffer unwrap = _unwrapBuf; - int i = inbound == null? -1 : inbound.length(); - int o = outbound == null ? -1 : outbound.length(); - int u = unwrap == null ? -1 : unwrap.length(); - return String.format(Locale.getDefault(), "SSL %s i/o/u=%d/%d/%d ishut=%b oshut=%b {%s}", - _engine.getHandshakeStatus(), - i, o, u, - _ishut, _oshut, - _connection); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/BlockingArrayQueue.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/BlockingArrayQueue.java deleted file mode 100644 index 110192b1..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/BlockingArrayQueue.java +++ /dev/null @@ -1,482 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.util.AbstractList; -import java.util.Collection; -import java.util.NoSuchElementException; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.ReentrantLock; - - -/* ------------------------------------------------------------ */ -/** Queue backed by a circular array. - * - * This queue is uses a variant of the two lock queue algorithm to - * provide an efficient queue or list backed by a growable circular - * array. This queue also has a partial implementation of - * {@link java.util.concurrent.BlockingQueue}, specifically the {@link #take()} and - * {@link #poll(long, TimeUnit)} methods. - * Unlike {@link java.util.concurrent.ArrayBlockingQueue}, this class is - * able to grow and provides a blocking put call. - * <p> - * The queue has both a capacity (the size of the array currently allocated) - * and a limit (the maximum size that may be allocated), which defaults to - * {@link Integer#MAX_VALUE}. - * - * @param <E> The element type - */ -public class BlockingArrayQueue<E> extends AbstractList<E> implements BlockingQueue<E> -{ - public final int DEFAULT_CAPACITY=128; - public final int DEFAULT_GROWTH=64; - private final int _limit; - private final AtomicInteger _size=new AtomicInteger(); - private final int _growCapacity; - - private volatile int _capacity; - private Object[] _elements; - - private final ReentrantLock _headLock = new ReentrantLock(); - private final Condition _notEmpty = _headLock.newCondition(); - private int _head; - - private final ReentrantLock _tailLock = new ReentrantLock(); - private int _tail; - - /* ------------------------------------------------------------ */ - /** Create a growing partially blocking Queue. - * @param capacity Initial capacity - * @param growBy Incremental capacity. - */ - public BlockingArrayQueue(int capacity,int growBy) - { - _elements=new Object[capacity]; - _capacity=_elements.length; - _growCapacity=growBy; - _limit=Integer.MAX_VALUE; - } - - /* ------------------------------------------------------------ */ - public int getCapacity() - { - return _capacity; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean add(E e) - { - return offer(e); - } - - /* ------------------------------------------------------------ */ - public E element() - { - E e = peek(); - if (e==null) - throw new NoSuchElementException(); - return e; - } - - /* ------------------------------------------------------------ */ - @SuppressWarnings("unchecked") - public E peek() - { - if (_size.get() == 0) - return null; - - E e = null; - _headLock.lock(); // Size cannot shrink - try - { - if (_size.get() > 0) - e = (E)_elements[_head]; - } - finally - { - _headLock.unlock(); - } - - return e; - } - - /* ------------------------------------------------------------ */ - public boolean offer(E e) - { - if (e == null) - throw new NullPointerException(); - - boolean not_empty=false; - _tailLock.lock(); // size cannot grow... only shrink - try - { - if (_size.get() >= _limit) - return false; - - // should we expand array? - if (_size.get()==_capacity) - { - _headLock.lock(); // Need to grow array - try - { - if (!grow()) - return false; - } - finally - { - _headLock.unlock(); - } - } - - // add the element - _elements[_tail]=e; - _tail=(_tail+1)%_capacity; - - not_empty=0==_size.getAndIncrement(); - - } - finally - { - _tailLock.unlock(); - } - - if (not_empty) - { - _headLock.lock(); - try - { - _notEmpty.signal(); - } - finally - { - _headLock.unlock(); - } - } - - return true; - } - - /* ------------------------------------------------------------ */ - @SuppressWarnings("unchecked") - public E poll() - { - if (_size.get() == 0) - return null; - - E e = null; - _headLock.lock(); // Size cannot shrink - try - { - if (_size.get() > 0) - { - final int head=_head; - e = (E)_elements[head]; - _elements[head]=null; - _head=(head+1)%_capacity; - - if (_size.decrementAndGet()>0) - _notEmpty.signal(); - } - } - finally - { - _headLock.unlock(); - } - - return e; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves and removes the head of this queue, waiting - * if no elements are present on this queue. - * @return the head of this queue - * @throws InterruptedException if interrupted while waiting. - */ - @SuppressWarnings("unchecked") - public E take() throws InterruptedException - { - E e = null; - _headLock.lockInterruptibly(); // Size cannot shrink - try - { - try - { - while (_size.get() == 0) - { - _notEmpty.await(); - } - } - catch (InterruptedException ie) - { - _notEmpty.signal(); - throw ie; - } - - final int head=_head; - e = (E)_elements[head]; - _elements[head]=null; - _head=(head+1)%_capacity; - - if (_size.decrementAndGet()>0) - _notEmpty.signal(); - } - finally - { - _headLock.unlock(); - } - - return e; - } - - /* ------------------------------------------------------------ */ - /** - * Retrieves and removes the head of this queue, waiting - * if necessary up to the specified wait time if no elements are - * present on this queue. - * @param time how long to wait before giving up, in units of - * <tt>unit</tt> - * @param unit a <tt>TimeUnit</tt> determining how to interpret the - * <tt>timeout</tt> parameter - * @return the head of this queue, or <tt>null</tt> if the - * specified waiting time elapses before an element is present. - * @throws InterruptedException if interrupted while waiting. - */ - @SuppressWarnings("unchecked") - public E poll(long time, TimeUnit unit) throws InterruptedException - { - - E e = null; - - long nanos = unit.toNanos(time); - - _headLock.lockInterruptibly(); // Size cannot shrink - try - { - try - { - while (_size.get() == 0) - { - if (nanos<=0) - return null; - nanos = _notEmpty.awaitNanos(nanos); - } - } - catch (InterruptedException ie) - { - _notEmpty.signal(); - throw ie; - } - - e = (E)_elements[_head]; - _elements[_head]=null; - _head=(_head+1)%_capacity; - - if (_size.decrementAndGet()>0) - _notEmpty.signal(); - } - finally - { - _headLock.unlock(); - } - - return e; - } - - /* ------------------------------------------------------------ */ - public E remove() - { - E e=poll(); - if (e==null) - throw new NoSuchElementException(); - return e; - } - - /* ------------------------------------------------------------ */ - @Override - public void clear() - { - _tailLock.lock(); - try - { - _headLock.lock(); - try - { - _head=0; - _tail=0; - _size.set(0); - } - finally - { - _headLock.unlock(); - } - } - finally - { - _tailLock.unlock(); - } - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isEmpty() - { - return _size.get()==0; - } - - /* ------------------------------------------------------------ */ - @Override - public int size() - { - return _size.get(); - } - - /* ------------------------------------------------------------ */ - @SuppressWarnings("unchecked") - @Override - public E get(int index) - { - _tailLock.lock(); - try - { - _headLock.lock(); - try - { - if (index<0 || index>=_size.get()) - throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")"); - int i = _head+index; - if (i>=_capacity) - i-=_capacity; - return (E)_elements[i]; - } - finally - { - _headLock.unlock(); - } - } - finally - { - _tailLock.unlock(); - } - } - - /* ------------------------------------------------------------ */ - private boolean grow() - { - if (_growCapacity<=0) - return false; - - _tailLock.lock(); - try - { - _headLock.lock(); - try - { - final int head=_head; - final int tail=_tail; - final int new_tail; - - Object[] elements=new Object[_capacity+_growCapacity]; - - if (head<tail) - { - new_tail=tail-head; - System.arraycopy(_elements,head,elements,0,new_tail); - } - else if (head>tail || _size.get()>0) - { - new_tail=_capacity+tail-head; - int cut=_capacity-head; - System.arraycopy(_elements,head,elements,0,cut); - System.arraycopy(_elements,0,elements,cut,tail); - } - else - { - new_tail=0; - } - - _elements=elements; - _capacity=_elements.length; - _head=0; - _tail=new_tail; - return true; - } - finally - { - _headLock.unlock(); - } - } - finally - { - _tailLock.unlock(); - } - - } - - /* ------------------------------------------------------------ */ - public int drainTo(Collection<? super E> c) - { - throw new UnsupportedOperationException(); - } - - /* ------------------------------------------------------------ */ - public int drainTo(Collection<? super E> c, int maxElements) - { - throw new UnsupportedOperationException(); - } - - /* ------------------------------------------------------------ */ - public boolean offer(E o, long timeout, TimeUnit unit) throws InterruptedException - { - throw new UnsupportedOperationException(); - } - - /* ------------------------------------------------------------ */ - public void put(E o) throws InterruptedException - { - if (!add(o)) - throw new IllegalStateException("full"); - } - - /* ------------------------------------------------------------ */ - public int remainingCapacity() - { - _tailLock.lock(); - try - { - _headLock.lock(); - try - { - return getCapacity()-size(); - } - finally - { - _headLock.unlock(); - } - } - finally - { - _tailLock.unlock(); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ConcurrentHashSet.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ConcurrentHashSet.java deleted file mode 100644 index 9f88ebc9..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ConcurrentHashSet.java +++ /dev/null @@ -1,126 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.util.AbstractSet; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E> -{ - private final Map<E, Boolean> _map = new ConcurrentHashMap<E, Boolean>(); - private transient Set<E> _keys = _map.keySet(); - - public ConcurrentHashSet() - { - } - - @Override - public boolean add(E e) - { - return _map.put(e,Boolean.TRUE) == null; - } - - @Override - public void clear() - { - _map.clear(); - } - - @Override - public boolean contains(Object o) - { - return _map.containsKey(o); - } - - @Override - public boolean containsAll(Collection<?> c) - { - return _keys.containsAll(c); - } - - @Override - public boolean equals(Object o) - { - return o == this || _keys.equals(o); - } - - @Override - public int hashCode() - { - return _keys.hashCode(); - } - - @Override - public boolean isEmpty() - { - return _map.isEmpty(); - } - - @Override - public Iterator<E> iterator() - { - return _keys.iterator(); - } - - @Override - public boolean remove(Object o) - { - return _map.remove(o) != null; - } - - @Override - public boolean removeAll(Collection<?> c) - { - return _keys.removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) - { - return _keys.retainAll(c); - } - - @Override - public int size() - { - return _map.size(); - } - - @Override - public Object[] toArray() - { - return _keys.toArray(); - } - - @Override - public <T> T[] toArray(T[] a) - { - return _keys.toArray(a); - } - - @Override - public String toString() - { - return _keys.toString(); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/IO.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/IO.java deleted file mode 100644 index ea1b0887..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/IO.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ======================================================================== */ -/** IO Utilities. - * Provides stream handling utilities in - * singleton Threadpool implementation accessed by static members. - */ -public class IO -{ - private static final Logger LOG = Log.getLogger(IO.class); - - /* ------------------------------------------------------------------- */ - public static int bufferSize = 64*1024; - - /* ------------------------------------------------------------------- */ - /** Copy Stream in to Stream out until EOF or exception. - */ - public static void copy(InputStream in, OutputStream out) - throws IOException - { - copy(in,out,-1); - } - - /* ------------------------------------------------------------------- */ - /** Copy Stream in to Stream for byteCount bytes or until EOF or exception. - */ - public static void copy(InputStream in, - OutputStream out, - long byteCount) - throws IOException - { - byte buffer[] = new byte[bufferSize]; - int len=bufferSize; - - if (byteCount>=0) - { - while (byteCount>0) - { - int max = byteCount<bufferSize?(int)byteCount:bufferSize; - len=in.read(buffer,0,max); - - if (len==-1) - break; - - byteCount -= len; - out.write(buffer,0,len); - } - } - else - { - while (true) - { - len=in.read(buffer,0,bufferSize); - if (len<0 ) - break; - out.write(buffer,0,len); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * closes any {@link Closeable} - * - * @param c the closeable to close - */ - public static void close(Closeable c) - { - try - { - if (c != null) - c.close(); - } - catch (IOException e) - { - LOG.ignore(e); - } - } - - /** - * closes an input stream, and logs exceptions - * - * @param is the input stream to close - */ - public static void close(InputStream is) - { - try - { - if (is != null) - is.close(); - } - catch (IOException e) - { - LOG.ignore(e); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/QuotedStringTokenizer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/QuotedStringTokenizer.java deleted file mode 100644 index 2c6e2460..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/QuotedStringTokenizer.java +++ /dev/null @@ -1,312 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.IOException; -import java.util.Arrays; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; - -/* ------------------------------------------------------------ */ -/** StringTokenizer with Quoting support. - * - * This class is a copy of the java.util.StringTokenizer API and - * the behaviour is the same, except that single and double quoted - * string values are recognised. - * Delimiters within quotes are not considered delimiters. - * Quotes can be escaped with '\'. - * - * @see java.util.StringTokenizer - * - */ -public class QuotedStringTokenizer - extends StringTokenizer -{ - private final static String __delim="\t\n\r"; - private String _string; - private String _delim = __delim; - private boolean _returnQuotes=false; - private boolean _returnDelimiters=false; - private StringBuffer _token; - private boolean _hasToken=false; - private int _i=0; - private boolean _double=true; - private boolean _single=true; - - /* ------------------------------------------------------------ */ - public QuotedStringTokenizer(String str, - String delim, - boolean returnDelimiters, - boolean returnQuotes) - { - super(""); - _string=str; - if (delim!=null) - _delim=delim; - _returnDelimiters=returnDelimiters; - _returnQuotes=returnQuotes; - - if (_delim.indexOf('\'')>=0 || - _delim.indexOf('"')>=0) - throw new Error("Can't use quotes as delimiters: "+_delim); - - _token=new StringBuffer(_string.length()>1024?512:_string.length()/2); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean hasMoreTokens() - { - // Already found a token - if (_hasToken) - return true; - - int state=0; - boolean escape=false; - while (_i<_string.length()) - { - char c=_string.charAt(_i++); - - switch (state) - { - case 0: // Start - if(_delim.indexOf(c)>=0) - { - if (_returnDelimiters) - { - _token.append(c); - return _hasToken=true; - } - } - else if (c=='\'' && _single) - { - if (_returnQuotes) - _token.append(c); - state=2; - } - else if (c=='\"' && _double) - { - if (_returnQuotes) - _token.append(c); - state=3; - } - else - { - _token.append(c); - _hasToken=true; - state=1; - } - break; - - case 1: // Token - _hasToken=true; - if(_delim.indexOf(c)>=0) - { - if (_returnDelimiters) - _i--; - return _hasToken; - } - else if (c=='\'' && _single) - { - if (_returnQuotes) - _token.append(c); - state=2; - } - else if (c=='\"' && _double) - { - if (_returnQuotes) - _token.append(c); - state=3; - } - else - { - _token.append(c); - } - break; - - case 2: // Single Quote - _hasToken=true; - if (escape) - { - escape=false; - _token.append(c); - } - else if (c=='\'') - { - if (_returnQuotes) - _token.append(c); - state=1; - } - else if (c=='\\') - { - if (_returnQuotes) - _token.append(c); - escape=true; - } - else - { - _token.append(c); - } - break; - - case 3: // Double Quote - _hasToken=true; - if (escape) - { - escape=false; - _token.append(c); - } - else if (c=='\"') - { - if (_returnQuotes) - _token.append(c); - state=1; - } - else if (c=='\\') - { - if (_returnQuotes) - _token.append(c); - escape=true; - } - else - { - _token.append(c); - } - break; - } - } - - return _hasToken; - } - - /* ------------------------------------------------------------ */ - @Override - public String nextToken() - throws NoSuchElementException - { - if (!hasMoreTokens() || _token==null) - throw new NoSuchElementException(); - String t=_token.toString(); - _token.setLength(0); - _hasToken=false; - return t; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean hasMoreElements() - { - return hasMoreTokens(); - } - - /* ------------------------------------------------------------ */ - @Override - public Object nextElement() - throws NoSuchElementException - { - return nextToken(); - } - - /* ------------------------------------------------------------ */ - /** Quote a string. - * The string is quoted only if quoting is required due to - * embedded delimiters, quote characters or the - * empty string. - * @param s The string to quote. - * @param delim the delimiter to use to quote the string - * @return quoted string - */ - public static String quoteIfNeeded(String s, String delim) - { - if (s==null) - return null; - if (s.length()==0) - return "\"\""; - - - for (int i=0;i<s.length();i++) - { - char c = s.charAt(i); - if (c=='\\' || c=='"' || c=='\'' || Character.isWhitespace(c) || delim.indexOf(c)>=0) - { - StringBuffer b=new StringBuffer(s.length()+8); - quote(b,s); - return b.toString(); - } - } - - return s; - } - - private static final char[] escapes = new char[32]; - static - { - Arrays.fill(escapes, (char)0xFFFF); - escapes['\b'] = 'b'; - escapes['\t'] = 't'; - escapes['\n'] = 'n'; - escapes['\f'] = 'f'; - escapes['\r'] = 'r'; - } - - /* ------------------------------------------------------------ */ - /** Quote a string into an Appendable. - * The characters ", \, \n, \r, \t, \f and \b are escaped - * @param buffer The Appendable - * @param input The String to quote. - */ - public static void quote(Appendable buffer, String input) - { - try - { - buffer.append('"'); - for (int i = 0; i < input.length(); ++i) - { - char c = input.charAt(i); - if (c >= 32) - { - if (c == '"' || c == '\\') - buffer.append('\\'); - buffer.append(c); - } - else - { - char escape = escapes[c]; - if (escape == 0xFFFF) - { - // Unicode escape - buffer.append('\\').append('u').append('0').append('0'); - if (c < 0x10) - buffer.append('0'); - buffer.append(Integer.toString(c, 16)); - } - else - { - buffer.append('\\').append(escape); - } - } - } - buffer.append('"'); - } - catch (IOException x) - { - throw new RuntimeException(x); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/StringMap.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/StringMap.java deleted file mode 100644 index addba083..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/StringMap.java +++ /dev/null @@ -1,603 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.Externalizable; -import java.util.AbstractMap; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/* ------------------------------------------------------------ */ -/** Map implementation Optimized for Strings keys.. - * This String Map has been optimized for mapping small sets of - * Strings where the most frequently accessed Strings have been put to - * the map first. - * - * It also has the benefit that it can look up entries by substring or - * sections of char and byte arrays. This can prevent many String - * objects from being created just to look up in the map. - * - * This map is NOT synchronized. - */ -public class StringMap extends AbstractMap<Object, Object> implements Externalizable -{ - public static final boolean CASE_INSENSTIVE=true; - protected static final int __HASH_WIDTH=17; - - /* ------------------------------------------------------------ */ - protected int _width=__HASH_WIDTH; - protected Node _root=new Node(); - protected boolean _ignoreCase=false; - protected NullEntry _nullEntry=null; - protected Object _nullValue=null; - protected HashSet<Entry<Object, Object>> _entrySet=new HashSet<Entry<Object, Object>>(3); - protected Set<Entry<Object, Object>> _umEntrySet=Collections.unmodifiableSet(_entrySet); - - /* ------------------------------------------------------------ */ - /** Constructor. - */ - public StringMap() - {} - - /* ------------------------------------------------------------ */ - /** Constructor. - * @param ignoreCase - */ - public StringMap(boolean ignoreCase) - { - this(); - _ignoreCase=ignoreCase; - } - - /* ------------------------------------------------------------ */ - /** Set the ignoreCase attribute. - * @param ic If true, the map is case insensitive for keys. - */ - public void setIgnoreCase(boolean ic) - { - if (_root._children!=null) - throw new IllegalStateException("Must be set before first put"); - _ignoreCase=ic; - } - - /* ------------------------------------------------------------ */ - @Override - public Object put(Object key, Object value) - { - if (key==null) - return put(null,value); - return put(key.toString(),value); - } - - /* ------------------------------------------------------------ */ - public Object put(String key, Object value) - { - if (key==null) - { - Object oldValue=_nullValue; - _nullValue=value; - if (_nullEntry==null) - { - _nullEntry=new NullEntry(); - _entrySet.add(_nullEntry); - } - return oldValue; - } - - Node node = _root; - int ni=-1; - Node prev = null; - Node parent = null; - - // look for best match - charLoop: - for (int i=0;i<key.length();i++) - { - char c=key.charAt(i); - - // Advance node - if (ni==-1) - { - parent=node; - prev=null; - ni=0; - node=(node._children==null)?null:node._children[c%_width]; - } - - // Loop through a node chain at the same level - while (node!=null) - { - // If it is a matching node, goto next char - if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c) - { - prev=null; - ni++; - if (ni==node._char.length) - ni=-1; - continue charLoop; - } - - // no char match - // if the first char, - if (ni==0) - { - // look along the chain for a char match - prev=node; - node=node._next; - } - else - { - // Split the current node! - node.split(this,ni); - i--; - ni=-1; - continue charLoop; - } - } - - // We have run out of nodes, so as this is a put, make one - node = new Node(_ignoreCase,key,i); - - if (prev!=null) // add to end of chain - prev._next=node; - else if (parent!=null) // add new child - { - if (parent._children==null) - parent._children=new Node[_width]; - parent._children[c%_width]=node; - int oi=node._ochar[0]%_width; - if (node._ochar!=null && node._char[0]%_width!=oi) - { - if (parent._children[oi]==null) - parent._children[oi]=node; - else - { - Node n=parent._children[oi]; - while(n._next!=null) - n=n._next; - n._next=node; - } - } - } - else // this is the root. - _root=node; - break; - } - - // Do we have a node - if (node!=null) - { - // Split it if we are in the middle - if(ni>0) - node.split(this,ni); - - Object old = node._value; - node._key=key; - node._value=value; - _entrySet.add(node); - return old; - } - return null; - } - - /* ------------------------------------------------------------ */ - @Override - public Object get(Object key) - { - if (key==null) - return _nullValue; - if (key instanceof String) - return get((String)key); - return get(key.toString()); - } - - /* ------------------------------------------------------------ */ - public Object get(String key) - { - if (key==null) - return _nullValue; - - Map.Entry<Object, Object> entry = getEntry(key,0,key.length()); - if (entry==null) - return null; - return entry.getValue(); - } - - /* ------------------------------------------------------------ */ - /** Get a map entry by substring key. - * @param key String containing the key - * @param offset Offset of the key within the String. - * @param length The length of the key - * @return The Map.Entry for the key or null if the key is not in - * the map. - */ - public Map.Entry<Object, Object> getEntry(String key,int offset, int length) - { - if (key==null) - return _nullEntry; - - Node node = _root; - int ni=-1; - - // look for best match - charLoop: - for (int i=0;i<length;i++) - { - char c=key.charAt(offset+i); - - // Advance node - if (ni==-1) - { - ni=0; - node=(node._children==null)?null:node._children[c%_width]; - } - - // Look through the node chain - while (node!=null) - { - // If it is a matching node, goto next char - if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c) - { - ni++; - if (ni==node._char.length) - ni=-1; - continue charLoop; - } - - // No char match, so if mid node then no match at all. - if (ni>0) return null; - - // try next in chain - node=node._next; - } - return null; - } - - if (ni>0) return null; - if (node!=null && node._key==null) - return null; - return node; - } - - /* ------------------------------------------------------------ */ - /** Get a map entry by byte array key, using as much of the passed key as needed for a match. - * A simple 8859-1 byte to char mapping is assumed. - * @param key char array containing the key - * @param offset Offset of the key within the array. - * @param maxLength The length of the key - * @return The Map.Entry for the key or null if the key is not in - * the map. - */ - public Map.Entry<Object, Object> getBestEntry(byte[] key,int offset, int maxLength) - { - if (key==null) - return _nullEntry; - - Node node = _root; - int ni=-1; - - // look for best match - charLoop: - for (int i=0;i<maxLength;i++) - { - char c=(char)key[offset+i]; - - // Advance node - if (ni==-1) - { - ni=0; - - Node child = (node._children==null)?null:node._children[c%_width]; - - if (child==null && i>0) - return node; // This is the best match - node=child; - } - - // While we have a node to try - while (node!=null) - { - // If it is a matching node, goto next char - if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c) - { - ni++; - if (ni==node._char.length) - ni=-1; - continue charLoop; - } - - // No char match, so if mid node then no match at all. - if (ni>0) return null; - - // try next in chain - node=node._next; - } - return null; - } - - if (ni>0) return null; - if (node!=null && node._key==null) - return null; - return node; - } - - - /* ------------------------------------------------------------ */ - @Override - public Object remove(Object key) - { - if (key==null) - return remove(null); - return remove(key.toString()); - } - - /* ------------------------------------------------------------ */ - public Object remove(String key) - { - if (key==null) - { - Object oldValue=_nullValue; - if (_nullEntry!=null) - { - _entrySet.remove(_nullEntry); - _nullEntry=null; - _nullValue=null; - } - return oldValue; - } - - Node node = _root; - int ni=-1; - - // look for best match - charLoop: - for (int i=0;i<key.length();i++) - { - char c=key.charAt(i); - - // Advance node - if (ni==-1) - { - ni=0; - node=(node._children==null)?null:node._children[c%_width]; - } - - // While we have a node to try - while (node!=null) - { - // If it is a matching node, goto next char - if (node._char[ni]==c || _ignoreCase&&node._ochar[ni]==c) - { - ni++; - if (ni==node._char.length) - ni=-1; - continue charLoop; - } - - // No char match, so if mid node then no match at all. - if (ni>0) return null; - - // try next in chain - node=node._next; - } - return null; - } - - if (ni>0) return null; - if (node!=null && node._key==null) - return null; - - Object old = node._value; - _entrySet.remove(node); - node._value=null; - node._key=null; - - return old; - } - - /* ------------------------------------------------------------ */ - @Override - public Set<Map.Entry<Object, Object>> entrySet() - { - return _umEntrySet; - } - - /* ------------------------------------------------------------ */ - @Override - public int size() - { - return _entrySet.size(); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isEmpty() - { - return _entrySet.isEmpty(); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean containsKey(Object key) - { - if (key==null) - return _nullEntry!=null; - return - getEntry(key.toString(),0,key==null?0:key.toString().length())!=null; - } - - /* ------------------------------------------------------------ */ - @Override - public void clear() - { - _root=new Node(); - _nullEntry=null; - _nullValue=null; - _entrySet.clear(); - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - private static class Node implements Map.Entry<Object, Object> - { - char[] _char; - char[] _ochar; - Node _next; - Node[] _children; - String _key; - Object _value; - - Node(){} - - Node(boolean ignoreCase,String s, int offset) - { - int l=s.length()-offset; - _char=new char[l]; - _ochar=new char[l]; - for (int i=0;i<l;i++) - { - char c=s.charAt(offset+i); - _char[i]=c; - if (ignoreCase) - { - char o=c; - if (Character.isUpperCase(c)) - o=Character.toLowerCase(c); - else if (Character.isLowerCase(c)) - o=Character.toUpperCase(c); - _ochar[i]=o; - } - } - } - - Node split(StringMap map,int offset) - { - Node split = new Node(); - int sl=_char.length-offset; - - char[] tmp=this._char; - this._char=new char[offset]; - split._char = new char[sl]; - System.arraycopy(tmp,0,this._char,0,offset); - System.arraycopy(tmp,offset,split._char,0,sl); - - if (this._ochar!=null) - { - tmp=this._ochar; - this._ochar=new char[offset]; - split._ochar = new char[sl]; - System.arraycopy(tmp,0,this._ochar,0,offset); - System.arraycopy(tmp,offset,split._ochar,0,sl); - } - - split._key=this._key; - split._value=this._value; - this._key=null; - this._value=null; - if (map._entrySet.remove(this)) - map._entrySet.add(split); - - split._children=this._children; - this._children=new Node[map._width]; - this._children[split._char[0]%map._width]=split; - if (split._ochar!=null && this._children[split._ochar[0]%map._width]!=split) - this._children[split._ochar[0]%map._width]=split; - - return split; - } - - public Object getKey(){return _key;} - public Object getValue(){return _value;} - public Object setValue(Object o){Object old=_value;_value=o;return old;} - @Override - public String toString() - { - StringBuilder buf=new StringBuilder(); - toString(buf); - return buf.toString(); - } - - private void toString(StringBuilder buf) - { - buf.append("{["); - if (_char==null) - buf.append('-'); - else - for (int i=0;i<_char.length;i++) - buf.append(_char[i]); - buf.append(':'); - buf.append(_key); - buf.append('='); - buf.append(_value); - buf.append(']'); - if (_children!=null) - { - for (int i=0;i<_children.length;i++) - { - buf.append('|'); - if (_children[i]!=null) - _children[i].toString(buf); - else - buf.append("-"); - } - } - buf.append('}'); - if (_next!=null) - { - buf.append(",\n"); - _next.toString(buf); - } - } - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - private class NullEntry implements Map.Entry<Object, Object> - { - public Object getKey(){return null;} - public Object getValue(){return _nullValue;} - public Object setValue(Object o) - {Object old=_nullValue;_nullValue=o;return old;} - @Override - public String toString(){return "[:null="+_nullValue+"]";} - } - - /* ------------------------------------------------------------ */ - public void writeExternal(java.io.ObjectOutput out) - throws java.io.IOException - { - HashMap<Object, Object> map = new HashMap<Object, Object>(this); - out.writeBoolean(_ignoreCase); - out.writeObject(map); - } - - /* ------------------------------------------------------------ */ - public void readExternal(java.io.ObjectInput in) - throws java.io.IOException, ClassNotFoundException - { - boolean ic=in.readBoolean(); - HashMap<?, ?> map = (HashMap<?, ?>)in.readObject(); - setIgnoreCase(ic); - this.putAll(map); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/TypeUtil.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/TypeUtil.java deleted file mode 100644 index 48c373fd..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/TypeUtil.java +++ /dev/null @@ -1,48 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.io.IOException; - -/* ------------------------------------------------------------ */ -/** - * TYPE Utilities. - * Provides various static utiltiy methods for manipulating types and their - * string representations. - * - * @since Jetty 4.1 - */ -public class TypeUtil -{ - /* ------------------------------------------------------------ */ - public static void toHex(byte b,Appendable buf) - { - try - { - int d=0xf&((0xF0&b)>>4); - buf.append((char)((d>9?('A'-10):'0')+d)); - d=0xf&b; - buf.append((char)((d>9?('A'-10):'0')+d)); - } - catch(IOException e) - { - throw new RuntimeException(e); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/AbstractLifeCycle.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/AbstractLifeCycle.java deleted file mode 100644 index 92c4996c..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/AbstractLifeCycle.java +++ /dev/null @@ -1,193 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.util.concurrent.CopyOnWriteArrayList; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * Basic implementation of the life cycle interface for components. - * - * - */ -public abstract class AbstractLifeCycle implements LifeCycle -{ - private static final Logger LOG = Log.getLogger(AbstractLifeCycle.class); - public static final String STOPPED="STOPPED"; - public static final String FAILED="FAILED"; - public static final String STARTING="STARTING"; - public static final String STARTED="STARTED"; - public static final String STOPPING="STOPPING"; - public static final String RUNNING="RUNNING"; - - private final Object _lock = new Object(); - private final int __FAILED = -1, __STOPPED = 0, __STARTING = 1, __STARTED = 2, __STOPPING = 3; - private volatile int _state = __STOPPED; - - protected final CopyOnWriteArrayList<LifeCycle.Listener> _listeners=new CopyOnWriteArrayList<LifeCycle.Listener>(); - - protected void doStart() throws Exception - { - } - - protected void doStop() throws Exception - { - } - - public final void start() throws Exception - { - synchronized (_lock) - { - try - { - if (_state == __STARTED || _state == __STARTING) - return; - setStarting(); - doStart(); - setStarted(); - } - catch (Exception e) - { - setFailed(e); - throw e; - } - catch (Error e) - { - setFailed(e); - throw e; - } - } - } - - public final void stop() throws Exception - { - synchronized (_lock) - { - try - { - if (_state == __STOPPING || _state == __STOPPED) - return; - setStopping(); - doStop(); - setStopped(); - } - catch (Exception e) - { - setFailed(e); - throw e; - } - catch (Error e) - { - setFailed(e); - throw e; - } - } - } - - public boolean isRunning() - { - final int state = _state; - - return state == __STARTED || state == __STARTING; - } - - public boolean isStarted() - { - return _state == __STARTED; - } - - public boolean isStarting() - { - return _state == __STARTING; - } - - public boolean isStopping() - { - return _state == __STOPPING; - } - - public boolean isStopped() - { - return _state == __STOPPED; - } - - public String getState() - { - switch(_state) - { - case __FAILED: return FAILED; - case __STARTING: return STARTING; - case __STARTED: return STARTED; - case __STOPPING: return STOPPING; - case __STOPPED: return STOPPED; - } - return null; - } - - public static String getState(LifeCycle lc) - { - if (lc.isStarting()) return STARTING; - if (lc.isStarted()) return STARTED; - if (lc.isStopping()) return STOPPING; - if (lc.isStopped()) return STOPPED; - return FAILED; - } - - private void setStarted() - { - _state = __STARTED; - LOG.debug(STARTED+" {}",this); - for (Listener listener : _listeners) - listener.lifeCycleStarted(this); - } - - private void setStarting() - { - LOG.debug("starting {}",this); - _state = __STARTING; - for (Listener listener : _listeners) - listener.lifeCycleStarting(this); - } - - private void setStopping() - { - LOG.debug("stopping {}",this); - _state = __STOPPING; - for (Listener listener : _listeners) - listener.lifeCycleStopping(this); - } - - private void setStopped() - { - _state = __STOPPED; - LOG.debug("{} {}",STOPPED,this); - for (Listener listener : _listeners) - listener.lifeCycleStopped(this); - } - - private void setFailed(Throwable th) - { - _state = __FAILED; - LOG.warn(FAILED+" " + this+": "+th,th); - for (Listener listener : _listeners) - listener.lifeCycleFailure(this,th); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/AggregateLifeCycle.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/AggregateLifeCycle.java deleted file mode 100644 index 670fbfd1..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/AggregateLifeCycle.java +++ /dev/null @@ -1,250 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * An AggregateLifeCycle is an {@link LifeCycle} implementation for a collection of contained beans. - * <p> - * Beans can be added the AggregateLifeCycle either as managed beans or as unmanaged beans. A managed bean is started, stopped and destroyed with the aggregate. - * An unmanaged bean is associated with the aggregate for the purposes of {@link #dump()}, but it's lifecycle must be managed externally. - * <p> - * When a bean is added, if it is a {@link LifeCycle} and it is already started, then it is assumed to be an unmanaged bean. - * Otherwise the methods {@link #addBean(Object, boolean)}, {@link #manage(Object)} and {@link #unmanage(Object)} can be used to - * explicitly control the life cycle relationship. - * <p> - * If adding a bean that is shared between multiple {@link AggregateLifeCycle} instances, then it should be started before being added, so it is unmanaged, or - * the API must be used to explicitly set it as unmanaged. - * <p> - */ -public class AggregateLifeCycle extends AbstractLifeCycle implements Dumpable -{ - private final List<Bean> _beans=new CopyOnWriteArrayList<Bean>(); - private boolean _started=false; - - private class Bean - { - Bean(Object b) - { - _bean=b; - } - final Object _bean; - volatile boolean _managed=true; - - public String toString() - { - return "{"+_bean+","+_managed+"}"; - } - } - - /* ------------------------------------------------------------ */ - /** - * Start the managed lifecycle beans in the order they were added. - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - for (Bean b:_beans) - { - if (b._managed && b._bean instanceof LifeCycle) - { - LifeCycle l=(LifeCycle)b._bean; - if (!l.isRunning()) - l.start(); - } - } - // indicate that we are started, so that addBean will start other beans added. - _started=true; - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /** - * Stop the joined lifecycle beans in the reverse order they were added. - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - @Override - protected void doStop() throws Exception - { - _started=false; - super.doStop(); - List<Bean> reverse = new ArrayList<Bean>(_beans); - Collections.reverse(reverse); - for (Bean b:reverse) - { - if (b._managed && b._bean instanceof LifeCycle) - { - LifeCycle l=(LifeCycle)b._bean; - if (l.isRunning()) - l.stop(); - } - } - } - - /* ------------------------------------------------------------ */ - /** Is the bean contained in the aggregate. - * @param bean - * @return True if the aggregate contains the bean - */ - public boolean contains(Object bean) - { - for (Bean b:_beans) - if (b._bean==bean) - return true; - return false; - } - - /* ------------------------------------------------------------ */ - /** - * Add an associated bean. - * If the bean is a {@link LifeCycle}, then it will be managed if it is not - * already started and umanaged if it is already started. The {@link #addBean(Object, boolean)} - * method should be used if this is not correct, or the {@link #manage(Object)} and {@link #unmanage(Object)} - * methods may be used after an add to change the status. - * @param o the bean object to add - * @return true if the bean was added or false if it has already been added. - */ - public boolean addBean(Object o) - { - // beans are joined unless they are started lifecycles - return addBean(o,!((o instanceof LifeCycle)&&((LifeCycle)o).isStarted())); - } - - /* ------------------------------------------------------------ */ - /** Add an associated lifecycle. - * @param o The lifecycle to add - * @param managed True if the LifeCycle is to be joined, otherwise it will be disjoint. - * @return true if bean was added, false if already present. - */ - public boolean addBean(Object o, boolean managed) - { - if (contains(o)) - return false; - - Bean b = new Bean(o); - b._managed=managed; - _beans.add(b); - - if (o instanceof LifeCycle) - { - LifeCycle l=(LifeCycle)o; - - // Start the bean if we are started - if (managed && _started) - { - try - { - l.start(); - } - catch(Exception e) - { - throw new RuntimeException (e); - } - } - } - return true; - } - - /* ------------------------------------------------------------ */ - protected void dumpThis(Appendable out) throws IOException - { - out.append(String.valueOf(this)).append(" - ").append(getState()).append("\n"); - } - - /* ------------------------------------------------------------ */ - public static void dumpObject(Appendable out,Object o) throws IOException - { - try - { - if (o instanceof LifeCycle) - out.append(String.valueOf(o)).append(" - ").append((AbstractLifeCycle.getState((LifeCycle)o))).append("\n"); - else - out.append(String.valueOf(o)).append("\n"); - } - catch(Throwable th) - { - out.append(" => ").append(th.toString()).append('\n'); - } - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out,String indent) throws IOException - { - dumpThis(out); - int size=_beans.size(); - if (size==0) - return; - int i=0; - for (Bean b : _beans) - { - i++; - - out.append(indent).append(" +- "); - if (b._managed) - { - if (b._bean instanceof Dumpable) - ((Dumpable)b._bean).dump(out,indent+(i==size?" ":" | ")); - else - dumpObject(out,b._bean); - } - else - dumpObject(out,b._bean); - } - - if (i!=size) - out.append(indent).append(" |\n"); - } - - /* ------------------------------------------------------------ */ - public static void dump(Appendable out,String indent,Collection<?>... collections) throws IOException - { - if (collections.length==0) - return; - int size=0; - for (Collection<?> c : collections) - size+=c.size(); - if (size==0) - return; - - int i=0; - for (Collection<?> c : collections) - { - for (Object o : c) - { - i++; - out.append(indent).append(" +- "); - - if (o instanceof Dumpable) - ((Dumpable)o).dump(out,indent+(i==size?" ":" | ")); - else - dumpObject(out,o); - } - - if (i!=size) - out.append(indent).append(" |\n"); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/Dumpable.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/Dumpable.java deleted file mode 100644 index 58d2404c..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/Dumpable.java +++ /dev/null @@ -1,26 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.io.IOException; - -public interface Dumpable -{ - void dump(Appendable out,String indent) throws IOException; -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/LifeCycle.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/LifeCycle.java deleted file mode 100644 index 85fe6503..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/component/LifeCycle.java +++ /dev/null @@ -1,107 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.component; - -import java.util.EventListener; - -/* ------------------------------------------------------------ */ -/** - * The lifecycle interface for generic components. - * <br /> - * Classes implementing this interface have a defined life cycle - * defined by the methods of this interface. - * - * - */ -public interface LifeCycle -{ - /* ------------------------------------------------------------ */ - /** - * Starts the component. - * @throws Exception If the component fails to start - * @see #isStarted() - * @see #stop() - * @see #isFailed() - */ - public void start() - throws Exception; - - /* ------------------------------------------------------------ */ - /** - * Stops the component. - * The component may wait for current activities to complete - * normally, but it can be interrupted. - * @exception Exception If the component fails to stop - * @see #isStopped() - * @see #start() - * @see #isFailed() - */ - public void stop() - throws Exception; - - /* ------------------------------------------------------------ */ - /** - * @return true if the component is starting or has been started. - */ - public boolean isRunning(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component has been started. - * @see #start() - * @see #isStarting() - */ - public boolean isStarted(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component is starting. - * @see #isStarted() - */ - public boolean isStarting(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component is stopping. - * @see #isStopped() - */ - public boolean isStopping(); - - /* ------------------------------------------------------------ */ - /** - * @return true if the component has been stopped. - * @see #stop() - * @see #isStopping() - */ - public boolean isStopped(); - - - /* ------------------------------------------------------------ */ - /** Listener. - * A listener for Lifecycle events. - */ - public interface Listener extends EventListener - { - public void lifeCycleStarting(LifeCycle event); - public void lifeCycleStarted(LifeCycle event); - public void lifeCycleFailure(LifeCycle event,Throwable cause); - public void lifeCycleStopping(LifeCycle event); - public void lifeCycleStopped(LifeCycle event); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/AndroidLogger.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/AndroidLogger.java deleted file mode 100644 index a04d21fe..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/AndroidLogger.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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. - */ -package org.eclipse.jetty.util.log; - -/** - * Logger for Android - * - * Copyright (c) 2015 KNOWLEDGECODE - */ -class AndroidLogger implements Logger { - - private String _tag; - - AndroidLogger() { - } - - private AndroidLogger(String tag) { - _tag = tag.substring(tag.length() > 23 ? tag.length() - 23 : 0); - } - - private static String format(String msg, Object... args) { - return String.format(msg.replaceAll("\\{\\}", "%s"), args); - } - - @Override - public String getName() { - return AndroidLogger.class.getName(); - } - - @Override - public void warn(String msg, Object... args) { - android.util.Log.w(_tag, format(msg, args)); - } - - @Override - public void warn(Throwable thrown) { - android.util.Log.w(_tag, thrown); - } - - @Override - public void warn(String msg, Throwable thrown) { - android.util.Log.w(_tag, msg, thrown); - } - - @Override - public void info(String msg, Object... args) { - android.util.Log.i(_tag, format(msg, args)); - } - - @Override - public void info(Throwable thrown) { - android.util.Log.i(_tag, "", thrown); - } - - @Override - public void info(String msg, Throwable thrown) { - android.util.Log.i(_tag, msg, thrown); - } - - @Override - public boolean isDebugEnabled() { - return android.util.Log.isLoggable(_tag, android.util.Log.DEBUG); - } - - @Override - public void setDebugEnabled(boolean enabled) { - throw new UnsupportedOperationException(); - } - - @Override - public void debug(String msg, Object... args) { - android.util.Log.d(_tag, format(msg, args)); - } - - @Override - public void debug(Throwable thrown) { - android.util.Log.d(_tag, "", thrown); - } - - @Override - public void debug(String msg, Throwable thrown) { - android.util.Log.d(_tag, msg, thrown); - } - - @Override - public Logger getLogger(String tag) { - return new AndroidLogger(tag); - } - - @Override - public void ignore(Throwable ignored) { - // ignore - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/Log.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/Log.java deleted file mode 100644 index 0549bab3..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/Log.java +++ /dev/null @@ -1,151 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -/** - * Logging. - * - * Modified by KNOWLEDGECODE - */ -public class Log -{ - public static final String EXCEPTION = "EXCEPTION "; - public static final String IGNORED = "IGNORED "; - - private static Logger LOG = new Logger() - { - @Override - public String getName() - { - return null; - } - - @Override - public void warn(String msg, Object... args) - { - } - - @Override - public void warn(Throwable thrown) - { - } - - @Override - public void warn(String msg, Throwable thrown) - { - } - - @Override - public void info(String msg, Object... args) - { - } - - @Override - public void info(Throwable thrown) - { - } - - @Override - public void info(String msg, Throwable thrown) - { - } - - @Override - public boolean isDebugEnabled() - { - return false; - } - - @Override - public void setDebugEnabled(boolean enabled) - { - } - - @Override - public void debug(String msg, Object... args) - { - } - - @Override - public void debug(Throwable thrown) - { - } - - @Override - public void debug(String msg, Throwable thrown) - { - } - - @Override - public Logger getLogger(String name) - { - return this; - } - - @Override - public void ignore(Throwable ignored) - { - } - }; - - static - { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - try - { - @SuppressWarnings("unchecked") - Class<Logger> clazz = (Class<Logger>) loader.loadClass("org.eclipse.jetty.util.log.AndroidLogger"); - LOG = clazz.newInstance(); - } - catch (ClassNotFoundException e) - { - } - catch (IllegalAccessException e) - { - } - catch (IllegalArgumentException e) - { - } - catch (InstantiationException e) - { - } - } - - /** - * Obtain a named Logger based on the fully qualified class name. - * - * @param clazz - * the class to base the Logger name off of - * @return the Logger with the given name - */ - public static Logger getLogger(Class<?> clazz) - { - return getLogger(clazz.getName()); - } - - /** - * Obtain a named Logger or the default Logger if null is passed. - * @param name the Logger name - * @return the Logger with the given name - */ - public static Logger getLogger(String name) - { - return LOG.getLogger(name); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/Logger.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/Logger.java deleted file mode 100644 index 40f70ff2..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/log/Logger.java +++ /dev/null @@ -1,113 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.log; - -/** - * A simple logging facade that is intended simply to capture the style of logging as used by Jetty. - */ -public interface Logger -{ - /** - * @return the name of this logger - */ - public String getName(); - - /** - * Formats and logs at warn level. - * @param msg the formatting string - * @param args the optional arguments - */ - public void warn(String msg, Object... args); - - /** - * Logs the given Throwable information at warn level - * @param thrown the Throwable to log - */ - public void warn(Throwable thrown); - - /** - * Logs the given message at warn level, with Throwable information. - * @param msg the message to log - * @param thrown the Throwable to log - */ - public void warn(String msg, Throwable thrown); - - /** - * Formats and logs at info level. - * @param msg the formatting string - * @param args the optional arguments - */ - public void info(String msg, Object... args); - - /** - * Logs the given Throwable information at info level - * @param thrown the Throwable to log - */ - public void info(Throwable thrown); - - /** - * Logs the given message at info level, with Throwable information. - * @param msg the message to log - * @param thrown the Throwable to log - */ - public void info(String msg, Throwable thrown); - - /** - * @return whether the debug level is enabled - */ - public boolean isDebugEnabled(); - - /** - * Mutator used to turn debug on programmatically. - * @param enabled whether to enable the debug level - */ - public void setDebugEnabled(boolean enabled); - - /** - * Formats and logs at debug level. - * @param msg the formatting string - * @param args the optional arguments - */ - public void debug(String msg, Object... args); - - /** - * Logs the given Throwable information at debug level - * @param thrown the Throwable to log - */ - public void debug(Throwable thrown); - - /** - * Logs the given message at debug level, with Throwable information. - * @param msg the message to log - * @param thrown the Throwable to log - */ - public void debug(String msg, Throwable thrown); - - /** - * @param name the name of the logger - * @return a logger with the given name - */ - public Logger getLogger(String name); - - /** - * Ignore an exception. - * <p>This should be used rather than an empty catch block. - */ - public void ignore(Throwable ignored); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/resource/Resource.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/resource/Resource.java deleted file mode 100644 index 90a3ba2f..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/resource/Resource.java +++ /dev/null @@ -1,119 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ------------------------------------------------------------ */ -/**g - * Abstract resource class. - */ -public abstract class Resource -{ - private static final Logger LOG = Log.getLogger(Resource.class); - public static boolean __defaultUseCaches = true; - volatile Object _associate; - - /* ------------------------------------------------------------ */ - /** Construct a resource from a url. - * @param url A URL. - * @return A Resource object. - * @throws IOException Problem accessing URL - */ - public static Resource newResource(URL url) - throws IOException - { - return newResource(url, __defaultUseCaches); - } - - /* ------------------------------------------------------------ */ - /** - * Construct a resource from a url. - * @param url the url for which to make the resource - * @param useCaches true enables URLConnection caching if applicable to the type of resource - * @return - */ - static Resource newResource(URL url, boolean useCaches) - { - if (url==null) - return null; - - return new URLResource(url,null,useCaches); - } - - /* ------------------------------------------------------------ */ - /** Construct a resource from a string. - * @param resource A URL or filename. - * @return A Resource object. - */ - public static Resource newResource(String resource) - throws MalformedURLException, IOException - { - return newResource(resource, __defaultUseCaches); - } - - /* ------------------------------------------------------------ */ - /** Construct a resource from a string. - * @param resource A URL or filename. - * @param useCaches controls URLConnection caching - * @return A Resource object. - */ - public static Resource newResource (String resource, boolean useCaches) - throws MalformedURLException, IOException - { - URL url=null; - try - { - // Try to format as a URL? - url = new URL(resource); - } - catch(MalformedURLException e) - { - LOG.warn("Bad Resource: "+resource); - throw e; - } - - return newResource(url); - } - - /* ------------------------------------------------------------ */ - @Override - protected void finalize() - { - release(); - } - - /* ------------------------------------------------------------ */ - /** Release any temporary resources held by the resource. - */ - public abstract void release(); - - /* ------------------------------------------------------------ */ - /** - * Returns an input stream to the resource - */ - public abstract InputStream getInputStream() - throws java.io.IOException; -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/resource/URLResource.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/resource/URLResource.java deleted file mode 100644 index 5de288ef..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/resource/URLResource.java +++ /dev/null @@ -1,130 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.resource; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.net.URLConnection; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ------------------------------------------------------------ */ -/** Abstract resource class. - */ -public class URLResource extends Resource -{ - private static final Logger LOG = Log.getLogger(URLResource.class); - protected URL _url; - protected String _urlString; - - protected URLConnection _connection; - protected InputStream _in=null; - transient boolean _useCaches = Resource.__defaultUseCaches; - - /* ------------------------------------------------------------ */ - protected URLResource(URL url, URLConnection connection) - { - _url = url; - _urlString=_url.toString(); - _connection=connection; - } - - /* ------------------------------------------------------------ */ - protected URLResource (URL url, URLConnection connection, boolean useCaches) - { - this (url, connection); - _useCaches = useCaches; - } - - /* ------------------------------------------------------------ */ - protected synchronized boolean checkConnection() - { - if (_connection==null) - { - try{ - _connection=_url.openConnection(); - _connection.setUseCaches(_useCaches); - } - catch(IOException e) - { - LOG.ignore(e); - } - } - return _connection!=null; - } - - /* ------------------------------------------------------------ */ - /** Release any resources held by the resource. - */ - @Override - public synchronized void release() - { - if (_in!=null) - { - try{_in.close();}catch(IOException e){LOG.ignore(e);} - _in=null; - } - - if (_connection!=null) - _connection=null; - } - - /* ------------------------------------------------------------ */ - /** - * Returns an input stream to the resource - */ - @Override - public synchronized InputStream getInputStream() - throws java.io.IOException - { - if (!checkConnection()) - throw new IOException( "Invalid resource"); - - try - { - if( _in != null) - { - InputStream in = _in; - _in=null; - return in; - } - return _connection.getInputStream(); - } - finally - { - _connection=null; - } - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return _urlString; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean equals( Object o) - { - return o instanceof URLResource && _urlString.equals(((URLResource)o)._urlString); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/CertificateUtils.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/CertificateUtils.java deleted file mode 100644 index 83828f95..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/CertificateUtils.java +++ /dev/null @@ -1,93 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.io.InputStream; -import java.security.KeyStore; -import java.security.cert.CRL; -import java.security.cert.CertificateFactory; -import java.util.Collection; - -import org.eclipse.jetty.util.resource.Resource; - -public class CertificateUtils -{ - /* ------------------------------------------------------------ */ - public static KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception - { - KeyStore keystore = null; - - if (storeStream != null || storePath != null) - { - InputStream inStream = storeStream; - try - { - if (inStream == null) - { - inStream = Resource.newResource(storePath).getInputStream(); - } - - if (storeProvider != null) - { - keystore = KeyStore.getInstance(storeType, storeProvider); - } - else - { - keystore = KeyStore.getInstance(storeType); - } - - keystore.load(inStream, storePassword == null ? null : storePassword.toCharArray()); - } - finally - { - if (inStream != null) - { - inStream.close(); - } - } - } - - return keystore; - } - - /* ------------------------------------------------------------ */ - public static Collection<? extends CRL> loadCRL(String crlPath) throws Exception - { - Collection<? extends CRL> crlList = null; - - if (crlPath != null) - { - InputStream in = null; - try - { - in = Resource.newResource(crlPath).getInputStream(); - crlList = CertificateFactory.getInstance("X.509").generateCRLs(in); - } - finally - { - if (in != null) - { - in.close(); - } - } - } - - return crlList; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/CertificateValidator.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/CertificateValidator.java deleted file mode 100644 index b018b83f..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/CertificateValidator.java +++ /dev/null @@ -1,228 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -import java.security.GeneralSecurityException; -import java.security.InvalidParameterException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.Security; -import java.security.cert.CRL; -import java.security.cert.CertPathBuilder; -import java.security.cert.CertPathBuilderResult; -import java.security.cert.CertPathValidator; -import java.security.cert.CertStore; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.X509CertSelector; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.atomic.AtomicLong; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * Convenience class to handle validation of certificates, aliases and keystores - * - * Allows specifying Certificate Revocation List (CRL), as well as enabling - * CRL Distribution Points Protocol (CRLDP) certificate extension support, - * and also enabling On-Line Certificate Status Protocol (OCSP) support. - * - * IMPORTANT: at least one of the above mechanisms *MUST* be configured and - * operational, otherwise certificate validation *WILL FAIL* unconditionally. - */ -public class CertificateValidator -{ - private static final Logger LOG = Log.getLogger(CertificateValidator.class); - private static AtomicLong __aliasCount = new AtomicLong(); - - private KeyStore _trustStore; - private Collection<? extends CRL> _crls; - - /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */ - private int _maxCertPathLength = -1; - /** CRL Distribution Points (CRLDP) support */ - private boolean _enableCRLDP = false; - /** On-Line Certificate Status Protocol (OCSP) support */ - private boolean _enableOCSP = false; - - /** - * creates an instance of the certificate validator - * - * @param trustStore - * @param crls - */ - public CertificateValidator(KeyStore trustStore, Collection<? extends CRL> crls) - { - if (trustStore == null) - { - throw new InvalidParameterException("TrustStore must be specified for CertificateValidator."); - } - - _trustStore = trustStore; - _crls = crls; - } - - /** - * validates a specific certificate inside of the keystore being passed in - * - * @param keyStore - * @param cert - * @throws CertificateException - */ - public void validate(KeyStore keyStore, Certificate cert) throws CertificateException - { - Certificate[] certChain = null; - - if (cert != null && cert instanceof X509Certificate) - { - ((X509Certificate)cert).checkValidity(); - - String certAlias = null; - try - { - if (keyStore == null) - { - throw new InvalidParameterException("Keystore cannot be null"); - } - - certAlias = keyStore.getCertificateAlias((X509Certificate)cert); - if (certAlias == null) - { - certAlias = "JETTY" + String.format("%016X",__aliasCount.incrementAndGet()); - keyStore.setCertificateEntry(certAlias, cert); - } - - certChain = keyStore.getCertificateChain(certAlias); - if (certChain == null || certChain.length == 0) - { - throw new IllegalStateException("Unable to retrieve certificate chain"); - } - } - catch (KeyStoreException kse) - { - LOG.debug(kse); - throw new CertificateException("Unable to validate certificate" + - (certAlias == null ? "":" for alias [" +certAlias + "]") + ": " + kse.getMessage(), kse); - } - - validate(certChain); - } - } - - public void validate(Certificate[] certChain) throws CertificateException - { - try - { - ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(); - for (Certificate item : certChain) - { - if (item == null) - continue; - - if (!(item instanceof X509Certificate)) - { - throw new IllegalStateException("Invalid certificate type in chain"); - } - - certList.add((X509Certificate)item); - } - - if (certList.isEmpty()) - { - throw new IllegalStateException("Invalid certificate chain"); - - } - - X509CertSelector certSelect = new X509CertSelector(); - certSelect.setCertificate(certList.get(0)); - - // Configure certification path builder parameters - PKIXBuilderParameters pbParams = new PKIXBuilderParameters(_trustStore, certSelect); - pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList))); - - // Set maximum certification path length - pbParams.setMaxPathLength(_maxCertPathLength); - - // Enable revocation checking - pbParams.setRevocationEnabled(true); - - // Set static Certificate Revocation List - if (_crls != null && !_crls.isEmpty()) - { - pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls))); - } - - // Enable On-Line Certificate Status Protocol (OCSP) support - if (_enableOCSP) - { - Security.setProperty("ocsp.enable","true"); - } - // Enable Certificate Revocation List Distribution Points (CRLDP) support - if (_enableCRLDP) - { - System.setProperty("com.sun.security.enableCRLDP","true"); - } - - // Build certification path - CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams); - - // Validate certification path - CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams); - } - catch (GeneralSecurityException gse) - { - LOG.debug(gse); - throw new CertificateException("Unable to validate certificate: " + gse.getMessage(), gse); - } - } - - /* ------------------------------------------------------------ */ - /** - * @param maxCertPathLength - * maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public void setMaxCertPathLength(int maxCertPathLength) - { - _maxCertPathLength = maxCertPathLength; - } - - /* ------------------------------------------------------------ */ - /** Enables CRL Distribution Points Support - * @param enableCRLDP true - turn on, false - turns off - */ - public void setEnableCRLDP(boolean enableCRLDP) - { - _enableCRLDP = enableCRLDP; - } - - /* ------------------------------------------------------------ */ - /** Enables On-Line Certificate Status Protocol support - * @param enableOCSP true - turn on, false - turn off - */ - public void setEnableOCSP(boolean enableOCSP) - { - _enableOCSP = enableOCSP; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/Password.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/Password.java deleted file mode 100644 index 255eee60..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/security/Password.java +++ /dev/null @@ -1,84 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.security; - -/* ------------------------------------------------------------ */ -/** - * Password utility class. - * - * This utility class gets a password or pass phrase either by: - * - * <PRE> - * + Password is set as a system property. - * + The password is prompted for and read from standard input - * + A program is run to get the password. - * </pre> - * - * Passwords that begin with OBF: are de obfuscated. Passwords can be obfuscated - * by run org.eclipse.util.Password as a main class. Obfuscated password are - * required if a system needs to recover the full password (eg. so that it may - * be passed to another system). They are not secure, but prevent casual - * observation. - * <p> - * Passwords that begin with CRYPT: are oneway encrypted with UnixCrypt. The - * real password cannot be retrieved, but comparisons can be made to other - * passwords. A Crypt can be generated by running org.eclipse.util.UnixCrypt as - * a main class, passing password and then the username. Checksum passwords are - * a secure(ish) way to store passwords that only need to be checked rather than - * recovered. Note that it is not strong security - specially if simple - * passwords are used. - * - * - */ -public class Password -{ - public static final String __OBFUSCATE = "OBF:"; - - private String _pw; - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return _pw; - } - - /* ------------------------------------------------------------ */ - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - - if (null == o) - return false; - - if (o instanceof Password) - { - Password p = (Password) o; - //noinspection StringEquality - return p._pw == _pw || (null != _pw && _pw.equals(p._pw)); - } - - if (o instanceof String) - return o.equals(_pw); - - return false; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java deleted file mode 100644 index 4c0da301..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java +++ /dev/null @@ -1,107 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.ssl; - -import java.net.Socket; -import java.security.Principal; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; - -import javax.net.ssl.X509ExtendedKeyManager; -import javax.net.ssl.X509KeyManager; - - -/* ------------------------------------------------------------ */ -/** - * KeyManager to select a key with desired alias - * while delegating processing to specified KeyManager - * Can be used both with server and client sockets - */ -public class AliasedX509ExtendedKeyManager extends X509ExtendedKeyManager -{ - private String _keyAlias; - private X509KeyManager _keyManager; - - /* ------------------------------------------------------------ */ - /** - * Construct KeyManager instance - * @param keyAlias Alias of the key to be selected - * @param keyManager Instance of KeyManager to be wrapped - * @throws Exception - */ - public AliasedX509ExtendedKeyManager(String keyAlias, X509KeyManager keyManager) throws Exception - { - _keyAlias = keyAlias; - _keyManager = keyManager; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#chooseClientAlias(java.lang.String[], java.security.Principal[], java.net.Socket) - */ - public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) - { - return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#chooseServerAlias(java.lang.String, java.security.Principal[], java.net.Socket) - */ - public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) - { - return _keyAlias == null ? _keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias; - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getClientAliases(java.lang.String, java.security.Principal[]) - */ - public String[] getClientAliases(String keyType, Principal[] issuers) - { - return _keyManager.getClientAliases(keyType, issuers); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getServerAliases(java.lang.String, java.security.Principal[]) - */ - public String[] getServerAliases(String keyType, Principal[] issuers) - { - return _keyManager.getServerAliases(keyType, issuers); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getCertificateChain(java.lang.String) - */ - public X509Certificate[] getCertificateChain(String alias) - { - return _keyManager.getCertificateChain(alias); - } - - /* ------------------------------------------------------------ */ - /** - * @see javax.net.ssl.X509KeyManager#getPrivateKey(java.lang.String) - */ - public PrivateKey getPrivateKey(String alias) - { - return _keyManager.getPrivateKey(alias); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ssl/SslContextFactory.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ssl/SslContextFactory.java deleted file mode 100644 index 4ac6ed95..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ /dev/null @@ -1,620 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.ssl; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.InputStream; -import java.security.KeyStore; -import java.security.SecureRandom; -import java.security.Security; -import java.security.cert.CRL; -import java.security.cert.CertStore; -import java.security.cert.Certificate; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.X509CertSelector; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import javax.net.ssl.CertPathTrustManagerParameters; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509KeyManager; -import javax.net.ssl.X509TrustManager; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.security.CertificateUtils; -import org.eclipse.jetty.util.security.CertificateValidator; -import org.eclipse.jetty.util.security.Password; - -import android.annotation.SuppressLint; -import android.os.Build; - - -/* ------------------------------------------------------------ */ -/** - * SslContextFactory is used to configure SSL connectors - * as well as HttpClient. It holds all SSL parameters and - * creates SSL context based on these parameters to be - * used by the SSL connectors. - * - * modified by KNOWLEDGECODE - */ -public class SslContextFactory extends AbstractLifeCycle -{ - public final static TrustManager[] TRUST_ALL_CERTS = new X509TrustManager[]{new X509TrustManager() - { - public java.security.cert.X509Certificate[] getAcceptedIssuers() - { - return new java.security.cert.X509Certificate[]{}; - } - - public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) - { - } - - public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) - { - /** - * workaround for SSL bugs in 4.0.3 and lower - * @see https://github.com/koush/AndroidAsync/blob/master/AndroidAsync/src/com/koushikdutta/async/AsyncSSLSocketWrapper.java - */ - if (Build.VERSION.SDK_INT <= 15) - { - for (java.security.cert.X509Certificate cert : certs) - { - if (cert != null && cert.getCriticalExtensionOIDs() != null) - { - cert.getCriticalExtensionOIDs().remove("2.5.29.15"); - } - } - } - } - }}; - - private static final Logger LOG = Log.getLogger(SslContextFactory.class); - - public static final String DEFAULT_KEYMANAGERFACTORY_ALGORITHM = - (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ? - "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm")); - public static final String DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM = - (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ? - "SunX509" : Security.getProperty("ssl.TrustManagerFactory.algorithm")); - - /** Default value for the keystore location path. */ - public static final String DEFAULT_KEYSTORE_PATH = - System.getProperty("user.home") + File.separator + ".keystore"; - - /** String name of key password property. */ - public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword"; - - /** String name of keystore password property. */ - public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password"; - - /** Excluded protocols. */ - private final Set<String> _excludeProtocols = new LinkedHashSet<String>(); - /** Included protocols. */ - private Set<String> _includeProtocols = new LinkedHashSet<String>(); - - /** Excluded cipher suites. */ - private final Set<String> _excludeCipherSuites = new LinkedHashSet<String>(); - /** Included cipher suites. */ - private Set<String> _includeCipherSuites = new LinkedHashSet<String>(); - - /** Keystore path. */ - private String _keyStorePath; - /** Keystore provider name */ - private String _keyStoreProvider; - /** Keystore type */ - private String _keyStoreType = "JKS"; - /** Keystore input stream */ - private InputStream _keyStoreInputStream; - - /** SSL certificate alias */ - private String _certAlias; - - /** Truststore path */ - private String _trustStorePath; - /** Truststore provider name */ - private String _trustStoreProvider; - /** Truststore type */ - private String _trustStoreType = "JKS"; - /** Truststore input stream */ - private InputStream _trustStoreInputStream; - - /** Set to true if client certificate authentication is required */ - private boolean _needClientAuth = false; - /** Set to true if client certificate authentication is desired */ - private boolean _wantClientAuth = false; - - /** Keystore password */ - private transient Password _keyStorePassword; - /** Key manager password */ - private transient Password _keyManagerPassword; - /** Truststore password */ - private transient Password _trustStorePassword; - - /** SSL provider name */ - private String _sslProvider; - /** SSL protocol name */ - private String _sslProtocol = "TLS"; - - /** SecureRandom algorithm */ - private String _secureRandomAlgorithm; - /** KeyManager factory algorithm */ - private String _keyManagerFactoryAlgorithm = DEFAULT_KEYMANAGERFACTORY_ALGORITHM; - /** TrustManager factory algorithm */ - private String _trustManagerFactoryAlgorithm = DEFAULT_TRUSTMANAGERFACTORY_ALGORITHM; - - /** Set to true if SSL certificate validation is required */ - private boolean _validateCerts; - /** Set to true if SSL certificate of the peer validation is required */ - private boolean _validatePeerCerts; - /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */ - private int _maxCertPathLength = -1; - /** Path to file that contains Certificate Revocation List */ - private String _crlPath; - /** Set to true to enable CRL Distribution Points (CRLDP) support */ - private boolean _enableCRLDP = false; - /** Set to true to enable On-Line Certificate Status Protocol (OCSP) support */ - private boolean _enableOCSP = false; - /** Location of OCSP Responder */ - private String _ocspResponderURL; - - /** SSL keystore */ - private KeyStore _keyStore; - /** SSL truststore */ - private KeyStore _trustStore; - /** Set to true to enable SSL Session caching */ - private boolean _sessionCachingEnabled = true; - - /** SSL context */ - private SSLContext _context; - - private boolean _trustAll; - - /* ------------------------------------------------------------ */ - /** - * Construct an instance of SslContextFactory - * Default constructor for use in XmlConfiguration files - */ - public SslContextFactory() - { - _trustAll=true; - } - - /* ------------------------------------------------------------ */ - /** - * Create the SSLContext object and start the lifecycle - * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() - */ - @SuppressLint("TrulyRandom") - @Override - protected void doStart() throws Exception - { - if (_context == null) - { - if (_keyStore==null && _keyStoreInputStream == null && _keyStorePath == null && - _trustStore==null && _trustStoreInputStream == null && _trustStorePath == null ) - { - TrustManager[] trust_managers=null; - - if (_trustAll) - { - LOG.debug("No keystore or trust store configured. ACCEPTING UNTRUSTED CERTIFICATES!!!!!"); - // Create a trust manager that does not validate certificate chains - trust_managers = TRUST_ALL_CERTS; - } - - SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm); - _context = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider); - _context.init(null, trust_managers, secureRandom); - } - else - { - // verify that keystore and truststore - // parameters are set up correctly - checkKeyStore(); - - KeyStore keyStore = loadKeyStore(); - KeyStore trustStore = loadTrustStore(); - - Collection<? extends CRL> crls = loadCRL(_crlPath); - - if (_validateCerts && keyStore != null) - { - if (_certAlias == null) - { - List<String> aliases = Collections.list(keyStore.aliases()); - _certAlias = aliases.size() == 1 ? aliases.get(0) : null; - } - - Certificate cert = _certAlias == null?null:keyStore.getCertificate(_certAlias); - if (cert == null) - { - throw new Exception("No certificate found in the keystore" + (_certAlias==null ? "":" for alias " + _certAlias)); - } - - CertificateValidator validator = new CertificateValidator(trustStore, crls); - validator.setMaxCertPathLength(_maxCertPathLength); - validator.setEnableCRLDP(_enableCRLDP); - validator.setEnableOCSP(_enableOCSP); - validator.validate(keyStore, cert); - } - - KeyManager[] keyManagers = getKeyManagers(keyStore); - TrustManager[] trustManagers = getTrustManagers(trustStore,crls); - - SecureRandom secureRandom = (_secureRandomAlgorithm == null)?null:SecureRandom.getInstance(_secureRandomAlgorithm); - _context = (_sslProvider == null)?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider); - _context.init(keyManagers,trustManagers,secureRandom); - - SSLEngine engine=newSslEngine(); - - LOG.info("Enabled Protocols {} of {}",Arrays.asList(engine.getEnabledProtocols()),Arrays.asList(engine.getSupportedProtocols())); - if (LOG.isDebugEnabled()) - LOG.debug("Enabled Ciphers {} of {}",Arrays.asList(engine.getEnabledCipherSuites()),Arrays.asList(engine.getSupportedCipherSuites())); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @return True if SSL needs client authentication. - * @see SSLEngine#getNeedClientAuth() - */ - public boolean getNeedClientAuth() - { - return _needClientAuth; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if SSL wants client authentication. - * @see SSLEngine#getWantClientAuth() - */ - public boolean getWantClientAuth() - { - return _wantClientAuth; - } - - /* ------------------------------------------------------------ */ - /** - * Override this method to provide alternate way to load a keystore. - * - * @return the key store instance - * @throws Exception if the keystore cannot be loaded - */ - protected KeyStore loadKeyStore() throws Exception - { - return _keyStore != null ? _keyStore : getKeyStore(_keyStoreInputStream, - _keyStorePath, _keyStoreType, _keyStoreProvider, - _keyStorePassword==null? null: _keyStorePassword.toString()); - } - - /* ------------------------------------------------------------ */ - /** - * Override this method to provide alternate way to load a truststore. - * - * @return the key store instance - * @throws Exception if the truststore cannot be loaded - */ - protected KeyStore loadTrustStore() throws Exception - { - return _trustStore != null ? _trustStore : getKeyStore(_trustStoreInputStream, - _trustStorePath, _trustStoreType, _trustStoreProvider, - _trustStorePassword==null? null: _trustStorePassword.toString()); - } - - /* ------------------------------------------------------------ */ - /** - * Loads keystore using an input stream or a file path in the same - * order of precedence. - * - * Required for integrations to be able to override the mechanism - * used to load a keystore in order to provide their own implementation. - * - * @param storeStream keystore input stream - * @param storePath path of keystore file - * @param storeType keystore type - * @param storeProvider keystore provider - * @param storePassword keystore password - * @return created keystore - * @throws Exception if the keystore cannot be obtained - */ - protected KeyStore getKeyStore(InputStream storeStream, String storePath, String storeType, String storeProvider, String storePassword) throws Exception - { - return CertificateUtils.getKeyStore(storeStream, storePath, storeType, storeProvider, storePassword); - } - - /* ------------------------------------------------------------ */ - /** - * Loads certificate revocation list (CRL) from a file. - * - * Required for integrations to be able to override the mechanism used to - * load CRL in order to provide their own implementation. - * - * @param crlPath path of certificate revocation list file - * @return Collection of CRL's - * @throws Exception if the certificate revocation list cannot be loaded - */ - protected Collection<? extends CRL> loadCRL(String crlPath) throws Exception - { - return CertificateUtils.loadCRL(crlPath); - } - - /* ------------------------------------------------------------ */ - protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception - { - KeyManager[] managers = null; - - if (keyStore != null) - { - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(_keyManagerFactoryAlgorithm); - keyManagerFactory.init(keyStore,_keyManagerPassword == null?(_keyStorePassword == null?null:_keyStorePassword.toString().toCharArray()):_keyManagerPassword.toString().toCharArray()); - managers = keyManagerFactory.getKeyManagers(); - - if (_certAlias != null) - { - for (int idx = 0; idx < managers.length; idx++) - { - if (managers[idx] instanceof X509KeyManager) - { - managers[idx] = new AliasedX509ExtendedKeyManager(_certAlias,(X509KeyManager)managers[idx]); - } - } - } - } - - return managers; - } - - /* ------------------------------------------------------------ */ - protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception - { - TrustManager[] managers = null; - if (trustStore != null) - { - // Revocation checking is only supported for PKIX algorithm - if (_validatePeerCerts && _trustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX")) - { - PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore,new X509CertSelector()); - - // Set maximum certification path length - pbParams.setMaxPathLength(_maxCertPathLength); - - // Make sure revocation checking is enabled - pbParams.setRevocationEnabled(true); - - if (crls != null && !crls.isEmpty()) - { - pbParams.addCertStore(CertStore.getInstance("Collection",new CollectionCertStoreParameters(crls))); - } - - if (_enableCRLDP) - { - // Enable Certificate Revocation List Distribution Points (CRLDP) support - System.setProperty("com.sun.security.enableCRLDP","true"); - } - - if (_enableOCSP) - { - // Enable On-Line Certificate Status Protocol (OCSP) support - Security.setProperty("ocsp.enable","true"); - - if (_ocspResponderURL != null) - { - // Override location of OCSP Responder - Security.setProperty("ocsp.responderURL", _ocspResponderURL); - } - } - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm); - trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams)); - - managers = trustManagerFactory.getTrustManagers(); - } - else - { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_trustManagerFactoryAlgorithm); - trustManagerFactory.init(trustStore); - - managers = trustManagerFactory.getTrustManagers(); - } - } - - return managers; - } - - /* ------------------------------------------------------------ */ - /** - * Check KeyStore Configuration. Ensures that if keystore has been - * configured but there's no truststore, that keystore is - * used as truststore. - * @throws IllegalStateException if SslContextFactory configuration can't be used. - */ - public void checkKeyStore() - { - if (_context != null) - return; //nothing to check if using preconfigured context - - - if (_keyStore == null && _keyStoreInputStream == null && _keyStorePath == null) - throw new IllegalStateException("SSL doesn't have a valid keystore"); - - // if the keystore has been configured but there is no - // truststore configured, use the keystore as the truststore - if (_trustStore == null && _trustStoreInputStream == null && _trustStorePath == null) - { - _trustStore = _keyStore; - _trustStorePath = _keyStorePath; - _trustStoreInputStream = _keyStoreInputStream; - _trustStoreType = _keyStoreType; - _trustStoreProvider = _keyStoreProvider; - _trustStorePassword = _keyStorePassword; - _trustManagerFactoryAlgorithm = _keyManagerFactoryAlgorithm; - } - - // It's the same stream we cannot read it twice, so read it once in memory - if (_keyStoreInputStream != null && _keyStoreInputStream == _trustStoreInputStream) - { - try - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - IO.copy(_keyStoreInputStream, baos); - _keyStoreInputStream.close(); - - _keyStoreInputStream = new ByteArrayInputStream(baos.toByteArray()); - _trustStoreInputStream = new ByteArrayInputStream(baos.toByteArray()); - } - catch (Exception ex) - { - throw new IllegalStateException(ex); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Select protocols to be used by the connector - * based on configured inclusion and exclusion lists - * as well as enabled and supported protocols. - * @param enabledProtocols Array of enabled protocols - * @param supportedProtocols Array of supported protocols - * @return Array of protocols to enable - */ - public String[] selectProtocols(String[] enabledProtocols, String[] supportedProtocols) - { - Set<String> selected_protocols = new LinkedHashSet<String>(); - - // Set the starting protocols - either from the included or enabled list - if (!_includeProtocols.isEmpty()) - { - // Use only the supported included protocols - for (String protocol : _includeProtocols) - if(Arrays.asList(supportedProtocols).contains(protocol)) - selected_protocols.add(protocol); - } - else - selected_protocols.addAll(Arrays.asList(enabledProtocols)); - - - // Remove any excluded protocols - if (_excludeProtocols != null) - selected_protocols.removeAll(_excludeProtocols); - - return selected_protocols.toArray(new String[selected_protocols.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * Select cipher suites to be used by the connector - * based on configured inclusion and exclusion lists - * as well as enabled and supported cipher suite lists. - * @param enabledCipherSuites Array of enabled cipher suites - * @param supportedCipherSuites Array of supported cipher suites - * @return Array of cipher suites to enable - */ - public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites) - { - Set<String> selected_ciphers = new LinkedHashSet<String>(); - - // Set the starting ciphers - either from the included or enabled list - if (!_includeCipherSuites.isEmpty()) - { - // Use only the supported included ciphers - for (String cipherSuite : _includeCipherSuites) - if(Arrays.asList(supportedCipherSuites).contains(cipherSuite)) - selected_ciphers.add(cipherSuite); - } - else - selected_ciphers.addAll(Arrays.asList(enabledCipherSuites)); - - - // Remove any excluded ciphers - if (_excludeCipherSuites != null) - selected_ciphers.removeAll(_excludeCipherSuites); - return selected_ciphers.toArray(new String[selected_ciphers.size()]); - } - - /* ------------------------------------------------------------ */ - /** - * @return true if SSL Session caching is enabled - */ - public boolean isSessionCachingEnabled() - { - return _sessionCachingEnabled; - } - - /* ------------------------------------------------------------ */ - public SSLEngine newSslEngine(String host,int port) - { - SSLEngine sslEngine=isSessionCachingEnabled() - ?_context.createSSLEngine(host, port) - :_context.createSSLEngine(); - - customize(sslEngine); - return sslEngine; - } - - /* ------------------------------------------------------------ */ - public SSLEngine newSslEngine() - { - SSLEngine sslEngine=_context.createSSLEngine(); - customize(sslEngine); - return sslEngine; - } - - /* ------------------------------------------------------------ */ - public void customize(SSLEngine sslEngine) - { - if (getWantClientAuth()) - sslEngine.setWantClientAuth(getWantClientAuth()); - if (getNeedClientAuth()) - sslEngine.setNeedClientAuth(getNeedClientAuth()); - - sslEngine.setEnabledCipherSuites(selectCipherSuites( - sslEngine.getEnabledCipherSuites(), - sslEngine.getSupportedCipherSuites())); - - sslEngine.setEnabledProtocols(selectProtocols(sslEngine.getEnabledProtocols(),sslEngine.getSupportedProtocols())); - } - - /* ------------------------------------------------------------ */ - public String toString() - { - return String.format("%s@%x(%s,%s)", - getClass().getSimpleName(), - hashCode(), - _keyStorePath, - _trustStorePath); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/QueuedThreadPool.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/QueuedThreadPool.java deleted file mode 100644 index 28cf3bd4..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/QueuedThreadPool.java +++ /dev/null @@ -1,385 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - - -package org.eclipse.jetty.util.thread; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Executor; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import org.eclipse.jetty.util.BlockingArrayQueue; -import org.eclipse.jetty.util.ConcurrentHashSet; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.component.Dumpable; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, Executor, Dumpable -{ - private static final Logger LOG = Log.getLogger(QueuedThreadPool.class); - - private final AtomicInteger _threadsStarted = new AtomicInteger(); - private final AtomicInteger _threadsIdle = new AtomicInteger(); - private final AtomicLong _lastShrink = new AtomicLong(); - private final ConcurrentHashSet<Thread> _threads=new ConcurrentHashSet<Thread>(); - private final Object _joinLock = new Object(); - private BlockingQueue<Runnable> _jobs; - private String _name; - private int _maxIdleTimeMs=60000; - private int _maxThreads=254; - private int _minThreads=8; - private int _maxQueued=-1; - private int _priority=Thread.NORM_PRIORITY; - private boolean _daemon=false; - private int _maxStopTime=100; - private boolean _detailedDump=false; - - /* ------------------------------------------------------------------- */ - /** Construct - */ - public QueuedThreadPool() - { - _name="qtp"+super.hashCode(); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - super.doStart(); - _threadsStarted.set(0); - - if (_jobs==null) - { - _jobs=_maxQueued>0 ?new ArrayBlockingQueue<Runnable>(_maxQueued) - :new BlockingArrayQueue<Runnable>(_minThreads,_minThreads); - } - - int threads=_threadsStarted.get(); - while (isRunning() && threads<_minThreads) - { - startThread(threads); - threads=_threadsStarted.get(); - } - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - long start=System.currentTimeMillis(); - - // let jobs complete naturally for a while - while (_threadsStarted.get()>0 && (System.currentTimeMillis()-start) < (_maxStopTime/2)) - Thread.sleep(1); - - // kill queued jobs and flush out idle jobs - _jobs.clear(); - Runnable noop = new Runnable(){public void run(){}}; - for (int i=_threadsIdle.get();i-->0;) - _jobs.offer(noop); - Thread.yield(); - - // interrupt remaining threads - if (_threadsStarted.get()>0) - for (Thread thread : _threads) - thread.interrupt(); - - // wait for remaining threads to die - while (_threadsStarted.get()>0 && (System.currentTimeMillis()-start) < _maxStopTime) - { - Thread.sleep(1); - } - Thread.yield(); - int size=_threads.size(); - if (size>0) - { - LOG.warn(size+" threads could not be stopped"); - - if (size==1 || LOG.isDebugEnabled()) - { - for (Thread unstopped : _threads) - { - LOG.info("Couldn't stop "+unstopped); - for (StackTraceElement element : unstopped.getStackTrace()) - { - LOG.info(" at "+element); - } - } - } - } - - synchronized (_joinLock) - { - _joinLock.notifyAll(); - } - } - - /* ------------------------------------------------------------ */ - /** Set the maximum number of threads. - * Delegated to the named or anonymous Pool. - * @see #setMaxThreads - * @return maximum number of threads. - */ - public int getMaxThreads() - { - return _maxThreads; - } - - /* ------------------------------------------------------------ */ - /** Get the minimum number of threads. - * Delegated to the named or anonymous Pool. - * @see #setMinThreads - * @return minimum number of threads. - */ - public int getMinThreads() - { - return _minThreads; - } - - /* ------------------------------------------------------------ */ - public boolean dispatch(Runnable job) - { - if (isRunning()) - { - final int jobQ = _jobs.size(); - final int idle = getIdleThreads(); - if(_jobs.offer(job)) - { - // If we had no idle threads or the jobQ is greater than the idle threads - if (idle==0 || jobQ>idle) - { - int threads=_threadsStarted.get(); - if (threads<_maxThreads) - startThread(threads); - } - return true; - } - } - LOG.debug("Dispatched {} to stopped {}",job,this); - return false; - } - - /* ------------------------------------------------------------ */ - public void execute(Runnable job) - { - if (!dispatch(job)) - throw new RejectedExecutionException(); - } - - /* ------------------------------------------------------------ */ - /** - * @return The total number of threads currently in the pool - */ - public int getThreads() - { - return _threadsStarted.get(); - } - - /* ------------------------------------------------------------ */ - /** - * @return The number of idle threads in the pool - */ - public int getIdleThreads() - { - return _threadsIdle.get(); - } - - /* ------------------------------------------------------------ */ - private boolean startThread(int threads) - { - final int next=threads+1; - if (!_threadsStarted.compareAndSet(threads,next)) - return false; - - boolean started=false; - try - { - Thread thread=newThread(_runnable); - thread.setDaemon(_daemon); - thread.setPriority(_priority); - thread.setName(_name+"-"+thread.getId()); - _threads.add(thread); - - thread.start(); - started=true; - } - finally - { - if (!started) - _threadsStarted.decrementAndGet(); - } - return started; - } - - /* ------------------------------------------------------------ */ - protected Thread newThread(Runnable runnable) - { - return new Thread(runnable); - } - - /* ------------------------------------------------------------ */ - public void dump(Appendable out, String indent) throws IOException - { - List<Object> dump = new ArrayList<Object>(getMaxThreads()); - for (final Thread thread: _threads) - { - final StackTraceElement[] trace=thread.getStackTrace(); - boolean inIdleJobPoll=false; - // trace can be null on early java 6 jvms - if (trace != null) - { - for (StackTraceElement t : trace) - { - if ("idleJobPoll".equals(t.getMethodName())) - { - inIdleJobPoll = true; - break; - } - } - } - final boolean idle=inIdleJobPoll; - - if (_detailedDump) - { - dump.add(new Dumpable() - { - public void dump(Appendable out, String indent) throws IOException - { - out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle?" IDLE":"").append('\n'); - if (!idle) - AggregateLifeCycle.dump(out,indent,Arrays.asList(trace)); - } - }); - } - else - { - dump.add(thread.getId()+" "+thread.getName()+" "+thread.getState()+" @ "+(trace.length>0?trace[0]:"???")+(idle?" IDLE":"")); - } - } - - AggregateLifeCycle.dumpObject(out,this); - AggregateLifeCycle.dump(out,indent,dump); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}"; - } - - /* ------------------------------------------------------------ */ - private Runnable idleJobPoll() throws InterruptedException - { - return _jobs.poll(_maxIdleTimeMs,TimeUnit.MILLISECONDS); - } - - /* ------------------------------------------------------------ */ - private Runnable _runnable = new Runnable() - { - public void run() - { - boolean shrink=false; - try - { - Runnable job=_jobs.poll(); - while (isRunning()) - { - // Job loop - while (job!=null && isRunning()) - { - runJob(job); - job=_jobs.poll(); - } - - // Idle loop - try - { - _threadsIdle.incrementAndGet(); - - while (isRunning() && job==null) - { - if (_maxIdleTimeMs<=0) - job=_jobs.take(); - else - { - // maybe we should shrink? - final int size=_threadsStarted.get(); - if (size>_minThreads) - { - long last=_lastShrink.get(); - long now=System.currentTimeMillis(); - if (last==0 || (now-last)>_maxIdleTimeMs) - { - shrink=_lastShrink.compareAndSet(last,now) && - _threadsStarted.compareAndSet(size,size-1); - if (shrink) - return; - } - } - job=idleJobPoll(); - } - } - } - finally - { - _threadsIdle.decrementAndGet(); - } - } - } - catch(InterruptedException e) - { - LOG.ignore(e); - } - catch(Exception e) - { - LOG.warn(e); - } - finally - { - if (!shrink) - _threadsStarted.decrementAndGet(); - _threads.remove(Thread.currentThread()); - } - } - }; - - /* ------------------------------------------------------------ */ - /** - * <p>Runs the given job in the {@link Thread#currentThread() current thread}.</p> - * <p>Subclasses may override to perform pre/post actions before/after the job is run.</p> - * - * @param job the job to run - */ - protected void runJob(Runnable job) - { - job.run(); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/ThreadPool.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/ThreadPool.java deleted file mode 100644 index 4bff2682..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/ThreadPool.java +++ /dev/null @@ -1,42 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.thread; - -/* ------------------------------------------------------------ */ -/** ThreadPool. - * - * - */ -public interface ThreadPool -{ - /* ------------------------------------------------------------ */ - public abstract boolean dispatch(Runnable job); - - /* ------------------------------------------------------------ */ - /** - * @return The total number of threads currently in the pool - */ - public int getThreads(); - - /* ------------------------------------------------------------ */ - /** - * @return The number of idle threads in the pool - */ - public int getIdleThreads(); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/Timeout.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/Timeout.java deleted file mode 100644 index d8086531..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/util/thread/Timeout.java +++ /dev/null @@ -1,282 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.util.thread; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** Timeout queue. - * This class implements a timeout queue for timers that are at least as likely to be cancelled as they are to expire. - * Unlike the util timeout class, the duration of the timeouts is shared by all scheduled tasks and if the duration - * is changed, this affects all scheduled tasks. - * <p> - * The nested class Task should be extended by users of this class to obtain call back notification of - * expires. - */ -public class Timeout -{ - private static final Logger LOG = Log.getLogger(Timeout.class); - private Object _lock; - private long _duration; - private volatile long _now=System.currentTimeMillis(); - private Task _head=new Task(); - - /* ------------------------------------------------------------ */ - public Timeout(Object lock) - { - _lock=lock; - _head._timeout=this; - } - - /* ------------------------------------------------------------ */ - /** - * @param duration The duration to set. - */ - public void setDuration(long duration) - { - _duration = duration; - } - - /* ------------------------------------------------------------ */ - public long getNow() - { - return _now; - } - - /* ------------------------------------------------------------ */ - public void setNow(long now) - { - _now=now; - } - - /* ------------------------------------------------------------ */ - /** Get an expired tasks. - * This is called instead of {@link #tick()} to obtain the next - * expired Task, but without calling it's {@link Task#expire()} or - * {@link Task#expired()} methods. - * - * @return the next expired task or null. - */ - public Task expired() - { - synchronized (_lock) - { - long _expiry = _now-_duration; - - if (_head._next!=_head) - { - Task task = _head._next; - if (task._timestamp>_expiry) - return null; - - task.unlink(); - task._expired=true; - return task; - } - return null; - } - } - - /* ------------------------------------------------------------ */ - public void tick() - { - final long expiry = _now-_duration; - - Task task=null; - while (true) - { - try - { - synchronized (_lock) - { - task= _head._next; - if (task==_head || task._timestamp>expiry) - break; - task.unlink(); - task._expired=true; - task.expire(); - } - - task.expired(); - } - catch(Throwable th) - { - LOG.warn(Log.EXCEPTION,th); - } - } - } - - /* ------------------------------------------------------------ */ - public void schedule(Task task) - { - schedule(task,0L); - } - - /* ------------------------------------------------------------ */ - /** - * @param task - * @param delay A delay in addition to the default duration of the timeout - */ - public void schedule(Task task,long delay) - { - synchronized (_lock) - { - if (task._timestamp!=0) - { - task.unlink(); - task._timestamp=0; - } - task._timeout=this; - task._expired=false; - task._delay=delay; - task._timestamp = _now+delay; - - Task last=_head._prev; - while (last!=_head) - { - if (last._timestamp <= task._timestamp) - break; - last=last._prev; - } - last.link(task); - } - } - - /* ------------------------------------------------------------ */ - public void cancelAll() - { - synchronized (_lock) - { - _head._next=_head._prev=_head; - } - } - - /* ------------------------------------------------------------ */ - public long getTimeToNext() - { - synchronized (_lock) - { - if (_head._next==_head) - return -1; - long to_next = _duration+_head._next._timestamp-_now; - return to_next<0?0:to_next; - } - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - StringBuffer buf = new StringBuffer(); - buf.append(super.toString()); - - Task task = _head._next; - while (task!=_head) - { - buf.append("-->"); - buf.append(task); - task=task._next; - } - - return buf.toString(); - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /** Task. - * The base class for scheduled timeouts. This class should be - * extended to implement the expire() method, which is called if the - * timeout expires. - * - * - * - */ - public static class Task - { - Task _next; - Task _prev; - Timeout _timeout; - long _delay; - long _timestamp=0; - boolean _expired=false; - - /* ------------------------------------------------------------ */ - protected Task() - { - _next=_prev=this; - } - - /* ------------------------------------------------------------ */ - private void unlink() - { - _next._prev=_prev; - _prev._next=_next; - _next=_prev=this; - _expired=false; - } - - /* ------------------------------------------------------------ */ - private void link(Task task) - { - Task next_next = _next; - _next._prev=task; - _next=task; - _next._next=next_next; - _next._prev=this; - } - - /* ------------------------------------------------------------ */ - /** Cancel the task. - * Remove the task from the timeout. - */ - public void cancel() - { - Timeout timeout = _timeout; - if (timeout!=null) - { - synchronized (timeout._lock) - { - unlink(); - _timestamp=0; - } - } - } - - /* ------------------------------------------------------------ */ - /** Expire task. - * This method is called when the timeout expires. It is called - * in the scope of the synchronize block (on this) that sets - * the {@link #isExpired()} state to true. - * @see #expired() For an unsynchronized callback. - */ - protected void expire(){} - - /* ------------------------------------------------------------ */ - /** Expire task. - * This method is called when the timeout expires. It is called - * outside of any synchronization scope and may be delayed. - * - */ - public void expired(){} - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/Extension.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/Extension.java deleted file mode 100644 index 936aa5fb..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/Extension.java +++ /dev/null @@ -1,31 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.util.Map; - -public interface Extension extends WebSocketParser.FrameHandler, WebSocketGenerator -{ - public String getName(); - public String getParameterizedName(); - - public boolean init(Map<String,String> parameters); - public void bind(WebSocket.FrameConnection connection, WebSocketParser.FrameHandler inbound, WebSocketGenerator outbound); - -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/MaskGen.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/MaskGen.java deleted file mode 100644 index 9178d906..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/MaskGen.java +++ /dev/null @@ -1,24 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -public interface MaskGen -{ - void genMask(byte[] mask); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/PerMessageDeflateExtension.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/PerMessageDeflateExtension.java deleted file mode 100644 index fdd11d93..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/PerMessageDeflateExtension.java +++ /dev/null @@ -1,291 +0,0 @@ -/* - * 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. - */ -package org.eclipse.jetty.websocket; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.zip.DataFormatException; -import java.util.zip.Deflater; -import java.util.zip.Inflater; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.WebSocket.FrameConnection; -import org.eclipse.jetty.websocket.WebSocketParser.FrameHandler; - -import android.annotation.TargetApi; -import android.os.Build; -import android.text.TextUtils; - -/** - * PerMessageDeflateExtension - * - * Copyright (c) 2015 KNOWLEDGECODE - */ -public class PerMessageDeflateExtension implements Extension { - - private static final Logger __log = Log.getLogger(PerMessageDeflateExtension.class.getName()); - private static final byte[] TAIL_BYTES = new byte[] { 0x00, 0x00, (byte) 0xff, (byte) 0xff }; - private static final int INITIAL_CAPACITY = 8192; - private static final String EXTENSION = "permessage-deflate"; - private static final String CLIENT_NO_CONTEXT_TAKEOVER = "client_no_context_takeover"; - private static final String SERVER_NO_CONTEXT_TAKEOVER = "server_no_context_takeover"; - private static final String SERVER_MAX_WINDOW_BITS = "server_max_window_bits"; - - private static class Zlib { - protected Deflater _deflater; - protected Inflater _inflater; - protected WebSocketBuffer _buffer; - protected byte[] _buf; - protected int _capcacity; - protected boolean _deflaterReset; - protected boolean _inflaterReset; - - public Zlib(boolean deflaterReset, boolean inflaterReset) { - _deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true); - _inflater = new Inflater(true); - _buffer = new WebSocketBuffer(INITIAL_CAPACITY); - _buf = new byte[INITIAL_CAPACITY]; - _capcacity = INITIAL_CAPACITY; - _deflaterReset = deflaterReset; - _inflaterReset = inflaterReset; - } - - public byte[] compress(byte[] b, int offset, int length) { - int len; - int index = 0; - - _deflater.reset(); - _deflater.setInput(b, offset, length); - _deflater.finish(); - while ((len = _deflater.deflate(_buf, index, _capcacity - index)) > 0) { - if ((index += len) == _capcacity) { - _buf = Arrays.copyOf(_buf, _capcacity <<= 1); - } - } - return Arrays.copyOf(_buf, index); - } - - public Buffer decompress(byte[] b, int offset, int length) throws DataFormatException { - int len; - int index = 0; - - if (_inflaterReset) { - _inflater.reset(); - } - _inflater.setInput(b, offset, length); - while ((len = _inflater.inflate(_buf, index, _capcacity - index)) > 0) { - if ((index += len) == _capcacity) { - _buf = Arrays.copyOf(_buf, _capcacity <<= 1); - } - } - _buffer.clear(); - return _buffer.append(_buf, 0, index); - } - - public boolean isCompressible() { - return _deflaterReset; - } - - public void end() { - _deflater.end(); - _inflater.end(); - } - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - private static class NewZlib extends Zlib { - public NewZlib(boolean deflaterReset, boolean inflaterReset) { - super(deflaterReset, inflaterReset); - } - - @Override - public byte[] compress(byte[] b, int offset, int length) { - int len; - int index = 0; - - if (_deflaterReset) { - _deflater.reset(); - } - _deflater.setInput(b, offset, length); - while ((len = _deflater.deflate(_buf, index, _capcacity - index, Deflater.SYNC_FLUSH)) > 0) { - if ((index += len) == _capcacity) { - _buf = Arrays.copyOf(_buf, _capcacity <<= 1); - } - } - return Arrays.copyOf(_buf, index - TAIL_BYTES.length); - } - - @Override - public boolean isCompressible() { - return true; - } - } - - private FrameConnection _connection; - private FrameHandler _inbound; - private WebSocketGenerator _outbound; - private Zlib _zlib; - private String _parameters; - private boolean _compressed; - - public PerMessageDeflateExtension() { - if (Build.VERSION.SDK_INT < 19) { - _parameters = TextUtils.join("; ", new String[]{ EXTENSION, CLIENT_NO_CONTEXT_TAKEOVER }); - } else { - _parameters = EXTENSION; - } - _compressed = false; - } - - @Override - public void onFrame(byte flags, byte opcode, Buffer buffer) { - switch (opcode) { - case WebSocketConnectionRFC6455.OP_TEXT: - case WebSocketConnectionRFC6455.OP_BINARY: - _compressed = ((flags & 0x07) == 0x04); - case WebSocketConnectionRFC6455.OP_CONTINUATION: - if (_compressed) { - try { - if ((flags &= 0x08) > 0) { - buffer.put(TAIL_BYTES); - } - _inbound.onFrame(flags, opcode, _zlib.decompress(buffer.array(), buffer.getIndex(), buffer.length())); - } catch (DataFormatException e) { - __log.warn(e); - _connection.close(WebSocketConnectionRFC6455.CLOSE_BAD_DATA, "Bad data"); - } - return; - } - } - _inbound.onFrame(flags, opcode, buffer); - } - - @Override - public void close(int code, String message) { - _zlib.end(); - } - - @Override - public int flush() throws IOException { - return 0; - } - - @Override - public boolean isBufferEmpty() { - return _outbound.isBufferEmpty(); - } - - @Override - public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException { - if (opcode == WebSocketConnectionRFC6455.OP_TEXT || opcode == WebSocketConnectionRFC6455.OP_BINARY) { - if (_zlib.isCompressible()) { - byte[] compressed = _zlib.compress(content, offset, length); - _outbound.addFrame((byte) (flags | 0x04), opcode, compressed, 0, compressed.length); - return; - } - } - _outbound.addFrame(flags, opcode, content, offset, length); - } - - @Override - public String getName() { - return EXTENSION; - } - - @Override - public String getParameterizedName() { - return _parameters; - } - - @Override - public boolean init(Map<String, String> parameters) { - boolean extension = false; - boolean client_no_context_takeover = false; - boolean server_no_context_takeover = false; - int server_max_window_bits = 0; - - _parameters = ""; - for (String key : parameters.keySet()) { - String value = parameters.get(key); - - if (EXTENSION.equals(key) && TextUtils.isEmpty(value) && !extension) { - extension = true; - } else if (CLIENT_NO_CONTEXT_TAKEOVER.equals(key) && TextUtils.isEmpty(value) && !client_no_context_takeover) { - client_no_context_takeover = true; - } else if (SERVER_NO_CONTEXT_TAKEOVER.equals(key) && TextUtils.isEmpty(value) && !server_no_context_takeover) { - server_no_context_takeover = true; - } else if (SERVER_MAX_WINDOW_BITS.equals(key) && server_max_window_bits == 0) { - if (TextUtils.isEmpty(value)) { - __log.warn("Unexpected parameter: {}", key); - return false; - } - if (!value.matches("[1-9]\\d?")) { - __log.warn("Unexpected parameter: {}={}", key, value); - return false; - } - int v = Integer.parseInt(value); - if (v < 8 || v > 15) { - __log.warn("Unexpected parameter: {}={}", key, value); - return false; - } - server_max_window_bits = v; - } else if (!TextUtils.isEmpty(value)) { - __log.warn("Unexpected parameter: {}={}", key, value); - return false; - } else { - __log.warn("Unexpected parameter: {}", key); - return false; - } - } - if (extension) { - List<String> p = new ArrayList<String>(); - - p.add(EXTENSION); - if (client_no_context_takeover) { - p.add(CLIENT_NO_CONTEXT_TAKEOVER); - } - if (server_no_context_takeover) { - p.add(SERVER_NO_CONTEXT_TAKEOVER); - } - if (server_max_window_bits > 0) { - p.add(String.format("%s=%d", SERVER_MAX_WINDOW_BITS, server_max_window_bits)); - } - _parameters = TextUtils.join("; ", p); - - if (Build.VERSION.SDK_INT < 19) { - _zlib = new Zlib(client_no_context_takeover, server_no_context_takeover); - } else { - _zlib = new NewZlib(client_no_context_takeover, server_no_context_takeover); - } - } - return extension; - } - - @Override - public void bind(FrameConnection connection, FrameHandler inbound, WebSocketGenerator outbound) { - _connection = connection; - _inbound = inbound; - _outbound = outbound; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/RandomMaskGen.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/RandomMaskGen.java deleted file mode 100644 index a180c60f..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/RandomMaskGen.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.util.Random; - - -public class RandomMaskGen implements MaskGen -{ - private final Random _random; - - public RandomMaskGen() - { - this(new Random()); - } - - public RandomMaskGen(Random random) - { - _random=random; - } - - public void genMask(byte[] mask) - { - // The assumption is that this code is always called - // with an external lock held to prevent concurrent access - // Otherwise we need to synchronize on the _random. - _random.nextBytes(mask); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocket.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocket.java deleted file mode 100644 index 4cf39df7..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocket.java +++ /dev/null @@ -1,273 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.IOException; - -/** - * WebSocket Interface. - * <p> - * This interface provides the signature for a server-side end point of a websocket connection. - * The Interface has several nested interfaces, for each type of message that may be received. - */ -public interface WebSocket -{ - /** - * Called when a new websocket connection is accepted. - * @param connection The Connection object to use to send messages. - */ - void onOpen(Connection connection); - - /** - * Called when an established websocket connection closes - * @param closeCode - * @param message - */ - void onClose(int closeCode, String message); - - /** - * A nested WebSocket interface for receiving text messages - */ - interface OnTextMessage extends WebSocket - { - /** - * Called with a complete text message when all fragments have been received. - * The maximum size of text message that may be aggregated from multiple frames is set with {@link Connection#setMaxTextMessageSize(int)}. - * @param data The message - */ - void onMessage(String data); - } - - /** - * A nested WebSocket interface for receiving binary messages - */ - interface OnBinaryMessage extends WebSocket - { - /** - * Called with a complete binary message when all fragments have been received. - * The maximum size of binary message that may be aggregated from multiple frames is set with {@link Connection#setMaxBinaryMessageSize(int)}. - * @param data - * @param offset - * @param length - */ - void onMessage(byte[] data, int offset, int length); - } - - /** - * A nested WebSocket interface for receiving control messages - */ - interface OnControl extends WebSocket - { - /** - * Called when a control message has been received. - * @param controlCode - * @param data - * @param offset - * @param length - * @return true if this call has completely handled the control message and no further processing is needed. - */ - boolean onControl(byte controlCode,byte[] data, int offset, int length); - } - - /** - * A nested WebSocket interface for receiving any websocket frame - */ - interface OnFrame extends WebSocket - { - /** - * Called when any websocket frame is received. - * @param flags - * @param opcode - * @param data - * @param offset - * @param length - * @return true if this call has completely handled the frame and no further processing is needed (including aggregation and/or message delivery) - */ - boolean onFrame(byte flags,byte opcode,byte[] data, int offset, int length); - - void onHandshake(FrameConnection connection); - } - - /** - * A Connection interface is passed to a WebSocket instance via the {@link WebSocket#onOpen(Connection)} to - * give the application access to the specifics of the current connection. This includes methods - * for sending frames and messages as well as methods for interpreting the flags and opcodes of the connection. - * - * modified by KNOWLEDGECODE - */ - public interface Connection - { - String getProtocol(); - String getExtensions(); - void sendMessage(String data) throws IOException; - void sendMessage(byte[] data, int offset, int length) throws IOException; - - /** - * Close the connection with normal close code. - */ - void close(); - - /** Close the connection with specific closeCode and message. - * @param closeCode The close code to send, or -1 for no close code - * @param message The message to send or null for no message - */ - void close(int closeCode,String message); - - boolean isOpen(); - - /** - * @param ms The time in ms that the connection can be idle before closing - */ - void setMaxIdleTime(int ms); - - /** - * @param size size<0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters - */ - void setMaxTextMessageSize(int size); - - /** - * @param size size<0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer - */ - void setMaxBinaryMessageSize(int size); - - /** - * @return The time in ms that the connection can be idle before closing - */ - int getMaxIdleTime(); - - /** - * Size in characters of the maximum text message to be received - * @return size <0 No aggregation of frames to messages, >=0 max size of text frame aggregation buffer in characters - */ - int getMaxTextMessageSize(); - - /** - * Size in bytes of the maximum binary message to be received - * @return size <0 no aggregation of binary frames, >=0 size of binary frame aggregation buffer - */ - int getMaxBinaryMessageSize(); - } - - /** - * Frame Level Connection - * <p>The Connection interface at the level of sending/receiving frames rather than messages. - * Also contains methods to decode/generate flags and opcodes without using constants, so that - * code can be written to work with multiple drafts of the protocol. - * - */ - public interface FrameConnection extends Connection - { - /** - * @return The opcode of a binary message - */ - byte binaryOpcode(); - - /** - * @return The opcode of a text message - */ - byte textOpcode(); - - /** - * @return The opcode of a continuation frame - */ - byte continuationOpcode(); - - /** - * @return Mask for the FIN bit. - */ - byte finMask(); - - /** Set if frames larger than the frame buffer are handled with local fragmentations - * @param allowFragmentation - */ - void setAllowFrameFragmentation(boolean allowFragmentation); - - /** - * @param flags The flags bytes of a frame - * @return True of the flags indicate a final frame. - */ - boolean isMessageComplete(byte flags); - - /** - * @param opcode - * @return True if the opcode is for a control frame - */ - boolean isControl(byte opcode); - - /** - * @param opcode - * @return True if the opcode is for a text frame - */ - boolean isText(byte opcode); - - /** - * @param opcode - * @return True if the opcode is for a binary frame - */ - boolean isBinary(byte opcode); - - /** - * @param opcode - * @return True if the opcode is for a continuation frame - */ - boolean isContinuation(byte opcode); - - /** - * @param opcode - * @return True if the opcode is a close control - */ - boolean isClose(byte opcode); - - /** - * @param opcode - * @return True if the opcode is a ping control - */ - boolean isPing(byte opcode); - - /** - * @param opcode - * @return True if the opcode is a pong control - */ - boolean isPong(byte opcode); - - /** - * @return True if frames larger than the frame buffer are fragmented. - */ - boolean isAllowFrameFragmentation(); - - /** Send a control frame - * @param control - * @param data - * @param offset - * @param length - * @throws IOException - */ - void sendControl(byte control,byte[] data, int offset, int length) throws IOException; - - /** Send an arbitrary frame - * @param flags - * @param opcode - * @param data - * @param offset - * @param length - * @throws IOException - */ - void sendFrame(byte flags,byte opcode,byte[] data, int offset, int length) throws IOException; - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketBuffer.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketBuffer.java deleted file mode 100644 index ad89312b..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketBuffer.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * 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. - */ -package org.eclipse.jetty.websocket; - -import java.nio.charset.Charset; -import java.util.Arrays; - -import org.eclipse.jetty.io.Buffer; - -/** - * WebSocketBuffer - * - * Copyright (c) 2015 KNOWLEDGECODE - */ -class WebSocketBuffer implements Buffer { - - private byte[] _buffer; - private int _index; - private int _capacity; - - public WebSocketBuffer(final int capacity) { - _buffer = new byte[capacity]; - _index = 0; - _capacity = capacity; - } - - public WebSocketBuffer(final byte[] buffer, final int offset, final int length) { - _buffer = Arrays.copyOfRange(buffer, offset, length); - _index = length; - _capacity = length; - } - - public WebSocketBuffer append(final byte[] array, final int offset, final int length) { - if ((_index += length) > _capacity) { - _buffer = Arrays.copyOf(_buffer, (_capacity = Math.max(_capacity << 1, _index))); - } - System.arraycopy(array, offset, _buffer, _index - length, length); - return this; - } - - @Override - public byte[] array() { - return _buffer; - } - - @Override - public byte[] asArray() { - return Arrays.copyOf(_buffer, _index); - } - - @Override - public Buffer buffer() { - return null; - } - - @Override - public Buffer asMutableBuffer() { - return null; - } - - @Override - public int capacity() { - return _capacity; - } - - @Override - public int space() { - return _capacity - _index; - } - - @Override - public void clear() { - _index = 0; - } - - @Override - public void compact() { - } - - @Override - public byte get() { - return 0; - } - - @Override - public int get(byte[] b, int offset, int length) { - return 0; - } - - @Override - public Buffer get(int length) { - return null; - } - - @Override - public int getIndex() { - return 0; - } - - @Override - public boolean hasContent() { - return false; - } - - @Override - public boolean equalsIgnoreCase(Buffer buffer) { - return false; - } - - @Override - public boolean isImmutable() { - return false; - } - - @Override - public boolean isReadOnly() { - return false; - } - - @Override - public boolean isVolatile() { - return false; - } - - @Override - public int length() { - return _index; - } - - @Override - public void mark() { - } - - @Override - public int markIndex() { - return 0; - } - - @Override - public byte peek() { - return 0; - } - - @Override - public byte peek(int index) { - return 0; - } - - @Override - public int peek(int index, byte[] b, int offset, int length) { - return 0; - } - - @Override - public int poke(int index, Buffer src) { - return 0; - } - - @Override - public void poke(int index, byte b) { - } - - @Override - public int poke(int index, byte[] b, int offset, int length) { - return 0; - } - - @Override - public int put(Buffer src) { - return 0; - } - - @Override - public void put(byte b) { - } - - @Override - public int put(byte[] b, int offset, int length) { - return 0; - } - - @Override - public int put(byte[] b) { - return 0; - } - - @Override - public int putIndex() { - return 0; - } - - @Override - public void setGetIndex(int newStart) { - } - - @Override - public void setMarkIndex(int newMark) { - } - - @Override - public void setPutIndex(int newLimit) { - } - - @Override - public int skip(int n) { - return n; - } - - @Override - public Buffer sliceFromMark() { - return null; - } - - @Override - public Buffer sliceFromMark(int length) { - return null; - } - - @Override - public String toDetailString() { - return null; - } - - @Override - public String toString(Charset charset) { - return new String(_buffer, 0, _index, charset); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketBuffers.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketBuffers.java deleted file mode 100644 index 97dcb135..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketBuffers.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.Buffers.Type; -import org.eclipse.jetty.io.ThreadLocalBuffers; - -/* ------------------------------------------------------------ */ -/** The WebSocket Buffer Pool. - * - * The normal buffers are byte array buffers so that user processes - * can access directly. However the generator uses direct buffers - * for the final output stage as they are filled in bulk and are more - * efficient to flush. - */ -public class WebSocketBuffers -{ - final private Buffers _buffers; - - public WebSocketBuffers(final int bufferSize) - { - _buffers = new ThreadLocalBuffers(Type.DIRECT, bufferSize, Type.INDIRECT, bufferSize, Type.INDIRECT); - } - - public Buffer getBuffer() - { - return _buffers.getBuffer(); - } - - public Buffer getDirectBuffer() - { - return _buffers.getHeader(); - } - - public void returnBuffer(Buffer buffer) - { - _buffers.returnBuffer(buffer); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketClient.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketClient.java deleted file mode 100644 index dc6fcf21..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketClient.java +++ /dev/null @@ -1,611 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ProtocolException; -import java.net.SocketAddress; -import java.net.URI; -import java.nio.channels.ByteChannel; -import java.nio.channels.SocketChannel; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** - * <p>{@link WebSocketClient} allows to create multiple connections to multiple destinations - * that can speak the websocket protocol.</p> - * <p>When creating websocket connections, {@link WebSocketClient} accepts a {@link WebSocket} - * object (to receive events from the server), and returns a {@link WebSocket.Connection} to - * send data to the server.</p> - * <p>Example usage is as follows:</p> - * <pre> - * WebSocketClientFactory factory = new WebSocketClientFactory(); - * factory.start(); - * - * WebSocketClient client = factory.newWebSocketClient(); - * // Configure the client - * - * WebSocket.Connection connection = client.open(new URI("ws://127.0.0.1:8080/"), new WebSocket.OnTextMessage() - * { - * public void onOpen(Connection connection) - * { - * // open notification - * } - * - * public void onClose(int closeCode, String message) - * { - * // close notification - * } - * - * public void onMessage(String data) - * { - * // handle incoming message - * } - * }).get(5, TimeUnit.SECONDS); - * - * connection.sendMessage("Hello World"); - * </pre> - * - * modified by KNOWLEDGECODE - */ -public class WebSocketClient -{ - private final static Logger __log = org.eclipse.jetty.util.log.Log.getLogger(WebSocketClient.class.getName()); - - private final WebSocketClientFactory _factory; - private final Map<String,String> _cookies=new ConcurrentHashMap<String, String>(); - private final List<Extension> _extensions=new CopyOnWriteArrayList<Extension>(); - private String _origin; - private String _protocol; - private String _agent; - private int _maxIdleTime=-1; - private int _maxTextMessageSize=-1; - private int _maxBinaryMessageSize=-1; - private MaskGen _maskGen; - private SocketAddress _bindAddress; - - /* ------------------------------------------------------------ */ - /** - * <p>Creates a WebSocketClient with shared WebSocketClientFactory.</p> - * - * @param factory the shared {@link WebSocketClientFactory} - */ - public WebSocketClient(WebSocketClientFactory factory) - { - _factory=factory; - _maskGen=_factory.getMaskGen(); - } - - /* ------------------------------------------------------------ */ - /** - * @return The WebSocketClientFactory this client was created with. - */ - public WebSocketClientFactory getFactory() - { - return _factory; - } - - /* ------------------------------------------------------------ */ - /** - * @return The maxIdleTime in ms for connections opened by this client, - * or -1 if the default from {@link WebSocketClientFactory#getSelectorManager()} is used. - * @see #setMaxIdleTime(int) - */ - public int getMaxIdleTime() - { - return _maxIdleTime; - } - - /* ------------------------------------------------------------ */ - /** - * @param maxIdleTime The max idle time in ms for connections opened by this client - * @see #getMaxIdleTime() - */ - public void setMaxIdleTime(int maxIdleTime) - { - _maxIdleTime=maxIdleTime; - } - - /* ------------------------------------------------------------ */ - /** - * @return The subprotocol string for connections opened by this client. - * @see #setProtocol(String) - */ - public String getProtocol() - { - return _protocol; - } - - /* ------------------------------------------------------------ */ - /** - * @param protocol The subprotocol string for connections opened by this client. - * @see #getProtocol() - */ - public void setProtocol(String protocol) - { - _protocol = protocol; - } - - /* ------------------------------------------------------------ */ - /** - * @return The origin URI of the client - * @see #setOrigin(String) - */ - public String getOrigin() - { - return _origin; - } - - /* ------------------------------------------------------------ */ - /** - * @param origin The origin URI of the client (eg "http://example.com") - * @see #getOrigin() - */ - public void setOrigin(String origin) - { - _origin = origin; - } - - /* ------------------------------------------------------------ */ - /** - * <p>Returns the map of the cookies that are sent during the initial HTTP handshake - * that upgrades to the websocket protocol.</p> - * @return The read-write cookie map - */ - public Map<String,String> getCookies() - { - return _cookies; - } - - /* ------------------------------------------------------------ */ - /** - * @return The list of websocket protocol extensions - */ - public List<Extension> getExtensions() - { - return _extensions; - } - - /* ------------------------------------------------------------ */ - /** - * @return the mask generator to use, or null if not mask generator should be used - * @see #setMaskGen(MaskGen) - */ - public MaskGen getMaskGen() - { - return _maskGen; - } - - /* ------------------------------------------------------------ */ - /** - * @param maskGen the mask generator to use, or null if not mask generator should be used - * @see #getMaskGen() - */ - public void setMaskGen(MaskGen maskGen) - { - _maskGen = maskGen; - } - - /* ------------------------------------------------------------ */ - /** - * @return The initial maximum text message size (in characters) for a connection - */ - public int getMaxTextMessageSize() - { - return _maxTextMessageSize; - } - - /* ------------------------------------------------------------ */ - /** - * Set the initial maximum text message size for a connection. This can be changed by - * the application calling {@link WebSocket.Connection#setMaxTextMessageSize(int)}. - * @param maxTextMessageSize The default maximum text message size (in characters) for a connection - */ - public void setMaxTextMessageSize(int maxTextMessageSize) - { - _maxTextMessageSize = maxTextMessageSize; - } - - /* ------------------------------------------------------------ */ - /** - * @return The initial maximum binary message size (in bytes) for a connection - */ - public int getMaxBinaryMessageSize() - { - return _maxBinaryMessageSize; - } - - /* ------------------------------------------------------------ */ - /** - * Set the initial maximum binary message size for a connection. This can be changed by - * the application calling {@link WebSocket.Connection#setMaxBinaryMessageSize(int)}. - * @param maxBinaryMessageSize The default maximum binary message size (in bytes) for a connection - */ - public void setMaxBinaryMessageSize(int maxBinaryMessageSize) - { - _maxBinaryMessageSize = maxBinaryMessageSize; - } - - /* ------------------------------------------------------------ */ - /** - * @return user-agent - */ - public String getAgent() - { - return _agent; - } - - /* ------------------------------------------------------------ */ - /** - * @param user-agent - */ - public void setAgent(String _agent) - { - this._agent = _agent; - } - - /* ------------------------------------------------------------ */ - /** - * <p>Opens a websocket connection to the URI and blocks until the connection is accepted or there is an error.</p> - * - * @param uri The URI to connect to. - * @param websocket The {@link WebSocket} instance to handle incoming events. - * @param maxConnectTime The interval to wait for a successful connection - * @param units the units of the maxConnectTime - * @return A {@link WebSocket.Connection} - * @throws IOException if the connection fails - * @throws InterruptedException if the thread is interrupted - * @throws TimeoutException if the timeout elapses before the connection is completed - * @see #open(URI, WebSocket) - */ - public WebSocket.Connection open(URI uri, WebSocket websocket,long maxConnectTime,TimeUnit units) throws IOException, InterruptedException, TimeoutException - { - try - { - return open(uri,websocket).get(maxConnectTime,units); - } - catch (ExecutionException e) - { - Throwable cause = e.getCause(); - if (cause instanceof IOException) - throw (IOException)cause; - if (cause instanceof Error) - throw (Error)cause; - if (cause instanceof RuntimeException) - throw (RuntimeException)cause; - throw new RuntimeException(cause); - } - } - - /* ------------------------------------------------------------ */ - /** - * <p>Asynchronously opens a websocket connection and returns a {@link Future} to obtain the connection.</p> - * <p>The caller must call {@link Future#get(long, TimeUnit)} if they wish to impose a connect timeout on the open.</p> - * - * @param uri The URI to connect to. - * @param websocket The {@link WebSocket} instance to handle incoming events. - * @return A {@link Future} to the {@link WebSocket.Connection} - * @throws IOException if the connection fails - * @see #open(URI, WebSocket, long, TimeUnit) - */ - public Future<WebSocket.Connection> open(URI uri, WebSocket websocket) throws IOException - { - if (!_factory.isStarted()) - throw new IllegalStateException("Factory !started"); - - InetSocketAddress address = toSocketAddress(uri); - - SocketChannel channel = null; - try - { - channel = SocketChannel.open(); - if (_bindAddress != null) - channel.socket().bind(_bindAddress); - channel.socket().setTcpNoDelay(true); - - WebSocketFuture holder = new WebSocketFuture(websocket,uri,this,channel); - - channel.configureBlocking(false); - channel.connect(address); - _factory.getSelectorManager().register(channel,holder); - - return holder; - } - catch (RuntimeException e) - { - // close the channel (prevent connection leak) - IO.close(channel); - - // rethrow - throw e; - } - catch(IOException e) - { - // close the channel (prevent connection leak) - IO.close(channel); - - // rethrow - throw e; - } - } - - public static InetSocketAddress toSocketAddress(URI uri) - { - String scheme = uri.getScheme(); - if (!("ws".equalsIgnoreCase(scheme) || "wss".equalsIgnoreCase(scheme))) - throw new IllegalArgumentException("Bad WebSocket scheme: " + scheme); - int port = uri.getPort(); - if (port == 0) - throw new IllegalArgumentException("Bad WebSocket port: " + port); - if (port < 0) - port = "ws".equals(scheme) ? 80 : 443; - - return new InetSocketAddress(uri.getHost(), port); - } - - /* ------------------------------------------------------------ */ - /** The Future Websocket Connection. - */ - static class WebSocketFuture implements Future<WebSocket.Connection> - { - final WebSocket _websocket; - final URI _uri; - final WebSocketClient _client; - final CountDownLatch _done = new CountDownLatch(1); - ByteChannel _channel; - WebSocketConnection _connection; - Throwable _exception; - - private WebSocketFuture(WebSocket websocket, URI uri, WebSocketClient client, ByteChannel channel) - { - _websocket=websocket; - _uri=uri; - _client=client; - _channel=channel; - } - - public void onConnection(WebSocketConnection connection) - { - try - { - _client.getFactory().addConnection(connection); - - connection.getConnection().setMaxTextMessageSize(_client.getMaxTextMessageSize()); - connection.getConnection().setMaxBinaryMessageSize(_client.getMaxBinaryMessageSize()); - - WebSocketConnection con; - synchronized (this) - { - if (_channel!=null) - _connection=connection; - con=_connection; - } - - if (con!=null) - { - if (_websocket instanceof WebSocket.OnFrame) - ((WebSocket.OnFrame)_websocket).onHandshake((WebSocket.FrameConnection)con.getConnection()); - - _websocket.onOpen(con.getConnection()); - } - } - finally - { - _done.countDown(); - } - } - - public void handshakeFailed(Throwable ex) - { - try - { - ByteChannel channel=null; - synchronized (this) - { - if (_channel!=null) - { - channel=_channel; - _channel=null; - _exception=ex; - } - } - - if (channel!=null) - { - if (ex instanceof ProtocolException) - closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_PROTOCOL,ex.getMessage()); - else - closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,ex.getMessage()); - } - } - finally - { - _done.countDown(); - } - } - - public Map<String,String> getCookies() - { - return _client.getCookies(); - } - - public String getProtocol() - { - return _client.getProtocol(); - } - - public WebSocket getWebSocket() - { - return _websocket; - } - - public URI getURI() - { - return _uri; - } - - public int getMaxIdleTime() - { - return _client.getMaxIdleTime(); - } - - public String getOrigin() - { - return _client.getOrigin(); - } - - public MaskGen getMaskGen() - { - return _client.getMaskGen(); - } - - public String getAgent() - { - return _client.getAgent(); - } - - public List<Extension> getExtensions() { - return _client.getExtensions(); - } - - @Override - public String toString() - { - return "[" + _uri + ","+_websocket+"]@"+hashCode(); - } - - public boolean cancel(boolean mayInterruptIfRunning) - { - try - { - ByteChannel channel=null; - synchronized (this) - { - if (_connection==null && _exception==null && _channel!=null) - { - channel=_channel; - _channel=null; - } - } - - if (channel!=null) - { - closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,"cancelled"); - return true; - } - return false; - } - finally - { - _done.countDown(); - } - } - - public boolean isCancelled() - { - synchronized (this) - { - return _channel==null && _connection==null; - } - } - - public boolean isDone() - { - synchronized (this) - { - return _connection!=null && _exception==null; - } - } - - public org.eclipse.jetty.websocket.WebSocket.Connection get() throws InterruptedException, ExecutionException - { - try - { - return get(Long.MAX_VALUE,TimeUnit.SECONDS); - } - catch(TimeoutException e) - { - throw new IllegalStateException("The universe has ended",e); - } - } - - public org.eclipse.jetty.websocket.WebSocket.Connection get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, - TimeoutException - { - _done.await(timeout,unit); - ByteChannel channel=null; - org.eclipse.jetty.websocket.WebSocket.Connection connection=null; - Throwable exception; - synchronized (this) - { - exception=_exception; - if (_connection==null) - { - exception=_exception; - channel=_channel; - _channel=null; - } - else - connection=_connection.getConnection(); - } - - if (channel!=null) - closeChannel(channel,WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,"timeout"); - if (exception!=null) - throw new ExecutionException(exception); - if (connection!=null) - return connection; - throw new TimeoutException(); - } - - private void closeChannel(ByteChannel channel,int code, String message) - { - try - { - _websocket.onClose(code,message); - } - catch(Exception e) - { - __log.warn(e); - } - - try - { - channel.close(); - } - catch(IOException e) - { - __log.debug(e); - } - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketClientFactory.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketClientFactory.java deleted file mode 100644 index f4d4549d..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketClientFactory.java +++ /dev/null @@ -1,634 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.EOFException; -import java.io.IOException; -import java.net.ProtocolException; -import java.nio.channels.SelectionKey; -import java.nio.channels.SocketChannel; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Queue; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; - -import javax.net.ssl.SSLEngine; - -import org.eclipse.jetty.http.HttpParser; -import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.ByteArrayBuffer; -import org.eclipse.jetty.io.ConnectedEndPoint; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.SimpleBuffers; -import org.eclipse.jetty.io.nio.AsyncConnection; -import org.eclipse.jetty.io.nio.SelectChannelEndPoint; -import org.eclipse.jetty.io.nio.SelectorManager; -import org.eclipse.jetty.io.nio.SslConnection; -import org.eclipse.jetty.util.QuotedStringTokenizer; -import org.eclipse.jetty.util.component.AggregateLifeCycle; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.util.thread.QueuedThreadPool; -import org.eclipse.jetty.util.thread.ThreadPool; - -import android.text.TextUtils; -import android.util.Base64; - -/* ------------------------------------------------------------ */ -/** - * <p>WebSocketClientFactory contains the common components needed by multiple {@link WebSocketClient} instances - * (for example, a {@link ThreadPool}, a {@link SelectorManager NIO selector}, etc).</p> - * <p>WebSocketClients with different configurations should share the same factory to avoid to waste resources.</p> - * <p>If a ThreadPool or MaskGen is passed in the constructor, then it is not added with {@link AggregateLifeCycle#addBean(Object)}, - * so it's lifecycle must be controlled externally. - * - * @see WebSocketClient - * - * modified by KNOWLEDGECODE - */ -public class WebSocketClientFactory extends AggregateLifeCycle -{ - private static final Logger __log = org.eclipse.jetty.util.log.Log.getLogger(WebSocketClientFactory.class.getName()); - private static final ByteArrayBuffer __ACCEPT = new ByteArrayBuffer.CaseInsensitive("Sec-WebSocket-Accept"); - private static final ByteArrayBuffer __PROTOCOL = new ByteArrayBuffer.CaseInsensitive("Sec-WebSocket-Protocol"); - private static final ByteArrayBuffer __EXTENSIONS = new ByteArrayBuffer.CaseInsensitive("Sec-WebSocket-Extensions"); - private final Queue<WebSocketConnection> connections = new ConcurrentLinkedQueue<WebSocketConnection>(); - private final SslContextFactory _sslContextFactory = new SslContextFactory(); - private final ThreadPool _threadPool; - private final WebSocketClientSelector _selector; - private MaskGen _maskGen; - private WebSocketBuffers _buffers; - - /* ------------------------------------------------------------ */ - /** - * <p>Creates a WebSocketClientFactory with the default configuration.</p> - */ - public WebSocketClientFactory() - { - this(null); - } - - /* ------------------------------------------------------------ */ - /** - * <p>Creates a WebSocketClientFactory with the given ThreadPool and the default configuration.</p> - * - * @param threadPool the ThreadPool instance to use - */ - public WebSocketClientFactory(ThreadPool threadPool) - { - this(threadPool, new RandomMaskGen()); - } - - /* ------------------------------------------------------------ */ - /** - * <p>Creates a WebSocketClientFactory with the given ThreadPool and the given MaskGen.</p> - * - * @param threadPool the ThreadPool instance to use - * @param maskGen the MaskGen instance to use - */ - public WebSocketClientFactory(ThreadPool threadPool, MaskGen maskGen) - { - this(threadPool, maskGen, 8192); - } - - /* ------------------------------------------------------------ */ - - /** - * <p>Creates a WebSocketClientFactory with the specified configuration.</p> - * - * @param threadPool the ThreadPool instance to use - * @param maskGen the mask generator to use - * @param bufferSize the read buffer size - */ - public WebSocketClientFactory(ThreadPool threadPool, MaskGen maskGen, int bufferSize) - { - if (threadPool == null) - threadPool = new QueuedThreadPool(); - _threadPool = threadPool; - addBean(_threadPool); - - _buffers = new WebSocketBuffers(bufferSize); - addBean(_buffers); - - _maskGen = maskGen; - addBean(_maskGen); - - _selector = new WebSocketClientSelector(); - addBean(_selector); - - addBean(_sslContextFactory); - } - - /* ------------------------------------------------------------ */ - /** - * @return the SslContextFactory used to configure SSL parameters - */ - public SslContextFactory getSslContextFactory() - { - return _sslContextFactory; - } - - /* ------------------------------------------------------------ */ - /** - * Get the selectorManager. Used to configure the manager. - * - * @return The {@link SelectorManager} instance. - */ - public SelectorManager getSelectorManager() - { - return _selector; - } - - /* ------------------------------------------------------------ */ - /** - * Get the ThreadPool. - * Used to set/query the thread pool configuration. - * - * @return The {@link ThreadPool} - */ - public ThreadPool getThreadPool() - { - return _threadPool; - } - - /* ------------------------------------------------------------ */ - /** - * @return the shared mask generator, or null if no shared mask generator is used - * @see WebSocketClient#getMaskGen() - */ - public MaskGen getMaskGen() - { - return _maskGen; - } - - @Override - protected void doStop() throws Exception - { - closeConnections(); - super.doStop(); - } - - /* ------------------------------------------------------------ */ - /** - * <p>Creates and returns a new instance of a {@link WebSocketClient}, configured with this - * WebSocketClientFactory instance.</p> - * - * @return a new {@link WebSocketClient} instance - */ - public WebSocketClient newWebSocketClient() - { - return new WebSocketClient(this); - } - - protected SSLEngine newSslEngine(SocketChannel channel) throws IOException - { - SSLEngine sslEngine; - if (channel != null) - { - String peerHost = channel.socket().getInetAddress().getHostAddress(); - int peerPort = channel.socket().getPort(); - sslEngine = _sslContextFactory.newSslEngine(peerHost, peerPort); - } - else - { - sslEngine = _sslContextFactory.newSslEngine(); - } - sslEngine.setUseClientMode(true); - sslEngine.beginHandshake(); - - return sslEngine; - } - - protected boolean addConnection(WebSocketConnection connection) - { - return isRunning() && connections.add(connection); - } - - protected boolean removeConnection(WebSocketConnection connection) - { - return connections.remove(connection); - } - - protected void closeConnections() - { - for (WebSocketConnection connection : connections) - connection.shutdown(); - } - - /* ------------------------------------------------------------ */ - /** - * WebSocket Client Selector Manager - */ - class WebSocketClientSelector extends SelectorManager - { - @Override - public boolean dispatch(Runnable task) - { - return _threadPool.dispatch(task); - } - - @Override - protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, final SelectionKey key) throws IOException - { - WebSocketClient.WebSocketFuture holder = (WebSocketClient.WebSocketFuture)key.attachment(); - int maxIdleTime = holder.getMaxIdleTime(); - if (maxIdleTime < 0) - maxIdleTime = (int)getMaxIdleTime(); - SelectChannelEndPoint result = new SelectChannelEndPoint(channel, selectSet, key, maxIdleTime); - AsyncEndPoint endPoint = result; - - // Detect if it is SSL, and wrap the connection if so - if ("wss".equals(holder.getURI().getScheme())) - { - SSLEngine sslEngine = newSslEngine(channel); - SslConnection sslConnection = new SslConnection(sslEngine, endPoint); - endPoint.setConnection(sslConnection); - endPoint = sslConnection.getSslEndPoint(); - } - - AsyncConnection connection = selectSet.getManager().newConnection(channel, endPoint, holder); - endPoint.setConnection(connection); - - return result; - } - - @Override - public AsyncConnection newConnection(SocketChannel channel, AsyncEndPoint endpoint, Object attachment) - { - WebSocketClient.WebSocketFuture holder = (WebSocketClient.WebSocketFuture)attachment; - return new HandshakeConnection(endpoint, holder); - } - - @Override - protected void endPointOpened(SelectChannelEndPoint endpoint) - { - // TODO expose on outer class ?? - } - - @Override - protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection) - { - LOG.debug("upgrade {} -> {}", oldConnection, endpoint.getConnection()); - } - - @Override - protected void endPointClosed(SelectChannelEndPoint endpoint) - { - endpoint.getConnection().onClose(); - } - - @Override - protected void connectionFailed(SocketChannel channel, Throwable ex, Object attachment) - { - if (!(attachment instanceof WebSocketClient.WebSocketFuture)) - super.connectionFailed(channel, ex, attachment); - else - { - __log.debug(ex); - WebSocketClient.WebSocketFuture future = (WebSocketClient.WebSocketFuture)attachment; - - future.handshakeFailed(ex); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Handshake Connection. - * Handles the connection until the handshake succeeds or fails. - */ - class HandshakeConnection extends AbstractConnection implements AsyncConnection - { - private static final String __COOKIE_DELIM="\"\\\n\r\t\f\b%+ ;="; - - private final AsyncEndPoint _endp; - private final WebSocketClient.WebSocketFuture _future; - private final String _key; - private final HttpParser _parser; - private String _accept; - private String _protocol; - private List<String> _extensions; - private String _error; - private ByteArrayBuffer _handshake; - - public HandshakeConnection(AsyncEndPoint endpoint, WebSocketClient.WebSocketFuture future) - { - super(endpoint, System.currentTimeMillis()); - _endp = endpoint; - _future = future; - - byte[] bytes = new byte[16]; - new Random().nextBytes(bytes); - _key = new String(Base64.encodeToString(bytes, Base64.NO_WRAP)); - _extensions = new ArrayList<String>(); - - Buffers buffers = new SimpleBuffers(_buffers.getBuffer(), null); - _parser = new HttpParser(buffers, _endp, new HttpParser.EventHandler() - { - @Override - public void startResponse(Buffer version, int status, Buffer reason) throws IOException - { - if (status != 101) - { - _error = "Bad response status " + status + " " + reason; - _endp.close(); - } - } - - @Override - public void parsedHeader(Buffer name, Buffer value) throws IOException - { - if (__ACCEPT.equals(name)) - _accept = value.toString(); - else if (__PROTOCOL.equals(name)) - _protocol = value.toString(); - else if (__EXTENSIONS.equals(name)) - for (String s : TextUtils.split(value.toString(), ",")) - _extensions.add(s.trim()); - } - - @Override // TODO simone says shouldn't be needed - public void startRequest(Buffer method, Buffer url, Buffer version) throws IOException - { - if (_error == null) - _error = "Bad response: " + method + " " + url + " " + version; - _endp.close(); - } - - @Override // TODO simone says shouldn't be needed - public void content(Buffer ref) throws IOException - { - if (_error == null) - _error = "Bad response. " + ref.length() + "B of content?"; - _endp.close(); - } - }); - } - - private boolean initExtensions(List<Extension> extensions) - { - Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>(); - Set<String> s = new HashSet<String>(); - - for (String ext : (String[]) _extensions.toArray(new String[]{})) - { - Map<String, String> m = new HashMap<String, String>(); - String key = null; - - for (String p : TextUtils.split(ext, ";")) - { - String[] pp = TextUtils.split(p.trim(), "="); - m.put(pp[0].trim(), pp.length > 1 ? pp[1].trim() : ""); - if (key == null) - key = pp[0].trim(); - if (!s.add(pp[0].trim())) - return false; - } - map.put(key, m); - } - for (Extension extension : extensions) - { - Map<String, String> m = map.remove(extension.getName()); - if (m != null) - { - if (!extension.init(m)) - return false; - } - else - { - extensions.remove(extension); - } - } - if (map.size() > 0) - return false; - - return true; - } - - private boolean handshake() - { - if (_handshake==null) - { - String path = _future.getURI().getPath(); - if (path == null || path.length() == 0) - path = "/"; - - if (_future.getURI().getRawQuery() != null) - path += "?" + _future.getURI().getRawQuery(); - - String origin = _future.getOrigin(); - - StringBuilder request = new StringBuilder(512); - request.append("GET ").append(path).append(" HTTP/1.1\r\n") - .append("Host: ").append(_future.getURI().getHost()).append(":"); - - int port = _future.getURI().getPort(); - if (port <= 0) - { - // fix it - String scheme = _future.getURI().getScheme(); - - if ("ws".equalsIgnoreCase(scheme)) - { - port = 80; - } - else if ("wss".equalsIgnoreCase(scheme)) - { - port = 443; - } - else - { - throw new RuntimeException("No valid port provided for scheme [" + scheme + "]"); - } - } - - request.append(port).append("\r\n"); - - request.append("Upgrade: websocket\r\n") - .append("Connection: Upgrade\r\n"); - - if (origin != null) - request.append("Origin: ").append(origin).append("\r\n"); - - if (_future.getProtocol() != null) - request.append("Sec-WebSocket-Protocol: ").append(_future.getProtocol()).append("\r\n"); - - request.append("pragma: no-cache\r\n"); - - request.append("cache-control: no-cache\r\n"); - - request.append("Sec-WebSocket-Key: ").append(_key).append("\r\n"); - - request.append("Sec-WebSocket-Version: ").append(WebSocketConnectionRFC6455.VERSION).append("\r\n"); - - if (_future.getAgent() != null) - request.append("user-agent: ").append(_future.getAgent()).append("\r\n"); - - if (_future.getExtensions().size() > 0) - { - List<String> extensions = new ArrayList<String>(); - for (Extension ext :_future.getExtensions()) - extensions.add(ext.getParameterizedName()); - request.append("Sec-WebSocket-Extensions: ").append(TextUtils.join(", ", extensions)).append("\r\n"); - } - - Map<String, String> cookies = _future.getCookies(); - if (cookies != null && cookies.size() > 0) - { - for (String cookie : cookies.keySet()) - request.append("Cookie: ") - .append(QuotedStringTokenizer.quoteIfNeeded(cookie, __COOKIE_DELIM)) - .append("=") - .append(QuotedStringTokenizer.quoteIfNeeded(cookies.get(cookie), __COOKIE_DELIM)) - .append("\r\n"); - } - - request.append("\r\n"); - - _handshake=new ByteArrayBuffer(request.toString(), false); - } - - try - { - int flushed = _endp.flush(_handshake); - if (flushed<0) - throw new IOException("incomplete handshake"); - } - catch (IOException e) - { - _future.handshakeFailed(e); - } - return _handshake.length()==0; - } - - public Connection handle() throws IOException - { - while (_endp.isOpen() && !_parser.isComplete()) - { - if (_handshake==null || _handshake.length()>0) - if (!handshake()) - return this; - - if (!_parser.parseAvailable()) - { - if (_endp.isInputShutdown()) - _future.handshakeFailed(new IOException("Incomplete handshake response")); - return this; - } - } - if (_error == null) - { - if (_accept == null) - { - _error = "No Sec-WebSocket-Accept"; - } - else if (!WebSocketConnectionRFC6455.hashKey(_key).equals(_accept)) - { - _error = "Bad Sec-WebSocket-Accept"; - } - else if (!initExtensions(_future.getExtensions())) - { - _error = "Bad Sec-WebSocket-Extension"; - } - else - { - WebSocketConnection connection = newWebSocketConnection(); - - Buffer header = _parser.getHeaderBuffer(); - if (header.hasContent()) - connection.fillBuffersFrom(header); - _buffers.returnBuffer(header); - - _future.onConnection(connection); - - return connection; - } - } - - _endp.close(); - return this; - } - - private WebSocketConnection newWebSocketConnection() throws IOException - { - __log.debug("newWebSocketConnection()"); - return new WebSocketClientConnection( - _future._client.getFactory(), - _future.getWebSocket(), - _endp, - _buffers, - System.currentTimeMillis(), - _future.getMaxIdleTime(), - _protocol, - _future.getExtensions(), - WebSocketConnectionRFC6455.VERSION, - _future.getMaskGen()); - } - - public void onInputShutdown() throws IOException - { - _endp.close(); - } - - public boolean isIdle() - { - return false; - } - - public boolean isSuspended() - { - return false; - } - - public void onClose() - { - if (_error != null) - _future.handshakeFailed(new ProtocolException(_error)); - else - _future.handshakeFailed(new EOFException()); - } - } - - private static class WebSocketClientConnection extends WebSocketConnectionRFC6455 - { - private final WebSocketClientFactory factory; - - public WebSocketClientConnection(WebSocketClientFactory factory, WebSocket webSocket, EndPoint endPoint, WebSocketBuffers buffers, long timeStamp, int maxIdleTime, String protocol, List<Extension> extensions, int draftVersion, MaskGen maskGen) throws IOException - { - super(webSocket, endPoint, buffers, timeStamp, maxIdleTime, protocol, extensions, draftVersion, maskGen); - this.factory = factory; - } - - @Override - public void onClose() - { - super.onClose(); - factory.removeConnection(this); - } - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketConnection.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketConnection.java deleted file mode 100644 index 76385f7d..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketConnection.java +++ /dev/null @@ -1,36 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - - -import java.util.List; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.nio.AsyncConnection; - -public interface WebSocketConnection extends AsyncConnection -{ - void fillBuffersFrom(Buffer buffer); - - List<Extension> getExtensions(); - - WebSocket.Connection getConnection(); - - void shutdown(); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java deleted file mode 100644 index c9f2759d..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketConnectionRFC6455.java +++ /dev/null @@ -1,887 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may select to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -import org.eclipse.jetty.io.AbstractConnection; -import org.eclipse.jetty.io.AsyncEndPoint; -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.websocket.WebSocket.OnBinaryMessage; -import org.eclipse.jetty.websocket.WebSocket.OnControl; -import org.eclipse.jetty.websocket.WebSocket.OnFrame; -import org.eclipse.jetty.websocket.WebSocket.OnTextMessage; - -import android.text.TextUtils; -import android.util.Base64; - -/* ------------------------------------------------------------ */ -/** - * <pre> - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-------+-+-------------+-------------------------------+ - * |F|R|R|R| opcode|M| Payload len | Extended payload length | - * |I|S|S|S| (4) |A| (7) | (16/64) | - * |N|V|V|V| |S| | (if payload len==126/127) | - * | |1|2|3| |K| | | - * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - * | Extended payload length continued, if payload len == 127 | - * + - - - - - - - - - - - - - - - +-------------------------------+ - * | |Masking-key, if MASK set to 1 | - * +-------------------------------+-------------------------------+ - * | Masking-key (continued) | Payload Data | - * +-------------------------------- - - - - - - - - - - - - - - - + - * : Payload Data continued ... : - * + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - * | Payload Data continued ... | - * +---------------------------------------------------------------+ - * </pre> - * - * modified by KNOWLEDGECODE - */ -public class WebSocketConnectionRFC6455 extends AbstractConnection implements WebSocketConnection -{ - private static final Logger LOG = Log.getLogger(WebSocketConnectionRFC6455.class); - - final static byte OP_CONTINUATION = 0x00; - final static byte OP_TEXT = 0x01; - final static byte OP_BINARY = 0x02; - final static byte OP_EXT_DATA = 0x03; - - final static byte OP_CONTROL = 0x08; - final static byte OP_CLOSE = 0x08; - final static byte OP_PING = 0x09; - final static byte OP_PONG = 0x0A; - final static byte OP_EXT_CTRL = 0x0B; - - final static int CLOSE_NORMAL=1000; - final static int CLOSE_SHUTDOWN=1001; - final static int CLOSE_PROTOCOL=1002; - final static int CLOSE_BAD_DATA=1003; - final static int CLOSE_UNDEFINED=1004; - final static int CLOSE_NO_CODE=1005; - final static int CLOSE_NO_CLOSE=1006; - final static int CLOSE_BAD_PAYLOAD=1007; - final static int CLOSE_POLICY_VIOLATION=1008; - final static int CLOSE_MESSAGE_TOO_LARGE=1009; - final static int CLOSE_REQUIRED_EXTENSION=1010; - final static int CLOSE_SERVER_ERROR=1011; - final static int CLOSE_FAILED_TLS_HANDSHAKE=1015; - - final static int FLAG_FIN=0x8; - - // Per RFC 6455, section 1.3 - Opening Handshake - this version is "13" - final static int VERSION=13; - - static boolean isLastFrame(byte flags) - { - return (flags&FLAG_FIN)!=0; - } - - static boolean isControlFrame(byte opcode) - { - return (opcode&OP_CONTROL)!=0; - } - - private final static byte[] MAGIC; - private final List<Extension> _extensions; - private final WebSocketParserRFC6455 _parser; - private final WebSocketGeneratorRFC6455 _generator; - private final WebSocketGenerator _outbound; - private final WebSocket _webSocket; - private final OnFrame _onFrame; - private final OnBinaryMessage _onBinaryMessage; - private final OnTextMessage _onTextMessage; - private final OnControl _onControl; - private final String _protocol; - private final ClassLoader _context; - private volatile int _closeCode; - private volatile String _closeMessage; - private volatile boolean _closedIn; - private volatile boolean _closedOut; - private int _maxTextMessageSize=-1; - private int _maxBinaryMessageSize=-1; - - private static final Charset _iso88591 = Charset.forName("ISO-8859-1"); - private static final Charset _utf8 = Charset.forName("UTF-8"); - - static - { - MAGIC="258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(_iso88591); - } - - private final WebSocket.FrameConnection _connection = new WSFrameConnection(); - - /* ------------------------------------------------------------ */ - public WebSocketConnectionRFC6455(WebSocket websocket, EndPoint endpoint, WebSocketBuffers buffers, long timestamp, int maxIdleTime, String protocol, List<Extension> extensions,int draft, MaskGen maskgen) - throws IOException - { - super(endpoint,timestamp); - - _context=Thread.currentThread().getContextClassLoader(); - - _endp.setMaxIdleTime(maxIdleTime); - - _webSocket = websocket; - _onFrame=_webSocket instanceof OnFrame ? (OnFrame)_webSocket : null; - _onTextMessage=_webSocket instanceof OnTextMessage ? (OnTextMessage)_webSocket : null; - _onBinaryMessage=_webSocket instanceof OnBinaryMessage ? (OnBinaryMessage)_webSocket : null; - _onControl=_webSocket instanceof OnControl ? (OnControl)_webSocket : null; - _generator = new WebSocketGeneratorRFC6455(buffers, _endp,maskgen); - - _extensions=extensions; - WebSocketParser.FrameHandler frameHandler = new WSFrameHandler(); - if (_extensions!=null) - { - int e=0; - for (Extension extension : _extensions) - { - extension.bind( - _connection, - e==extensions.size()-1? frameHandler :extensions.get(e+1), - e==0?_generator:extensions.get(e-1)); - e++; - } - } - - _outbound=(_extensions==null||_extensions.size()==0)?_generator:extensions.get(extensions.size()-1); - WebSocketParser.FrameHandler inbound = (_extensions == null || _extensions.size() == 0) ? frameHandler : extensions.get(0); - - _parser = new WebSocketParserRFC6455(buffers, endpoint, inbound,maskgen==null); - - _protocol=protocol; - - } - - /* ------------------------------------------------------------ */ - public WebSocket.Connection getConnection() - { - return _connection; - } - - /* ------------------------------------------------------------ */ - public List<Extension> getExtensions() - { - if (_extensions==null) - return Collections.emptyList(); - - return _extensions; - } - - /* ------------------------------------------------------------ */ - public Connection handle() throws IOException - { - Thread current = Thread.currentThread(); - ClassLoader oldcontext = current.getContextClassLoader(); - current.setContextClassLoader(_context); - try - { - // handle the framing protocol - boolean progress=true; - - while (progress) - { - int flushed=_generator.flushBuffer(); - int filled=_parser.parseNext(); - - progress = flushed>0 || filled>0; - _endp.flush(); - - if (_endp instanceof AsyncEndPoint && ((AsyncEndPoint)_endp).hasProgressed()) - progress=true; - } - } - catch(IOException e) - { - try - { - if (_endp.isOpen()) - _endp.close(); - } - catch(IOException e2) - { - LOG.ignore(e2); - } - throw e; - } - finally - { - current.setContextClassLoader(oldcontext); - _parser.returnBuffer(); - _generator.returnBuffer(); - if (_endp.isOpen()) - { - if (_closedIn && _closedOut && _outbound.isBufferEmpty()) - _endp.close(); - else if (_endp.isInputShutdown() && !_closedIn) - closeIn(CLOSE_NO_CLOSE,null); - else - checkWriteable(); - } - } - return this; - } - - /* ------------------------------------------------------------ */ - public void onInputShutdown() throws IOException - { - if (!_closedIn) - _endp.close(); - } - - /* ------------------------------------------------------------ */ - public boolean isIdle() - { - return _parser.isBufferEmpty() && _outbound.isBufferEmpty(); - } - - /* ------------------------------------------------------------ */ - @Override - public void onIdleExpired(long idleForMs) - { - closeOut(WebSocketConnectionRFC6455.CLOSE_NORMAL,"Idle for "+idleForMs+"ms > "+_endp.getMaxIdleTime()+"ms"); - } - - /* ------------------------------------------------------------ */ - public boolean isSuspended() - { - return false; - } - - /* ------------------------------------------------------------ */ - public void onClose() - { - final boolean closed; - synchronized (this) - { - closed=_closeCode==0; - if (closed) - _closeCode=WebSocketConnectionRFC6455.CLOSE_NO_CLOSE; - } - if (closed) - _webSocket.onClose(WebSocketConnectionRFC6455.CLOSE_NO_CLOSE,"closed"); - } - - /* ------------------------------------------------------------ */ - public void closeIn(int code,String message) - { - LOG.debug("ClosedIn {} {} {}",this,code,message); - - final boolean closed_out; - final boolean tell_app; - synchronized (this) - { - closed_out=_closedOut; - _closedIn=true; - tell_app=_closeCode==0; - if (tell_app) - { - _closeCode=code; - _closeMessage=message; - } - } - - try - { - if (!closed_out) - closeOut(code,message); - } - finally - { - if (tell_app) - _webSocket.onClose(code,message); - } - } - - /* ------------------------------------------------------------ */ - public void closeOut(int code,String message) - { - LOG.debug("ClosedOut {} {} {}",this,code,message); - - final boolean closed_out; - final boolean tell_app; - synchronized (this) - { - closed_out=_closedOut; - _closedOut=true; - tell_app=_closeCode==0; - if (tell_app) - { - _closeCode=code; - _closeMessage=message; - } - } - - try - { - if (tell_app) - _webSocket.onClose(code,message); - } - finally - { - try - { - if (!closed_out) - { - // Close code 1005/1006/1015 are never to be sent as a status over - // a Close control frame. Code<-1 also means no node. - - if (code < 0 || (code == WebSocketConnectionRFC6455.CLOSE_NO_CODE) || (code == WebSocketConnectionRFC6455.CLOSE_NO_CLOSE) - || (code == WebSocketConnectionRFC6455.CLOSE_FAILED_TLS_HANDSHAKE)) - { - code = -1; - } - else if (code == 0) - { - code = WebSocketConnectionRFC6455.CLOSE_NORMAL; - } - - byte[] bytes = ("xx"+(message==null?"":message)).getBytes(_iso88591); - bytes[0]=(byte)(code/0x100); - bytes[1]=(byte)(code%0x100); - _outbound.addFrame((byte)FLAG_FIN,WebSocketConnectionRFC6455.OP_CLOSE,bytes,0,code>0?bytes.length:0); - _outbound.flush(); - } - } - catch(IOException e) - { - LOG.ignore(e); - } - } - } - - public void shutdown() - { - final WebSocket.Connection connection = _connection; - if (connection != null) - connection.close(CLOSE_SHUTDOWN, null); - } - - /* ------------------------------------------------------------ */ - public void fillBuffersFrom(Buffer buffer) - { - _parser.fill(buffer); - } - - /* ------------------------------------------------------------ */ - private void checkWriteable() - { - if (!_outbound.isBufferEmpty() && _endp instanceof AsyncEndPoint) - { - ((AsyncEndPoint)_endp).scheduleWrite(); - } - } - - protected void onFrameHandshake() - { - if (_onFrame != null) - { - _onFrame.onHandshake(_connection); - } - } - - protected void onWebSocketOpen() - { - _webSocket.onOpen(_connection); - } - - /* ------------------------------------------------------------ */ - private class WSFrameConnection implements WebSocket.FrameConnection - { - private volatile boolean _disconnecting; - - /* ------------------------------------------------------------ */ - public void sendMessage(String content) throws IOException - { - if (_closedOut) - throw new IOException("closedOut " + _closeCode + ":" + _closeMessage); - byte[] data = content.getBytes(_utf8); - _outbound.addFrame((byte)FLAG_FIN, WebSocketConnectionRFC6455.OP_TEXT, data, 0, data.length); - checkWriteable(); - } - - /* ------------------------------------------------------------ */ - public void sendMessage(byte[] content, int offset, int length) throws IOException - { - if (_closedOut) - throw new IOException("closedOut " + _closeCode + ":" + _closeMessage); - _outbound.addFrame((byte)FLAG_FIN, WebSocketConnectionRFC6455.OP_BINARY, content, offset, length); - checkWriteable(); - } - - /* ------------------------------------------------------------ */ - public void sendFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException - { - if (_closedOut) - throw new IOException("closedOut " + _closeCode + ":" + _closeMessage); - _outbound.addFrame(flags, opcode, content, offset, length); - checkWriteable(); - } - - /* ------------------------------------------------------------ */ - public void sendControl(byte ctrl, byte[] data, int offset, int length) throws IOException - { - // TODO: section 5.5 states that control frames MUST never be length > 125 bytes and MUST NOT be fragmented - if (_closedOut) - throw new IOException("closedOut " + _closeCode + ":" + _closeMessage); - _outbound.addFrame((byte)FLAG_FIN, ctrl, data, offset, length); - checkWriteable(); - } - - /* ------------------------------------------------------------ */ - public boolean isMessageComplete(byte flags) - { - return isLastFrame(flags); - } - - /* ------------------------------------------------------------ */ - public boolean isOpen() - { - return _endp!=null&&_endp.isOpen(); - } - - /* ------------------------------------------------------------ */ - public void close(int code, String message) - { - if (_disconnecting) - return; - _disconnecting=true; - WebSocketConnectionRFC6455.this.closeOut(code,message); - } - - /* ------------------------------------------------------------ */ - public void setMaxIdleTime(int ms) - { - try - { - _endp.setMaxIdleTime(ms); - } - catch(IOException e) - { - LOG.warn(e); - } - } - - /* ------------------------------------------------------------ */ - public void setMaxTextMessageSize(int size) - { - _maxTextMessageSize=size; - } - - /* ------------------------------------------------------------ */ - public void setMaxBinaryMessageSize(int size) - { - _maxBinaryMessageSize=size; - } - - /* ------------------------------------------------------------ */ - public int getMaxIdleTime() - { - return _endp.getMaxIdleTime(); - } - - /* ------------------------------------------------------------ */ - public int getMaxTextMessageSize() - { - return _maxTextMessageSize; - } - - /* ------------------------------------------------------------ */ - public int getMaxBinaryMessageSize() - { - return _maxBinaryMessageSize; - } - - /* ------------------------------------------------------------ */ - public String getProtocol() - { - return _protocol; - } - - /* ------------------------------------------------------------ */ - public String getExtensions() - { - List<String> extensions = new ArrayList<String>(); - - for (Extension extension : _extensions) - { - extensions.add(extension.getParameterizedName()); - } - return TextUtils.join(", ", extensions); - } - - /* ------------------------------------------------------------ */ - public byte binaryOpcode() - { - return OP_BINARY; - } - - /* ------------------------------------------------------------ */ - public byte textOpcode() - { - return OP_TEXT; - } - - /* ------------------------------------------------------------ */ - public byte continuationOpcode() - { - return OP_CONTINUATION; - } - - /* ------------------------------------------------------------ */ - public byte finMask() - { - return FLAG_FIN; - } - - /* ------------------------------------------------------------ */ - public boolean isControl(byte opcode) - { - return isControlFrame(opcode); - } - - /* ------------------------------------------------------------ */ - public boolean isText(byte opcode) - { - return opcode==OP_TEXT; - } - - /* ------------------------------------------------------------ */ - public boolean isBinary(byte opcode) - { - return opcode==OP_BINARY; - } - - /* ------------------------------------------------------------ */ - public boolean isContinuation(byte opcode) - { - return opcode==OP_CONTINUATION; - } - - /* ------------------------------------------------------------ */ - public boolean isClose(byte opcode) - { - return opcode==OP_CLOSE; - } - - /* ------------------------------------------------------------ */ - public boolean isPing(byte opcode) - { - return opcode==OP_PING; - } - - /* ------------------------------------------------------------ */ - public boolean isPong(byte opcode) - { - return opcode==OP_PONG; - } - - /* ------------------------------------------------------------ */ - public void close() - { - close(CLOSE_NORMAL,null); - } - - /* ------------------------------------------------------------ */ - public void setAllowFrameFragmentation(boolean allowFragmentation) - { - _parser.setFakeFragments(allowFragmentation); - } - - /* ------------------------------------------------------------ */ - public boolean isAllowFrameFragmentation() - { - return _parser.isFakeFragments(); - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return String.format(Locale.getDefault(), "%s@%x l(%s:%d)<->r(%s:%d)", - getClass().getSimpleName(), - hashCode(), - _endp.getLocalAddr(), - _endp.getLocalPort(), - _endp.getRemoteAddr(), - _endp.getRemotePort()); - } - } - - private class WSFrameHandler implements WebSocketParser.FrameHandler - { - private static final int MAX_CONTROL_FRAME_PAYLOAD = 125; - private static final int INITIAL_CAPACITY = 8192; - private WebSocketBuffer _buffer = new WebSocketBuffer(INITIAL_CAPACITY); - private byte _opcode = -1; - - private boolean excess(int opcode, int length) - { - switch (opcode) - { - case WebSocketConnectionRFC6455.OP_TEXT: - return _maxTextMessageSize > 0 && _maxTextMessageSize < length; - case WebSocketConnectionRFC6455.OP_BINARY: - return _maxBinaryMessageSize > 0 && _maxBinaryMessageSize < length; - default: - return false; - } - } - - public void onFrame(final byte flags, final byte opcode, final Buffer buffer) - { - synchronized (WebSocketConnectionRFC6455.this) - { - // Ignore incoming after a close - if (_closedIn) - { - return; - } - } - - byte[] array = buffer.array(); - int offset = buffer.getIndex(); - int length = buffer.length(); - - if (isControlFrame(opcode) && length > MAX_CONTROL_FRAME_PAYLOAD) - { - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL, "Control frame too large: " + length + " > " + MAX_CONTROL_FRAME_PAYLOAD); - return; - } - - if ((flags & 0x7) != 0) - { - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL, "RSV bits set 0x" + Integer.toHexString(flags)); - return; - } - - // Ignore all frames after error close - if (_closeCode != 0 && _closeCode != CLOSE_NORMAL && opcode != OP_CLOSE) - { - return; - } - - // Deliver frame if websocket is a FrameWebSocket - if (_onFrame != null) - { - if (_onFrame.onFrame(flags, opcode, array, offset, length)) - { - return; - } - } - - if (_onControl != null && isControlFrame(opcode)) - { - if (_onControl.onControl(opcode, array, offset, length)) - { - return; - } - } - - switch (opcode) - { - case WebSocketConnectionRFC6455.OP_TEXT: - case WebSocketConnectionRFC6455.OP_BINARY: - { - if (_opcode != -1) - { - _buffer.clear(); - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL, "Expected Continuation" + Integer.toHexString(opcode)); - return; - } - _opcode = opcode; - } - case WebSocketConnectionRFC6455.OP_CONTINUATION: - { - if (_opcode == -1) - { - _buffer.clear(); - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL, "Bad Continuation"); - return; - } - if (excess(_opcode, _buffer.length() + length)) - { - switch (_opcode) - { - case WebSocketConnectionRFC6455.OP_TEXT: - _connection.close(WebSocketConnectionRFC6455.CLOSE_MESSAGE_TOO_LARGE, "Text message size > " + _maxTextMessageSize + " chars"); - return; - case WebSocketConnectionRFC6455.OP_BINARY: - _connection.close(WebSocketConnectionRFC6455.CLOSE_MESSAGE_TOO_LARGE, "Message size > " + _maxBinaryMessageSize); - return; - } - } - if (isLastFrame(flags)) - { - switch (_opcode) - { - case WebSocketConnectionRFC6455.OP_TEXT: - if (_buffer.length() == 0) - { - _onTextMessage.onMessage(new String(array, offset, length, _utf8)); - } - else - { - _onTextMessage.onMessage(_buffer.append(array, offset, length).toString(_utf8)); - } - break; - case WebSocketConnectionRFC6455.OP_BINARY: - if (_buffer.length() == 0) - { - _onBinaryMessage.onMessage(array, offset, length); - } - else - { - _onBinaryMessage.onMessage(_buffer.append(array, offset, length).array(), 0, _buffer.length()); - } - break; - } - _opcode = -1; - _buffer.clear(); - } - else - { - _buffer.append(array, offset, length); - } - break; - } - - case WebSocketConnectionRFC6455.OP_PING: - { - LOG.debug("PING {}",this); - if (!_closedOut) - { - try - { - _connection.sendControl(WebSocketConnectionRFC6455.OP_PONG, array, offset, length); - } - catch (Throwable e) - { - errorClose(WebSocketConnectionRFC6455.CLOSE_SERVER_ERROR, "Internal Server Error: " + e); - } - } - break; - } - - case WebSocketConnectionRFC6455.OP_PONG: - { - LOG.debug("PONG {}",this); - break; - } - - case WebSocketConnectionRFC6455.OP_CLOSE: - { - int code = WebSocketConnectionRFC6455.CLOSE_NO_CODE; - String message = null; - if (length >= 2) - { - code=(0xff & array[offset]) * 0x100 + (0xff & array[offset + 1]); - - // Validate close status codes. - if (code < WebSocketConnectionRFC6455.CLOSE_NORMAL || - code == WebSocketConnectionRFC6455.CLOSE_UNDEFINED || - code == WebSocketConnectionRFC6455.CLOSE_NO_CLOSE || - code == WebSocketConnectionRFC6455.CLOSE_NO_CODE || - ( code > 1011 && code <= 2999 ) || - code >= 5000 ) - { - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Invalid close code " + code); - return; - } - } - else if(buffer.length() == 1) - { - // Invalid length. use status code 1002 (Protocol error) - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Invalid payload length of 1"); - return; - } - closeIn(code, message); - break; - } - - default: - errorClose(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Bad opcode 0x"+Integer.toHexString(opcode)); - break; - } - } - - private void errorClose(int code, String message) - { - _connection.close(code, message); - - // Brutally drop the connection - try - { - _endp.close(); - } - catch (IOException e) - { - LOG.warn(e.toString()); - LOG.debug(e); - } - } - - public void close(int code,String message) - { - if (code != CLOSE_NORMAL) - LOG.warn("Close: " + code + " " + message); - _connection.close(code, message); - } - - @Override - public String toString() - { - return WebSocketConnectionRFC6455.this.toString() + "FH"; - } - } - - /* ------------------------------------------------------------ */ - public static String hashKey(String key) - { - try - { - MessageDigest md = MessageDigest.getInstance("SHA1"); - md.update(key.getBytes(_utf8)); - md.update(MAGIC); - return Base64.encodeToString(md.digest(), Base64.NO_WRAP); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return String.format("%s p=%s g=%s", getClass().getSimpleName(), _parser, _generator); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketGenerator.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketGenerator.java deleted file mode 100644 index 10046ac2..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketGenerator.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.IOException; - - - -/* ------------------------------------------------------------ */ -/** WebSocketGenerator. - */ -public interface WebSocketGenerator -{ - int flush() throws IOException; - boolean isBufferEmpty(); - void addFrame(byte flags,byte opcode, byte[] content, int offset, int length) throws IOException; -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java deleted file mode 100644 index 7fedfb3f..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketGeneratorRFC6455.java +++ /dev/null @@ -1,319 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.IOException; -import java.util.Locale; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.io.EofException; - - -/** - * WebSocketGenerator. - * This class generates websocket packets. - * It is fully synchronized because it is likely that async - * threads will call the addMessage methods while other - * threads are flushing the generator. - * - * modified by KNOWLEDGECODE - */ -public class WebSocketGeneratorRFC6455 implements WebSocketGenerator -{ - private final Lock _lock = new ReentrantLock(); - private final WebSocketBuffers _buffers; - private final EndPoint _endp; - private final byte[] _mask = new byte[4]; - private final MaskGen _maskGen; - private Buffer _buffer; - private int _m; - private boolean _opsent; - private boolean _closed; - - public WebSocketGeneratorRFC6455(WebSocketBuffers buffers, EndPoint endp) - { - this(buffers, endp, null); - } - - public WebSocketGeneratorRFC6455(WebSocketBuffers buffers, EndPoint endp, MaskGen maskGen) - { - _buffers = buffers; - _endp = endp; - _maskGen = maskGen; - } - - public Buffer getBuffer() - { - _lock.lock(); - try - { - return _buffer; - } - finally - { - _lock.unlock(); - } - } - - public void addFrame(byte flags, byte opcode, byte[] content, int offset, int length) throws IOException - { - _lock.lock(); - try - { - if (_closed) - throw new EofException("Closed"); - if (opcode == WebSocketConnectionRFC6455.OP_CLOSE) - _closed = true; - - boolean mask = _maskGen != null; - - if (_buffer == null) - _buffer = mask ? _buffers.getBuffer() : _buffers.getDirectBuffer(); - - boolean last = WebSocketConnectionRFC6455.isLastFrame(flags); - - int space = mask ? 14 : 10; - - do - { - if (_opsent) - { - flags &= 0x0b; - opcode = WebSocketConnectionRFC6455.OP_CONTINUATION; - } - opcode = (byte)(((0xf & flags) << 4) + (0xf & opcode)); - _opsent = true; - - int payload = length; - if (payload + space > _buffer.capacity()) - { - // We must fragement, so clear FIN bit - opcode = (byte)(opcode & 0x7F); // Clear the FIN bit - payload = _buffer.capacity() - space; - } - else if (last) - opcode = (byte)(opcode | 0x80); // Set the FIN bit - - // ensure there is space for header - if (_buffer.space() <= space) - { - flushBuffer(); - if (_buffer.space() <= space) - flush(); - } - - // write the opcode and length - if (payload > 0xffff) - { - _buffer.put(new byte[]{ - opcode, - mask ? (byte)0xff : (byte)0x7f, - (byte)0, - (byte)0, - (byte)0, - (byte)0, - (byte)((payload >> 24) & 0xff), - (byte)((payload >> 16) & 0xff), - (byte)((payload >> 8) & 0xff), - (byte)(payload & 0xff)}); - } - else if (payload >= 0x7e) - { - _buffer.put(new byte[]{ - opcode, - mask ? (byte)0xfe : (byte)0x7e, - (byte)(payload >> 8), - (byte)(payload & 0xff)}); - } - else - { - _buffer.put(new byte[]{ - opcode, - (byte)(mask ? (0x80 | payload) : payload)}); - } - - // write mask - if (mask) - { - _maskGen.genMask(_mask); - _m = 0; - _buffer.put(_mask); - } - - // write payload - int remaining = payload; - while (remaining > 0) - { - _buffer.compact(); - int chunk = remaining < _buffer.space() ? remaining : _buffer.space(); - - if (mask) - { - for (int i = 0; i < chunk; i++) - _buffer.put((byte)(content[offset + (payload - remaining) + i] ^ _mask[+_m++ % 4])); - } - else - _buffer.put(content, offset + (payload - remaining), chunk); - - remaining -= chunk; - if (_buffer.space() > 0) - { - // Gently flush the data, issuing a non-blocking write - flushBuffer(); - } - else - { - // Forcibly flush the data, issuing a blocking write - flush(); - if (remaining == 0) - { - // Gently flush the data, issuing a non-blocking write - flushBuffer(); - } - } - } - offset += payload; - length -= payload; - } - while (length > 0); - _opsent = !last; - - if (_buffer != null && _buffer.length() == 0) - { - _buffers.returnBuffer(_buffer); - _buffer = null; - } - } - finally - { - _lock.unlock(); - } - } - - public int flushBuffer() throws IOException - { - if (!_lock.tryLock()) - return 0; - - try - { - if (!_endp.isOpen()) - throw new EofException(); - - if (_buffer != null) - { - int flushed = _buffer.hasContent() ? _endp.flush(_buffer) : 0; - if (_closed && _buffer.length() == 0) - _endp.shutdownOutput(); - return flushed; - } - - return 0; - } - finally - { - _lock.unlock(); - } - } - - public int flush() throws IOException - { - if (!_lock.tryLock()) - return 0; - - try - { - if (_buffer == null) - return 0; - - int result = flushBuffer(); - if (!_endp.isBlocking()) - { - long now = System.currentTimeMillis(); - long end = now + _endp.getMaxIdleTime(); - while (_buffer.length() > 0) - { - boolean ready = _endp.blockWritable(end - now); - if (!ready) - { - now = System.currentTimeMillis(); - if (now < end) - continue; - throw new IOException("Write timeout"); - } - - result += flushBuffer(); - } - } - _buffer.compact(); - return result; - } - finally - { - _lock.unlock(); - } - } - - public boolean isBufferEmpty() - { - _lock.lock(); - try - { - return _buffer == null || _buffer.length() == 0; - } - finally - { - _lock.unlock(); - } - } - - public void returnBuffer() - { - _lock.lock(); - try - { - if (_buffer != null && _buffer.length() == 0) - { - _buffers.returnBuffer(_buffer); - _buffer = null; - } - } - finally - { - _lock.unlock(); - } - } - - @Override - public String toString() - { - // Do NOT use synchronized (this) - // because it's very easy to deadlock when debugging is enabled. - // We do a best effort to print the right toString() and that's it. - Buffer buffer = _buffer; - return String.format(Locale.getDefault(), "%s@%x closed=%b buffer=%d", - getClass().getSimpleName(), - hashCode(), - _closed, - buffer == null ? -1 : buffer.length()); - } -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketParser.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketParser.java deleted file mode 100644 index b53250b5..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketParser.java +++ /dev/null @@ -1,49 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import org.eclipse.jetty.io.Buffer; - -/* ------------------------------------------------------------ */ -/** - * Parser the WebSocket protocol. - * - */ -public interface WebSocketParser -{ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - public interface FrameHandler - { - void onFrame(byte flags, byte opcode, Buffer buffer); - void close(int code,String message); - } - - Buffer getBuffer(); - - /** - * @return an indication of progress, normally bytes filled plus events parsed, or -1 for EOF - */ - int parseNext(); - - boolean isBufferEmpty(); - - void fill(Buffer buffer); -} diff --git a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java b/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java deleted file mode 100644 index 5b516e19..00000000 --- a/plugins/cordova-plugin-websocket/src/android/org/eclipse/jetty/websocket/WebSocketParserRFC6455.java +++ /dev/null @@ -1,392 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.websocket; - -import java.io.IOException; - -import org.eclipse.jetty.io.Buffer; -import org.eclipse.jetty.io.Buffers; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ------------------------------------------------------------ */ -/** - * Parser the WebSocket protocol. - * - */ -public class WebSocketParserRFC6455 implements WebSocketParser -{ - private static final Logger LOG = Log.getLogger(WebSocketParserRFC6455.class); - - public enum State { - - START(0), OPCODE(1), LENGTH_7(1), LENGTH_16(2), LENGTH_63(8), MASK(4), PAYLOAD(0), DATA(0), SKIP(1), SEEK_EOF(1); - - int _needs; - - State(int needs) - { - _needs=needs; - } - - int getNeeds() - { - return _needs; - } - } - - private final WebSocketBuffers _buffers; - private final EndPoint _endp; - private final FrameHandler _handler; - private final boolean _shouldBeMasked; - private State _state; - private Buffer _buffer; - private byte _flags; - private byte _opcode; - private int _bytesNeeded; - private long _length; - private boolean _masked; - private final byte[] _mask = new byte[4]; - private int _m; - private boolean _skip; - private boolean _fragmentFrames=true; - - /* ------------------------------------------------------------ */ - /** - * @param buffers The buffers to use for parsing. Only the {@link Buffers#getBuffer()} is used. - * This should be a direct buffer if binary data is mostly used or an indirect buffer if utf-8 data - * is mostly used. - * @param endp the endpoint - * @param handler the handler to notify when a parse event occurs - * @param shouldBeMasked whether masking should be handled - */ - public WebSocketParserRFC6455(WebSocketBuffers buffers, EndPoint endp, FrameHandler handler, boolean shouldBeMasked) - { - _buffers=buffers; - _endp=endp; - _handler=handler; - _shouldBeMasked=shouldBeMasked; - _state=State.START; - } - - /* ------------------------------------------------------------ */ - /** - * @return True if fake fragments should be created for frames larger than the buffer. - */ - public boolean isFakeFragments() - { - return _fragmentFrames; - } - - /* ------------------------------------------------------------ */ - /** - * @param fakeFragments True if fake fragments should be created for frames larger than the buffer. - */ - public void setFakeFragments(boolean fakeFragments) - { - _fragmentFrames = fakeFragments; - } - - /* ------------------------------------------------------------ */ - public boolean isBufferEmpty() - { - return _buffer==null || _buffer.length()==0; - } - - /* ------------------------------------------------------------ */ - public Buffer getBuffer() - { - return _buffer; - } - - /* ------------------------------------------------------------ */ - /** Parse to next event. - * Parse to the next {@link WebSocketParser.FrameHandler} event or until no more data is - * available. Fill data from the {@link EndPoint} only as necessary. - * @return An indication of progress or otherwise. -1 indicates EOF, 0 indicates - * that no bytes were read and no messages parsed. A positive number indicates either - * the bytes filled or the messages parsed. - */ - public int parseNext() - { - if (_buffer==null) - _buffer=_buffers.getBuffer(); - - boolean progress=false; - int filled=-1; - - // Loop until a datagram call back or can't fill anymore - while(!progress && (!_endp.isInputShutdown()||_buffer.length()>0)) - { - int available=_buffer.length(); - - // Fill buffer if we need a byte or need length - while (available<(_state==State.SKIP?1:_bytesNeeded)) - { - // compact to mark (set at start of data) - _buffer.compact(); - - // if no space, then the data is too big for buffer - if (_buffer.space() == 0) - { - // Can we send a fake frame? - if (_fragmentFrames && _state==State.DATA) - { - Buffer data =_buffer.get(4*(available/4)); - _buffer.compact(); - if (_masked) - { - if (data.array()==null) - data=_buffer.asMutableBuffer(); - byte[] array = data.array(); - final int end=data.putIndex(); - for (int i=data.getIndex();i<end;i++) - array[i]^=_mask[_m++%4]; - } - - // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length()); - _bytesNeeded-=data.length(); - progress=true; - _handler.onFrame((byte)(_flags&(0xff^WebSocketConnectionRFC6455.FLAG_FIN)), _opcode, data); - - _opcode=WebSocketConnectionRFC6455.OP_CONTINUATION; - } - - if (_buffer.space() == 0) - throw new IllegalStateException("FULL: "+_state+" "+_bytesNeeded+">"+_buffer.capacity()); - } - - // catch IOExceptions (probably EOF) and try to parse what we have - try - { - filled=_endp.isInputShutdown()?-1:_endp.fill(_buffer); - available=_buffer.length(); - // System.err.printf(">> filled %d/%d%n",filled,available); - if (filled<=0) - break; - } - catch(IOException e) - { - LOG.debug(e); - filled=-1; - break; - } - } - // Did we get enough? - if (available<(_state==State.SKIP?1:_bytesNeeded)) - break; - - // if we are here, then we have sufficient bytes to process the current state. - // Parse the buffer byte by byte (unless it is STATE_DATA) - byte b; - while (_state!=State.DATA && available>=(_state==State.SKIP?1:_bytesNeeded)) - { - switch (_state) - { - case START: - _skip=false; - _state=_opcode==WebSocketConnectionRFC6455.OP_CLOSE?State.SEEK_EOF:State.OPCODE; - _bytesNeeded=_state.getNeeds(); - continue; - - case OPCODE: - b=_buffer.get(); - available--; - _opcode=(byte)(b&0xf); - _flags=(byte)(0xf&(b>>4)); - - if (WebSocketConnectionRFC6455.isControlFrame(_opcode)&&!WebSocketConnectionRFC6455.isLastFrame(_flags)) - { - LOG.warn("Fragmented Control from "+_endp); - _handler.close(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Fragmented control"); - progress=true; - _skip=true; - } - - _state=State.LENGTH_7; - _bytesNeeded=_state.getNeeds(); - - continue; - - case LENGTH_7: - b=_buffer.get(); - available--; - _masked=(b&0x80)!=0; - b=(byte)(0x7f&b); - - switch(b) - { - case 0x7f: - _length=0; - _state=State.LENGTH_63; - break; - case 0x7e: - _length=0; - _state=State.LENGTH_16; - break; - default: - _length=(0x7f&b); - _state=_masked?State.MASK:State.PAYLOAD; - } - _bytesNeeded=_state.getNeeds(); - continue; - - case LENGTH_16: - b=_buffer.get(); - available--; - _length = _length*0x100 + (0xff&b); - if (--_bytesNeeded==0) - { - if (_length>_buffer.capacity() && !_fragmentFrames) - { - progress=true; - _handler.close(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,"frame size "+_length+">"+_buffer.capacity()); - _skip=true; - } - - _state=_masked?State.MASK:State.PAYLOAD; - _bytesNeeded=_state.getNeeds(); - } - continue; - - case LENGTH_63: - b=_buffer.get(); - available--; - _length = _length*0x100 + (0xff&b); - if (--_bytesNeeded==0) - { - _bytesNeeded=(int)_length; - if (_length>=_buffer.capacity() && !_fragmentFrames) - { - progress=true; - _handler.close(WebSocketConnectionRFC6455.CLOSE_POLICY_VIOLATION,"frame size "+_length+">"+_buffer.capacity()); - _skip=true; - } - - _state=_masked?State.MASK:State.PAYLOAD; - _bytesNeeded=_state.getNeeds(); - } - continue; - - case MASK: - _buffer.get(_mask,0,4); - _m=0; - available-=4; - _state=State.PAYLOAD; - _bytesNeeded=_state.getNeeds(); - break; - - case PAYLOAD: - _bytesNeeded=(int)_length; - _state=_skip?State.SKIP:State.DATA; - break; - - case DATA: - break; - - case SKIP: - int skip=Math.min(available,_bytesNeeded); - progress=true; - _buffer.skip(skip); - available-=skip; - _bytesNeeded-=skip; - if (_bytesNeeded==0) - _state=State.START; - break; - - case SEEK_EOF: - progress=true; - _buffer.skip(available); - available=0; - break; - } - } - - if (_state==State.DATA && available>=_bytesNeeded) - { - if ( _masked!=_shouldBeMasked) - { - _buffer.skip(_bytesNeeded); - _state=State.START; - progress=true; - _handler.close(WebSocketConnectionRFC6455.CLOSE_PROTOCOL,"Not masked"); - } - else - { - Buffer data =_buffer.get(_bytesNeeded); - if (_masked) - { - if (data.array()==null) - data=_buffer.asMutableBuffer(); - byte[] array = data.array(); - final int end=data.putIndex(); - for (int i=data.getIndex();i<end;i++) - array[i]^=_mask[_m++%4]; - } - - // System.err.printf("%s %s %s >>\n",TypeUtil.toHexString(_flags),TypeUtil.toHexString(_opcode),data.length()); - - progress=true; - _handler.onFrame(_flags, _opcode, data); - _bytesNeeded=0; - _state=State.START; - } - - break; - } - } - - return progress?1:filled; - } - - /* ------------------------------------------------------------ */ - public void fill(Buffer buffer) - { - if (buffer!=null && buffer.length()>0) - { - if (_buffer==null) - _buffer=_buffers.getBuffer(); - - _buffer.put(buffer); - buffer.clear(); - } - } - - /* ------------------------------------------------------------ */ - public void returnBuffer() - { - if (_buffer!=null && _buffer.length()==0) - { - _buffers.returnBuffer(_buffer); - _buffer=null; - } - } - - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return String.format("%s@%x state=%s buffer=%s", - getClass().getSimpleName(), - hashCode(), - _state, - _buffer); - } -} diff --git a/plugins/cordova-plugin-websocket/www/websocket.js b/plugins/cordova-plugin-websocket/www/websocket.js deleted file mode 100644 index 09ad873e..00000000 --- a/plugins/cordova-plugin-websocket/www/websocket.js +++ /dev/null @@ -1,274 +0,0 @@ -/* - * 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. - */ -/** - * Cordova WebSocket Plugin for Android - * @author KNOWLEDGECODE <knowledgecode@gmail.com> - * @version 0.11.0 - */ -(function (window) { - 'use strict'; - var BuiltinWebSocket = window.WebSocket, - exec = require('cordova/exec'), - identifier = 0, - listeners = {}, - taskQueue = { - uuid: require('cordova/utils').createUUID(), - tasks: [], - push: function (fn) { - this.tasks.push(fn); - window.postMessage(this.uuid, '*'); - }, - listener: function (event) { - if (event.source === window && event.data === taskQueue.uuid) { - event.stopPropagation(); - if (taskQueue.tasks.length) { - taskQueue.tasks.shift()(); - } - } - } - }, - createMessage = function (type, data, origin) { - var evt = document.createEvent('Event'); - - evt.initEvent(type, false, false); - switch (type) { - case 'message': - evt.data = data; - evt.origin = origin; - break; - case 'close': - evt.wasClean = data.substring(0, 1) === '1'; - evt.code = parseInt(data.substring(1, 5), 10) || 0; - evt.reason = data.substring(5); - break; - } - return evt; - }, - Blob = (function () { - if (typeof window.WebKitBlobBuilder === 'function') { - return function (data) { - var blob = new window.WebKitBlobBuilder(); - blob.append(data[0]); - return blob.getBlob(); - }; - } - return window.Blob; - }()), - binaryToString = function (data, onComplete) { - var blob, r; - - if (data instanceof window.ArrayBuffer || data.buffer instanceof window.ArrayBuffer) { - blob = new Blob([data.buffer || data]); - } else if (data instanceof window.Blob) { - blob = data; - } else { - throw new TypeError('\'%s\' is not a valid value for binaryType.'.replace('%s', typeof data)); - } - r = new window.FileReader(); - r.onload = function () { - onComplete(this.result); - }; - r.readAsDataURL(blob); - }, - stringToBinary = function (data, binaryType) { - var i, len, array; - - data = atob(data); - len = data.length; - array = new window.Uint8Array(len); - for (i = 0; i < len; i++) { - array[i] = data.charCodeAt(i); - } - if (binaryType === 'arraybuffer') { - return array.buffer; - } - if (binaryType === 'blob') { - return new Blob([array.buffer]); - } - throw new TypeError('\'%s\' is not a valid value for binaryType.'.replace('%s', binaryType)); - }, - EventTarget = function () { - this.addEventListener = function (type, listener) { - var el = listeners[this.__getId__()][type] || []; - - if (el.indexOf(listener) < 0) { - el.push(listener); - listeners[this.__getId__()][type] = el; - } - }; - this.removeEventListener = function (type, listener) { - var i, el = listeners[this.__getId__()][type] || []; - - i = el.indexOf(listener); - if (i >= 0) { - el.splice(i, 1); - } - }; - this.dispatchEvent = function (evt) { - var i, len, el = listeners[this.__getId__()][evt.type] || []; - - for (i = 0, len = el.length; i < len; i++) { - el[i].call(this, evt); - } - }; - }, - WebSocketPrototype = function () { - this.CONNECTING = 0; - this.OPEN = 1; - this.CLOSING = 2; - this.CLOSED = 3; - this.send = function (data) { - var that = this; - - if (typeof data === 'string') { - exec(null, null, 'WebSocket', 'send', [that.__getId__() + '0' + data]); - } else { - binaryToString(data, function (blob) { - exec(null, null, 'WebSocket', 'send', [that.__getId__() + '1' + blob]); - }); - } - }; - this.close = function (code, reason) { - if (this.readyState === this.CONNECTING || this.readyState === this.OPEN) { - this.readyState = this.CLOSING; - exec(null, null, 'WebSocket', 'close', [this.__getId__(), code || 0, reason || '']); - } - }; - }, - WebSocket = function (url, protocols) { - var i, len, that = this, id = ('0000000' + identifier.toString(16)).slice(-8); - - if (this === window) { - throw new TypeError('Failed to construct \'WebSocket\': ' + - 'Please use the \'new\' operator, ' + - 'this DOM object constructor cannot be called as a function.'); - } - if (!WebSocket.pluginOptions.override && BuiltinWebSocket) { - return new (BuiltinWebSocket.bind.apply(BuiltinWebSocket, [].concat(this, Array.prototype.slice.call(arguments))))(); - } - switch (arguments.length) { - case 0: - throw new TypeError('Failed to construct \'WebSocket\': 1 argument required, but only 0 present.'); - case 1: - protocols = ''; - break; - case 2: - if (!Array.isArray(protocols)) { - protocols = [protocols]; - } - for (i = 0, len = protocols.length; i < len; i++) { - if (!/^[0-9A-Za-z!#\$%&'\*\+\-\.\^_`|~]+$/.test(protocols[i])) { - throw new SyntaxError('Failed to construct \'WebSocket\': The subprotocol \'' + protocols[i] + '\' is invalid.'); - } - } - protocols = len ? protocols.join(', ') : ''; - break; - default: - throw new TypeError('Failed to construct \'WebSocket\': No matching constructor signature.'); - } - - this.url = url; - this.binaryType = Blob ? 'blob' : 'arraybuffer'; - this.readyState = 0; - this.bufferedAmount = 0; - this.onopen = null; - this.onmessage = null; - this.onerror = null; - this.onclose = null; - this.extensions = ''; - this.protocol = ''; - this.__getId__ = function () { - return id; - }; - listeners[id] = {}; - - exec(function (data) { - switch (data[0]) { - case 'O': - taskQueue.push(function () { - var evt = createMessage('open'), - param = JSON.parse(data.substring(1)); - - that.protocol = param[0]; - that.extensions = param[1]; - that.readyState = that.OPEN; - if (that.onopen) { - that.onopen(evt); - } - that.dispatchEvent(evt); - }); - break; - case 'T': - taskQueue.push(function () { - var evt = createMessage('message', data.substring(1), that.url); - - if (that.onmessage) { - that.onmessage(evt); - } - that.dispatchEvent(evt); - }); - break; - case 'B': - taskQueue.push(function () { - var evt = createMessage('message', stringToBinary(data.substring(1), that.binaryType), that.url); - - if (that.onmessage) { - that.onmessage(evt); - } - that.dispatchEvent(evt); - }); - break; - case 'C': - taskQueue.push(function () { - var evt = createMessage('close', data.substring(1)); - - that.readyState = that.CLOSED; - if (that.onclose) { - that.onclose(evt); - } - that.dispatchEvent(evt); - delete listeners[that.__getId__()]; - }); - break; - } - }, function () { - taskQueue.push(function () { - var evt = createMessage('error'); - - if (that.onerror) { - that.onerror(evt); - } - that.dispatchEvent(evt); - }); - }, 'WebSocket', 'create', [identifier++, url, protocols, location.origin, navigator.userAgent, WebSocket.pluginOptions || {}]); - }, - ver = /Chrome\/(\d+)/.exec(navigator.userAgent); - - WebSocketPrototype.prototype = new EventTarget(); - WebSocketPrototype.prototype.constructor = WebSocketPrototype; - WebSocket.prototype = new WebSocketPrototype(); - WebSocket.prototype.constructor = WebSocket; - WebSocket.pluginOptions = {}; - module.exports = WebSocket; - window.addEventListener('message', taskQueue.listener, true); - - if (!ver || parseInt(ver[1], 10) < 30) { - BuiltinWebSocket = undefined; - } -}(this)); diff --git a/plugins/cordova-plugin-whitelist/CONTRIBUTING.md b/plugins/cordova-plugin-whitelist/CONTRIBUTING.md deleted file mode 100644 index e4a178f5..00000000 --- a/plugins/cordova-plugin-whitelist/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/cordova-plugin-whitelist/LICENSE b/plugins/cordova-plugin-whitelist/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/cordova-plugin-whitelist/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/cordova-plugin-whitelist/NOTICE b/plugins/cordova-plugin-whitelist/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/cordova-plugin-whitelist/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/cordova-plugin-whitelist/README.md b/plugins/cordova-plugin-whitelist/README.md deleted file mode 100644 index def10044..00000000 --- a/plugins/cordova-plugin-whitelist/README.md +++ /dev/null @@ -1,144 +0,0 @@ -<!--- - license: 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. ---> - -# cordova-plugin-whitelist - -This plugin implements a whitelist policy for navigating the application webview on Cordova 4.0 - -## Supported Cordova Platforms - -* Android 4.0.0 or above -* iOS 4.0.0 or above - -## Navigation Whitelist -Controls which URLs the WebView itself can be navigated to. Applies to -top-level navigations only. - -Quirks: on Android it also applies to iframes for non-http(s) schemes. - -By default, navigations only to `file://` URLs, are allowed. To allow other -other URLs, you must add `<allow-navigation>` tags to your `config.xml`: - - <!-- Allow links to example.com --> - <allow-navigation href="http://example.com/*" /> - - <!-- Wildcards are allowed for the protocol, as a prefix - to the host, or as a suffix to the path --> - <allow-havigation href="*://*.example.com/*" /> - - <!-- A wildcard can be used to whitelist the entire network, - over HTTP and HTTPS. - *NOT RECOMMENDED* --> - <allow-navigation href="*" /> - - <!-- The above is equivalent to these three declarations --> - <allow-navigation href="http://*/*" /> - <allow-navigation href="https://*/*" /> - <allow-navigation href="data:*" /> - -## Intent Whitelist -Controls which URLs the app is allowed to ask the system to open. -By default, no external URLs are allowed. - -On Android, this equates to sending an intent of type BROWSEABLE. - -This whitelist does not apply to plugins, only hyperlinks and calls to `window.open()`. - -In `config.xml`, add `<allow-intent>` tags, like this: - - <!-- Allow links to web pages to open in a browser --> - <allow-intent href="http://*/*" /> - <allow-intent href="https://*/*" /> - - <!-- Allow links to example.com to open in a browser --> - <allow-intent href="http://example.com/*" /> - - <!-- Wildcards are allowed for the protocol, as a prefix - to the host, or as a suffix to the path --> - <allow-intent href="*://*.example.com/*" /> - - <!-- Allow SMS links to open messaging app --> - <allow-intent href="sms:*" /> - - <!-- Allow tel: links to open the dialer --> - <allow-intent href="tel:*" /> - - <!-- Allow geo: links to open maps --> - <allow-intent href="geo:*" /> - - <!-- Allow all unrecognized URLs to open installed apps - *NOT RECOMMENDED* --> - <allow-intent href="*" /> - -## Network Request Whitelist -Controls which network requests (images, XHRs, etc) are allowed to be made (via cordova native hooks). - -Note: We suggest you use a Content Security Policy (see below), which is more secure. This whitelist is mostly historical for webviews which do not support CSP. - -In `config.xml`, add `<access>` tags, like this: - - <!-- Allow images, xhrs, etc. to google.com --> - <access origin="http://google.com" /> - <access origin="https://google.com" /> - - <!-- Access to the subdomain maps.google.com --> - <access origin="http://maps.google.com" /> - - <!-- Access to all the subdomains on google.com --> - <access origin="http://*.google.com" /> - - <!-- Enable requests to content: URLs --> - <access origin="content:///*" /> - - <!-- Don't block any requests --> - <access origin="*" /> - -Without any `<access>` tags, only requests to `file://` URLs are allowed. However, the default Cordova application includes `<access origin="*">` by default. - -Quirk: Android also allows requests to https://ssl.gstatic.com/accessibility/javascript/android/ by default, since this is required for TalkBack to function properly. - -### Content Security Policy -Controls which network requests (images, XHRs, etc) are allowed to be made (via webview directly). - -On Android and iOS, the network request whitelist (see above) is not able to filter all types of requests (e.g. `<video>` & WebSockets are not blocked). So, in addition to the whitelist, you should use a [Content Security Policy](http://content-security-policy.com/) `<meta>` tag on all of your pages. - -On Android, support for CSP within the system webview starts with KitKat (but is available on all versions using Crosswalk WebView). - -Here are some example CSP declarations for your `.html` pages: - - <!-- Good default declaration: - * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication - * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly - * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this: - * Enable inline JS: add 'unsafe-inline' to default-src - * Enable eval(): add 'unsafe-eval' to default-src - --> - <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *"> - - <!-- Allow requests to foo.com --> - <meta http-equiv="Content-Security-Policy" content="default-src 'self' foo.com"> - - <!-- Enable all requests, inline styles, and eval() --> - <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src: 'self' 'unsafe-inline' 'unsafe-eval'"> - - <!-- Allow XHRs via https only --> - <meta http-equiv="Content-Security-Policy" content="default-src 'self' https:"> - - <!-- Allow iframe to https://cordova.apache.org/ --> - <meta http-equiv="Content-Security-Policy" content="default-src 'self'; frame-src 'self' https://cordova.apache.org"> diff --git a/plugins/cordova-plugin-whitelist/RELEASENOTES.md b/plugins/cordova-plugin-whitelist/RELEASENOTES.md deleted file mode 100644 index 703552ca..00000000 --- a/plugins/cordova-plugin-whitelist/RELEASENOTES.md +++ /dev/null @@ -1,28 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 1.0.0 (Mar 25, 2015) -* CB-8739 added missing license headers -* Add @Override to CustomConfigXmlParser methods -* Change ID to cordova-plugin-whitelist rather than reverse-DNS-style -* Tweak CSP examples in README -* CB-8660 remove extra commas from package.json diff --git a/plugins/cordova-plugin-whitelist/package.json b/plugins/cordova-plugin-whitelist/package.json deleted file mode 100644 index 2c72e256..00000000 --- a/plugins/cordova-plugin-whitelist/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "cordova-plugin-whitelist", - "version": "1.0.0", - "description": "Cordova Whitelist Plugin", - "cordova": { - "platforms": [ - "android", - "ios" - ] - }, - "repository": { - "type": "git", - "url": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-whitelist.git" - }, - "keywords": [ - "cordova", - "whitelist", - "ecosystem:cordova", - "cordova-android", - "cordova-ios" - ], - "engines": [ - { - "name": "cordova-android", - "version": ">=4.0.0-dev" - }, - { - "name": "cordova-ios", - "version": ">=4.0.0-dev" - } - ], - "author": "Apache Software Foundation", - "license": "Apache 2.0" -} diff --git a/plugins/cordova-plugin-whitelist/plugin.xml b/plugins/cordova-plugin-whitelist/plugin.xml deleted file mode 100644 index 2ec60b3c..00000000 --- a/plugins/cordova-plugin-whitelist/plugin.xml +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="cordova-plugin-whitelist" - version="1.0.0"> - <name>Whitelist</name> - <description>Cordova Network Whitelist Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,whitelist,policy</keywords> - - <engines> - <engine name="cordova-android" version=">=4.0.0-dev" /> - </engines> - - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Whitelist" > - <param name="android-package" value="org.apache.cordova.whitelist.WhitelistPlugin"/> - <param name="onload" value="true" /> - </feature> - </config-file> - - <source-file src="src/android/WhitelistPlugin.java" target-dir="src/org/apache/cordova/whitelist" /> - - <js-module src="whitelist.js" name="whitelist"> - <runs /> - </js-module> - </platform> -</plugin> diff --git a/plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java b/plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java deleted file mode 100644 index 4e4f57e1..00000000 --- a/plugins/cordova-plugin-whitelist/src/android/WhitelistPlugin.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - 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. -*/ - -package org.apache.cordova.whitelist; - -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.ConfigXmlParser; -import org.apache.cordova.Whitelist; -import org.xmlpull.v1.XmlPullParser; - -import android.content.Context; -import android.util.Log; - -public class WhitelistPlugin extends CordovaPlugin { - private static final String LOG_TAG = "WhitelistPlugin"; - private Whitelist allowedNavigations; - private Whitelist allowedIntents; - private Whitelist allowedRequests; - - // Used when instantiated via reflection by PluginManager - public WhitelistPlugin() { - } - // These can be used by embedders to allow Java-configuration of whitelists. - public WhitelistPlugin(Context context) { - this(new Whitelist(), new Whitelist(), null); - new CustomConfigXmlParser().parse(context); - } - public WhitelistPlugin(XmlPullParser xmlParser) { - this(new Whitelist(), new Whitelist(), null); - new CustomConfigXmlParser().parse(xmlParser); - } - public WhitelistPlugin(Whitelist allowedNavigations, Whitelist allowedIntents, Whitelist allowedRequests) { - if (allowedRequests == null) { - allowedRequests = new Whitelist(); - allowedRequests.addWhiteListEntry("file:///*", false); - allowedRequests.addWhiteListEntry("data:*", false); - } - this.allowedNavigations = allowedNavigations; - this.allowedIntents = allowedIntents; - this.allowedRequests = allowedRequests; - } - @Override - public void pluginInitialize() { - if (allowedNavigations == null) { - allowedNavigations = new Whitelist(); - allowedIntents = new Whitelist(); - allowedRequests = new Whitelist(); - new CustomConfigXmlParser().parse(webView.getContext()); - } - } - - private class CustomConfigXmlParser extends ConfigXmlParser { - @Override - public void handleStartTag(XmlPullParser xml) { - String strNode = xml.getName(); - if (strNode.equals("content")) { - String startPage = xml.getAttributeValue(null, "src"); - allowedNavigations.addWhiteListEntry(startPage, false); - } else if (strNode.equals("allow-navigation")) { - String origin = xml.getAttributeValue(null, "href"); - if ("*".equals(origin)) { - allowedNavigations.addWhiteListEntry("http://*/*", false); - allowedNavigations.addWhiteListEntry("https://*/*", false); - allowedNavigations.addWhiteListEntry("data:*", false); - } else { - allowedNavigations.addWhiteListEntry(origin, false); - } - } else if (strNode.equals("allow-intent")) { - String origin = xml.getAttributeValue(null, "href"); - allowedIntents.addWhiteListEntry(origin, false); - } else if (strNode.equals("access")) { - String origin = xml.getAttributeValue(null, "origin"); - String subdomains = xml.getAttributeValue(null, "subdomains"); - boolean external = (xml.getAttributeValue(null, "launch-external") != null); - if (origin != null) { - if (external) { - Log.w(LOG_TAG, "Found <access launch-external> within config.xml. Please use <allow-intent> instead."); - allowedIntents.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); - } else { - if ("*".equals(origin)) { - allowedRequests.addWhiteListEntry("http://*/*", false); - allowedRequests.addWhiteListEntry("https://*/*", false); - } else { - allowedRequests.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0)); - } - } - } - } - } - @Override - public void handleEndTag(XmlPullParser xml) { - } - } - - @Override - public Boolean shouldAllowNavigation(String url) { - if (allowedNavigations.isUrlWhiteListed(url)) { - return true; - } - return null; // Default policy - } - - @Override - public Boolean shouldAllowRequest(String url) { - if (Boolean.TRUE == shouldAllowNavigation(url)) { - return true; - } - if (allowedRequests.isUrlWhiteListed(url)) { - return true; - } - return null; // Default policy - } - - @Override - public Boolean shouldOpenExternalUrl(String url) { - if (allowedIntents.isUrlWhiteListed(url)) { - return true; - } - return null; // Default policy - } - - public Whitelist getAllowedNavigations() { - return allowedNavigations; - } - - public void setAllowedNavigations(Whitelist allowedNavigations) { - this.allowedNavigations = allowedNavigations; - } - - public Whitelist getAllowedIntents() { - return allowedIntents; - } - - public void setAllowedIntents(Whitelist allowedIntents) { - this.allowedIntents = allowedIntents; - } - - public Whitelist getAllowedRequests() { - return allowedRequests; - } - - public void setAllowedRequests(Whitelist allowedRequests) { - this.allowedRequests = allowedRequests; - } -} diff --git a/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.h b/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.h deleted file mode 100644 index d0b93654..00000000 --- a/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> -#import <Cordova/CDVWhitelist.h> - -@interface CDVNavigationWhitelistPlugin : CDVPlugin {} - -@property (nonatomic, readonly, strong) CDVWhitelist* whitelist; // readonly for public - -- (BOOL)shouldAllowNavigationToURL:(NSURL *)url; -- (BOOL)shouldAllowRequestForURL:(NSURL *)url; - -@end diff --git a/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.m b/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.m deleted file mode 100644 index 5895e89b..00000000 --- a/plugins/cordova-plugin-whitelist/src/ios/CDVNavigationWhitelistPlugin.m +++ /dev/null @@ -1,89 +0,0 @@ -/* - 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 "CDVNavigationWhitelistPlugin.h" -#import <Cordova/CDVViewController.h> - -#pragma mark CDVNavigationWhitelistConfigParser - -@interface CDVNavigationWhitelistConfigParser : NSObject <NSXMLParserDelegate> {} - -@property (nonatomic, strong) NSMutableArray* whitelistHosts; - -@end - -@implementation CDVNavigationWhitelistConfigParser - -@synthesize whitelistHosts; - -- (id)init -{ - self = [super init]; - if (self != nil) { - self.whitelistHosts = [[NSMutableArray alloc] initWithCapacity:30]; - [self.whitelistHosts addObject:@"file:///*"]; - [self.whitelistHosts addObject:@"content:///*"]; - [self.whitelistHosts addObject:@"data:///*"]; - } - return self; -} - -- (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName attributes:(NSDictionary*)attributeDict -{ - if ([elementName isEqualToString:@"allow-navigation"]) { - [whitelistHosts addObject:attributeDict[@"href"]]; - } -} - -- (void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qualifiedName -{ -} - -- (void)parser:(NSXMLParser*)parser parseErrorOccurred:(NSError*)parseError -{ - NSAssert(NO, @"config.xml parse error line %ld col %ld", (long)[parser lineNumber], (long)[parser columnNumber]); -} - - -@end - -#pragma mark CDVNavigationWhitelistPlugin - -@interface CDVNavigationWhitelistPlugin () {} -@property (nonatomic, strong) CDVWhitelist* whitelist; -@end - -@implementation CDVNavigationWhitelistPlugin - -@synthesize whitelist; - -- (void)setViewController:(UIViewController *)viewController -{ - if ([viewController isKindOfClass:[CDVViewController class]]) { - CDVWhitelistConfigParser *whitelistConfigParser = [[CDVWhitelistConfigParser alloc] init]; - [(CDVViewController *)viewController parseSettingsWithParser:whitelistConfigParser]; - self.whitelist = [[CDVWhitelist alloc] initWithArray:whitelistConfigParser.whitelistHosts]; - } -} - -- (BOOL)shouldAllowNavigationToURL:(NSURL *)url -{ - return [self.whitelist URLIsAllowed:url]; -} -@end diff --git a/plugins/cordova-plugin-whitelist/whitelist.js b/plugins/cordova-plugin-whitelist/whitelist.js deleted file mode 100644 index 74d7a99d..00000000 --- a/plugins/cordova-plugin-whitelist/whitelist.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - * -*/ - -if (!document.querySelector('meta[http-equiv=Content-Security-Policy]')) { - var msg = 'No Content-Security-Policy meta tag found. Please add one when using the cordova-plugin-whitelist plugin.'; - console.error(msg); - setInterval(function() { - console.warn(msg); - }, 10000); -} diff --git a/plugins/de.appplant.cordova.common.registerusernotificationsettings/LICENSE b/plugins/de.appplant.cordova.common.registerusernotificationsettings/LICENSE deleted file mode 100644 index 28974b74..00000000 --- a/plugins/de.appplant.cordova.common.registerusernotificationsettings/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2013-2015 appPlant UG, Inc. - - Licensed 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.
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.common.registerusernotificationsettings/README.md b/plugins/de.appplant.cordova.common.registerusernotificationsettings/README.md deleted file mode 100644 index bebb014d..00000000 --- a/plugins/de.appplant.cordova.common.registerusernotificationsettings/README.md +++ /dev/null @@ -1,25 +0,0 @@ - -Cordova RegisterUserNotificationSettings Plugin -=============================================== - -Implements didRegisterUserNotificationSettings and broadcasts the event for listening plugins. - -```obj-c -#import "AppDelegate+APPRegisterUserNotificationSettings.h" - -- (void) pluginInitialize -{ - NSNotificationCenter* center = [NSNotificationCenter - defaultCenter]; - - [center addObserver:self - selector:@selector(didRegisterUserNotificationSettings:) - name:UIApplicationRegisterUserNotificationSettings - object:nil]; -} - -- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings -{ - ... -} -```
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.common.registerusernotificationsettings/package.json b/plugins/de.appplant.cordova.common.registerusernotificationsettings/package.json deleted file mode 100644 index 9de11497..00000000 --- a/plugins/de.appplant.cordova.common.registerusernotificationsettings/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "version": "1.0.1", - "name": "de.appplant.cordova.common.registerusernotificationsettings", - "cordova_name": "RegisterUserNotificationSettings", - "description": "Implements didRegisterUserNotificationSettings and broadcasts the event.", - "license": "Apache 2.0", - "repo": "https://github.com/katzer/cordova-common-registerusernotificationsettings", - "keywords": [ - "appplant", - "didRegisterUserNotificationSettings" - ], - "platforms": [ - "ios" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ] -}
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.common.registerusernotificationsettings/plugin.xml b/plugins/de.appplant.cordova.common.registerusernotificationsettings/plugin.xml deleted file mode 100644 index 28f36358..00000000 --- a/plugins/de.appplant.cordova.common.registerusernotificationsettings/plugin.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="de.appplant.cordova.common.registerusernotificationsettings" - version="1.0.1"> - - <name>RegisterUserNotificationSettings</name> - - <description>Implements didRegisterUserNotificationSettings and broadcasts the event.</description> - - <repo>https://github.com/katzer/cordova-common-registerusernotificationsettings</repo> - - <keywords>appplant, didRegisterUserNotificationSettings</keywords> - - <license>Apache 2.0</license> - - <author>Sebastián Katzer</author> - - <!-- cordova --> - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <!-- ios --> - <platform name="ios"> - <header-file src="src/ios/AppDelegate+APPRegisterUserNotificationSettings.h" /> - <source-file src="src/ios/AppDelegate+APPRegisterUserNotificationSettings.m" /> - </platform> - -</plugin> diff --git a/plugins/de.appplant.cordova.common.registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.h b/plugins/de.appplant.cordova.common.registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.h deleted file mode 100644 index 78768260..00000000 --- a/plugins/de.appplant.cordova.common.registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "AppDelegate.h" -#import <Availability.h> - -extern NSString* const UIApplicationRegisterUserNotificationSettings; - -@interface AppDelegate (APPRegisterUserNotificationSettings) - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 -// Tells the delegate what types of notifications may be used -- (void) application:(UIApplication*)application - didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings; -#endif - -@end
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.common.registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.m b/plugins/de.appplant.cordova.common.registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.m deleted file mode 100644 index e56a084b..00000000 --- a/plugins/de.appplant.cordova.common.registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.m +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "AppDelegate+APPRegisterUserNotificationSettings.h" -#import <Availability.h> - -NSString* const UIApplicationRegisterUserNotificationSettings = @"UIApplicationRegisterUserNotificationSettings"; - -@implementation AppDelegate (APPRegisterUserNotificationSettings) - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 -/** - * Tells the delegate what types of notifications may be used - * to get the user’s attention. - */ -- (void) application:(UIApplication*)application - didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings -{ - NSNotificationCenter* center = [NSNotificationCenter - defaultCenter]; - - // re-post (broadcast) - [center postNotificationName:UIApplicationRegisterUserNotificationSettings - object:settings]; -} -#endif - -@end
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.badge/CHANGELOG.md b/plugins/de.appplant.cordova.plugin.badge/CHANGELOG.md deleted file mode 100644 index b2aba530..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/CHANGELOG.md +++ /dev/null @@ -1,83 +0,0 @@ -## ChangeLog -#### Version 0.7.1 (30.07.2015) -- Support for app icon badges on selective Android platforms thanks to [ShortcutBadger](https://github.com/leolin310148/ShortcutBadger) - - Sony - - Samsung - - LG - - HTC - - Xiaomi - - ASUS - - ADW, APEX, NOVA - -#### Version 0.7.0 (18.07.2015) -- New platform support: - - Amazon FireOS - - Browser - - Windows -- `get`, `set` and `clear` support callbacks. -- Support for [Glyphs](https://msdn.microsoft.com/de-de/library/windows/apps/hh779719#phone_badge) on _Windows_ platform. -- Added tests - -#### Version 0.6.4 (02.05.2015) -- Upgrade cordova dependency from 3.0 to 3.6 -- Fix incompatibility with local-notification plugin and PGB caused by the usage of hooks. - -#### Version 0.6.3 (22.03.2015) -- New interfaces to increase or decrease the badge number. -- Fix incompatibility with local-notification plugin. -- Add instead of replace permissions on iOS. -- Refreshed layout of the example app. - -#### Version 0.6.2 (01.03.2015) -- [change:] Renamed `promptForPermission` to `registerPermission`. Older one is still supported. -- [enhancement:] Support iOS8 and older SDK versions from a single binary. -- [enhancement:] `registerPermission` returns result of registration. -- [enhancement:] No need anymore to call `registerPermission` explicit before trying to set the badge number. - -#### Version 0.6.1 (03.10.2014) -- [bugfix:] `hasPermission` and `promptForPermission` let the app crash on iOS7 and older. - -#### Version 0.6.0 (29.09.2014) -- [enhancement:] iOS 8 support -- [enhancement:] All methods are asynchron now and do not block the main thread anymore. -- [feature:] New method `hasPermission` to ask if the user has granted to display badge notifications. -- [feature:] New method `promptForPermission` to promt the user to grant permission to display badge notifications. -- [feature:] New method `configure` to configure badge properties. -- [feature:] The small icon on Android can be changed through `configure`. -- [**change**:] The namespace `plugin.notification.badge` will be removed with v0.6.1 -- [**change**:] `setTitle` is deprecated, please use `configure({ title: 'title' })`. -- [**change**:] `clearOnTap` is deprecated, please use `configure({ autoClear: true })`. -- [bugfix:] `getBadge` still returned the number when autoClear: was set and the notification was already cleared by the system (Android). -- [bugfix:] `clean` was not working on Windows Phone. - -#### Version 0.5.3 (23.05.2014) -- Added new namespace `cordova.plugins.notification.badge`<br> - **Note:** The former `plugin.notification.badge` namespace is deprecated now and will be removed in the next major release. - -- [bugfix:] `get` returned the old value even after `clear` was called on Android. - -#### Version 0.5.2 (12.04.2014) -- [enhancement:] Badge can be cleared automatically through `setClearOnTap` -- [enhancement:] Badge can be retrieved through `get` - -#### Version 0.5.1 (25.01.2014) -- [enhancement:] Specify custom notification title on Android can be set through JS interface. -- [enhancement:] Setting launchMode to *singleInstance* isn't necessary anymore. App does not restart on click anymore. - -#### Version 0.5.0 (04.01.2014) -- Added Android support - -#### Version 0.4.1 (04.12.2013) -- Release under the Apache 2.0 license. - -#### Version 0.4.0 (07.10.2013) -- Added WP8 support -- **Note:** The former `plugin.badge` namespace is not longer available. - -#### Version 0.2.1 (15.08.2013) -- Added new namespace `plugin.notification.badge`<br> - **Note:** The former `plugin.badge` namespace is deprecated now and will be removed in the next major release. - -#### Version 0.2.0 (11.08.2013) -- Added iOS support<br> - *Based on the Badge iOS plugin made by* ***Joseph Stuhr*** diff --git a/plugins/de.appplant.cordova.plugin.badge/LICENSE b/plugins/de.appplant.cordova.plugin.badge/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.badge/README.md b/plugins/de.appplant.cordova.plugin.badge/README.md deleted file mode 100644 index e7f44ba9..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/README.md +++ /dev/null @@ -1,113 +0,0 @@ - -[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FF6GG425KEQ3E "Donate once-off to this project using Paypal") -[](http://badge.fury.io/js/de.appplant.cordova.plugin.badge) -[](https://codeclimate.com/github/katzer/cordova-plugin-badge) - -Cordova Badge Plugin -==================== - -The essential purpose of badge numbers is to enable an application to inform its users that it has something for them — for example, unread messages — when the application isn’t running in the foreground. - -<img height="150px" align="right" hspace="19" vspace="12" src="http://4.bp.blogspot.com/-GBwBSN92DvU/UB8Kut7Oz0I/AAAAAAAAJKs/mJgBmj1RKqU/s1600/whatsapp+wp8+10.png"></img> - -### How they appear to the user -Users see notifications in the following ways: -- Badging the app’s icon - - -## Supported Platforms -The current 0.7 branch does support the following platforms: -- __Amazon FireOS__ -- __Android__ -- __Browser__ -- __iOS__ -- __Windows__ -- __WP8__ and __WP8.1 Silverlight__ - -Find out more informations [here][wiki_platforms] in our wiki. - - -## Installation -The plugin is installable from source and available on Cordova Plugin Registry and PhoneGap Build. - -Find out more informations [here][wiki_installation] in our wiki. - - -## I want to get a quick overview -All wiki pages contain samples, but for a quick overview the sample section may be the fastest way. - -Find out more informations [here][wiki_samples] in our wiki. - - -## I want to get a deep overview -The plugin allows you to set, get, clear, increase and decrease the badge number. For Android the plugin offers additional configuration flags. - -Find out more about how to set, increase or decrease the badge [here][wiki_set]. - -To get a deep overview we recommend to read about all the topics in this wiki and try out the [Kitchen Sink App][wiki_kitchensink] - - -## I want to see the plugin in action -The plugin offers a kitchen sink sample app. Check out the cordova project and run the app directly from your command line or preferred IDE. - -Find out more informations [here][wiki_kitchensink] in our wiki. - - -## What's new -We are proud to announce our newest release version 0.7.x. Beside the hard work at the office and at the weekends it contains a lot of goodies, new features and easy to use APIs. - -Find out more informations [here][wiki_changelog] in our wiki. - - -## Sample -The sample demonstrates how to set a fix badge number and how to increase the current badge number. - -```javascript -// Set 10 on device ready -document.addEventListener('deviceready', function () { - cordova.plugins.notification.badge.set(10); -}, false); -``` -```javascript -// Increase the badge each time on pause -document.addEventListener('pause', function () { - cordova.plugins.notification.badge.increase(); -}, false); -``` - -Find out more informations [here][wiki_samples] in our wiki. - - -## Supporting -Your support is needed. If you use the plugin please support us in order to ensure further development and send us a drop through the donation button. - -Thank you! - -[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FF6GG425KEQ3E "Donate once-off to this project using Paypal") - - -## Contributing - -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request - - -## License - -This software is released under the [Apache 2.0 License][apache2_license]. - -© 2013-2015 appPlant UG, Inc. All rights reserved - - -[cordova]: https://cordova.apache.org -[wiki]: https://github.com/katzer/cordova-plugin-badge/wiki -[wiki_platforms]: https://github.com/katzer/cordova-plugin-badge/wiki/01.-Platforms -[wiki_installation]: https://github.com/katzer/cordova-plugin-badge/wiki/02.-Installation -[wiki_kitchensink]: https://github.com/katzer/cordova-plugin-badge/tree/example -[wiki_set]: https://github.com/katzer/cordova-plugin-badge/wiki/03.-Set-Badge -[wiki_samples]: https://github.com/katzer/cordova-plugin-badge/wiki/07.-Samples -[wiki_changelog]: https://github.com/katzer/cordova-plugin-badge/wiki/08.-Changelog -[apache2_license]: http://opensource.org/licenses/Apache-2.0 diff --git a/plugins/de.appplant.cordova.plugin.badge/package.json b/plugins/de.appplant.cordova.plugin.badge/package.json deleted file mode 100644 index 391794a7..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "version": "0.7.1", - "name": "de.appplant.cordova.plugin.badge", - "cordova_name": "Cordova Badge Plugin", - "description": "Cordova plugin to access and modify the badge number of the app icon", - "author": "Sebastián Katzer", - "license": "Apache 2.0", - "repo": "https://github.com/katzer/cordova-plugin-badge.git", - "issue": "https://github.com/katzer/cordova-plugin-badge/issues", - "keywords": [ - "appplant", - "badge", - "cordova", - "ecosystem:cordova", - "cordova-android", - "cordova-amazon-fireos", - "cordova-ios", - "cordova-wp8", - "cordova-windows", - "cordova-browser" - ], - "platforms": [ - "ios", - "wp8", - "android", - "amazon-fireos", - "browser", - "windows" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/katzer/cordova-plugin-badge.git" - } -} diff --git a/plugins/de.appplant.cordova.plugin.badge/plugin.xml b/plugins/de.appplant.cordova.plugin.badge/plugin.xml deleted file mode 100644 index 46bae990..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/plugin.xml +++ /dev/null @@ -1,201 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="de.appplant.cordova.plugin.badge" - version="0.7.1"> - - <name>Cordova Badge Plugin</name> - - <description> - Cordova plugin to access and modify the badge number of the app icon - </description> - - <repo>https://github.com/katzer/cordova-plugin-badge.git</repo> - - <issue>https://github.com/katzer/cordova-plugin-badge/issues</issue> - - <keywords>appplant, badge</keywords> - - <license>Apache 2.0</license> - - <author>Sebastián Katzer</author> - - <!-- cordova --> - <engines> - <engine name="cordova" version=">=3.0.0" /> - <engine name="cordova-android" version=">=4"/> - <engine name="cordova-plugman" version=">=4.2.0"/><!-- needed for gradleReference support --> - </engines> - - <!-- js --> - <js-module src="www/badge.js" name="Badge"> - <clobbers target="plugin.notification.badge" /> - <clobbers target="cordova.plugins.notification.badge" /> - </js-module> - - <!-- info --> - <info> - Your support is needed. If you use the badge plugin please support us in order to ensure further development. - https://github.com/katzer/cordova-plugin-badge#supporting - - Thank you! - </info> - - <!-- ios --> - <platform name="ios"> - - <dependency id="de.appplant.cordova.common.registerusernotificationsettings" /> - - <config-file target="config.xml" parent="/*"> - <feature name="Badge"> - <param name="ios-package" value="APPBadge"/> - </feature> - </config-file> - - <header-file src="src/ios/APPBadge.h" /> - <source-file src="src/ios/APPBadge.m" /> - - <header-file src="src/ios/UIApplication+APPBadge.h" /> - <source-file src="src/ios/UIApplication+APPBadge.m" /> - - </platform> - - <!-- wp8 --> - <platform name="wp8"> - - <config-file target="config.xml" parent="/*"> - <feature name="Badge"> - <param name="wp-package" value="Badge"/> - </feature> - </config-file> - - <source-file src="src/wp8/Badge.cs" /> - - </platform> - - <!-- android --> - <platform name="android"> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Badge"> - <param name="android-package" value="de.appplant.cordova.plugin.badge.Badge"/> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/manifest/application"> - <!-- - * The launch activity is triggered when a notification is clicked by a user. - * The activity launches the main activity. - --> - <activity - android:name="de.appplant.cordova.plugin.badge.LaunchActivity" - android:theme="@android:style/Theme.Black.NoTitleBar" - android:launchMode="singleInstance" - android:exported="false" /> - </config-file> - - <framework src="src/android/badge.gradle" custom="true" type="gradleReference"/> - - <source-file - src="src/android/Badge.java" - target-dir="src/de/appplant/cordova/plugin/badge" /> - - <source-file - src="src/android/BadgeImpl.java" - target-dir="src/de/appplant/cordova/plugin/badge" /> - - <source-file - src="src/android/LaunchActivity.java" - target-dir="src/de/appplant/cordova/plugin/badge" /> - - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Badge"> - <param name="android-package" value="de.appplant.cordova.plugin.badge.Badge"/> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/manifest/application"> - <!-- - * The launch activity is triggered when a notification is clicked by a user. - * The activity launches the main activity. - --> - <activity - android:name="de.appplant.cordova.plugin.badge.LaunchActivity" - android:theme="@android:style/Theme.Black.NoTitleBar" - android:launchMode="singleInstance" - android:exported="false" /> - </config-file> - - <framework src="src/android/badge.gradle" custom="true" type="gradleReference"/> - - <source-file - src="src/android/Badge.java" - target-dir="src/de/appplant/cordova/plugin/badge" /> - - <source-file - src="src/android/BadgeImpl.java" - target-dir="src/de/appplant/cordova/plugin/badge" /> - - <source-file - src="src/android/LaunchActivity.java" - target-dir="src/de/appplant/cordova/plugin/badge" /> - - </platform> - - <!-- browser --> - <platform name="browser"> - - <config-file target="config.xml" parent="/*"> - <feature name="Badge"> - <param name="browser-package" value="Badge"/> - </feature> - </config-file> - - <js-module src="src/browser/favico.min.js" name="Badge.Favico"> - <clobbers target="cordova.plugins.notification.badge.Favico" /> - </js-module> - - <js-module src="src/browser/BadgeProxy.js" name="Badge.Proxy"> - <runs /> - </js-module> - - </platform> - - <!-- windows --> - <platform name="windows"> - - <js-module src="src/windows/BadgeProxy.js" name="Badge.Proxy" > - <runs /> - </js-module> - - </platform> - -</plugin> diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/Badge.java b/plugins/de.appplant.cordova.plugin.badge/src/android/Badge.java deleted file mode 100644 index 97f710e6..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/android/Badge.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.badge; - -import android.content.Context; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.json.JSONArray; -import org.json.JSONException; - - -public class Badge extends CordovaPlugin { - - /** - * Implementation of the badge interface methods. - */ - private final BadgeImpl badgeImpl = new BadgeImpl(); - - /** - * Executes the request. - * - * @param action The action to execute. - * @param args The exec() arguments. - * @param callback The callback context used when - * calling back into JavaScript. - * - * @return - * Returning false results in a "MethodNotFound" error. - * - * @throws JSONException - */ - @Override - public boolean execute (String action, JSONArray args, CallbackContext callback) - throws JSONException { - - if (action.equalsIgnoreCase("clearBadge")) { - clearBadge(callback); - return true; - } - - if (action.equalsIgnoreCase("getBadge")) { - getBadge(callback); - return true; - } - - if (action.equalsIgnoreCase("hasPermission")) { - hasPermission(callback); - return true; - } - - if (action.equalsIgnoreCase("registerPermission")) { - hasPermission(callback); - return true; - } - - if (action.equalsIgnoreCase("setBadge")) { - setBadge(args, callback); - return true; - } - - return false; - } - - /** - * Clears the badge of the app icon. - * - * @param callback - * The function to be exec as the callback - */ - private void clearBadge (final CallbackContext callback) { - cordova.getThreadPool().execute(new Runnable() { - @Override - public void run() { - badgeImpl.clearBadge(getContext()); - badgeImpl.getBadge(callback, getContext()); - } - }); - } - - /** - * Retrieves the badge of the app icon. - * - * @param callback - * The function to be exec as the callback - */ - private void getBadge (final CallbackContext callback) { - cordova.getThreadPool().execute(new Runnable() { - @Override - public void run() { - badgeImpl.getBadge(callback, getContext()); - } - }); - } - - /** - * Informs if the app has the permission to show badges. - * - * @param callback - * The function to be exec as the callback - */ - private void hasPermission (final CallbackContext callback) { - cordova.getThreadPool().execute(new Runnable() { - @Override - public void run() { - badgeImpl.hasPermission(callback); - } - }); - } - - /** - * Sets the badge of the app icon. - * - * @param args - * The new badge number - * @param callback - * The function to be exec as the callback - */ - private void setBadge (final JSONArray args, - final CallbackContext callback) { - - cordova.getThreadPool().execute(new Runnable() { - @Override - public void run() { - badgeImpl.clearBadge(getContext()); - badgeImpl.setBadge(args, getContext()); - badgeImpl.getBadge(callback, getContext()); - } - }); - } - - /** - * Returns the context of the activity. - */ - private Context getContext () { - return cordova.getActivity(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/BadgeImpl.java b/plugins/de.appplant.cordova.plugin.badge/src/android/BadgeImpl.java deleted file mode 100644 index 9f55c920..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/android/BadgeImpl.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.badge; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Build; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; - -import me.leolin.shortcutbadger.ShortcutBadger; -import me.leolin.shortcutbadger.impl.DefaultBadger; - -/** - * Implementation of the badge interface methods. - */ -class BadgeImpl { - - /** - * The ID for the notification - */ - private final int ID = -450793490; - - /** - * The name for the shared preferences key - */ - protected static final String KEY = "badge"; - - /** - * Bundle identifier for the autoCancel value - */ - protected static final String EXTRA_AUTO_CANCEL = "EXTRA_AUTO_CANCEL"; - - /** - * Finds out if badgeing the app icon is possible on that device. - * - * @param ctx - * The application context. - * @return - * true if its supported. - */ - private boolean canBadgeAppIcon (Context ctx) { - ShortcutBadger badger = ShortcutBadger.with(ctx); - - return !(badger instanceof DefaultBadger); - } - - /** - * Clears the badge of the app icon. - * - * @param ctx - * The application context. - */ - protected void clearBadge (Context ctx) { - saveBadge(0, ctx); - getNotificationManager(ctx).cancel(ID); - ShortcutBadger.with(ctx).remove(); - } - - /** - * Retrieves the badge of the app icon. - * - * @param ctx - * The application context. - * @param callback - * The function to be exec as the callback. - */ - protected void getBadge (CallbackContext callback, Context ctx) { - SharedPreferences settings = getSharedPreferences(ctx); - int badge = settings.getInt(KEY, 0); - PluginResult result; - - result = new PluginResult(PluginResult.Status.OK, badge); - - callback.sendPluginResult(result); - } - - /** - * Sets the badge of the app icon. - * - * @param args - * The new badge number - * @param ctx - * The application context - */ - protected void setBadge (JSONArray args, Context ctx) { - int badge = args.optInt(0); - - saveBadge(badge, ctx); - - if (canBadgeAppIcon(ctx)) { - ShortcutBadger.with(ctx).count(badge); - } else { - setBadgeNotification(badge, args, ctx); - } - } - - /** - * Sets the badge of the app icon. - * - * @param args - * The new badge number - * @param ctx - * The application context - */ - @SuppressWarnings("deprecation") - private void setBadgeNotification (int badge, JSONArray args, Context ctx) { - String title = args.optString(1, "%d new messages"); - String icon = args.optString(2); - boolean autoCancel = args.optBoolean(3, false); - - Resources res = ctx.getResources(); - Bitmap appIcon = BitmapFactory.decodeResource( - res, getDrawableIcon(ctx)); - - Intent intent = new Intent(ctx, LaunchActivity.class) - .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - - intent.putExtra(EXTRA_AUTO_CANCEL, autoCancel); - - PendingIntent contentIntent = PendingIntent.getActivity( - ctx, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT); - - String title_ = String.format(title, badge); - - Notification.Builder notification = new Notification.Builder(ctx) - .setContentTitle(title_) - .setNumber(badge) - .setTicker(title_) - .setAutoCancel(autoCancel) - .setSmallIcon(getResIdForSmallIcon(icon, ctx)) - .setLargeIcon(appIcon) - .setContentIntent(contentIntent); - - if (Build.VERSION.SDK_INT<16) { - // Build notification for HoneyComb to ICS - getNotificationManager(ctx).notify(ID, notification.getNotification()); - } else if (Build.VERSION.SDK_INT>15) { - // Notification for Jellybean and above - getNotificationManager(ctx).notify(ID, notification.build()); - } - } - - /** - * Persist the badge of the app icon so that `getBadge` is able to return - * the badge number back to the client. - * - * @param badge - * The badge of the app icon. - * @param ctx - * The application context. - */ - protected void saveBadge (int badge, Context ctx) { - SharedPreferences.Editor editor = getSharedPreferences(ctx).edit(); - - editor.putInt(KEY, badge); - editor.apply(); - } - - /** - * Informs if the app has the permission to show badges. - * - * @param callback - * The function to be exec as the callback - */ - protected void hasPermission (final CallbackContext callback) { - PluginResult result = new PluginResult(PluginResult.Status.OK, true); - - callback.sendPluginResult(result); - } - - /** - * The Local storage for the application. - */ - private SharedPreferences getSharedPreferences (Context context) { - return context.getSharedPreferences(KEY, Context.MODE_PRIVATE); - } - - /** - * The NotificationManager for the app. - */ - private NotificationManager getNotificationManager (Context context) { - return (NotificationManager) context.getSystemService( - Context.NOTIFICATION_SERVICE); - } - - /** - * Returns the ID for the given resource. - * - * @return - * The resource ID of the app icon - */ - private int getDrawableIcon (Context ctx) { - Resources res = ctx.getResources(); - String pkgName = ctx.getPackageName(); - - int resId; - resId = res.getIdentifier("icon", "drawable", pkgName); - - return resId; - } - - /** - * Returns the ID for the given resource. - * - * @return - * The resource ID for the small icon. - */ - private int getResIdForSmallIcon (String smallIcon, Context ctx) { - int resId; - - String pkgName = ctx.getPackageName(); - - resId = getResId(pkgName, smallIcon); - - if (resId == 0) { - resId = getResId("android", smallIcon); - } - - if (resId == 0) { - resId = getResId("android", "ic_dialog_email"); - } - - return resId; - } - - /** - * Returns numerical icon Value. - * - * @param className - * The class name prefix either from Android or the app. - * @param iconName - * The resource name. - */ - private int getResId (String className, String iconName) { - int icon = 0; - - try { - Class<?> klass = Class.forName(className + ".R$drawable"); - - icon = (Integer) klass.getDeclaredField(iconName).get(Integer.class); - } catch (Exception ignored) {} - - return icon; - } - -} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/LaunchActivity.java b/plugins/de.appplant.cordova.plugin.badge/src/android/LaunchActivity.java deleted file mode 100644 index 8e2227fb..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/android/LaunchActivity.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.badge; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; - -public class LaunchActivity extends Activity { - - /** - * Clears the badge and moves the launch intent - * (web view) back to front. - */ - @Override - public void onCreate (Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent intent = getIntent(); - boolean cancel = intent.getBooleanExtra( - BadgeImpl.EXTRA_AUTO_CANCEL, false); - - if (cancel) { - clearBagde(); - } - - launchMainIntent(); - } - - /** - * Launch main intent for package. - */ - private void launchMainIntent () { - Context context = getApplicationContext(); - String pkgName = context.getPackageName(); - Intent intent = context.getPackageManager() - .getLaunchIntentForPackage(pkgName); - - intent.addFlags( - Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); - - context.startActivity(intent); - } - - /** - * Removes the badge of the app icon so that `getBadge` - * will return 0 back to the client. - */ - private void clearBagde () { - SharedPreferences.Editor editor = getSharedPreferences().edit(); - - editor.putInt(BadgeImpl.KEY, 0); - editor.apply(); - } - - /** - * The Local storage for the application. - */ - private SharedPreferences getSharedPreferences () { - Context context = getApplicationContext(); - - return context.getSharedPreferences(BadgeImpl.KEY, Context.MODE_PRIVATE); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/android/badge.gradle b/plugins/de.appplant.cordova.plugin.badge/src/android/badge.gradle deleted file mode 100644 index b2a7b07d..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/android/badge.gradle +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -repositories { - mavenCentral() -} - -dependencies { - compile 'me.leolin:ShortcutBadger:1.1.2@aar' -} diff --git a/plugins/de.appplant.cordova.plugin.badge/src/browser/BadgeProxy.js b/plugins/de.appplant.cordova.plugin.badge/src/browser/BadgeProxy.js deleted file mode 100644 index 44edd023..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/browser/BadgeProxy.js +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - - -/** - * Instance of the Favico.js libary. - * @type {Favico} - */ -exports.favico = new cordova.plugins.notification.badge.Favico({ - animation: 'none' -}); - -/** - * Holds the current badge number value. - * @type {Number} - */ -exports.badgeNumber = 0; - - -/** - * Clears the badge of the app icon. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.clearBadge = function (success, error) { - exports.setBadge(success, error, [0]); -}; - -/** - * Sets the badge of the app icon. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {Number} badge - * The new badge number - */ -exports.setBadge = function (success, error, args) { - var badge = args[0]; - - exports.badgeNumber = badge; - - exports.favico.badge(badge); - success(badge); -}; - -/** - * Gets the badge of the app icon. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.getBadge = function (success, error) { - success(exports.badgeNumber); -}; - -/** - * Informs if the app has the permission to show badges. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.hasPermission = function (success, error) { - success(true); -}; - -/** - * Register permission to show badges if not already granted. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.registerPermission = function (success, error) { - success(true); -}; - - -cordova.commandProxy.add('Badge', exports); diff --git a/plugins/de.appplant.cordova.plugin.badge/src/browser/favico.min.js b/plugins/de.appplant.cordova.plugin.badge/src/browser/favico.min.js deleted file mode 100644 index de0de6bc..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/browser/favico.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @license MIT - * @fileOverview Favico animations - * @author Miroslav Magda, http://blog.ejci.net - * @version 0.3.9 - */ -!function(){var e=function(e){"use strict";function t(e){if(e.paused||e.ended||g)return!1;try{f.clearRect(0,0,s,l),f.drawImage(e,0,0,s,l)}catch(o){}p=setTimeout(t,S.duration,e),O.setIcon(h)}function o(e){var t=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(t,function(e,t,o,n){return t+t+o+o+n+n});var o=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return o?{r:parseInt(o[1],16),g:parseInt(o[2],16),b:parseInt(o[3],16)}:!1}function n(e,t){var o,n={};for(o in e)n[o]=e[o];for(o in t)n[o]=t[o];return n}function r(){return b.hidden||b.msHidden||b.webkitHidden||b.mozHidden}e=e?e:{};var i,a,l,s,h,f,c,d,u,y,w,g,x,m,p,b,v={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1,dataUrl:!1,win:window};x={},x.ff="undefined"!=typeof InstallTrigger,x.chrome=!!window.chrome,x.opera=!!window.opera||navigator.userAgent.indexOf("Opera")>=0,x.ie=/*@cc_on!@*/!1,x.safari=Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>0,x.supported=x.chrome||x.ff||x.opera;var C=[];w=function(){},d=g=!1;var E=function(){i=n(v,e),i.bgColor=o(i.bgColor),i.textColor=o(i.textColor),i.position=i.position.toLowerCase(),i.animation=S.types[""+i.animation]?i.animation:v.animation,b=i.win.document;var t=i.position.indexOf("up")>-1,r=i.position.indexOf("left")>-1;if(t||r)for(var d=0;d<S.types[""+i.animation].length;d++){var u=S.types[""+i.animation][d];t&&(u.y=u.y<.6?u.y-.4:u.y-2*u.y+(1-u.w)),r&&(u.x=u.x<.6?u.x-.4:u.x-2*u.x+(1-u.h)),S.types[""+i.animation][d]=u}i.type=A[""+i.type]?i.type:v.type,a=O.getIcon(),h=document.createElement("canvas"),c=document.createElement("img"),a.hasAttribute("href")?(c.setAttribute("crossOrigin","anonymous"),c.setAttribute("src",a.getAttribute("href")),c.onload=function(){l=c.height>0?c.height:32,s=c.width>0?c.width:32,h.height=l,h.width=s,f=h.getContext("2d"),M.ready()}):(c.setAttribute("src",""),l=32,s=32,c.height=l,c.width=s,h.height=l,h.width=s,f=h.getContext("2d"),M.ready())},M={};M.ready=function(){d=!0,M.reset(),w()},M.reset=function(){d&&(C=[],u=!1,y=!1,f.clearRect(0,0,s,l),f.drawImage(c,0,0,s,l),O.setIcon(h),window.clearTimeout(m),window.clearTimeout(p))},M.start=function(){if(d&&!y){var e=function(){u=C[0],y=!1,C.length>0&&(C.shift(),M.start())};if(C.length>0){y=!0;var t=function(){["type","animation","bgColor","textColor","fontFamily","fontStyle"].forEach(function(e){e in C[0].options&&(i[e]=C[0].options[e])}),S.run(C[0].options,function(){e()},!1)};u?S.run(u.options,function(){t()},!0):t()}}};var A={},I=function(e){return e.n="number"==typeof e.n?Math.abs(0|e.n):e.n,e.x=s*e.x,e.y=l*e.y,e.w=s*e.w,e.h=l*e.h,e.len=(""+e.n).length,e};A.circle=function(e){e=I(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),f.clearRect(0,0,s,l),f.drawImage(c,0,0,s,l),f.beginPath(),f.font=i.fontStyle+" "+Math.floor(e.h*(e.n>99?.85:1))+"px "+i.fontFamily,f.textAlign="center",t?(f.moveTo(e.x+e.w/2,e.y),f.lineTo(e.x+e.w-e.h/2,e.y),f.quadraticCurveTo(e.x+e.w,e.y,e.x+e.w,e.y+e.h/2),f.lineTo(e.x+e.w,e.y+e.h-e.h/2),f.quadraticCurveTo(e.x+e.w,e.y+e.h,e.x+e.w-e.h/2,e.y+e.h),f.lineTo(e.x+e.h/2,e.y+e.h),f.quadraticCurveTo(e.x,e.y+e.h,e.x,e.y+e.h-e.h/2),f.lineTo(e.x,e.y+e.h/2),f.quadraticCurveTo(e.x,e.y,e.x+e.h/2,e.y)):f.arc(e.x+e.w/2,e.y+e.h/2,e.h/2,0,2*Math.PI),f.fillStyle="rgba("+i.bgColor.r+","+i.bgColor.g+","+i.bgColor.b+","+e.o+")",f.fill(),f.closePath(),f.beginPath(),f.stroke(),f.fillStyle="rgba("+i.textColor.r+","+i.textColor.g+","+i.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?f.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):f.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),f.closePath()},A.rectangle=function(e){e=I(e);var t=!1;2===e.len?(e.x=e.x-.4*e.w,e.w=1.4*e.w,t=!0):e.len>=3&&(e.x=e.x-.65*e.w,e.w=1.65*e.w,t=!0),f.clearRect(0,0,s,l),f.drawImage(c,0,0,s,l),f.beginPath(),f.font=i.fontStyle+" "+Math.floor(e.h*(e.n>99?.9:1))+"px "+i.fontFamily,f.textAlign="center",f.fillStyle="rgba("+i.bgColor.r+","+i.bgColor.g+","+i.bgColor.b+","+e.o+")",f.fillRect(e.x,e.y,e.w,e.h),f.fillStyle="rgba("+i.textColor.r+","+i.textColor.g+","+i.textColor.b+","+e.o+")","number"==typeof e.n&&e.n>999?f.fillText((e.n>9999?9:Math.floor(e.n/1e3))+"k+",Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.2*e.h)):f.fillText(e.n,Math.floor(e.x+e.w/2),Math.floor(e.y+e.h-.15*e.h)),f.closePath()};var T=function(e,t){t=("string"==typeof t?{animation:t}:t)||{},w=function(){try{if("number"==typeof e?e>0:""!==e){var n={type:"badge",options:{n:e}};if("animation"in t&&S.types[""+t.animation]&&(n.options.animation=""+t.animation),"type"in t&&A[""+t.type]&&(n.options.type=""+t.type),["bgColor","textColor"].forEach(function(e){e in t&&(n.options[e]=o(t[e]))}),["fontStyle","fontFamily"].forEach(function(e){e in t&&(n.options[e]=t[e])}),C.push(n),C.length>100)throw new Error("Too many badges requests in queue.");M.start()}else M.reset()}catch(r){throw new Error("Error setting badge. Message: "+r.message)}},d&&w()},U=function(e){w=function(){try{var t=e.width,o=e.height,n=document.createElement("img"),r=o/l>t/s?t/s:o/l;n.setAttribute("crossOrigin","anonymous"),n.setAttribute("src",e.getAttribute("src")),n.height=o/r,n.width=t/r,f.clearRect(0,0,s,l),f.drawImage(n,0,0,s,l),O.setIcon(h)}catch(i){throw new Error("Error setting image. Message: "+i.message)}},d&&w()},R=function(e){w=function(){try{if("stop"===e)return g=!0,M.reset(),void(g=!1);e.addEventListener("play",function(){t(this)},!1)}catch(o){throw new Error("Error setting video. Message: "+o.message)}},d&&w()},L=function(e){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(e){return e}),x.supported){var o=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,w=function(){try{if("stop"===e)return g=!0,M.reset(),void(g=!1);o=document.createElement("video"),o.width=s,o.height=l,navigator.getUserMedia({video:!0,audio:!1},function(e){o.src=URL.createObjectURL(e),o.play(),t(o)},function(){})}catch(n){throw new Error("Error setting webcam. Message: "+n.message)}},d&&w()}},O={};O.getIcon=function(){var e=!1,t=function(){for(var e=b.getElementsByTagName("head")[0].getElementsByTagName("link"),t=e.length,o=t-1;o>=0;o--)if(/(^|\s)icon(\s|$)/i.test(e[o].getAttribute("rel")))return e[o];return!1};return i.element?e=i.element:i.elementId?(e=b.getElementById(i.elementId),e.setAttribute("href",e.getAttribute("src"))):(e=t(),e===!1&&(e=b.createElement("link"),e.setAttribute("rel","icon"),b.getElementsByTagName("head")[0].appendChild(e))),e.setAttribute("type","image/png"),e},O.setIcon=function(e){var t=e.toDataURL("image/png");if(i.dataUrl&&i.dataUrl(t),i.element)i.element.setAttribute("href",t),i.element.setAttribute("src",t);else if(i.elementId){var o=b.getElementById(i.elementId);o.setAttribute("href",t),o.setAttribute("src",t)}else if(x.ff||x.opera){var n=a;a=b.createElement("link"),x.opera&&a.setAttribute("rel","icon"),a.setAttribute("rel","icon"),a.setAttribute("type","image/png"),b.getElementsByTagName("head")[0].appendChild(a),a.setAttribute("href",t),n.parentNode&&n.parentNode.removeChild(n)}else a.setAttribute("href",t)};var S={};return S.duration=40,S.types={},S.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],S.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],S.run=function(e,t,o,a){var l=S.types[r()?"none":i.animation];return a=o===!0?"undefined"!=typeof a?a:l.length-1:"undefined"!=typeof a?a:0,t=t?t:function(){},a<l.length&&a>=0?(A[i.type](n(e,l[a])),m=setTimeout(function(){o?a-=1:a+=1,S.run(e,t,o,a)},S.duration),O.setIcon(h),void 0):void t()},E(),{badge:T,video:R,image:U,webcam:L,reset:M.reset,browser:{supported:x.supported}}};"undefined"!=typeof define&&define.amd?define([],function(){return e}):"undefined"!=typeof module&&module.exports?module.exports=e:this.Favico=e}(); diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.h b/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.h deleted file mode 100644 index bf9a1e58..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import <Foundation/Foundation.h> -#import <Cordova/CDVPlugin.h> - -@interface APPBadge : CDVPlugin - -// Clears the badge of the app icon -- (void) clearBadge:(CDVInvokedUrlCommand *)command; -// Sets the badge of the app icon -- (void) setBadge:(CDVInvokedUrlCommand *)command; -// Gets the badge of the app icon -- (void) getBadge:(CDVInvokedUrlCommand *)command; -// Informs if the app has the permission to show badges -- (void) hasPermission:(CDVInvokedUrlCommand *)command; -// Register permission to show badges -- (void) registerPermission:(CDVInvokedUrlCommand *)command; - -@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.m b/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.m deleted file mode 100644 index e7db643f..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/ios/APPBadge.m +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "APPBadge.h" -#import "UIApplication+APPBadge.h" -#import "AppDelegate+APPRegisterUserNotificationSettings.h" - -@interface APPBadge () - -// Needed when calling `registerPermission` -@property (nonatomic, retain) CDVInvokedUrlCommand* command; - -@end - -@implementation APPBadge - -#pragma mark - -#pragma mark Interface - -/** - * Clears the badge of the app icon. - * - */ -- (void) clearBadge:(CDVInvokedUrlCommand *)command -{ - [self.commandDelegate runInBackground:^{ - [self.app setApplicationIconBadgeNumber:0]; - - [self sendPluginResult:CDVCommandStatus_OK - messageAsLong:0 - callbackId:command.callbackId]; - }]; -} - -/** - * Sets the badge of the app icon. - * - * @param badge - * The badge to be set - */ -- (void) setBadge:(CDVInvokedUrlCommand *)command -{ - NSArray* args = [command arguments]; - int number = [[args objectAtIndex:0] intValue]; - - [self.commandDelegate runInBackground:^{ - [self.app setApplicationIconBadgeNumber:number]; - - [self sendPluginResult:CDVCommandStatus_OK - messageAsLong:number - callbackId:command.callbackId]; - }]; -} - -/** - * Gets the badge of the app icon. - * - * @param callback - * The function to be exec as the callback - */ -- (void) getBadge:(CDVInvokedUrlCommand *)command -{ - [self.commandDelegate runInBackground:^{ - long badge = [self.app applicationIconBadgeNumber]; - - [self sendPluginResult:CDVCommandStatus_OK - messageAsLong:badge - callbackId:command.callbackId]; - }]; -} - -/** - * Informs if the app has the permission to show badges. - * - * @param callback - * The function to be exec as the callback - */ -- (void) hasPermission:(CDVInvokedUrlCommand *)command -{ - [self.commandDelegate runInBackground:^{ - BOOL hasPermission = [self.app hasPermissionToDisplayBadges]; - - [self sendPluginResult:CDVCommandStatus_OK - messageAsBool:hasPermission - callbackId:command.callbackId]; - }]; -} - -/** - * Register permission to show badges. - * - * @param callback - * The function to be exec as the callback - */ -- (void) registerPermission:(CDVInvokedUrlCommand *)command -{ - if (![[UIApplication sharedApplication] - respondsToSelector:@selector(registerUserNotificationSettings:)]) - { - return [self hasPermission:command]; - } - - _command = command; - - [self.commandDelegate runInBackground:^{ - [self.app registerPermissionToDisplayBadges]; - }]; -} - -#pragma mark - -#pragma mark Delegates - -/** - * Called on otification settings registration is completed. - */ -- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings -{ - if (_command) - { - [self hasPermission:_command]; - _command = NULL; - } -} - -#pragma mark - -#pragma mark Life Cycle - -/** - * Registers obervers after plugin was initialized. - */ -- (void) pluginInitialize -{ - NSNotificationCenter* center = [NSNotificationCenter - defaultCenter]; - - [center addObserver:self - selector:@selector(didRegisterUserNotificationSettings:) - name:UIApplicationRegisterUserNotificationSettings - object:nil]; -} - -#pragma mark - -#pragma mark Helper - -/** - * Short hand for shared application instance. - */ -- (UIApplication*) app -{ - return [UIApplication sharedApplication]; -} - -/** - * Sends a plugin result with the specified status and message. - */ -- (void) sendPluginResult:(CDVCommandStatus)status - messageAsBool:(BOOL)msg - callbackId:(NSString*)callbackId -{ - CDVPluginResult* result; - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsBool:msg]; - - [self.commandDelegate sendPluginResult:result - callbackId:callbackId]; -} - -/** - * Sends a plugin result with the specified status and message. - */ -- (void) sendPluginResult:(CDVCommandStatus)status - messageAsLong:(long)msg - callbackId:(NSString*)callbackId -{ - CDVPluginResult* result; - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDouble:msg]; - - [self.commandDelegate sendPluginResult:result - callbackId:callbackId]; -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.h b/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.h deleted file mode 100644 index 9ce7f7e5..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -@interface UIApplication (APPBadge) - -// If the app has the permission to display badges -- (BOOL) hasPermissionToDisplayBadges; -// Ask for permission to display badges -- (void) registerPermissionToDisplayBadges; - -@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.m b/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.m deleted file mode 100644 index 3e4cd99b..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/ios/UIApplication+APPBadge.m +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "UIApplication+APPBadge.h" - -@implementation UIApplication (APPBadge) - -#pragma mark - -#pragma mark Permissions - -/** - * If the app has the permission to display badges. - */ -- (BOOL) hasPermissionToDisplayBadges -{ - if (![self respondsToRegisterUserNotificationSettings]) - return YES; - - UIUserNotificationSettings *settings; - - settings = [[UIApplication sharedApplication] - currentUserNotificationSettings]; - - return (settings.types & UIUserNotificationTypeBadge); -} - -/** - * Register permission to display badges. - */ -- (void) registerPermissionToDisplayBadges -{ - if (![self respondsToRegisterUserNotificationSettings]) - return; - - UIUserNotificationType types; - UIUserNotificationSettings *settings; - - settings = [[UIApplication sharedApplication] - currentUserNotificationSettings]; - - types = settings.types | UIUserNotificationTypeBadge; - - settings = [UIUserNotificationSettings settingsForTypes:types - categories:nil]; - - [[UIApplication sharedApplication] - registerUserNotificationSettings:settings]; -} - -#pragma mark - -#pragma mark Helper methods - -/** - * If UIApplication responds to seelctor registerUserNotificationSettings: - * - * @return - * true for iOS8 and above - */ -- (BOOL) respondsToRegisterUserNotificationSettings -{ - return [[UIApplication sharedApplication] - respondsToSelector:@selector(registerUserNotificationSettings:)]; -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.badge/src/windows/BadgeProxy.js b/plugins/de.appplant.cordova.plugin.badge/src/windows/BadgeProxy.js deleted file mode 100644 index 33029f2c..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/windows/BadgeProxy.js +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - - -/** - * Clears the badge of the app icon. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.clearBadge = function (success, error) { - exports.setBadge(success, error, [0]); -}; - -/** - * Gets the badge of the app icon. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.getBadge = function (success, error) { - var app = WinJS.Application, - file = exports._cordova_badge_number; - - app.local.exists(file).then(function (exists) { - if (exists) { - app.local.readText(file).then(function (badge) { - success(isNaN(badge) ? badge : Number(badge)); - }); - } else { - success(0); - } - }); -}; - -/** - * Informs if the app has the permission to show badges. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.hasPermission = function (success, error) { - success(true); -}; - -/** - * Register permission to show badges if not already granted. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.registerPermission = function (success, error) { - exports.hasPermission(success, error); -}; - -/** - * Sets the badge of the app icon. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {Number} badge - * The new badge number - */ -exports.setBadge = function (success, error, args) { - var notifications = Windows.UI.Notifications, - badge = args[0], - type = notifications.BadgeTemplateType.badgeNumber, - xml = notifications.BadgeUpdateManager.getTemplateContent(type), - attrs = xml.getElementsByTagName('badge'), - notification = new notifications.BadgeNotification(xml); - - attrs[0].setAttribute('value', badge); - - notifications.BadgeUpdateManager - .createBadgeUpdaterForApplication() - .update(notification); - - exports._saveBadge(badge); - - success(badge); -}; - - -/******** - * UTIL * - ********/ - -/** - * Path to file that containes the badge number. - * @type {String} - */ -exports._cordova_badge_number = 'cordova_badge_number'; - -/** - * Persist the badge of the app icon so that `getBadge` is able to return the - * badge number back to the client. - * - * @param {Number|String} badge - * The badge number to save for. - * - * @return void - */ -exports._saveBadge = function (badge) { - WinJS.Application.local.writeText(exports._cordova_badge_number, badge); -}; - - -cordova.commandProxy.add('Badge', exports); diff --git a/plugins/de.appplant.cordova.plugin.badge/src/wp8/Badge.cs b/plugins/de.appplant.cordova.plugin.badge/src/wp8/Badge.cs deleted file mode 100644 index eb384c38..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/src/wp8/Badge.cs +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -using System; -using System.Linq; - -using Microsoft.Phone.Shell; - -using WPCordovaClassLib.Cordova; -using WPCordovaClassLib.Cordova.Commands; -using WPCordovaClassLib.Cordova.JSON; -using System.IO.IsolatedStorage; - -namespace Cordova.Extension.Commands -{ - public class Badge : BaseCommand - { - - /// <summary> - /// Name for the shared preferences - /// <summary> - private const string KEY = "badge"; - - /// <summary> - /// Clears the count property of the live tile - /// </summary> - public void clearBadge (string args) - { - setBadge(args); - getBadge(args); - } - - /// <summary> - /// Sets the count property of the live tile - /// </summary> - public void setBadge (string args) - { - // Application Tile is always the first Tile, even if it is not pinned to Start. - ShellTile tile = ShellTile.ActiveTiles.First(); - - // Application should always be found - if (tile != null) - { - string[] ary = JsonHelper.Deserialize<string[]>(args); - int count = 0; - string title = ""; - - try { - count = int.Parse(ary[0]); - } - catch (FormatException) { }; - - if (ary.Length > 1) - { - title = ary[1].Replace("%d", "{0}"); - title = String.Format(title, count); - } - - StandardTileData TileData = new StandardTileData - { - Count = count, - BackTitle = title - }; - - SaveBadge(count); - - tile.Update(TileData); - } - - getBadge(args); - } - - /// <summary> - /// Gets the count property of the live tile - /// </summary> - public void getBadge (string args) - { - // Application Tile is always the first Tile, even if it is not pinned to Start. - ShellTile tile = ShellTile.ActiveTiles.First(); - - // Application should always be found - if (tile != null) - { - IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings; - int badge = 0; - PluginResult result; - - if (settings.Contains(KEY)) { - badge = (int)settings[KEY]; - } - - result = new PluginResult(PluginResult.Status.OK, badge); - - DispatchCommandResult(result); - } - } - - /// <summery> - /// Informs if the app has the permission to show badges. - /// </summery> - public void hasPermission (string args) - { - PluginResult result; - - result = new PluginResult(PluginResult.Status.OK, true); - - DispatchCommandResult(result); - } - - /// <summery> - /// Ask for permission to show badges. - /// </summery> - public void registerPermission (string args) - { - hasPermission(args); - } - - /// <summary> - /// Persist the badge of the app icon so that `getBadge` is able to return - /// the badge number back to the client. - /// </summary> - private void SaveBadge (int badge) - { - IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings; - - if (settings.Contains(KEY)) { - settings[KEY] = badge; - } - else { - settings.Add(KEY, badge); - } - } - - } -} diff --git a/plugins/de.appplant.cordova.plugin.badge/tests/plugin.xml b/plugins/de.appplant.cordova.plugin.badge/tests/plugin.xml deleted file mode 100644 index f8d815bf..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/tests/plugin.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="de.appplant.cordova.plugin.badge-tests" - version="0.7.0dev"> - - <name>Cordova Badge Plugin Tests</name> - <license>Apache 2.0</license> - - <js-module src="tests.js" name="tests" /> -</plugin> diff --git a/plugins/de.appplant.cordova.plugin.badge/tests/tests.js b/plugins/de.appplant.cordova.plugin.badge/tests/tests.js deleted file mode 100644 index 473cd02a..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/tests/tests.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - - -exports.defineAutoTests = function() { - - describe('Badge Plugin (cordova.plugins.notification.badge)', function () { - - describe('Plugin availability', function () { - - it("should exist", function() { - expect(cordova.plugins.notification.badge).toBeDefined(); - }); - - it("should define clear", function() { - expect(cordova.plugins.notification.badge.clear).toBeDefined(); - }); - - it("should define get", function() { - expect(cordova.plugins.notification.badge.get).toBeDefined(); - }); - - it("should define set", function() { - expect(cordova.plugins.notification.badge.set).toBeDefined(); - }); - - it("should define increase", function() { - expect(cordova.plugins.notification.badge.increase).toBeDefined(); - }); - - it("should define decrease", function() { - expect(cordova.plugins.notification.badge.decrease).toBeDefined(); - }); - - it("should define hasPermission", function() { - expect(cordova.plugins.notification.badge.hasPermission).toBeDefined(); - }); - - it("should define registerPermission", function() { - expect(cordova.plugins.notification.badge.registerPermission).toBeDefined(); - }); - - it("should define configure", function() { - expect(cordova.plugins.notification.badge.configure).toBeDefined(); - }); - - }); - - describe('API callbacks', function () { - - it("clear should invoke callback", function(done) { - cordova.plugins.notification.badge.clear(done); - }); - - it("get should invoke callback", function(done) { - cordova.plugins.notification.badge.get(done); - }); - - it("set should invoke callback", function(done) { - cordova.plugins.notification.badge.set(done); - }); - - it("increase should invoke callback", function(done) { - cordova.plugins.notification.badge.increase(done); - }); - - it("decrease should invoke callback", function(done) { - cordova.plugins.notification.badge.decrease(done); - }); - - it("hasPermission should invoke callback", function(done) { - cordova.plugins.notification.badge.hasPermission(done); - }); - - it("registerPermission should invoke callback", function(done) { - cordova.plugins.notification.badge.registerPermission(done); - }); - - }); - - describe('API functions', function () { - - it("clear should set badge to 0", function(done) { - cordova.plugins.notification.badge.clear(function (badge) { - expect(badge).toBe(0); - done(); - }); - }); - - it("should return badge", function(done) { - cordova.plugins.notification.badge.set(10, function (badge) { - expect(badge).toBe(10); - - cordova.plugins.notification.badge.get(function (badge2) { - expect(badge).toBe(badge2); - done(); - }); - }); - }); - - it("should increase badge", function(done) { - cordova.plugins.notification.badge.set(10, function () { - cordova.plugins.notification.badge.increase(1, function (badge) { - expect(badge).toBe(11); - done(); - }); - }); - }); - - it("should decrease badge", function(done) { - cordova.plugins.notification.badge.set(10, function () { - cordova.plugins.notification.badge.decrease(1, function (badge) { - expect(badge).toBe(9); - done(); - }); - }); - }); - - it("hasPermission should return boolean", function(done) { - cordova.plugins.notification.badge.hasPermission(function (has) { - expect(has === true || has === false).toBe(true); - done(); - }); - }); - - it("registerPermission should return boolean", function(done) { - cordova.plugins.notification.badge.registerPermission(function (has) { - expect(has === true || has === false).toBe(true); - done(); - }); - }); - - }); - - }); -}; diff --git a/plugins/de.appplant.cordova.plugin.badge/www/badge.js b/plugins/de.appplant.cordova.plugin.badge/www/badge.js deleted file mode 100644 index ab6177cc..00000000 --- a/plugins/de.appplant.cordova.plugin.badge/www/badge.js +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -var exec = require('cordova/exec'), - channel = require('cordova/channel'); - - -/************* - * INTERFACE * - *************/ - -/** - * Clears the badge of the app icon. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.clear = function (callback, scope) { - this.exec('clearBadge', null, callback, scope); -}; - -/** - * Sets the badge of the app icon. - * - * @param {Number} badge - * The new badge number - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.set = function (badge, callback, scope) { - var args = [ - parseInt(badge) || 0, - this._config.title, - this._config.smallIcon, - this._config.autoClear - ]; - - this.registerPermission(function (granted) { - if (granted) { - this.exec('setBadge', args, callback, scope); - } - }, this); -}; - -/** - * Gets the badge of the app icon. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.get = function (callback, scope) { - this.exec('getBadge', null, callback, scope); -}; - -/** - * Increases the badge number. - * - * @param {Number} count - * Count to add to the current badge number - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.increase = function (count, callback, scope) { - this.get(function (badge) { - this.set(badge + (count || 1), callback, scope); - }, this); -}; - -/** - * Decreases the badge number. - * - * @param {Number} count - * Count to subtract from the current badge number - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.decrease = function (count, callback, scope) { - this.get(function (badge) { - this.set(Math.max(0, badge - (count || 1)), callback, scope); - }, this); -}; - -/** - * Informs if the app has the permission to show badges. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.hasPermission = function (callback, scope) { - this.exec('hasPermission', null, callback, scope); -}; - -/** - * Register permission to show badges if not already granted. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.registerPermission = function (callback, scope) { - this.exec('registerPermission', null, callback, scope); -}; - -/** - * Configures the plugin's platform options. - * - * @param {Hash?} object - * The new configuration settings - * - * @return {Hash} - * The current configuration settings - */ -exports.configure = function (config) { - for (var key in config) { - if (this._config.hasOwnProperty(key)) { - this._config[key] = config[key]; - } - } - - return this._config; -}; - - -/**************** - * DEPRECATIONS * - ****************/ - -/** - * Sets the custom notification title for Android. - * - * @param {String} title - * The title of the notification - */ -exports.setTitle = function (title) { - console.warn('badge.setTitle(title) is deprecated! Please use badge.configure({ title:title }) instead.'); - - this._config.title = title; -}; - -/** - * Tells the plugin if the badge needs to be cleared when the user taps - * the icon. - * - * @param {Boolean} clearOnTap - * Either true or false - */ -exports.setClearOnTap = function (clearOnTap) { - console.warn('badge.clearOnTap(bool) is deprecated! Please use badge.configure({ autoClear:bool }) instead.'); - - this._config.autoClear = clearOnTap; -}; - -/** - * Register permission to show notifications - * if not already granted. - */ -exports.promptForPermission = function () { - console.warn('Depreated: Please use `notification.badge.registerPermission` instead.'); - - this.registerPermission.apply(this, arguments); -}; - - -/*********** - * MEMBERS * - ***********/ - -exports._config = { - // Titel der Meldung für Android - title: '%d new messages', - // Ob die Badge Zahl automatisch beim Öffnen der App gelöscht werden soll - autoClear: false, - // Ob und welches Icon für Android verwendet werden soll - smallIcon: 'ic_dialog_email' -}; - - -/******** - * UTIL * - ********/ - -/** - * Create callback, which will be executed within a specific scope. - * - * @param {Function} callbackFn - * The callback function - * @param {Object} scope - * The scope for the function - * - * @return {Function} - * The new callback function - */ -exports.createCallbackFn = function (callbackFn, scope) { - if (typeof callbackFn != 'function') - return; - - return function () { - callbackFn.apply(scope || this, arguments); - }; -}; - -/** - * Execute the native counterpart. - * - * @param {String} action - * The name of the action - * @param args[] - * Array of arguments - * @param {Function} callback - * The callback function - * @param {Object} scope - * The scope for the function - */ -exports.exec = function (action, args, callback, scope) { - var fn = this.createCallbackFn(callback, scope), - params = []; - - if (Array.isArray(args)) { - params = args; - } else if (args) { - params.push(args); - } - - exec(fn, null, 'Badge', action, params); -}; - - -/********* - * HOOKS * - *********/ - -channel.onCordovaReady.subscribe(function () { - if (exports._config.autoClear) { exports.clear(); } -}); - -channel.onResume.subscribe(function () { - if (exports._config.autoClear) { exports.clear(); } -}); diff --git a/plugins/de.appplant.cordova.plugin.email-composer/CHANGELOG.md b/plugins/de.appplant.cordova.plugin.email-composer/CHANGELOG.md deleted file mode 100644 index 4c8908b0..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/CHANGELOG.md +++ /dev/null @@ -1,63 +0,0 @@ -## ChangeLog -#### Version 0.8.2 (01.03.2015) -- Added new namespace `cordova.plugins.email`<br> - **Note:** The former `plugin.email` namespace is now deprecated and will be removed with the next major release. -- [___change:___] Unified `absolute:` and `relative:` to `file:` -- [___change:___] Renamed `isServiceAvailable` to `isAvailable` -- [feature:] `app:` allows to specify target mail app on Android -- [feature:] `res:` prefix for native ressource attachments -- [enhancement:] Support attachments on Windows Phone 8.1 -- [enhancement:] `open` supports callbacks -- [enhancement:] `isHTML` can be used next `isHtml` -- [enhancement:] Set mime type to binary if unknown -- [bugfix:] Defaults were ignored - -#### Version 0.8.1 (06.04.2014) -- [enhancement:] Make use Cordovas NSData+Base64 extension. -- [enhancement:] Log error message if attachment path does not exist. -- [feature:] Add support for amazon fire -- [bugfix:] Fix INSTALL_FAILED_CONFLICTING_PROVIDER error -- [bugfix:] `relative://` attachment path wasnt working due to a missing permission. -- [bugfix:] `base64://` attachment path looked up in the wrong directory. -- [enhancement:] `relative://` supports now any file types and not only images. -- [___change:___] `relative://` URI's even for Android need a file extension. - -#### Version 0.8.0 (02.03.2014) -- [enhancement:] New `absolute://` and `relative://` attachment prefixes. -- [feature:] New `base64://` prefix to attach base64 encoded data streams. - -#### Version 0.7.2 (01.03.2014) -- [enhancement:] Attachments are added with their real name. - -#### Version 0.7.1 (17.12.2013) -- [bugfix:] Only the last attachment was added to the email composer on android. - -#### Version 0.7.0 (05.12.2013) -- Release under the Apache 2.0 license. -- [___change:___] Removed the `callback` property from the `open` interface. -- [___change:___] Renamed the properties `recipients`, `ccRecipients`, `bccRecipients`. -- [bugfix:] Plugin under WP8 throws an error, if recipients were given as arrays. -- [enhancement:] `open` does not block the ui thread on iOS & Android anymore. - -#### Version 0.6.0 (17.11.2013) -- Added WP8 support -- [***deprecated:***] The `callback` property will be removed with v0.7.0. - -#### Version 0.4.2 (17.11.2013) -- [feature:] Added alias `openDraft` to the `open` interface. - -#### Version 0.4.1 (03.11.2013) -- [bugfix]: On Android, the `isServiceAvailable()` interface has returned string values instead of boolean values. -- [bugfix]: Sometimes the device said that no email app is available because of the missing mime type. - -#### Version 0.4.0 (20.08.2013) -- Added Android support<br> - *Based on the EmailComposerWithAttachments Android plugin made by* ***guidosabatini*** - -#### Version 0.2.1 (15.08.2013) -- [bugfix]: Email was not send in HTML format, if the `isHtml` flag was set. -- [bugfix]: `email.open()` without a parameter throw an error. - -#### Version 0.2.0 (13.08.2013) -- Added iOS support<br> - *Based on the EmailComposer(WithAttachments) iOS plugin made by* ***Randy McMillan*** *and* ***guidosabatini***
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.email-composer/LICENSE b/plugins/de.appplant.cordova.plugin.email-composer/LICENSE deleted file mode 100644 index c0bcf461..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2013-2015 appPlant UG - - Licensed 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.
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.email-composer/README.md b/plugins/de.appplant.cordova.plugin.email-composer/README.md deleted file mode 100644 index ef01b5f0..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/README.md +++ /dev/null @@ -1,332 +0,0 @@ - -<p align="right"> - <a href="https://github.com/katzer/cordova-plugin-email-composer/tree/example">EXAMPLE :point_right:</a> -</p> - -Cordova Email Plugin -==================== - -<img width="260px" align="right" hspace="7" vspace="5" src="http://flashsimulations.com/wp-content/uploads/2011/12/air-ios-in-app-mail-app.png"> - -The plugin provides access to the standard interface that manages the editing and sending an email message. You can use this view controller to display a standard email view inside your application and populate the fields of that view with initial values, such as the subject, email recipients, body text, and attachments. The user can edit the initial contents you specify and choose to send the email or cancel the operation. - -Using this interface does not guarantee immediate delivery of the corresponding email message. The user may cancel the creation of the message, and if the user does choose to send the message, the message is only queued in the Mail application outbox. This allows you to generate emails even in situations where the user does not have network access, such as in airplane mode. This interface does not provide a way for you to verify whether emails were actually sent. - - -### Plugin's Purpose -The purpose of the plugin is to create an platform independent javascript interface for [Cordova][cordova] based mobile applications to access the specific email composition API on each platform. - - -## Overview -1. [Supported Platforms](#supported-platforms) -2. [Installation](#installation) -3. [ChangeLog](#changelog) -4. [Using the plugin](#using-the-plugin) -5. [Examples](#examples) -6. [Quirks](#quirks) - - -## Supported Platforms -- __iOS__ _(up to iOS8)_ -- __Android__ _(up to KitKat and L)_ -- __WP 8.0__ and __WP 8.1 Silverlight__ -- __Windows__ - - -## Installation -The plugin can either be installed from git repository, from local file system through the [Command-line Interface][CLI]. Or cloud based through [PhoneGap Build][PGB]. - -### Local development environment -From master: -```bash -# ~~ from master branch ~~ -cordova plugin add https://github.com/katzer/cordova-plugin-email-composer.git -``` -from a local folder: -```bash -# ~~ local folder ~~ -cordova plugin add de.appplant.cordova.plugin.email-composer --searchpath path/to/plugin -``` -or to use the last stable version: -```bash -# ~~ stable version ~~ -cordova plugin add de.appplant.cordova.plugin.email-composer@0.8.2 -``` - -### PhoneGap Build -Add the following xml to your config.xml to always use the latest version of this plugin: -```xml -<gap:plugin name="de.appplant.cordova.plugin.email-composer" version="0.8.2" /> -``` -More informations can be found [here][PGB_plugin]. - - -## ChangeLog -#### Version 0.8.2 (01.03.2015) -- Added new namespace `cordova.plugins.email`<br> - **Note:** The former `plugin.email` namespace is now deprecated and will be removed with the next major release. -- [___change:___] Unified `absolute:` and `relative:` to `file:` -- [___change:___] Renamed `isServiceAvailable` to `isAvailable` -- [feature:] `app:` allows to specify target mail app on Android -- [feature:] `res:` prefix for native ressource attachments -- [enhancement:] Support attachments on Windows Phone 8.1 -- [enhancement:] `open` supports callbacks -- [enhancement:] `isHTML` can be used next `isHtml` -- [enhancement:] Set mime type to binary if unknown -- [bugfix:] Defaults were ignored - -#### Known issues -- _\<img\>_ tags do not work on Android. -- Callbacks for WP8/Windows platform are called immediately. -- _isAvailable_ does always return _true_ for WP8/Windows platform. -- The plugin may crash on WP8.1/Windows if an attachmant does not exist. - -#### Further informations -- See [CHANGELOG.md][changelog] to get the full changelog for the plugin. - - -## Using the plugin -The plugin creates the object ```cordova.plugins.email``` with following methods: - -1. [email.isAvailable][available] -2. [email.open][open] - -### Plugin initialization -The plugin and its methods are not available before the *deviceready* event has been fired. - -```javascript -document.addEventListener('deviceready', function () { - // cordova.plugins.email is now available -}, false); -``` - -### Determine if the device is capable to send emails -The ability to send emails can be revised through the `email.isAvailable` interface. The method takes a callback function, passed to which is a boolean property. Optionally the callback scope can be assigned as a second parameter. - -The Email service is only available on devices capable which are able to send emails. E.g. which have configured an email account and have installed an email app. You can use this function to hide email functionality from users who will be unable to use it. - -```javascript -cordova.plugins.email.isAvailable( - function (isAvailable) { - // alert('Service is not available') unless isAvailable; - } -); -``` - -### Open a pre-filled email draft -A pre-filled email draft can be opened through the `email.open` or `email.openDraft` interface. The method takes a hash as an argument to specify the email's properties. All properties are optional. Further more it accepts an callback function to be called after the email view has been dismissed. - -After opening the draft the user may have the possibilities to edit, delete or send the email. - -#### Further informations -- An [configured email account][available] is required to send emails. -- Attachments can be either base64 encoded datas, files from the the device storage or assets from within the *www* folder. -- The default value for *isHTML* is *true*. -- Its possible to [specify][email_app] the email app on Android. -- See the [examples][examples] for how to create and show an email draft. - -```javascript -cordova.plugins.email.open({ - to: Array, // email addresses for TO field - cc: Array, // email addresses for CC field - bcc: Array, // email addresses for BCC field - attachments: Array, // file paths or base64 data streams - subject: String, // subject of the email - body: String, // email body (for HTML, set isHtml to true) - isHtml: Boolean, // indicats if the body is HTML or plain text -}, callback, scope); -``` - - -## Examples - -### Open an email draft -The following example shows how to create and show an email draft pre-filled with different kind of properties. - -```javascript -cordova.plugins.email.open({ - to: 'max@mustermann.de', - cc: 'erika@mustermann.de', - bcc: ['john@doe.com', 'jane@doe.com'], - subject: 'Greetings', - body: 'How are you? Nice greetings from Leipzig' -}); -``` - -Of course its also possible to open a blank draft. -```javascript -cordova.plugins.email.open(); -``` - -### Send HTML encoded body -Its possible to send the email body either as text or HTML. In the case of HTML the `isHTML` properties needs to be set. - -```javascript -cordova.plugins.email.open({ - to: 'max@mustermann.de', - subject: 'Greetings', - body: '<h1>Nice greetings from Leipzig</h1>', - isHtml: true -}); -``` - -### Get informed when the view has been dismissed -The `open` method supports additional callback to get informed when the view has been dismissed. - -```javascript -cordova.plugins.email.open(properties, function () { - console.log('email view dismissed'); -}, this); -``` - -### Adding attachments -Attachments can be either base64 encoded datas, files from the the device storage or assets from within the *www* folder. - -#### Attach Base64 encoded content -The code below shows how to attach an base64 encoded image which will be added as a image with the name *icon.png*. - -```javascript -cordova.plugins.email.open({ - subject: 'Cordova Icon', - attachments: 'base64:icon.png//iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/...' -}); -``` - -#### Attach files from the device storage -The path to the files must be defined absolute from the root of the file system. - -```javascript -cordova.plugins.email.open({ - attachments: 'file:///storage/sdcard/icon.png', //=> Android -}); -``` - -#### Attach native app resources -Each app has a resource folder, e.g. the _res_ folder for Android apps or the _Resource_ folder for iOS apps. The following example shows how to attach the app icon from within the app's resource folder. - -```javascript -cordova.plugins.email.open({ - attachments: 'res://icon.png' //=> res/drawable/icon (Android) -}); -``` - -#### Attach assets from the www folder -The path to the files must be defined relative from the root of the mobile web app folder, which is located under the _www_ folder. - -```javascript -cordova.plugins.email.open({ - attachments: [ - 'file://img/logo.png', //=> assets/www/img/logo.png (Android) - 'file://css/index.css' //=> www/css/index.css (iOS) - ] -}); -``` - - -## Platform specifics - -### Specify email app -Its possible to specify the email app __on Android__ which shall open the draft for further editing. By default `email.open` does show a chooser with all available applications. - -The app can be specified by either an alias or its package name. The alias _gmail_ is available by default. - -```javascript -// Add app alias -cordova.plugins.email.addAlias('gmail', 'com.google.android.gm'); - -// Specify app by name or alias -cordova.plugins.email.open({ - app: 'gmail', - subject: 'Sent from Gmail' -}) -``` - - -## Quirks - -### HTML and CSS on Android -Even Android is capable to render HTML formatted mails, most native Mail clients like the standard app or Gmail only support rich formatted text while writing mails. That means that __CSS cannot be used__ (no _class_ and _style_ support). - -The following table gives an overview which tags and attributes can be used: - -<table> -<td width="60%"> - <ul> - <li><code><a href="..."></code></li> - <li><code><b></code></li> - <li><code><big></code></li> - <li><code><blockquote></code></li> - <li><code><br></code></li> - <li><code><cite></code></li> - <li><code><dfn></code></li> - <li><code><div align="..."></code></li> - <li><code><em></code></li> - <li><code><font size="..." color="..." face="..."></code></li> - <li><code><h1></code></li> - <li><code><h2></code></li> - <li><code><h3></code></li> - </ul> -</td> -<td width="40%"> - <ul> - <li><code><h4></code></li> - <li><code><h5></code></li> - <li><code><h6></code></li> - <li><code><i></code></li> - <li><code><img src="..."></code></li> - <li><code><p></code></li> - <li><code><small></code></li> - <li><code><strike></code></li> - <li><code><strong></code></li> - <li><code><sub></code></li> - <li><code><sup></code></li> - <li><code><tt></code></li> - <li><code><u></code></li> - </ul> -</td> -</table> - -### HTML, CSS and attachments on Windows Phone 8 -Attachments and HTML+CSS formatted body are not supported through the native API for Windows Phone 8.0 and Windows Phone 8.1 Silverlight. - -### Compile error on iOS -The error indicates, that the `MessageUI.framework` is not linked to your project. The framework is linked automatically when the plugin was installed, but may removed later. - -``` -Undefined symbols for architecture i386: - "_OBJC_CLASS_$_MFMailComposeViewController", referenced from: - objc-class-ref in APPEmailComposer.o -ld: symbol(s) not found for architecture i386 -clang: error: linker command failed with exit code 1 (use -v to see invocation) -``` - - -## Contributing - -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request - - -## License - -This software is released under the [Apache 2.0 License][apache2_license]. - -© 2013-2015 appPlant UG, Inc. All rights reserved - - -[cordova]: https://cordova.apache.org -[ios_guide]: http://developer.apple.com/library/ios/documentation/MessageUI/Reference/MFMailComposeViewController_class/Reference/Reference.html -[wp8_guide]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394003.aspx -[CLI]: http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface -[PGB]: http://docs.build.phonegap.com/en_US/index.html -[PGB_plugin]: https://build.phonegap.com/plugins/2055 -[messageui_framework]: #compile-error-on-ios -[changelog]: https://github.com/katzer/cordova-plugin-email-composer/blob/master/CHANGELOG.md -[available]: #determine-if-the-device-is-capable-to-send-emails -[open]: #open-a-pre-filled-email-draft -[email_app]: #specify-email-app -[examples]: #examples -[apache2_license]: http://opensource.org/licenses/Apache-2.0 diff --git a/plugins/de.appplant.cordova.plugin.email-composer/plugin.xml b/plugins/de.appplant.cordova.plugin.email-composer/plugin.xml deleted file mode 100644 index 5fc8defb..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/plugin.xml +++ /dev/null @@ -1,120 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - Copyright 2013-2015 appPlant UG - - 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. ---> - - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="de.appplant.cordova.plugin.email-composer" - version="0.8.2"> - - <name>EmailComposer</name> - - <description> - Provides access to the standard interface that manages - the editing and sending an email message - </description> - - <repo> - https://github.com/katzer/cordova-plugin-email-composer.git - </repo> - - <keywords> - appplant, email - </keywords> - - <license>Apache 2.0</license> - - <author>Sebastián Katzer</author> - - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <!-- interface --> - <js-module src="www/email_composer.js" name="EmailComposer"> - <clobbers target="cordova.plugins.email" /> - <clobbers target="plugin.email" /> - </js-module> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="EmailComposer"> - <param name="ios-package" value="APPEmailComposer"/> - </feature> - </config-file> - - <header-file src="src/ios/APPEmailComposer.h" /> - <source-file src="src/ios/APPEmailComposer.m" /> - - <framework src="MessageUI.framework" weak="true" /> - </platform> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="EmailComposer"> - <param name="android-package" - value="de.appplant.cordova.emailcomposer.EmailComposer"/> - </feature> - </config-file> - - <source-file - src="src/android/EmailComposer.java" - target-dir="src/de/appplant/cordova/emailcomposer" /> - - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="EmailComposer"> - <param name="android-package" - value="de.appplant.cordova.emailcomposer.EmailComposer"/> - </feature> - </config-file> - - <source-file - src="src/android/EmailComposer.java" - target-dir="src/de/appplant/cordova/emailcomposer" /> - - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="EmailComposer"> - <param name="wp-package" value="EmailComposer"/> - </feature> - </config-file> - - <source-file src="src/wp8/EmailComposer.cs" /> - <source-file src="src/wp8/Options.cs" /> - </platform> - - <!-- windows --> - <platform name="windows"> - <js-module src="src/windows/EmailComposerProxy.js" name="EmailComposerProxy"> - <merges target="" /> - </js-module> - </platform> -</plugin> diff --git a/plugins/de.appplant.cordova.plugin.email-composer/src/android/EmailComposer.java b/plugins/de.appplant.cordova.plugin.email-composer/src/android/EmailComposer.java deleted file mode 100755 index ddda3104..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/src/android/EmailComposer.java +++ /dev/null @@ -1,574 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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. -*/ - -package de.appplant.cordova.emailcomposer; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.res.AssetManager; -import android.content.res.Resources; -import android.net.Uri; -import android.os.Build; -import android.text.Html; -import android.util.Base64; -import android.util.Log; - -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.PluginResult; - -@SuppressWarnings("Convert2Diamond") -public class EmailComposer extends CordovaPlugin { - - // - static private final String STORAGE_FOLDER = "/email_composer"; - - // The callback context used when calling back into JavaScript - private CallbackContext command; - - /** - * Executes the request. - * - * This method is called from the WebView thread. - * To do a non-trivial amount of work, use: - * cordova.getThreadPool().execute(runnable); - * - * To run on the UI thread, use: - * cordova.getActivity().runOnUiThread(runnable); - * - * @param action The action to execute. - * @param args The exec() arguments in JSON form. - * @param callback The callback context used when calling - * back into JavaScript. - * @return Whether the action was valid. - */ - @Override - public boolean execute (String action, JSONArray args, - CallbackContext callback) throws JSONException { - - this.command = callback; - - if ("open".equals(action)) { - open(args); - - return true; - } - - if ("isAvailable".equals(action)) { - isAvailable(); - - return true; - } - - // Returning false results in a "MethodNotFound" error. - return false; - } - - /** - * Tells if the device has the capability to send emails. - */ - private void isAvailable () { - cordova.getThreadPool().execute(new Runnable() { - public void run() { - Boolean available = isEmailAccountConfigured(); - PluginResult result = new PluginResult(PluginResult.Status.OK, available); - - command.sendPluginResult(result); - } - }); - } - - /** - * Sends an intent to the email app. - * - * @param args - * The email properties like subject or body - * - * @throws JSONException - */ - private void open (JSONArray args) throws JSONException { - JSONObject properties = args.getJSONObject(0); - Intent draft = getDraftWithProperties(properties); - - final Intent chooser = Intent.createChooser(draft, "Open with"); - final EmailComposer plugin = this; - - cordova.getThreadPool().execute(new Runnable() { - public void run() { - cordova.startActivityForResult( - plugin, chooser, 0); - } - }); - } - - /** - * The intent with the containing email properties. - * - * @param params - * The email properties like subject or body - * @return - * The resulting intent - * - * @throws JSONException - */ - private Intent getDraftWithProperties (JSONObject params) throws JSONException { - Intent mail = new Intent(Intent.ACTION_SEND_MULTIPLE); - String app = params.optString("app", null); - - if (params.has("subject")) - setSubject(params.getString("subject"), mail); - if (params.has("body")) - setBody(params.getString("body"), params.optBoolean("isHtml"), mail); - if (params.has("to")) - setRecipients(params.getJSONArray("to"), mail); - if (params.has("cc")) - setCcRecipients(params.getJSONArray("cc"), mail); - if (params.has("bcc")) - setBccRecipients(params.getJSONArray("bcc"), mail); - if (params.has("attachments")) - setAttachments(params.getJSONArray("attachments"), mail); - - if (app != null && isAppInstalled(app)) { - mail.setPackage(app); - } - - mail.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - - return mail; - } - - /** - * Setter for the subject. - * - * @param subject - * The subject - * @param draft - * The intent - */ - private void setSubject (String subject, Intent draft) { - draft.putExtra(Intent.EXTRA_SUBJECT, subject); - } - - /** - * Setter for the body. - * - * @param body - * The body - * @param isHTML - * Indicates the encoding - * (HTML or plain text) - * @param draft - * The intent - */ - private void setBody (String body, Boolean isHTML, Intent draft) { - if (isHTML) { - draft.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(body)); - draft.setType("text/html"); - - if (Build.VERSION.SDK_INT > 15) { - draft.putExtra(Intent.EXTRA_HTML_TEXT, body); - } - } else { - draft.putExtra(Intent.EXTRA_TEXT, body); - draft.setType("text/plain"); - } - } - - /** - * Setter for the recipients. - * - * @param recipients - * List of email addresses - * @param draft - * The intent - * - * @throws JSONException - */ - private void setRecipients (JSONArray recipients, Intent draft) throws JSONException { - String[] receivers = new String[recipients.length()]; - - for (int i = 0; i < recipients.length(); i++) { - receivers[i] = recipients.getString(i); - } - - draft.putExtra(Intent.EXTRA_EMAIL, receivers); - } - - /** - * Setter for the cc recipients. - * - * @param recipients - * List of email addresses - * @param draft - * The intent - * - * @throws JSONException - */ - private void setCcRecipients (JSONArray recipients, Intent draft) throws JSONException { - String[] receivers = new String[recipients.length()]; - - for (int i = 0; i < recipients.length(); i++) { - receivers[i] = recipients.getString(i); - } - - draft.putExtra(Intent.EXTRA_CC, receivers); - } - - /** - * Setter for the bcc recipients. - * - * @param recipients - * List of email addresses - * @param draft - * The intent - * - * @throws JSONException - */ - private void setBccRecipients (JSONArray recipients, Intent draft) throws JSONException { - String[] receivers = new String[recipients.length()]; - - for (int i = 0; i < recipients.length(); i++) { - receivers[i] = recipients.getString(i); - } - - draft.putExtra(Intent.EXTRA_BCC, receivers); - } - - /** - * Setter for the attachments. - * - * @param attachments - * List of URIs - * @param draft - * The intent - * - * @throws JSONException - */ - private void setAttachments (JSONArray attachments, Intent draft) throws JSONException { - ArrayList<Uri> uris = new ArrayList<Uri>(); - - for (int i = 0; i < attachments.length(); i++) { - Uri uri = getUriForPath(attachments.getString(i)); - - uris.add(uri); - } - - draft.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); - } - - /** - * The URI for an attachment path. - * - * @param path - * The given path to the attachment - * - * @return - * The URI pointing to the given path - */ - private Uri getUriForPath (String path) { - if (path.startsWith("res:")) { - return getUriForResourcePath(path); - } else if (path.startsWith("file:///")) { - return getUriForAbsolutePath(path); - } else if (path.startsWith("file://")) { - return getUriForAssetPath(path); - } else if (path.startsWith("base64:")) { - return getUriForBase64Content(path); - } - - return Uri.parse(path); - } - - /** - * The URI for a file. - * - * @param path - * The given absolute path - * - * @return - * The URI pointing to the given path - */ - private Uri getUriForAbsolutePath (String path) { - String absPath = path.replaceFirst("file://", ""); - File file = new File(absPath); - - if (!file.exists()) { - Log.e("EmailComposer", "File not found: " + file.getAbsolutePath()); - } - - return Uri.fromFile(file); - } - - /** - * The URI for an asset. - * - * @param path - * The given asset path - * - * @return - * The URI pointing to the given path - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - private Uri getUriForAssetPath (String path) { - String resPath = path.replaceFirst("file:/", "www"); - String fileName = resPath.substring(resPath.lastIndexOf('/') + 1); - File dir = cordova.getActivity().getExternalCacheDir(); - - if (dir == null) { - Log.e("EmailComposer", "Missing external cache dir"); - return Uri.EMPTY; - } - - String storage = dir.toString() + STORAGE_FOLDER; - File file = new File(storage, fileName); - - new File(storage).mkdir(); - - try { - AssetManager assets = cordova.getActivity().getAssets(); - - FileOutputStream outStream = new FileOutputStream(file); - InputStream inputStream = assets.open(resPath); - - copyFile(inputStream, outStream); - outStream.flush(); - outStream.close(); - } catch (Exception e) { - Log.e("EmailComposer", "File not found: assets/" + resPath); - e.printStackTrace(); - } - - return Uri.fromFile(file); - } - - /** - * The URI for a resource. - * - * @param path - * The given relative path - * - * @return - * The URI pointing to the given path - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - private Uri getUriForResourcePath (String path) { - String resPath = path.replaceFirst("res://", ""); - String fileName = resPath.substring(resPath.lastIndexOf('/') + 1); - String resName = fileName.substring(0, fileName.lastIndexOf('.')); - String extension = resPath.substring(resPath.lastIndexOf('.')); - File dir = cordova.getActivity().getExternalCacheDir(); - - if (dir == null) { - Log.e("EmailComposer", "Missing external cache dir"); - return Uri.EMPTY; - } - - String storage = dir.toString() + STORAGE_FOLDER; - int resId = getResId(resPath); - File file = new File(storage, resName + extension); - - if (resId == 0) { - Log.e("EmailComposer", "File not found: " + resPath); - } - - new File(storage).mkdir(); - - try { - Resources res = cordova.getActivity().getResources(); - FileOutputStream outStream = new FileOutputStream(file); - InputStream inputStream = res.openRawResource(resId); - - copyFile(inputStream, outStream); - outStream.flush(); - outStream.close(); - } catch (Exception e) { - e.printStackTrace(); - } - - return Uri.fromFile(file); - } - - /** - * The URI for a base64 encoded content. - * - * @param content - * The given base64 encoded content - * - * @return - * The URI including the given content - */ - @SuppressWarnings("ResultOfMethodCallIgnored") - private Uri getUriForBase64Content (String content) { - String resName = content.substring(content.indexOf(":") + 1, content.indexOf("//")); - String resData = content.substring(content.indexOf("//") + 2); - File dir = cordova.getActivity().getExternalCacheDir(); - byte[] bytes; - - try { - bytes = Base64.decode(resData, 0); - } catch (Exception ignored) { - Log.e("EmailComposer", "Invalid Base64 string"); - return Uri.EMPTY; - } - - if (dir == null) { - Log.e("EmailComposer", "Missing external cache dir"); - return Uri.EMPTY; - } - - String storage = dir.toString() + STORAGE_FOLDER; - File file = new File(storage, resName); - - new File(storage).mkdir(); - - try { - FileOutputStream outStream = new FileOutputStream(file); - - outStream.write(bytes); - outStream.flush(); - outStream.close(); - } catch (Exception e) { - e.printStackTrace(); - } - - return Uri.fromFile(file); - } - - /** - * Writes an InputStream to an OutputStream - * - * @param in - * The input stream - * @param out - * The output stream - */ - private void copyFile (InputStream in, OutputStream out) throws IOException { - byte[] buffer = new byte[1024]; - int read; - - while((read = in.read(buffer)) != -1){ - out.write(buffer, 0, read); - } - } - - /** - * @return - * The resource ID for the given resource. - */ - private int getResId (String resPath) { - Resources res = cordova.getActivity().getResources(); - int resId; - - String pkgName = getPackageName(); - String dirName = "drawable"; - String fileName = resPath; - - if (resPath.contains("/")) { - dirName = resPath.substring(0, resPath.lastIndexOf('/')); - fileName = resPath.substring(resPath.lastIndexOf('/') + 1); - } - - String resName = fileName.substring(0, fileName.lastIndexOf('.')); - - resId = res.getIdentifier(resName, dirName, pkgName); - - if (resId == 0) { - resId = res.getIdentifier(resName, "drawable", pkgName); - } - - return resId; - } - - /** - * If email apps are available. - * - * @return - * true if available, otherwise false - */ - private Boolean isEmailAccountConfigured () { - Uri uri = Uri.fromParts("mailto","max@mustermann.com", null); - Intent intent = new Intent(Intent.ACTION_SENDTO, uri); - PackageManager pm = cordova.getActivity().getPackageManager(); - int mailApps = pm.queryIntentActivities(intent, 0).size(); - Boolean available; - - available = mailApps > 0; - - return available; - } - - /** - * Ask the package manager if the app is installed on the device. - * - * @param id - * The app id - * - * @return - * true if yes otherwise false - */ - private boolean isAppInstalled(String id) { - PackageManager pm = cordova.getActivity().getPackageManager(); - - try { - pm.getPackageInfo(id, 0); - return true; - } catch(PackageManager.NameNotFoundException e) { - return false; - } - } - - /** - * The name for the package. - * - * @return - * The package name - */ - private String getPackageName () { - return cordova.getActivity().getPackageName(); - } - - /** - * Called when an activity you launched exits, giving you the reqCode you - * started it with, the resCode it returned, and any additional data from it. - * - * @param reqCode The request code originally supplied to startActivityForResult(), - * allowing you to identify who this result came from. - * @param resCode The integer result code returned by the child activity - * through its setResult(). - * @param intent An Intent, which can return result data to the caller - * (various data can be attached to Intent "extras"). - */ - @Override - public void onActivityResult(int reqCode, int resCode, Intent intent) { - command.success(); - } -} diff --git a/plugins/de.appplant.cordova.plugin.email-composer/src/ios/APPEmailComposer.h b/plugins/de.appplant.cordova.plugin.email-composer/src/ios/APPEmailComposer.h deleted file mode 100644 index c7ea09b8..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/src/ios/APPEmailComposer.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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 <MessageUI/MFMailComposeViewController.h> -#import <Cordova/CDVPlugin.h> - -@interface APPEmailComposer : CDVPlugin <MFMailComposeViewControllerDelegate> - -// Shows the email composer view with pre-filled data -- (void) open:(CDVInvokedUrlCommand*)command; -// Checks if the mail composer is able to send mails -- (void) isAvailable:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/de.appplant.cordova.plugin.email-composer/src/ios/APPEmailComposer.m b/plugins/de.appplant.cordova.plugin.email-composer/src/ios/APPEmailComposer.m deleted file mode 100644 index 52bb66d7..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/src/ios/APPEmailComposer.m +++ /dev/null @@ -1,490 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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 "APPEmailComposer.h" -#import "Cordova/NSData+Base64.h" -#import "Cordova/CDVAvailability.h" -#import <MobileCoreServices/MobileCoreServices.h> - -#include "TargetConditionals.h" - -@interface APPEmailComposer () - -@property (nonatomic, retain) CDVInvokedUrlCommand* command; - -@end - -@implementation APPEmailComposer - -#pragma mark - -#pragma mark Plugin interface methods - -/** - * Checks if the mail composer is able to send mails. - * - * @param callbackId - * The ID of the JS function to be called with the result - */ -- (void) isAvailable:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - bool canSendMail = [MFMailComposeViewController canSendMail]; - CDVPluginResult* result; - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsBool:canSendMail]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; - }]; -} - -/** - * Shows the email composer view with pre-filled data. - * - * @param properties - * The email properties like subject, body, attachments - */ -- (void) open:(CDVInvokedUrlCommand*)command -{ - _command = command; - - if (TARGET_IPHONE_SIMULATOR && IsAtLeastiOSVersion(@"8.0")) { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Email-Composer Plug-in" - message:@"Plug-in cannot run on the iOS8 Simulator.\nPlease downgrade or use a physical device." - delegate:nil - cancelButtonTitle:@"OK" - otherButtonTitles:nil]; - [alert show]; - [self execCallback]; - return; - } - - [self.commandDelegate runInBackground:^{ - NSArray* args = command.arguments; - NSDictionary* properties = [args objectAtIndex:0]; - MFMailComposeViewController* draft; - - draft = [self getDraftWithProperties:properties]; - - if (!draft) { - [self execCallback]; - return; - } - - [self openDraft:draft]; - }]; -} - -#pragma mark - -#pragma mark MFMailComposeViewControllerDelegate methods - -/** - * Delegate will be called after the mail composer did finish an action - * to dismiss the view. - */ -- (void) mailComposeController:(MFMailComposeViewController*)controller - didFinishWithResult:(MFMailComposeResult)result - error:(NSError*)error -{ - [controller dismissViewControllerAnimated:YES completion:nil]; - - [self execCallback]; -} - -#pragma mark - -#pragma mark Plugin core methods - -/** - * Instantiates an email composer view. - * - * @param properties - * The email properties like subject, body, attachments - * - * @return - * The configured email composer view - */ -- (MFMailComposeViewController*) getDraftWithProperties:(NSDictionary*)properties -{ - // Falls das Gerät kein Email Interface unterstützt - if (![MFMailComposeViewController canSendMail]) { - return NULL; - } - - BOOL isHTML = [[properties objectForKey:@"isHtml"] boolValue]; - - MFMailComposeViewController* draft; - - draft = [[MFMailComposeViewController alloc] init]; - - // Subject - [self setSubject:[properties objectForKey:@"subject"] ofDraft:draft]; - // Body (as HTML) - [self setBody:[properties objectForKey:@"body"] ofDraft:draft isHTML:isHTML]; - // Recipients - [self setToRecipients:[properties objectForKey:@"to"] ofDraft:draft]; - // CC Recipients - [self setCcRecipients:[properties objectForKey:@"cc"] ofDraft:draft]; - // BCC Recipients - [self setBccRecipients:[properties objectForKey:@"bcc"] ofDraft:draft]; - // Attachments - [self setAttachments:[properties objectForKey:@"attachments"] ofDraft:draft]; - - draft.mailComposeDelegate = self; - - return draft; -} - -/** - * Displays the email draft. - * - * @param draft - * The email composer view - */ -- (void) openDraft:(MFMailComposeViewController*)draft -{ - [self.viewController presentViewController:draft - animated:YES - completion:NULL]; -} - -/** - * Sets the subject of the email draft. - * - * @param subject - * The subject of the email - * @param draft - * The email composer view - */ -- (void) setSubject:(NSString*)subject - ofDraft:(MFMailComposeViewController*)draft -{ - [draft setSubject:subject]; -} - -/** - * Sets the body of the email draft. - * - * @param body - * The body of the email - * @param isHTML - * Indicates if the body is an HTML encoded string - * @param draft - * The email composer view - */ -- (void) setBody:(NSString*)body ofDraft:(MFMailComposeViewController*)draft - isHTML:(BOOL)isHTML -{ - [draft setMessageBody:body isHTML:isHTML]; -} - -/** - * Sets the recipients of the email draft. - * - * @param recipients - * The recipients of the email - * @param draft - * The email composer view - */ -- (void) setToRecipients:(NSArray*)recipients - ofDraft:(MFMailComposeViewController*)draft -{ - [draft setToRecipients:recipients]; -} - -/** - * Sets the CC recipients of the email draft. - * - * @param ccRecipients - * The CC recipients of the email - * @param draft - * The email composer view - */ -- (void) setCcRecipients:(NSArray*)ccRecipients - ofDraft:(MFMailComposeViewController*)draft -{ - [draft setCcRecipients:ccRecipients]; -} - -/** - * Sets the BCC recipients of the email draft. - * - * @param bccRecipients - * The BCC recipients of the email - * @param draft - * The email composer view - */ -- (void) setBccRecipients:(NSArray*)bccRecipients - ofDraft:(MFMailComposeViewController*)draft -{ - [draft setBccRecipients:bccRecipients]; -} - -/** - * Sets the attachments of the email draft. - * - * @param attachments - * The attachments of the email - * @param draft - * The email composer view - */ -- (void) setAttachments:(NSArray*)attatchments - ofDraft:(MFMailComposeViewController*)draft -{ - if (attatchments) - { - for (NSString* path in attatchments) - { - NSData* data = [self getDataForAttachmentPath:path]; - - NSString* basename = [self getBasenameFromAttachmentPath:path]; - NSString* pathExt = [basename pathExtension]; - NSString* fileName = [basename pathComponents].lastObject; - NSString* mimeType = [self getMimeTypeFromFileExtension:pathExt]; - - // Couldn't find mimeType, must be some type of binary data - if (mimeType == nil) mimeType = @"application/octet-stream"; - - [draft addAttachmentData:data mimeType:mimeType fileName:fileName]; - } - } -} - -/** - * Returns the data for a given (relative) attachment path. - * - * @param path - * An absolute/relative path or the base64 data - * - * @return - * The data for the attachment - */ -- (NSData*) getDataForAttachmentPath:(NSString*)path -{ - if ([path hasPrefix:@"file:///"]) - { - return [self dataForAbsolutePath:path]; - } - else if ([path hasPrefix:@"res:"]) - { - return [self dataForResource:path]; - } - else if ([path hasPrefix:@"file://"]) - { - return [self dataForAsset:path]; - } - else if ([path hasPrefix:@"base64:"]) - { - return [self dataFromBase64:path]; - } - - NSFileManager* fileManager = [NSFileManager defaultManager]; - - if (![fileManager fileExistsAtPath:path]){ - NSLog(@"File not found: %@", path); - } - - return [fileManager contentsAtPath:path]; -} - -/** - * Retrieves the data for an absolute attachment path. - * - * @param path - * An absolute file path - * - * @return - * The data for the attachment - */ -- (NSData*) dataForAbsolutePath:(NSString*)path -{ - NSFileManager* fileManager = [NSFileManager defaultManager]; - NSString* absPath; - - absPath = [path stringByReplacingOccurrencesOfString:@"file://" - withString:@""]; - - if (![fileManager fileExistsAtPath:absPath]){ - NSLog(@"File not found: %@", absPath); - } - - NSData* data = [fileManager contentsAtPath:absPath]; - - return data; -} - -/** - * Retrieves the data for a resource path. - * - * @param path - * A relative file path - * - * @return - * The data for the attachment - */ -- (NSData*) dataForResource:(NSString*)path -{ - NSFileManager* fileManager = [NSFileManager defaultManager]; - NSString* absPath; - - NSBundle* mainBundle = [NSBundle mainBundle]; - NSString* bundlePath = [[mainBundle bundlePath] - stringByAppendingString:@"/"]; - - absPath = [path pathComponents].lastObject; - - absPath = [bundlePath stringByAppendingString:absPath]; - - if (![fileManager fileExistsAtPath:absPath]){ - NSLog(@"File not found: %@", absPath); - } - - NSData* data = [fileManager contentsAtPath:absPath]; - - return data; -} - -/** - * Retrieves the data for a asset path. - * - * @param path - * A relative www file path - * - * @return - * The data for the attachment - */ -- (NSData*) dataForAsset:(NSString*)path -{ - NSFileManager* fileManager = [NSFileManager defaultManager]; - NSString* absPath; - - NSBundle* mainBundle = [NSBundle mainBundle]; - NSString* bundlePath = [[mainBundle bundlePath] - stringByAppendingString:@"/"]; - - absPath = [path stringByReplacingOccurrencesOfString:@"file:/" - withString:@"www"]; - - absPath = [bundlePath stringByAppendingString:absPath]; - - if (![fileManager fileExistsAtPath:absPath]){ - NSLog(@"File not found: %@", absPath); - } - - NSData* data = [fileManager contentsAtPath:absPath]; - - return data; -} - -/** - * Retrieves the data for a base64 encoded string. - * - * @param base64String - * Base64 encoded string - * - * @return - * The data for the attachment - */ -- (NSData*) dataFromBase64:(NSString*)base64String -{ - NSUInteger length = [base64String length]; - NSRegularExpression *regex; - NSString *dataString; - - regex = [NSRegularExpression regularExpressionWithPattern:@"^base64:[^/]+.." - options:NSRegularExpressionCaseInsensitive - error:Nil]; - - dataString = [regex stringByReplacingMatchesInString:base64String - options:0 - range:NSMakeRange(0, length) - withTemplate:@""]; - - NSData* data = [NSData dataFromBase64String:dataString]; - - return data; -} - -#pragma mark - -#pragma mark Plugin helper methods - -/** - * Retrieves the mime type from the file extension. - * - * @param extension - * The file's extension - * - * @return - * The coresponding MIME type - */ -- (NSString*) getMimeTypeFromFileExtension:(NSString*)extension -{ - if (!extension) { - return nil; - } - - // Get the UTI from the file's extension - CFStringRef ext = (CFStringRef)CFBridgingRetain(extension); - CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL); - - // Converting UTI to a mime type - return (NSString*)CFBridgingRelease(UTTypeCopyPreferredTagWithClass(type, kUTTagClassMIMEType)); -} - -/** - * Retrieves the attachments basename. - * - * @param path - * The file path or bas64 data of the attachment - * - * @return - * The attachments basename - */ -- (NSString*) getBasenameFromAttachmentPath:(NSString*)path -{ - if ([path hasPrefix:@"base64:"]) - { - NSString* pathWithoutPrefix; - - pathWithoutPrefix = [path stringByReplacingOccurrencesOfString:@"base64:" - withString:@""]; - - return [pathWithoutPrefix substringToIndex: - [pathWithoutPrefix rangeOfString:@"//"].location]; - } - - return path; - -} - -/** - * Invokes the callback without any parameter. - */ -- (void) execCallback -{ - CDVPluginResult *result = [CDVPluginResult - resultWithStatus:CDVCommandStatus_OK]; - - [self.commandDelegate sendPluginResult:result - callbackId:_command.callbackId]; -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.email-composer/src/windows/EmailComposerProxy.js b/plugins/de.appplant.cordova.plugin.email-composer/src/windows/EmailComposerProxy.js deleted file mode 100644 index 382eb79a..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/src/windows/EmailComposerProxy.js +++ /dev/null @@ -1,273 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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. -*/ - -/** - * Verifies if sending emails is supported on the device. - * - * @param {Function} success - * Success callback function - * @param {Function} error - * Error callback function - * @param {Array} args - * Interface arguments - */ -exports.isAvailable = function (success, error, args) { - success(true); -}; - -/** - * Displays the email composer pre-filled with data. - * - * @param {Function} success - * Success callback function - * @param {Function} error - * Error callback function - * @param {Array} args - * Interface arguments - */ -exports.open = function (success, error, args) { - var props = args[0], - email = exports.getDraftWithProperties(props); - - Windows.ApplicationModel.Email.EmailManager - .showComposeNewEmailAsync(email) - .done(success()); -}; - -/** - * The Email with the containing properties. - * - * @param {Object} props - * The email properties like subject or body - * @return {Windows.ApplicationModel.Email.EmailMessage} - * The resulting email draft - */ -exports.getDraftWithProperties = function (props) { - var mail = new Windows.ApplicationModel.Email.EmailMessage(); - - // subject - exports.setSubject(props.subject, mail); - // body - exports.setBody(props.body, props.isHtml, mail); - // To recipients - exports.setRecipients(props.to, mail); - // CC recipients - exports.setCcRecipients(props.cc, mail); - // BCC recipients - exports.setBccRecipients(props.bcc, mail); - // attachments - exports.setAttachments(props.attachments, mail); - - return mail; -}; - -/** - * Setter for the subject. - * - * @param {String} subject - * The subject - * @param {Windows.ApplicationModel.Email.EmailMessage} draft - * The draft - */ -exports.setSubject = function (subject, draft) { - draft.subject = subject; -}; - -/** - * Setter for the body. - * - * @param {String} body - * The body - * @param isHTML - * Indicates the encoding - * (HTML or plain text) - * @param {Windows.ApplicationModel.Email.EmailMessage} draft - * The draft - */ -exports.setBody = function (body, isHTML, draft) { - draft.body = body; -}; - -/** - * Setter for the recipients. - * - * @param {String[]} recipients - * List of mail addresses - * @param {Windows.ApplicationModel.Email.EmailMessage} draft - * The draft - */ -exports.setRecipients = function (recipients, draft) { - recipients.forEach(function (address) { - draft.to.push( - new Windows.ApplicationModel.Email.EmailRecipient(address)); - }); -}; - -/** - * Setter for the cc recipients. - * - * @param {String[]} recipients - * List of mail addresses - * @param {Windows.ApplicationModel.Email.EmailMessage} draft - * The draft - */ -exports.setCcRecipients = function (recipients, draft) { - recipients.forEach(function (address) { - draft.cc.push( - new Windows.ApplicationModel.Email.EmailRecipient(address)); - }); -}; - -/** - * Setter for the bcc recipients. - * - * @param {String[]} recipients - * List of mail addresses - * @param {Windows.ApplicationModel.Email.EmailMessage} draft - * The draft - */ -exports.setBccRecipients = function (recipients, draft) { - recipients.forEach(function (address) { - draft.bcc.push( - new Windows.ApplicationModel.Email.EmailRecipient(address)); - }); -}; - -/** - * Setter for the attachments. - * - * @param {String[]} attachments - * List of URIs - * @param {Windows.ApplicationModel.Email.EmailMessage} draft - * The draft - */ -exports.setAttachments = function (attachments, draft) { - attachments.forEach(function (path) { - var uri = exports.getUriForPath(path), - name = uri.path.split('/').reverse()[0], - stream = Windows.Storage.Streams.RandomAccessStreamReference - .createFromUri(uri); - - draft.attachments.push( - new Windows.ApplicationModel.Email. - EmailAttachment(name, stream) - ); - }); -}; - -/** - * The URI for an attachment path. - * - * @param {String} path - * The given path to the attachment - * - * @return - * The URI pointing to the given path - */ -exports.getUriForPath = function (path) { - if (path.match(/^res:/)) { - return exports.getUriForResourcePath(path); - } else if (path.match(/^file:\/{3}/)) { - return exports.getUriForAbsolutePath(path); - } else if (path.match(/^file:/)) { - return exports.getUriForAssetPath(path); - } else if (path.match(/^base64:/)) { - return exports.getUriForBase64Content(path); - } - - return new Windows.Foundation.Uri(path); -}; - -/** - * The URI for a file. - * - * @param {String} path - * The given absolute path - * - * @return - * The URI pointing to the given path - */ -exports.getUriForAbsolutePath = function (path) { - return new Windows.Foundation.Uri(path); -}; - -/** - * The URI for an asset. - * - * @param {String} path - * The given asset path - * - * @return - * The URI pointing to the given path - */ -exports.getUriForAssetPath = function (path) { - var host = document.location.host, - protocol = document.location.protocol, - resPath = path.replace('file:/', '/www'), - rawUri = protocol + '//' + host + resPath; - - return new Windows.Foundation.Uri(rawUri); -}; - -/** - * The URI for a resource. - * - * @param {String} path - * The given relative path - * - * @return - * The URI pointing to the given path - */ -exports.getUriForResourcePath = function (path) { - var host = document.location.host, - protocol = document.location.protocol, - resPath = path.replace('res:/', '/images'), - rawUri = protocol + '//' + host + resPath; - - return new Windows.Foundation.Uri(rawUri); -}; - -/** - * The URI for a base64 encoded content. - * - * @param {String} content - * The given base64 encoded content - * - * @return - * The URI including the given content - */ -exports.getUriForBase64Content = function (content) { - var match = content.match(/^base64:([^\/]+)\/\/(.*)/), - base64 = match[2], - name = match[1], - buffer = Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(base64), - rwplus = Windows.Storage.CreationCollisionOption.openIfExists, - folder = Windows.Storage.ApplicationData.current.temporaryFolder, - uri = new Windows.Foundation.Uri('ms-appdata:///temp/' + name); - - folder.createFileAsync(name, rwplus).done(function (file) { - Windows.Storage.FileIO.writeBufferAsync(file, buffer); - }); - - return uri; -}; - -require('cordova/exec/proxy').add('EmailComposer', exports); diff --git a/plugins/de.appplant.cordova.plugin.email-composer/src/wp8/EmailComposer.cs b/plugins/de.appplant.cordova.plugin.email-composer/src/wp8/EmailComposer.cs deleted file mode 100644 index db0d613e..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/src/wp8/EmailComposer.cs +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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. -*/ - -using De.APPPlant.Cordova.Plugin.EmailComposer; -using Microsoft.Phone.Tasks; -using System; -using System.Linq; -using WPCordovaClassLib.Cordova; -using WPCordovaClassLib.Cordova.Commands; -using WPCordovaClassLib.Cordova.JSON; - -namespace Cordova.Extension.Commands -{ - /// <summary> - /// Implementes access to email composer task - /// http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh394003(v=vs.105).aspx - /// </summary> - public class EmailComposer : BaseCommand - { - /// <summary> - /// Überprüft, ob Emails versendet werden können. - /// </summary> - public void isAvailable(string jsonArgs) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true)); - } - - /// <summary> - /// Öffnet den Email-Kontroller mit vorausgefüllten Daten. - /// </summary> - public void open(string jsonArgs) - { - string[] args = JsonHelper.Deserialize<string[]>(jsonArgs); - Options options = JsonHelper.Deserialize<Options>(args[0]); - EmailComposeTask draft = GetDraftWithProperties(options); - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true)); - - OpenDraft(draft); - } - - /// </summary> - /// Erstellt den Email-Composer und fügt die übergebenen Eigenschaften ein. - /// </summary> - private EmailComposeTask GetDraftWithProperties(Options options) - { - EmailComposeTask draft = new EmailComposeTask(); - - SetSubject(options.Subject, draft); - SetBody(options.Body, options.IsHtml, draft); - SetTo(options.To, draft); - SetCc(options.Cc, draft); - SetBcc(options.Bcc, draft); - SetAttachments(options.Attachments, draft); - - return draft; - } - - /// </summary> - /// Zeigt den ViewController zum Versenden/Bearbeiten der Mail an. - /// </summary> - private void OpenDraft(EmailComposeTask draft) - { - draft.Show(); - } - - /// </summary> - /// Setzt den Subject der Mail. - /// </summary> - private void SetSubject(string subject, EmailComposeTask draft) - { - draft.Subject = subject; - } - - /// </summary> - /// Setzt den Body der Mail. - /// </summary> - private void SetBody(string body, Boolean isHTML, EmailComposeTask draft) - { - draft.Body = body; - } - - /// </summary> - /// Setzt die Empfänger der Mail. - /// </summary> - private void SetTo(string[] recipients, EmailComposeTask draft) - { - draft.To = string.Join(",", recipients); - } - - /// </summary> - /// Setzt die CC-Empfänger der Mail. - /// </summary> - private void SetCc(string[] recipients, EmailComposeTask draft) - { - draft.Cc = string.Join(",", recipients); - } - - /// </summary> - /// Setzt die BCC-Empfänger der Mail. - /// </summary> - private void SetBcc(string[] recipients, EmailComposeTask draft) - { - draft.Bcc = string.Join(",", recipients); - } - - /// </summary> - /// Fügt die Anhände zur Mail hinzu. - /// </summary> - private void SetAttachments(string[] attachments, EmailComposeTask draft) - { - // Not supported on WP8.0 and WP8.1 Silverlight - } - } -} diff --git a/plugins/de.appplant.cordova.plugin.email-composer/src/wp8/Options.cs b/plugins/de.appplant.cordova.plugin.email-composer/src/wp8/Options.cs deleted file mode 100644 index b7c7206e..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/src/wp8/Options.cs +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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. -*/ - -using System; -using System.Linq; -using System.Runtime.Serialization; - -namespace De.APPPlant.Cordova.Plugin.EmailComposer -{ - /// <summary> - /// Represents email composer task options - /// </summary> - [DataContract] - class Options - { - /// <summary> - /// Represents the subject of the email - /// </summary> - [DataMember(IsRequired = false, Name = "subject")] - public string Subject { get; set; } - - /// <summary> - /// Represents the email body (could be HTML code, in this case set isHtml to true) - /// </summary> - [DataMember(IsRequired = false, Name = "body")] - public string Body { get; set; } - - /// <summary> - /// Indicats if the body is HTML or plain text - /// </summary> - [DataMember(IsRequired = false, Name = "isHtml")] - public bool IsHtml { get; set; } - - /// <summary> - /// Contains all the email addresses for TO field - /// </summary> - [DataMember(IsRequired = false, Name = "to")] - public string[] To { get; set; } - - /// <summary> - /// Contains all the email addresses for CC field - /// </summary> - [DataMember(IsRequired = false, Name = "cc")] - public string[] Cc { get; set; } - - /// <summary> - /// Contains all the email addresses for BCC field - /// </summary> - [DataMember(IsRequired = false, Name = "bcc")] - public string[] Bcc { get; set; } - - /// <summary> - /// Contains all full paths to the files you want to attach - /// </summary> - [DataMember(IsRequired = false, Name = "attachments")] - public string[] Attachments { get; set; } - } -} diff --git a/plugins/de.appplant.cordova.plugin.email-composer/www/email_composer.js b/plugins/de.appplant.cordova.plugin.email-composer/www/email_composer.js deleted file mode 100644 index 7fd86076..00000000 --- a/plugins/de.appplant.cordova.plugin.email-composer/www/email_composer.js +++ /dev/null @@ -1,186 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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 exec = require('cordova/exec'); - -/** - * List of all registered mail app aliases. - */ -exports.aliases = { - gmail: 'com.google.android.gm' -}; - -/** - * List of all available options with their default value. - * - * @return {Object} - */ -exports.getDefaults = function () { - return { - app: undefined, - subject: '', - body: '', - to: [], - cc: [], - bcc: [], - attachments: [], - isHtml: true - }; -}; - -/** - * Verifies if sending emails is supported on the device. - * - * @param {Function} callback - * A callback function to be called with the result - * @param {Object} scope - * The scope of the callback - */ -exports.isAvailable = function (callback, scope) { - var fn = this.createCallbackFn(callback, scope); - - exec(fn, null, 'EmailComposer', 'isAvailable', []); -}; - -/** - * Displays the email composer pre-filled with data. - * - * @param {Object} options - * Different properties of the email like the body, subject - * @param {Function} callback - * A callback function to be called with the result - * @param {Object?} scope - * The scope of the callback - */ -exports.open = function (options, callback, scope) { - var fn = this.createCallbackFn(callback, scope); - - options = this.mergeWithDefaults(options || {}); - - exec(fn, null, 'EmailComposer', 'open', [options]); -}; - -/** - * Adds a new mail app alias. - * - * @param {String} alias - * The alias name - * @param {String} package - * The package name - */ -exports.addAlias = function (alias, package) { - this.aliases[alias] = package; -} - -/** - * @depreacted - */ -exports.isServiceAvailable = function () { - console.log('`email.isServiceAvailable` is deprecated.' + - ' Please use `email.isAvailable` instead.'); - - this.isAvailable.apply(this, arguments); -}; - -/** - * Alias für `open()`. - */ -exports.openDraft = function () { - this.open.apply(this, arguments); -}; - -/** - * @private - * - * Merge settings with default values. - * - * @param {Object} options - * The custom options - * - * @retrun {Object} - * Default values merged - * with custom values - */ -exports.mergeWithDefaults = function (options) { - var defaults = this.getDefaults(); - - if (options.hasOwnProperty('isHTML')) { - options.isHtml = options.isHTML; - } - - if (options.hasOwnProperty('app')) { - var package = this.aliases[options.app]; - - options.app = package || options.app; - } - - for (var key in defaults) { - - if (!options.hasOwnProperty(key)) { - options[key] = defaults[key]; - continue; - } - - var custom_ = options[key], - default_ = defaults[key]; - - if (custom_ === null || custom_ === undefined) { - options[key] = default_; - continue; - } - - if (typeof default_ != typeof custom_) { - - if (typeof default_ == 'string') { - options[key] = custom_.join(''); - } - - else if (typeof default_ == 'object') { - options[key] = [custom_.toString()]; - } - } - } - - return options; -}; - -/** - * @private - * - * Creates a callback, which will be executed - * within a specific scope. - * - * @param {Function} callbackFn - * The callback function - * @param {Object} scope - * The scope for the function - * - * @return {Function} - * The new callback function - */ -exports.createCallbackFn = function (callbackFn, scope) { - if (typeof callbackFn != 'function') - return; - - return function () { - callbackFn.apply(scope || this, arguments); - }; -}; diff --git a/plugins/de.appplant.cordova.plugin.local-notification/CHANGELOG.md b/plugins/de.appplant.cordova.plugin.local-notification/CHANGELOG.md deleted file mode 100644 index 611e02f8..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/CHANGELOG.md +++ /dev/null @@ -1,61 +0,0 @@ -ChangeLog ---------- - -Please also read the [Upgrade Guide](https://github.com/katzer/cordova-plugin-local-notifications/wiki/Upgrade-Guide) for more information. - -#### Version 0.8.1 (08.03.2015) - -- Fix incompatibility with cordova version 3.5-3.0 -- Fire `clear` instead of `cancel` event when clicked on repeating notifications -- Do not fire `clear` or `cancel` event when clicked on persistent notifications - -### Version 0.8.0 (05.03.2015) - -- Support for iOS 8, Android 2 (SDK >= 7) and Android 5 - - Windows Phone 8.1 will be added soon -- New interfaces to ask for / register permissions required to schedule local notifications - - `hasPermission()` and `registerPermission()` - - _schedule()_ will register the permission automatically and schedule the notification if granted. -- New interface to update already scheduled|triggered local notifications - - `update()` -- New interfaces to clear the notification center - - `clear()` and `clearAll()` -- New interfaces to query for local notifications, their properties, their IDs and their existence depend on their state - - `isPresent()`, `isScheduled()`, `isTriggered()` - - `getIds()`, `getAllIds()`, `getScheduledIds()`, `getTriggeredIds()` - - `get()`, `getAll()`, `getScheduled()`, `getTriggered()` -- Schedule multiple local notifications at once - - `schedule( [{...},{...}] )` -- Update multiple local notifications at once - - `update( [{...},{...}] )` -- Clear multiple local notifications at once - - `clear( [1, 2] )` -- Cancel multiple local notifications at once - - `cancel( [1, 2] )` -- New URI format to specify sound and image resources - - `http(s):` for remote resources _(Android)_ - - `file:` for local resources relative to the _www_ folder - - `res:` for native resources -- New events - - `schedule`, `update`, `clear`, `clearall` and `cancelall` -- Enhanced event informations - - Listener will get called with the local notification object instead of only the ID -- Multiple listener for one event - - `on(event, callback, scope)` -- Unregister event listener - - `un(event, callback)` -- New Android specific properties - - `led` properties - - `sound` and `image` accepts remote resources -- Callback function and scope for all interface methods - - `schedule( notification, callback, scope )` -- Renamed `add()` to `schedule()` -- `autoCancel` property has been removed - - Use `ongoing: true` for persistent local notifications on Android -- Renamed repeat intervals - - `second`, `minute`, `hour`, `day`, `week`, `month` and `year` -- Renamed some local notification properties - - `date`, `json`, `message` and `repeat` - - Scheduling local notifications with the deprecated properties is still possible -- [Kitchen Sink sample app](https://github.com/katzer/cordova-plugin-local-notifications/tree/example) -- [Wiki](https://github.com/katzer/cordova-plugin-local-notifications/wiki) diff --git a/plugins/de.appplant.cordova.plugin.local-notification/LICENSE b/plugins/de.appplant.cordova.plugin.local-notification/LICENSE deleted file mode 100644 index 28974b74..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2013-2015 appPlant UG, Inc. - - Licensed 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.
\ No newline at end of file diff --git a/plugins/de.appplant.cordova.plugin.local-notification/README.md b/plugins/de.appplant.cordova.plugin.local-notification/README.md deleted file mode 100644 index 878632ba..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/README.md +++ /dev/null @@ -1,136 +0,0 @@ - -[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L3HKQCD9UA35A "Donate once-off to this project using Paypal") - -#### :bangbang: Please vote for these cordova-windows issues :bangbang: -1. https://issues.apache.org/jira/browse/CB-8674 _(Missing launch arguments)_ -2. https://issues.apache.org/jira/browse/CB-8946 _(Missing ToastCapable flag)_ - -Thanks a lot! - -Cordova Local-Notification Plugin -================================= - -The essential purpose of local notifications is to enable an application to inform its users that it has something for them — for example, a message or an upcoming appointment — when the application isn’t running in the foreground.<br> -They are scheduled by an application and delivered on the same device. - -<img width="35%" align="right" hspace="19" vspace="12" src="https://github.com/katzer/cordova-plugin-local-notifications/blob/example/images/android.png"></img> - -### How they appear to the user -Users see notifications in the following ways: -- Displaying an alert or banner -- Badging the app’s icon -- Playing a sound - - -### Examples of Notification Usage -Local notifications are ideally suited for applications with time-based behaviors, such as calendar and to-do list applications. Applications that run in the background for the limited period allowed by iOS might also find local notifications useful.<br> -For example, applications that depend on servers for messages or data can poll their servers for incoming items while running in the background; if a message is ready to view or an update is ready to download, they can then present a local notification immediately to inform their users. - - -## Supported Platforms -The current 0.8 branch supports the following platforms: -- __iOS__ _(including iOS8)_<br> -- __Android__ _(SDK >=7)_ -- __Windows 8.1__ _(added with v0.8.2)_ -- __Windows Phone 8.1__ _(added with v0.8.2)_ - -Find out more informations [here][wiki_platforms] in our wiki. - - -## Installation -The plugin is installable from source and available on Cordova Plugin Registry and PhoneGap Build. - -Find out more informations [here][wiki_installation] in our wiki. - - -## I want to get a quick overview -All wiki pages contain samples, but for a quick overview the sample section may be the fastest way. - -Find out more informations [here][wiki_samples] in our wiki. - - -## I want to get a deep overview -The plugin supports scheduling local notifications in various ways with a single interface. It also allows you to update, clear or cancel them. There are different interfaces to query for local notifications and a complete set of events to hook into the life cycle of local notifications. - -Find out more about how to schedule single, multiple, delayed or repeating local notifications [here][wiki_schedule].<br> -Informations about events like _click_ or _trigger_ can be found [here][wiki_events]. - -To get a deep overview we recommend to read about all the topics in our [wiki][wiki] and try out the [Kitchen Sink App][wiki_kitchensink] - - -## I want to see the plugin in action -The plugin offers a kitchen sink sample app. Check out the cordova project and run the app directly from your command line or preferred IDE. - -Find out more informations [here][wiki_kitchensink] in our wiki. - - -## What's new -We are proud to announce our newest release version 0.8.x. Beside the hard work at the office and at the weekends it contains a lot of goodies, new features and easy to use APIs. - -Find out more informations [here][wiki_changelog] in our wiki. - - -## Sample -The sample demonstrates how to schedule a local notification which repeats every week. The listener will be called when the user has clicked on the local notification. - -```javascript -cordova.plugins.notification.local.schedule({ - id: 1, - title: "Production Jour fixe", - text: "Duration 1h", - firstAt: monday_9_am, - every: "week", - sound: "file://sounds/reminder.mp3", - icon: "http://icons.com/?cal_id=1", - data: { meetingId:"123#fg8" } -}); - -cordova.plugins.notification.local.on("click", function (notification) { - joinMeeting(notification.data.meetingId); -}); -``` - -Find out more informations [here][wiki_samples] in our wiki. - - -## I would like to propose new features -We appricate any feature proposal and support for their development. Please describe them [here][feature_proposal_issue]. - -Find out more informations [here][wiki_next] in our wiki. - -## Supporting -Your support is needed. If you use the plugin please send us a drop through the donation button. - -Thank you! - -[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=L3HKQCD9UA35A "Donate once-off to this project using Paypal") - - -## Contributing - -1. Fork it -2. Create your feature branch (`git checkout -b my-new-feature`) -3. Commit your changes (`git commit -am 'Add some feature'`) -4. Push to the branch (`git push origin my-new-feature`) -5. Create new Pull Request - - -## License - -This software is released under the [Apache 2.0 License][apache2_license]. - -© 2013-2015 appPlant UG, Inc. All rights reserved - - -[cordova]: https://cordova.apache.org -[wiki]: https://github.com/katzer/cordova-plugin-local-notifications/wiki -[wiki_platforms]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/02.-Platforms -[wiki_installation]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/03.-Installation -[wiki_kitchensink]: https://github.com/katzer/cordova-plugin-local-notifications/tree/example -[wiki_schedule]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/04.-Scheduling -[wiki_events]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/09.-Events -[wiki_samples]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/11.-Samples -[wiki_changelog]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/Upgrade-Guide -[wiki_next]: https://github.com/katzer/cordova-plugin-local-notifications/wiki/Feature-Requests -[feature_proposal_issue]: https://github.com/katzer/cordova-plugin-local-notifications/issues/451 -[apache2_license]: http://opensource.org/licenses/Apache-2.0 diff --git a/plugins/de.appplant.cordova.plugin.local-notification/plugin.xml b/plugins/de.appplant.cordova.plugin.local-notification/plugin.xml deleted file mode 100644 index 7efd3434..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/plugin.xml +++ /dev/null @@ -1,228 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="de.appplant.cordova.plugin.local-notification" - version="0.8.2-dev"> - - <name>LocalNotification</name> - - <description>The plugin supports scheduling local notifications in various ways with a single interface. It also allows you to update, clear or cancel them. There are different interfaces to query for local notifications and a complete set of events to hook into the life cycle of local notifications. To get a deep overview we recommend to read about all the topics in our wiki and try out the Kitchen Sink App</description> - - <repo>https://github.com/katzer/cordova-plugin-local-notifications.git</repo> - - <keywords>appplant, notification, local notification</keywords> - - <license>Apache 2.0</license> - - <author>Sebastián Katzer</author> - - <!-- cordova --> - <engines> - <engine name="cordova" version=">=3.6.0" /> - <engine name="cordova" version="<4.0.0" /> - </engines> - - <!-- dependencies --> - <dependency id="cordova-plugin-device" /> - - <!-- info --> - <info> - Your support is needed. If you use the local-notification plugin please support us in order to ensure further development. - https://github.com/katzer/cordova-plugin-local-notifications#supporting - - Thank you! - </info> - - <!-- js --> - <js-module src="www/local-notification.js" name="LocalNotification"> - <clobbers target="cordova.plugins.notification.local" /> - <clobbers target="plugin.notification.local" /> - </js-module> - - <js-module src="www/local-notification-core.js" name="LocalNotification.Core"> - <clobbers target="cordova.plugins.notification.local.core" /> - <clobbers target="plugin.notification.local.core" /> - </js-module> - - <js-module src="www/local-notification-util.js" name="LocalNotification.Util"> - <merges target="cordova.plugins.notification.local.core" /> - <merges target="plugin.notification.local.core" /> - </js-module> - - <!-- ios --> - <platform name="ios"> - - <dependency id="de.appplant.cordova.common.registerusernotificationsettings" /> - - <config-file target="config.xml" parent="/*"> - <feature name="LocalNotification"> - <param name="ios-package" value="APPLocalNotification" onload="true" /> - <param name="onload" value="true" /> - </feature> - </config-file> - - <header-file src="src/ios/APPLocalNotification.h" /> - <source-file src="src/ios/APPLocalNotification.m" /> - - <header-file src="src/ios/APPLocalNotificationOptions.h" /> - <source-file src="src/ios/APPLocalNotificationOptions.m" /> - - <header-file src="src/ios/UIApplication+APPLocalNotification.h" /> - <source-file src="src/ios/UIApplication+APPLocalNotification.m" /> - - <header-file src="src/ios/UILocalNotification+APPLocalNotification.h" /> - <source-file src="src/ios/UILocalNotification+APPLocalNotification.m" /> - - </platform> - - <!-- android --> - <platform name="android"> - - <framework src="com.android.support:support-v4:+" /> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="LocalNotification"> - <param name="android-package" value="de.appplant.cordova.plugin.localnotification.LocalNotification"/> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/manifest/application"> - - <receiver - android:name="de.appplant.cordova.plugin.localnotification.TriggerReceiver" - android:exported="false" /> - - <receiver - android:name="de.appplant.cordova.plugin.localnotification.ClearReceiver" - android:exported="false" /> - - <activity - android:name="de.appplant.cordova.plugin.localnotification.ClickActivity" - android:launchMode="singleInstance" - android:theme="@android:style/Theme.NoDisplay" - android:exported="false" /> - - <receiver - android:name="de.appplant.cordova.plugin.notification.TriggerReceiver" - android:exported="false" /> - - <receiver - android:name="de.appplant.cordova.plugin.notification.ClearReceiver" - android:exported="false" /> - - <receiver android:name="de.appplant.cordova.plugin.localnotification.RestoreReceiver" android:exported="false" > - <intent-filter> - <action android:name="android.intent.action.BOOT_COMPLETED" /> - </intent-filter> - </receiver> - - <activity - android:name="de.appplant.cordova.plugin.notification.ClickActivity" - android:launchMode="singleInstance" - android:theme="@android:style/Theme.NoDisplay" - android:exported="false" /> - - </config-file> - - <config-file target="AndroidManifest.xml" parent="/manifest"> - <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </config-file> - - <source-file - src="src/android/LocalNotification.java" - target-dir="src/de/appplant/cordova/plugin/localnotification" /> - - <source-file - src="src/android/TriggerReceiver.java" - target-dir="src/de/appplant/cordova/plugin/localnotification" /> - - <source-file - src="src/android/ClickActivity.java" - target-dir="src/de/appplant/cordova/plugin/localnotification" /> - - <source-file - src="src/android/ClearReceiver.java" - target-dir="src/de/appplant/cordova/plugin/localnotification" /> - - <source-file - src="src/android/RestoreReceiver.java" - target-dir="src/de/appplant/cordova/plugin/localnotification" /> - - <source-file - src="src/android/notification/AbstractClearReceiver.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/AbstractClickActivity.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/AbstractRestoreReceiver.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/AbstractTriggerReceiver.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/AssetUtil.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/Builder.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/ClearReceiver.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/ClickActivity.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/Manager.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/Notification.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/Options.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - <source-file - src="src/android/notification/TriggerReceiver.java" - target-dir="src/de/appplant/cordova/plugin/notification" /> - - </platform> - - <!-- windows --> - <platform name="windows"> - - <js-module src="src/windows/LocalNotificationProxy.js" name="LocalNotification.Proxy" > - <merges target="" /> - </js-module> - - <js-module src="src/windows/LocalNotificationCore.js" name="LocalNotification.Proxy.Core" > - <merges target="" /> - </js-module> - - <js-module src="src/windows/LocalNotificationUtil.js" name="LocalNotification.Proxy.Util" > - <merges target="" /> - </js-module> - - <!-- Platform Hooks --> - <hook type="after_platform_add" src="scripts/windows/setToastCapable.js" /> - <hook type="after_plugin_install" src="scripts/windows/setToastCapable.js" /> - - <hook type="after_platform_add" src="scripts/windows/broadcastActivateEvent.js" /> - <hook type="after_plugin_install" src="scripts/windows/broadcastActivateEvent.js" /> - <hook type="after_prepare" src="scripts/windows/broadcastActivateEvent.js" /> - - </platform> - -</plugin> diff --git a/plugins/de.appplant.cordova.plugin.local-notification/scripts/windows/broadcastActivateEvent.js b/plugins/de.appplant.cordova.plugin.local-notification/scripts/windows/broadcastActivateEvent.js deleted file mode 100755 index 40a90ca0..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/scripts/windows/broadcastActivateEvent.js +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env node - -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - - -// Includes a snippet into the cordova-core js file -// to fire the activated event after device is ready - - -var fs = require('fs'), - rootdir = process.argv[2]; - -if (!rootdir) - return; - -/** - * Replaces a string with another one in a file. - * - * @param {String} path - * Absolute or relative file path from cordova root project. - * @param {String} to_replace - * The string to replace. - * @param {String} - * The string to replace with. - */ -function replace (filename, to_replace, replace_with) { - var data = fs.readFileSync(filename, 'utf8'), - result; - - if (data.indexOf(replace_with) > -1) - return; - - result = data.replace(to_replace, replace_with); - fs.writeFileSync(filename, result, 'utf8'); -} - -// Fires the activated event again after device is ready -var snippet = - "var activatedHandler = function (args) {" + - "channel.deviceready.subscribe(function () {" + - "app.queueEvent(args);" + - "});" + - "};" + - "app.addEventListener('activated', activatedHandler, false);" + - "document.addEventListener('deviceready', function () {" + - "app.removeEventListener('activated', activatedHandler);" + - "}, false);\n" + - " app.start();"; - -// Path to cordova-core js files where the snippet needs to be included -var files = [ - 'platforms/windows/www/cordova.js', - 'platforms/windows/platform_www/cordova.js' -]; - -// Includes the snippet before app.start() is called -for (var i = 0; i < files.length; i++) { - replace(files[i], 'app.start();', snippet); -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/scripts/windows/setToastCapable.js b/plugins/de.appplant.cordova.plugin.local-notification/scripts/windows/setToastCapable.js deleted file mode 100755 index 46b56102..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/scripts/windows/setToastCapable.js +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env node - -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - - -// Hook sets ToastCapable on true to enable local-notifications - - -var fs = require('fs'), - rootdir = process.argv[2]; - -if (!rootdir) - return; - -/** - * Replaces a string with another one in a file. - * - * @param {String} path - * Absolute or relative file path from cordova root project. - * @param {String} to_replace - * The string to replace. - * @param {String} - * The string to replace with. - */ -function replace (filename, to_replace, replace_with) { - var data = fs.readFileSync(filename, 'utf8'), - result; - - if (data.indexOf('ToastCapable') > -1) - return; - - result = data.replace(new RegExp(to_replace, 'g'), replace_with); - - fs.writeFileSync(filename, result, 'utf8'); -} - -// Set ToastCapable for Windows Phone -replace('platforms/windows/package.phone.appxmanifest', '<m3:VisualElements', '<m3:VisualElements ToastCapable="true"'); -// Set ToastCapable for Windows 8.1 -replace('platforms/windows/package.windows.appxmanifest', '<m2:VisualElements', '<m2:VisualElements ToastCapable="true"'); -// Set ToastCapable for Windows 8.0 -replace('platforms/windows/package.windows80.appxmanifest', '<VisualElements', '<VisualElements ToastCapable="true"'); diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClearReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClearReceiver.java deleted file mode 100644 index e0892e37..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClearReceiver.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.localnotification; - -import de.appplant.cordova.plugin.notification.Notification; - - -/** - * The clear intent receiver is triggered when the user clears a - * notification manually. It un-persists the cleared notification from the - * shared preferences. - */ -public class ClearReceiver extends de.appplant.cordova.plugin.notification.ClearReceiver { - - /** - * Called when a local notification was cleared from outside of the app. - * - * @param notification - * Wrapper around the local notification - */ - @Override - public void onClear (Notification notification) { - super.onClear(notification); - LocalNotification.fireEvent("clear", notification); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClickActivity.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClickActivity.java deleted file mode 100644 index d366d355..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/ClickActivity.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.localnotification; - -import de.appplant.cordova.plugin.notification.Builder; -import de.appplant.cordova.plugin.notification.Notification; -import de.appplant.cordova.plugin.notification.TriggerReceiver; - -/** - * The receiver activity is triggered when a notification is clicked by a user. - * The activity calls the background callback and brings the launch intent - * up to foreground. - */ -public class ClickActivity extends de.appplant.cordova.plugin.notification.ClickActivity { - - /** - * Called when local notification was clicked by the user. - * - * @param notification - * Wrapper around the local notification - */ - @Override - public void onClick(Notification notification) { - LocalNotification.fireEvent("click", notification); - - if (!notification.getOptions().isOngoing()) { - String event = notification.isRepeating() ? "clear" : "cancel"; - - LocalNotification.fireEvent(event, notification); - } - - super.onClick(notification); - } - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - @Override - public Notification buildNotification (Builder builder) { - return builder - .setTriggerReceiver(TriggerReceiver.class) - .build(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/LocalNotification.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/LocalNotification.java deleted file mode 100644 index 906c8d69..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/LocalNotification.java +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.localnotification; - -import android.app.Activity; -import android.os.Build; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -import de.appplant.cordova.plugin.notification.Manager; -import de.appplant.cordova.plugin.notification.Notification; - -/** - * This plugin utilizes the Android AlarmManager in combination with local - * notifications. When a local notification is scheduled the alarm manager takes - * care of firing the event. When the event is processed, a notification is put - * in the Android notification center and status bar. - */ -public class LocalNotification extends CordovaPlugin { - - // Reference to the web view for static access - private static CordovaWebView webView = null; - - // Indicates if the device is ready (to receive events) - private static Boolean deviceready = false; - - // To inform the user about the state of the app in callbacks - protected static Boolean isInBackground = true; - - // Queues all events before deviceready - private static ArrayList<String> eventQueue = new ArrayList<String>(); - - /** - * Called after plugin construction and fields have been initialized. - * Prefer to use pluginInitialize instead since there is no value in - * having parameters on the initialize() function. - * - * pluginInitialize is not available for cordova 3.0-3.5 ! - */ - @Override - public void initialize (CordovaInterface cordova, CordovaWebView webView) { - LocalNotification.webView = super.webView; - } - - /** - * Called when the system is about to start resuming a previous activity. - * - * @param multitasking - * Flag indicating if multitasking is turned on for app - */ - @Override - public void onPause(boolean multitasking) { - super.onPause(multitasking); - isInBackground = true; - } - - /** - * Called when the activity will start interacting with the user. - * - * @param multitasking - * Flag indicating if multitasking is turned on for app - */ - @Override - public void onResume(boolean multitasking) { - super.onResume(multitasking); - isInBackground = false; - deviceready(); - } - - /** - * The final call you receive before your activity is destroyed. - */ - @Override - public void onDestroy() { - deviceready = false; - isInBackground = true; - } - - /** - * Executes the request. - * - * This method is called from the WebView thread. To do a non-trivial - * amount of work, use: - * cordova.getThreadPool().execute(runnable); - * - * To run on the UI thread, use: - * cordova.getActivity().runOnUiThread(runnable); - * - * @param action - * The action to execute. - * @param args - * The exec() arguments in JSON form. - * @param command - * The callback context used when calling back into JavaScript. - * @return - * Whether the action was valid. - */ - @Override - public boolean execute (final String action, final JSONArray args, - final CallbackContext command) throws JSONException { - - Notification.setDefaultTriggerReceiver(TriggerReceiver.class); - - cordova.getThreadPool().execute(new Runnable() { - public void run() { - if (action.equals("schedule")) { - schedule(args); - command.success(); - } - else if (action.equals("update")) { - update(args); - command.success(); - } - else if (action.equals("cancel")) { - cancel(args); - command.success(); - } - else if (action.equals("cancelAll")) { - cancelAll(); - command.success(); - } - else if (action.equals("clear")) { - clear(args); - command.success(); - } - else if (action.equals("clearAll")) { - clearAll(); - command.success(); - } - else if (action.equals("isPresent")) { - isPresent(args.optInt(0), command); - } - else if (action.equals("isScheduled")) { - isScheduled(args.optInt(0), command); - } - else if (action.equals("isTriggered")) { - isTriggered(args.optInt(0), command); - } - else if (action.equals("getAllIds")) { - getAllIds(command); - } - else if (action.equals("getScheduledIds")) { - getScheduledIds(command); - } - else if (action.equals("getTriggeredIds")) { - getTriggeredIds(command); - } - else if (action.equals("getSingle")) { - getSingle(args, command); - } - else if (action.equals("getSingleScheduled")) { - getSingleScheduled(args, command); - } - else if (action.equals("getSingleTriggered")) { - getSingleTriggered(args, command); - } - else if (action.equals("getAll")) { - getAll(args, command); - } - else if (action.equals("getScheduled")) { - getScheduled(args, command); - } - else if (action.equals("getTriggered")) { - getTriggered(args, command); - } - else if (action.equals("deviceready")) { - deviceready(); - } - } - }); - - return true; - } - - /** - * Schedule multiple local notifications. - * - * @param notifications - * Properties for each local notification - */ - private void schedule (JSONArray notifications) { - for (int i = 0; i < notifications.length(); i++) { - JSONObject options = notifications.optJSONObject(i); - - Notification notification = - getNotificationMgr().schedule(options, TriggerReceiver.class); - - fireEvent("schedule", notification); - } - } - - /** - * Update multiple local notifications. - * - * @param updates - * Notification properties including their IDs - */ - private void update (JSONArray updates) { - for (int i = 0; i < updates.length(); i++) { - JSONObject update = updates.optJSONObject(i); - int id = update.optInt("id", 0); - - Notification notification = - getNotificationMgr().update(id, update, TriggerReceiver.class); - - fireEvent("update", notification); - } - } - - /** - * Cancel multiple local notifications. - * - * @param ids - * Set of local notification IDs - */ - private void cancel (JSONArray ids) { - for (int i = 0; i < ids.length(); i++) { - int id = ids.optInt(i, 0); - - Notification notification = - getNotificationMgr().cancel(id); - - if (notification != null) { - fireEvent("cancel", notification); - } - } - } - - /** - * Cancel all scheduled notifications. - */ - private void cancelAll() { - getNotificationMgr().cancelAll(); - fireEvent("cancelall"); - } - - /** - * Clear multiple local notifications without canceling them. - * - * @param ids - * Set of local notification IDs - */ - private void clear(JSONArray ids){ - for (int i = 0; i < ids.length(); i++) { - int id = ids.optInt(i, 0); - - Notification notification = - getNotificationMgr().clear(id); - - if (notification != null) { - fireEvent("clear", notification); - } - } - } - - /** - * Clear all triggered notifications without canceling them. - */ - private void clearAll() { - getNotificationMgr().clearAll(); - fireEvent("clearall"); - } - - /** - * If a notification with an ID is present. - * - * @param id - * Notification ID - * @param command - * The callback context used when calling back into JavaScript. - */ - private void isPresent (int id, CallbackContext command) { - boolean exist = getNotificationMgr().exist(id); - - PluginResult result = new PluginResult( - PluginResult.Status.OK, exist); - - command.sendPluginResult(result); - } - - /** - * If a notification with an ID is scheduled. - * - * @param id - * Notification ID - * @param command - * The callback context used when calling back into JavaScript. - */ - private void isScheduled (int id, CallbackContext command) { - boolean exist = getNotificationMgr().exist( - id, Notification.Type.SCHEDULED); - - PluginResult result = new PluginResult( - PluginResult.Status.OK, exist); - - command.sendPluginResult(result); - } - - /** - * If a notification with an ID is triggered. - * - * @param id - * Notification ID - * @param command - * The callback context used when calling back into JavaScript. - */ - private void isTriggered (int id, CallbackContext command) { - boolean exist = getNotificationMgr().exist( - id, Notification.Type.TRIGGERED); - - PluginResult result = new PluginResult( - PluginResult.Status.OK, exist); - - command.sendPluginResult(result); - } - - /** - * Set of IDs from all existent notifications. - * - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getAllIds (CallbackContext command) { - List<Integer> ids = getNotificationMgr().getIds(); - - command.success(new JSONArray(ids)); - } - - /** - * Set of IDs from all scheduled notifications. - * - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getScheduledIds (CallbackContext command) { - List<Integer> ids = getNotificationMgr().getIdsByType( - Notification.Type.SCHEDULED); - - command.success(new JSONArray(ids)); - } - - /** - * Set of IDs from all triggered notifications. - * - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getTriggeredIds (CallbackContext command) { - List<Integer> ids = getNotificationMgr().getIdsByType( - Notification.Type.TRIGGERED); - - command.success(new JSONArray(ids)); - } - - /** - * Options from local notification. - * - * @param ids - * Set of local notification IDs - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getSingle (JSONArray ids, CallbackContext command) { - getOptions(ids.optString(0), Notification.Type.ALL, command); - } - - /** - * Options from scheduled notification. - * - * @param ids - * Set of local notification IDs - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getSingleScheduled (JSONArray ids, CallbackContext command) { - getOptions(ids.optString(0), Notification.Type.SCHEDULED, command); - } - - /** - * Options from triggered notification. - * - * @param ids - * Set of local notification IDs - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getSingleTriggered (JSONArray ids, CallbackContext command) { - getOptions(ids.optString(0), Notification.Type.TRIGGERED, command); - } - - /** - * Set of options from local notification. - * - * @param ids - * Set of local notification IDs - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getAll (JSONArray ids, CallbackContext command) { - getOptions(ids, Notification.Type.ALL, command); - } - - /** - * Set of options from scheduled notifications. - * - * @param ids - * Set of local notification IDs - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getScheduled (JSONArray ids, CallbackContext command) { - getOptions(ids, Notification.Type.SCHEDULED, command); - } - - /** - * Set of options from triggered notifications. - * - * @param ids - * Set of local notification IDs - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getTriggered (JSONArray ids, CallbackContext command) { - getOptions(ids, Notification.Type.TRIGGERED, command); - } - - /** - * Options from local notification. - * - * @param id - * Set of local notification IDs - * @param type - * The local notification life cycle type - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getOptions (String id, Notification.Type type, - CallbackContext command) { - - JSONArray ids = new JSONArray().put(id); - - JSONObject options = - getNotificationMgr().getOptionsBy(type, toList(ids)).get(0); - - command.success(options); - } - - /** - * Set of options from local notifications. - * - * @param ids - * Set of local notification IDs - * @param type - * The local notification life cycle type - * @param command - * The callback context used when calling back into JavaScript. - */ - private void getOptions (JSONArray ids, Notification.Type type, - CallbackContext command) { - - List<JSONObject> options; - - if (ids.length() == 0) { - options = getNotificationMgr().getOptionsByType(type); - } else { - options = getNotificationMgr().getOptionsBy(type, toList(ids)); - } - - command.success(new JSONArray(options)); - } - - /** - * Call all pending callbacks after the deviceready event has been fired. - */ - private static synchronized void deviceready () { - isInBackground = false; - deviceready = true; - - for (String js : eventQueue) { - sendJavascript(js); - } - - eventQueue.clear(); - } - - /** - * Fire given event on JS side. Does inform all event listeners. - * - * @param event - * The event name - */ - private void fireEvent (String event) { - fireEvent(event, null); - } - - /** - * Fire given event on JS side. Does inform all event listeners. - * - * @param event - * The event name - * @param notification - * Optional local notification to pass the id and properties. - */ - static void fireEvent (String event, Notification notification) { - String state = getApplicationState(); - String params = "\"" + state + "\""; - - if (notification != null) { - params = notification.toString() + "," + params; - } - - String js = "cordova.plugins.notification.local.core.fireEvent(" + - "\"" + event + "\"," + params + ")"; - - sendJavascript(js); - } - - /** - * Use this instead of deprecated sendJavascript - * - * @param js - * JS code snippet as string - */ - private static synchronized void sendJavascript(final String js) { - - if (!deviceready) { - eventQueue.add(js); - return; - } - Runnable jsLoader = new Runnable() { - public void run() { - webView.loadUrl("javascript:" + js); - } - }; - try { - Method post = webView.getClass().getMethod("post",Runnable.class); - post.invoke(webView,jsLoader); - } catch(Exception e) { - - ((Activity)(webView.getContext())).runOnUiThread(jsLoader); - } - } - - /** - * Convert JSON array of integers to List. - * - * @param ary - * Array of integers - */ - private List<Integer> toList (JSONArray ary) { - ArrayList<Integer> list = new ArrayList<Integer>(); - - for (int i = 0; i < ary.length(); i++) { - list.add(ary.optInt(i)); - } - - return list; - } - - /** - * Current application state. - * - * @return - * "background" or "foreground" - */ - static String getApplicationState () { - return isInBackground ? "background" : "foreground"; - } - - /** - * Notification manager instance. - */ - private Manager getNotificationMgr() { - return Manager.getInstance(cordova.getActivity()); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/RestoreReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/RestoreReceiver.java deleted file mode 100644 index 7de4e328..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/RestoreReceiver.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.localnotification; - -import de.appplant.cordova.plugin.notification.AbstractRestoreReceiver; -import de.appplant.cordova.plugin.notification.Builder; -import de.appplant.cordova.plugin.notification.Notification; - -/** - * This class is triggered upon reboot of the device. It needs to re-register - * the alarms with the AlarmManager since these alarms are lost in case of - * reboot. - */ -public class RestoreReceiver extends AbstractRestoreReceiver { - - /** - * Called when a local notification need to be restored. - * - * @param notification - * Wrapper around the local notification - */ - @Override - public void onRestore (Notification notification) { - if (notification.isScheduled()) { - notification.schedule(); - } - } - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - @Override - public Notification buildNotification (Builder builder) { - return builder - .setTriggerReceiver(TriggerReceiver.class) - .setClearReceiver(ClearReceiver.class) - .setClickActivity(ClickActivity.class) - .build(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/TriggerReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/TriggerReceiver.java deleted file mode 100644 index 3c423c01..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/TriggerReceiver.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.localnotification; - -import de.appplant.cordova.plugin.notification.Builder; -import de.appplant.cordova.plugin.notification.Notification; - -/** - * The alarm receiver is triggered when a scheduled alarm is fired. This class - * reads the information in the intent and displays this information in the - * Android notification bar. The notification uses the default notification - * sound and it vibrates the phone. - */ -public class TriggerReceiver extends de.appplant.cordova.plugin.notification.TriggerReceiver { - - /** - * Called when a local notification was triggered. Does present the local - * notification, re-schedule the alarm if necessary and fire trigger event. - * - * @param notification - * Wrapper around the local notification - * @param updated - * If an update has triggered or the original - */ - @Override - public void onTrigger (Notification notification, boolean updated) { - super.onTrigger(notification, updated); - - if (!updated) { - LocalNotification.fireEvent("trigger", notification); - } - } - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - @Override - public Notification buildNotification (Builder builder) { - return builder - .setTriggerReceiver(TriggerReceiver.class) - .setClickActivity(ClickActivity.class) - .setClearReceiver(ClearReceiver.class) - .build(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClearReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClearReceiver.java deleted file mode 100644 index 94d2a19b..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClearReceiver.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Abstract delete receiver for local notifications. Creates the local - * notification and calls the event functions for further proceeding. - */ -abstract public class AbstractClearReceiver extends BroadcastReceiver { - - /** - * Called when the notification was cleared from the notification center. - * - * @param context - * Application context - * @param intent - * Received intent with content data - */ - @Override - public void onReceive(Context context, Intent intent) { - Bundle bundle = intent.getExtras(); - JSONObject options; - - try { - String data = bundle.getString(Options.EXTRA); - options = new JSONObject(data); - } catch (JSONException e) { - e.printStackTrace(); - return; - } - - Notification notification = - new Builder(context, options).build(); - - onClear(notification); - } - - /** - * Called when a local notification was cleared from outside of the app. - * - * @param notification - * Wrapper around the local notification - */ - abstract public void onClear (Notification notification); - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClickActivity.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClickActivity.java deleted file mode 100644 index a02a9981..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractClickActivity.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Abstract content receiver activity for local notifications. Creates the - * local notification and calls the event functions for further proceeding. - */ -abstract public class AbstractClickActivity extends Activity { - - /** - * Called when local notification was clicked to launch the main intent. - * - * @param state - * Saved instance state - */ - @Override - public void onCreate (Bundle state) { - super.onCreate(state); - - Intent intent = getIntent(); - Bundle bundle = intent.getExtras(); - Context context = getApplicationContext(); - - try { - String data = bundle.getString(Options.EXTRA); - JSONObject options = new JSONObject(data); - - Builder builder = - new Builder(context, options); - - Notification notification = - buildNotification(builder); - - onClick(notification); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - /** - * Called when local notification was clicked by the user. - * - * @param notification - * Wrapper around the local notification - */ - abstract public void onClick (Notification notification); - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - abstract public Notification buildNotification (Builder builder); - - /** - * Launch main intent from package. - */ - public void launchApp() { - Context context = getApplicationContext(); - String pkgName = context.getPackageName(); - - Intent intent = context - .getPackageManager() - .getLaunchIntentForPackage(pkgName); - - intent.addFlags( - Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); - - context.startActivity(intent); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractRestoreReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractRestoreReceiver.java deleted file mode 100644 index 8a1f3656..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractRestoreReceiver.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2014-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import org.json.JSONObject; - -import java.util.List; - -/** - * This class is triggered upon reboot of the device. It needs to re-register - * the alarms with the AlarmManager since these alarms are lost in case of - * reboot. - */ -abstract public class AbstractRestoreReceiver extends BroadcastReceiver { - - /** - * Called on device reboot. - * - * @param context - * Application context - * @param intent - * Received intent with content data - */ - @Override - public void onReceive (Context context, Intent intent) { - Manager notificationMgr = - Manager.getInstance(context); - - List<JSONObject> options = - notificationMgr.getOptions(); - - for (JSONObject data : options) { - Builder builder = new Builder(context, data); - - Notification notification = - buildNotification(builder); - - onRestore(notification); - } - } - - /** - * Called when a local notification need to be restored. - * - * @param notification - * Wrapper around the local notification - */ - abstract public void onRestore (Notification notification); - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - abstract public Notification buildNotification (Builder builder); - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractTriggerReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractTriggerReceiver.java deleted file mode 100644 index fc6759c5..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AbstractTriggerReceiver.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Calendar; - -/** - * Abstract broadcast receiver for local notifications. Creates the - * notification options and calls the event functions for further proceeding. - */ -abstract public class AbstractTriggerReceiver extends BroadcastReceiver { - - /** - * Called when an alarm was triggered. - * - * @param context - * Application context - * @param intent - * Received intent with content data - */ - @Override - public void onReceive(Context context, Intent intent) { - Bundle bundle = intent.getExtras(); - Options options; - - try { - String data = bundle.getString(Options.EXTRA); - JSONObject dict = new JSONObject(data); - - options = new Options(context).parse(dict); - } catch (JSONException e) { - e.printStackTrace(); - return; - } - - if (options == null) - return; - - if (isFirstAlarmInFuture(options)) - return; - - Builder builder = new Builder(options); - Notification notification = buildNotification(builder); - boolean updated = notification.isUpdate(); - - onTrigger(notification, updated); - } - - /** - * Called when a local notification was triggered. - * - * @param notification - * Wrapper around the local notification - * @param updated - * If an update has triggered or the original - */ - abstract public void onTrigger (Notification notification, boolean updated); - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - abstract public Notification buildNotification (Builder builder); - - /* - * If you set a repeating alarm at 11:00 in the morning and it - * should trigger every morning at 08:00 o'clock, it will - * immediately fire. E.g. Android tries to make up for the - * 'forgotten' reminder for that day. Therefore we ignore the event - * if Android tries to 'catch up'. - */ - private Boolean isFirstAlarmInFuture (Options options) { - Notification notification = new Builder(options).build(); - - if (!notification.isRepeating()) - return false; - - Calendar now = Calendar.getInstance(); - Calendar alarm = Calendar.getInstance(); - - alarm.setTime(notification.getOptions().getTriggerDate()); - - int alarmHour = alarm.get(Calendar.HOUR_OF_DAY); - int alarmMin = alarm.get(Calendar.MINUTE); - int currentHour = now.get(Calendar.HOUR_OF_DAY); - int currentMin = now.get(Calendar.MINUTE); - - return (currentHour != alarmHour && currentMin != alarmMin); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AssetUtil.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AssetUtil.java deleted file mode 100644 index 2da8a2c3..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/AssetUtil.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.content.Context; -import android.content.res.AssetManager; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.StrictMode; -import android.util.Log; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * Util class to map unified asset URIs to native URIs. URIs like file:/// - * map to absolute paths while file:// point relatively to the www folder - * within the asset resources. And res:// means a resource from the native - * res folder. Remote assets are accessible via http:// for example. - */ -class AssetUtil { - - // Name of the storage folder - private static final String STORAGE_FOLDER = "/localnotification"; - - // Placeholder URI for default sound - private static final String DEFAULT_SOUND = "res://platform_default"; - - // Ref to the context passed through the constructor to access the - // resources and app directory. - private final Context context; - - /** - * Constructor - * - * @param context - * Application context - */ - private AssetUtil(Context context) { - this.context = context; - } - - /** - * Static method to retrieve class instance. - * - * @param context - * Application context - */ - static AssetUtil getInstance(Context context) { - return new AssetUtil(context); - } - - /** - * Parse path path to native URI. - * - * @param path - * Path to path file - */ - Uri parseSound (String path) { - - if (path == null || path.isEmpty()) - return Uri.EMPTY; - - if (path.equalsIgnoreCase(DEFAULT_SOUND)) { - return RingtoneManager.getDefaultUri(RingtoneManager - .TYPE_NOTIFICATION); - } - - return parse(path); - } - - /** - * The URI for a path. - * - * @param path - * The given path - */ - Uri parse (String path) { - - if (path.startsWith("res:")) { - return getUriForResourcePath(path); - } else if (path.startsWith("file:///")) { - return getUriFromPath(path); - } else if (path.startsWith("file://")) { - return getUriFromAsset(path); - } else if (path.startsWith("http")){ - return getUriFromRemote(path); - } - - return Uri.EMPTY; - } - - /** - * URI for a file. - * - * @param path - * Absolute path like file:///... - * - * @return - * URI pointing to the given path - */ - private Uri getUriFromPath(String path) { - String absPath = path.replaceFirst("file://", ""); - File file = new File(absPath); - - if (!file.exists()) { - Log.e("Asset", "File not found: " + file.getAbsolutePath()); - return Uri.EMPTY; - } - - return Uri.fromFile(file); - } - - /** - * URI for an asset. - * - * @param path - * Asset path like file://... - * - * @return - * URI pointing to the given path - */ - private Uri getUriFromAsset(String path) { - File dir = context.getExternalCacheDir(); - - if (dir == null) { - Log.e("Asset", "Missing external cache dir"); - return Uri.EMPTY; - } - - String resPath = path.replaceFirst("file:/", "www"); - String fileName = resPath.substring(resPath.lastIndexOf('/') + 1); - String storage = dir.toString() + STORAGE_FOLDER; - File file = new File(storage, fileName); - - //noinspection ResultOfMethodCallIgnored - new File(storage).mkdir(); - - try { - AssetManager assets = context.getAssets(); - FileOutputStream outStream = new FileOutputStream(file); - InputStream inputStream = assets.open(resPath); - - copyFile(inputStream, outStream); - - outStream.flush(); - outStream.close(); - - return Uri.fromFile(file); - - } catch (Exception e) { - Log.e("Asset", "File not found: assets/" + resPath); - e.printStackTrace(); - } - - return Uri.EMPTY; - } - - /** - * The URI for a resource. - * - * @param path - * The given relative path - * - * @return - * URI pointing to the given path - */ - private Uri getUriForResourcePath(String path) { - File dir = context.getExternalCacheDir(); - - if (dir == null) { - Log.e("Asset", "Missing external cache dir"); - return Uri.EMPTY; - } - - String resPath = path.replaceFirst("res://", ""); - - int resId = getResIdForDrawable(resPath); - - if (resId == 0) { - Log.e("Asset", "File not found: " + resPath); - return Uri.EMPTY; - } - - String resName = extractResourceName(resPath); - String extName = extractResourceExtension(resPath); - String storage = dir.toString() + STORAGE_FOLDER; - File file = new File(storage, resName + extName); - - //noinspection ResultOfMethodCallIgnored - new File(storage).mkdir(); - - try { - Resources res = context.getResources(); - FileOutputStream outStream = new FileOutputStream(file); - InputStream inputStream = res.openRawResource(resId); - copyFile(inputStream, outStream); - - outStream.flush(); - outStream.close(); - - return Uri.fromFile(file); - - } catch (Exception e) { - e.printStackTrace(); - } - - return Uri.EMPTY; - } - - /** - * Uri from remote located content. - * - * @param path - * Remote address - * - * @return - * Uri of the downloaded file - */ - private Uri getUriFromRemote(String path) { - File dir = context.getExternalCacheDir(); - - if (dir == null) { - Log.e("Asset", "Missing external cache dir"); - return Uri.EMPTY; - } - - String resName = extractResourceName(path); - String extName = extractResourceExtension(path); - String storage = dir.toString() + STORAGE_FOLDER; - File file = new File(storage, resName + extName); - - //noinspection ResultOfMethodCallIgnored - new File(storage).mkdir(); - - try { - URL url = new URL(path); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - - StrictMode.ThreadPolicy policy = - new StrictMode.ThreadPolicy.Builder().permitAll().build(); - - StrictMode.setThreadPolicy(policy); - - connection.setRequestProperty("Connection", "close"); - connection.setConnectTimeout(5000); - connection.connect(); - - InputStream input = connection.getInputStream(); - FileOutputStream outStream = new FileOutputStream(file); - - copyFile(input, outStream); - - outStream.flush(); - outStream.close(); - - return Uri.fromFile(file); - - } catch (MalformedURLException e) { - Log.e("Asset", "Incorrect URL"); - e.printStackTrace(); - } catch (FileNotFoundException e) { - Log.e("Asset", "Failed to create new File from HTTP Content"); - e.printStackTrace(); - } catch (IOException e) { - Log.e("Asset", "No Input can be created from http Stream"); - e.printStackTrace(); - } - - return Uri.EMPTY; - } - - /** - * Copy content from input stream into output stream. - * - * @param in - * The input stream - * @param out - * The output stream - */ - private void copyFile(InputStream in, OutputStream out) throws IOException { - byte[] buffer = new byte[1024]; - int read; - - while ((read = in.read(buffer)) != -1) { - out.write(buffer, 0, read); - } - } - - /** - * Resource ID for drawable. - * - * @param resPath - * Resource path as string - */ - int getResIdForDrawable(String resPath) { - int resId = getResIdForDrawable(getPkgName(), resPath); - - if (resId == 0) { - resId = getResIdForDrawable("android", resPath); - } - - return resId; - } - - /** - * Resource ID for drawable. - * - * @param clsName - * Relative package or global android name space - * @param resPath - * Resource path as string - */ - int getResIdForDrawable(String clsName, String resPath) { - String drawable = extractResourceName(resPath); - int resId = 0; - - try { - Class<?> cls = Class.forName(clsName + ".R$drawable"); - - resId = (Integer) cls.getDeclaredField(drawable).get(Integer.class); - } catch (Exception ignore) {} - - return resId; - } - - /** - * Convert drawable resource to bitmap. - * - * @param drawable - * Drawable resource name - */ - Bitmap getIconFromDrawable (String drawable) { - Resources res = context.getResources(); - int iconId; - - iconId = getResIdForDrawable(getPkgName(), drawable); - - if (iconId == 0) { - iconId = getResIdForDrawable("android", drawable); - } - - if (iconId == 0) { - iconId = android.R.drawable.ic_menu_info_details; - } - - return BitmapFactory.decodeResource(res, iconId); - } - - /** - * Convert URI to Bitmap. - * - * @param uri - * Internal image URI - */ - Bitmap getIconFromUri (Uri uri) throws IOException { - InputStream input = context.getContentResolver().openInputStream(uri); - - return BitmapFactory.decodeStream(input); - } - - /** - * Extract name of drawable resource from path. - * - * @param resPath - * Resource path as string - */ - private String extractResourceName (String resPath) { - String drawable = resPath; - - if (drawable.contains("/")) { - drawable = drawable.substring(drawable.lastIndexOf('/') + 1); - } - - if (resPath.contains(".")) { - drawable = drawable.substring(0, drawable.lastIndexOf('.')); - } - - return drawable; - } - - /** - * Extract extension of drawable resource from path. - * - * @param resPath - * Resource path as string - */ - private String extractResourceExtension (String resPath) { - String extName = "png"; - - if (resPath.contains(".")) { - extName = resPath.substring(resPath.lastIndexOf('.')); - } - - return extName; - } - - /** - * Package name specified by context. - */ - private String getPkgName () { - return context.getPackageName(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Builder.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Builder.java deleted file mode 100644 index a0be8b93..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Builder.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.support.v4.app.NotificationCompat; - -import org.json.JSONObject; - -import java.util.Random; - -/** - * Builder class for local notifications. Build fully configured local - * notification specified by JSON object passed from JS side. - */ -public class Builder { - - // Application context passed by constructor - private final Context context; - - // Notification options passed by JS - private final Options options; - - // Receiver to handle the trigger event - private Class<?> triggerReceiver; - - // Receiver to handle the clear event - private Class<?> clearReceiver = ClearReceiver.class; - - // Activity to handle the click event - private Class<?> clickActivity = ClickActivity.class; - - /** - * Constructor - * - * @param context - * Application context - * @param options - * Notification options - */ - public Builder(Context context, JSONObject options) { - this.context = context; - this.options = new Options(context).parse(options); - } - - /** - * Constructor - * - * @param options - * Notification options - */ - public Builder(Options options) { - this.context = options.getContext(); - this.options = options; - } - - /** - * Set trigger receiver. - * - * @param receiver - * Broadcast receiver - */ - public Builder setTriggerReceiver(Class<?> receiver) { - this.triggerReceiver = receiver; - return this; - } - - /** - * Set clear receiver. - * - * @param receiver - * Broadcast receiver - */ - public Builder setClearReceiver(Class<?> receiver) { - this.clearReceiver = receiver; - return this; - } - - /** - * Set click activity. - * - * @param activity - * Activity - */ - public Builder setClickActivity(Class<?> activity) { - this.clickActivity = activity; - return this; - } - - /** - * Creates the notification with all its options passed through JS. - */ - public Notification build() { - Uri sound = options.getSoundUri(); - NotificationCompat.BigTextStyle style; - NotificationCompat.Builder builder; - - style = new NotificationCompat.BigTextStyle() - .bigText(options.getText()); - - builder = new NotificationCompat.Builder(context) - .setDefaults(0) - .setContentTitle(options.getTitle()) - .setContentText(options.getText()) - .setNumber(options.getBadgeNumber()) - .setTicker(options.getText()) - .setSmallIcon(options.getSmallIcon()) - .setLargeIcon(options.getIconBitmap()) - .setAutoCancel(options.isAutoClear()) - .setOngoing(options.isOngoing()) - .setStyle(style) - .setLights(options.getLedColor(), 500, 500); - - if (sound != null) { - builder.setSound(sound); - } - - applyDeleteReceiver(builder); - applyContentReceiver(builder); - - return new Notification(context, options, builder, triggerReceiver); - } - - /** - * Set intent to handle the delete event. Will clean up some persisted - * preferences. - * - * @param builder - * Local notification builder instance - */ - private void applyDeleteReceiver(NotificationCompat.Builder builder) { - - if (clearReceiver == null) - return; - - Intent deleteIntent = new Intent(context, clearReceiver) - .setAction(options.getIdStr()) - .putExtra(Options.EXTRA, options.toString()); - - PendingIntent dpi = PendingIntent.getBroadcast( - context, 0, deleteIntent, PendingIntent.FLAG_CANCEL_CURRENT); - - builder.setDeleteIntent(dpi); - } - - /** - * Set intent to handle the click event. Will bring the app to - * foreground. - * - * @param builder - * Local notification builder instance - */ - private void applyContentReceiver(NotificationCompat.Builder builder) { - - if (clickActivity == null) - return; - - Intent intent = new Intent(context, clickActivity) - .putExtra(Options.EXTRA, options.toString()) - .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - - int requestCode = new Random().nextInt(); - - PendingIntent contentIntent = PendingIntent.getActivity( - context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); - - builder.setContentIntent(contentIntent); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClearReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClearReceiver.java deleted file mode 100644 index 761b6c5c..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClearReceiver.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -/** - * The clear intent receiver is triggered when the user clears a - * notification manually. It un-persists the cleared notification from the - * shared preferences. - */ -public class ClearReceiver extends AbstractClearReceiver { - - /** - * Called when a local notification was cleared from outside of the app. - * - * @param notification - * Wrapper around the local notification - */ - @Override - public void onClear (Notification notification) { - notification.clear(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClickActivity.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClickActivity.java deleted file mode 100644 index 01af5c45..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/ClickActivity.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -/** - * The receiver activity is triggered when a notification is clicked by a user. - * The activity calls the background callback and brings the launch intent - * up to foreground. - */ -public class ClickActivity extends AbstractClickActivity { - - /** - * Called when local notification was clicked by the user. Will - * move the app to foreground. - * - * @param notification - * Wrapper around the local notification - */ - @Override - public void onClick(Notification notification) { - launchApp(); - } - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - public Notification buildNotification (Builder builder) { - return builder.build(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Manager.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Manager.java deleted file mode 100644 index 03ea384f..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Manager.java +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.app.NotificationManager; -import android.content.Context; -import android.content.SharedPreferences; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static de.appplant.cordova.plugin.notification.Notification.PREF_KEY; - -/** - * Central way to access all or single local notifications set by specific - * state like triggered or scheduled. Offers shortcut ways to schedule, - * cancel or clear local notifications. - */ -public class Manager { - - // Context passed through constructor and used for notification builder. - private Context context; - - /** - * Constructor - * - * @param context - * Application context - */ - private Manager(Context context){ - this.context = context; - } - - /** - * Static method to retrieve class instance. - * - * @param context - * Application context - */ - public static Manager getInstance(Context context) { - return new Manager(context); - } - - /** - * Schedule local notification specified by JSON object. - * - * @param options - * JSON object with set of options - * @param receiver - * Receiver to handle the trigger event - */ - public Notification schedule (JSONObject options, Class<?> receiver) { - return schedule(new Options(context).parse(options), receiver); - } - - /** - * Schedule local notification specified by options object. - * - * @param options - * Set of notification options - * @param receiver - * Receiver to handle the trigger event - */ - public Notification schedule (Options options, Class<?> receiver) { - Notification notification = new Builder(options) - .setTriggerReceiver(receiver) - .build(); - - notification.schedule(); - - return notification; - } - - /** - * Clear local notification specified by ID. - * - * @param id - * The notification ID - * @param updates - * JSON object with notification options - * @param receiver - * Receiver to handle the trigger event - */ - public Notification update (int id, JSONObject updates, Class<?> receiver) { - Notification notification = get(id); - - if (notification == null) - return null; - - notification.cancel(); - - JSONObject options = mergeJSONObjects( - notification.getOptions().getDict(), updates); - - try { - options.putOpt("updatedAt", new Date().getTime()); - } catch (JSONException ignore) {} - - return schedule(options, receiver); - } - - /** - * Clear local notification specified by ID. - * - * @param id - * The notification ID - */ - public Notification clear (int id) { - Notification notification = get(id); - - if (notification != null) { - notification.clear(); - } - - return notification; - } - - /** - * Clear local notification specified by ID. - * - * @param id - * The notification ID - */ - public Notification cancel (int id) { - Notification notification = get(id); - - if (notification != null) { - notification.cancel(); - } - - return notification; - } - - /** - * Clear all local notifications. - */ - public void clearAll () { - List<Notification> notifications = getAll(); - - for (Notification notification : notifications) { - notification.clear(); - } - - getNotMgr().cancelAll(); - } - - /** - * Cancel all local notifications. - */ - public void cancelAll () { - List<Notification> notifications = getAll(); - - for (Notification notification : notifications) { - notification.cancel(); - } - - getNotMgr().cancelAll(); - } - - /** - * All local notifications IDs. - */ - public List<Integer> getIds() { - Set<String> keys = getPrefs().getAll().keySet(); - ArrayList<Integer> ids = new ArrayList<Integer>(); - - for (String key : keys) { - ids.add(Integer.parseInt(key)); - } - - return ids; - } - - /** - * All local notification IDs for given type. - * - * @param type - * The notification life cycle type - */ - public List<Integer> getIdsByType(Notification.Type type) { - List<Notification> notifications = getAll(); - ArrayList<Integer> ids = new ArrayList<Integer>(); - - for (Notification notification : notifications) { - if (notification.getType() == type) { - ids.add(notification.getId()); - } - } - - return ids; - } - - /** - * List of local notifications with matching ID. - * - * @param ids - * Set of notification IDs - */ - public List<Notification> getByIds(List<Integer> ids) { - ArrayList<Notification> notifications = new ArrayList<Notification>(); - - for (int id : ids) { - Notification notification = get(id); - - if (notification != null) { - notifications.add(notification); - } - } - - return notifications; - } - - /** - * List of all local notification. - */ - public List<Notification> getAll() { - return getByIds(getIds()); - } - - /** - * List of local notifications from given type. - * - * @param type - * The notification life cycle type - */ - public List<Notification> getByType(Notification.Type type) { - List<Notification> notifications = getAll(); - ArrayList<Notification> list = new ArrayList<Notification>(); - - if (type == Notification.Type.ALL) - return notifications; - - for (Notification notification : notifications) { - if (notification.getType() == type) { - list.add(notification); - } - } - - return list; - } - - /** - * List of local notifications with matching ID from given type. - * - * @param type - * The notification life cycle type - * @param ids - * Set of notification IDs - */ - @SuppressWarnings("UnusedDeclaration") - public List<Notification> getBy(Notification.Type type, List<Integer> ids) { - ArrayList<Notification> notifications = new ArrayList<Notification>(); - - for (int id : ids) { - Notification notification = get(id); - - if (notification != null && notification.isScheduled()) { - notifications.add(notification); - } - } - - return notifications; - } - - /** - * If a notification with an ID exists. - * - * @param id - * Notification ID - */ - public boolean exist (int id) { - return get(id) != null; - } - - /** - * If a notification with an ID and type exists. - * - * @param id - * Notification ID - * @param type - * Notification type - */ - public boolean exist (int id, Notification.Type type) { - Notification notification = get(id); - - return notification != null && notification.getType() == type; - } - - /** - * List of properties from all local notifications. - */ - public List<JSONObject> getOptions() { - return getOptionsById(getIds()); - } - - /** - * List of properties from local notifications with matching ID. - * - * @param ids - * Set of notification IDs - */ - public List<JSONObject> getOptionsById(List<Integer> ids) { - ArrayList<JSONObject> options = new ArrayList<JSONObject>(); - - for (int id : ids) { - Notification notification = get(id); - - if (notification != null) { - options.add(notification.getOptions().getDict()); - } - } - - return options; - } - - /** - * List of properties from all local notifications from given type. - * - * @param type - * The notification life cycle type - */ - public List<JSONObject> getOptionsByType(Notification.Type type) { - ArrayList<JSONObject> options = new ArrayList<JSONObject>(); - List<Notification> notifications = getByType(type); - - for (Notification notification : notifications) { - options.add(notification.getOptions().getDict()); - } - - return options; - } - - /** - * List of properties from local notifications with matching ID from - * given type. - * - * @param type - * The notification life cycle type - * @param ids - * Set of notification IDs - */ - public List<JSONObject> getOptionsBy(Notification.Type type, - List<Integer> ids) { - - if (type == Notification.Type.ALL) - return getOptionsById(ids); - - ArrayList<JSONObject> options = new ArrayList<JSONObject>(); - List<Notification> notifications = getByIds(ids); - - for (Notification notification : notifications) { - if (notification.getType() == type) { - options.add(notification.getOptions().getDict()); - } - } - - return options; - } - - /** - * Get existent local notification. - * - * @param id - * Notification ID - */ - public Notification get(int id) { - Map<String, ?> alarms = getPrefs().getAll(); - String notId = Integer.toString(id); - JSONObject options; - - if (!alarms.containsKey(notId)) - return null; - - - try { - String json = alarms.get(notId).toString(); - options = new JSONObject(json); - } catch (JSONException e) { - e.printStackTrace(); - return null; - } - - Builder builder = new Builder(context, options); - - return builder.build(); - } - - /** - * Merge two JSON objects. - * - * @param obj1 - * JSON object - * @param obj2 - * JSON object with new options - */ - private JSONObject mergeJSONObjects (JSONObject obj1, JSONObject obj2) { - Iterator it = obj2.keys(); - - while (it.hasNext()) { - try { - String key = (String)it.next(); - - obj1.put(key, obj2.opt(key)); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - return obj1; - } - - /** - * Shared private preferences for the application. - */ - private SharedPreferences getPrefs () { - return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); - } - - /** - * Notification manager for the application. - */ - private NotificationManager getNotMgr () { - return (NotificationManager) context - .getSystemService(Context.NOTIFICATION_SERVICE); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Notification.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Notification.java deleted file mode 100644 index 5dba9d54..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Notification.java +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - - -import android.app.AlarmManager; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.support.v4.app.NotificationCompat; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Date; - -/** - * Wrapper class around OS notification class. Handles basic operations - * like show, delete, cancel for a single local notification instance. - */ -public class Notification { - - // Used to differ notifications by their life cycle state - public enum Type { - ALL, SCHEDULED, TRIGGERED - } - - // Default receiver to handle the trigger event - private static Class<?> defaultReceiver = TriggerReceiver.class; - - // Key for private preferences - static final String PREF_KEY = "LocalNotification"; - - // Application context passed by constructor - private final Context context; - - // Notification options passed by JS - private final Options options; - - // Builder with full configuration - private final NotificationCompat.Builder builder; - - // Receiver to handle the trigger event - private Class<?> receiver = defaultReceiver; - - /** - * Constructor - * - * @param context - * Application context - * @param options - * Parsed notification options - * @param builder - * Pre-configured notification builder - */ - protected Notification (Context context, Options options, - NotificationCompat.Builder builder, Class<?> receiver) { - - this.context = context; - this.options = options; - this.builder = builder; - - this.receiver = receiver != null ? receiver : defaultReceiver; - } - - /** - * Get application context. - */ - public Context getContext () { - return context; - } - - /** - * Get notification options. - */ - public Options getOptions () { - return options; - } - - /** - * Get notification ID. - */ - public int getId () { - return options.getId(); - } - - /** - * If it's a repeating notification. - */ - public boolean isRepeating () { - return getOptions().getRepeatInterval() > 0; - } - - /** - * If the notification was in the past. - */ - public boolean wasInThePast () { - return new Date().after(options.getTriggerDate()); - } - - /** - * If the notification is scheduled. - */ - public boolean isScheduled () { - return isRepeating() || !wasInThePast(); - } - - /** - * If the notification is triggered. - */ - public boolean isTriggered () { - return wasInThePast(); - } - - /** - * If the notification is an update. - */ - protected boolean isUpdate () { - - if (!options.getDict().has("updatedAt")) - return false; - - long now = new Date().getTime(); - - long updatedAt = options.getDict().optLong("updatedAt", now); - - return (now - updatedAt) < 1000; - } - - /** - * Notification type can be one of pending or scheduled. - */ - public Type getType () { - return isTriggered() ? Type.TRIGGERED : Type.SCHEDULED; - } - - /** - * Schedule the local notification. - */ - public void schedule() { - long triggerTime = options.getTriggerTime(); - - persist(); - - // Intent gets called when the Notification gets fired - Intent intent = new Intent(context, receiver) - .setAction(options.getIdStr()) - .putExtra(Options.EXTRA, options.toString()); - - PendingIntent pi = PendingIntent.getBroadcast( - context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - - if (isRepeating()) { - getAlarmMgr().setRepeating(AlarmManager.RTC_WAKEUP, - triggerTime, options.getRepeatInterval(), pi); - } else { - getAlarmMgr().set(AlarmManager.RTC_WAKEUP, triggerTime, pi); - } - } - - /** - * Clear the local notification without canceling repeating alarms. - * - */ - public void clear () { - if (!isRepeating() && wasInThePast()) { - unpersist(); - } else { - getNotMgr().cancel(getId()); - } - } - - /** - * Cancel the local notification. - * - * Create an intent that looks similar, to the one that was registered - * using schedule. Making sure the notification id in the action is the - * same. Now we can search for such an intent using the 'getService' - * method and cancel it. - */ - public void cancel() { - Intent intent = new Intent(context, receiver) - .setAction(options.getIdStr()); - - PendingIntent pi = PendingIntent. - getBroadcast(context, 0, intent, 0); - - getAlarmMgr().cancel(pi); - getNotMgr().cancel(options.getId()); - - unpersist(); - } - - /** - * Present the local notification to user. - */ - public void show () { - // TODO Show dialog when in foreground - showNotification(); - } - - /** - * Show as local notification when in background. - */ - @SuppressWarnings("deprecation") - private void showNotification () { - int id = getOptions().getId(); - - if (Build.VERSION.SDK_INT <= 15) { - // Notification for HoneyComb to ICS - getNotMgr().notify(id, builder.getNotification()); - } else { - // Notification for Jellybean and above - getNotMgr().notify(id, builder.build()); - } - } - - /** - * Show as modal dialog when in foreground. - */ - private void showDialog () { - // TODO - } - - /** - * Count of triggers since schedule. - */ - public int getTriggerCountSinceSchedule() { - long now = System.currentTimeMillis(); - long triggerTime = options.getTriggerTime(); - - if (!wasInThePast()) - return 0; - - if (!isRepeating()) - return 1; - - return (int) ((now - triggerTime) / options.getRepeatInterval()); - } - - /** - * Encode options to JSON. - */ - public String toString() { - JSONObject dict = options.getDict(); - JSONObject json = new JSONObject(); - - try { - json = new JSONObject(dict.toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - - json.remove("firstAt"); - json.remove("updatedAt"); - json.remove("soundUri"); - json.remove("iconUri"); - - return json.toString(); - } - - /** - * Persist the information of this notification to the Android Shared - * Preferences. This will allow the application to restore the notification - * upon device reboot, app restart, retrieve notifications, aso. - */ - private void persist () { - SharedPreferences.Editor editor = getPrefs().edit(); - - editor.putString(options.getIdStr(), options.toString()); - - if (Build.VERSION.SDK_INT < 9) { - editor.commit(); - } else { - editor.apply(); - } - } - - /** - * Remove the notification from the Android shared Preferences. - */ - private void unpersist () { - SharedPreferences.Editor editor = getPrefs().edit(); - - editor.remove(options.getIdStr()); - - if (Build.VERSION.SDK_INT < 9) { - editor.commit(); - } else { - editor.apply(); - } - } - - /** - * Shared private preferences for the application. - */ - private SharedPreferences getPrefs () { - return context.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE); - } - - /** - * Notification manager for the application. - */ - private NotificationManager getNotMgr () { - return (NotificationManager) context - .getSystemService(Context.NOTIFICATION_SERVICE); - } - - /** - * Alarm manager for the application. - */ - private AlarmManager getAlarmMgr () { - return (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - } - - /** - * Set default receiver to handle the trigger event. - * - * @param receiver - * broadcast receiver - */ - public static void setDefaultTriggerReceiver (Class<?> receiver) { - defaultReceiver = receiver; - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Options.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Options.java deleted file mode 100644 index 198a52f4..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/Options.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -import android.app.AlarmManager; -import android.content.Context; -import android.graphics.Bitmap; -import android.net.Uri; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Date; - -/** - * Wrapper around the JSON object passed through JS which contains all - * possible option values. Class provides simple readers and more advanced - * methods to convert independent values into platform specific values. - */ -public class Options { - - // Key name for bundled extras - static final String EXTRA = "NOTIFICATION_OPTIONS"; - - // The original JSON object - private JSONObject options = new JSONObject(); - - // Repeat interval - private long interval = 0; - - // Application context - private final Context context; - - // Asset util instance - private final AssetUtil assets; - - - /** - * Constructor - * - * @param context - * Application context - */ - public Options(Context context){ - this.context = context; - this.assets = AssetUtil.getInstance(context); - } - - /** - * Parse given JSON properties. - * - * @param options - * JSON properties - */ - public Options parse (JSONObject options) { - this.options = options; - - parseInterval(); - parseAssets(); - - return this; - } - - /** - * Parse repeat interval. - */ - private void parseInterval() { - String every = options.optString("every").toLowerCase(); - - if (every.isEmpty()) { - interval = 0; - } else - if (every.equals("second")) { - interval = 1000; - } else - if (every.equals("minute")) { - interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES / 15; - } else - if (every.equals("hour")) { - interval = AlarmManager.INTERVAL_HOUR; - } else - if (every.equals("day")) { - interval = AlarmManager.INTERVAL_DAY; - } else - if (every.equals("week")) { - interval = AlarmManager.INTERVAL_DAY * 7; - } else - if (every.equals("month")) { - interval = AlarmManager.INTERVAL_DAY * 31; - } else - if (every.equals("year")) { - interval = AlarmManager.INTERVAL_DAY * 365; - } else { - try { - interval = Integer.parseInt(every) * 60000; - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - /** - * Parse asset URIs. - */ - private void parseAssets() { - - if (options.has("iconUri")) - return; - - Uri iconUri = assets.parse(options.optString("icon", "icon")); - Uri soundUri = assets.parseSound(options.optString("sound", null)); - - try { - options.put("iconUri", iconUri.toString()); - options.put("soundUri", soundUri.toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - /** - * Application context. - */ - public Context getContext () { - return context; - } - - /** - * Wrapped JSON object. - */ - JSONObject getDict () { - return options; - } - - /** - * Text for the local notification. - */ - public String getText() { - return options.optString("text", ""); - } - - /** - * Repeat interval (day, week, month, year, aso.) - */ - public long getRepeatInterval() { - return interval; - } - - /** - * Badge number for the local notification. - */ - public int getBadgeNumber() { - return options.optInt("badge", 0); - } - - /** - * ongoing flag for local notifications. - */ - public Boolean isOngoing() { - return options.optBoolean("ongoing", false); - } - - /** - * autoClear flag for local notifications. - */ - public Boolean isAutoClear() { - return options.optBoolean("autoClear", false); - } - - /** - * ID for the local notification as a number. - */ - public Integer getId() { - return options.optInt("id", 0); - } - - /** - * ID for the local notification as a string. - */ - public String getIdStr() { - return getId().toString(); - } - - /** - * Trigger date. - */ - public Date getTriggerDate() { - return new Date(getTriggerTime()); - } - - /** - * Trigger date in milliseconds. - */ - public long getTriggerTime() { - return Math.max( - System.currentTimeMillis(), - options.optLong("at", 0) * 1000 - ); - } - - /** - * Title for the local notification. - */ - public String getTitle() { - String title = options.optString("title", ""); - - if (title.isEmpty()) { - title = context.getApplicationInfo().loadLabel( - context.getPackageManager()).toString(); - } - - return title; - } - - /** - * @return - * The notification color for LED - */ - public int getLedColor() { - String hex = options.optString("led", "000000"); - int aRGB = Integer.parseInt(hex,16); - - aRGB += 0xFF000000; - - return aRGB; - } - - /** - * Sound file path for the local notification. - */ - public Uri getSoundUri() { - Uri uri = null; - - try{ - uri = Uri.parse(options.optString("soundUri")); - } catch (Exception e){ - e.printStackTrace(); - } - - return uri; - } - - /** - * Icon bitmap for the local notification. - */ - public Bitmap getIconBitmap() { - String icon = options.optString("icon", "icon"); - Bitmap bmp; - - try{ - Uri uri = Uri.parse(options.optString("iconUri")); - bmp = assets.getIconFromUri(uri); - } catch (Exception e){ - bmp = assets.getIconFromDrawable(icon); - } - - return bmp; - } - - /** - * Small icon resource ID for the local notification. - */ - public int getSmallIcon () { - String icon = options.optString("smallIcon", ""); - - int resId = assets.getResIdForDrawable(icon); - - if (resId == 0) { - resId = android.R.drawable.screen_background_dark; - } - - return resId; - } - - /** - * JSON object as string. - */ - public String toString() { - return options.toString(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/TriggerReceiver.java b/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/TriggerReceiver.java deleted file mode 100644 index 9427e31e..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/android/notification/TriggerReceiver.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -package de.appplant.cordova.plugin.notification; - -/** - * The alarm receiver is triggered when a scheduled alarm is fired. This class - * reads the information in the intent and displays this information in the - * Android notification bar. The notification uses the default notification - * sound and it vibrates the phone. - */ -public class TriggerReceiver extends AbstractTriggerReceiver { - - /** - * Called when a local notification was triggered. Does present the local - * notification and re-schedule the alarm if necessary. - * - * @param notification - * Wrapper around the local notification - * @param updated - * If an update has triggered or the original - */ - @Override - public void onTrigger (Notification notification, boolean updated) { - notification.show(); - } - - /** - * Build notification specified by options. - * - * @param builder - * Notification builder - */ - @Override - public Notification buildNotification (Builder builder) { - return builder.build(); - } - -} diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.h deleted file mode 100644 index f86bf498..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import <Foundation/Foundation.h> -#import <Cordova/CDVPlugin.h> - -@interface APPLocalNotification : CDVPlugin - -// Execute all queued events -- (void) deviceready:(CDVInvokedUrlCommand*)command; - -// Inform if the app has the permission to show notifications -- (void) hasPermission:(CDVInvokedUrlCommand*)command; -// Register permission to show notifications -- (void) registerPermission:(CDVInvokedUrlCommand*)command; - -// Schedule set of notifications -- (void) schedule:(CDVInvokedUrlCommand*)command; -// Update set of notifications -- (void) update:(CDVInvokedUrlCommand*)command; -// Cancel set of notifications -- (void) cancel:(CDVInvokedUrlCommand*)command; -// Cancel all notifications -- (void) cancelAll:(CDVInvokedUrlCommand*)command; -// Clear set of notifications -- (void) clear:(CDVInvokedUrlCommand*)command; -// Clear all notifications -- (void) clearAll:(CDVInvokedUrlCommand*)command; - -// If a notification with an ID is present -- (void) isPresent:(CDVInvokedUrlCommand*)command; -// If a notification with an ID is scheduled -- (void) isScheduled:(CDVInvokedUrlCommand*)command; -// If a notification with an ID is triggered -- (void) isTriggered:(CDVInvokedUrlCommand*)command; - -// List all ids from all local notifications -- (void) getAllIds:(CDVInvokedUrlCommand*)command; -// List all ids from all pending notifications -- (void) getScheduledIds:(CDVInvokedUrlCommand*)command; -// List all ids from all triggered notifications -- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command; - -// Propertys for given local notification -- (void) getSingle:(CDVInvokedUrlCommand*)command; -// Propertya for given scheduled notification -- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command; -// Propertys for given triggered notification -- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command; - -// Property list for given local notifications -- (void) getAll:(CDVInvokedUrlCommand*)command; -// Property list for given scheduled notifications -- (void) getScheduled:(CDVInvokedUrlCommand*)command; -// Property list for given triggered notifications -- (void) getTriggered:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.m deleted file mode 100644 index 43cf9f8c..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotification.m +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "APPLocalNotification.h" -#import "APPLocalNotificationOptions.h" -#import "UIApplication+APPLocalNotification.h" -#import "UILocalNotification+APPLocalNotification.h" -#import "AppDelegate+APPRegisterUserNotificationSettings.h" - -@interface APPLocalNotification () - -// Retrieves the application state -@property (readonly, getter=applicationState) NSString* applicationState; -// All events will be queued until deviceready has been fired -@property (readwrite, assign) BOOL deviceready; -// Event queue -@property (readonly, nonatomic, retain) NSMutableArray* eventQueue; -// Needed when calling `registerPermission` -@property (nonatomic, retain) CDVInvokedUrlCommand* command; - -@end - -@implementation APPLocalNotification - -@synthesize deviceready, eventQueue; - -#pragma mark - -#pragma mark Interface - -/** - * Execute all queued events. - */ -- (void) deviceready:(CDVInvokedUrlCommand*)command -{ - deviceready = YES; - - for (NSString* js in eventQueue) { - [self.commandDelegate evalJs:js]; - } - - [eventQueue removeAllObjects]; -} - -/** - * Schedule a set of notifications. - * - * @param properties - * A dict of properties for each notification - */ -- (void) schedule:(CDVInvokedUrlCommand*)command -{ - NSArray* notifications = command.arguments; - - [self.commandDelegate runInBackground:^{ - for (NSDictionary* options in notifications) { - UILocalNotification* notification; - - notification = [[UILocalNotification alloc] - initWithOptions:options]; - - [self scheduleLocalNotification:[notification copy]]; - [self fireEvent:@"schedule" notification:notification]; - - if (notifications.count > 1) { - [NSThread sleepForTimeInterval:0.01]; - } - } - - [self execCallback:command]; - }]; -} - -/** - * Update a set of notifications. - * - * @param properties - * A dict of properties for each notification - */ -- (void) update:(CDVInvokedUrlCommand*)command -{ - NSArray* notifications = command.arguments; - - [self.commandDelegate runInBackground:^{ - for (NSDictionary* options in notifications) { - NSNumber* id = [options objectForKey:@"id"]; - UILocalNotification* notification; - - notification = [self.app localNotificationWithId:id]; - - if (!notification) - continue; - - [self updateLocalNotification:[notification copy] - withOptions:options]; - - [self fireEvent:@"update" notification:notification]; - - if (notifications.count > 1) { - [NSThread sleepForTimeInterval:0.01]; - } - } - - [self execCallback:command]; - }]; -} - -/** - * Cancel a set of notifications. - * - * @param ids - * The IDs of the notifications - */ -- (void) cancel:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - for (NSNumber* id in command.arguments) { - UILocalNotification* notification; - - notification = [self.app localNotificationWithId:id]; - - if (!notification) - continue; - - [self.app cancelLocalNotification:notification]; - [self fireEvent:@"cancel" notification:notification]; - } - - [self execCallback:command]; - }]; -} - -/** - * Cancel all local notifications. - */ -- (void) cancelAll:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - [self cancelAllLocalNotifications]; - [self fireEvent:@"cancelall"]; - [self execCallback:command]; - }]; -} - -/** - * Clear a set of notifications. - * - * @param ids - * The IDs of the notifications - */ -- (void) clear:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - for (NSNumber* id in command.arguments) { - UILocalNotification* notification; - - notification = [self.app localNotificationWithId:id]; - - if (!notification) - continue; - - [self.app clearLocalNotification:notification]; - [self fireEvent:@"clear" notification:notification]; - } - - [self execCallback:command]; - }]; -} - -/** - * Clear all local notifications. - */ -- (void) clearAll:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - [self clearAllLocalNotifications]; - [self fireEvent:@"clearall"]; - [self execCallback:command]; - }]; -} - -/** - * If a notification by ID is present. - * - * @param id - * The ID of the notification - */ -- (void) isPresent:(CDVInvokedUrlCommand *)command -{ - [self isPresent:command type:NotifcationTypeAll]; -} - -/** - * If a notification by ID is scheduled. - * - * @param id - * The ID of the notification - */ -- (void) isScheduled:(CDVInvokedUrlCommand*)command -{ - [self isPresent:command type:NotifcationTypeScheduled]; -} - -/** - * Check if a notification with an ID is triggered. - * - * @param id - * The ID of the notification - */ -- (void) isTriggered:(CDVInvokedUrlCommand*)command -{ - [self isPresent:command type:NotifcationTypeTriggered]; -} - -/** - * Check if a notification with an ID exists. - * - * @param type - * The notification life cycle type - */ -- (void) isPresent:(CDVInvokedUrlCommand*)command - type:(APPLocalNotificationType)type; -{ - [self.commandDelegate runInBackground:^{ - NSNumber* id = [command argumentAtIndex:0]; - BOOL exist; - - CDVPluginResult* result; - - if (type == NotifcationTypeAll) { - exist = [self.app localNotificationExist:id]; - } else { - exist = [self.app localNotificationExist:id type:type]; - } - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsBool:exist]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; - }]; -} - -/** - * List all ids from all local notifications. - */ -- (void) getAllIds:(CDVInvokedUrlCommand*)command -{ - [self getIds:command byType:NotifcationTypeAll]; -} - -/** - * List all ids from all pending notifications. - */ -- (void) getScheduledIds:(CDVInvokedUrlCommand*)command -{ - [self getIds:command byType:NotifcationTypeScheduled]; -} - -/** - * List all ids from all triggered notifications. - */ -- (void) getTriggeredIds:(CDVInvokedUrlCommand*)command -{ - [self getIds:command byType:NotifcationTypeTriggered]; -} - -/** - * List of ids for given local notifications. - * - * @param type - * Notification life cycle type - * @param ids - * The IDs of the notifications - */ -- (void) getIds:(CDVInvokedUrlCommand*)command - byType:(APPLocalNotificationType)type; -{ - [self.commandDelegate runInBackground:^{ - CDVPluginResult* result; - NSArray* ids; - - if (type == NotifcationTypeAll) { - ids = [self.app localNotificationIds]; - } else { - ids = [self.app localNotificationIdsByType:type]; - } - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsArray:ids]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; - }]; -} - -/** - * Propertys for given local notification. - */ -- (void) getSingle:(CDVInvokedUrlCommand*)command -{ - [self getOption:command byType:NotifcationTypeAll]; -} - -/** - * Propertya for given scheduled notification. - */ -- (void) getSingleScheduled:(CDVInvokedUrlCommand*)command -{ - [self getOption:command byType:NotifcationTypeScheduled]; -} - -// Propertys for given triggered notification -- (void) getSingleTriggered:(CDVInvokedUrlCommand*)command -{ - [self getOption:command byType:NotifcationTypeTriggered]; -} - -/** - * Property list for given local notifications. - * - * @param ids - * The IDs of the notifications - */ -- (void) getAll:(CDVInvokedUrlCommand*)command -{ - [self getOptions:command byType:NotifcationTypeAll]; -} - -/** - * Property list for given scheduled notifications. - * - * @param ids - * The IDs of the notifications - */ -- (void) getScheduled:(CDVInvokedUrlCommand*)command -{ - [self getOptions:command byType:NotifcationTypeScheduled]; -} - -/** - * Property list for given triggered notifications. - * - * @param ids - * The IDs of the notifications - */ -- (void) getTriggered:(CDVInvokedUrlCommand *)command -{ - [self getOptions:command byType:NotifcationTypeTriggered]; -} - -/** - * Propertys for given triggered notification. - * - * @param type - * Notification life cycle type - * @param ids - * The ID of the notification - */ -- (void) getOption:(CDVInvokedUrlCommand*)command - byType:(APPLocalNotificationType)type; -{ - [self.commandDelegate runInBackground:^{ - NSArray* ids = command.arguments; - NSArray* notifications; - CDVPluginResult* result; - - if (type == NotifcationTypeAll) { - notifications = [self.app localNotificationOptionsById:ids]; - } - else { - notifications = [self.app localNotificationOptionsByType:type - andId:ids]; - } - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDictionary:notifications[0]]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; - }]; -} - -/** - * Property list for given triggered notifications. - * - * @param type - * Notification life cycle type - * @param ids - * The IDs of the notifications - */ -- (void) getOptions:(CDVInvokedUrlCommand*)command - byType:(APPLocalNotificationType)type; -{ - [self.commandDelegate runInBackground:^{ - NSArray* ids = command.arguments; - NSArray* notifications; - CDVPluginResult* result; - - if (type == NotifcationTypeAll && ids.count == 0) { - notifications = [self.app localNotificationOptions]; - } - else if (type == NotifcationTypeAll) { - notifications = [self.app localNotificationOptionsById:ids]; - } - else if (ids.count == 0) { - notifications = [self.app localNotificationOptionsByType:type]; - } - else { - notifications = [self.app localNotificationOptionsByType:type - andId:ids]; - } - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsArray:notifications]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; - }]; -} - -/** - * Inform if the app has the permission to show - * badges and local notifications. - */ -- (void) hasPermission:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - CDVPluginResult* result; - BOOL hasPermission; - - hasPermission = [self.app hasPermissionToScheduleLocalNotifications]; - - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsBool:hasPermission]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; - }]; -} - -/** - * Ask for permission to show badges. - */ -- (void) registerPermission:(CDVInvokedUrlCommand*)command -{ - if ([[UIApplication sharedApplication] - respondsToSelector:@selector(registerUserNotificationSettings:)]) - { - _command = command; - - [self.commandDelegate runInBackground:^{ - [self.app registerPermissionToScheduleLocalNotifications]; - }]; - } else { - [self hasPermission:command]; - } -} - -#pragma mark - -#pragma mark Core Logic - -/** - * Schedule the local notification. - */ -- (void) scheduleLocalNotification:(UILocalNotification*)notification -{ - [self cancelForerunnerLocalNotification:notification]; - [self.app scheduleLocalNotification:notification]; -} - -/** - * Update the local notification. - */ -- (void) updateLocalNotification:(UILocalNotification*)notification - withOptions:(NSDictionary*)newOptions -{ - NSMutableDictionary* options = [notification.userInfo mutableCopy]; - - [options addEntriesFromDictionary:newOptions]; - [options setObject:[NSDate date] forKey:@"updatedAt"]; - - notification = [[UILocalNotification alloc] - initWithOptions:options]; - - [self scheduleLocalNotification:notification]; -} - -/** - * Cancel all local notifications. - */ -- (void) cancelAllLocalNotifications -{ - [self.app cancelAllLocalNotifications]; - [self.app setApplicationIconBadgeNumber:0]; -} - -/** - * Clear all local notifications. - */ -- (void) clearAllLocalNotifications -{ - [self.app clearAllLocalNotifications]; - [self.app setApplicationIconBadgeNumber:0]; -} - -/** - * Cancel a maybe given forerunner with the same ID. - */ -- (void) cancelForerunnerLocalNotification:(UILocalNotification*)notification -{ - NSNumber* id = notification.options.id; - UILocalNotification* forerunner; - - forerunner = [self.app localNotificationWithId:id]; - - if (!forerunner) - return; - - [self.app cancelLocalNotification:forerunner]; -} - -/** - * Cancels all non-repeating local notification older then - * a specific amount of seconds - */ -- (void) cancelAllNotificationsWhichAreOlderThen:(float)seconds -{ - NSArray* notifications; - - notifications = [self.app localNotifications]; - - for (UILocalNotification* notification in notifications) - { - if (![notification isRepeating] - && notification.timeIntervalSinceFireDate > seconds) - { - [self.app cancelLocalNotification:notification]; - [self fireEvent:@"cancel" notification:notification]; - } - } -} - -#pragma mark - -#pragma mark Delegates - -/** - * Calls the cancel or trigger event after a local notification was received. - * Cancels the local notification if autoCancel was set to true. - */ -- (void) didReceiveLocalNotification:(NSNotification*)localNotification -{ - UILocalNotification* notification = [localNotification object]; - - if ([notification wasUpdated]) - return; - - NSTimeInterval timeInterval = [notification timeIntervalSinceLastTrigger]; - - NSString* event = (timeInterval <= 1 && deviceready) ? @"trigger" : @"click"; - - [self fireEvent:event notification:notification]; - - if (![event isEqualToString:@"click"]) - return; - - if ([notification isRepeating]) { - [self fireEvent:@"clear" notification:notification]; - } else { - [self.app cancelLocalNotification:notification]; - [self fireEvent:@"cancel" notification:notification]; - } -} - -/** - * Called when app has started - * (by clicking on a local notification). - */ -- (void) didFinishLaunchingWithOptions:(NSNotification*)notification -{ - NSDictionary* launchOptions = [notification userInfo]; - - UILocalNotification* localNotification; - - localNotification = [launchOptions objectForKey: - UIApplicationLaunchOptionsLocalNotificationKey]; - - if (localNotification) { - [self didReceiveLocalNotification: - [NSNotification notificationWithName:CDVLocalNotification - object:localNotification]]; - } -} - -/** - * Called on otification settings registration is completed. - */ -- (void) didRegisterUserNotificationSettings:(UIUserNotificationSettings*)settings -{ - if (_command) - { - [self hasPermission:_command]; - _command = NULL; - } -} - -#pragma mark - -#pragma mark Life Cycle - -/** - * Registers obervers after plugin was initialized. - */ -- (void) pluginInitialize -{ - NSNotificationCenter* center = [NSNotificationCenter - defaultCenter]; - - eventQueue = [[NSMutableArray alloc] init]; - - [center addObserver:self - selector:@selector(didReceiveLocalNotification:) - name:CDVLocalNotification - object:nil]; - - [center addObserver:self - selector:@selector(didFinishLaunchingWithOptions:) - name:UIApplicationDidFinishLaunchingNotification - object:nil]; - - [center addObserver:self - selector:@selector(didRegisterUserNotificationSettings:) - name:UIApplicationRegisterUserNotificationSettings - object:nil]; -} - -/** - * Clears all single repeating notifications which are older then 5 days - * before the app terminates. - */ -- (void) onAppTerminate -{ - [self cancelAllNotificationsWhichAreOlderThen:432000]; -} - -#pragma mark - -#pragma mark Helper - -/** - * Retrieves the application state - * - * @return - * Either "background" or "foreground" - */ -- (NSString*) applicationState -{ - UIApplicationState state = [self.app applicationState]; - - bool isActive = state == UIApplicationStateActive; - - return isActive ? @"foreground" : @"background"; -} - -/** - * Simply invokes the callback without any parameter. - */ -- (void) execCallback:(CDVInvokedUrlCommand*)command -{ - CDVPluginResult *result = [CDVPluginResult - resultWithStatus:CDVCommandStatus_OK]; - - [self.commandDelegate sendPluginResult:result - callbackId:command.callbackId]; -} - -/** - * Short hand for shared application instance. - */ -- (UIApplication*) app -{ - return [UIApplication sharedApplication]; -} - -/** - * Fire general event. - */ -- (void) fireEvent:(NSString*)event -{ - [self fireEvent:event notification:NULL]; -} - -/** - * Fire event for local notification. - */ -- (void) fireEvent:(NSString*)event notification:(UILocalNotification*)notification -{ - NSString* js; - NSString* params = [NSString stringWithFormat: - @"\"%@\"", self.applicationState]; - - if (notification) { - NSString* args = [notification encodeToJSON]; - - params = [NSString stringWithFormat: - @"%@,'%@'", - args, self.applicationState]; - } - - js = [NSString stringWithFormat: - @"cordova.plugins.notification.local.core.fireEvent('%@', %@)", - event, params]; - - if (deviceready) { - [self.commandDelegate evalJs:js]; - } else { - [self.eventQueue addObject:js]; - } -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.h deleted file mode 100644 index 73c3ef75..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -@interface APPLocalNotificationOptions : NSObject - -- (id) initWithDict:(NSDictionary*)dict; - -@property (readonly, getter=id) NSNumber* id; -@property (readonly, getter=badgeNumber) NSInteger badgeNumber; -@property (readonly, getter=alertBody) NSString* alertBody; -@property (readonly, getter=soundName) NSString* soundName; -@property (readonly, getter=fireDate) NSDate* fireDate; -@property (readonly, getter=repeatInterval) NSCalendarUnit repeatInterval; -@property (readonly, getter=userInfo) NSDictionary* userInfo; - -// If it's a repeating notification -- (BOOL) isRepeating; - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.m deleted file mode 100644 index ac90f993..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/APPLocalNotificationOptions.m +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "APPLocalNotificationOptions.h" - -// Default sound ressource path -NSString* const DEFAULT_SOUND = @"res://platform_default"; - -@interface APPLocalNotificationOptions () - -// The dictionary which contains all notification properties -@property(nonatomic, retain) NSDictionary* dict; - -@end - -@implementation APPLocalNotificationOptions - -@synthesize dict; - -#pragma mark - -#pragma mark Initialization - -/** - * Initialize the object with the given options when calling on JS side: - * notification.local.add(options) - */ -- (id) initWithDict:(NSDictionary*)dictionary -{ - self = [self init]; - - self.dict = dictionary; - - return self; -} - -#pragma mark - -#pragma mark Attributes - -/** - * The notification's ID. - */ -- (NSNumber*) id -{ - NSInteger id = [[dict objectForKey:@"id"] integerValue]; - - return [NSNumber numberWithInteger:id]; -} - -/** - * The notification's title. - */ -- (NSString*) title -{ - return [dict objectForKey:@"title"]; -} - -/** - * The notification's message. - */ -- (NSString*) text -{ - return [dict objectForKey:@"text"]; -} - -/** - * The notification's badge number. - */ -- (NSInteger) badgeNumber -{ - return [[dict objectForKey:@"badge"] intValue]; -} - -#pragma mark - -#pragma mark Complex Attributes - -/** - * The notification's alert body. - */ -- (NSString*) alertBody -{ - NSString* title = [self title]; - NSString* msg = [self text]; - - NSString* alertBody = msg; - - if (![self stringIsNullOrEmpty:title]) - { - alertBody = [NSString stringWithFormat:@"%@\n%@", - title, msg]; - } - - return alertBody; -} - -/** - * The notification's sound path. - */ -- (NSString*) soundName -{ - NSString* path = [dict objectForKey:@"sound"]; - - if ([self stringIsNullOrEmpty:path]) - return NULL; - - if ([path isEqualToString:DEFAULT_SOUND]) - return UILocalNotificationDefaultSoundName; - - if ([path hasPrefix:@"file:/"]) - return [self soundNameForAsset:path]; - - if ([path hasPrefix:@"res:"]) - return [self soundNameForResource:path]; - - return NULL; -} - -/** - * The notification's fire date. - */ -- (NSDate*) fireDate -{ - double timestamp = [[dict objectForKey:@"at"] - doubleValue]; - - return [NSDate dateWithTimeIntervalSince1970:timestamp]; -} - -/** - * The notification's repeat interval. - */ -- (NSCalendarUnit) repeatInterval -{ - NSString* interval = [dict objectForKey:@"every"]; - - if ([self stringIsNullOrEmpty:interval]) { - return NSCalendarUnitEra; - } - else if ([interval isEqualToString:@"second"]) { - return NSCalendarUnitSecond; - } - else if ([interval isEqualToString:@"minute"]) { - return NSCalendarUnitMinute; - } - else if ([interval isEqualToString:@"hour"]) { - return NSCalendarUnitHour; - } - else if ([interval isEqualToString:@"day"]) { - return NSCalendarUnitDay; - } - else if ([interval isEqualToString:@"week"]) { - return NSCalendarUnitWeekOfYear; - } - else if ([interval isEqualToString:@"month"]) { - return NSCalendarUnitMonth; - } - else if ([interval isEqualToString:@"year"]) { - return NSCalendarUnitYear; - } - - return NSCalendarUnitEra; -} - -#pragma mark - -#pragma mark Methods - -/** - * The notification's user info dict. - */ -- (NSDictionary*) userInfo -{ - if ([dict objectForKey:@"updatedAt"]) { - NSMutableDictionary* data = [dict mutableCopy]; - - [data removeObjectForKey:@"updatedAt"]; - - return data; - } - - return dict; -} - -/** - * If it's a repeating notification. - */ -- (BOOL) isRepeating -{ - NSCalendarUnit interval = self.repeatInterval; - - return !(interval == NSCalendarUnitEra || interval == 0); -} - -#pragma mark - -#pragma mark Helpers - -/** - * Convert relative path to valid sound name attribute. - */ -- (NSString*) soundNameForAsset:(NSString*)path -{ - return [path stringByReplacingOccurrencesOfString:@"file:/" - withString:@"www"]; -} - -/** - * Convert resource path to valid sound name attribute. - */ -- (NSString*) soundNameForResource:(NSString*)path -{ - return [path pathComponents].lastObject; -} - -/** - * If the string is empty. - */ -- (BOOL) stringIsNullOrEmpty:(NSString*)str -{ - if (str == (NSString*)[NSNull null]) - return YES; - - if ([str isEqualToString:@""]) - return YES; - - return NO; -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.h deleted file mode 100644 index a18568e5..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "UILocalNotification+APPLocalNotification.h" - -@interface UIApplication (APPLocalNotification) - -@property (readonly, getter=localNotifications) NSArray* localNotifications; -@property (readonly, getter=localNotificationIds) NSArray* localNotificationIds; - -// If the app has the permission to schedule local notifications -- (BOOL) hasPermissionToScheduleLocalNotifications; -// Ask for permission to schedule local notifications -- (void) registerPermissionToScheduleLocalNotifications; - -// List of all local notification IDs from given type -- (NSArray*) localNotificationIdsByType:(APPLocalNotificationType)type; - -// If local notification with ID exists -- (BOOL) localNotificationExist:(NSNumber*)id; -// If local notification with ID and type exists -- (BOOL) localNotificationExist:(NSNumber*)id type:(APPLocalNotificationType)type; - -// Local notification by ID -- (UILocalNotification*) localNotificationWithId:(NSNumber*)id; -// Local notification by ID and type -- (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPLocalNotificationType)type; - -// Property list from all local notifications -- (NSArray*) localNotificationOptions; -// Property list from given local notifications -- (NSArray*) localNotificationOptionsById:(NSArray*)ids; -// Property list from all local notifications with type constraint -- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type; -// Property list from given local notifications with type constraint -- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type andId:(NSArray*)ids; - -// Clear single local notfications -- (void) clearLocalNotification:(UILocalNotification*)notification; -// Clear all local notfications -- (void) clearAllLocalNotifications; - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.m deleted file mode 100644 index 60b6daac..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UIApplication+APPLocalNotification.m +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "UIApplication+APPLocalNotification.h" -#import "UILocalNotification+APPLocalNotification.h" - -@implementation UIApplication (APPLocalNotification) - -#pragma mark - -#pragma mark Permissions - -/** - * If the app has the permission to schedule local notifications. - */ -- (BOOL) hasPermissionToScheduleLocalNotifications -{ - if ([[UIApplication sharedApplication] - respondsToSelector:@selector(registerUserNotificationSettings:)]) - { - UIUserNotificationType types; - UIUserNotificationSettings *settings; - - settings = [[UIApplication sharedApplication] - currentUserNotificationSettings]; - - types = UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; - - return (settings.types & types); - } else { - return YES; - } -} - -/** - * Ask for permission to schedule local notifications. - */ -- (void) registerPermissionToScheduleLocalNotifications -{ - if ([[UIApplication sharedApplication] - respondsToSelector:@selector(registerUserNotificationSettings:)]) - { - UIUserNotificationType types; - UIUserNotificationSettings *settings; - - settings = [[UIApplication sharedApplication] - currentUserNotificationSettings]; - - types = settings.types|UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound; - - settings = [UIUserNotificationSettings settingsForTypes:types - categories:nil]; - - [[UIApplication sharedApplication] - registerUserNotificationSettings:settings]; - } -} - -#pragma mark - -#pragma mark LocalNotifications - -/** - * List of all local notifications which have been added - * but not yet removed from the notification center. - */ -- (NSArray*) localNotifications -{ - NSArray* scheduledNotifications = self.scheduledLocalNotifications; - NSMutableArray* notifications = [[NSMutableArray alloc] init]; - - for (UILocalNotification* notification in scheduledNotifications) - { - if (notification) { - [notifications addObject:notification]; - } - } - - return notifications; -} - -/** - * List of all triggered local notifications which have been scheduled - * and not yet removed the notification center. - */ -- (NSArray*) triggeredLocalNotifications -{ - NSArray* notifications = self.localNotifications; - NSMutableArray* triggeredNotifications = [[NSMutableArray alloc] init]; - - for (UILocalNotification* notification in notifications) - { - if ([notification isTriggered]) { - [triggeredNotifications addObject:notification]; - } - } - - return triggeredNotifications; -} - -/** - * List of all local notifications IDs. - */ -- (NSArray*) localNotificationIds -{ - NSArray* notifications = self.localNotifications; - NSMutableArray* ids = [[NSMutableArray alloc] init]; - - for (UILocalNotification* notification in notifications) - { - [ids addObject:notification.options.id]; - } - - return ids; -} - -/** - * List of all local notifications IDs from given type. - * - * @param type - * Notification life cycle type - */ -- (NSArray*) localNotificationIdsByType:(APPLocalNotificationType)type -{ - NSArray* notifications = self.localNotifications; - NSMutableArray* ids = [[NSMutableArray alloc] init]; - - for (UILocalNotification* notification in notifications) - { - if (notification.type == type) { - [ids addObject:notification.options.id]; - } - } - - return ids; -} - -/* - * If local notification with ID exists. - * - * @param id - * Notification ID - */ -- (BOOL) localNotificationExist:(NSNumber*)id -{ - return [self localNotificationWithId:id] != NULL; -} - -/* If local notification with ID and type exists - * - * @param id - * Notification ID - * @param type - * Notification life cycle type - */ -- (BOOL) localNotificationExist:(NSNumber*)id type:(APPLocalNotificationType)type -{ - return [self localNotificationWithId:id andType:type] != NULL; -} - -/** - * Get local notification with ID. - * - * @param id - * Notification ID - */ -- (UILocalNotification*) localNotificationWithId:(NSNumber*)id -{ - NSArray* notifications = self.localNotifications; - - for (UILocalNotification* notification in notifications) - { - if ([notification.options.id isEqualToNumber:id]) { - return notification; - } - } - - return NULL; -} - -/* - * Get local notification with ID and type. - * - * @param id - * Notification ID - * @param type - * Notification life cycle type - */ -- (UILocalNotification*) localNotificationWithId:(NSNumber*)id andType:(APPLocalNotificationType)type -{ - UILocalNotification* notification = [self localNotificationWithId:id]; - - if (notification && notification.type == type) - return notification; - - return NULL; -} - -/** - * List of properties from all notifications. - */ -- (NSArray*) localNotificationOptions -{ - NSArray* notifications = self.localNotifications; - NSMutableArray* options = [[NSMutableArray alloc] init]; - - for (UILocalNotification* notification in notifications) - { - [options addObject:notification.options.userInfo]; - } - - return options; -} - -/** - * List of properties from all local notifications from given type. - * - * @param type - * Notification life cycle type - */ -- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type -{ - NSArray* notifications = self.localNotifications; - NSMutableArray* options = [[NSMutableArray alloc] init]; - - for (UILocalNotification* notification in notifications) - { - if (notification.type == type) { - [options addObject:notification.options.userInfo]; - } - } - - return options; -} - -/** - * List of properties from given local notifications. - * - * @param ids - * Notification IDs - */ -- (NSArray*) localNotificationOptionsById:(NSArray*)ids -{ - UILocalNotification* notification; - NSMutableArray* options = [[NSMutableArray alloc] init]; - - for (NSNumber* id in ids) - { - notification = [self localNotificationWithId:id]; - - if (notification) { - [options addObject:notification.options.userInfo]; - } - } - - return options; -} - -/** - * List of properties from given local notifications. - * - * @param type - * Notification life cycle type - * @param ids - * Notification IDs - */ -- (NSArray*) localNotificationOptionsByType:(APPLocalNotificationType)type andId:(NSArray*)ids -{ - UILocalNotification* notification; - NSMutableArray* options = [[NSMutableArray alloc] init]; - - for (NSNumber* id in ids) - { - notification = [self localNotificationWithId:id]; - - if (notification && notification.type == type) { - [options addObject:notification.options.userInfo]; - } - } - - return options; -} - -/* - * Clear all local notfications. - */ -- (void) clearAllLocalNotifications -{ - NSArray* notifications = self.triggeredLocalNotifications; - - for (UILocalNotification* notification in notifications) { - [self clearLocalNotification:notification]; - } -} - -/* - * Clear single local notfication. - * - * @param notification - * The local notification object - */ -- (void) clearLocalNotification:(UILocalNotification*)notification -{ - [self cancelLocalNotification:notification]; - - if ([notification isRepeating]) { - notification.fireDate = notification.options.fireDate; - - [self scheduleLocalNotification:notification]; - }; -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.h b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.h deleted file mode 100644 index ac0fdc20..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "APPLocalNotificationOptions.h" - -typedef NS_ENUM(NSUInteger, APPLocalNotificationType) { - NotifcationTypeAll = 0, - NotifcationTypeScheduled = 1, - NotifcationTypeTriggered = 2 -}; - -@interface UILocalNotification (APPLocalNotification) - -// Initialize a new local notification -- (id) initWithOptions:(NSDictionary*)dict; -// The options provided by the plug-in -- (APPLocalNotificationOptions*) options; -// Timeinterval since last trigger date -- (double) timeIntervalSinceLastTrigger; -// Timeinterval since fire date -- (double) timeIntervalSinceFireDate; -// If the fire date was in the past -- (BOOL) wasInThePast; -// If the notification was already scheduled -- (BOOL) isScheduled; -// If the notification was already triggered -- (BOOL) isTriggered; -// If the notification was updated -- (BOOL) wasUpdated; -// If it's a repeating notification -- (BOOL) isRepeating; -// Notifciation type -- (APPLocalNotificationType) type; -// Encode the user info dict to JSON -- (NSString*) encodeToJSON; - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.m b/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.m deleted file mode 100644 index d225cf52..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/ios/UILocalNotification+APPLocalNotification.m +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -#import "UILocalNotification+APPLocalNotification.h" -#import "APPLocalNotificationOptions.h" -#import <objc/runtime.h> - -static char optionsKey; - -NSInteger const APPLocalNotificationTypeScheduled = 1; -NSInteger const APPLocalNotificationTypeTriggered = 2; - -@implementation UILocalNotification (APPLocalNotification) - -#pragma mark - -#pragma mark Init - -/** - * Initialize a local notification with the given options when calling on JS side: - * notification.local.add(options) - */ -- (id) initWithOptions:(NSDictionary*)dict -{ - self = [self init]; - - [self setUserInfo:dict]; - [self __init]; - - return self; -} - -/** - * Applies the given options when calling on JS side: - * notification.local.add(options) - - */ -- (void) __init -{ - APPLocalNotificationOptions* options = self.options; - - self.fireDate = options.fireDate; - self.timeZone = [NSTimeZone defaultTimeZone]; - self.applicationIconBadgeNumber = options.badgeNumber; - self.repeatInterval = options.repeatInterval; - self.alertBody = options.alertBody; - self.soundName = options.soundName; - - if ([self wasInThePast]) { - self.fireDate = [NSDate date]; - } -} - -#pragma mark - -#pragma mark Methods - -/** - * The options provided by the plug-in. - */ -- (APPLocalNotificationOptions*) options -{ - APPLocalNotificationOptions* options = [self getOptions]; - - if (!options) { - options = [[APPLocalNotificationOptions alloc] - initWithDict:[self userInfo]]; - - [self setOptions:options]; - } - - return options; -} - -/** - * Get associated option object - */ -- (APPLocalNotificationOptions*) getOptions -{ - return objc_getAssociatedObject(self, &optionsKey); -} - -/** - * Set associated option object - */ -- (void) setOptions:(APPLocalNotificationOptions*)options -{ - objc_setAssociatedObject(self, &optionsKey, - options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -/** - * The repeating interval in seconds. - */ -- (int) repeatIntervalInSeconds -{ - switch (self.repeatInterval) { - case NSCalendarUnitMinute: - return 60; - - case NSCalendarUnitHour: - return 60000; - - case NSCalendarUnitDay: - case NSCalendarUnitWeekOfYear: - case NSCalendarUnitMonth: - case NSCalendarUnitYear: - return 86400; - - default: - return 1; - } -} - -/** - * Timeinterval since fire date. - */ -- (double) timeIntervalSinceFireDate -{ - NSDate* now = [NSDate date]; - NSDate* fireDate = self.fireDate; - - int timespan = [now timeIntervalSinceDate:fireDate]; - - return timespan; -} - -/** - * Timeinterval since last trigger date. - */ -- (double) timeIntervalSinceLastTrigger -{ - int timespan = [self timeIntervalSinceFireDate]; - - if ([self isRepeating]) { - timespan = timespan % [self repeatIntervalInSeconds]; - } - - return timespan; -} - -/** - * Encode the user info dict to JSON. - */ -- (NSString*) encodeToJSON -{ - NSString* json; - NSData* data; - NSMutableDictionary* obj = [self.userInfo mutableCopy]; - - [obj removeObjectForKey:@"updatedAt"]; - - data = [NSJSONSerialization dataWithJSONObject:obj - options:NSJSONWritingPrettyPrinted - error:Nil]; - - json = [[NSString alloc] initWithData:data - encoding:NSUTF8StringEncoding]; - - return [json stringByReplacingOccurrencesOfString:@"\n" - withString:@""]; -} - -#pragma mark - -#pragma mark State - -/** - * If the fire date was in the past. - */ -- (BOOL) wasInThePast -{ - return [self timeIntervalSinceLastTrigger] > 0; -} - -// If the notification was already scheduled -- (BOOL) isScheduled -{ - return [self isRepeating] || ![self wasInThePast]; -} - -/** - * If the notification was already triggered. - */ -- (BOOL) isTriggered -{ - NSDate* now = [NSDate date]; - NSDate* fireDate = self.fireDate; - - bool isLaterThanFireDate = !([now compare:fireDate] == NSOrderedAscending); - - return isLaterThanFireDate; -} - -/** - * If the notification was updated. - */ -- (BOOL) wasUpdated -{ - NSDate* now = [NSDate date]; - NSDate* updatedAt = [self.userInfo objectForKey:@"updatedAt"]; - - if (updatedAt == NULL) - return NO; - - int timespan = [now timeIntervalSinceDate:updatedAt]; - - return timespan < 1; -} - -/** - * If it's a repeating notification. - */ -- (BOOL) isRepeating -{ - return [self.options isRepeating]; -} - -/** - * Process state type of the local notification. - */ -- (APPLocalNotificationType) type -{ - return [self isTriggered] ? NotifcationTypeTriggered : NotifcationTypeScheduled; -} - -@end diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js deleted file mode 100644 index f27193e1..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationCore.js +++ /dev/null @@ -1,436 +0,0 @@ -/*
- Copyright 2013-2015 appPlant UG
-
- 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 proxy = require('de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy');
-
-var Notifications = Windows.UI.Notifications;
-
-
-proxy.core = {
-
- /**
- * Executes all queued events.
- */
- deviceready: function () {
- var plugin = cordova.plugins.notification.local,
- events = this.eventQueue;
-
- this.isReady = true;
-
- for (var i = 0; i < events.length; i++) {
- plugin.fireEvent.apply(plugin, events[i]);
- }
-
- this.eventQueue = [];
- },
-
- /**
- * Schedules new local notifications.
- *
- * @param {Object[]} notifications
- * Array of local notifications
- * @param {String} event
- * 'schedule' or 'update'
- */
- schedule: function (notifications) {
- var triggerFn = function (notification) {
- this.updateBadge(notification.badge);
- this.fireEvent('trigger', notification);
- };
-
- for (var i = 0; i < notifications.length; i++) {
- var options = notifications[i],
- notification = this.build(options);
-
- this.cancelLocalNotification(options.id);
- this.scheduleLocalNotification(notification, options);
- this.scheduleBackupNotification(notification, options);
- this.fireEvent('schedule', options);
- this.callOnTrigger(options, triggerFn);
- }
- },
-
- /**
- * Schedules a single local notification.
- *
- * @param {Windows.Data.Xml.Dom.XmlDocument} notification
- * The local notification
- * @param {Object} options
- * Local notification properties
- */
- scheduleLocalNotification: function (notification, options) {
- var interval = this.getRepeatInterval(options.every),
- triggerTime = new Date((options.at * 1000)),
- now = new Date().getTime(),
- toast;
-
- if (triggerTime <= now) {
- triggerTime = new Date(now + 10);
- }
-
- try {
- if (interval !== 0 && interval < 360001 && interval > 59999) {
- toast = new Notifications.ScheduledToastNotification(
- notification, triggerTime, interval, 5);
- } else {
- toast = new Notifications.ScheduledToastNotification(
- notification, triggerTime);
- }
- } catch (e) {
- console.error(e);
- return;
- }
-
- toast.id = options.id;
- toast.tag = 'Toast' + toast.id;
-
- Notifications.ToastNotificationManager
- .createToastNotifier()
- .addToSchedule(toast);
- },
-
- /**
- * Schedules a backup local notification 10 years later.
- *
- * @param {Object} notification
- * The local notification
- */
- scheduleBackupNotification: function (notification, options) {
- var properties = Object.create(options);
-
- properties.id = options.id + '-2';
- properties.at = options.at + 315360000; // 10 years later
-
- this.scheduleLocalNotification(notification, properties);
- },
-
- /**
- * Updates the badge number of the active tile.
- *
- * @param {Number} badge
- * The badge number. Zero will clean the badge.
- */
- updateBadge: function (badge) {
- var notifications = Windows.UI.Notifications,
- type = notifications.BadgeTemplateType.badgeNumber,
- xml = notifications.BadgeUpdateManager.getTemplateContent(type),
- attrs = xml.getElementsByTagName('badge'),
- notification = new notifications.BadgeNotification(xml);
-
- attrs[0].setAttribute('value', badge);
-
- notifications.BadgeUpdateManager.createBadgeUpdaterForApplication()
- .update(notification);
- },
-
- /**
- * Updates existing notifications specified by IDs in options.
- *
- * @param {Object[]} notifications
- * Array of local notifications
- */
- update: function (notifications) {
- for (var i = 0; i < notifications.length; i++) {
- var updates = notifications[i],
- options = getAll(updates.id || '0')[0];
-
- this.updateLocalNotification(options, updates);
- this.fireEvent('update', options);
- }
- },
-
- /**
- * Updates a single local notification.
- *
- * @param {Object} notification
- * The local notification
- * @param {Object} updates
- * Updated properties
- */
- updateLocalNotification: function (notification, updates) {
- for (var key in updates) {
- notification[key] = updates[key];
- }
-
- this.cancelLocalNotification(notification.id);
- this.scheduleLocalNotification(notification);
- },
-
- /**
- * Clears the specified notifications.
- *
- * @param {int[]} ids
- * List of local notification IDs
- */
- clear: function (ids) {
- for (var i = 0; i < ids.length; i++) {
- var id = ids[i],
- notification = this.getAll([id])[0];
-
- this.clearLocalNotification(id);
- this.fireEvent('clear', notification);
- }
- },
-
- /**
- * Clears the local notification with the given ID.
- *
- * @param {String} id
- * Local notification ID
- */
- clearLocalNotification: function (id) {
- var notification = this.getAll([id])[0];
-
- try {
- this.getToastHistory().remove('Toast' + id);
- } catch (e) {/*Only Phones support the NotificationHistory*/ }
-
- if (this.isRepeating(notification))
- return;
-
- if (this.isTriggered(id) && !this.isScheduled(id)) {
- this.cancelLocalNotification(id);
- }
- },
-
- /**
- * Clears all notifications.
- */
- clearAll: function () {
- var ids = this.getTriggeredIds();
-
- for (var i = 0; i < ids.length; i++) {
- this.clearLocalNotification(ids[i]);
- }
-
- try {
- this.getToastHistory().clear();
- } catch (e) {/*Only Phones support the NotificationHistory*/ }
- this.fireEvent('clearall');
- },
-
- /**
- * Cancels all specified notifications.
- *
- * @param {int[]} ids
- * List of local notification IDs
- */
- cancel: function (ids) {
- for (var i = 0; i < ids.length; i++) {
- var id = ids[i],
- notification = this.getAll([id])[0];
-
- this.cancelLocalNotification(ids[i]);
- this.fireEvent('cancel', notification);
- }
- },
-
- /**
- * Cancels the local notification with the given ID.
- *
- * @param {String} id
- * Local notification ID
- */
- cancelLocalNotification: function (id) {
- var notifier = this.getToastNotifier(),
- history = this.getToastHistory(),
- toasts = this.getScheduledToasts();
-
- try {
- history.remove('Toast' + id);
- } catch (e) {/*Only Phones support the NotificationHistory*/ }
-
- for (var i = 0; i < toasts.length; i++) {
- var toast = toasts[i];
-
- if (toast.id == id || toast.id == id + '-2') {
- notifier.removeFromSchedule(toast);
- }
- }
- },
-
- /**
- * Cancels all notifications.
- */
- cancelAll: function () {
- var ids = this.getAllIds();
-
- for (var i = 0; i < ids.length; i++) {
- this.cancelLocalNotification(ids[i]);
- }
-
- try {
- this.getToastHistory().clear();
- } catch (e) {/*Only Phones support the NotificationHistory*/ }
- this.fireEvent('cancelall');
- },
-
- /**
- * Checks if a notification with an ID is present.
- *
- * @param {int} id
- * Local notification ID
- */
- isPresent: function (id) {
- return !!this.findToastById(id);
- },
-
- /**
- * Checks if a notification with an ID was scheduled.
- *
- * @param {int} id
- * Local notification ID
- */
- isScheduled: function (id) {
- var toast = this.findToastById(id);
-
- return toast && this.isToastScheduled(toast);
- },
-
- /**
- * Checks if a notification with an ID was triggered.
- *
- * @param {int} id
- * Local notification ID
- */
- isTriggered: function (id) {
- var toast = this.findToastById(id);
-
- return toast && this.isToastTriggered(toast);
- },
-
- /**
- * Lists all local notification IDs.
- */
- getAllIds: function () {
- var toasts = this.getScheduledToasts(),
- ids = [];
-
- for (var i = 0; i < toasts.length; i++) {
- var toast = toasts[i];
-
- ids.push(this.getToastId(toast));
- }
-
- return ids;
- },
-
- /**
- * Lists all scheduled notification IDs.
- */
- getScheduledIds: function () {
- var toasts = this.getScheduledToasts(),
- ids = [];
-
- for (var i = 0; i < toasts.length; i++) {
- var toast = toasts[i];
-
- if (!this.isToastScheduled(toast))
- continue;
-
- ids.push(this.getToastId(toast));
- }
-
- return ids;
- },
-
- /**
- * Lists all scheduled notification IDs.
- */
- getTriggeredIds: function () {
- var toasts = this.getScheduledToasts(),
- ids = [];
-
- for (var i = 0; i < toasts.length; i++) {
- var toast = toasts[i];
-
- if (!this.isToastTriggered(toast))
- continue;
-
- ids.push(this.getToastId(toast));
- }
-
- return ids;
- },
-
- /**
- * Property list for given notifications.
- * If called without IDs, all notification will be returned.
- *
- * @param {int[]} ids
- * List of local notification IDs.
- * @param {String?} type
- * Local notification life cycle type
- */
- getAll: function (ids, type) {
- var toasts = this.getScheduledToasts(),
- notifications = [];
-
- if (!ids || ids.length === 0) {
- ids = this.getAllIds();
- }
-
- for (var index = 0; index < ids.length; index++) {
- var id = ids[index],
- toast = this.findToastById(id);
-
- if (!toast || type && this.getToastType(toast) != type)
- continue;
-
- var json = toast.content.lastChild.lastChild.innerText;
-
- notifications.push(JSON.parse(json));
- }
-
- return notifications;
- },
-
- /**
- * Property list for given notifications.
- * If called without IDs, all notification will be returned.
- *
- * @param {int[]} ids
- * List of local notification IDs
- */
- getScheduled: function (ids) {
- if (!ids || ids.length === 0) {
- ids = this.getAllIds();
- }
-
- return this.getAll(ids, 'scheduled');
- },
-
- /**
- * Property list for given notifications.
- * If called without IDs, all notification will be returned.
- *
- * @param {int[]} ids
- * List of local notification IDs
- */
- getTriggered: function (ids) {
- if (!ids || ids.length === 0) {
- ids = this.getAllIds();
- }
-
- return this.getAll(ids, 'triggered');
- },
-};
diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js deleted file mode 100644 index 2f7ed3d7..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationProxy.js +++ /dev/null @@ -1,311 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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. -*/ - -/** - * Executes all queued events. - */ -exports.deviceready = function () { - exports.core.deviceready(); -}; - -/** - * Schedule a new local notification. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {Object[]} notifications - * Array of local notifications - */ -exports.schedule = function (success, error, notifications) { - exports.core.schedule(notifications, 'schedule'); - - success(); -}; - -/** - * Update existing notifications specified by IDs in options. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {Object[]} notifications - * Array of local notifications - */ -exports.update = function (success, error, notifications) { - exports.core.update(notifications); - - success(); -}; - -/** - * Clear the specified notification. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.clear = function (success, error, ids) { - exports.core.clear(ids, true); - - success(); -}; - -/** - * Clear all previously sheduled notifications. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.clearAll = function (success, error) { - exports.core.clearAll(); - - success(); -}; - -/** - * Cancel the specified notifications. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.cancel = function (success, error, ids) { - exports.core.cancel(ids, true); - - success(); -}; - -/** - * Remove all previously registered notifications. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.cancelAll = function (success, error) { - exports.core.cancelAll(); - - success(); -}; - -/** - * Check if a notification with an ID is present. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int} id - * Local notification ID - */ -exports.isPresent = function (success, error, args) { - var found = exports.core.isPresent(args[0]); - - success(found); -}; - -/** - * Check if a notification with an ID is scheduled. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int} id - * Local notification ID - */ -exports.isScheduled = function (success, error, args) { - var found = exports.core.isScheduled(args[0]); - - success(found); -}; - -/** - * Check if a notification with an ID was triggered. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int} id - * Local notification ID - */ -exports.isTriggered = function (success, error, args) { - var found = exports.core.isTriggered(args[0]); - - success(found); -}; - -/** - * List all local notification IDs. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.getAllIds = function (success, error) { - var ids = exports.core.getAllIds(); - - success(ids); -}; - -/** - * List all scheduled notification IDs. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.getScheduledIds = function (success, error) { - var ids = exports.core.getScheduledIds(); - - success(ids); -}; - -/** - * List all triggered notification IDs. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - */ -exports.getTriggeredIds = function (success, error) { - var ids = exports.core.getTriggeredIds(); - - success(ids); -}; - -/** - * Propertys for given notification. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.getSingle = function (success, error, ids) { - var notification = exports.core.getAll(ids)[0]; - - success(notification); -}; - -/** - * Propertys for given scheduled notification. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.getSingleScheduled = function (success, error, ids) { - var notification = exports.core.getScheduled(ids)[0]; - - success(notification); -}; - -/** - * Propertys for given triggered notification. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.getSingleTriggered = function (success, error, ids) { - var notification = exports.core.getTriggered(ids)[0]; - - success(notification); -}; - -/** - * Property list for given notifications. - * If called without IDs, all notification will be returned. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.getAll = function (success, error, ids) { - var notifications = exports.core.getAll(ids); - - success(notifications); -}; - -/** - * Property list for given triggered notifications. - * If called without IDs, all notification will be returned. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.getScheduled = function (success, error, ids) { - var notifications = exports.core.getScheduled(ids); - - success(notifications); -}; - -/** - * Property list for given triggered notifications. - * If called without IDs, all notification will be returned. - * - * @param {Function} success - * Success callback - * @param {Function} error - * Error callback - * @param {int[]} ids - * List of local notification IDs - */ -exports.getTriggered = function (success, error, ids) { - var notifications = exports.core.getTriggered(ids); - - success(notifications); -}; - - -cordova.commandProxy.add('LocalNotification', exports); diff --git a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js b/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js deleted file mode 100644 index 4081a0b8..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/src/windows/LocalNotificationUtil.js +++ /dev/null @@ -1,443 +0,0 @@ -/* - Copyright 2013-2015 appPlant UG - - 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. -*/ - - -exports = require('de.appplant.cordova.plugin.local-notification.LocalNotification.Proxy').core; - -var channel = require('cordova/channel'); - - -/*********** - * MEMBERS * - ***********/ - -// True if App is running, false if suspended -exports.isInBackground = true; - -// Indicates if the device is ready (to receive events) -exports.isReady = false; - -// Queues all events before deviceready -exports.eventQueue = []; - -/******** - * UTIL * - ********/ - -/** - * The repeating interval in milliseconds. - * - * @param {String} interval - * A number or a placeholder like `minute`. - * - * @return {Number} - * Interval in milliseconds - */ -exports.getRepeatInterval = function (every) { - - if (!every) - return 0; - - if (every == 'minute') - return 60000; - - if (every == 'hour') - return 360000; - - if (!NaN(every)) - return parseInt(every) * 60000; - - return 0; -}; - -/** - * If the notification is repeating. - * - * @param {Object} notification - * Local notification object - * - * @return Boolean - */ -exports.isRepeating = function (notification) { - return this.getRepeatInterval(notification.every) !== 0; -}; - -/** - * Parses sound file path. - * - * @param {String} path - * Relative path to sound resource - * - * @return {String} XML Tag for Sound-File - */ -exports.parseSound = function (path) { - if (!path.match(/^file/)) - return ''; - - var uri = this.parseUri(path), - audio = "<audio src=" + uri + " loop='false'/>"; - - return audio; -}; - -/** - * Parses image file path. - * - * @param {String} path - * Relative path to image resource - * - * @return {String} XML-Tag for Image-File - */ -exports.parseImage = function (path) { - if (!path.match(/^file/)) - return ''; - - var uri = this.parseUri(path), - image = "<image id='1' src=" + uri + " />"; - - return image; -}; - -/** - * Parses file path to URI. - * - * @param {String} path - * Relative path to a resource - * - * @return {String} URI to File - */ -exports.parseUri = function (path) { - var pkg = Windows.ApplicationModel.Package.current, - pkgId = pkg.id, - pkgName = pkgId.name; - - var uri = "'ms-appx://" + pkgName + "/www" + path.slice(6, path.length) + "'"; - - return uri; -}; - -/** - * Builds the xml payload for a local notification based on its options. - * - * @param {Object} options - * Local notification properties - * - * @return Windows.Data.Xml.Dom.XmlDocument - */ -exports.build = function (options) { - var template = this.buildToastTemplate(options), - notification = new Windows.Data.Xml.Dom.XmlDocument(); - - try { - notification.loadXml(template); - } catch (e) { - console.error( - 'LocalNotification#schedule', - 'Error loading the xml, check for invalid characters.'); - } - - // Launch Attribute to enable onClick event - var launchAttr = notification.createAttribute('launch'), - toastNode = notification.selectSingleNode('/toast'); - - launchAttr.value = options.id.toString(); - toastNode.attributes.setNamedItem(launchAttr); - - return notification; -}; - -/** - * Builds the toast template with the right style depend on the options. - * - * @param {Object} options - * Local notification properties - * - * @return String - */ -exports.buildToastTemplate = function (options) { - var title = options.title, - message = options.text || '', - json = JSON.stringify(options), - sound = ''; - - if (options.sound && options.sound !== '') { - sound = this.parseSound(options.sound); - } - - var templateName = "ToastText", - imageNode; - if (options.icon && options.icon !== '') { - imageNode = this.parseImage(options.icon); - // template with Image - if (imageNode !== '') { - templateName = "ToastImageAndText"; - } - } else { - imageNode = ""; - } - - var bindingNode; - if (title && title !== '') { - bindingNode = "<binding template='" + templateName + "02'>" + - imageNode + - "<text id='1'>" + title + "</text>" + - "<text id='2'>" + message + "</text>" + - "</binding>"; - } else { - bindingNode = "<binding template='" + templateName + "01'>" + - imageNode + - "<text id='1'>" + message + "</text>" + - "</binding>"; - } - return "<toast>" + - "<visual>" + - bindingNode + - "</visual>" + - sound + - "<json>" + json + "</json>" + - "</toast>"; -}; - -/** - * Short-hand method for the toast notification history. - */ -exports.getToastHistory = function () { - return Windows.UI.Notifications.ToastNotificationManager.history; -}; - -/** - * Gets a toast notifier instance. - * - * @return Object - */ -exports.getToastNotifier = function () { - return Windows.UI.Notifications.ToastNotificationManager - .createToastNotifier(); -}; - -/** - * List of all scheduled toast notifiers. - * - * @return Array - */ -exports.getScheduledToasts = function () { - return this.getToastNotifier().getScheduledToastNotifications(); -}; - -/** - * Gets the Id from the toast notifier. - * - * @param {Object} toast - * A toast notifier object - * - * @return String - */ -exports.getToastId = function (toast) { - var id = toast.id; - - if (id.match(/-2$/)) - return id.match(/^[^-]+/)[0]; - - return id; -}; - -/** - * Gets the notification life cycle type - * (scheduled or triggered) - * - * @param {Object} toast - * A toast notifier object - * - * @return String - */ -exports.getToastType = function (toast) { - return this.isToastTriggered(toast) ? 'triggered' : 'scheduled'; -}; - -/** - * If the toast is already scheduled. - * - * @param {Object} toast - * A toast notifier object - * - * @return Boolean - */ -exports.isToastScheduled = function (toast) { - return !this.isToastTriggered(toast); -}; - -/** - * If the toast is already triggered. - * - * @param {Object} toast - * A toast notifier object - * - * @return Boolean - */ -exports.isToastTriggered = function (toast) { - var id = this.getToastId(toast), - notification = this.getAll([id])[0], - fireDate = new Date((notification.at) * 1000); - - if (this.isRepeating(notification)) - return false; - - return fireDate <= new Date(); -}; - -/** - * Finds the toast by it's ID. - * - * @param {String} id - * Local notification ID - * - * @param Object - */ -exports.findToastById = function (id) { - var toasts = this.getScheduledToasts(); - - for (var i = 0; i < toasts.length; i++) { - var toast = toasts[i]; - - if (this.getToastId(toast) == id) - return toast; - } - - return null; -}; - -/** - * Sets trigger event for local notification. - * - * @param {Object} notification - * Local notification object - * @param {Function} callback - * Callback function - */ -exports.callOnTrigger = function (notification, callback) { - var triggerTime = new Date((notification.at * 1000)), - interval = triggerTime - new Date(); - - if (interval <= 0) { - callback.call(this, notification); - return; - } - - WinJS.Promise.timeout(interval).then(function () { - if (exports.isPresent(notification.id)) { - callback.call(exports, notification); - } - }); -}; - -/** - * Sets trigger event for all scheduled local notification. - * - * @param {Function} callback - * Callback function - */ -exports.callOnTriggerForScheduled = function (callback) { - var notifications = this.getScheduled(); - - for (var i = 0; i < notifications.length; i++) { - this.callOnTrigger(notifications[i], callback); - } -}; - -/** - * The application state - background or foreground. - * - * @return String - */ -exports.getApplicationState = function () { - return this.isInBackground ? 'background' : 'foreground'; -}; - -/** - * Fires the event about a local notification. - * - * @param {String} event - * The event - * @param {Object} notification - * The notification - */ -exports.fireEvent = function (event, notification) { - var plugin = cordova.plugins.notification.local.core, - state = this.getApplicationState(), - args; - - if (notification) { - args = [event, notification, state]; - } else { - args = [event, state]; - } - - if (this.isReady && plugin) { - plugin.fireEvent.apply(plugin, args); - } else { - this.eventQueue.push(args); - } -}; - - -/************** - * LIFE CYCLE * - **************/ - -// Called before 'deviceready' event -channel.onCordovaReady.subscribe(function () { - // Register trigger handler for each scheduled notification - exports.callOnTriggerForScheduled(function (notification) { - this.updateBadge(notification.badge); - this.fireEvent('trigger', notification); - }); -}); - -// Handle onclick event -WinJS.Application.addEventListener('activated', function (args) { - var id = args.detail.arguments, - notification = exports.getAll([id])[0]; - - if (!notification) - return; - - exports.clearLocalNotification(id); - - var repeating = exports.isRepeating(notification); - - exports.fireEvent('click', notification); - exports.fireEvent(repeating ? 'clear' : 'cancel', notification); -}, false); - -// App is running in background -document.addEventListener('pause', function () { - exports.isInBackground = true; -}, false); - -// App is running in foreground -document.addEventListener('resume', function () { - exports.isInBackground = false; -}, false); - -// App is running in foreground -document.addEventListener('deviceready', function () { - exports.isInBackground = false; -}, false); diff --git a/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js b/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js deleted file mode 100644 index 03faa834..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-core.js +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -var exec = require('cordova/exec'); - - -/******** - * CORE * - ********/ - -/** - * Returns the default settings. - * - * @return {Object} - */ -exports.getDefaults = function () { - return this._defaults; -}; - -/** - * Overwrite default settings. - * - * @param {Object} defaults - */ -exports.setDefaults = function (newDefaults) { - var defaults = this.getDefaults(); - - for (var key in defaults) { - if (newDefaults.hasOwnProperty(key)) { - defaults[key] = newDefaults[key]; - } - } -}; - -/** - * Schedule a new local notification. - * - * @param {Object} opts - * The notification properties - * @param {Function} callback - * A function to be called after the notification has been canceled - * @param {Object?} scope - * The scope for the callback function - */ -exports.schedule = function (opts, callback, scope) { - this.registerPermission(function(granted) { - - if (!granted) - return; - - var notifications = Array.isArray(opts) ? opts : [opts]; - - for (var i = 0; i < notifications.length; i++) { - var properties = notifications[i]; - - this.mergeWithDefaults(properties); - this.convertProperties(properties); - } - - this.exec('schedule', notifications, callback, scope); - }, this); -}; - -/** - * Update existing notifications specified by IDs in options. - * - * @param {Object} options - * The notification properties to update - * @param {Function} callback - * A function to be called after the notification has been updated - * @param {Object?} scope - * The scope for the callback function - */ -exports.update = function (opts, callback, scope) { - var notifications = Array.isArray(opts) ? opts : [opts]; - - for (var i = 0; i < notifications.length; i++) { - var properties = notifications[i]; - - this.convertProperties(properties); - } - - this.exec('update', notifications, callback, scope); -}; - -/** - * Clear the specified notification. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A function to be called after the notification has been cleared - * @param {Object?} scope - * The scope for the callback function - */ -exports.clear = function (ids, callback, scope) { - ids = Array.isArray(ids) ? ids : [ids]; - ids = this.convertIds(ids); - - this.exec('clear', ids, callback, scope); -}; - -/** - * Clear all previously sheduled notifications. - * - * @param {Function} callback - * A function to be called after all notifications have been cleared - * @param {Object?} scope - * The scope for the callback function - */ -exports.clearAll = function (callback, scope) { - this.exec('clearAll', null, callback, scope); -}; - -/** - * Cancel the specified notifications. - * - * @param {String[]} ids - * The IDs of the notifications - * @param {Function} callback - * A function to be called after the notifications has been canceled - * @param {Object?} scope - * The scope for the callback function - */ -exports.cancel = function (ids, callback, scope) { - ids = Array.isArray(ids) ? ids : [ids]; - ids = this.convertIds(ids); - - this.exec('cancel', ids, callback, scope); -}; - -/** - * Remove all previously registered notifications. - * - * @param {Function} callback - * A function to be called after all notifications have been canceled - * @param {Object?} scope - * The scope for the callback function - */ -exports.cancelAll = function (callback, scope) { - this.exec('cancelAll', null, callback, scope); -}; - -/** - * Check if a notification with an ID is present. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.isPresent = function (id, callback, scope) { - this.exec('isPresent', id || 0, callback, scope); -}; - -/** - * Check if a notification with an ID is scheduled. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.isScheduled = function (id, callback, scope) { - this.exec('isScheduled', id || 0, callback, scope); -}; - -/** - * Check if a notification with an ID was triggered. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.isTriggered = function (id, callback, scope) { - this.exec('isTriggered', id || 0, callback, scope); -}; - -/** - * List all local notification IDs. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAllIds = function (callback, scope) { - this.exec('getAllIds', null, callback, scope); -}; - -/** - * Alias for `getAllIds`. - */ -exports.getIds = function () { - this.getAllIds.apply(this, arguments); -}; - -/** - * List all scheduled notification IDs. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getScheduledIds = function (callback, scope) { - this.exec('getScheduledIds', null, callback, scope); -}; - -/** - * List all triggered notification IDs. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getTriggeredIds = function (callback, scope) { - this.exec('getTriggeredIds', null, callback, scope); -}; - -/** - * Property list for given local notifications. - * If called without IDs, all notification will be returned. - * - * @param {Number[]?} ids - * Set of notification IDs - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.get = function () { - var args = Array.apply(null, arguments); - - if (typeof args[0] == 'function') { - args.unshift([]); - } - - var ids = args[0], - callback = args[1], - scope = args[2]; - - if (!Array.isArray(ids)) { - this.exec('getSingle', Number(ids), callback, scope); - return; - } - - ids = this.convertIds(ids); - - this.exec('getAll', ids, callback, scope); -}; - -/** - * Property list for all local notifications. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAll = function (callback, scope) { - this.exec('getAll', null, callback, scope); -}; - -/** - * Property list for given scheduled notifications. - * If called without IDs, all notification will be returned. - * - * @param {Number[]?} ids - * Set of notification IDs - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getScheduled = function () { - var args = Array.apply(null, arguments); - - if (typeof args[0] == 'function') { - args.unshift([]); - } - - var ids = args[0], - callback = args[1], - scope = args[2]; - - if (!Array.isArray(ids)) { - ids = [ids]; - } - - if (!Array.isArray(ids)) { - this.exec('getSingleScheduled', Number(ids), callback, scope); - return; - } - - ids = this.convertIds(ids); - - this.exec('getScheduled', ids, callback, scope); -}; - -/** - * Property list for all scheduled notifications. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAllScheduled = function (callback, scope) { - this.exec('getScheduled', null, callback, scope); -}; - -/** - * Property list for given triggered notifications. - * If called without IDs, all notification will be returned. - * - * @param {Number[]?} ids - * Set of notification IDs - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getTriggered = function () { - var args = Array.apply(null, arguments); - - if (typeof args[0] == 'function') { - args.unshift([]); - } - - var ids = args[0], - callback = args[1], - scope = args[2]; - - if (!Array.isArray(ids)) { - ids = [ids]; - } - - if (!Array.isArray(ids)) { - this.exec('getSingleTriggered', Number(ids), callback, scope); - return; - } - - ids = this.convertIds(ids); - - this.exec('getTriggered', ids, callback, scope); -}; - -/** - * Property list for all triggered notifications. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAllTriggered = function (callback, scope) { - this.exec('getTriggered', null, callback, scope); -}; - -/** - * Informs if the app has the permission to show notifications. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.hasPermission = function (callback, scope) { - var fn = this.createCallbackFn(callback, scope); - - if (device.platform != 'iOS') { - fn(true); - return; - } - - exec(fn, null, 'LocalNotification', 'hasPermission', []); -}; - -/** - * Register permission to show notifications if not already granted. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.registerPermission = function (callback, scope) { - var fn = this.createCallbackFn(callback, scope); - - if (device.platform != 'iOS') { - fn(true); - return; - } - - exec(fn, null, 'LocalNotification', 'registerPermission', []); -}; - - -/********** - * EVENTS * - **********/ - -/** - * Register callback for given event. - * - * @param {String} event - * The event's name - * @param {Function} callback - * The function to be exec as callback - * @param {Object?} scope - * The callback function's scope - */ -exports.on = function (event, callback, scope) { - - if (!this._listener[event]) { - this._listener[event] = []; - } - - var item = [callback, scope || window]; - - this._listener[event].push(item); -}; - -/** - * Unregister callback for given event. - * - * @param {String} event - * The event's name - * @param {Function} callback - * The function to be exec as callback - */ -exports.un = function (event, callback) { - var listener = this._listener[event]; - - if (!listener) - return; - - for (var i = 0; i < listener.length; i++) { - var fn = listener[i][0]; - - if (fn == callback) { - listener.splice(i, 1); - break; - } - } -}; diff --git a/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js b/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js deleted file mode 100644 index 7e96b64c..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - -var exec = require('cordova/exec'), - channel = require('cordova/channel'); - - -/*********** - * MEMBERS * - ***********/ - -// Default values -exports._defaults = { - text: '', - title: '', - sound: 'res://platform_default', - badge: 0, - id: 0, - data: undefined, - every: undefined, - at: undefined -}; - -// listener -exports._listener = {}; - - -/******** - * UTIL * - ********/ - -/** - * Merge platform specific properties into the default ones. - * - * @return {Object} - * The default properties for the platform - */ -exports.applyPlatformSpecificOptions = function () { - var defaults = this._defaults; - - switch (device.platform) { - case 'Android': - defaults.icon = 'res://icon'; - defaults.smallIcon = 'res://ic_popup_reminder'; - defaults.ongoing = false; - defaults.autoClear = true; - defaults.led = 'FFFFFF'; - break; - } - - return defaults; -}; - -/** - * Merge custom properties with the default values. - * - * @param {Object} options - * Set of custom values - * - * @retrun {Object} - * The merged property list - */ -exports.mergeWithDefaults = function (options) { - var defaults = this.getDefaults(); - - options.at = this.getValueFor(options, 'at', 'firstAt', 'date'); - options.text = this.getValueFor(options, 'text', 'message'); - options.data = this.getValueFor(options, 'data', 'json'); - - if (defaults.hasOwnProperty('autoClear')) { - options.autoClear = this.getValueFor(options, 'autoClear', 'autoCancel'); - } - - if (options.autoClear !== true && options.ongoing) { - options.autoClear = false; - } - - if (options.at === undefined || options.at === null) { - options.at = new Date(); - } - - for (var key in defaults) { - if (options[key] === null || options[key] === undefined) { - if (options.hasOwnProperty(key) && ['data','sound'].indexOf(key) > -1) { - options[key] = undefined; - } else { - options[key] = defaults[key]; - } - } - } - - for (key in options) { - if (!defaults.hasOwnProperty(key)) { - delete options[key]; - console.warn('Unknown property: ' + key); - } - } - - return options; -}; - -/** - * Convert the passed values to their required type. - * - * @param {Object} options - * Set of custom values - * - * @retrun {Object} - * The converted property list - */ -exports.convertProperties = function (options) { - - if (options.id) { - if (isNaN(options.id)) { - options.id = this.getDefaults().id; - console.warn('Id is not a number: ' + options.id); - } else { - options.id = Number(options.id); - } - } - - if (options.title) { - options.title = options.title.toString(); - } - - if (options.text) { - options.text = options.text.toString(); - } - - if (options.badge) { - if (isNaN(options.badge)) { - options.badge = this.getDefaults().badge; - console.warn('Badge number is not a number: ' + options.id); - } else { - options.badge = Number(options.badge); - } - } - - if (options.at) { - if (typeof options.at == 'object') { - options.at = options.at.getTime(); - } - - options.at = Math.round(options.at/1000); - } - - if (typeof options.data == 'object') { - options.data = JSON.stringify(options.data); - } - - return options; -}; - -/** - * Create callback, which will be executed within a specific scope. - * - * @param {Function} callbackFn - * The callback function - * @param {Object} scope - * The scope for the function - * - * @return {Function} - * The new callback function - */ -exports.createCallbackFn = function (callbackFn, scope) { - - if (typeof callbackFn != 'function') - return; - - return function () { - callbackFn.apply(scope || this, arguments); - }; -}; - -/** - * Convert the IDs to numbers. - * - * @param {String/Number[]} ids - * - * @return Array of Numbers - */ -exports.convertIds = function (ids) { - var convertedIds = []; - - for (var i = 0; i < ids.length; i++) { - convertedIds.push(Number(ids[i])); - } - - return convertedIds; -}; - -/** - * First found value for the given keys. - * - * @param {Object} options - * Object with key-value properties - * @param {String[]} keys* - * Key list - */ -exports.getValueFor = function (options) { - var keys = Array.apply(null, arguments).slice(1); - - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - - if (options.hasOwnProperty(key)) { - return options[key]; - } - } -}; - -/** - * Fire event with given arguments. - * - * @param {String} event - * The event's name - * @param {args*} - * The callback's arguments - */ -exports.fireEvent = function (event) { - var args = Array.apply(null, arguments).slice(1), - listener = this._listener[event]; - - if (!listener) - return; - - for (var i = 0; i < listener.length; i++) { - var fn = listener[i][0], - scope = listener[i][1]; - - fn.apply(scope, args); - } -}; - -/** - * Execute the native counterpart. - * - * @param {String} action - * The name of the action - * @param args[] - * Array of arguments - * @param {Function} callback - * The callback function - * @param {Object} scope - * The scope for the function - */ -exports.exec = function (action, args, callback, scope) { - var fn = this.createCallbackFn(callback, scope), - params = []; - - if (Array.isArray(args)) { - params = args; - } else if (args) { - params.push(args); - } - - exec(fn, null, 'LocalNotification', action, params); -}; - - -/********* - * HOOKS * - *********/ - -// Called after 'deviceready' event -channel.deviceready.subscribe(function () { - // Device is ready now, the listeners are registered - // and all queued events can be executed. - exec(null, null, 'LocalNotification', 'deviceready', []); -}); - -// Called before 'deviceready' event -channel.onCordovaReady.subscribe(function () { - // Device plugin is ready now - channel.onCordovaInfoReady.subscribe(function () { - // Merge platform specifics into defaults - exports.applyPlatformSpecificOptions(); - }); -}); diff --git a/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js b/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js deleted file mode 100644 index 9e9bd284..00000000 --- a/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright (c) 2013-2015 by appPlant UG. All rights reserved. - * - * @APPPLANT_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apache License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://opensource.org/licenses/Apache-2.0/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPPLANT_LICENSE_HEADER_END@ - */ - - -/************* - * INTERFACE * - *************/ - -/** - * Returns the default settings. - * - * @return {Object} - */ -exports.getDefaults = function () { - return this.core.getDefaults(); -}; - -/** - * Overwrite default settings. - * - * @param {Object} defaults - */ -exports.setDefaults = function (defaults) { - this.core.setDefaults(defaults); -}; - -/** - * Schedule a new local notification. - * - * @param {Object} opts - * The notification properties - * @param {Function} callback - * A function to be called after the notification has been canceled - * @param {Object?} scope - * The scope for the callback function - */ -exports.schedule = function (opts, callback, scope) { - this.core.schedule(opts, callback, scope); -}; - -/** - * Update existing notifications specified by IDs in options. - * - * @param {Object} options - * The notification properties to update - * @param {Function} callback - * A function to be called after the notification has been updated - * @param {Object?} scope - * The scope for the callback function - */ -exports.update = function (opts, callback, scope) { - this.core.update(opts, callback, scope); -}; - -/** - * Clear the specified notification. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A function to be called after the notification has been cleared - * @param {Object?} scope - * The scope for the callback function - */ -exports.clear = function (ids, callback, scope) { - this.core.clear(ids, callback, scope); -}; - -/** - * Clear all previously sheduled notifications. - * - * @param {Function} callback - * A function to be called after all notifications have been cleared - * @param {Object?} scope - * The scope for the callback function - */ -exports.clearAll = function (callback, scope) { - this.core.clearAll(callback, scope); -}; - -/** - * Cancel the specified notifications. - * - * @param {String[]} ids - * The IDs of the notifications - * @param {Function} callback - * A function to be called after the notifications has been canceled - * @param {Object?} scope - * The scope for the callback function - */ -exports.cancel = function (ids, callback, scope) { - this.core.cancel(ids, callback, scope); -}; - -/** - * Remove all previously registered notifications. - * - * @param {Function} callback - * A function to be called after all notifications have been canceled - * @param {Object?} scope - * The scope for the callback function - */ -exports.cancelAll = function (callback, scope) { - this.core.cancelAll(callback, scope); -}; - -/** - * Check if a notification with an ID is present. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.isPresent = function (id, callback, scope) { - this.core.isPresent(id, callback, scope); -}; - -/** - * Check if a notification with an ID is scheduled. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.isScheduled = function (id, callback, scope) { - this.core.isScheduled(id, callback, scope); -}; - -/** - * Check if a notification with an ID was triggered. - * - * @param {String} id - * The ID of the notification - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.isTriggered = function (id, callback, scope) { - this.core.isTriggered(id, callback, scope); -}; - -/** - * List all local notification IDs. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAllIds = function (callback, scope) { - this.core.getAllIds(callback, scope); -}; - -/** - * Alias for `getAllIds`. - */ -exports.getIds = function () { - this.getAllIds.apply(this, arguments); -}; - -/** - * List all scheduled notification IDs. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getScheduledIds = function (callback, scope) { - this.core.getScheduledIds(callback, scope); -}; - -/** - * List all triggered notification IDs. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getTriggeredIds = function (callback, scope) { - this.core.getTriggeredIds(callback, scope); -}; - -/** - * Property list for given local notifications. - * If called without IDs, all notification will be returned. - * - * @param {Number[]?} ids - * Set of notification IDs - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.get = function () { - this.core.get.apply(this.core, arguments); -}; - -/** - * Property list for all local notifications. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAll = function (callback, scope) { - this.core.getAll(callback, scope); -}; - -/** - * Property list for given scheduled notifications. - * If called without IDs, all notification will be returned. - * - * @param {Number[]?} ids - * Set of notification IDs - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getScheduled = function () { - this.core.getScheduled.apply(this.core, arguments); -}; - -/** - * Property list for all scheduled notifications. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAllScheduled = function (callback, scope) { - this.core.getAllScheduled(callback, scope); -}; - -/** - * Property list for given triggered notifications. - * If called without IDs, all notification will be returned. - * - * @param {Number[]?} ids - * Set of notification IDs - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getTriggered = function () { - this.core.getTriggered.apply(this.core, arguments); -}; - -/** - * Property list for all triggered notifications. - * - * @param {Function} callback - * A callback function to be called with the list - * @param {Object?} scope - * The scope for the callback function - */ -exports.getAllTriggered = function (callback, scope) { - this.core.getAllTriggered(callback, scope); -}; - -/** - * Informs if the app has the permission to show notifications. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.hasPermission = function (callback, scope) { - this.core.hasPermission(callback, scope); -}; - -/** - * Register permission to show notifications if not already granted. - * - * @param {Function} callback - * The function to be exec as the callback - * @param {Object?} scope - * The callback function's scope - */ -exports.registerPermission = function (callback, scope) { - this.core.registerPermission(callback, scope); -}; - - -/**************** - * DEPRECATIONS * - ****************/ - -/** - * Schedule a new local notification. - */ -exports.add = function () { - console.warn('Depreated: Please use `notification.local.schedule` instead.'); - - this.schedule.apply(this, arguments); -}; - -/** - * Register permission to show notifications - * if not already granted. - */ -exports.promptForPermission = function () { - console.warn('Depreated: Please use `notification.local.registerPermission` instead.'); - - this.registerPermission.apply(this, arguments); -}; - - -/********** - * EVENTS * - **********/ - -/** - * Register callback for given event. - * - * @param {String} event - * The event's name - * @param {Function} callback - * The function to be exec as callback - * @param {Object?} scope - * The callback function's scope - */ -exports.on = function (event, callback, scope) { - this.core.on(event, callback, scope); -}; - -/** - * Unregister callback for given event. - * - * @param {String} event - * The event's name - * @param {Function} callback - * The function to be exec as callback - */ -exports.un = function (event, callback) { - this.core.un(event, callback, scope); -}; diff --git a/plugins/fetch.json b/plugins/fetch.json deleted file mode 100644 index 532c8ada..00000000 --- a/plugins/fetch.json +++ /dev/null @@ -1,218 +0,0 @@ -{ - "org.apache.cordova.device": { - "source": { - "type": "registry", - "id": "org.apache.cordova.device" - } - }, - "org.apache.cordova.console": { - "source": { - "type": "registry", - "id": "org.apache.cordova.console" - } - }, - "com.ionic.keyboard": { - "source": { - "type": "registry", - "id": "com.ionic.keyboard" - }, - "is_top_level": true, - "variables": {} - }, - "org.apache.cordova.statusbar": { - "source": { - "type": "registry", - "id": "org.apache.cordova.statusbar" - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-whitelist": { - "source": { - "type": "registry", - "id": "cordova-plugin-whitelist" - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-inappbrowser": { - "source": { - "type": "registry", - "id": "cordova-plugin-inappbrowser" - }, - "is_top_level": true, - "variables": {} - }, - "nl.x-services.plugins.insomnia": { - "source": { - "type": "git", - "url": "https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-file": { - "source": { - "type": "registry", - "id": "cordova-plugin-file" - }, - "is_top_level": true, - "variables": {} - }, - "de.appplant.cordova.plugin.email-composer": { - "source": { - "type": "git", - "url": "https://github.com/katzer/cordova-plugin-email-composer.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "uk.co.whiteoctober.cordova.appversion": { - "source": { - "type": "git", - "url": "https://github.com/whiteoctober/cordova-plugin-app-version.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "org.pbernasconi.progressindicator": { - "source": { - "type": "git", - "url": "https://github.com/pbernasconi/cordova-progressIndicator.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "org.devgeeks.Canvas2ImagePlugin": { - "source": { - "type": "git", - "url": "https://github.com/devgeeks/Canvas2ImagePlugin.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "com.phonegap.plugins.OrientationLock": { - "source": { - "type": "git", - "url": "https://github.com/cogitor/PhoneGap-OrientationLock.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-splashscreen": { - "source": { - "type": "registry", - "id": "cordova-plugin-splashscreen" - }, - "is_top_level": true, - "variables": {} - }, - "hu.dpal.phonegap.plugins.PinDialog": { - "source": { - "type": "git", - "url": "https://github.com/Paldom/PinDialog.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-touchid": { - "source": { - "type": "git", - "url": "https://github.com/leecrossley/cordova-plugin-touchid.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-crosswalk-webview": { - "source": { - "type": "registry", - "id": "cordova-plugin-crosswalk-webview" - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-ios-longpress-fix": { - "source": { - "type": "registry", - "id": "cordova-plugin-ios-longpress-fix" - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-websocket": { - "source": { - "type": "registry", - "id": "cordova-plugin-websocket" - }, - "is_top_level": true, - "variables": {} - }, - "de.appplant.cordova.plugin.local-notification": { - "source": { - "type": "git", - "url": "https://github.com/katzer/cordova-plugin-local-notifications.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "cordova-plugin-device": { - "source": { - "type": "registry", - "id": "cordova-plugin-device" - }, - "is_top_level": false, - "variables": {} - }, - "de.appplant.cordova.common.registerusernotificationsettings": { - "source": { - "type": "registry", - "id": "de.appplant.cordova.common.registerusernotificationsettings" - }, - "is_top_level": false, - "variables": {} - }, - "de.appplant.cordova.plugin.badge": { - "source": { - "type": "git", - "url": "https://github.com/katzer/cordova-plugin-badge.git", - "subdir": "." - }, - "is_top_level": true, - "variables": {} - }, - "phonegap-plugin-push": { - "source": { - "type": "registry", - "id": "phonegap-plugin-push" - }, - "is_top_level": true, - "variables": {} - }, - "org.apache.cordova.file": { - "source": { - "type": "registry", - "id": "org.apache.cordova.file" - }, - "is_top_level": false, - "variables": {} - }, - "org.apache.cordova.media": { - "source": { - "type": "git", - "url": "https://github.com/pliablepixels/cordova-plugin-media.git", - "subdir": ".", - "ref": "playback-only" - }, - "is_top_level": true, - "variables": {} - } -}
\ No newline at end of file diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/LICENSE b/plugins/hu.dpal.phonegap.plugins.PinDialog/LICENSE deleted file mode 100644 index 3b489884..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Paldom - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/README.md b/plugins/hu.dpal.phonegap.plugins.PinDialog/README.md deleted file mode 100644 index 0f5ba3b3..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/README.md +++ /dev/null @@ -1,43 +0,0 @@ -PinDialog -========= - -PhoneGap numeric password dialog plugin for Android and iOS. Forked from https://github.com/apache/cordova-plugin-dialogs.git - -## Installation - -Latest stable release: ```phonegap local plugin add hu.dpal.phonegap.plugins.pindialog``` -or ```cordova plugin add hu.dpal.phonegap.plugins.pindialog``` - -Current state from git: ```phonegap local plugin add https://github.com/Paldom/PinDialog.git``` -or ```cordova plugin add https://github.com/Paldom/PinDialog.git``` - -## Installation - PhoneGap Build - -Add following to config.xml: ```<gap:plugin name="hu.dpal.phonegap.plugins.pindialog" />``` -or ```<gap:plugin name="hu.dpal.phonegap.plugins.pindialog" source="plugins.cordova.io" />``` - -## Supported Platforms - -- Android -- iOS - -## Usage: - - // Show pin dialog - window.plugins.pinDialog.prompt("message", callback, "title", ["OK","Cancel"]); - -Callback: - - function callback(results) - { - if(results.buttonIndex == 1) - { - // OK clicked, show input value - alert(results.input1); - } - if(results.buttonIndex == 2) - { - // Cancel clicked - alert("Cancel"); - } - }; diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/plugin.xml b/plugins/hu.dpal.phonegap.plugins.PinDialog/plugin.xml deleted file mode 100644 index 95c37524..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/plugin.xml +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0" - id="hu.dpal.phonegap.plugins.PinDialog" - version="0.1.3"> - - <name>PinDialog</name> - - <description> - PhoneGap numeric password dialog plugin for Android and iOS. Forked from https://github.com/apache/cordova-plugin-dialogs.git - </description> - <license>MIT</license> - <keywords>phonegap,android,ios,numeric,password,pin,dialog</keywords> - - <js-module src="www/pin.js" name="PinDialog"> - <merges target="window.plugins.pinDialog" /> - </js-module> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="PinDialog"> - <param name="android-package" value="hu.dpal.phonegap.plugins.PinDialog"/> - </feature> - </config-file> - - <source-file src="src/android/PinDialog.java" target-dir="src/hu/dpal/phonegap/plugins" /> - - </platform> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="PinDialog"> - <param name="ios-package" value="CDVPinDialog"/> - </feature> - </config-file> - - <header-file src="src/ios/CDVPinDialog.h" /> - <source-file src="src/ios/CDVPinDialog.m" /> - </platform> - -</plugin> - diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/src/android/PinDialog.java b/plugins/hu.dpal.phonegap.plugins.PinDialog/src/android/PinDialog.java deleted file mode 100644 index 6be1d6e3..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/src/android/PinDialog.java +++ /dev/null @@ -1,124 +0,0 @@ -package hu.dpal.phonegap.plugins; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.DialogInterface; -import android.text.InputType; -import android.text.method.PasswordTransformationMethod; -import android.widget.EditText; - - -public class PinDialog extends CordovaPlugin { - - public ProgressDialog spinnerDialog = null; - - public PinDialog() { - } - - public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { - if (action.equals("prompt")) { - - final String message = args.getString(0); - final String title = args.getString(1); - final JSONArray buttonLabels = args.getJSONArray(2); - - final CordovaInterface cordova = this.cordova; - final EditText promptInput = new EditText(cordova.getActivity()); - promptInput.setInputType(InputType.TYPE_CLASS_NUMBER); - promptInput.setTransformationMethod(PasswordTransformationMethod.getInstance()); - - Runnable runnable = new Runnable() { - public void run() { - AlertDialog.Builder dlg = new AlertDialog.Builder(cordova.getActivity()); - dlg.setMessage(message); - dlg.setTitle(title); - dlg.setCancelable(true); - - dlg.setView(promptInput); - - final JSONObject result = new JSONObject(); - - // First button - if (buttonLabels.length() > 0) { - try { - dlg.setNegativeButton(buttonLabels.getString(0), - new AlertDialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - try { - result.put("buttonIndex",1); - result.put("input1", promptInput.getText().toString().trim().length()==0 ? "" : promptInput.getText()); - } catch (JSONException e) { e.printStackTrace(); } - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); - } - }); - } catch (JSONException e) { } - } - - // Second button - if (buttonLabels.length() > 1) { - try { - dlg.setNeutralButton(buttonLabels.getString(1), - new AlertDialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - try { - result.put("buttonIndex",2); - result.put("input1", promptInput.getText().toString().trim().length()==0 ? "" : promptInput.getText()); - } catch (JSONException e) { e.printStackTrace(); } - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); - } - }); - } catch (JSONException e) { } - } - - // Third button - if (buttonLabels.length() > 2) { - try { - dlg.setPositiveButton(buttonLabels.getString(2), - new AlertDialog.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - try { - result.put("buttonIndex",3); - result.put("input1", promptInput.getText().toString().trim().length()==0 ? "" : promptInput.getText()); - } catch (JSONException e) { e.printStackTrace(); } - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); - } - }); - } catch (JSONException e) { } - } - - dlg.setOnCancelListener(new AlertDialog.OnCancelListener() { - public void onCancel(DialogInterface dialog){ - dialog.dismiss(); - try { - result.put("buttonIndex",0); - result.put("input1", promptInput.getText().toString().trim().length()==0 ? "" : promptInput.getText()); - } catch (JSONException e) { e.printStackTrace(); } - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); - } - }); - - dlg.create(); - dlg.show(); - - }; - }; - this.cordova.getActivity().runOnUiThread(runnable); - - - } - - return true; - } - -}
\ No newline at end of file diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/src/ios/CDVPinDialog.h b/plugins/hu.dpal.phonegap.plugins.PinDialog/src/ios/CDVPinDialog.h deleted file mode 100644 index 415195d5..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/src/ios/CDVPinDialog.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// CDVPinDialog.h -// HelloWorld -// -// -// - -#import <Foundation/Foundation.h> -#import <UIKit/UIKit.h> -#import <Cordova/CDVPlugin.h> - - -@interface CDVPinDialog : CDVPlugin <UIAlertViewDelegate>{} -@property (nonatomic, copy) NSString* callbackId; - -- (void)prompt:(CDVInvokedUrlCommand*)command; - -@end - diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/src/ios/CDVPinDialog.m b/plugins/hu.dpal.phonegap.plugins.PinDialog/src/ios/CDVPinDialog.m deleted file mode 100644 index bd33a205..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/src/ios/CDVPinDialog.m +++ /dev/null @@ -1,61 +0,0 @@ -// -// CDVPinDialog.m -// HelloWorld -// -// -// - -#import "CDVPinDialog.h" - -@implementation CDVPinDialog - -- (void)prompt:(CDVInvokedUrlCommand*)command -{ - self.callbackId = command.callbackId; - NSString* message = [command argumentAtIndex:0]; - NSString* title = [command argumentAtIndex:1]; - NSArray* buttons = [command argumentAtIndex:2]; - - UIAlertView* alertView = [[UIAlertView alloc] - initWithTitle:title - message:message - delegate:self - cancelButtonTitle:nil - otherButtonTitles:nil]; - - //alertView.callbackId = callbackId; - - int count = [buttons count]; - - for (int n = 0; n < count; n++) { - [alertView addButtonWithTitle:[buttons objectAtIndex:n]]; - } - - alertView.alertViewStyle = UIAlertViewStyleSecureTextInput; - UITextField* textField = [alertView textFieldAtIndex:0]; - - [alertView show]; - - [textField resignFirstResponder]; - [textField setKeyboardType:UIKeyboardTypeNumberPad]; - [textField becomeFirstResponder]; - -} - - -- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex -{ - CDVPluginResult* result; - - NSString* value0 = [[alertView textFieldAtIndex:0] text]; - NSDictionary* info = @{ - @"buttonIndex":@(buttonIndex + 1), - @"input1":(value0 ? value0 : [NSNull null]) - }; - result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info]; - - [self.commandDelegate sendPluginResult:result callbackId:self.callbackId]; -} - - -@end diff --git a/plugins/hu.dpal.phonegap.plugins.PinDialog/www/pin.js b/plugins/hu.dpal.phonegap.plugins.PinDialog/www/pin.js deleted file mode 100644 index 0633748b..00000000 --- a/plugins/hu.dpal.phonegap.plugins.PinDialog/www/pin.js +++ /dev/null @@ -1,13 +0,0 @@ -var exec = require('cordova/exec'); - - -module.exports = { - - prompt: function(message, resultCallback, title, buttonLabels) { - var _message = (message || "Message"); - var _title = (title || "Title"); - var _buttonLabels = (buttonLabels || ["OK","Cancel"]); - cordova.exec(resultCallback, null, "PinDialog", "prompt", [_message, _title, _buttonLabels]); - } - -};
\ No newline at end of file diff --git a/plugins/ios.json b/plugins/ios.json deleted file mode 100644 index 993fa085..00000000 --- a/plugins/ios.json +++ /dev/null @@ -1,209 +0,0 @@ -{ - "prepare_queue": { - "installed": [], - "uninstalled": [] - }, - "config_munge": { - "files": { - "config.xml": { - "parents": { - "/*": [ - { - "xml": "<feature name=\"Keyboard\"><param name=\"ios-package\" onload=\"true\" value=\"IonicKeyboard\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"File\"><param name=\"ios-package\" value=\"CDVFile\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"InAppBrowser\"><param name=\"ios-package\" value=\"CDVInAppBrowser\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"LongPressFix\"><param name=\"ios-package\" value=\"LongPressFix\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"SplashScreen\"><param name=\"ios-package\" value=\"CDVSplashScreen\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"TouchID\"><param name=\"ios-package\" value=\"TouchID\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Badge\"><param name=\"ios-package\" value=\"APPBadge\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"EmailComposer\"><param name=\"ios-package\" value=\"APPEmailComposer\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Device\"><param name=\"ios-package\" value=\"CDVDevice\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"LocalNotification\"><param name=\"ios-package\" onload=\"true\" value=\"APPLocalNotification\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"PinDialog\"><param name=\"ios-package\" value=\"CDVPinDialog\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Insomnia\"><param name=\"ios-package\" value=\"Insomnia\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Console\"><param name=\"ios-package\" value=\"CDVLogger\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"StatusBar\"><param name=\"ios-package\" value=\"CDVStatusBar\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<preference name=\"StatusBarOverlaysWebView\" value=\"true\" />", - "count": 1 - }, - { - "xml": "<preference name=\"StatusBarStyle\" value=\"lightcontent\" />", - "count": 1 - }, - { - "xml": "<feature name=\"Canvas2ImagePlugin\"><param name=\"ios-package\" value=\"Canvas2ImagePlugin\" /><param name=\"onload\" value=\"true\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"PushNotification\"><param name=\"ios-package\" value=\"PushPlugin\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"AppVersion\"><param name=\"ios-package\" value=\"AppVersion\" /></feature>", - "count": 1 - }, - { - "xml": "<feature name=\"Media\"><param name=\"ios-package\" value=\"CDVSound\" /></feature>", - "count": 1 - } - ] - } - }, - "framework": { - "parents": { - "AssetsLibrary.framework": [ - { - "xml": false, - "count": 1 - } - ], - "MobileCoreServices.framework": [ - { - "xml": false, - "count": 1 - } - ], - "CoreGraphics.framework": [ - { - "xml": false, - "count": 2 - } - ], - "LocalAuthentication.framework": [ - { - "xml": false, - "count": 1 - } - ], - "Security.framework": [ - { - "xml": false, - "count": 1 - } - ], - "MessageUI.framework": [ - { - "xml": true, - "count": 1 - } - ] - } - } - } - }, - "installed_plugins": { - "com.ionic.keyboard": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "com.phonegap.plugins.OrientationLock": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-crosswalk-webview": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-file": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-inappbrowser": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-ios-longpress-fix": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-splashscreen": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-touchid": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-websocket": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "cordova-plugin-whitelist": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.common.registerusernotificationsettings": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.plugin.badge": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.plugin.email-composer": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "de.appplant.cordova.plugin.local-notification": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "hu.dpal.phonegap.plugins.PinDialog": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "nl.x-services.plugins.insomnia": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.apache.cordova.console": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.apache.cordova.statusbar": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.devgeeks.Canvas2ImagePlugin": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "phonegap-plugin-push": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "uk.co.whiteoctober.cordova.appversion": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - }, - "org.apache.cordova.media": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - } - }, - "dependent_plugins": { - "org.apache.cordova.device": { - "PACKAGE_NAME": "com.pliablepixels.zmninja" - } - } -}
\ No newline at end of file diff --git a/plugins/nl.x-services.plugins.insomnia/README.md b/plugins/nl.x-services.plugins.insomnia/README.md deleted file mode 100644 index aea1b505..00000000 --- a/plugins/nl.x-services.plugins.insomnia/README.md +++ /dev/null @@ -1,138 +0,0 @@ -# Insomnia-PhoneGap-Plugin - -by [Eddy Verbruggen](http://www.x-services.nl) - -1. [Description](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#1-description) -2. [Installation](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#2-installation) - 2. [Automatically (CLI / Plugman)](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#automatically-cli--plugman) - 2. [Manually](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#manually) - 2. [PhoneGap Build](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#phonegap-build) -3. [Usage](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#3-usage) -4. [Credits](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#4-credits) -5. [License](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin#5-license) - -This is for PhoneGap 3.x, [here is the 2.x version](https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin/tree/phonegap-2.x) - -## 1. Description - -Prevent the screen of the mobile device from falling asleep. - -* The device will never fall asleep after calling `keepAwake`. -* After making your app practically a zombie, you can allow it to sleep again by calling `allowSleepAgain`. -* Works on Android, probably every version you'd care about. -* Works on iOS, probably every version you'd care about. -* Works on wp8. - -## 2. Installation - -### Automatically (CLI / Plugman) -Insomnia is compatible with [Cordova Plugman](https://github.com/apache/cordova-plugman) and ready for the [PhoneGap 2.9.0 CLI](http://docs.phonegap.com/en/2.9.0/guide_cli_index.md.html#The%20Command-line%20Interface_add_features), here's how it works with the CLI: - -``` -$ phonegap local plugin add https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin.git -``` -or -``` -$ cordova plugin add https://github.com/EddyVerbruggen/Insomnia-PhoneGap-Plugin.git -``` -run this command afterwards: -``` -$ cordova prepare -``` - -The javascript bridge is brought in automatically, so no need to reference Insomnia.js from your html. - -### Manually - -1\. Add the following xml to your `config.xml` in the root directory of your `www` folder: -```xml -<!-- for iOS --> -<feature name="Insomnia"> - <param name="ios-package" value="Insomnia" /> -</feature> -``` - -```xml -<!-- for Android --> -<feature name="Insomnia"> - <param name="android-package" value="nl.xservices.plugins.Insomnia" /> -</feature> -``` - -```xml -<!-- for wp8 --> -<feature name="Insomnia"> - <param name="wp-package" value="Insomnia" /> -</feature> -``` - -2\. Grab a copy of Insomnia.js, add it to your project and reference it in `index.html`: -```html -<script type="text/javascript" src="js/Insomnia.js"></script> -``` - -3\. Download the source files for iOS and/or Android and copy them to your project. - -iOS: Copy `Insomnia.h` and `Insomnia.h` to `platforms/ios/<ProjectName>/Plugins` - -Android: Copy `Insomnia.java` to `platforms/android/src/nl/xservices/plugins` (create the folders) - -wp8: Copy `Insomnia.cs` to `platforms/wp8/Plugins/nl.x-services.plugins.insomnia` (create the folders) - -### PhoneGap Build - -Insomnia works with PhoneGap build too, look for Insomnia here: https://build.phonegap.com/plugins/ -Just add the following xml to your `config.xml` to always use the latest version of this plugin: -```xml -<gap:plugin name="nl.x-services.plugins.insomnia" /> -``` -or to use this exact version: -```xml -<gap:plugin name="nl.x-services.plugins.insomnia" version="4.0.0" /> -``` - -The plugin's javascript file is brought in automatically. Make sure though you include a reference to cordova.js in your index.html's head: -```html -<script type="text/javascript" src="cordova.js"></script> -``` - -## 3. Usage -```html -<button onclick="window.plugins.insomnia.keepAwake()">keep awake</button> -<button onclick="window.plugins.insomnia.allowSleepAgain()">allow sleep again</button> -``` -An optional successCallback (first argument) will be triggered if the functions succeed. Even calling `keepAwake` twice will fire the successCallback, because the app will respond as expected (being kept awake). - -An optional errorCallback (second argument) will only be triggered if something fatal happened, preventing the plugin to work as expected. - -## 4. CREDITS ## - -This plugin was enhanced for Plugman / PhoneGap Build by [Eddy Verbruggen](http://www.x-services.nl). - -The Android code was entirely created by the author. - -The iOS code was heavily inspired by [Wolfgang Koller](https://github.com/simplec-dev/powermanagement). - -Many thanks to [Jesse MacFadyen](https://github.com/purplecabbage) for implementing the wp8 version! - -## 5. License - -[The MIT License (MIT)](http://www.opensource.org/licenses/mit-license.html) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/plugins/nl.x-services.plugins.insomnia/plugin.xml b/plugins/nl.x-services.plugins.insomnia/plugin.xml deleted file mode 100755 index b8118322..00000000 --- a/plugins/nl.x-services.plugins.insomnia/plugin.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="nl.x-services.plugins.insomnia" - version="4.0.1"> - - <name>Insomnia (prevent screen sleep)</name> - - <description> - Prevent the screen of the mobile device from falling asleep. - </description> - - <license>MIT</license> - - <engines> - <engine name="cordova" version=">=3.0.0"/> - </engines> - - <js-module src="www/Insomnia.js" name="Insomnia"> - <clobbers target="window.plugins.insomnia" /> - </js-module> - - <!-- ios --> - <platform name="ios"> - - <config-file target="config.xml" parent="/*"> - <feature name="Insomnia"> - <param name="ios-package" value="Insomnia"/> - </feature> - </config-file> - - <header-file src="src/ios/Insomnia.h"/> - <source-file src="src/ios/Insomnia.m"/> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="Insomnia"> - <param name="wp-package" value="Insomnia"/> - </feature> - </config-file> - - <source-file src="src/wp8/Insomnia.cs" /> - </platform> - - <!-- android --> - <platform name="android"> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Insomnia"> - <param name="android-package" value="nl.xservices.plugins.Insomnia" /> - </feature> - </config-file> - - <source-file src="src/android/nl/xservices/plugins/Insomnia.java" target-dir="src/nl/xservices/plugins"/> - </platform> - - <!-- firefoxos --> - <platform name="firefoxos"> - <js-module src="src/firefoxos/insomnia.js" name="InsomniaProxy"> - <runs /> - </js-module> - </platform> - -</plugin> diff --git a/plugins/nl.x-services.plugins.insomnia/src/android/nl/xservices/plugins/Insomnia.java b/plugins/nl.x-services.plugins.insomnia/src/android/nl/xservices/plugins/Insomnia.java deleted file mode 100644 index 95094938..00000000 --- a/plugins/nl.x-services.plugins.insomnia/src/android/nl/xservices/plugins/Insomnia.java +++ /dev/null @@ -1,47 +0,0 @@ -package nl.xservices.plugins; - -import android.view.WindowManager; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; - -public class Insomnia extends CordovaPlugin { - - private static final String ACTION_KEEP_AWAKE = "keepAwake"; - private static final String ACTION_ALLOW_SLEEP_AGAIN = "allowSleepAgain"; - - @Override - public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { - try { - if (ACTION_KEEP_AWAKE.equals(action)) { - cordova.getActivity().runOnUiThread( - new Runnable() { - public void run() { - cordova.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); - } - }); - return true; - - } else if (ACTION_ALLOW_SLEEP_AGAIN.equals(action)) { - cordova.getActivity().runOnUiThread( - new Runnable() { - public void run() { - cordova.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK)); - } - }); - return true; - - } else { - callbackContext.error("insomnia." + action + " is not a supported function. Did you mean '" + ACTION_KEEP_AWAKE + "'?"); - return false; - } - } catch (Exception e) { - callbackContext.error(e.getMessage()); - return false; - } - } -} diff --git a/plugins/nl.x-services.plugins.insomnia/src/firefoxos/insomnia.js b/plugins/nl.x-services.plugins.insomnia/src/firefoxos/insomnia.js deleted file mode 100644 index ed4ea3af..00000000 --- a/plugins/nl.x-services.plugins.insomnia/src/firefoxos/insomnia.js +++ /dev/null @@ -1,16 +0,0 @@ -var lock; - -module.exports = { - keepAwake: function() { - if (navigator.requestWakeLock) { - lock = navigator.requestWakeLock("screen"); - } - }, - allowSleepAgain: function() { - if (lock && typeof lock.unlock === "function") { - lock.unlock(); - } - } -}; - -require("cordova/exec/proxy").add("Insomnia", module.exports); diff --git a/plugins/nl.x-services.plugins.insomnia/src/ios/Insomnia.h b/plugins/nl.x-services.plugins.insomnia/src/ios/Insomnia.h deleted file mode 100755 index c13c07ba..00000000 --- a/plugins/nl.x-services.plugins.insomnia/src/ios/Insomnia.h +++ /dev/null @@ -1,9 +0,0 @@ -#import <Cordova/CDV.h> - -@interface Insomnia :CDVPlugin - -- (void) keepAwake:(CDVInvokedUrlCommand*)command; - -- (void) allowSleepAgain:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/nl.x-services.plugins.insomnia/src/ios/Insomnia.m b/plugins/nl.x-services.plugins.insomnia/src/ios/Insomnia.m deleted file mode 100755 index 7eca3b07..00000000 --- a/plugins/nl.x-services.plugins.insomnia/src/ios/Insomnia.m +++ /dev/null @@ -1,32 +0,0 @@ -#import "Insomnia.h" -#import <Cordova/CDV.h> - -@implementation Insomnia - -- (void) keepAwake:(CDVInvokedUrlCommand*)command { - NSString *callbackId = command.callbackId; - - // Acquire a reference to the local UIApplication singleton - UIApplication* app = [UIApplication sharedApplication]; - - if (![app isIdleTimerDisabled]) { - [app setIdleTimerDisabled:true]; - } - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:result callbackId:callbackId]; -} - -- (void) allowSleepAgain:(CDVInvokedUrlCommand*)command { - NSString *callbackId = command.callbackId; - - // Acquire a reference to the local UIApplication singleton - UIApplication* app = [UIApplication sharedApplication]; - - if([app isIdleTimerDisabled]) { - [app setIdleTimerDisabled:false]; - } - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:result callbackId:callbackId]; -} - -@end
\ No newline at end of file diff --git a/plugins/nl.x-services.plugins.insomnia/src/wp8/Insomnia.cs b/plugins/nl.x-services.plugins.insomnia/src/wp8/Insomnia.cs deleted file mode 100644 index 034d1711..00000000 --- a/plugins/nl.x-services.plugins.insomnia/src/wp8/Insomnia.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.Phone.Shell; - -namespace WPCordovaClassLib.Cordova.Commands -{ - public class Insomnia : BaseCommand - { - public void keepAwake(string options) - { - PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled; - DispatchCommandResult(new PluginResult(PluginResult.Status.OK)); - } - - public void allowSleepAgain(string options) - { - PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Enabled; - DispatchCommandResult(new PluginResult(PluginResult.Status.OK)); - } - } -} diff --git a/plugins/nl.x-services.plugins.insomnia/www/Insomnia.js b/plugins/nl.x-services.plugins.insomnia/www/Insomnia.js deleted file mode 100755 index 17b63740..00000000 --- a/plugins/nl.x-services.plugins.insomnia/www/Insomnia.js +++ /dev/null @@ -1,21 +0,0 @@ -function Insomnia() { -} - -Insomnia.prototype.keepAwake = function (successCallback, errorCallback) { - cordova.exec(successCallback, errorCallback, "Insomnia", "keepAwake", []); -}; - -Insomnia.prototype.allowSleepAgain = function (successCallback, errorCallback) { - cordova.exec(successCallback, errorCallback, "Insomnia", "allowSleepAgain", []); -}; - -Insomnia.install = function () { - if (!window.plugins) { - window.plugins = {}; - } - - window.plugins.insomnia = new Insomnia(); - return window.plugins.insomnia; -}; - -cordova.addConstructor(Insomnia.install); diff --git a/plugins/org.apache.cordova.console/CONTRIBUTING.md b/plugins/org.apache.cordova.console/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/org.apache.cordova.console/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/org.apache.cordova.console/LICENSE b/plugins/org.apache.cordova.console/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/org.apache.cordova.console/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/NOTICE b/plugins/org.apache.cordova.console/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/org.apache.cordova.console/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/org.apache.cordova.console/README.md b/plugins/org.apache.cordova.console/README.md deleted file mode 100644 index c7552cb1..00000000 --- a/plugins/org.apache.cordova.console/README.md +++ /dev/null @@ -1,22 +0,0 @@ -<!--- - license: 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. ---> - -# org.apache.cordova.console - -Plugin documentation: [doc/index.md](doc/index.md) diff --git a/plugins/org.apache.cordova.console/RELEASENOTES.md b/plugins/org.apache.cordova.console/RELEASENOTES.md deleted file mode 100644 index 6f40771c..00000000 --- a/plugins/org.apache.cordova.console/RELEASENOTES.md +++ /dev/null @@ -1,64 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.2.3 (Sept 25, 2013) -* CB-4889 bumping&resetting version -* CB-4889 renaming org.apache.cordova.core.console to org.apache.cordova.console -* Rename CHANGELOG.md -> RELEASENOTES.md -* [CB-4752] Incremented plugin version on dev branch. - - ### 0.2.4 (Oct 28, 2013) -* CB-5154 log formatting incorrectly to native -* CB-5128: added repo + issue tag to plugin.xml for console plugin -* [CB-4915] Incremented plugin version on dev branch. - -### 0.2.5 (Dec 4, 2013) -* add ubuntu platform - -### 0.2.6 (Jan 02, 2014) -* CB-5658 Add doc/index.md for Console plugin - -### 0.2.7 (Feb 05, 2014) -* Native console needs to be called DebugConsole to avoid ambiguous reference. This commit requires the 3.4.0 version of the native class factory -* CB-4718 fixed Console plugin not working on wp - -### 0.2.8 (Apr 17, 2014) -* CB-6460: Update license headers -* Add NOTICE file - -### 0.2.9 (Jun 05, 2014) -* CB-6848 Add Android quirk, list applicable platforms -* CB-6796 Add license -* CB-6491 add CONTRIBUTING.md - -### 0.2.10 (Aug 06, 2014) -* CB-6127 Updated translations for docs - -### 0.2.11 (Sep 17, 2014) -* CB-7249 cordova-plugin-console documentation translation - -### 0.2.12 (Dec 02, 2014) -* CB-7977 Mention `deviceready` in plugin docs -* CB-7700 cordova-plugin-console documentation translation: cordova-plugin-console - -### 0.2.13 (Feb 04, 2015) -* CB-8351 ios: Use argumentForIndex rather than NSArray extension diff --git a/plugins/org.apache.cordova.console/doc/de/index.md b/plugins/org.apache.cordova.console/doc/de/index.md deleted file mode 100644 index 07c8317a..00000000 --- a/plugins/org.apache.cordova.console/doc/de/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -Dieses Plugin stellt sicher, dass der Befehl console.log() so hilfreich ist, wie er sein kann. Es fügt zusätzliche Funktion für iOS, Ubuntu, Windows Phone 8 und Windows 8 hinzu. Teilweise kann es vorkommen, dass der Befehl console.log() nicht korrekt erkannt wird, und es zu Fehlern bzw. zu nicht angezeigten Logs in der Console kommt. Wenn Sie mit der derzeitigen Funktionsweise zufrieden sind, kann es sein, dass Sie dieses Plugin nicht benötigen. - -## Installation - - cordova plugin add org.apache.cordova.console - - -### Android Eigenarten - -Auf einigen anderen Plattformen als Android reagiert der Befehl console.log ("1", "2", "3") auf mehrere Befehle. In diesem Fall 1, 2 und 3. Android wird jedoch nur auf das erste Argument (1) reagieren. Nachfolgende Argumente zu console.log() (2 und 3) werden ignoriert. Dafür ist aber nicht dieses Plugin verantwortlich! Es ist eine Limitierung die von Android kommt und nicht von diesem Plugin beeinflusst werden kann.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/es/index.md b/plugins/org.apache.cordova.console/doc/es/index.md deleted file mode 100644 index 610dab37..00000000 --- a/plugins/org.apache.cordova.console/doc/es/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -Este plugin es para asegurarse de que console.log() es tan útil como puede ser. Añade función adicional para iOS, Windows Phone 8, Ubuntu y Windows 8. Si estás contento con cómo funciona console.log() para ti, entonces probablemente no necesitas este plugin. - -## Instalación - - cordova plugin add org.apache.cordova.console - - -### Rarezas Android - -En algunas plataformas que no sean Android, console.log() actuará en varios argumentos, como console.log ("1", "2", "3"). Sin embargo, Android actuará sólo en el primer argumento. Se omitirá posteriores argumentos para console.log(). Este plugin no es la causa de eso, es una limitación propia de Android.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/fr/index.md b/plugins/org.apache.cordova.console/doc/fr/index.md deleted file mode 100644 index bde950e7..00000000 --- a/plugins/org.apache.cordova.console/doc/fr/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -Ce plugin est destiné à faire en sorte que console.log() est aussi utile que possible. Il ajoute une fonction supplémentaire pour iOS, Ubuntu, Windows Phone 8 et Windows 8. Si vous êtes satisfait du fonctionnement de console.log() pour vous, alors vous avez probablement pas besoin ce plugin. - -## Installation - - cordova plugin add org.apache.cordova.console - - -### Quirks Android - -Sur certaines plateformes autres que Android, console.log() va agir sur plusieurs arguments, tels que console.log ("1", "2", "3"). Toutefois, Android doit agir uniquement sur le premier argument. Les arguments suivants à console.log() seront ignorées. Ce plugin n'est pas la cause de cela, il s'agit d'une limitation d'Android lui-même.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/index.md b/plugins/org.apache.cordova.console/doc/index.md deleted file mode 100644 index ea801f78..00000000 --- a/plugins/org.apache.cordova.console/doc/index.md +++ /dev/null @@ -1,46 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -This plugin is meant to ensure that console.log() is as useful as it can be. -It adds additional function for iOS, Ubuntu, Windows Phone 8, and Windows 8. If -you are happy with how console.log() works for you, then you probably -don't need this plugin. - -This plugin defines a global `console` object. - -Although the object is in the global scope, features provided by this plugin -are not available until after the `deviceready` event. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log("console.log works well"); - } - -## Installation - - cordova plugin add org.apache.cordova.console - -### Android Quirks - -On some platforms other than Android, console.log() will act on multiple -arguments, such as console.log("1", "2", "3"). However, Android will act only -on the first argument. Subsequent arguments to console.log() will be ignored. -This plugin is not the cause of that, it is a limitation of Android itself. diff --git a/plugins/org.apache.cordova.console/doc/it/index.md b/plugins/org.apache.cordova.console/doc/it/index.md deleted file mode 100644 index f80a637e..00000000 --- a/plugins/org.apache.cordova.console/doc/it/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -Questo plugin è intesa a garantire che console.log() è tanto utile quanto può essere. Aggiunge una funzione aggiuntiva per iOS, Ubuntu, Windows 8 e Windows Phone 8. Se sei soddisfatto di come console.log() funziona per voi, quindi probabilmente non è necessario questo plugin. - -## Installazione - - cordova plugin add org.apache.cordova.console - - -### Stranezze Android - -Su alcune piattaforme diverse da Android, console.log() agirà su più argomenti, come ad esempio console ("1", "2", "3"). Tuttavia, Android agirà solo sul primo argomento. Argomenti successivi a console.log() verranno ignorati. Questo plugin non è la causa di ciò, è una limitazione di Android stesso.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/ja/index.md b/plugins/org.apache.cordova.console/doc/ja/index.md deleted file mode 100644 index f8a39c59..00000000 --- a/plugins/org.apache.cordova.console/doc/ja/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -このプラグインは、その console.log() がすることができます便利なことを確認するものです。 それは、iOS、Ubuntu、Windows Phone 8 および Windows 8 の追加関数を追加します。 場合はあなたのための console.log() の作品に満足しているし、おそらく必要はありませんこのプラグイン。 - -## インストール - - cordova plugin add org.apache.cordova.console - - -### Android の癖 - -アンドロイド以外のいくつかのプラットフォームで console.log() は console.log (「1」、「2」、「3」) など、複数の引数に動作します。 しかし、アンドロイドは、最初の引数でのみ動作します。 Console.log() に後続の引数は無視されます。 このプラグインが原因ではない、それは Android の自体の制限です。
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/ko/index.md b/plugins/org.apache.cordova.console/doc/ko/index.md deleted file mode 100644 index b07b2d6c..00000000 --- a/plugins/org.apache.cordova.console/doc/ko/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -이 플러그인을 console.log()로 수 유용 되도록 의미입니다. IOS, 우분투, Windows Phone 8 및 윈도우 8에 대 한 추가 기능을 추가 하 고 합니다. Console.log() 당신을 위해 작동 하는 어떻게 행복 한 경우에, 그때 당신은 아마 필요 하지 않습니다이 플러그인. - -## 설치 - - cordova plugin add org.apache.cordova.console - - -### 안 드 로이드 단점 - -안 드 로이드 이외의 일부 플랫폼에서 console.log() console.log ("1", "2", "3")와 같이 여러 인수에 작동할 것 이다. 그러나, 안 드 로이드는 첫 번째 인수에만 작동할 것 이다. Console.log() 후속 인수는 무시 됩니다. 이 플러그인의 원인이 되지 않습니다, 그리고 그것은 안 드 로이드 자체의 한계입니다.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/pl/index.md b/plugins/org.apache.cordova.console/doc/pl/index.md deleted file mode 100644 index 9260d598..00000000 --- a/plugins/org.apache.cordova.console/doc/pl/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -Ten plugin jest przeznaczona do zapewnienia, że console.log() jest tak przydatne, jak to może być. To dodaje dodatkową funkcję dla iOS, Ubuntu, Windows Phone 8 i Windows 8. Jeśli jesteś zadowolony z jak console.log() pracuje dla Ciebie, wtedy prawdopodobnie nie potrzebują tej wtyczki. - -## Instalacja - - cordova plugin add org.apache.cordova.console - - -### Dziwactwa Androida - -Na niektórych platformach innych niż Android console.log() będzie działać na wielu argumentów, takich jak console.log ("1", "2", "3"). Jednak Android będzie działać tylko na pierwszy argument. Kolejne argumenty do console.log() będą ignorowane. Ten plugin nie jest przyczyną, że, jest to ograniczenie Androida, sam.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/ru/index.md b/plugins/org.apache.cordova.console/doc/ru/index.md deleted file mode 100644 index 9ea1cd27..00000000 --- a/plugins/org.apache.cordova.console/doc/ru/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -Этот плагин предназначен для обеспечения как полезным, поскольку это может быть что console.log(). Он добавляет дополнительные функции для iOS, Ubuntu, Windows Phone 8 и Windows 8. Если вы не довольны как console.log() работает для вас, то вы вероятно не нужен этот плагин. - -## Установка - - cordova plugin add org.apache.cordova.console - - -### Особенности Android - -На некоторых платформах, отличных от Android console.log() будет действовать на нескольких аргументов, например console.log («1», «2», «3»). Тем не менее Android будет действовать только на первого аргумента. Последующие аргументы для console.log() будет игнорироваться. Этот плагин не является причиной этого, это ограничение Android сам.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/doc/zh/index.md b/plugins/org.apache.cordova.console/doc/zh/index.md deleted file mode 100644 index 50445633..00000000 --- a/plugins/org.apache.cordova.console/doc/zh/index.md +++ /dev/null @@ -1,31 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.console - -這個外掛程式是為了確保該 console.log() 是一樣有用,它可以是。 它將添加附加功能的 iOS、 Ubuntu,Windows Phone 8 和 Windows 8。 如果你是快樂與 console.log() 是如何為你工作,那麼可能不需要這個外掛程式。 - -## 安裝 - - cordova plugin add org.apache.cordova.console - - -### Android 的怪癖 - -在一些非 Android 平臺上,console.log() 將作用於多個參數,如 console.log ("1"、"2"、"3")。 然而,Android 將僅在第一個參數上採取行動。 對 console.log() 的後續參數將被忽略。 這個外掛程式不是的原因,,它是安卓系統本身的限制。
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/package.json b/plugins/org.apache.cordova.console/package.json deleted file mode 100644 index ef6eba71..00000000 --- a/plugins/org.apache.cordova.console/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "version": "0.2.13", - "name": "org.apache.cordova.console", - "cordova_name": "Console", - "description": "Cordova Console Plugin", - "license": "Apache 2.0", - "repo": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-console.git", - "issue": "https://issues.apache.org/jira/browse/CB/component/12320644", - "keywords": [ - "cordova", - "console" - ], - "platforms": [ - "ios", - "ubuntu", - "wp7", - "wp8", - "windows8" - ], - "engines": [], - "englishdoc": "<!---\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership. The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License. You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied. See the License for the\n specific language governing permissions and limitations\n under the License.\n-->\n\n# org.apache.cordova.console\n\nThis plugin is meant to ensure that console.log() is as useful as it can be.\nIt adds additional function for iOS, Ubuntu, Windows Phone 8, and Windows 8. If\nyou are happy with how console.log() works for you, then you probably\ndon't need this plugin.\n\nThis plugin defines a global `console` object.\n\nAlthough the object is in the global scope, features provided by this plugin\nare not available until after the `deviceready` event.\n\n document.addEventListener(\"deviceready\", onDeviceReady, false);\n function onDeviceReady() {\n console.log(\"console.log works well\");\n }\n\n## Installation\n\n cordova plugin add org.apache.cordova.console\n\n### Android Quirks\n\nOn some platforms other than Android, console.log() will act on multiple\narguments, such as console.log(\"1\", \"2\", \"3\"). However, Android will act only\non the first argument. Subsequent arguments to console.log() will be ignored.\nThis plugin is not the cause of that, it is a limitation of Android itself.\n" -}
\ No newline at end of file diff --git a/plugins/org.apache.cordova.console/plugin.xml b/plugins/org.apache.cordova.console/plugin.xml deleted file mode 100644 index 41dd0db3..00000000 --- a/plugins/org.apache.cordova.console/plugin.xml +++ /dev/null @@ -1,118 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - id="org.apache.cordova.console" - version="0.2.13"> - - <name>Console</name> - <description>Cordova Console Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,console</keywords> - <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-console.git</repo> - <issue>https://issues.apache.org/jira/browse/CB/component/12320644</issue> - - <!-- ios --> - <platform name="ios"> - - <config-file target="config.xml" parent="/*"> - <feature name="Console"> - <param name="ios-package" value="CDVLogger"/> - </feature> - </config-file> - - <js-module src="www/console-via-logger.js" name="console"> - <clobbers target="console" /> - </js-module> - - <js-module src="www/logger.js" name="logger"> - <clobbers target="cordova.logger" /> - </js-module> - - <header-file src="src/ios/CDVLogger.h" /> - <source-file src="src/ios/CDVLogger.m" /> - - </platform> - - <!-- ubuntu --> - <platform name="ubuntu"> - <js-module src="www/console-via-logger.js" name="console"> - <clobbers target="console" /> - </js-module> - - <js-module src="www/logger.js" name="logger"> - <clobbers target="cordova.logger" /> - </js-module> - - <header-file src="src/ubuntu/console.h" /> - <source-file src="src/ubuntu/console.cpp" /> - - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="config.xml" parent="/*"> - <feature name="Console"> - <param name="wp-package" value="DebugConsole"/> - </feature> - </config-file> - - <js-module src="www/console-via-logger.js" name="console"> - <clobbers target="console" /> - </js-module> - - <js-module src="www/logger.js" name="logger"> - <clobbers target="cordova.logger" /> - </js-module> - - <source-file src="src/wp/DebugConsole.cs" /> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="Console"> - <param name="wp-package" value="DebugConsole"/> - </feature> - </config-file> - - <js-module src="www/console-via-logger.js" name="console"> - <clobbers target="console" /> - </js-module> - - <js-module src="www/logger.js" name="logger"> - <clobbers target="cordova.logger" /> - </js-module> - - <source-file src="src/wp/DebugConsole.cs" /> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="www/logger.js" name="logger"> - <clobbers target="cordova.logger" /> - </js-module> - <js-module src="www/console-via-logger.js" name="console"> - <clobbers target="console" /> - </js-module> - - </platform> - -</plugin> diff --git a/plugins/org.apache.cordova.console/src/ios/CDVLogger.h b/plugins/org.apache.cordova.console/src/ios/CDVLogger.h deleted file mode 100644 index 7cfb3063..00000000 --- a/plugins/org.apache.cordova.console/src/ios/CDVLogger.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> - -@interface CDVLogger : CDVPlugin - -- (void)logLevel:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/org.apache.cordova.console/src/ios/CDVLogger.m b/plugins/org.apache.cordova.console/src/ios/CDVLogger.m deleted file mode 100644 index ccfa3a51..00000000 --- a/plugins/org.apache.cordova.console/src/ios/CDVLogger.m +++ /dev/null @@ -1,38 +0,0 @@ -/* - 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 "CDVLogger.h" -#import <Cordova/CDV.h> - -@implementation CDVLogger - -/* log a message */ -- (void)logLevel:(CDVInvokedUrlCommand*)command -{ - id level = [command argumentAtIndex:0]; - id message = [command argumentAtIndex:1]; - - if ([level isEqualToString:@"LOG"]) { - NSLog(@"%@", message); - } else { - NSLog(@"%@: %@", level, message); - } -} - -@end diff --git a/plugins/org.apache.cordova.console/src/ubuntu/console.cpp b/plugins/org.apache.cordova.console/src/ubuntu/console.cpp deleted file mode 100644 index 9de09f43..00000000 --- a/plugins/org.apache.cordova.console/src/ubuntu/console.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed 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 "console.h" - -#include <iostream> - -Console::Console(Cordova *cordova) : CPlugin(cordova) { -} - -void Console::logLevel(int scId, int ecId, QString level, QString message) { - Q_UNUSED(scId) - Q_UNUSED(ecId) - - if (level != "LOG") - std::cout << "[" << level.toStdString() << "] "; - std::cout << message.toStdString() << std::endl; -} diff --git a/plugins/org.apache.cordova.console/src/ubuntu/console.h b/plugins/org.apache.cordova.console/src/ubuntu/console.h deleted file mode 100644 index 3f3d1634..00000000 --- a/plugins/org.apache.cordova.console/src/ubuntu/console.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef CONSOLE_H_FDSVCXGFRS -#define CONSOLE_H_FDSVCXGFRS - -#include <cplugin.h> - -#include <QtCore> - -class Console : public CPlugin { - Q_OBJECT -public: - explicit Console(Cordova *cordova); - - virtual const QString fullName() override { - return Console::fullID(); - } - - virtual const QString shortName() override { - return "Console"; - } - - static const QString fullID() { - return "Console"; - } - -public slots: - void logLevel(int scId, int ecId, QString level, QString message); -}; - -#endif diff --git a/plugins/org.apache.cordova.console/src/wp/DebugConsole.cs b/plugins/org.apache.cordova.console/src/wp/DebugConsole.cs deleted file mode 100644 index 9bb5476d..00000000 --- a/plugins/org.apache.cordova.console/src/wp/DebugConsole.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using System.Diagnostics; - -namespace WPCordovaClassLib.Cordova.Commands -{ - public class DebugConsole : BaseCommand - { - public void logLevel(string options) - { - string[] args = JSON.JsonHelper.Deserialize<string[]>(options); - string level = args[0]; - string msg = args[1]; - - if (level.Equals("LOG")) - { - Debug.WriteLine(msg); - } - else - { - Debug.WriteLine(level + ": " + msg); - } - } - } -} diff --git a/plugins/org.apache.cordova.console/www/console-via-logger.js b/plugins/org.apache.cordova.console/www/console-via-logger.js deleted file mode 100644 index 4095eb3e..00000000 --- a/plugins/org.apache.cordova.console/www/console-via-logger.js +++ /dev/null @@ -1,187 +0,0 @@ -/* - * - * 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 logger = require("./logger"); -var utils = require("cordova/utils"); - -//------------------------------------------------------------------------------ -// object that we're exporting -//------------------------------------------------------------------------------ -var console = module.exports; - -//------------------------------------------------------------------------------ -// copy of the original console object -//------------------------------------------------------------------------------ -var WinConsole = window.console; - -//------------------------------------------------------------------------------ -// whether to use the logger -//------------------------------------------------------------------------------ -var UseLogger = false; - -//------------------------------------------------------------------------------ -// Timers -//------------------------------------------------------------------------------ -var Timers = {}; - -//------------------------------------------------------------------------------ -// used for unimplemented methods -//------------------------------------------------------------------------------ -function noop() {} - -//------------------------------------------------------------------------------ -// used for unimplemented methods -//------------------------------------------------------------------------------ -console.useLogger = function (value) { - if (arguments.length) UseLogger = !!value; - - if (UseLogger) { - if (logger.useConsole()) { - throw new Error("console and logger are too intertwingly"); - } - } - - return UseLogger; -}; - -//------------------------------------------------------------------------------ -console.log = function() { - if (logger.useConsole()) return; - logger.log.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.error = function() { - if (logger.useConsole()) return; - logger.error.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.warn = function() { - if (logger.useConsole()) return; - logger.warn.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.info = function() { - if (logger.useConsole()) return; - logger.info.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.debug = function() { - if (logger.useConsole()) return; - logger.debug.apply(logger, [].slice.call(arguments)); -}; - -//------------------------------------------------------------------------------ -console.assert = function(expression) { - if (expression) return; - - var message = logger.format.apply(logger.format, [].slice.call(arguments, 1)); - console.log("ASSERT: " + message); -}; - -//------------------------------------------------------------------------------ -console.clear = function() {}; - -//------------------------------------------------------------------------------ -console.dir = function(object) { - console.log("%o", object); -}; - -//------------------------------------------------------------------------------ -console.dirxml = function(node) { - console.log(node.innerHTML); -}; - -//------------------------------------------------------------------------------ -console.trace = noop; - -//------------------------------------------------------------------------------ -console.group = console.log; - -//------------------------------------------------------------------------------ -console.groupCollapsed = console.log; - -//------------------------------------------------------------------------------ -console.groupEnd = noop; - -//------------------------------------------------------------------------------ -console.time = function(name) { - Timers[name] = new Date().valueOf(); -}; - -//------------------------------------------------------------------------------ -console.timeEnd = function(name) { - var timeStart = Timers[name]; - if (!timeStart) { - console.warn("unknown timer: " + name); - return; - } - - var timeElapsed = new Date().valueOf() - timeStart; - console.log(name + ": " + timeElapsed + "ms"); -}; - -//------------------------------------------------------------------------------ -console.timeStamp = noop; - -//------------------------------------------------------------------------------ -console.profile = noop; - -//------------------------------------------------------------------------------ -console.profileEnd = noop; - -//------------------------------------------------------------------------------ -console.count = noop; - -//------------------------------------------------------------------------------ -console.exception = console.log; - -//------------------------------------------------------------------------------ -console.table = function(data, columns) { - console.log("%o", data); -}; - -//------------------------------------------------------------------------------ -// return a new function that calls both functions passed as args -//------------------------------------------------------------------------------ -function wrappedOrigCall(orgFunc, newFunc) { - return function() { - var args = [].slice.call(arguments); - try { orgFunc.apply(WinConsole, args); } catch (e) {} - try { newFunc.apply(console, args); } catch (e) {} - }; -} - -//------------------------------------------------------------------------------ -// For every function that exists in the original console object, that -// also exists in the new console object, wrap the new console method -// with one that calls both -//------------------------------------------------------------------------------ -for (var key in console) { - if (typeof WinConsole[key] == "function") { - console[key] = wrappedOrigCall(WinConsole[key], console[key]); - } -} diff --git a/plugins/org.apache.cordova.console/www/logger.js b/plugins/org.apache.cordova.console/www/logger.js deleted file mode 100644 index cbf81b9c..00000000 --- a/plugins/org.apache.cordova.console/www/logger.js +++ /dev/null @@ -1,355 +0,0 @@ -/* - * - * 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. - * -*/ - -//------------------------------------------------------------------------------ -// The logger module exports the following properties/functions: -// -// LOG - constant for the level LOG -// ERROR - constant for the level ERROR -// WARN - constant for the level WARN -// INFO - constant for the level INFO -// DEBUG - constant for the level DEBUG -// logLevel() - returns current log level -// logLevel(value) - sets and returns a new log level -// useConsole() - returns whether logger is using console -// useConsole(value) - sets and returns whether logger is using console -// log(message,...) - logs a message at level LOG -// error(message,...) - logs a message at level ERROR -// warn(message,...) - logs a message at level WARN -// info(message,...) - logs a message at level INFO -// debug(message,...) - logs a message at level DEBUG -// logLevel(level,message,...) - logs a message specified level -// -//------------------------------------------------------------------------------ - -var logger = exports; - -var exec = require('cordova/exec'); -var utils = require('cordova/utils'); - -var UseConsole = false; -var UseLogger = true; -var Queued = []; -var DeviceReady = false; -var CurrentLevel; - -var originalConsole = console; - -/** - * Logging levels - */ - -var Levels = [ - "LOG", - "ERROR", - "WARN", - "INFO", - "DEBUG" -]; - -/* - * add the logging levels to the logger object and - * to a separate levelsMap object for testing - */ - -var LevelsMap = {}; -for (var i=0; i<Levels.length; i++) { - var level = Levels[i]; - LevelsMap[level] = i; - logger[level] = level; -} - -CurrentLevel = LevelsMap.WARN; - -/** - * Getter/Setter for the logging level - * - * Returns the current logging level. - * - * When a value is passed, sets the logging level to that value. - * The values should be one of the following constants: - * logger.LOG - * logger.ERROR - * logger.WARN - * logger.INFO - * logger.DEBUG - * - * The value used determines which messages get printed. The logging - * values above are in order, and only messages logged at the logging - * level or above will actually be displayed to the user. E.g., the - * default level is WARN, so only messages logged with LOG, ERROR, or - * WARN will be displayed; INFO and DEBUG messages will be ignored. - */ -logger.level = function (value) { - if (arguments.length) { - if (LevelsMap[value] === null) { - throw new Error("invalid logging level: " + value); - } - CurrentLevel = LevelsMap[value]; - } - - return Levels[CurrentLevel]; -}; - -/** - * Getter/Setter for the useConsole functionality - * - * When useConsole is true, the logger will log via the - * browser 'console' object. - */ -logger.useConsole = function (value) { - if (arguments.length) UseConsole = !!value; - - if (UseConsole) { - if (typeof console == "undefined") { - throw new Error("global console object is not defined"); - } - - if (typeof console.log != "function") { - throw new Error("global console object does not have a log function"); - } - - if (typeof console.useLogger == "function") { - if (console.useLogger()) { - throw new Error("console and logger are too intertwingly"); - } - } - } - - return UseConsole; -}; - -/** - * Getter/Setter for the useLogger functionality - * - * When useLogger is true, the logger will log via the - * native Logger plugin. - */ -logger.useLogger = function (value) { - // Enforce boolean - if (arguments.length) UseLogger = !!value; - return UseLogger; -}; - -/** - * Logs a message at the LOG level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.log = function(message) { logWithArgs("LOG", arguments); }; - -/** - * Logs a message at the ERROR level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.error = function(message) { logWithArgs("ERROR", arguments); }; - -/** - * Logs a message at the WARN level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.warn = function(message) { logWithArgs("WARN", arguments); }; - -/** - * Logs a message at the INFO level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.info = function(message) { logWithArgs("INFO", arguments); }; - -/** - * Logs a message at the DEBUG level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.debug = function(message) { logWithArgs("DEBUG", arguments); }; - -// log at the specified level with args -function logWithArgs(level, args) { - args = [level].concat([].slice.call(args)); - logger.logLevel.apply(logger, args); -} - -// return the correct formatString for an object -function formatStringForMessage(message) { - return (typeof message === "string") ? "" : "%o"; -} - -/** - * Logs a message at the specified level. - * - * Parameters passed after message are used applied to - * the message with utils.format() - */ -logger.logLevel = function(level /* , ... */) { - // format the message with the parameters - var formatArgs = [].slice.call(arguments, 1); - var fmtString = formatStringForMessage(formatArgs[0]); - if (fmtString.length > 0){ - formatArgs.unshift(fmtString); // add formatString - } - - var message = logger.format.apply(logger.format, formatArgs); - - if (LevelsMap[level] === null) { - throw new Error("invalid logging level: " + level); - } - - if (LevelsMap[level] > CurrentLevel) return; - - // queue the message if not yet at deviceready - if (!DeviceReady && !UseConsole) { - Queued.push([level, message]); - return; - } - - // Log using the native logger if that is enabled - if (UseLogger) { - exec(null, null, "Console", "logLevel", [level, message]); - } - - // Log using the console if that is enabled - if (UseConsole) { - // make sure console is not using logger - if (console.useLogger()) { - throw new Error("console and logger are too intertwingly"); - } - - // log to the console - switch (level) { - case logger.LOG: originalConsole.log(message); break; - case logger.ERROR: originalConsole.log("ERROR: " + message); break; - case logger.WARN: originalConsole.log("WARN: " + message); break; - case logger.INFO: originalConsole.log("INFO: " + message); break; - case logger.DEBUG: originalConsole.log("DEBUG: " + message); break; - } - } -}; - - -/** - * Formats a string and arguments following it ala console.log() - * - * Any remaining arguments will be appended to the formatted string. - * - * for rationale, see FireBug's Console API: - * http://getfirebug.com/wiki/index.php/Console_API - */ -logger.format = function(formatString, args) { - return __format(arguments[0], [].slice.call(arguments,1)).join(' '); -}; - - -//------------------------------------------------------------------------------ -/** - * Formats a string and arguments following it ala vsprintf() - * - * format chars: - * %j - format arg as JSON - * %o - format arg as JSON - * %c - format arg as '' - * %% - replace with '%' - * any other char following % will format it's - * arg via toString(). - * - * Returns an array containing the formatted string and any remaining - * arguments. - */ -function __format(formatString, args) { - if (formatString === null || formatString === undefined) return [""]; - if (arguments.length == 1) return [formatString.toString()]; - - if (typeof formatString != "string") - formatString = formatString.toString(); - - var pattern = /(.*?)%(.)(.*)/; - var rest = formatString; - var result = []; - - while (args.length) { - var match = pattern.exec(rest); - if (!match) break; - - var arg = args.shift(); - rest = match[3]; - result.push(match[1]); - - if (match[2] == '%') { - result.push('%'); - args.unshift(arg); - continue; - } - - result.push(__formatted(arg, match[2])); - } - - result.push(rest); - - var remainingArgs = [].slice.call(args); - remainingArgs.unshift(result.join('')); - return remainingArgs; -} - -function __formatted(object, formatChar) { - - try { - switch(formatChar) { - case 'j': - case 'o': return JSON.stringify(object); - case 'c': return ''; - } - } - catch (e) { - return "error JSON.stringify()ing argument: " + e; - } - - if ((object === null) || (object === undefined)) { - return Object.prototype.toString.call(object); - } - - return object.toString(); -} - - -//------------------------------------------------------------------------------ -// when deviceready fires, log queued messages -logger.__onDeviceReady = function() { - if (DeviceReady) return; - - DeviceReady = true; - - for (var i=0; i<Queued.length; i++) { - var messageArgs = Queued[i]; - logger.logLevel(messageArgs[0], messageArgs[1]); - } - - Queued = null; -}; - -// add a deviceready event to log queued messages -document.addEventListener("deviceready", logger.__onDeviceReady, false); diff --git a/plugins/org.apache.cordova.device/CONTRIBUTING.md b/plugins/org.apache.cordova.device/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/org.apache.cordova.device/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/org.apache.cordova.device/LICENSE b/plugins/org.apache.cordova.device/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/org.apache.cordova.device/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/NOTICE b/plugins/org.apache.cordova.device/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/org.apache.cordova.device/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/org.apache.cordova.device/README.md b/plugins/org.apache.cordova.device/README.md deleted file mode 100644 index 5158f6f2..00000000 --- a/plugins/org.apache.cordova.device/README.md +++ /dev/null @@ -1,22 +0,0 @@ -<!--- - license: 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. ---> - -# org.apache.cordova.device - -Plugin documentation: [doc/index.md](doc/index.md) diff --git a/plugins/org.apache.cordova.device/RELEASENOTES.md b/plugins/org.apache.cordova.device/RELEASENOTES.md deleted file mode 100644 index 12288b2c..00000000 --- a/plugins/org.apache.cordova.device/RELEASENOTES.md +++ /dev/null @@ -1,98 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.2.1 (Sept 5, 2013) -* removed extraneous print statement -* [CB-4432] copyright notice change - -### 0.2.3 (Sept 25, 2013) -* CB-4889 bumping&resetting version -* [windows8] commandProxy has moved -* [BlackBerry10] removed uneeded permission tags in plugin.xml -* CB-4889 renaming org.apache.cordova.core.device to org.apache.cordova.device -* Rename CHANGELOG.md -> RELEASENOTES.md -* updated to use commandProxy for ffos -* add firefoxos support -* [CB-4752] Incremented plugin version on dev branch. - -### 0.2.4 (Oct 28, 2013) -* CB-5128: added repo + issue tag in plugin.xml for device plugin -* CB-5085 device.cordova returning wrong value -* [CB-4915] Incremented plugin version on dev branch. - -### 0.2.5 (Dec 4, 2013) -* CB-5316 Spell Cordova as a brand unless it's a command or script -* [ubuntu] use cordova/exec/proxy -* add ubuntu platform -* Modify Device.platform logic to use amazon-fireos as the platform for Amazon Devices -* 1. Added amazon-fireos platform. 2. Change to use cordova-amazon-fireos as the platform if user agent contains 'cordova-amazon-fireos' - -### 0.2.6 (Jan 02, 2014) -* CB-5658 Add doc/index.md for Device plugin -* CB-5504 Moving Telephony Logic out of Device - -### 0.2.7 (Jan 07, 2014) -* CB-5737 Fix exception on close caused by left over telephony code from CB-5504 - -### 0.2.8 (Feb 05, 2014) -* Tizen support added - -### 0.2.9 (Apr 17, 2014) -* CB-5105: [Android, windows8, WP, BlackBerry10] Removed dead code for device.version -* CB-6422: [windows8] use cordova/exec/proxy -* CB-6460: Update license headers -* Add NOTICE file - -### 0.2.10 (Jun 05, 2014) -* CB-6127 Spanish and French Translations added. Github close #12 -* Changing 1.5 to 2.0 -* added firefoxos version - conversion -* added firefoxos version -* CB-6800 Add license -* CB-6491 add CONTRIBUTING.md - -### 0.2.11 (Aug 06, 2014) -* [FFOS] update DeviceProxy.js -* CB-6127 Updated translations for docs -* Use Windows system calls to get better info - -### 0.2.12 (Sep 17, 2014) -* CB-7471 cordova-plugin-device documentation translation -* CB-7552 device.name docs have not been removed -* [fxos] Fix cordova version -* added status box and documentation to manual tests -* [fxos] Fix cordova version -* added status box and documentation to manual tests -* Added plugin support for the browser -* CB-7262 Adds support for universal windows apps. - -### 0.2.13 (Dec 02, 2014) -* Changing `device.platform` to always report the platform as "browser". -* CB-5892 - Remove deprecated `window.Settings` -* CB-7700 cordova-plugin-device documentation translation: cordova-plugin-device -* CB-7571 Bump version of nested plugin to match parent plugin - -### 0.3.0 (Feb 04, 2015) -* Added device.manufacturer property for Android, iOS, Blackberry, WP8 -* Support for Windows Phone 8 ANID2 ANID is only supported up to Windows Phone 7.5 -* CB-8351 Use a local copy of uniqueAppInstanceIdentifier rather than CordovaLib's version -* browser: Fixed a bug that caused an "cannot call method of undefined" error if the browser's user agent wasn't recognized diff --git a/plugins/org.apache.cordova.device/doc/de/index.md b/plugins/org.apache.cordova.device/doc/de/index.md deleted file mode 100644 index f51618e5..00000000 --- a/plugins/org.apache.cordova.device/doc/de/index.md +++ /dev/null @@ -1,206 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -Dieses Plugin definiert eine globale `device` -Objekt, das des Geräts Hard- und Software beschreibt. Das Objekt im globalen Gültigkeitsbereich ist es zwar nicht verfügbar bis nach dem `deviceready` Ereignis. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## Installation - - cordova plugin add org.apache.cordova.device - - -## Eigenschaften - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -Rufen Sie die Version von Cordova, die auf dem Gerät ausgeführt. - -### Unterstützte Plattformen - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Browser -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 und 8 -* Windows 8 - -## device.model - -Die `device.model` gibt den Namen der Modell- oder des Geräts zurück. Der Wert wird vom Gerätehersteller festgelegt und kann zwischen den Versionen des gleichen Produkts unterschiedlich sein. - -### Unterstützte Plattformen - -* Android -* BlackBerry 10 -* Browser -* iOS -* Tizen -* Windows Phone 7 und 8 -* Windows 8 - -### Kurzes Beispiel - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Finden Sie unter http://theiphonewiki.com/wiki/index.php?title=Models / / Var-Modell = device.model; - - -### Android Eigenarten - -* Ruft den [Produktname][1] anstelle des [Modellnamens][2], das ist oft der Codename für die Produktion. Beispielsweise das Nexus One gibt `Passion` , und Motorola Droid gibt`voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Tizen Macken - -* Gibt z. B. das Gerätemodell von dem Kreditor zugeordnet,`TIZEN` - -### Windows Phone 7 und 8 Eigenarten - -* Gibt das vom Hersteller angegebenen Gerätemodell zurück. Beispielsweise gibt der Samsung-Fokus`SGH-i917`. - -## device.platform - -Name des Betriebssystems des Geräts zu erhalten. - - var string = device.platform; - - -### Unterstützte Plattformen - -* Android -* BlackBerry 10 -* Browser4 -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 und 8 -* Windows 8 - -### Kurzes Beispiel - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 Macken - -Windows Phone 7 Geräte melden die Plattform als`WinCE`. - -### Windows Phone 8 Macken - -Windows Phone 8 Geräte melden die Plattform als`Win32NT`. - -## device.uuid - -Des Geräts Universally Unique Identifier ([UUID][3] zu erhalten). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### Beschreibung - -Die Details wie eine UUID generiert wird werden vom Gerätehersteller und beziehen sich auf die Plattform oder das Modell des Geräts. - -### Unterstützte Plattformen - -* Android -* BlackBerry 10 -* iOS -* Tizen -* Windows Phone 7 und 8 -* Windows 8 - -### Kurzes Beispiel - - / / Android: wird eine zufällige 64-Bit-Ganzzahl (als Zeichenfolge, wieder!) / / die ganze Zahl wird beim ersten Start des Geräts erzeugt / / / / BlackBerry: gibt die PIN-Nummer des Gerätes / / Dies ist eine neunstellige eindeutige Ganzzahl (als String, obwohl!) / / / / iPhone: (paraphrasiert aus der Dokumentation zur UIDevice-Klasse) / / liefert eine Reihe von Hash-Werte, die aus mehreren Hardware erstellt identifiziert. - / / Es ist gewährleistet, dass für jedes Gerät eindeutig sein und kann nicht gebunden werden / / an den Benutzer weitergeleitet. - / / Windows Phone 7: gibt einen Hash des Gerät + aktueller Benutzer, / / wenn der Benutzer nicht definiert ist, eine Guid generiert und wird weiter bestehen, bis die app deinstalliert wird / / Tizen: gibt das Gerät IMEI (International Mobile Equipment Identity oder IMEI ist eine Zahl / / einzigartig für jedes GSM- und UMTS-Handy. - var deviceID = device.uuid; - - -### iOS Quirk - -Die `uuid` auf iOS ist nicht eindeutig zu einem Gerät, aber für jede Anwendung, für jede Installation variiert. Es ändert sich, wenn Sie löschen und neu die app installieren, und möglicherweise auch beim iOS zu aktualisieren, oder auch ein Upgrade möglich die app pro Version (scheinbaren in iOS 5.1). Die `uuid` ist kein zuverlässiger Wert. - -### Windows Phone 7 und 8 Eigenarten - -Die `uuid` für Windows Phone 7 die Berechtigung erfordert `ID_CAP_IDENTITY_DEVICE` . Microsoft wird diese Eigenschaft wahrscheinlich bald abzuschaffen. Wenn die Funktion nicht verfügbar ist, generiert die Anwendung eine persistente Guid, die für die Dauer der Installation der Anwendung auf dem Gerät gewährleistet ist. - -## device.version - -Version des Betriebssystems zu erhalten. - - var string = device.version; - - -### Unterstützte Plattformen - -* Android 2.1 + -* BlackBerry 10 -* Browser -* iOS -* Tizen -* Windows Phone 7 und 8 -* Windows 8 - -### Kurzes Beispiel - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/es/index.md b/plugins/org.apache.cordova.device/doc/es/index.md deleted file mode 100644 index 9c9eb38d..00000000 --- a/plugins/org.apache.cordova.device/doc/es/index.md +++ /dev/null @@ -1,220 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -Este plugin define un global `device` objeto que describe del dispositivo hardware y software. Aunque el objeto está en el ámbito global, no está disponible hasta después de la `deviceready` evento. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## Instalación - - cordova plugin add org.apache.cordova.device - - -## Propiedades - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -Obtener la versión de Cordova que se ejecuta en el dispositivo. - -### Plataformas soportadas - -* Amazon fire OS -* Android -* BlackBerry 10 -* Explorador -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 y 8 -* Windows 8 - -## device.model - -El `device.model` devuelve el nombre de modelo del dispositivo o producto. El valor es fijado por el fabricante del dispositivo y puede ser diferente a través de versiones del mismo producto. - -### Plataformas soportadas - -* Android -* BlackBerry 10 -* Explorador -* iOS -* Tizen -* Windows Phone 7 y 8 -* Windows 8 - -### Ejemplo rápido - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models - // - var model = device.model; - - -### Rarezas Android - -* Obtiene el [nombre del producto][1] en lugar del [nombre de la modelo][2], que es a menudo el nombre de código de producción. Por ejemplo, el Nexus One devuelve `Passion` y Motorola Droid devuelve `voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Rarezas Tizen - -* Devuelve que el modelo de dispositivo asignado por el proveedor, por ejemplo, `TIZEN` - -### Windows Phone 7 y 8 rarezas - -* Devuelve el modelo de dispositivo especificado por el fabricante. Por ejemplo, el Samsung Focus devuelve `SGH-i917`. - -## device.platform - -Obtener el nombre del sistema operativo del dispositivo. - - var string = device.platform; - - -### Plataformas soportadas - -* Android -* BlackBerry 10 -* Browser4 -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 y 8 -* Windows 8 - -### Ejemplo rápido - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 rarezas - -Dispositivos Windows Phone 7 informe de la plataforma como `WinCE`. - -### Windows Phone 8 rarezas - -Dispositivos Windows Phone 8 Informe la plataforma como `Win32NT`. - -## device.uuid - -Obtener identificador universalmente única del dispositivo ([UUID][3]). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### Descripción - -Los detalles de cómo se genera un UUID son determinados por el fabricante del dispositivo y son específicos a la plataforma del dispositivo o modelo. - -### Plataformas soportadas - -* Android -* BlackBerry 10 -* iOS -* Tizen -* Windows Phone 7 y 8 -* Windows 8 - -### Ejemplo rápido - - // Android: devuelve un entero de 64 bits al azar (como una cadena, otra vez!) - // el entero es generado en el primer arranque del dispositivo - // - // BlackBerry: devuelve el número PIN del dispositivo - // este es un entero único de nueve dígitos (como una cadena, aunque!) - // - // iPhone: (parafraseado de la documentación de la clase UIDevice) - // devuelve una cadena de valores hash creado a partir - // de múltiples hardware identifica. - / / Está garantizado para ser único para cada dispositivo y no puede ser atado / / a la cuenta de usuario. - // Windows Phone 7: devuelve un hash de dispositivo + usuario actual, - // si el usuario no está definido, un guid generado y persistirá hasta que se desinstala la aplicación - // - // Tizen: devuelve el dispositivo IMEI (identidad de equipo móvil internacional o IMEI es un número - // único para cada teléfono móvil GSM y UMTS. - var deviceID = device.uuid; - - -### iOS chanfle - -El `uuid` en iOS no es exclusiva de un dispositivo, pero varía para cada aplicación, para cada instalación. Cambia si puedes borrar y volver a instalar la aplicación, y posiblemente también cuándo actualizar iOS, o incluso mejorar la aplicación por la versión (evidente en iOS 5.1). El `uuid` no es un valor confiable. - -### Windows Phone 7 y 8 rarezas - -El `uuid` para Windows Phone 7 requiere el permiso `ID_CAP_IDENTITY_DEVICE`. Microsoft pronto probablemente desaprueban esta propiedad. Si la capacidad no está disponible, la aplicación genera un guid persistente que se mantiene durante la duración de la instalación de la aplicación en el dispositivo. - -## device.version - -Obtener la versión del sistema operativo. - - var string = device.version; - - -### Plataformas soportadas - -* Android 2.1 + -* BlackBerry 10 -* Explorador -* iOS -* Tizen -* Windows Phone 7 y 8 -* Windows 8 - -### Ejemplo rápido - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. el Mango se vuelve 7.10.7720 - // Tizen: devuelve "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/fr/index.md b/plugins/org.apache.cordova.device/doc/fr/index.md deleted file mode 100644 index 472fda53..00000000 --- a/plugins/org.apache.cordova.device/doc/fr/index.md +++ /dev/null @@ -1,218 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -Ce plugin définit un global `device` objet qui décrit le matériel et les logiciels de l'appareil. Bien que l'objet est dans la portée globale, il n'est pas disponible jusqu'après la `deviceready` événement. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## Installation - - cordova plugin add org.apache.cordova.device - - -## Propriétés - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -Retourne la version de Cordova en cours d'exécution sur l'appareil. - -### Plates-formes prises en charge - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Navigateur -* Firefox OS -* iOS -* Paciarelli -* Windows Phone 7 et 8 -* Windows 8 - -## device.model - -L'objet `device.model` retourne le nom du modèle de l'appareil/produit. Cette valeur est définie par le fabricant du périphérique et peut varier entre les différentes versions d'un même produit. - -### Plates-formes prises en charge - -* Android -* BlackBerry 10 -* Navigateur -* iOS -* Paciarelli -* Windows Phone 7 et 8 -* Windows 8 - -### Petit exemple - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Voir http://theiphonewiki.com/wiki/index.php?title=Models - // - var model = device.model; - - -### Quirks Android - -* Retourne le [nom du produit][1] au lieu du [nom du modèle][2], ce qui équivaut souvent au nom de code de production. Par exemple, `Passion` pour le Nexus One et `voles` pour le Motorola Droid. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Bizarreries de paciarelli - -* Retourne le modèle du dispositif, assigné par le vendeur, par exemple `TIZEN` - -### Windows Phone 7 et 8 Quirks - -* Retourne le modèle de l'appareil spécifié par le fabricant. Par exemple `SGH-i917` pour le Samsung Focus. - -## device.platform - -Obtenir le nom de système d'exploitation de l'appareil. - - var string = device.platform; - - -### Plates-formes prises en charge - -* Android -* BlackBerry 10 -* Browser4 -* Firefox OS -* iOS -* Paciarelli -* Windows Phone 7 et 8 -* Windows 8 - -### Petit exemple - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 Quirks - -Appareils Windows Phone 7 rapport de la plate-forme comme`WinCE`. - -### Notes au sujet de Windows Phone 8 - -Appareils Windows Phone 8 rapport de la plate-forme comme`Win32NT`. - -## device.uuid - -Obtenir Universally Unique Identifier de l'appareil ([UUID][3]). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### Description - -Les détails de comment un UUID généré sont déterminées par le fabricant du périphérique et sont spécifiques à la plate-forme ou le modèle de l'appareil. - -### Plates-formes prises en charge - -* Android -* BlackBerry 10 -* iOS -* Paciarelli -* Windows Phone 7 et 8 -* Windows 8 - -### Petit exemple - - // Android : retourne un nombre entier 64-bit aléatoire (sous la forme d'une chaîne de caractères, encore !) - // Ce nombre entier est généré lors du premier démarrage de l'appareil - // - // BlackBerry : retourne le numéro PIN de l'appareil - // Il s'agit d'un nombre entier unique à neuf chiffres (sous la forme d'une chaîne de caractères cependant !) - // - // iPhone : (copié depuis la documentation de la classe UIDevice) - // Retourne une chaîne de caractères générée à partir de plusieurs caractéristiques matérielles. - / / Il est garanti pour être unique pour chaque appareil et ne peut pas être lié / / pour le compte d'utilisateur. - // Windows Phone 7 : retourne un hashage généré à partir de appareil+utilisateur actuel, - // si aucun utilisateur n'est défini, un guid est généré persistera jusqu'à ce que l'application soit désinstallée - // Tizen : retourne le numéro IMEI (International Mobile Equipment Identity) de l'appareil, ce numéro est - // unique pour chaque téléphone GSM et UMTS. - var deviceID = device.uuid; - - -### Spécificités iOS - -Le `uuid` sur iOS n'est pas propre à un périphérique, mais varie pour chaque application, pour chaque installation. Elle change si vous supprimez, puis réinstallez l'application, et éventuellement aussi quand vous mettre à jour d'iOS, ou même mettre à jour le soft par version (apparent dans iOS 5.1). Le `uuid` n'est pas une valeur fiable. - -### Windows Phone 7 et 8 Quirks - -Le `uuid` pour Windows Phone 7 requiert l'autorisation `ID_CAP_IDENTITY_DEVICE` . Microsoft va probablement bientôt obsolète de cette propriété. Si la capacité n'est pas disponible, l'application génère un guid persistant qui est maintenu pendant toute la durée de l'installation de l'application sur le périphérique. - -## device.version - -Téléchargez la version de système d'exploitation. - - var string = device.version; - - -### Plates-formes prises en charge - -* Android 2.1+ -* BlackBerry 10 -* Navigateur -* iOS -* Paciarelli -* Windows Phone 7 et 8 -* Windows 8 - -### Petit exemple - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/index.md b/plugins/org.apache.cordova.device/doc/index.md deleted file mode 100644 index b3acc9f6..00000000 --- a/plugins/org.apache.cordova.device/doc/index.md +++ /dev/null @@ -1,218 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -This plugin defines a global `device` object, which describes the device's hardware and software. -Although the object is in the global scope, it is not available until after the `deviceready` event. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - -## Installation - - cordova plugin add org.apache.cordova.device - -## Properties - -- device.cordova -- device.model -- device.platform -- device.uuid -- device.version - -## device.cordova - -Get the version of Cordova running on the device. - -### Supported Platforms - -- Amazon Fire OS -- Android -- BlackBerry 10 -- Browser -- Firefox OS -- iOS -- Tizen -- Windows Phone 7 and 8 -- Windows 8 - -## device.model - -The `device.model` returns the name of the device's model or -product. The value is set by the device manufacturer and may be -different across versions of the same product. - -### Supported Platforms - -- Android -- BlackBerry 10 -- Browser -- iOS -- Tizen -- Windows Phone 7 and 8 -- Windows 8 - -### Quick Example - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models - // - var model = device.model; - -### Android Quirks - -- Gets the [product name](http://developer.android.com/reference/android/os/Build.html#PRODUCT) instead of the [model name](http://developer.android.com/reference/android/os/Build.html#MODEL), which is often the production code name. For example, the Nexus One returns `Passion`, and Motorola Droid returns `voles`. - -### Tizen Quirks - -- Returns the device model assigned by the vendor, for example, `TIZEN` - -### Windows Phone 7 and 8 Quirks - -- Returns the device model specified by the manufacturer. For example, the Samsung Focus returns `SGH-i917`. - -## device.platform - -Get the device's operating system name. - - var string = device.platform; - -### Supported Platforms - -- Android -- BlackBerry 10 -- Browser4 -- Firefox OS -- iOS -- Tizen -- Windows Phone 7 and 8 -- Windows 8 - -### Quick Example - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - -### Windows Phone 7 Quirks - -Windows Phone 7 devices report the platform as `WinCE`. - -### Windows Phone 8 Quirks - -Windows Phone 8 devices report the platform as `Win32NT`. - -## device.uuid - -Get the device's Universally Unique Identifier ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)). - - var string = device.uuid; - -### Description - -The details of how a UUID is generated are determined by the device manufacturer and are specific to the device's platform or model. - -### Supported Platforms - -- Android -- BlackBerry 10 -- iOS -- Tizen -- Windows Phone 7 and 8 -- Windows 8 - -### Quick Example - - // Android: Returns a random 64-bit integer (as a string, again!) - // The integer is generated on the device's first boot - // - // BlackBerry: Returns the PIN number of the device - // This is a nine-digit unique integer (as a string, though!) - // - // iPhone: (Paraphrased from the UIDevice Class documentation) - // Returns a string of hash values created from multiple hardware identifies. - // It is guaranteed to be unique for every device and can't be tied - // to the user account. - // Windows Phone 7 : Returns a hash of device+current user, - // if the user is not defined, a guid is generated and will persist until the app is uninstalled - // Tizen: returns the device IMEI (International Mobile Equipment Identity or IMEI is a number - // unique to every GSM and UMTS mobile phone. - var deviceID = device.uuid; - -### iOS Quirk - -The `uuid` on iOS is not unique to a device, but varies for each -application, for each installation. It changes if you delete and -re-install the app, and possibly also when you upgrade iOS, or even -upgrade the app per version (apparent in iOS 5.1). The `uuid` is not -a reliable value. - -### Windows Phone 7 and 8 Quirks - -The `uuid` for Windows Phone 7 requires the permission -`ID_CAP_IDENTITY_DEVICE`. Microsoft will likely deprecate this -property soon. If the capability is not available, the application -generates a persistent guid that is maintained for the duration of the -application's installation on the device. - -## device.version - -Get the operating system version. - - var string = device.version; - -### Supported Platforms - -- Android 2.1+ -- BlackBerry 10 -- Browser -- iOS -- Tizen -- Windows Phone 7 and 8 -- Windows 8 - -### Quick Example - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version; - diff --git a/plugins/org.apache.cordova.device/doc/it/index.md b/plugins/org.apache.cordova.device/doc/it/index.md deleted file mode 100644 index 0414dc6f..00000000 --- a/plugins/org.apache.cordova.device/doc/it/index.md +++ /dev/null @@ -1,206 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -Questo plugin definisce un global `device` oggetto che descrive il dispositivo hardware e software. Sebbene l'oggetto sia in ambito globale, non è disponibile fino a dopo il `deviceready` evento. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## Installazione - - cordova plugin add org.apache.cordova.device - - -## Proprietà - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -Ottenere la versione di Cordova in esecuzione nel dispositivo. - -### Piattaforme supportate - -* Amazon fuoco OS -* Android -* BlackBerry 10 -* Browser -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 e 8 -* Windows 8 - -## device.model - -Il `device.model` restituisce il nome del modello del dispositivo o del prodotto. Il valore viene impostato dal produttore del dispositivo e può essere differente tra le versioni dello stesso prodotto. - -### Piattaforme supportate - -* Android -* BlackBerry 10 -* Browser -* iOS -* Tizen -* Windows Phone 7 e 8 -* Windows 8 - -### Esempio rapido - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Vedi http://theiphonewiki.com/wiki/index.php?title=Models / / modello var = device.model; - - -### Stranezze Android - -* Ottiene il [nome del prodotto][1] anziché il [nome del modello][2], che è spesso il nome di codice di produzione. Ad esempio, restituisce il Nexus One `Passion` , e Motorola Droid restituisce`voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Tizen stranezze - -* Restituisce il modello di dispositivo assegnato dal fornitore, ad esempio,`TIZEN` - -### Windows Phone 7 e 8 stranezze - -* Restituisce il modello di dispositivo specificato dal produttore. Ad esempio, restituisce il Samsung Focus`SGH-i917`. - -## device.platform - -Ottenere il nome del sistema operativo del dispositivo. - - var string = device.platform; - - -### Piattaforme supportate - -* Android -* BlackBerry 10 -* Browser4 -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 e 8 -* Windows 8 - -### Esempio rapido - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 capricci - -Windows Phone 7 dispositivi segnalano la piattaforma come`WinCE`. - -### Windows Phone 8 stranezze - -Dispositivi Windows Phone 8 segnalano la piattaforma come`Win32NT`. - -## device.uuid - -Ottenere identificatore del dispositivo univoco universale ([UUID][3]). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### Descrizione - -I dettagli di come viene generato un UUID sono determinati dal produttore del dispositivo e sono specifici per la piattaforma o il modello del dispositivo. - -### Piattaforme supportate - -* Android -* BlackBerry 10 -* iOS -* Tizen -* Windows Phone 7 e 8 -* Windows 8 - -### Esempio rapido - - / / Android: restituisce un intero casuale di 64 bit (come stringa, ancora una volta!) / / il numero intero è generato al primo avvio del dispositivo / / / / BlackBerry: restituisce il numero PIN del dispositivo / / questo è un valore integer univoco a nove cifre (come stringa, benchè!) / / / / iPhone: (parafrasato dalla documentazione della classe UIDevice) / / restituisce una stringa di valori hash creata dall'hardware più identifica. - / / È garantito per essere unica per ogni dispositivo e non può essere legato / / per l'account utente. - / / Windows Phone 7: restituisce un hash dell'utente corrente, + dispositivo / / se l'utente non è definito, un guid generato e persisterà fino a quando l'applicazione viene disinstallata / / Tizen: restituisce il dispositivo IMEI (International Mobile Equipment Identity o IMEI è un numero / / unico per ogni cellulare GSM e UMTS. - var deviceID = device.uuid; - - -### iOS Quirk - -Il `uuid` su iOS non è univoco per un dispositivo, ma varia per ogni applicazione, per ogni installazione. Cambia se si elimina e re-installare l'app, e possibilmente anche quando aggiornare iOS o anche aggiornare l'app per ogni versione (apparente in iOS 5.1). Il `uuid` non è un valore affidabile. - -### Windows Phone 7 e 8 stranezze - -Il `uuid` per Windows Phone 7 richiede l'autorizzazione `ID_CAP_IDENTITY_DEVICE` . Microsoft probabilmente sarà presto deprecare questa proprietà. Se la funzionalità non è disponibile, l'applicazione genera un guid persistente che viene mantenuto per la durata dell'installazione dell'applicazione sul dispositivo. - -## device.version - -Ottenere la versione del sistema operativo. - - var string = device.version; - - -### Piattaforme supportate - -* Android 2.1 + -* BlackBerry 10 -* Browser -* iOS -* Tizen -* Windows Phone 7 e 8 -* Windows 8 - -### Esempio rapido - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/ja/index.md b/plugins/org.apache.cordova.device/doc/ja/index.md deleted file mode 100644 index ee447202..00000000 --- a/plugins/org.apache.cordova.device/doc/ja/index.md +++ /dev/null @@ -1,206 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -このプラグインをグローバル定義します `device` オブジェクトは、デバイスのハードウェアとソフトウェアについて説明します。 それは後まで利用可能なオブジェクトがグローバル スコープでは、 `deviceready` イベント。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## インストール - - cordova plugin add org.apache.cordova.device - - -## プロパティ - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -デバイスで実行されているコルドバのバージョンを取得します。 - -### サポートされているプラットフォーム - -* アマゾン火 OS -* アンドロイド -* ブラックベリー 10 -* ブラウザー -* Firefox の OS -* iOS -* Tizen -* Windows Phone 7 と 8 -* Windows 8 - -## device.model - -`device.model`、デバイスのモデルまたは製品の名前を返します。値は、デバイスの製造元によって設定され、同じ製品のバージョン間で異なる可能性があります。 - -### サポートされているプラットフォーム - -* アンドロイド -* ブラックベリー 10 -* ブラウザー -* iOS -* Tizen -* Windows Phone 7 と 8 -* Windows 8 - -### 簡単な例 - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Http://theiphonewiki.com/wiki/index.php?title=Models を参照してください//var モデル = device.model; - - -### Android の癖 - -* 生産コード名は[モデル名][1]の代わりに[製品名][2]を取得します。 たとえば、ネクサス 1 つを返します `Passion` 、Motorola のドロイドを返します`voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#MODEL - [2]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - -### Tizen の癖 - -* たとえば、ベンダーによって割り当てられているデバイスのモデルを返します`TIZEN` - -### Windows Phone 7 と 8 癖 - -* 製造元によって指定されたデバイスのモデルを返します。たとえば、三星フォーカスを返します`SGH-i917`. - -## device.platform - -デバイスのオペレーティング システム名を取得します。 - - var string = device.platform; - - -### サポートされているプラットフォーム - -* アンドロイド -* ブラックベリー 10 -* Browser4 -* Firefox の OS -* iOS -* Tizen -* Windows Phone 7 と 8 -* Windows 8 - -### 簡単な例 - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 の癖 - -Windows Phone 7 デバイスとプラットフォームを報告します。`WinCE`. - -### Windows Phone 8 癖 - -Windows Phone 8 デバイスとプラットフォームを報告します。`Win32NT`. - -## device.uuid - -デバイスのユニバーサル ・ ユニーク識別子 ([UUID][3]を取得します。). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### 説明 - -UUID を生成する方法の詳細は、デバイスの製造元によって決定され、デバイスのプラットフォームやモデルに固有です。 - -### サポートされているプラットフォーム - -* アンドロイド -* ブラックベリー 10 -* iOS -* Tizen -* Windows Phone 7 と 8 -* Windows 8 - -### 簡単な例 - - //アンドロイド: ランダムな 64 ビットの整数 (を文字列として返します、再び !)/デバイスの最初の起動時に生成される整数/////ブラックベリー: デバイスのピン番号を返します//これは 9 桁の一意な整数 (を文字列としても !)////iPhone: (UIDevice クラスのドキュメントから言い換え)//識別複数のハードウェアから作成されたハッシュ値の文字列を返します。。 - //それはすべてのデバイスに対して一意であることが保証され、接続することはできません//ユーザー アカウント。 - //Windows Phone 7: デバイス + 現在のユーザーのハッシュを返します//ユーザーが定義されていない場合 guid が生成され、アプリがアンインストールされるまで保持されます//Tizen: デバイスの IMEI を返します (国際モバイル機器アイデンティティまたは IMEI は番号です//すべての GSM および UMTS の携帯電話に固有です。 - var deviceID = device.uuid; - - -### iOS の気まぐれ - -`uuid`IOS で、デバイスに固有ではないインストールごと、アプリケーションごとに異なります。 削除、アプリを再インストールした場合に変更と多分またときアップグレード iOS の, またはもアップグレードするアプリ (iOS の 5.1 で明らかに) バージョンごと。 `uuid`は信頼性の高い値ではありません。 - -### Windows Phone 7 と 8 癖 - -`uuid`のために Windows Phone 7 には、権限が必要です `ID_CAP_IDENTITY_DEVICE` 。 Microsoft はすぐにこのプロパティを廃止して可能性があります。 機能が利用できない場合、アプリケーションはデバイスへのアプリケーションのインストールの持続期間のために保持されている永続的な guid を生成します。 - -## device.version - -オペレーティング システムのバージョンを取得します。 - - var string = device.version; - - -### サポートされているプラットフォーム - -* アンドロイド 2.1 + -* ブラックベリー 10 -* ブラウザー -* iOS -* Tizen -* Windows Phone 7 と 8 -* Windows 8 - -### 簡単な例 - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/ko/index.md b/plugins/org.apache.cordova.device/doc/ko/index.md deleted file mode 100644 index af44d40a..00000000 --- a/plugins/org.apache.cordova.device/doc/ko/index.md +++ /dev/null @@ -1,206 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -이 플러그인 정의 전역 `device` 개체, 디바이스의 하드웨어 및 소프트웨어에 설명 합니다. 개체는 전역 범위에서 비록 그것은 후까지 사용할 수 있는 `deviceready` 이벤트. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## 설치 - - cordova plugin add org.apache.cordova.device - - -## 속성 - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -코르도바는 장치에서 실행 중인 버전을 얻을. - -### 지원 되는 플랫폼 - -* 아마존 화재 운영 체제 -* 안 드 로이드 -* 블랙베리 10 -* 브라우저 -* Firefox 운영 체제 -* iOS -* Tizen -* Windows Phone 7과 8 -* 윈도우 8 - -## device.model - -`device.model`소자의 모델 또는 제품의 이름을 반환 합니다. 값 장치 제조업체에서 설정 되 고 동일 제품의 버전 간에 다를 수 있습니다. - -### 지원 되는 플랫폼 - -* 안 드 로이드 -* 블랙베리 10 -* 브라우저 -* iOS -* Tizen -* Windows Phone 7과 8 -* 윈도우 8 - -### 빠른 예제 - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Http://theiphonewiki.com/wiki/index.php?title=Models 참조 / / var 모델 = device.model; - - -### 안 드 로이드 단점 - -* 어떤은 종종 프로덕션 코드 이름 대신 [제품 모델 이름][1], [제품 이름][2] 을 가져옵니다. 예를 들어 넥서스 하나 반환 합니다 `Passion` , 모토로라 Droid를 반환 합니다`voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#MODEL - [2]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - -### Tizen 특수 - -* 예를 들어, 공급 업체에 의해 할당 된 디바이스 모델을 반환 합니다.`TIZEN` - -### Windows Phone 7, 8 특수 - -* 제조업체에서 지정 하는 장치 모델을 반환 합니다. 예를 들어 삼성 포커스를 반환 합니다.`SGH-i917`. - -## device.platform - -장치의 운영 체제 이름을 얻을. - - var string = device.platform; - - -### 지원 되는 플랫폼 - -* 안 드 로이드 -* 블랙베리 10 -* Browser4 -* Firefox 운영 체제 -* iOS -* Tizen -* Windows Phone 7과 8 -* 윈도우 8 - -### 빠른 예제 - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 단점 - -Windows Phone 7 장치 보고 플랫폼으로`WinCE`. - -### Windows Phone 8 단점 - -Windows Phone 8 장치 보고 플랫폼으로`Win32NT`. - -## device.uuid - -소자의 보편적으로 고유 식별자 ([UUID][3] 를 얻을합니다). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### 설명 - -UUID 생성 방법의 자세한 내용은 장치 제조업체에 의해 결정 됩니다 및 소자의 플랫폼 이나 모델. - -### 지원 되는 플랫폼 - -* 안 드 로이드 -* 블랙베리 10 -* iOS -* Tizen -* Windows Phone 7과 8 -* 윈도우 8 - -### 빠른 예제 - - / / 안 드 로이드: (문자열로 다시!) 임의의 64 비트 정수를 반환 합니다 / / 정수 장치의 첫 번째 부팅에서 생성 / / / / 블랙베리: 디바이스의 핀 번호를 반환 합니다 / / 이것은 9 자리 고유 정수 (문자열로 비록!) / / / / 아이폰: (UIDevice 클래스 설명서에서 읊 었) / / 문자열 여러 하드웨어에서 생성 하는 해시 값을 식별 하는 반환 합니다. - / 그것은 모든 장치에 대 한 고유 해야 보장 되 고 묶일 수 없습니다 / / / 사용자 계정에. - / / Windows Phone 7: 장치 + 현재 사용자의 해시를 반환 합니다 / / 사용자 정의 되지 않은 경우 guid 생성 되 고 응용 프로그램을 제거할 때까지 유지 됩니다 / / Tizen: 반환 장치 IMEI (국제 모바일 기기 식별 또는 IMEI 숫자입니다 / / 모든 GSM와 UMTS 휴대 전화 고유. - var deviceID = device.uuid; - - -### iOS 특질 - -`uuid`ios 장치에 고유 하지 않습니다 하지만 각 설치에 대 한 응용 프로그램 마다 다릅니다. 삭제 하 고 다시 애플 리 케이 션을 설치 하는 경우 변경 가능 하 게 또한 iOS를 업그레이드 하거나 때 버전 (iOS 5.1에에서 명백한) 당 응용 프로그램 업그레이드도 하 고. `uuid`은 신뢰할 수 있는 값이 아닙니다. - -### Windows Phone 7, 8 특수 - -`uuid`Windows Phone 7 필요 허가 `ID_CAP_IDENTITY_DEVICE` . Microsoft는 곧이 속성을 세웁니다 가능성이 것입니다. 기능을 사용할 수 없는 경우 응용 프로그램 장치에 응용 프로그램의 설치 하는 동안 유지 하는 영구 guid를 생성 합니다. - -## device.version - -운영 체제 버전을 얻을. - - var string = device.version; - - -### 지원 되는 플랫폼 - -* 안 드 로이드 2.1 + -* 블랙베리 10 -* 브라우저 -* iOS -* Tizen -* Windows Phone 7과 8 -* 윈도우 8 - -### 빠른 예제 - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/pl/index.md b/plugins/org.apache.cordova.device/doc/pl/index.md deleted file mode 100644 index 3806d050..00000000 --- a/plugins/org.apache.cordova.device/doc/pl/index.md +++ /dev/null @@ -1,206 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -Ten plugin określa globalne `device` obiekt, który opisuje urządzenia sprzętowe i programowe. Mimo, że obiekt jest w globalnym zasięgu, nie jest dostępne dopiero po `deviceready` zdarzenie. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## Instalacja - - cordova plugin add org.apache.cordova.device - - -## Właściwości - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -Pobierz wersję Cordova działa na urządzeniu. - -### Obsługiwane platformy - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Przeglądarka -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 i 8 -* Windows 8 - -## device.model - -`device.model`Zwraca nazwę modelu lub produktu. Wartość jest zestaw przez producenta urządzenia i mogą się różnić między wersjami tego samego produktu. - -### Obsługiwane platformy - -* Android -* BlackBerry 10 -* Przeglądarka -* iOS -* Tizen -* Windows Phone 7 i 8 -* Windows 8 - -### Szybki przykład - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. Zobacz http://theiphonewiki.com/wiki/index.php?title=Models / / modelu var = device.model; - - -### Dziwactwa Androida - -* Pobiera [nazwę produktu][1] zamiast [nazwy modelu][2], który często jest nazwą kod produkcji. Na przykład, Nexus One zwraca `Passion` , i zwraca Motorola Droid`voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Dziwactwa Tizen - -* Zwraca modelu urządzenia przypisane przez dostawcę, na przykład,`TIZEN` - -### Windows Phone 7 i 8 dziwactwa - -* Zwraca modelu urządzenia, określonej przez producenta. Na przykład Samsung ostrości zwraca`SGH-i917`. - -## device.platform - -Uzyskać nazwę systemu operacyjnego urządzenia. - - var string = device.platform; - - -### Obsługiwane platformy - -* Android -* BlackBerry 10 -* Browser4 -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 i 8 -* Windows 8 - -### Szybki przykład - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Dziwactwa Windows Phone 7 - -Urządzenia Windows Phone 7 raport platformy jako`WinCE`. - -### Windows Phone 8 dziwactwa - -Urządzenia Windows Phone 8 raport platformy jako`Win32NT`. - -## device.uuid - -Się urządzenia uniwersalnie unikatowy identyfikator ([UUID][3]). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### Opis - -Szczegóły jak UUID jest generowane są określane przez producenta urządzenia i są specyficzne dla platformy lub modelu urządzenia. - -### Obsługiwane platformy - -* Android -* BlackBerry 10 -* iOS -* Tizen -* Windows Phone 7 i 8 -* Windows 8 - -### Szybki przykład - - / / Android: zwraca losowe 64-bitowa liczba całkowita (jako ciąg, znowu!) / / liczba całkowita jest generowany na pierwszego uruchomienia urządzenia / / / / BlackBerry: zwraca numer PIN urządzenia / / to jest unikatową liczbą całkowitą dziewięciu cyfr (jako ciąg, choć!) / / / / iPhone: (zacytowana w dokumentacji klasy UIDevice) / / zwraca ciąg wartości mieszania utworzone z wielu sprzętu identyfikuje. - Zapewniona jest unikatowy dla każdego urządzenia i nie może być związane z / do konta użytkownika. - / / Windows Phone 7: zwraca wartość mieszania urządzenia + bieżący użytkownik, / / jeśli nie zdefiniowane przez użytkownika, identyfikator guid jest generowany i będzie trwać do czasu odinstalowania aplikacji / / Tizen: zwraca urządzenia IMEI (International Mobile Equipment Identity lub IMEI jest liczbą / / unikatowe dla każdego telefonu komórkowego GSM i UMTS. - var deviceID = device.uuid; - - -### iOS dziwactwo - -`uuid`Na iOS nie jest przypisany do urządzenia, ale różni się dla każdej aplikacji, dla każdej instalacji. Zmienia się jeśli możesz usunąć i ponownie zainstalować aplikację, a ewentualnie także po aktualizacji iOS czy nawet uaktualnienia aplikacji dla wersji (widoczny w iOS 5.1). `uuid`Jest nie wiarygodne wartości. - -### Windows Phone 7 i 8 dziwactwa - -`uuid`Dla Windows Phone 7 wymaga uprawnień `ID_CAP_IDENTITY_DEVICE` . Microsoft będzie prawdopodobnie potępiać ten wkrótce. Jeśli funkcja nie jest dostępna, aplikacja generuje trwałe identyfikator guid, który jest utrzymywany przez czas trwania instalacji aplikacji na urządzeniu. - -## device.version - -Pobierz wersję systemu operacyjnego. - - var string = device.version; - - -### Obsługiwane platformy - -* Android 2.1 + -* BlackBerry 10 -* Przeglądarka -* iOS -* Tizen -* Windows Phone 7 i 8 -* Windows 8 - -### Szybki przykład - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/ru/index.md b/plugins/org.apache.cordova.device/doc/ru/index.md deleted file mode 100644 index c0195748..00000000 --- a/plugins/org.apache.cordova.device/doc/ru/index.md +++ /dev/null @@ -1,219 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -Этот плагин определяет глобальный объект `device`, который описывает оборудование и программное обеспечение устройства. Несмотря на то что объект в глобальной области видимости, он не доступен до того момента пока не произойдет событие `deviceready`. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## Установка - - cordova plugin add org.apache.cordova.device - - -## Параметры - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -Возвращает версию Cordova, работающую на устройстве. - -### Поддерживаемые платформы - -* Amazon Fire OS -* Android -* BlackBerry 10 -* Обозреватель -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 и 8 -* Windows 8 - -## device.model - -Свойство `device.model` возвращает имя устройства модели или продукта. Значение устанавливается производителем устройства и могут отличаться в разных версиях одного и того же продукта. - -### Поддерживаемые платформы - -* Android -* BlackBerry 10 -* Обозреватель -* iOS -* Tizen -* Windows Phone 7 и 8 -* Windows 8 - -### Краткий пример - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models - // - var model = device.model; - - -### Особенности Android - -* Возвращает [имя продукта][1] , а не [имя модели][2], которое часто является производственным кодом. Например, Nexus One из них возвращает `Passion` , и Motorola Droid возвращает `voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Особенности Tizen - -* Возвращает модель устройства, назначенного вендором, например,`TIZEN` - -### Особенности Windows Phone 7 и 8 - -* Возвращает модель устройства, указанной заводом-изготовителем. Например Samsung Focus возвращает `SGH-i917`. - -## device.platform - -Получите имя операционной системы устройства. - - var string = device.platform; - - -### Поддерживаемые платформы - -* Android -* BlackBerry 10 -* Браузером4 -* Firefox OS -* iOS -* Tizen -* Windows Phone 7 и 8 -* Windows 8 - -### Краткий пример - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Особенности Windows Phone 7 - -Windows Phone 7 устройства сообщают платформу как `WinCE`. - -### Особенности Windows Phone 8 - -Устройства Windows Phone 8 сообщают платформу как `Win32NT`. - -## device.uuid - -Возвращает универсальный уникального идентификатора ([UUID][3] устройства). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### Описание - -Подробная информация о том как UUID генерируется, определяются изготовителем устройства и являются специфическими для платформы или модели устройства. - -### Поддерживаемые платформы - -* Android -* BlackBerry 10 -* iOS -* Tizen -* Windows Phone 7 и 8 -* Windows 8 - -### Краткий пример - - // Android: Возвращает случайное 64-разрядное целое число (в виде строки, опять!) - // целое число генерируется при первой загрузке устройства - // - // BlackBerry: Возвращает номер PIN устройства - // это 9 значный уникальный целочисленный (как строка, хотя!) - // - // iPhone: (Перефразировано из документации класса UIDevice) - // возвращает строку хэш-значения, созданные из нескольких аппаратных определяет. - // Это значение гарантированно является уникальным для каждого устройства и не может быть привязано - // к учетной записи пользователя. - // Windows Phone 7: Возвращает хэш устройство + текущего пользователя, - // если пользователь не определен, формируется guid который и будет сохраняться до тех пор, пока приложение не удалиться - // Tizen: возвращает IMEI устройства (Международный идентификатор мобильного оборудования или IMEI это число - // уникальное для каждого мобильного телефона GSM и UMTS. - var deviceID = device.uuid; - - -### Особенности iOS - -На iOS `uuid` не является уникальным для устройства, но варьируется для каждого приложения, и для каждой установки. Значение меняется, если удалить и повторно установить приложение, и возможно также когда вы обновите iOS, или даже обновить приложение до следующей версии (очевидно в iOS 5.1). Значение `uuid` не является надежным. - -### Особенности Windows Phone 7 и 8 - -Для Windows Phone 7 `uuid` требует разрешения `ID_CAP_IDENTITY_DEVICE` . Microsoft скорее всего скоро сделает это свойство устаревшим. Если возможность недоступна, приложение создает постоянные guid, который сохраняется на все время установки приложения на устройстве. - -## device.version - -Возвращает версию операционной системы. - - var string = device.version; - - -### Поддерживаемые платформы - -* Android 2.1 + -* BlackBerry 10 -* Обозреватель -* iOS -* Tizen -* Windows Phone 7 и 8 -* Windows 8 - -### Краткий пример - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/doc/zh/index.md b/plugins/org.apache.cordova.device/doc/zh/index.md deleted file mode 100644 index 58818a85..00000000 --- a/plugins/org.apache.cordova.device/doc/zh/index.md +++ /dev/null @@ -1,206 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.device - -這個外掛程式定義全球 `device` 物件,描述該設備的硬體和軟體。 雖然物件是在全球範圍內,但不是可用,直到後 `deviceready` 事件。 - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(device.cordova); - } - - -## 安裝 - - cordova plugin add org.apache.cordova.device - - -## 屬性 - -* device.cordova -* device.model -* device.platform -* device.uuid -* device.version - -## device.cordova - -獲取科爾多瓦在設備上運行的版本。 - -### 支援的平臺 - -* 亞馬遜火 OS -* Android 系統 -* 黑莓 10 -* 瀏覽器 -* 火狐瀏覽器的作業系統 -* iOS -* 泰 -* Windows Phone 7 和 8 -* Windows 8 - -## device.model - -`device.model`返回設備的模型或產品的名稱。值由設備製造商設置和同一產品的不同版本可能不同。 - -### 支援的平臺 - -* Android 系統 -* 黑莓 10 -* 瀏覽器 -* iOS -* 泰 -* Windows Phone 7 和 8 -* Windows 8 - -### 快速的示例 - - // Android: Nexus One returns "Passion" (Nexus One code name) - // Motorola Droid returns "voles" - // BlackBerry: Torch 9800 returns "9800" - // Browser: Google Chrome returns "Chrome" - // Safari returns "Safari" - // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. 請參閱 HTTP://theiphonewiki.com/wiki/index.php?title=Models / / var 模型 = device.model ; - - -### Android 的怪癖 - -* 獲取[產品名稱][1]而不是[產品型號名稱][2],這往往是生產代碼名稱。 例如,Nexus One 返回 `Passion` ,和摩托羅拉 Droid 返回`voles`. - - [1]: http://developer.android.com/reference/android/os/Build.html#PRODUCT - [2]: http://developer.android.com/reference/android/os/Build.html#MODEL - -### Tizen 怪癖 - -* 例如,返回與供應商指派的設備模型`TIZEN` - -### Windows Phone 7 和 8 怪癖 - -* 返回由製造商指定的設備模型。例如,三星焦點返回`SGH-i917`. - -## device.platform - -獲取設備的作業系統名稱。 - - var string = device.platform; - - -### 支援的平臺 - -* Android 系統 -* 黑莓 10 -* Browser4 -* 火狐瀏覽器的作業系統 -* iOS -* 泰 -* Windows Phone 7 和 8 -* Windows 8 - -### 快速的示例 - - // Depending on the device, a few examples are: - // - "Android" - // - "BlackBerry 10" - // - Browser: returns "MacIntel" on Mac - // returns "Win32" on Windows - // - "iOS" - // - "WinCE" - // - "Tizen" - var devicePlatform = device.platform; - - -### Windows Phone 7 的怪癖 - -Windows Phone 7 設備報告作為平臺`WinCE`. - -### Windows Phone 8 怪癖 - -Windows Phone 8 設備報告作為平臺`Win32NT`. - -## device.uuid - -獲取設備的通用唯一識別碼 ([UUID][3]). - - [3]: http://en.wikipedia.org/wiki/Universally_Unique_Identifier - - var string = device.uuid; - - -### 說明 - -如何生成一個 UUID 的細節由設備製造商和特定于設備的平臺或模型。 - -### 支援的平臺 - -* Android 系統 -* 黑莓 10 -* iOS -* Tizen -* Windows Phone 7 和 8 -* Windows 8 - -### 快速的示例 - - / / Android: 一個隨機的 64 位整數 (作為字串返回,再次!) / / 上設備的第一次啟動生成的整數 / / / / 黑莓手機: 返回設備的 PIN 號碼 / / 這是九個數字的唯一整數 (作為字串,雖然!) / / / / iPhone: (從 UIDevice 類文檔解釋) / / 返回一個字串的雜湊值創建的多個硬體標識。 - / / 它保證是唯一的每個設備並不能綁 / / 到使用者帳戶。 - / / Windows Phone 7: 返回的雜湊代碼的設備 + 當前使用者,/ / 如果未定義使用者,則一個 guid 生成的並且將會保留直到卸載該應用程式 / / Tizen: 返回設備 IMEI (國際行動裝置身份或 IMEI 是一個數位 / / 獨有的每一個 UMTS 和 GSM 行動電話。 - var deviceID = device.uuid; - - -### iOS 怪癖 - -`uuid`在 iOS 不是唯一的一種裝置,但對於每個應用程式,為每個安裝而異。 如果您刪除並重新安裝該應用程式,它更改和可能還當你升級 iOS,或甚至升級每個版本 (iOS 5.1 中存在明顯的) 的應用程式。 `uuid`不是一個可靠的值。 - -### Windows Phone 7 和 8 怪癖 - -`uuid`為 Windows Phone 7 須經許可 `ID_CAP_IDENTITY_DEVICE` 。 Microsoft 可能會很快棄用此屬性。 如果沒有可用的能力,應用程式將生成設備上應用程式的安裝過程中保持持續的 guid。 - -## device.version - -獲取作業系統版本。 - - var string = device.version; - - -### 支援的平臺 - -* Android 2.1 + -* 黑莓 10 -* 瀏覽器 -* iOS -* 泰 -* Windows Phone 7 和 8 -* Windows 8 - -### 快速的示例 - - // Android: Froyo OS would return "2.2" - // Eclair OS would return "2.1", "2.0.1", or "2.0" - // Version can also return update level "2.1-update1" - // - // BlackBerry: Torch 9800 using OS 6.0 would return "6.0.0.600" - // - // Browser: Returns version number for the browser - // - // iPhone: iOS 3.2 returns "3.2" - // - // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720 - // Tizen: returns "TIZEN_20120425_2" - var deviceVersion = device.version;
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/package.json b/plugins/org.apache.cordova.device/package.json deleted file mode 100644 index b2036819..00000000 --- a/plugins/org.apache.cordova.device/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "version": "0.3.0", - "name": "org.apache.cordova.device", - "cordova_name": "Device", - "description": "Cordova Device Plugin", - "license": "Apache 2.0", - "repo": "https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git", - "issue": "https://issues.apache.org/jira/browse/CB/component/12320648", - "keywords": [ - "cordova", - "device" - ], - "platforms": [ - "firefoxos", - "tizen", - "android", - "amazon-fireos", - "ubuntu", - "ios", - "blackberry10", - "wp7", - "wp8", - "windows8", - "windows", - "browser" - ], - "engines": [], - "englishdoc": "<!---\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership. The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License. You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied. See the License for the\n specific language governing permissions and limitations\n under the License.\n-->\n\n# org.apache.cordova.device\n\nThis plugin defines a global `device` object, which describes the device's hardware and software.\nAlthough the object is in the global scope, it is not available until after the `deviceready` event.\n\n document.addEventListener(\"deviceready\", onDeviceReady, false);\n function onDeviceReady() {\n console.log(device.cordova);\n }\n\n## Installation\n\n cordova plugin add org.apache.cordova.device\n\n## Properties\n\n- device.cordova\n- device.model\n- device.platform\n- device.uuid\n- device.version\n\n## device.cordova\n\nGet the version of Cordova running on the device.\n\n### Supported Platforms\n\n- Amazon Fire OS\n- Android\n- BlackBerry 10\n- Browser\n- Firefox OS\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n\n## device.model\n\nThe `device.model` returns the name of the device's model or\nproduct. The value is set by the device manufacturer and may be\ndifferent across versions of the same product.\n\n### Supported Platforms\n\n- Android\n- BlackBerry 10\n- Browser\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n\n### Quick Example\n\n // Android: Nexus One returns \"Passion\" (Nexus One code name)\n // Motorola Droid returns \"voles\"\n // BlackBerry: Torch 9800 returns \"9800\"\n // Browser: Google Chrome returns \"Chrome\"\n // Safari returns \"Safari\"\n // iOS: for the iPad Mini, returns iPad2,5; iPhone 5 is iPhone 5,1. See http://theiphonewiki.com/wiki/index.php?title=Models\n //\n var model = device.model;\n\n### Android Quirks\n\n- Gets the [product name](http://developer.android.com/reference/android/os/Build.html#PRODUCT) instead of the [model name](http://developer.android.com/reference/android/os/Build.html#MODEL), which is often the production code name. For example, the Nexus One returns `Passion`, and Motorola Droid returns `voles`.\n\n### Tizen Quirks\n\n- Returns the device model assigned by the vendor, for example, `TIZEN`\n\n### Windows Phone 7 and 8 Quirks\n\n- Returns the device model specified by the manufacturer. For example, the Samsung Focus returns `SGH-i917`.\n\n## device.platform\n\nGet the device's operating system name.\n\n var string = device.platform;\n\n### Supported Platforms\n\n- Android\n- BlackBerry 10\n- Browser4\n- Firefox OS\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n\n### Quick Example\n\n // Depending on the device, a few examples are:\n // - \"Android\"\n // - \"BlackBerry 10\"\n // - Browser: returns \"MacIntel\" on Mac\n // returns \"Win32\" on Windows\n // - \"iOS\"\n // - \"WinCE\"\n // - \"Tizen\"\n var devicePlatform = device.platform;\n\n### Windows Phone 7 Quirks\n\nWindows Phone 7 devices report the platform as `WinCE`.\n\n### Windows Phone 8 Quirks\n\nWindows Phone 8 devices report the platform as `Win32NT`.\n\n## device.uuid\n\nGet the device's Universally Unique Identifier ([UUID](http://en.wikipedia.org/wiki/Universally_Unique_Identifier)).\n\n var string = device.uuid;\n\n### Description\n\nThe details of how a UUID is generated are determined by the device manufacturer and are specific to the device's platform or model.\n\n### Supported Platforms\n\n- Android\n- BlackBerry 10\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n\n### Quick Example\n\n // Android: Returns a random 64-bit integer (as a string, again!)\n // The integer is generated on the device's first boot\n //\n // BlackBerry: Returns the PIN number of the device\n // This is a nine-digit unique integer (as a string, though!)\n //\n // iPhone: (Paraphrased from the UIDevice Class documentation)\n // Returns a string of hash values created from multiple hardware identifies.\n // It is guaranteed to be unique for every device and can't be tied\n // to the user account.\n // Windows Phone 7 : Returns a hash of device+current user,\n // if the user is not defined, a guid is generated and will persist until the app is uninstalled\n // Tizen: returns the device IMEI (International Mobile Equipment Identity or IMEI is a number\n // unique to every GSM and UMTS mobile phone.\n var deviceID = device.uuid;\n\n### iOS Quirk\n\nThe `uuid` on iOS is not unique to a device, but varies for each\napplication, for each installation. It changes if you delete and\nre-install the app, and possibly also when you upgrade iOS, or even\nupgrade the app per version (apparent in iOS 5.1). The `uuid` is not\na reliable value.\n\n### Windows Phone 7 and 8 Quirks\n\nThe `uuid` for Windows Phone 7 requires the permission\n`ID_CAP_IDENTITY_DEVICE`. Microsoft will likely deprecate this\nproperty soon. If the capability is not available, the application\ngenerates a persistent guid that is maintained for the duration of the\napplication's installation on the device.\n\n## device.version\n\nGet the operating system version.\n\n var string = device.version;\n\n### Supported Platforms\n\n- Android 2.1+\n- BlackBerry 10\n- Browser\n- iOS\n- Tizen\n- Windows Phone 7 and 8\n- Windows 8\n\n### Quick Example\n\n // Android: Froyo OS would return \"2.2\"\n // Eclair OS would return \"2.1\", \"2.0.1\", or \"2.0\"\n // Version can also return update level \"2.1-update1\"\n //\n // BlackBerry: Torch 9800 using OS 6.0 would return \"6.0.0.600\"\n //\n // Browser: Returns version number for the browser\n //\n // iPhone: iOS 3.2 returns \"3.2\"\n //\n // Windows Phone 7: returns current OS version number, ex. on Mango returns 7.10.7720\n // Tizen: returns \"TIZEN_20120425_2\"\n var deviceVersion = device.version;\n\n" -}
\ No newline at end of file diff --git a/plugins/org.apache.cordova.device/plugin.xml b/plugins/org.apache.cordova.device/plugin.xml deleted file mode 100644 index c5052880..00000000 --- a/plugins/org.apache.cordova.device/plugin.xml +++ /dev/null @@ -1,168 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:rim="http://www.blackberry.com/ns/widgets" - xmlns:android="http://schemas.android.com/apk/res/android" - id="org.apache.cordova.device" - version="0.3.0"> - <name>Device</name> - <description>Cordova Device Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,device</keywords> - <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git</repo> - <issue>https://issues.apache.org/jira/browse/CB/component/12320648</issue> - - <js-module src="www/device.js" name="device"> - <clobbers target="device" /> - </js-module> - - <!-- firefoxos --> - <platform name="firefoxos"> - <config-file target="config.xml" parent="/*"> - <feature name="Device"> - <param name="firefoxos-package" value="Device" /> - </feature> - </config-file> - - <js-module src="src/firefoxos/DeviceProxy.js" name="DeviceProxy"> - <runs /> - </js-module> - </platform> - - <!-- tizen --> - <platform name="tizen"> - <js-module src="src/tizen/DeviceProxy.js" name="DeviceProxy"> - <runs /> - </js-module> - </platform> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Device" > - <param name="android-package" value="org.apache.cordova.device.Device"/> - </feature> - </config-file> - - <source-file src="src/android/Device.java" target-dir="src/org/apache/cordova/device" /> - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Device" > - <param name="android-package" value="org.apache.cordova.device.Device"/> - </feature> - </config-file> - - <source-file src="src/android/Device.java" target-dir="src/org/apache/cordova/device" /> - </platform> - - <!-- ubuntu --> - <platform name="ubuntu"> - <header-file src="src/ubuntu/device.h" /> - <source-file src="src/ubuntu/device.cpp" /> - <js-module src="src/ubuntu/device.js" name="DeviceProxy"> - <merges target="device" /> - </js-module> - </platform> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="Device"> - <param name="ios-package" value="CDVDevice"/> - </feature> - </config-file> - - <header-file src="src/ios/CDVDevice.h" /> - <source-file src="src/ios/CDVDevice.m" /> - </platform> - - <!-- blackberry10 --> - <platform name="blackberry10"> - <source-file src="src/blackberry10/index.js" target-dir="Device" /> - <config-file target="www/config.xml" parent="/widget"> - <feature name="Device" value="Device"/> - </config-file> - <config-file target="www/config.xml" parent="/widget/rim:permissions"> - <rim:permit>read_device_identifying_information</rim:permit> - </config-file> - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="config.xml" parent="/*"> - <feature name="Device"> - <param name="wp-package" value="Device"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_IDENTITY_DEVICE" /> - </config-file> - - <source-file src="src/wp/Device.cs" /> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="Device"> - <param name="wp-package" value="Device"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_IDENTITY_DEVICE" /> - </config-file> - - <source-file src="src/wp/Device.cs" /> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="src/windows8/DeviceProxy.js" name="DeviceProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- windows --> - <platform name="windows"> - <js-module src="src/windows/DeviceProxy.js" name="DeviceProxy"> - <merges target="" /> - </js-module> - </platform> - - <!-- browser --> - <platform name="browser"> - <config-file target="config.xml" parent="/*"> - <feature name="Device"> - <param name="browser-package" value="Device" /> - </feature> - </config-file> - - <js-module src="src/browser/DeviceProxy.js" name="DeviceProxy"> - <runs /> - </js-module> - </platform> - -</plugin> diff --git a/plugins/org.apache.cordova.device/src/android/Device.java b/plugins/org.apache.cordova.device/src/android/Device.java deleted file mode 100644 index 5eded907..00000000 --- a/plugins/org.apache.cordova.device/src/android/Device.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.device; - -import java.util.TimeZone; - -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaInterface; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.provider.Settings; - -public class Device extends CordovaPlugin { - public static final String TAG = "Device"; - - public static String platform; // Device OS - public static String uuid; // Device UUID - - private static final String ANDROID_PLATFORM = "Android"; - private static final String AMAZON_PLATFORM = "amazon-fireos"; - private static final String AMAZON_DEVICE = "Amazon"; - - /** - * Constructor. - */ - public Device() { - } - - /** - * Sets the context of the Command. This can then be used to do things like - * get file paths associated with the Activity. - * - * @param cordova The context of the main Activity. - * @param webView The CordovaWebView Cordova is running in. - */ - public void initialize(CordovaInterface cordova, CordovaWebView webView) { - super.initialize(cordova, webView); - Device.uuid = getUuid(); - } - - /** - * Executes the request and returns PluginResult. - * - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackContext The callback id used when calling back into JavaScript. - * @return True if the action was valid, false if not. - */ - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - if (action.equals("getDeviceInfo")) { - JSONObject r = new JSONObject(); - r.put("uuid", Device.uuid); - r.put("version", this.getOSVersion()); - r.put("platform", this.getPlatform()); - r.put("model", this.getModel()); - r.put("manufacturer", this.getManufacturer()); - callbackContext.success(r); - } - else { - return false; - } - return true; - } - - //-------------------------------------------------------------------------- - // LOCAL METHODS - //-------------------------------------------------------------------------- - - /** - * Get the OS name. - * - * @return - */ - public String getPlatform() { - String platform; - if (isAmazonDevice()) { - platform = AMAZON_PLATFORM; - } else { - platform = ANDROID_PLATFORM; - } - return platform; - } - - /** - * Get the device's Universally Unique Identifier (UUID). - * - * @return - */ - public String getUuid() { - String uuid = Settings.Secure.getString(this.cordova.getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); - return uuid; - } - - public String getModel() { - String model = android.os.Build.MODEL; - return model; - } - - public String getProductName() { - String productname = android.os.Build.PRODUCT; - return productname; - } - - public String getManufacturer() { - String manufacturer = android.os.Build.MANUFACTURER; - return manufacturer; - } - /** - * Get the OS version. - * - * @return - */ - public String getOSVersion() { - String osversion = android.os.Build.VERSION.RELEASE; - return osversion; - } - - public String getSDKVersion() { - @SuppressWarnings("deprecation") - String sdkversion = android.os.Build.VERSION.SDK; - return sdkversion; - } - - public String getTimeZoneID() { - TimeZone tz = TimeZone.getDefault(); - return (tz.getID()); - } - - /** - * Function to check if the device is manufactured by Amazon - * - * @return - */ - public boolean isAmazonDevice() { - if (android.os.Build.MANUFACTURER.equals(AMAZON_DEVICE)) { - return true; - } - return false; - } - -} diff --git a/plugins/org.apache.cordova.device/src/blackberry10/index.js b/plugins/org.apache.cordova.device/src/blackberry10/index.js deleted file mode 100644 index 77f25a9e..00000000 --- a/plugins/org.apache.cordova.device/src/blackberry10/index.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * - * 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. - * -*/ - -function getModelName () { - var modelName = window.qnx.webplatform.device.modelName; - //Pre 10.2 (meaning Z10 or Q10) - if (typeof modelName === "undefined") { - if (window.screen.height === 720 && window.screen.width === 720) { - if ( window.matchMedia("(-blackberry-display-technology: -blackberry-display-oled)").matches) { - modelName = "Q10"; - } else { - modelName = "Q5"; - } - } else if ((window.screen.height === 1280 && window.screen.width === 768) || - (window.screen.height === 768 && window.screen.width === 1280)) { - modelName = "Z10"; - } else { - modelName = window.qnx.webplatform.deviceName; - } - } - - return modelName; -} - -function getUUID () { - var uuid = ""; - try { - //Must surround by try catch because this will throw if the app is missing permissions - uuid = window.qnx.webplatform.device.devicePin; - } catch (e) { - //DO Nothing - } - return uuid; -} - -module.exports = { - getDeviceInfo: function (success, fail, args, env) { - var result = new PluginResult(args, env), - modelName = getModelName(), - uuid = getUUID(), - info = { - manufacturer: 'BlackBerry', - platform: "blackberry10", - version: window.qnx.webplatform.device.scmBundle, - model: modelName, - uuid: uuid - }; - - result.ok(info); - } -}; diff --git a/plugins/org.apache.cordova.device/src/browser/DeviceProxy.js b/plugins/org.apache.cordova.device/src/browser/DeviceProxy.js deleted file mode 100644 index fcaed20c..00000000 --- a/plugins/org.apache.cordova.device/src/browser/DeviceProxy.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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 browser = require('cordova/platform'); -var cordova = require('cordova'); - -function getPlatform() { - return "browser"; -} - -function getModel() { - return getBrowserInfo(true); -} - -function getVersion() { - return getBrowserInfo(false); -} - -function getBrowserInfo(getModel) { - var userAgent = navigator.userAgent; - var returnVal = ''; - - if ((offset = userAgent.indexOf('Chrome')) !== -1) { - returnVal = (getModel) ? 'Chrome' : userAgent.substring(offset + 7); - } else if ((offset = userAgent.indexOf('Safari')) !== -1) { - if (getModel) { - returnVal = 'Safari'; - } else { - returnVal = userAgent.substring(offset + 7); - - if ((offset = userAgent.indexOf('Version')) !== -1) { - returnVal = userAgent.substring(offset + 8); - } - } - } else if ((offset = userAgent.indexOf('Firefox')) !== -1) { - returnVal = (getModel) ? 'Firefox' : userAgent.substring(offset + 8); - } else if ((offset = userAgent.indexOf('MSIE')) !== -1) { - returnVal = (getModel) ? 'MSIE' : userAgent.substring(offset + 5); - } else if ((offset = userAgent.indexOf('Trident')) !== -1) { - returnVal = (getModel) ? 'MSIE' : '11'; - } - - if ((offset = returnVal.indexOf(';')) !== -1 || (offset = returnVal.indexOf(' ')) !== -1) { - returnVal = returnVal.substring(0, offset); - } - - return returnVal; -} - - -module.exports = { - getDeviceInfo: function (success, error) { - setTimeout(function () { - success({ - cordova: browser.cordovaVersion, - platform: getPlatform(), - model: getModel(), - version: getVersion(), - uuid: null - }); - }, 0); - } -}; - -require("cordova/exec/proxy").add("Device", module.exports); diff --git a/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js b/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js deleted file mode 100644 index 79f3a2b0..00000000 --- a/plugins/org.apache.cordova.device/src/firefoxos/DeviceProxy.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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. - * - */ -//example UA String for Firefox OS -//Mozilla/5.0 (Mobile; rv:26.0) Gecko/26.0 Firefox/26.0 -var firefoxos = require('cordova/platform'); -var cordova = require('cordova'); - -//UA parsing not recommended but currently this is the only way to get the Firefox OS version -//https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference - -//Should be replaced when better conversion to Firefox OS Version is available -function convertVersionNumber(ver) { - var hashVersion = { - '18.0': '1.0.1', - '18.1': '1.1', - '26.0': '1.2', - '28.0': '1.3', - '30.0': '1.4', - '32.0': '2.0' - }; - var rver = ver; - var sStr = ver.substring(0, 4); - if (hashVersion[sStr]) { - rver = hashVersion[sStr]; - } - return (rver); - -} -function getVersion() { - if (navigator.userAgent.match(/(mobile|tablet)/i)) { - var ffVersionArray = (navigator.userAgent.match(/Firefox\/([\d]+\.[\w]?\.?[\w]+)/)); - if (ffVersionArray.length === 2) { - return (convertVersionNumber(ffVersionArray[1])); - } - } - return (null); -} - -function getModel() { - var uaArray = navigator.userAgent.split(/\s*[;)(]\s*/); - if (navigator.userAgent.match(/(mobile|tablet)/i)) { - if (uaArray.length === 5) { - return (uaArray[2]); - } - } - return (null); -} -module.exports = { - getDeviceInfo: function (success, error) { - setTimeout(function () { - success({ - platform: 'firefoxos', - model: getModel(), - version: getVersion(), - uuid: null - }); - }, 0); - } -}; - -require("cordova/exec/proxy").add("Device", module.exports); diff --git a/plugins/org.apache.cordova.device/src/ios/CDVDevice.h b/plugins/org.apache.cordova.device/src/ios/CDVDevice.h deleted file mode 100644 index a146d882..00000000 --- a/plugins/org.apache.cordova.device/src/ios/CDVDevice.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> - -@interface CDVDevice : CDVPlugin -{} - -+ (NSString*)cordovaVersion; - -- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/org.apache.cordova.device/src/ios/CDVDevice.m b/plugins/org.apache.cordova.device/src/ios/CDVDevice.m deleted file mode 100644 index 5a3f4708..00000000 --- a/plugins/org.apache.cordova.device/src/ios/CDVDevice.m +++ /dev/null @@ -1,99 +0,0 @@ -/* - 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 <sys/types.h> -#include <sys/sysctl.h> - -#import <Cordova/CDV.h> -#import "CDVDevice.h" - -@implementation UIDevice (ModelVersion) - -- (NSString*)modelVersion -{ - size_t size; - - sysctlbyname("hw.machine", NULL, &size, NULL, 0); - char* machine = malloc(size); - sysctlbyname("hw.machine", machine, &size, NULL, 0); - NSString* platform = [NSString stringWithUTF8String:machine]; - free(machine); - - return platform; -} - -@end - -@interface CDVDevice () {} -@end - -@implementation CDVDevice - -- (NSString*)uniqueAppInstanceIdentifier:(UIDevice*)device -{ - NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; - static NSString* UUID_KEY = @"CDVUUID"; - - NSString* app_uuid = [userDefaults stringForKey:UUID_KEY]; - - if (app_uuid == nil) { - CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault); - CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef); - - app_uuid = [NSString stringWithString:(__bridge NSString*)uuidString]; - [userDefaults setObject:app_uuid forKey:UUID_KEY]; - [userDefaults synchronize]; - - CFRelease(uuidString); - CFRelease(uuidRef); - } - - return app_uuid; -} - -- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command -{ - NSDictionary* deviceProperties = [self deviceProperties]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:deviceProperties]; - - [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; -} - -- (NSDictionary*)deviceProperties -{ - UIDevice* device = [UIDevice currentDevice]; - NSMutableDictionary* devProps = [NSMutableDictionary dictionaryWithCapacity:4]; - - [devProps setObject:@"Apple" forKey:@"manufacturer"]; - [devProps setObject:[device modelVersion] forKey:@"model"]; - [devProps setObject:@"iOS" forKey:@"platform"]; - [devProps setObject:[device systemVersion] forKey:@"version"]; - [devProps setObject:[self uniqueAppInstanceIdentifier:device] forKey:@"uuid"]; - [devProps setObject:[[self class] cordovaVersion] forKey:@"cordova"]; - - NSDictionary* devReturn = [NSDictionary dictionaryWithDictionary:devProps]; - return devReturn; -} - -+ (NSString*)cordovaVersion -{ - return CDV_VERSION; -} - -@end diff --git a/plugins/org.apache.cordova.device/src/tizen/DeviceProxy.js b/plugins/org.apache.cordova.device/src/tizen/DeviceProxy.js deleted file mode 100644 index 2afc3243..00000000 --- a/plugins/org.apache.cordova.device/src/tizen/DeviceProxy.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * 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 tizen = require('cordova/platform'); -var cordova = require('cordova'); - -module.exports = { - getDeviceInfo: function(success, error) { - setTimeout(function () { - success({ - cordova: tizen.cordovaVersion, - platform: 'tizen', - model: null, - version: null, - uuid: null - }); - }, 0); - } -}; - -require("cordova/tizen/commandProxy").add("Device", module.exports); diff --git a/plugins/org.apache.cordova.device/src/ubuntu/device.cpp b/plugins/org.apache.cordova.device/src/ubuntu/device.cpp deleted file mode 100644 index eb5a012d..00000000 --- a/plugins/org.apache.cordova.device/src/ubuntu/device.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2011 Wolfgang Koller - http://www.gofg.at/ - * - * Licensed 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 <QDeviceInfo> -#include <QtSystemInfo> - -#include"device.h" - -#define CORDOVA "3.0.0" - -Device::Device(Cordova *cordova) : CPlugin(cordova) { -} - -static QString getOSName() { -#ifdef Q_OS_SYMBIAN - QString platform = "Symbian"; -#endif -#ifdef Q_OS_WIN - QString platform = "Windows"; -#endif -#ifdef Q_OS_WINCE - QString platform = "Windows CE"; -#endif -#ifdef Q_OS_LINUX - QString platform = "Linux"; -#endif - return platform; -} - -void Device::getInfo(int scId, int ecId) { - Q_UNUSED(ecId) - - QDeviceInfo systemDeviceInfo; - QDeviceInfo systemInfo; - - QString platform = getOSName(); - - QString uuid = systemDeviceInfo.uniqueDeviceID(); - if (uuid.isEmpty()) { - QString deviceDescription = systemInfo.imei(0) + ";" + systemInfo.manufacturer() + ";" + systemInfo.model() + ";" + systemInfo.productName() + ";" + platform; - QString user = qgetenv("USER"); - if (user.isEmpty()) { - user = qgetenv("USERNAME"); - if (user.isEmpty()) - user = QDir::homePath(); - } - uuid = QString(QCryptographicHash::hash((deviceDescription + ";" + user).toUtf8(), QCryptographicHash::Md5).toHex()); - } - - this->cb(scId, systemDeviceInfo.model(), CORDOVA, platform, uuid, systemInfo.version(QDeviceInfo::Os)); -} diff --git a/plugins/org.apache.cordova.device/src/ubuntu/device.h b/plugins/org.apache.cordova.device/src/ubuntu/device.h deleted file mode 100644 index 91cb9377..00000000 --- a/plugins/org.apache.cordova.device/src/ubuntu/device.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011 Wolfgang Koller - http://www.gofg.at/ - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DEVICE_H_FDSAFAS -#define DEVICE_H_FDSAFAS - -#include <QtCore> - -#include <cplugin.h> - -class Device: public CPlugin { - Q_OBJECT -public: - explicit Device(Cordova *cordova); - - virtual const QString fullName() override { - return Device::fullID(); - } - - virtual const QString shortName() override { - return "Device"; - } - - static const QString fullID() { - return "com.cordova.Device"; - } - -signals: - -public slots: - void getInfo(int scId, int ecId); -}; - -#endif diff --git a/plugins/org.apache.cordova.device/src/ubuntu/device.js b/plugins/org.apache.cordova.device/src/ubuntu/device.js deleted file mode 100644 index 3adb110b..00000000 --- a/plugins/org.apache.cordova.device/src/ubuntu/device.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * 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 cordova = require('cordova'); -var exec = require('cordova/exec'); - -module.exports = { - getInfo:function(win,fail,args) { - Cordova.exec(function (model, cordova, platform, uuid, version) { - win({name: name, model: model, cordova: cordova, - platform: platform, uuid: uuid, version: version}); - }, null, "com.cordova.Device", "getInfo", []); - } -}; - -require("cordova/exec/proxy").add("Device", module.exports); diff --git a/plugins/org.apache.cordova.device/src/windows/DeviceProxy.js b/plugins/org.apache.cordova.device/src/windows/DeviceProxy.js deleted file mode 100644 index 69ed4446..00000000 --- a/plugins/org.apache.cordova.device/src/windows/DeviceProxy.js +++ /dev/null @@ -1,108 +0,0 @@ -/* - * - * 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 ROOT_CONTAINER = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}"; -var DEVICE_CLASS_KEY = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10"; -var DEVICE_CLASS_KEY_NO_SEMICOLON = '{A45C254E-DF1C-4EFD-8020-67D146A850E0}10'; -var ROOT_CONTAINER_QUERY = "System.Devices.ContainerId:=\"" + ROOT_CONTAINER + "\""; -var HAL_DEVICE_CLASS = "4d36e966-e325-11ce-bfc1-08002be10318"; -var DEVICE_DRIVER_VERSION_KEY = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3"; -var MANU_KEY = "System.Devices.Manufacturer"; - -module.exports = { - - getDeviceInfo:function(win, fail, args) { - - // deviceId aka uuid, stored in Windows.Storage.ApplicationData.current.localSettings.values.deviceId - var deviceId; - var manufacturer = "unknown"; - - // get deviceId, or create and store one - var localSettings = Windows.Storage.ApplicationData.current.localSettings; - if (localSettings.values.deviceId) { - deviceId = localSettings.values.deviceId; - } - else { - // App-specific hardware id could be used as uuid, but it changes if the hardware changes... - try { - var ASHWID = Windows.System.Profile.HardwareIdentification.getPackageSpecificToken(null).id; - deviceId = Windows.Storage.Streams.DataReader.fromBuffer(ASHWID).readGuid(); - } catch (e) { - // Couldn't get the hardware UUID - deviceId = createUUID(); - } - //...so cache it per-install - localSettings.values.deviceId = deviceId; - } - - - var userAgent = window.clientInformation.userAgent; - // this will report "windows" in windows8.1 and windows phone 8.1 apps - // and "windows8" in windows 8.0 apps similar to cordova.js - // See https://github.com/apache/cordova-js/blob/master/src/windows/platform.js#L25 - var devicePlatform = userAgent.indexOf("MSAppHost/1.0") == -1 ? "windows" : "windows8"; - var versionString = userAgent.match(/Windows (?:Phone |NT )?([0-9.]+)/)[1]; - - - - var Pnp = Windows.Devices.Enumeration.Pnp; - - Pnp.PnpObject.findAllAsync(Pnp.PnpObjectType.deviceContainer,[MANU_KEY]) - .then(function (infoList) { - var numDevices = infoList.length; - if (numDevices) { - for (var i = 0; i < numDevices; i++) { - var devContainer = infoList[i]; - if (devContainer.id == ROOT_CONTAINER) { - manufacturer = devContainer.properties[MANU_KEY]; - break; - } - } - } - }) - .then(function () { - Pnp.PnpObject.findAllAsync(Pnp.PnpObjectType.device, - [DEVICE_DRIVER_VERSION_KEY, DEVICE_CLASS_KEY], - ROOT_CONTAINER_QUERY) - .then(function (rootDevices) { - for (var i = 0; i < rootDevices.length; i++) { - var rootDevice = rootDevices[i]; - if (!rootDevice.properties) continue; - if (rootDevice.properties[DEVICE_CLASS_KEY_NO_SEMICOLON] == HAL_DEVICE_CLASS) { - versionString = rootDevice.properties[DEVICE_DRIVER_VERSION_KEY]; - break; - } - } - - setTimeout(function () { - win({ platform: devicePlatform, - version: versionString, - uuid: deviceId, - model: window.clientInformation.platform, - manufacturer:manufacturer}); - }, 0); - }); - }); - } - -}; // exports - -require("cordova/exec/proxy").add("Device", module.exports); diff --git a/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js b/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js deleted file mode 100644 index 3ddc9b2b..00000000 --- a/plugins/org.apache.cordova.device/src/windows8/DeviceProxy.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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 cordova = require('cordova'); -var utils = require('cordova/utils'); - -module.exports = { - - getDeviceInfo:function(win,fail,args) { - - // deviceId aka uuid, stored in Windows.Storage.ApplicationData.current.localSettings.values.deviceId - var deviceId; - - var localSettings = Windows.Storage.ApplicationData.current.localSettings; - - if (localSettings.values.deviceId) { - deviceId = localSettings.values.deviceId; - } - else { - // App-specific hardware id could be used as uuid, but it changes if the hardware changes... - try { - var ASHWID = Windows.System.Profile.HardwareIdentification.getPackageSpecificToken(null).id; - deviceId = Windows.Storage.Streams.DataReader.fromBuffer(ASHWID).readGuid(); - } catch (e) { - // Couldn't get the hardware UUID - deviceId = createUUID(); - } - //...so cache it per-install - localSettings.values.deviceId = deviceId; - } - - var versionString = window.clientInformation.userAgent.match(/Windows NT ([0-9.]+)/)[1]; - - (function(self){ - var ROOT_CONTAINER = "{00000000-0000-0000-FFFF-FFFFFFFFFFFF}"; - var DEVICE_CLASS_KEY = "{A45C254E-DF1C-4EFD-8020-67D146A850E0},10"; - var DEVICE_CLASS_KEY_NO_SEMICOLON = '{A45C254E-DF1C-4EFD-8020-67D146A850E0}10'; - var ROOT_CONTAINER_QUERY = "System.Devices.ContainerId:=\"" + ROOT_CONTAINER + "\""; - var HAL_DEVICE_CLASS = "4d36e966-e325-11ce-bfc1-08002be10318"; - var DEVICE_DRIVER_VERSION_KEY = "{A8B865DD-2E3D-4094-AD97-E593A70C75D6},3"; - var pnpObject = Windows.Devices.Enumeration.Pnp.PnpObject; - pnpObject.findAllAsync(Windows.Devices.Enumeration.Pnp.PnpObjectType.device, [DEVICE_DRIVER_VERSION_KEY, DEVICE_CLASS_KEY], ROOT_CONTAINER_QUERY).then(function(rootDevices) { - - for (var i = 0; i < rootDevices.length; i++) { - var rootDevice = rootDevices[i]; - if (!rootDevice.properties) continue; - if (rootDevice.properties[DEVICE_CLASS_KEY_NO_SEMICOLON] == HAL_DEVICE_CLASS) { - versionString = rootDevice.properties[DEVICE_DRIVER_VERSION_KEY]; - break; - } - } - - setTimeout(function () { - win({ platform: "windows8", version: versionString, uuid: deviceId, model: window.clientInformation.platform }); - }, 0); - }); - })(this); - } - -}; - -require("cordova/exec/proxy").add("Device", module.exports); - diff --git a/plugins/org.apache.cordova.device/src/wp/Device.cs b/plugins/org.apache.cordova.device/src/wp/Device.cs deleted file mode 100644 index 897a35af..00000000 --- a/plugins/org.apache.cordova.device/src/wp/Device.cs +++ /dev/null @@ -1,135 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Net; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Documents; -using System.Windows.Ink; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; -using Microsoft.Phone.Info; -using System.IO.IsolatedStorage; -using System.Windows.Resources; -using System.IO; -using System.Diagnostics; - -namespace WPCordovaClassLib.Cordova.Commands -{ - public class Device : BaseCommand - { - public void getDeviceInfo(string notused) - { - - string res = String.Format("\"name\":\"{0}\",\"platform\":\"{1}\",\"uuid\":\"{2}\",\"version\":\"{3}\",\"model\":\"{4}\",\"manufacturer\":\"{5}\"", - this.name, - this.platform, - this.uuid, - this.version, - this.model, - this.manufacturer); - - res = "{" + res + "}"; - //Debug.WriteLine("Result::" + res); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res)); - } - - public string model - { - get - { - return DeviceStatus.DeviceName; - //return String.Format("{0},{1},{2}", DeviceStatus.DeviceManufacturer, DeviceStatus.DeviceHardwareVersion, DeviceStatus.DeviceFirmwareVersion); - } - } - - public string manufacturer - { - get - { - return DeviceStatus.DeviceManufacturer; - } - } - - public string name - { - get - { - return DeviceStatus.DeviceName; - - } - } - - public string platform - { - get - { - return Environment.OSVersion.Platform.ToString(); - } - } - - public string uuid - { - get - { - object id; - - UserExtendedProperties.TryGetValue("ANID", out id); - if (id != null) - { - return id.ToString().Substring(2, 32); - } - - UserExtendedProperties.TryGetValue("ANID2", out id); - if (id != null) - { - return id.ToString(); - } - - string returnVal = "???unknown???"; - - using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication()) - { - try - { - IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage); - - using (StreamReader reader = new StreamReader(fileStream)) - { - returnVal = reader.ReadLine(); - } - } - catch (Exception /*ex*/) - { - - } - } - - return returnVal; - } - } - - public string version - { - get - { - return Environment.OSVersion.Version.ToString(); - } - } - - } -} diff --git a/plugins/org.apache.cordova.device/tests/plugin.xml b/plugins/org.apache.cordova.device/tests/plugin.xml deleted file mode 100644 index 8819816a..00000000 --- a/plugins/org.apache.cordova.device/tests/plugin.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:rim="http://www.blackberry.com/ns/widgets" - xmlns:android="http://schemas.android.com/apk/res/android" - id="org.apache.cordova.device.tests" - version="0.2.14"> - <name>Cordova Device Plugin Tests</name> - <license>Apache 2.0</license> - - <js-module src="tests.js" name="tests"> - </js-module> -</plugin> diff --git a/plugins/org.apache.cordova.device/tests/tests.js b/plugins/org.apache.cordova.device/tests/tests.js deleted file mode 100644 index 1f49d7e1..00000000 --- a/plugins/org.apache.cordova.device/tests/tests.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * 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. - * -*/ - -exports.defineAutoTests = function() { - describe('Device Information (window.device)', function () { - it("should exist", function() { - expect(window.device).toBeDefined(); - }); - - it("should contain a platform specification that is a string", function() { - expect(window.device.platform).toBeDefined(); - expect((new String(window.device.platform)).length > 0).toBe(true); - }); - - it("should contain a version specification that is a string", function() { - expect(window.device.version).toBeDefined(); - expect((new String(window.device.version)).length > 0).toBe(true); - }); - - it("should contain a UUID specification that is a string or a number", function() { - expect(window.device.uuid).toBeDefined(); - if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') { - expect((new String(window.device.uuid)).length > 0).toBe(true); - } else { - expect(window.device.uuid > 0).toBe(true); - } - }); - - it("should contain a cordova specification that is a string", function() { - expect(window.device.cordova).toBeDefined(); - expect((new String(window.device.cordova)).length > 0).toBe(true); - }); - - it("should depend on the presence of cordova.version string", function() { - expect(window.cordova.version).toBeDefined(); - expect((new String(window.cordova.version)).length > 0).toBe(true); - }); - - it("should contain device.cordova equal to cordova.version", function() { - expect(window.device.cordova).toBe(window.cordova.version); - }); - - it("should contain a model specification that is a string", function() { - expect(window.device.model).toBeDefined(); - expect((new String(window.device.model)).length > 0).toBe(true); - }); - - it("should contain a manufacturer property that is a string", function() { - expect(window.device.manufacturer).toBeDefined(); - expect((new String(window.device.manufacturer)).length > 0).toBe(true); - }); - }); -}; - -exports.defineManualTests = function(contentEl, createActionButton) { - var logMessage = function (message, color) { - var log = document.getElementById('info'); - var logLine = document.createElement('div'); - if (color) { - logLine.style.color = color; - } - logLine.innerHTML = message; - log.appendChild(logLine); - } - - var clearLog = function () { - var log = document.getElementById('info'); - log.innerHTML = ''; - } - - var device_tests = '<h3>Press Dump Device button to get device information</h3>' + - '<div id="dump_device"></div>' + - 'Expected result: Status box will get updated with device info. (i.e. platform, version, uuid, model, etc)'; - - contentEl.innerHTML = '<div id="info"></div>' + device_tests; - - createActionButton('Dump device', function() { - clearLog(); - logMessage(JSON.stringify(window.device, null, '\t')); - }, "dump_device"); -}; diff --git a/plugins/org.apache.cordova.device/www/device.js b/plugins/org.apache.cordova.device/www/device.js deleted file mode 100644 index b1d0d25d..00000000 --- a/plugins/org.apache.cordova.device/www/device.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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 argscheck = require('cordova/argscheck'), - channel = require('cordova/channel'), - utils = require('cordova/utils'), - exec = require('cordova/exec'), - cordova = require('cordova'); - -channel.createSticky('onCordovaInfoReady'); -// Tell cordova channel to wait on the CordovaInfoReady event -channel.waitForInitialization('onCordovaInfoReady'); - -/** - * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the - * phone, etc. - * @constructor - */ -function Device() { - this.available = false; - this.platform = null; - this.version = null; - this.uuid = null; - this.cordova = null; - this.model = null; - this.manufacturer = null; - - var me = this; - - channel.onCordovaReady.subscribe(function() { - me.getInfo(function(info) { - //ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js - //TODO: CB-5105 native implementations should not return info.cordova - var buildLabel = cordova.version; - me.available = true; - me.platform = info.platform; - me.version = info.version; - me.uuid = info.uuid; - me.cordova = buildLabel; - me.model = info.model; - me.manufacturer = info.manufacturer || 'unknown'; - channel.onCordovaInfoReady.fire(); - },function(e) { - me.available = false; - utils.alert("[ERROR] Error initializing Cordova: " + e); - }); - }); -} - -/** - * Get device info - * - * @param {Function} successCallback The function to call when the heading data is available - * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) - */ -Device.prototype.getInfo = function(successCallback, errorCallback) { - argscheck.checkArgs('fF', 'Device.getInfo', arguments); - exec(successCallback, errorCallback, "Device", "getDeviceInfo", []); -}; - -module.exports = new Device(); diff --git a/plugins/org.apache.cordova.media/CONTRIBUTING.md b/plugins/org.apache.cordova.media/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/org.apache.cordova.media/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/org.apache.cordova.media/LICENSE b/plugins/org.apache.cordova.media/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/org.apache.cordova.media/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/NOTICE b/plugins/org.apache.cordova.media/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/org.apache.cordova.media/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/org.apache.cordova.media/README.md b/plugins/org.apache.cordova.media/README.md deleted file mode 100644 index bacd84b0..00000000 --- a/plugins/org.apache.cordova.media/README.md +++ /dev/null @@ -1,22 +0,0 @@ -<!--- - license: 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. ---> - -# org.apache.cordova.media - -Plugin documentation: [doc/index.md](doc/index.md) diff --git a/plugins/org.apache.cordova.media/RELEASENOTES.md b/plugins/org.apache.cordova.media/RELEASENOTES.md deleted file mode 100644 index d6fa87fa..00000000 --- a/plugins/org.apache.cordova.media/RELEASENOTES.md +++ /dev/null @@ -1,111 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.2.1 (Sept 5, 2013) -* CB-4432 copyright notice change - -### 0.2.3 (Sept 25, 2013) -* CB-4889 bumping&resetting version -* [windows8] commandProxy was moved -* CB-4889 renaming references -* CB-4889 renaming org.apache.cordova.core.media to org.apache.cordova.media -* [CB-4847] iOS 7 microphone access requires user permission - if denied, CDVCapture, CDVSound does not handle it properly -* Rename CHANGELOG.md -> RELEASENOTES.md -* [CB-4799] Fix incorrect JS references within native code on Android & iOS -* Fix compiler/lint warnings -* Rename plugin id from AudioHandler -> media -* [CB-4763] Remove reference to cordova-android's FileHelper. -* [CB-4752] Incremented plugin version on dev branch. - -### 0.2.4 (Oct 9, 2013) -* [CB-4928] plugin-media doesn't load on windows8 -* [CB-4915] Incremented plugin version on dev branch. - -### 0.2.5 (Oct 28, 2013) -* CB-5128: add repo + issue tag to plugin.xml for media plugin -* [CB-5010] Incremented plugin version on dev branch. - - -### 0.2.6 (Dec 4, 2013) -* [ubuntu] specify policy_group -* add ubuntu platform -* Added amazon-fireos platform. Change to use amazon-fireos as a platform if the user agent string contains 'cordova-amazon-fireos' - -### 0.2.7 (Jan 02, 2014) -* CB-5658 Add doc/index.md for Media plugin -* Adding READ_PHONE_STATE to the plugin permissions - -### 0.2.8 (Feb 05, 2014) -* Add preliminary support for Tizen. -* [CB-4755] Fix crash in Media.setVolume on iOS - -### 0.2.9 (Feb 26, 2014) -* CB-6051 Update media plugin to work with new cdvfile:// urls -* CB-5748 Make sure that Media.onStatus is called when recording is started. - -### 0.2.10 (Apr 17, 2014) -* CB-6422: [windows8] use cordova/exec/proxy -* CB-6212: [iOS] fix warnings compiled under arm64 64-bit -* CB-6225: Specify plugin dependency on File plugin 1.0.1 -* CB-6460: Update license headers -* CB-6465: Add license headers to Tizen code -* Add NOTICE file - -### 0.2.11 (Jun 05, 2014) -* CB-6127 Spanish and French Translations added. Github close #13 -* CB-6807 Add license -* CB-6706: Relax dependency on file plugin -* CB-6478: Fix exception when try to record audio file on windows 8 -* CB-6477: Add musicLibrary and microphone capabilities to windows 8 platform -* CB-6491 add CONTRIBUTING.md - -### 0.2.12 (Aug 06, 2014) -* CB-6127 Updated translations for docs -* ios: Make it easier to play media and record audio simultaneously -* code #s for MediaError - -### 0.2.13 (Sep 17, 2014) -* CB-6963 renamed folder to tests + added nested plugin.xml -* added documentation for manual tests -* CB-6963 Port Media manual & automated tests -* CB-6963 Port media tests to plugin-test-framework - -### 0.2.14 (Oct 03, 2014) -* Amazon Specific changes: Added READ_PHONE_STATE permission same as done in Android -* make possible plays wav file -* CB-7638 Get audio duration properly on windows -* CB-7454 Adds support for m4a audio format for Windows -* CB-7547 Fixes audio recording on windows platform -* CB-7531 Fixes play() failure after release() call - -### 0.2.15 (Dec 02, 2014) -* CB-6153 **Android**: Add docs for volume control behaviour, and fix controls not being reset on page navigation -* CB-6153 **Android**: Make volume buttons control music stream while any audio players are created -* CB-7977 Mention `deviceready` in plugin docs -* CB-7945 Made media.spec.15 and media.spec.16 auto tests green -* CB-7700 cordova-plugin-media documentation translation: cordova-plugin-media - -### 0.2.16 (Feb 04, 2015) -* CB-8351 ios: Stop using (newly) deprecated CDVJSON.h -* CB-8351 ios: Use argumentForIndex rather than NSArray extension -* CB-8252 android: Fire audio events from native via message channel -* CB-8152 ios: Remove deprecated methods in Media plugin (deprecated since 2.5) diff --git a/plugins/org.apache.cordova.media/doc/de/index.md b/plugins/org.apache.cordova.media/doc/de/index.md deleted file mode 100644 index e3e6cd73..00000000 --- a/plugins/org.apache.cordova.media/doc/de/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -Dieses Plugin bietet die Möglichkeit zum Aufzeichnen und Wiedergeben von audio-Dateien auf einem Gerät. - -**Hinweis**: die aktuelle Implementierung eine W3C-Spezifikation für Medien-Capture nicht einhalten, und wird nur zu Informationszwecken zur Verfügung gestellt. Zukünftiger Implementierungen wird an der aktuellen W3C-Spezifikation und kann die aktuellen APIs entweiht. - -## Installation - - cordova plugin add org.apache.cordova.media - - -## Unterstützte Plattformen - -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 und 8 -* Tizen -* Windows 8 - -## Windows Phone Macken - -* Nur eine Mediendatei kann gleichzeitig abgespielt werden. - -* Es gibt strenge Beschränkungen, wie Ihre Anwendung mit anderen Medien interagiert. Finden Sie in der [Microsoft-Dokumentation für details][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Medien - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### Parameter - -* **Src**: ein URI mit der audio-Inhalte. *(DOM-String und enthält)* - -* **MediaSuccess**: (Optional) der Rückruf, der nach dem führt ein `Media` -Objekt abgeschlossen hat, die aktuelle Wiedergabe, Aufzeichnung oder Stop-Action. *(Funktion)* - -* **Medienfehler**: (Optional) der Rückruf, der ausgeführt wird, wenn ein Fehler auftritt. *(Funktion)* - -* **MediaStatus**: (Optional) der Rückruf, der ausgeführt wird, um Statusänderungen anzugeben. *(Funktion)* - -### Konstanten - -Die folgenden Konstanten werden gemeldet, als einzigem Parameter an die `mediaStatus` Rückruf: - -* `Media.MEDIA_NONE`= 0; -* `Media.MEDIA_STARTING`= 1; -* `Media.MEDIA_RUNNING`= 2; -* `Media.MEDIA_PAUSED`= 3; -* `Media.MEDIA_STOPPED`= 4; - -### Methoden - -* `media.getCurrentPosition`: Gibt die aktuelle Position in einer Audiodatei. - -* `media.getDuration`: Gibt die Dauer einer Audiodatei. - -* `media.play`: Starten Sie oder fortsetzen Sie der Wiedergabe einer Audiodatei. - -* `media.pause`: Anhalten der Wiedergabe einer Audiodatei. - -* `media.release`: Das zugrunde liegende Betriebssystem audio Ressourcen frei. - -* `media.seekTo`: Verschiebt die Position innerhalb der audio-Datei. - -* `media.setVolume`: Stellen Sie die Lautstärke für die Audiowiedergabe. - -* `media.startRecord`: Starten der Aufnahme einer audio-Datei. - -* `media.stopRecord`: Stoppen Sie die Aufnahme einer audio-Datei. - -* `media.stop`: Abspielen einer Audiodatei zu stoppen. - -### Zusätzliche ReadOnly-Parameter - -* **Position**: die Position innerhalb der audio-Wiedergabe in Sekunden. - - * Nicht während des Spiels automatisch aktualisiert; Rufen Sie `getCurrentPosition` zu aktualisieren. - -* **Dauer**: die Dauer der Medien, in Sekunden. - -## media.getCurrentPosition - -Gibt die aktuelle Position in einer Audiodatei. Aktualisiert auch die `Media` des Objekts `position` Parameter. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### Parameter - -* **MediaSuccess**: der Rückruf, der die aktuelle Position in Sekunden übergeben wird. - -* **Medienfehler**: (Optional) der Rückruf ausgeführt, wenn ein Fehler auftritt. - -### Kurzes Beispiel - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -Gibt die Dauer einer Audiodatei in Sekunden. Wenn die Dauer unbekannt ist, wird der Wert-1 zurückgegeben. - - media.getDuration(); - - -### Kurzes Beispiel - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## Media.Pause - -Pausen Abspielen einer Audiodatei. - - media.pause(); - - -### Kurzes Beispiel - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## Media.Play - -Startet oder setzt fort, Abspielen einer Audiodatei. - - media.play(); - - -### Kurzes Beispiel - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS Macken - -* **NumberOfLoops**: übergeben Sie diese Option, um die `play` -Methode können Sie die Anzahl der angeben soll die Mediendatei ausspielen, z.B.: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **PlayAudioWhenScreenIsLocked**: übergeben Sie diese Option, um die `play` -Methode können Sie angeben, ob Sie möchten Wiedergabe zu ermöglichen, wenn der Bildschirm gesperrt ist. Wenn legen Sie auf `true` (der Standardwert), der Zustand der die mute Taste wird ignoriert, z.B.: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **Reihenfolge der Dateisuche**: Wenn nur ein Dateiname oder Pfad angegeben wird, sucht iOS in das `www` Verzeichnis für die Datei, dann in der Anwendung `documents/tmp` Verzeichnis: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -Das zugrunde liegende Betriebssystem audio Ressourcen frei. Dies ist besonders wichtig für Android, da gibt es eine begrenzte Anzahl von OpenCore-Instanzen für die Medienwiedergabe. Anwendungen rufen die `release` -Funktion für alle `Media` Ressource, die nicht mehr benötigt wird. - - media.release(); - - -### Kurzes Beispiel - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Legt die aktuelle Position in einer Audiodatei. - - media.seekTo(milliseconds); - - -### Parameter - -* **Millisekunden**: die Position die Wiedergabeposition innerhalb des Audiotracks in Millisekunden festgelegt. - -### Kurzes Beispiel - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### BlackBerry 10 Macken - -* BlackBerry OS 5-Geräten unterstützt nicht. - -## media.setVolume - -Stellen Sie die Lautstärke für eine audio-Datei. - - media.setVolume(volume); - - -### Parameter - -* **Lautstärke**: die Lautstärke für Wiedergabe fest. Der Wert muss im Bereich zwischen 0,0 und 1,0 liegen. - -### Unterstützte Plattformen - -* Android -* iOS - -### Kurzes Beispiel - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Beginnt mit der Aufnahme einer audio-Datei. - - media.startRecord(); - - -### Unterstützte Plattformen - -* Android -* iOS -* Windows Phone 7 und 8 -* Windows 8 - -### Kurzes Beispiel - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Android Eigenarten - -* Android-Geräte aufnehmen Audio im Adaptive Sprachcodecs Format. Die angegebene Datei sollte mit einer Endung *.amr* enden. - -### iOS Macken - -* iOS nur Datensätze, die Dateien des Typs *WAV* und gibt ein Fehler, wenn die Dateinamen-Erweiterung ist richtig nicht. - -* Wenn ein vollständiger Pfad nicht angegeben ist, wird die Aufzeichnung in der Anwendung platziert `documents/tmp` Verzeichnis. Erreichbar über die `File` -API verwenden `LocalFileSystem.TEMPORARY` . Allen Unterverzeichnissen in Rekordzeit angegeben muss bereits vorhanden sein. - -* Dateien können aufgezeichnet und spielte mit die Dokumenten URI zurück: - - var myMedia = new Media("documents://beer.mp3") - - -### Windows 8 Macken - -* Wenn Sie ein vollständiger Pfad nicht angegeben ist, wird die Aufnahme im AppData/Temp-Verzeichnis platziert. Erreichbar über die `Datei` API verwenden `LocalFileSystem.TEMPORARY` oder "ms-Appdata: / / / Temp /<filename>' URI. - -* Allen Unterverzeichnissen in Rekordzeit angegeben muss bereits vorhanden sein. - -### Tizen Macken - -* Tizen Geräten unterstützt nicht. - -## media.stop - -Beendet die Wiedergabe einer Audiodatei. - - Media.Stop(); - - -### Kurzes Beispiel - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Stoppt die Aufnahme einer audio-Datei. - - media.stopRecord(); - - -### Unterstützte Plattformen - -* Android -* iOS -* Windows Phone 7 und 8 -* Windows 8 - -### Kurzes Beispiel - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Tizen Macken - -* Tizen Geräten unterstützt nicht. - -## Medienfehler - -A `MediaError` Objekt wird zurückgegeben, um die `mediaError` Callback-Funktion, wenn ein Fehler auftritt. - -### Eigenschaften - -* **Code**: einer der vordefinierten Fehlercodes aufgeführt. - -* **Nachricht**: eine Fehlermeldung beschreibt die Details des Fehlers. - -### Konstanten - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/es/index.md b/plugins/org.apache.cordova.media/doc/es/index.md deleted file mode 100644 index ce5d8dd0..00000000 --- a/plugins/org.apache.cordova.media/doc/es/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -Este plugin proporciona la capacidad de grabar y reproducir archivos de audio en un dispositivo. - -**Nota**: la implementación actual no se adhiere a una especificación del W3C para la captura de los medios de comunicación y se proporciona únicamente para su comodidad. Una futura implementación se adherirá a la más reciente especificación W3C y puede desaprueban las API actuales. - -## Instalación - - cordova plugin add org.apache.cordova.media - - -## Plataformas soportadas - -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 y 8 -* Tizen -* Windows 8 - -## Windows Phone rarezas - -* Archivo único multimedia puede reproducir en un momento. - -* Hay restricciones estrictas sobre cómo interactúa la aplicación con otros medios. Consulte la [documentación de Microsoft para obtener más detalles][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Los medios de comunicación - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### Parámetros - -* **src**: un URI que contiene el contenido de audio. *(DOMString)* - -* **mediaSuccess**: (opcional) la devolución de llamada que se ejecuta después de que un objeto `Media` ha completado el juego actual, registro o acción. *(Function)* - -* **mediaError**: (opcional) la devolución de llamada que se ejecuta si se produce un error. *(Función)* - -* **mediaStatus**: (opcional) la devolución de llamada que se ejecuta para indicar cambios en el estado. *(Función)* - -### Constantes - -Las siguientes constantes son reportadas como el único parámetro para la devolución de llamada `mediaStatus`: - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED` = 3; -* `Media.MEDIA_STOPPED` = 4; - -### Métodos - -* `media.getCurrentPosition`: devuelve la posición actual dentro de un archivo de audio. - -* `media.getDuration`: devuelve la duración de un archivo de audio. - -* `media.play`: iniciar o reanudar reproducción de un archivo de audio. - -* `media.pause`: pausar la reproducción de un archivo de audio. - -* `media.release`: libera recursos de audio del sistema operativo subyacente. - -* `media.seekTo`: mueve la posición dentro del archivo de audio. - -* `media.setVolume`: ajuste el volumen de reproducción de audio. - -* `media.startRecord`: iniciar la grabación de un archivo de audio. - -* `media.stopRecord`: dejar de grabar un archivo de audio. - -* `media.stop`: deja de jugar a un archivo de audio. - -### Parámetros adicionales ReadOnly - -* **posición**: la posición dentro de la reproducción de audio, en segundos. - - * No actualizada automáticamente durante la reproducción; Llame a `getCurrentPosition` para actualizar. - -* **duration**: la duración de los medios de comunicación, en segundos. - -## media.getCurrentPosition - -Devuelve la posición actual dentro de un archivo de audio. También actualiza el `Media` del objeto `position` parámetro. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### Parámetros - -* **mediaSuccess**: la devolución de llamada que se pasa a la posición actual en segundos. - -* **mediaError**: (opcional) la devolución de llamada para ejecutar si se produce un error. - -### Ejemplo rápido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -Devuelve la duración de un archivo de audio en segundos. Si se desconoce la duración, devuelve un valor de -1. - - media.getDuration(); - - -### Ejemplo rápido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## media.pause - -Pausas jugando un archivo de audio. - - media.pause(); - - -### Ejemplo rápido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## media.play - -Inicia o reanuda la reproducción de un archivo de audio. - - media.play(); - - -### Ejemplo rápido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS rarezas - -* **numberOfLoops**: pasar esta opción al método `play` para especificar el número de veces que desea que los medios de archivo para jugar, por ejemplo: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**: pasar en esta opción el método `play` para especificar si desea permitir la reproducción cuando la pantalla está bloqueada. Si se omite establecido en `true` (el valor predeterminado), el estado del botón mute hardware, por ejemplo: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **orden de búsqueda de archivos**: cuando se proporciona sólo un nombre de archivo o ruta simple, iOS busca en el directorio `www` para el archivo, luego en el directorio de la aplicación `documents/tmp`: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -Libera los recursos de audio del sistema operativo subyacente. Esto es particularmente importante para Android, ya que hay una cantidad finita de instancias de OpenCore para la reproducción multimedia. Las aplicaciones deben llamar a la función de `release` para cualquier recurso `Media` que ya no es necesario. - - media.release(); - - -### Ejemplo rápido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Establece la posición actual dentro de un archivo de audio. - - media.seekTo(milliseconds); - - -### Parámetros - -* **milliseconds**: la posición para ajustar la posición de reproducción en el audio, en milisegundos. - -### Ejemplo rápido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### BlackBerry 10 rarezas - -* No compatible con dispositivos BlackBerry OS 5. - -## media.setVolume - -Ajustar el volumen para un archivo de audio. - - media.setVolume(volume); - - -### Parámetros - -* **volume**: el volumen para la reproducción. El valor debe estar dentro del rango de 0.0 a 1.0. - -### Plataformas soportadas - -* Android -* iOS - -### Ejemplo rápido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Empieza a grabar un archivo de audio. - - media.startRecord(); - - -### Plataformas soportadas - -* Android -* iOS -* Windows Phone 7 y 8 -* Windows 8 - -### Ejemplo rápido - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Rarezas Android - -* Dispositivos Android grabación audio en formato Adaptive Multi-rate. El archivo especificado debe terminar con una extensión de *.amr*. - -### iOS rarezas - -* iOS únicos registros a archivos de tipo *.wav* y devuelve un error si el archivo de extensión el nombre es no es correcto. - -* Si no se proporciona una ruta completa, la grabación se coloca en el directorio de la aplicación `documents/tmp`. Esto se puede acceder mediante el `File` API utilizando `LocalFileSystem.TEMPORARY`. Ya debe existir cualquier subdirectorio especificado en un tiempo récord. - -* Archivos pueden ser grabados y jugó de nuevo usando los documentos URI: - - var myMedia = new Media("documents://beer.mp3") - - -### Rarezas de Windows 8 - -* Si no se proporciona una ruta completa, la grabación se coloca en el directorio AppData/temp. Esto puede accederse a través de la `Archivo` Usando API `LocalFileSystem.TEMPORARY` o ' ms-appdata: temporal / / / /<filename>' URI. - -* Ya debe existir cualquier subdirectorio especificado en un tiempo récord. - -### Rarezas Tizen - -* No compatible con dispositivos Tizen. - -## media.stop - -Deja de jugar a un archivo de audio. - - media.stop(); - - -### Ejemplo rápido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Detiene la grabación de un archivo de audio. - - media.stopRecord(); - - -### Plataformas soportadas - -* Android -* iOS -* Windows Phone 7 y 8 -* Windows 8 - -### Ejemplo rápido - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Rarezas Tizen - -* No compatible con dispositivos Tizen. - -## MediaError - -A `MediaError` objeto es devuelto a la `mediaError` función de devolución de llamada cuando se produce un error. - -### Propiedades - -* **code**: uno de los códigos de error predefinido enumerados a continuación. - -* **mensaje**: un mensaje de error que describe los detalles del error. - -### Constantes - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/fr/index.md b/plugins/org.apache.cordova.media/doc/fr/index.md deleted file mode 100644 index 291c13b1..00000000 --- a/plugins/org.apache.cordova.media/doc/fr/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -Ce plugin permet d'enregistrer et de lire des fichiers audio sur un périphérique. - -**Remarque**: l'implémentation actuelle n'est pas conforme à une spécification du W3C pour la capture de médias et est fournie pour plus de commodité seulement. Une prochaine implémentation adhèrera à la toute dernière spécification du W3C, ce qui aura probablement pour effet de déprécier l'API actuelle. - -## Installation - - cordova plugin add org.apache.cordova.media - - -## Plates-formes prises en charge - -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 et 8 -* Paciarelli -* Windows 8 - -## Windows Phone Quirks - -* Un seul fichier média peut être lu à la fois. - -* Il y a des restrictions strictes concernant la façon dont votre application interagit avec d'autres médias. Consultez la [documentation de Microsoft pour plus d'informations][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Media - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### Paramètres - -* **src** : l'URI du contenu audio. *(DOMString)* - -* **mediaSuccess** : (facultative) la fonction callback exécutée après que la lecture en cours, l'action d'enregistrement ou l'arrêt de lecture de l'objet `Media` soit terminée. *(Function)* - -* **mediaError** : (facultative) la fonction callback exécutée si une erreur survient. *(Function)* - -* **mediaStatus** : (facultative) la fonction callback exécutée lors de chaque changement d'état. *(Function)* - -### Constantes - -Les constantes suivantes correspondent au seul paramètre transmis à la fonction callback `mediaStatus` : - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED` = 3; -* `Media.MEDIA_STOPPED` = 4; - -### Méthodes - -* `media.getCurrentPosition` : retourne la position de lecture dans un fichier audio. - -* `media.getDuration`: retourne la durée d'un fichier audio. - -* `media.play` : permet de commencer ou reprendre la lecture d'un fichier audio. - -* `media.pause` : interrompt la lecture d'un fichier audio. - -* `media.release` : libère les ressources audio correspondantes du système d'exploitation. - -* `media.seekTo` : déplace la position de lecture au sein du fichier audio. - -* `media.setVolume` : permet de régler le volume du clip audio. - -* `media.startRecord` : commence l'enregistrement d'un fichier audio. - -* `media.stopRecord` : arrête l'enregistrement d'un fichier audio. - -* `media.stop` : arrête la lecture d'un fichier audio. - -### Paramètres supplémentaires en lecture seule - -* **position** : la position de lecture sein du clip audio, en secondes. - - * La valeur n'est pas automatiquement rafraichie pendant la lecture ; un appel à `getCurrentPosition` permet sa mise à jour. - -* **duration** : la durée du média, en secondes. - -## media.getCurrentPosition - -Retourne la position courante dans un fichier audio. Met également à jour la `Media` de l'objet `position` paramètre. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### Paramètres - -* **mediaSuccess** : la fonction callback à laquelle est transmise la position actuelle exprimée en secondes. - -* **mediaError** : (facultative) la fonction callback exécutée si une erreur se produit. - -### Petit exemple - - // lecteur audio - // - var my_media = new Media(src, onSuccess, onError); - - // met à jour la position de lecture du fichier à chaque seconde - var mediaTimer = setInterval(function () { - // récupère la position - my_media.getCurrentPosition( - // fonction callback de succès - function (position) { - if (position > -1) { - console.log((position) + " secondes"); - } - }, - // fonction callback d'erreur - function (e) { - console.log("Erreur lors de l'obtention de la position : " + e); - } - ); - }, 1000); - - -## media.getDuration - -Retourne la durée d'un fichier audio en quelques secondes. Si on ne connaît pas la durée, elle retourne la valeur -1. - - media.getDuration(); - - -### Petit exemple - - // lecteur audio - // - var my_media = new Media(src, onSuccess, onError); - - // récupère la durée - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " secondes"; - } - }, 100); - - -## media.pause - -Suspend la lecture d'un fichier audio. - - media.pause(); - - -### Petit exemple - - // joue le clip audio - // - function playAudio(url) { - // joue le fichier audio situé à cette url - var my_media = new Media(url, - // fonction callback de succès - function () { console.log("playAudio() : clip audio joué avec succès"); }, - // error callback - function (err) { console.log("playAudio() : erreur lors de la lecture du clip audio: " + err); } - ); - - // lance la lecture du clip audio - my_media.play(); - - // met la lecture en pause après 10 secondes - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## media.play - -Commence ou reprend la lecture d'un fichier audio. - - media.play(); - - -### Petit exemple - - // joue le clip audio - // - function playAudio(url) { - // joue le fichier audio situé à cette url - var my_media = new Media(url, - // fonction callback de succès - function () { - console.log("playAudio() : fichier audio lu avec succès"); - }, - // fonction callback d'erreur - function (err) { - console.log("playAudio() : erreur lors de la lecture du fichier audio : " + err); - } - ); - // commence la lecture du clip audio - my_media.play(); - } - - -### iOS Quirks - -* **numberOfLoops** : transmettre cette option à la méthode `play` permet de spécifier le nombre de lectures à la suite d'un fichier donné, par exemple : - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked** : transmettre cette option à la méthode `play` permet de spécifier si la lecture doit continuer même lorsque l'écran de l'appareil est verrouillé. Si la valeur est `true` (par défaut), le bouton matériel mute est ignoré, par exemple : - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **ordre de recherche de fichier** : si un nom de fichier ou chemin d'accès simple est fourni, iOS recherche d'abord le fichier correspondant dans le répertoire `www`, puis dans le répertoire `documents/tmp` appartenant à l'application : - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // recherche d'abord le fichier www/audio/beer.mp3 puis <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -Libère certaines ressources audio du système d'exploitation. Cela est particulièrement important pour Android, puisqu'il y a une quantité finie d'instances OpenCore pour la lecture du média. Les applications doivent en général appeler cette fonction `release` pour toute ressource `Media` qui n'est plus nécessaire. - - media.release(); - - -### Petit exemple - - // lecteur audio - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Définit la position de lecture actuelle dans un fichier audio. - - media.seekTo(milliseconds); - - -### Paramètres - -* **milliseconds** : la nouvelle position de lecture au sein du fichier audio, en millisecondes. - -### Petit exemple - - // lecteur audio - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // avance la position à 10 secondes du début du fichier après 5 secondes - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### BlackBerry 10 Quirks - -* Cette méthode n'est pas prise en charge sur les périphériques BlackBerry OS 5. - -## media.setVolume - -Permet de régler le volume d'un fichier audio. - - media.setVolume(volume); - - -### Paramètres - -* **volume** : le volume à utiliser pour la lecture. La valeur doit être comprise entre 0.0 et 1.0 inclus. - -### Plates-formes prises en charge - -* Android -* iOS - -### Petit exemple - - // joue le clip audio - // - function playAudio(url) { - // joue le fichier audio situé à cette url - var my_media = new Media(url, - // fonction callback de succès - function() { - console.log("playAudio() : fichier audio lu avec succès"); - }, - // fonction callback d'erreur - function(err) { - console.log("playAudio() : erreur lors de la lecture du fichier audio : " + err); - }); - - // lance la lecture du clip audio - my_media.play(); - - // baisse le volume au maximum après 2 secondes - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // monte le volume à 1.0 (maximum) après 5 secondes - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Permet de démarrer l'enregistrement d'un fichier audio. - - media.startRecord(); - - -### Plates-formes prises en charge - -* Android -* iOS -* Windows Phone 7 et 8 -* Windows 8 - -### Petit exemple - - // enregistrement audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // fonction callback de succès - function() { - console.log("recordAudio() : audio enregistré avec succès"); - }, - - // fonction callback d'erreur - function(err) { - console.log("recordAudio() : erreur lors de l'enregistrement audio : " + err.code); - }); - - // débute l'enregistrement audio - mediaRec.startRecord(); - } - - -### Quirks Android - -* Les appareils Android enregistrent de l'audio au format Adaptive Multi-Rate. Le nom de fichier spécifié doit donc comporter une extension *.amr*. - -### iOS Quirks - -* iOS produit uniquement des enregistrements sous la forme de fichier de type *.wav* et renvoie une erreur si l'extension du nom de fichier est incorrecte. - -* Si un chemin d'accès complet n'est pas précisé, l'enregistrement est placé dans le répertoire `documents/tmp` correspondant à l'application. Il sera ensuite accessible via l'API `File` en utilisant la constante `LocalFileSystem.TEMPORARY`. Tout sous-répertoire présent dans le chemin d'accès au moment de l'enregistrement doit déjà exister. - -* Les fichiers peuvent être enregistrés et lus à l'aide de l'URI des documents : - - var myMedia = new Media("documents://beer.mp3") - - -### Bizarreries de Windows 8 - -* Si un chemin d'accès complet n'est pas fourni, l'enregistrement est placé dans le répertoire AppData/temp. Ce qui peut être consulté le `Fichier` À l'aide de l'API `LocalFileSystem.TEMPORARY` ou ' ms-appdata : temp / / / /<filename>' URI. - -* N'importe quel sous-répertoire spécifié au moment de l'enregistrement doit déjà exister. - -### Bizarreries de paciarelli - -* Pas pris en charge sur les appareils paciarelli. - -## media.stop - -Arrête la lecture d'un fichier audio. - - media.stop(); - - -### Petit exemple - - // joue le clip audio - // - function playAudio(url) { - // joue le fichier audio situé à cette url - var my_media = new Media(url, - // fonction callback de succès - function() { - console.log("playAudio() : clip audio lu avec succès"); - }, - // fonction callback d'erreur - function(err) { - console.log("playAudio() : erreur lors de la lecture du clip audio : " + err); - } - ); - - // démarre la lecture du clip audio - my_media.play(); - - // arrête la lecture après 10 secondes - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Arrête l'enregistrement d'un fichier audio. - - media.stopRecord(); - - -### Plates-formes prises en charge - -* Android -* iOS -* Windows Phone 7 et 8 -* Windows 8 - -### Petit exemple - - // enregistrement audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // fonction callback de succès - function() { - console.log("recordAudio() : audio enregistré avec succès"); - }, - - // fonction callback d'erreur - function(err) { - console.log("recordAudio() : erreur lors de l'enregistrement audio : " + err.code); - } - ); - - // débute l'enregistrement audio - mediaRec.startRecord(); - - // arrête l'enregistrement après 10 secondes - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Bizarreries de paciarelli - -* Pas pris en charge sur les appareils paciarelli. - -## MediaError - -Un objet `MediaError` est transmis à la fonction callback `mediaError` lorsqu'une erreur survient. - -### Propriétés - -* **code**: l'un des codes d'erreur prédéfinis énumérés ci-dessous. - -* **message**: un message d'erreur décrivant les détails de l'erreur. - -### Constantes - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/index.md b/plugins/org.apache.cordova.media/doc/index.md deleted file mode 100644 index 297d1e72..00000000 --- a/plugins/org.apache.cordova.media/doc/index.md +++ /dev/null @@ -1,508 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -This plugin provides the ability to record and play back audio files on a device. - -__NOTE__: The current implementation does not adhere to a W3C -specification for media capture, and is provided for convenience only. -A future implementation will adhere to the latest W3C specification -and may deprecate the current APIs. - -This plugin defines a global `Media` Constructor. - -Although in the global scope, it is not available until after the `deviceready` event. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(Media); - } - -## Installation - - cordova plugin add org.apache.cordova.media - -## Supported Platforms - -- Android -- BlackBerry 10 -- iOS -- Windows Phone 7 and 8 -- Tizen -- Windows 8 - -## Windows Phone Quirks - -- Only one media file can be played back at a time. - -- There are strict restrictions on how your application interacts with other media. See the [Microsoft documentation for details][url]. - -[url]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Media - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - -### Parameters - -- __src__: A URI containing the audio content. _(DOMString)_ - -- __mediaSuccess__: (Optional) The callback that executes after a `Media` object has completed the current play, record, or stop action. _(Function)_ - -- __mediaError__: (Optional) The callback that executes if an error occurs. _(Function)_ - -- __mediaStatus__: (Optional) The callback that executes to indicate status changes. _(Function)_ - -### Constants - -The following constants are reported as the only parameter to the -`mediaStatus` callback: - -- `Media.MEDIA_NONE` = 0; -- `Media.MEDIA_STARTING` = 1; -- `Media.MEDIA_RUNNING` = 2; -- `Media.MEDIA_PAUSED` = 3; -- `Media.MEDIA_STOPPED` = 4; - -### Methods - -- `media.getCurrentPosition`: Returns the current position within an audio file. - -- `media.getDuration`: Returns the duration of an audio file. - -- `media.play`: Start or resume playing an audio file. - -- `media.pause`: Pause playback of an audio file. - -- `media.release`: Releases the underlying operating system's audio resources. - -- `media.seekTo`: Moves the position within the audio file. - -- `media.setVolume`: Set the volume for audio playback. - -- `media.startRecord`: Start recording an audio file. - -- `media.stopRecord`: Stop recording an audio file. - -- `media.stop`: Stop playing an audio file. - -### Additional ReadOnly Parameters - -- __position__: The position within the audio playback, in seconds. - - Not automatically updated during play; call `getCurrentPosition` to update. - -- __duration__: The duration of the media, in seconds. - - -## media.getCurrentPosition - -Returns the current position within an audio file. Also updates the `Media` object's `position` parameter. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - -### Parameters - -- __mediaSuccess__: The callback that is passed the current position in seconds. - -- __mediaError__: (Optional) The callback to execute if an error occurs. - -### Quick Example - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -Returns the duration of an audio file in seconds. If the duration is unknown, it returns a value of -1. - - - media.getDuration(); - -### Quick Example - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## media.pause - -Pauses playing an audio file. - - media.pause(); - - -### Quick Example - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## media.play - -Starts or resumes playing an audio file. - - media.play(); - - -### Quick Example - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS Quirks - -- __numberOfLoops__: Pass this option to the `play` method to specify - the number of times you want the media file to play, e.g.: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - -- __playAudioWhenScreenIsLocked__: Pass in this option to the `play` - method to specify whether you want to allow playback when the screen - is locked. If set to `true` (the default value), the state of the - hardware mute button is ignored, e.g.: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - -- __order of file search__: When only a file name or simple path is - provided, iOS searches in the `www` directory for the file, then in - the application's `documents/tmp` directory: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - -## media.release - -Releases the underlying operating system's audio resources. -This is particularly important for Android, since there are a finite amount of -OpenCore instances for media playback. Applications should call the `release` -function for any `Media` resource that is no longer needed. - - media.release(); - - -### Quick Example - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Sets the current position within an audio file. - - media.seekTo(milliseconds); - -### Parameters - -- __milliseconds__: The position to set the playback position within the audio, in milliseconds. - - -### Quick Example - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### BlackBerry 10 Quirks - -- Not supported on BlackBerry OS 5 devices. - -## media.setVolume - -Set the volume for an audio file. - - media.setVolume(volume); - -### Parameters - -- __volume__: The volume to set for playback. The value must be within the range of 0.0 to 1.0. - -### Supported Platforms - -- Android -- iOS - -### Quick Example - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Starts recording an audio file. - - media.startRecord(); - -### Supported Platforms - -- Android -- iOS -- Windows Phone 7 and 8 -- Windows 8 - -### Quick Example - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Android Quirks - -- Android devices record audio in Adaptive Multi-Rate format. The specified file should end with a _.amr_ extension. -- The hardware volume controls are wired up to the media volume while any Media objects are alive. Once the last created Media object has `release()` called on it, the volume controls revert to their default behaviour. The controls are also reset on page navigation, as this releases all Media objects. - -### iOS Quirks - -- iOS only records to files of type _.wav_ and returns an error if the file name extension is not correct. - -- If a full path is not provided, the recording is placed in the application's `documents/tmp` directory. This can be accessed via the `File` API using `LocalFileSystem.TEMPORARY`. Any subdirectory specified at record time must already exist. - -- Files can be recorded and played back using the documents URI: - - var myMedia = new Media("documents://beer.mp3") - -### Windows 8 Quirks - -- If a full path is not provided, the recording is placed in the AppData/temp directory. This can be accessed via the `File` API using `LocalFileSystem.TEMPORARY` or 'ms-appdata:///temp/<filename>' URI. - -- Any subdirectory specified at record time must already exist. - -### Tizen Quirks - -- Not supported on Tizen devices. - -## media.stop - -Stops playing an audio file. - - media.stop(); - -### Quick Example - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Stops recording an audio file. - - media.stopRecord(); - -### Supported Platforms - -- Android -- iOS -- Windows Phone 7 and 8 -- Windows 8 - -### Quick Example - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Tizen Quirks - -- Not supported on Tizen devices. - -## MediaError - -A `MediaError` object is returned to the `mediaError` callback -function when an error occurs. - -### Properties - -- __code__: One of the predefined error codes listed below. - -- __message__: An error message describing the details of the error. - -### Constants - -- `MediaError.MEDIA_ERR_ABORTED` = 1 -- `MediaError.MEDIA_ERR_NETWORK` = 2 -- `MediaError.MEDIA_ERR_DECODE` = 3 -- `MediaError.MEDIA_ERR_NONE_SUPPORTED` = 4 - diff --git a/plugins/org.apache.cordova.media/doc/it/index.md b/plugins/org.apache.cordova.media/doc/it/index.md deleted file mode 100644 index 50da3aaf..00000000 --- a/plugins/org.apache.cordova.media/doc/it/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -Questo plugin consente di registrare e riprodurre i file audio su un dispositivo. - -**Nota**: l'implementazione attuale non aderisce a una specifica del W3C per l'acquisizione di mezzi e viene fornito solo per comodità. Una futura realizzazione aderirà alla specifica W3C più recente e può deprecare le API corrente. - -## Installazione - - cordova plugin add org.apache.cordova.media - - -## Piattaforme supportate - -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 e 8 -* Tizen -* Windows 8 - -## Stranezze di Windows Phone - -* File sola multimediale può essere riprodotti in un momento. - -* Ci sono severe restrizioni su come l'applicazione interagisce con altri media. Vedere la [documentazione di Microsoft per maggiori dettagli][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Media - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### Parametri - -* **src**: un URI contenente il contenuto audio. *(DOMString)* - -* **mediaSuccess**: (facoltativo) il callback che viene eseguito dopo un `Media` oggetto ha completato il gioco corrente, record o interrompere l'azione. *(Funzione)* - -* **errore mediaError**: (facoltativo) il callback che viene eseguito se si verifica un errore. *(Funzione)* - -* **mediaStatus**: (facoltativo) il callback che viene eseguito per indicare i cambiamenti di stato. *(Funzione)* - -### Costanti - -Costanti sono segnalate come unico parametro per il `mediaStatus` callback: - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED` = 3; -* `Media.MEDIA_STOPPED` = 4; - -### Metodi - -* `media.getCurrentPosition`: Restituisce la posizione corrente all'interno di un file audio. - -* `media.getDuration`: Restituisce la durata di un file audio. - -* `media.play`: Iniziare o riprendere la riproduzione di un file audio. - -* `media.pause`: Pausa la riproduzione di un file audio. - -* `media.release`: Libera risorse audio del sistema operativo sottostante. - -* `media.seekTo`: Sposta la posizione all'interno del file audio. - -* `media.setVolume`: Impostare il volume per la riproduzione audio. - -* `media.startRecord`: Iniziare a registrare un file audio. - -* `media.stopRecord`: Interrompere la registrazione di un file audio. - -* `media.stop`: Interrompere la riproduzione di un file audio. - -### Parametri supplementari ReadOnly - -* **posizione**: la posizione all'interno della riproduzione audio, in pochi secondi. - - * Non aggiornate automaticamente durante il gioco; chiamare `getCurrentPosition` per l'aggiornamento. - -* **durata**: la durata dei media, in secondi. - -## media.getCurrentPosition - -Restituisce la posizione corrente all'interno di un file audio. Aggiorna anche il `Media` dell'oggetto `position` parametro. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### Parametri - -* **mediaSuccess**: il callback passato la posizione corrente in pochi secondi. - -* **errore mediaError**: (facoltativo) il callback da eseguire se si verifica un errore. - -### Esempio rapido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -Restituisce la durata di un file audio in secondi. Se la durata è sconosciuta, essa restituisce un valore di -1. - - media.getDuration(); - - -### Esempio rapido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## Media.pause - -Sospende la riproduzione di un file audio. - - media.pause(); - - -### Esempio rapido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## Media.Play - -Avvia o riprende la riproduzione di un file audio. - - media.play(); - - -### Esempio rapido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS stranezze - -* **numberOfLoops**: passare questa opzione per il `play` metodo per specificare il numero di volte desiderato file multimediale per riprodurre, ad esempio: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**: questa opzione per passare il `play` metodo per specificare se si desidera consentire la riproduzione quando lo schermo è bloccato. Se impostato su `true` (il valore predefinito), viene ignorato lo stato del pulsante mute hardware, ad esempio: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **ordine di ricerca di file**: quando viene fornito solo un nome file o percorso semplice, cerca in iOS il `www` directory per il file, quindi l'applicazione `documents/tmp` directory: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -Rilascia le risorse audio del sistema operativo sottostante. Ciò è particolarmente importante per Android, dato che ci sono una quantità finita di OpenCore istanze per la riproduzione multimediale. Le applicazioni devono chiamare il `release` funzione per qualsiasi `Media` risorsa che non è più necessario. - - media.release(); - - -### Esempio rapido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Imposta la posizione corrente all'interno di un file audio. - - media.seekTo(milliseconds); - - -### Parametri - -* **millisecondi**: posizione per impostare la posizione di riproduzione all'interno l'audio, in millisecondi. - -### Esempio rapido - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### BlackBerry 10 capricci - -* Non è supportato sui dispositivi BlackBerry OS 5. - -## media.setVolume - -Impostare il volume per un file audio. - - media.setVolume(volume); - - -### Parametri - -* **volume**: il volume impostato per la riproduzione. Il valore deve essere all'interno della gamma di 0,0 e 1,0. - -### Piattaforme supportate - -* Android -* iOS - -### Esempio rapido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Avvia la registrazione di un file audio. - - media.startRecord(); - - -### Piattaforme supportate - -* Android -* iOS -* Windows Phone 7 e 8 -* Windows 8 - -### Esempio rapido - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Stranezze Android - -* Dispositivi Android registrano audio in formato Adaptive Multi-Rate. Il file specificato deve terminare con l'estensione ** . - -### iOS stranezze - -* iOS solo i record per i file di tipo *WAV* e restituisce un errore se il file di nome estensione è non corretto. - -* Se non è specificato un percorso completo, la registrazione viene inserita nell'applicazione `documents/tmp` directory. Questo si può accedere tramite il `File` API utilizzando `LocalFileSystem.TEMPORARY` . Deve esistere alcuna sottodirectory specificate a tempo di record. - -* I file possono essere registrati e giocati indietro usando i documenti URI: - - var myMedia = new Media("documents://beer.mp3") - - -### Stranezze di Windows 8 - -* Se non è specificato un percorso completo, la registrazione viene inserita nella directory AppData/temp. Questo si può accedere tramite il `File` Utilizzando API `LocalFileSystem.TEMPORARY` o ' ms-appdata: / / temp /<filename>' URI. - -* Deve esistere alcuna sottodirectory specificate a tempo di record. - -### Tizen stranezze - -* Tizen periferiche non supportano. - -## media.stop - -Interrompe la riproduzione di un file audio. - - Media.Stop(); - - -### Esempio rapido - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Smette di registrare un file audio. - - media.stopRecord(); - - -### Piattaforme supportate - -* Android -* iOS -* Windows Phone 7 e 8 -* Windows 8 - -### Esempio rapido - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Tizen stranezze - -* Tizen periferiche non supportano. - -## Errore MediaError - -A `MediaError` oggetto viene restituito alla `mediaError` funzione di callback quando si verifica un errore. - -### Proprietà - -* **codice**: uno dei codici di errore predefiniti elencati di seguito. - -* **messaggio**: un messaggio di errore che descrive i dettagli dell'errore. - -### Costanti - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/ja/index.md b/plugins/org.apache.cordova.media/doc/ja/index.md deleted file mode 100644 index 29c63e6d..00000000 --- a/plugins/org.apache.cordova.media/doc/ja/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -このプラグインは、記録し、デバイス上のオーディオ ファイルを再生する機能を提供します。 - -**注**: 現在の実装では、メディアのキャプチャのための W3C 仕様に準拠していないとは便宜上提供されるだけです。 将来の実装を最新の W3C 仕様に準拠し、現在 Api をとがめることがあります。 - -## インストール - - cordova plugin add org.apache.cordova.media - - -## サポートされているプラットフォーム - -* アンドロイド -* ブラックベリー 10 -* iOS -* Windows Phone 7 と 8 -* Tizen -* Windows 8 - -## Windows Phone の癖 - -* のみ 1 つのメディア ファイルは、一度に再生できます。 - -* アプリケーションと他のメディアとの対話に厳格な制限があります。 [詳細については、Microsoft のマニュアル][1]を参照してください。. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## メディア - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### パラメーター - -* **src**: オーディオのコンテンツを含む URI。*(,)* - -* **mediaSuccess**: (省略可能) 後に実行するコールバックを `Media` 再生用に現在、レコード、または stop アクション オブジェクトが完了しました。*(機能)* - -* **mediaError**: (省略可能) エラーが発生した場合に実行されるコールバック。*(機能)* - -* **mediaStatus**: (省略可能) 状態の変化を示すために実行されるコールバック。*(機能)* - -### 定数 - -次の定数を唯一のパラメーターとして報告されます、 `mediaStatus` コールバック。 - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED` = 3; -* `Media.MEDIA_STOPPED` = 4; - -### メソッド - -* `media.getCurrentPosition`: オーディオ ファイル内の現在位置を返します。 - -* `media.getDuration`: オーディオ ファイルの継続時間を返します。 - -* `media.play`: 開始またはオーディオ ファイルの再生を再開します。 - -* `media.pause`: オーディオ ファイルの再生を一時停止。 - -* `media.release`: 基になるオペレーティング システムのオーディオ リソースを解放します。 - -* `media.seekTo`: オーディオ ファイル内の位置を移動します。 - -* `media.setVolume`: オーディオの再生ボリュームを設定します。 - -* `media.startRecord`: オーディオ ファイルの録音を開始します。 - -* `media.stopRecord`: オーディオ ファイルの録音を停止します。 - -* `media.stop`: オーディオ ファイルの再生を停止します。 - -### 追加読み取り専用パラメーター - -* **位置**: 数秒でオーディオの再生では、内の位置。 - - * 自動的に更新されません; のプレイ中にコール `getCurrentPosition` を更新します。 - -* **期間**: 秒で、メディアの期間。 - -## media.getCurrentPosition - -オーディオ ファイル内の現在位置を返します。また更新して、 `Media` オブジェクトの `position` パラメーター。 - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### パラメーター - -* **mediaSuccess**: 秒の現在の位置を渡されるコールバック。 - -* **mediaError**: (省略可能) コールバックでエラーが発生した場合に実行します。 - -### 簡単な例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -オーディオ ファイルの継続時間 (秒単位) を返します。期間は知られている、-1 の値が返されます。 - - media.getDuration(); - - -### 簡単な例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## media.pause - -オーディオ ファイルの再生を一時停止します。 - - media.pause(); - - -### 簡単な例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## media.play - -開始またはオーディオ ファイルの再生を再開します。 - - media.play(); - - -### 簡単な例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS の癖 - -* **numberOfLoops**: このオプションを指定して、 `play` メディア ファイルを再生する、例えば回数を指定する方法。 - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**: このオプションを渡す、 `play` 、画面がロックされているときに再生を許可するかどうかを指定するメソッド。 場合に設定されている `true` (既定値)、例えば、ハードウェア ミュート ボタンの状態は無視されます。 - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **ファイル検索の順序**: iOS の検索でファイル名または単純なパスのみが提供される場合、 `www` ディレクトリ、ファイルをアプリケーションの `documents/tmp` ディレクトリ。 - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -基になるオペレーティング システムのオーディオ リソースを解放します。 メディアの再生のための OpenCore インスタンスの有限な量があるので、人造人間のため特に重要です。 アプリケーションを呼び出す必要があります、 `release` 任意の関数 `Media` は、もはや必要なリソースです。 - - media.release(); - - -### 簡単な例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -オーディオ ファイル内の現在位置を設定します。 - - media.seekTo(milliseconds); - - -### パラメーター - -* **ミリ秒単位**: ミリ秒単位で、オーディオの再生位置を設定する位置。 - -### 簡単な例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### ブラックベリー 10 癖 - -* ブラックベリー OS 5 デバイスでサポートされていません。 - -## media.setVolume - -オーディオ ファイルの音量を設定します。 - - media.setVolume(volume); - - -### パラメーター - -* **ボリューム**: ボリュームの再生を設定します。値は 0.0 ~ 1.0 の範囲内である必要があります。 - -### サポートされているプラットフォーム - -* アンドロイド -* iOS - -### 簡単な例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -オーディオ ファイルの録音を開始します。 - - media.startRecord(); - - -### サポートされているプラットフォーム - -* アンドロイド -* iOS -* Windows Phone 7 と 8 -* Windows 8 - -### 簡単な例 - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Android の癖 - -* Android 端末適応型マルチレート形式にオーディオを録音します。指定したファイルは、 *.amr*拡張子で終わる必要があります。 - -### iOS の癖 - -* iOS の種類*.wav*と返しますエラー場合は、ファイル名拡張子がファイルをレコードのみが修正されません。 - -* 記録は、アプリケーションの配置の完全なパスを指定しない場合 `documents/tmp` ディレクトリ。 これを介してアクセスすることができます、 `File` API を使用して `LocalFileSystem.TEMPORARY` 。 記録時に指定された任意のサブディレクトリに存在する必要があります。 - -* ファイルを記録し、再生することができますドキュメント URI を使用して。 - - var myMedia = new Media("documents://beer.mp3") - - -### Windows 8 の癖 - -* 完全なパスを指定しない場合、記録は AppData/temp ディレクトリに配置されます。これを介してアクセスすることができます、 `ファイル` API を使用してください。 `LocalFileSystem.TEMPORARY` または ' ms appdata: temp////<filename>' URI。 - -* 記録時に指定された任意のサブディレクトリに存在する必要があります。 - -### Tizen の癖 - -* Tizen のデバイスでサポートされていません。 - -## media.stop - -オーディオ ファイルの再生を停止します。 - - media.stop(); - - -### 簡単な例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -オーディオ ファイルの録音を停止します。 - - media.stopRecord(); - - -### サポートされているプラットフォーム - -* アンドロイド -* iOS -* Windows Phone 7 と 8 -* Windows 8 - -### 簡単な例 - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Tizen の癖 - -* Tizen のデバイスでサポートされていません。 - -## MediaError - -A `MediaError` オブジェクトに返される、 `mediaError` コールバック関数でエラーが発生したとき。 - -### プロパティ - -* **コード**: 次のいずれかの定義済みのエラー コード。 - -* **メッセージ**: エラーの詳細を説明するエラー メッセージ。 - -### 定数 - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/ko/index.md b/plugins/org.apache.cordova.media/doc/ko/index.md deleted file mode 100644 index 3a7a908c..00000000 --- a/plugins/org.apache.cordova.media/doc/ko/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -이 플러그인 기록 장치에 오디오 파일을 재생 하는 기능을 제공 합니다. - -**참고**: 현재 구현 미디어 캡처에 대 한 W3C 사양을 준수 하지 않는 및 편의 위해서만 제공 됩니다. 미래 구현 최신 W3C 사양을 준수 한다 고 현재 Api 사용 중지 될 수 있습니다. - -## 설치 - - cordova plugin add org.apache.cordova.media - - -## 지원 되는 플랫폼 - -* 안 드 로이드 -* 블랙베리 10 -* iOS -* Windows Phone 7과 8 -* Tizen -* 윈도우 8 - -## Windows Phone 단점 - -* 한 번에 하나의 미디어 파일을 다시 재생할 수 있습니다. - -* 응용 프로그램 다른 미디어와 상호 작용 하는 방법에 대 한 엄격한 제한이 있다. [자세한 내용은 Microsoft 문서][1] 를 참조 하십시오. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## 미디어 - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### 매개 변수 - -* **src**: 오디오 콘텐츠를 포함 하는 URI. *(DOMString)* - -* **mediaSuccess**: (선택 사항) 후 실행 되는 콜백 한 `Media` 개체 현재 재생, 기록, 또는 중지 작업을 완료 했습니다. *(기능)* - -* **mediaError**: (선택 사항) 오류가 발생 하면 실행 되는 콜백. *(기능)* - -* **mediaStatus**: (선택 사항) 상태 변화를 나타내기 위해 실행 하는 콜백. *(기능)* - -### 상수 - -다음 상수를 유일한 매개 변수로 보고 되는 `mediaStatus` 콜백: - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED` = 3; -* `Media.MEDIA_STOPPED` = 4; - -### 메서드 - -* `media.getCurrentPosition`: 오디오 파일 내에서 현재 위치를 반환합니다. - -* `media.getDuration`: 오디오 파일의 기간을 반환합니다. - -* `media.play`: 시작 또는 오디오 파일 재생을 다시 시작 합니다. - -* `media.pause`: 오디오 파일의 재생을 일시 중지 합니다. - -* `media.release`: 기본 운영 체제의 오디오 리소스를 해제합니다. - -* `media.seekTo`: 오디오 파일 내에서 위치를 이동합니다. - -* `media.setVolume`: 오디오 재생 볼륨을 설정 합니다. - -* `media.startRecord`: 오디오 파일을 녹음을 시작 합니다. - -* `media.stopRecord`: 오디오 파일 기록을 중지 합니다. - -* `media.stop`: 오디오 파일 재생을 중지 합니다. - -### 추가 읽기 전용 매개 변수 - -* **위치**: 위치 오디오 재생 시간 (초). - - * 플레이; 하는 동안 자동으로 업데이트 전화 `getCurrentPosition` 를 업데이트 합니다. - -* **기간**: 기간, 매체의 초. - -## media.getCurrentPosition - -오디오 파일 내에서 현재 위치를 반환합니다. 또한 업데이트는 `Media` 개체의 `position` 매개 변수. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### 매개 변수 - -* **mediaSuccess**: 현재 위치 (초) 전달 되는 콜백. - -* **mediaError**: (선택 사항) 콜백 실행 오류가 발생 하는 경우에. - -### 빠른 예제 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -초 오디오 파일의 기간을 반환합니다. 기간을 알 수 없는 경우-1 값을 반환 합니다. - - media.getDuration(); - - -### 빠른 예제 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## media.pause - -오디오 파일 재생을 일시 중지 합니다. - - media.pause(); - - -### 빠른 예제 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## media.play - -시작 또는 오디오 파일 재생을 다시 시작 합니다. - - media.play(); - - -### 빠른 예제 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS 단점 - -* **numberOfLoops**:이 옵션을 전달할는 `play` 시간을 재생 하려면, 예를 들어 미디어 파일의 수를 지정 하는 방법: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**:이 옵션을 전달할는 `play` 메서드는 화면이 잠겨 때 재생 수 있도록 지정 하려면. 만약 설정 `true` (기본값) 하드웨어 음소거 버튼의 상태, 예를 들면 무시 됩니다: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **파일 검색의 순서**: iOS에서 검색 한 파일 이름 또는 간단한 경로 제공 하는 경우는 `www` 파일을 다음 응용 프로그램의 디렉터리 `documents/tmp` 디렉터리: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -기본 운영 체제의 오디오 리소스를 해제합니다. 이것은 유한 양의 미디어 재생용 OpenCore 인스턴스 때문에 안 드 로이드를 위해 특히 중요 하다입니다. 응용 프로그램 호출 해야는 `release` 함수에 대 한 `Media` 리소스를 더 이상 필요 합니다. - - media.release(); - - -### 빠른 예제 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -오디오 파일 내의 현재 위치를 설정합니다. - - media.seekTo(milliseconds); - - -### 매개 변수 - -* **밀리초**: 밀리초에서는 오디오에서 재생 위치를 설정 하는 위치. - -### 빠른 예제 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### 블랙베리 10 단점 - -* 블랙베리 OS 5 장치에서 지원 되지 않습니다. - -## media.setVolume - -오디오 파일의 볼륨을 설정 합니다. - - media.setVolume(volume); - - -### 매개 변수 - -* **볼륨**: 볼륨 재생을 위한 설정. 값은 0.0에서 1.0의 범위 내에서 해야 합니다. - -### 지원 되는 플랫폼 - -* 안 드 로이드 -* iOS - -### 빠른 예제 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -오디오 파일 녹음을 시작 합니다. - - media.startRecord(); - - -### 지원 되는 플랫폼 - -* 안 드 로이드 -* iOS -* Windows Phone 7과 8 -* 윈도우 8 - -### 빠른 예제 - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### 안 드 로이드 단점 - -* 안 드 로이드 장치 적응 다중 속도 형식에서 오디오를 기록합니다. 지정 된 파일 *.amr* 확장명으로 끝나야 합니다. - -### iOS 단점 - -* iOS만 레코드 형식을 *.wav* 및 반환 오류 경우 파일 이름 확장명의 파일을 수정 하지. - -* 전체 경로 제공 하지 않으면 응용 프로그램의 기록 배치 됩니다 `documents/tmp` 디렉터리. 이 통해 액세스할 수 있는 `File` API를 사용 하 여 `LocalFileSystem.TEMPORARY` . 기록 시간에 지정 된 하위 디렉터리에 이미 존재 해야 합니다. - -* 파일을 기록 하 고 재생할 수 있습니다 문서 URI를 사용 하 여 다시: - - var myMedia = new Media("documents://beer.mp3") - - -### 윈도우 8 단점 - -* 전체 경로 제공 하지 않으면 녹음 AppData/temp 디렉터리에 배치 됩니다. 이 통해 액세스할 수 있는 `파일` API를 사용 하 여 `LocalFileSystem.TEMPORARY` 또는 ' ms appdata: 온도 / / / /<filename>' URI. - -* 기록 시간에 지정 된 하위 디렉터리에 이미 존재 해야 합니다. - -### Tizen 특수 - -* Tizen 장치에서 지원 되지 않습니다. - -## media.stop - -오디오 파일 재생을 중지 합니다. - - media.stop(); - - -### 빠른 예제 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -오디오 파일 녹음을 중지 합니다. - - media.stopRecord(); - - -### 지원 되는 플랫폼 - -* 안 드 로이드 -* iOS -* Windows Phone 7과 8 -* 윈도우 8 - -### 빠른 예제 - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Tizen 특수 - -* Tizen 장치에서 지원 되지 않습니다. - -## MediaError - -A `MediaError` 개체에 반환 됩니다는 `mediaError` 콜백 함수 오류가 발생 합니다. - -### 속성 - -* **코드**: 미리 정의 된 오류 코드 중 하나가 아래에 나열 된. - -* **메시지**: 오류 세부 정보를 설명 하는 오류 메시지. - -### 상수 - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/pl/index.md b/plugins/org.apache.cordova.media/doc/pl/index.md deleted file mode 100644 index 81fdb311..00000000 --- a/plugins/org.apache.cordova.media/doc/pl/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -Plugin daje możliwość nagrywania i odtwarzania plików audio na urządzeniu. - -**Uwaga**: Obecna implementacja nie stosować się do specyfikacji W3C do przechwytywania mediów i jest dostarczane jedynie dla wygody. Przyszłej realizacji będą przylegać do najnowszych specyfikacji W3C i może potępiać bieżące interfejsów API. - -## Instalacja - - cordova plugin add org.apache.cordova.media - - -## Obsługiwane platformy - -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 i 8 -* Tizen -* Windows 8 - -## Windows Phone dziwactwa - -* Tylko jeden plik mogą być zagrany w tył w czasie. - -* Istnieją ścisłe ograniczenia na jak aplikacja współdziała z innymi mediami. Zobacz [Microsoft dokumentacji szczegóły][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Media - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### Parametry - -* **src**: URI zawierający zawartość audio. *(DOMString)* - -* **mediaSuccess**: (opcjonalne) wywołania zwrotnego, który wykonuje po `Media` obiektu została zakończona bieżącej gry, rekordu lub działania stop. *(Funkcja)* - -* **mediaError**: (opcjonalne) wywołania zwrotnego, która wykonuje w przypadku wystąpienia błędu. *(Funkcja)* - -* **mediaStatus**: (opcjonalne) wywołania zwrotnego, który wykonuje wskazać zmiany statusu. *(Funkcja)* - -### Stałe - -Poniższe stałe są zgłaszane jako parametr tylko do `mediaStatus` wywołania zwrotnego: - -* `Media.MEDIA_NONE`= 0; -* `Media.MEDIA_STARTING`= 1; -* `Media.MEDIA_RUNNING`= 2; -* `Media.MEDIA_PAUSED`= 3; -* `Media.MEDIA_STOPPED`= 4; - -### Metody - -* `media.getCurrentPosition`: Zwraca bieżącej pozycji w pliku audio. - -* `media.getDuration`: Zwraca czas trwania pliku audio. - -* `media.play`: Rozpoczęcie lub wznowienie odtwarzania pliku audio. - -* `media.pause`: Wstrzymanie odtwarzania pliku audio. - -* `media.release`: Zwalnia zasoby audio system operacyjny. - -* `media.seekTo`: Porusza się pozycji w pliku audio. - -* `media.setVolume`: Ustaw głośność odtwarzania dźwięku. - -* `media.startRecord`: Nagrywanie pliku audio. - -* `media.stopRecord`: Zatrzymaj nagrywanie pliku audio. - -* `media.stop`: Zatrzymania odtwarzania pliku audio. - -### Parametry dodatkowe ReadOnly - -* **stanowisko**: stanowisko w odtwarzaniu dźwięku, w kilka sekund. - - * Nie jest automatycznie aktualizowana podczas odtwarzania; wywołanie `getCurrentPosition` aktualizacji. - -* **czas**: trwania mediów, w kilka sekund. - -## media.getCurrentPosition - -Zwraca bieżącą pozycję w pliku audio. Również aktualizacje `Media` obiektu `position` parametr. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### Parametry - -* **mediaSuccess**: wywołania zwrotnego, który jest przekazywany bieżącej pozycji w kilka sekund. - -* **mediaError**: (opcjonalne) wywołanie zwrotne do wykonać, jeśli wystąpi błąd. - -### Szybki przykład - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -Zwraca czas trwania pliku audio w kilka sekund. Jeśli czas trwania jest nieznane, to zwraca wartość -1. - - media.getDuration(); - - -### Szybki przykład - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## Media.Pause - -Wstrzymuje odtwarzanie pliku audio. - - media.pause(); - - -### Szybki przykład - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## Media.play - -Rozpoczyna się lub wznawia odtwarzanie pliku audio. - - media.play(); - - -### Szybki przykład - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### Dziwactwa iOS - -* **numberOfLoops**: przekazać tę opcję, aby `play` Metoda, aby określić ile razy chcesz, pliku multimedialnego do gry, np.: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**: przekazać tę opcję, aby `play` Metoda, aby określić, czy chcesz umożliwić odtwarzanie, gdy ekran jest zablokowana. Jeśli zestaw `true` (wartość domyślna), stan przycisku Wycisz sprzętu jest ignorowane, np.: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **kolejność wyszukiwania plików**: gdy tylko nazwa pliku lub ścieżka prosta pod warunkiem, iOS wyszukiwania w `www` katalogu, pliku, a następnie w aplikacji `documents/tmp` katalogu: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -Zwalnia zasoby audio system operacyjny. Jest to szczególnie ważne dla systemu Android, ponieważ istnieje skończona ilość podstawie OpenCore wystąpień do odtwarzania multimediów. Aplikacje powinny wywoływać `release` funkcja dla każdego `Media` zasób, który nie jest już potrzebna. - - media.release(); - - -### Szybki przykład - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Ustawia bieżącej pozycji w pliku audio. - - media.seekTo(milliseconds); - - -### Parametry - -* **milisekund**: stanowisko ustala pozycję odtwarzania w audio, w milisekundach. - -### Szybki przykład - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### Jeżyna 10 dziwactwa - -* Nie obsługiwane na urządzeniach BlackBerry OS w wersji 5. - -## media.setVolume - -Ustaw głośność pliku audio. - - media.setVolume(volume); - - -### Parametry - -* **wielkość**: wielkość ustawić odtwarzanie. Wartość musi być z zakresu od 0.0 do 1.0. - -### Obsługiwane platformy - -* Android -* iOS - -### Szybki przykład - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Rozpoczyna nagrywanie pliku audio. - - media.startRecord(); - - -### Obsługiwane platformy - -* Android -* iOS -* Windows Phone 7 i 8 -* Windows 8 - -### Szybki przykład - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Dziwactwa Androida - -* Urządzenia z systemem Android nagrywanie dźwięku w formacie Adaptive Multi-Rate. Określony plik powinien kończyć się rozszerzeniem *AMR* . - -### Dziwactwa iOS - -* iOS tylko rekordy do plików typu *.wav* i zwraca błąd, jeśli nazwa pliku rozszerzenie jest nie prawidłowe. - -* Jeśli nie podano pełną ścieżkę, nagrywanie jest umieszczony w aplikacji `documents/tmp` katalogu. To mogą być dostępne za pośrednictwem `File` za pomocą interfejsu API `LocalFileSystem.TEMPORARY` . Każdy podkatalog określony w rekordowym czasie musi już istnieć. - -* Pliki mogą być zapisywane i grał z powrotem za pomocą dokumentów URI: - - var myMedia = new Media("documents://beer.mp3") - - -### Windows 8 dziwactwa - -* Jeśli nie podano pełną ścieżkę, nagrywanie jest umieszczony w katalogu AppData/temp. To mogą być dostępne za pośrednictwem `Plik` Za pomocą interfejsu API `LocalFileSystem.TEMPORARY` lub "ms-appdata: temp / / / /<filename>"URI. - -* Każdy podkatalog określony w rekordowym czasie musi już istnieć. - -### Dziwactwa Tizen - -* Nie obsługiwane na Tizen urządzenia. - -## media.stop - -Zatrzymuje odtwarzanie pliku audio. - - Media.stop(); - - -### Szybki przykład - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Zatrzymuje nagrywanie pliku audio. - - media.stopRecord(); - - -### Obsługiwane platformy - -* Android -* iOS -* Windows Phone 7 i 8 -* Windows 8 - -### Szybki przykład - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Dziwactwa Tizen - -* Nie obsługiwane na Tizen urządzenia. - -## MediaError - -A `MediaError` obiekt jest zwracany do `mediaError` funkcji wywołania zwrotnego, gdy wystąpi błąd. - -### Właściwości - -* **Kod**: jeden z kodów błędów wstępnie zdefiniowanych poniżej. - -* **wiadomość**: komunikat o błędzie, opisując szczegóły błędu. - -### Stałe - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/ru/index.md b/plugins/org.apache.cordova.media/doc/ru/index.md deleted file mode 100644 index facda0f8..00000000 --- a/plugins/org.apache.cordova.media/doc/ru/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -Этот плагин предоставляет возможность записывать и воспроизводить аудио файлы на устройство. - -**Примечание**: Текущая реализация не соответствует спецификации W3C для захвата СМИ и предоставляется только для удобства. Будущее осуществление будет придерживаться последней спецификации W3C и может Опознайте текущих API. - -## Установка - - cordova plugin add org.apache.cordova.media - - -## Поддерживаемые платформы - -* Android -* BlackBerry 10 -* iOS -* Windows Phone 7 и 8 -* Tizen -* Windows 8 - -## Windows Phone причуды - -* Только один файл может воспроизводиться одновременно. - -* Существуют строгие ограничения в отношении как ваше приложение взаимодействует с другими средствами массовой информации. Смотрите в [документации Microsoft для подробной информации][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## Аудио и видео - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### Параметры - -* **src**: URI, содержащий аудио-контент. *(DOMString)* - -* **mediaSuccess**: (необязательно) обратного вызова, который выполняется после `Media` объект завершения текущего воспроизведения, записи или стоп действий. *(Функция)* - -* **mediaError**: (необязательно) обратного вызова, который выполняется при возникновении ошибки. *(Функция)* - -* **mediaStatus**: (необязательно) обратного вызова, который выполняется для отображения изменений состояния. *(Функция)* - -### Константы - -Следующие константы сообщается как единственный параметр для `mediaStatus` обратного вызова: - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED` = 3; -* `Media.MEDIA_STOPPED` = 4; - -### Методы - -* `media.getCurrentPosition`: Возвращает текущую позицию в аудиофайл. - -* `media.getDuration`: Возвращает продолжительность звукового файла. - -* `media.play`: Начать или возобновить воспроизведение звукового файла. - -* `media.pause`: Приостановка воспроизведения звукового файла. - -* `media.release`: Выпускает аудио ресурсы базовой операционной системы. - -* `media.seekTo`: Перемещает положение в пределах звукового файла. - -* `media.setVolume`: Задайте громкость воспроизведения звука. - -* `media.startRecord`: Начните запись звукового файла. - -* `media.stopRecord`: Остановите запись аудио файлов. - -* `media.stop`: Остановка воспроизведения звукового файла. - -### Дополнительные ReadOnly параметры - -* **позиции**: позиция в аудио воспроизведения в секундах. - - * Не автоматически обновляются во время игры; Вызовите `getCurrentPosition` для обновления. - -* **Продолжительность**: продолжительность СМИ, в секундах. - -## media.getCurrentPosition - -Возвращает текущую позицию в звуковой файл. Также обновляет `Media` объекта `position` параметр. - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### Параметры - -* **mediaSuccess**: обратный вызов, который передается в текущую позицию в секундах. - -* **mediaError**: (необязательно) обратного вызова для выполнения, если происходит ошибка. - -### Краткий пример - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -Возвращает продолжительность аудио файла в секундах. Если длительность неизвестна, она возвращает значение -1. - - media.getDuration(); - - -### Краткий пример - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## Media.Pause - -Приостанавливает воспроизведение звукового файла. - - media.pause(); - - -### Краткий пример - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## Media.Play - -Запускает или возобновляет воспроизведение звукового файла. - - media.play(); - - -### Краткий пример - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### Особенности iOS - -* **numberOfLoops**: этот параметр, чтобы передать `play` метод, чтобы указать количество раз, вы хотите, чтобы средства массовой информации файла для воспроизведения, например: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**: передайте этот параметр для `play` метод, чтобы указать, хотите ли вы разрешить воспроизведение, когда экран заблокирован. Если значение `true` (значение по умолчанию), состояние оборудования безгласную кнопку игнорируется, например: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **Порядок поиска файла**: когда предоставляется только имя файла или простой путь, iOS ищет в `www` каталог для файла, а затем в приложении `documents/tmp` каталога: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -Освобождает ресурсы аудио базовой операционной системы. Это особенно важно для Android, так как существует конечное количество экземпляров OpenCore для воспроизведения мультимедиа. Приложения должны вызвать `release` функция для любого `Media` ресурс, который больше не нужен. - - media.release(); - - -### Краткий пример - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -Задает текущую позицию в течение звукового файла. - - media.seekTo(milliseconds); - - -### Параметры - -* **МС**: позиции задать позицию воспроизведения в аудио, в миллисекундах. - -### Краткий пример - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### Особенности BlackBerry 10 - -* Не поддерживается на устройствах BlackBerry OS 5. - -## media.setVolume - -Задайте громкость звукового файла. - - media.setVolume(volume); - - -### Параметры - -* **объем**: тома, чтобы задать для воспроизведения. Значение должно быть в диапазоне от 0.0 до 1.0. - -### Поддерживаемые платформы - -* Android -* iOS - -### Краткий пример - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -Начинает запись аудио файлов. - - media.startRecord(); - - -### Поддерживаемые платформы - -* Android -* iOS -* Windows Phone 7 и 8 -* Windows 8 - -### Краткий пример - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Особенности Android - -* Android устройств записи аудио в формате адаптивной мульти ставка. Указанный файл должен заканчиваться *.amr* расширение. - -### Особенности iOS - -* iOS только записи в файлы типа *.wav* и возвращает ошибку, если расширение не исправить. - -* Если полный путь не указан, запись помещается в приложения `documents/tmp` каталог. Это могут быть доступны через `File` API с помощью `LocalFileSystem.TEMPORARY` . Любой подкаталог, указанный на время записи должны уже существовать. - -* Файлы могут быть и сыграны записываются обратно, используя документы URI: - - var myMedia = new Media("documents://beer.mp3") - - -### Совместимости Windows 8 - -* Если не указан полный путь, запись помещается в каталоге AppData/temp. Это могут быть доступны через `Файл` С помощью API `LocalFileSystem.TEMPORARY` или ' ms-appdata: / / / temp /<filename>' URI. - -* Любой подкаталог указанного в рекордное время должна уже существовать. - -### Особенности Tizen - -* Не поддерживается на устройствах Tizen. - -## media.stop - -Останавливает воспроизведение звукового файла. - - media.stop(); - - -### Краткий пример - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -Прекращает запись аудио файлов. - - media.stopRecord(); - - -### Поддерживаемые платформы - -* Android -* iOS -* Windows Phone 7 и 8 -* Windows 8 - -### Краткий пример - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### Особенности Tizen - -* Не поддерживается на устройствах Tizen. - -## MediaError - -A `MediaError` объект возвращается к `mediaError` функции обратного вызова при возникновении ошибки. - -### Параметры - -* **code**: один из стандартных кодов ошибок, перечисленных ниже. - -* **сообщение**: сообщение об ошибке, с подробными сведениями об ошибке. - -### Константы - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/doc/zh/index.md b/plugins/org.apache.cordova.media/doc/zh/index.md deleted file mode 100644 index c94104a8..00000000 --- a/plugins/org.apache.cordova.media/doc/zh/index.md +++ /dev/null @@ -1,494 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.media - -這個外掛程式提供錄製和播放設備上的音訊檔的能力。 - -**注**: 當前的實現並不遵循 W3C 規範的媒體捕獲和僅用於提供方便。 將來的實現將堅持以最新的 W3C 規範和可能棄用當前 Api。 - -## 安裝 - - cordova plugin add org.apache.cordova.media - - -## 支援的平臺 - -* Android 系統 -* 黑莓 10 -* iOS -* Windows Phone 7 和 8 -* Tizen -* Windows 8 - -## Windows Phone 怪癖 - -* 只有一個媒體檔案,可以播放一次。 - -* 沒有嚴格限制對您的應用程式與其他媒體的對話模式。 請參見[Microsoft 文檔的詳細資訊][1]. - - [1]: http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh184838(v=vs.92).aspx - -## 媒體 - - var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - - -### 參數 - -* **src**: 包含音訊內容的 URI。*() DOMString* - -* **mediaSuccess**: (可選) 後執行的回檔 `Media` 物件已完成當前戲劇、 記錄或停止行動。*(函數)* - -* **mediaError**: (可選) 如果錯誤發生時執行的回檔。*(函數)* - -* **mediaStatus**: (可選) 執行以指示狀態的更改的回檔。*(函數)* - -### 常量 - -以下常量作為唯一的參數到據報告 `mediaStatus` 回檔: - -* `Media.MEDIA_NONE` = 0; -* `Media.MEDIA_STARTING` = 1; -* `Media.MEDIA_RUNNING` = 2; -* `Media.MEDIA_PAUSED`= 3 ; -* `Media.MEDIA_STOPPED`= 4 ; - -### 方法 - -* `media.getCurrentPosition`: 返回一個音訊檔內的當前位置。 - -* `media.getDuration`: 返回一個音訊檔的持續時間。 - -* `media.play`: 啟動或繼續播放音訊檔。 - -* `media.pause`: 暫停播放的音訊檔。 - -* `media.release`: 釋放底層作業系統的音訊資源。 - -* `media.seekTo`: 在音訊檔內移動的位置。 - -* `media.setVolume`: 設置音訊播放的音量。 - -* `media.startRecord`: 開始錄製的音訊檔。 - -* `media.stopRecord`: 停止錄製的音訊檔。 - -* `media.stop`: 停止播放音訊檔。 - -### 附加唯讀參數 - -* **位置**: 內音訊播放,以秒為單位的位置。 - - * 不會自動更新期間播放 ;調用 `getCurrentPosition` 來更新。 - -* **持續時間**: 媒體的持續時間以秒為單位。 - -## media.getCurrentPosition - -返回一個音訊檔內的當前位置。此外可以更新 `Media` 物件的 `position` 參數。 - - media.getCurrentPosition(mediaSuccess, [mediaError]); - - -### 參數 - -* **mediaSuccess**: 傳遞的當前的位置,以秒為單位的回檔。 - -* **mediaError**: (可選) 回檔執行如果發生錯誤。 - -### 快速的示例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Update media position every second - var mediaTimer = setInterval(function () { - // get media position - my_media.getCurrentPosition( - // success callback - function (position) { - if (position > -1) { - console.log((position) + " sec"); - } - }, - // error callback - function (e) { - console.log("Error getting pos=" + e); - } - ); - }, 1000); - - -## media.getDuration - -以秒為單位返回一個音訊檔的持續時間。如果持續時間是未知的則傳回值為-1。 - - media.getDuration(); - - -### 快速的示例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - // Get duration - var counter = 0; - var timerDur = setInterval(function() { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = my_media.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('audio_duration').innerHTML = (dur) + " sec"; - } - }, 100); - - -## media.pause - -暫停播放音訊檔。 - - media.pause(); - - -### 快速的示例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { console.log("playAudio():Audio Success"); }, - // error callback - function (err) { console.log("playAudio():Audio Error: " + err); } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function () { - media.pause(); - }, 10000); - } - - -## media.play - -開始或重新開始播放音訊檔。 - - media.play(); - - -### 快速的示例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function () { - console.log("playAudio():Audio Success"); - }, - // error callback - function (err) { - console.log("playAudio():Audio Error: " + err); - } - ); - // Play audio - my_media.play(); - } - - -### iOS 的怪癖 - -* **numberOfLoops**: 傳遞到此選項 `play` 方法,以指定的次數,你想讓媒體檔案以播放,例如: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ numberOfLoops: 2 }) - - -* **playAudioWhenScreenIsLocked**: 通過此選項可在 `play` 方法,以指定您是否要允許播放時螢幕鎖定。 如果設置為 `true` (預設值),將忽略硬體靜音按鈕的狀態,例如: - - var myMedia = new Media("http://audio.ibeat.org/content/p1rj1s/p1rj1s_-_rockGuitar.mp3") - myMedia.play({ playAudioWhenScreenIsLocked : false }) - - -* **檔搜索順序**: 當只有一個檔的名稱或簡單路徑提供時,搜索中的 iOS `www` 目錄為該檔,然後在應用程式中的 `documents/tmp` 目錄: - - var myMedia = new Media("audio/beer.mp3") - myMedia.play() // first looks for file in www/audio/beer.mp3 then in <application>/documents/tmp/audio/beer.mp3 - - -## media.release - -釋放底層作業系統的音訊資源。 這是特別重要的 android 作業系統,因為有了有限數量的 OpenCore 實例播放媒體。 應用程式應當調用 `release` 函數的任何 `Media` 不再需要的資源。 - - media.release(); - - -### 快速的示例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - - my_media.play(); - my_media.stop(); - my_media.release(); - - -## media.seekTo - -在音訊檔中設置的當前的位置。 - - media.seekTo(milliseconds); - - -### 參數 - -* **毫秒為單位)**: 要以毫秒為單位設置中,音訊的播放位置的位置。 - -### 快速的示例 - - // Audio player - // - var my_media = new Media(src, onSuccess, onError); - my_media.play(); - // SeekTo to 10 seconds after 5 seconds - setTimeout(function() { - my_media.seekTo(10000); - }, 5000); - - -### 黑莓 10 怪癖 - -* 黑莓 OS 5 設備上不支援。 - -## media.setVolume - -設置音訊檔的音量。 - - media.setVolume(volume) ; - - -### 參數 - -* **體積**: 要為播放設置的卷。值必須在 0.0 到 1.0 的範圍內。 - -### 支援的平臺 - -* Android 系統 -* iOS - -### 快速的示例 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - }); - - // Play audio - my_media.play(); - - // Mute volume after 2 seconds - setTimeout(function() { - my_media.setVolume('0.0'); - }, 2000); - - // Set volume to 1.0 after 5 seconds - setTimeout(function() { - my_media.setVolume('1.0'); - }, 5000); - } - - -## media.startRecord - -開始錄製的音訊檔。 - - media.startRecord() ; - - -### 支援的平臺 - -* Android 系統 -* iOS -* Windows Phone 7 和 8 -* Windows 8 - -### 快速的示例 - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - }); - - // Record audio - mediaRec.startRecord(); - } - - -### Android 的怪癖 - -* Android 設備音訊格式記錄的自我調整多速率。指定的檔應以*.amr*副檔名結尾。 - -### iOS 的怪癖 - -* iOS 只記錄到檔的類型*.wav*和返回一個錯誤如果檔副檔名不正確。 - -* 如果未提供的完整路徑,錄音放在應用程式的 `documents/tmp` 目錄。 這可以通過訪問 `File` API 使用 `LocalFileSystem.TEMPORARY` 。 在記錄時指定的任何子目錄中必須已經存在。 - -* 檔可以記錄和演奏的後面使用的檔的 URI: - - var myMedia = new Media("documents://beer.mp3") - - -### Windows 8 的怪癖 - -* 如果沒有提供完整的路徑,錄音被放在應用程式/temp 目錄。這可以通過訪問 `檔` API 使用 `LocalFileSystem.TEMPORARY` 或 ' ms appdata: temp / / /<filename>' URI。 - -* 在記錄時指定的任何子目錄中必須已經存在。 - -### 泰怪癖 - -* 不支援在 Tizen 設備上。 - -## media.stop - -停止播放音訊檔。 - - media.stop() ; - - -### 簡單的例子 - - // Play audio - // - function playAudio(url) { - // Play the audio file at url - var my_media = new Media(url, - // success callback - function() { - console.log("playAudio():Audio Success"); - }, - // error callback - function(err) { - console.log("playAudio():Audio Error: "+err); - } - ); - - // Play audio - my_media.play(); - - // Pause after 10 seconds - setTimeout(function() { - my_media.stop(); - }, 10000); - } - - -## media.stopRecord - -停止錄製音訊檔。 - - media.stopRecord() ; - - -### 支援的平臺 - -* 安卓系統 -* iOS -* Windows Phone 7 和 8 -* Windows 8 - -### 簡單的例子 - - // Record audio - // - function recordAudio() { - var src = "myrecording.mp3"; - var mediaRec = new Media(src, - // success callback - function() { - console.log("recordAudio():Audio Success"); - }, - - // error callback - function(err) { - console.log("recordAudio():Audio Error: "+ err.code); - } - ); - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 seconds - setTimeout(function() { - mediaRec.stopRecord(); - }, 10000); - } - - -### 泰怪癖 - -* 不支援在 Tizen 設備上。 - -## MediaError - -A `MediaError` 物件返回到 `mediaError` 時出現錯誤的回呼函數。 - -### 屬性 - -* **代碼**: 下面列出的預定義的錯誤代碼之一。 - -* **消息**: 錯誤訊息,描述該錯誤的詳細資訊。 - -### 常量 - -* `MediaError.MEDIA_ERR_ABORTED`= 1 -* `MediaError.MEDIA_ERR_NETWORK`= 2 -* `MediaError.MEDIA_ERR_DECODE`= 3 -* `MediaError.MEDIA_ERR_NONE_SUPPORTED`= 4
\ No newline at end of file diff --git a/plugins/org.apache.cordova.media/plugin.xml b/plugins/org.apache.cordova.media/plugin.xml deleted file mode 100644 index dd2d08d7..00000000 --- a/plugins/org.apache.cordova.media/plugin.xml +++ /dev/null @@ -1,161 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" -xmlns:android="http://schemas.android.com/apk/res/android" -id="org.apache.cordova.media" - version="0.2.16"> - - <name>Media</name> - <description>Cordova Media Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,media</keywords> - <repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-media.git</repo> - <issue>https://issues.apache.org/jira/browse/CB/component/12320647</issue> - - <dependency id="org.apache.cordova.file" version=">=1.0.1" /> - - <js-module src="www/MediaError.js" name="MediaError"> - <clobbers target="window.MediaError" /> - </js-module> - - <js-module src="www/Media.js" name="Media"> - <clobbers target="window.Media" /> - </js-module> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Media" > - <param name="android-package" value="org.apache.cordova.media.AudioHandler"/> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/*"> - </config-file> - - <source-file src="src/android/AudioHandler.java" target-dir="src/org/apache/cordova/media" /> - <source-file src="src/android/AudioPlayer.java" target-dir="src/org/apache/cordova/media" /> - <source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/media" /> - </platform> - - <!-- amazon-fireos --> - <platform name="amazon-fireos"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Media" > - <param name="android-package" value="org.apache.cordova.media.AudioHandler"/> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/*"> - - </config-file> - - <source-file src="src/android/AudioHandler.java" target-dir="src/org/apache/cordova/media" /> - <source-file src="src/android/AudioPlayer.java" target-dir="src/org/apache/cordova/media" /> - <source-file src="src/android/FileHelper.java" target-dir="src/org/apache/cordova/media" /> - </platform> - - - <!-- ubuntu --> - <platform name="ubuntu"> - <config-file target="config.xml" parent="/*"> - <feature name="Media"> - <param policy_group="microphone" policy_version="1" /> - <param policy_group="video" policy_version="1" /> - </feature> - </config-file> - <header-file src="src/ubuntu/media.h" /> - <source-file src="src/ubuntu/media.cpp" /> - </platform> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="Media"> - <param name="ios-package" value="CDVSound" /> - </feature> - </config-file> - <header-file src="src/ios/CDVSound.h" /> - <source-file src="src/ios/CDVSound.m" /> - </platform> - - <!-- blackberry10 --> - <platform name="blackberry10"> - <source-file src="src/blackberry10/index.js" target-dir="Media" /> - <config-file target="www/config.xml" parent="/widget"> - <feature name="Media" value="Media"/> - </config-file> - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="config.xml" parent="/*"> - <feature name="Media"> - <param name="wp-package" value="Media"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_MEDIALIB"/> - <Capability Name="ID_CAP_MICROPHONE"/> - </config-file> - - <source-file src="src/wp/Media.cs" /> - <source-file src="src/wp/AudioPlayer.cs" /> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="Media"> - <param name="wp-package" value="Media"/> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_MEDIALIB_AUDIO"/> - <Capability Name="ID_CAP_MEDIALIB_PLAYBACK"/> - <Capability Name="ID_CAP_MICROPHONE"/> - </config-file> - - <source-file src="src/wp/Media.cs" /> - <source-file src="src/wp/AudioPlayer.cs" /> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="src/windows8/MediaProxy.js" name="MediaProxy"> - <merges target="" /> - </js-module> - - <config-file target="package.appxmanifest" parent="/Package/Capabilities"> - <Capability Name="musicLibrary" /> - <DeviceCapability Name="microphone" /> - </config-file> - </platform> - - <!-- tizen --> - <platform name="tizen"> - <js-module src="src/tizen/MediaProxy.js" name="MediaProxy"> - <runs/> - </js-module> - </platform> -</plugin> diff --git a/plugins/org.apache.cordova.media/src/android/AudioHandler.java b/plugins/org.apache.cordova.media/src/android/AudioHandler.java deleted file mode 100644 index f06b75a4..00000000 --- a/plugins/org.apache.cordova.media/src/android/AudioHandler.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.media; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaResourceApi; - -import android.content.Context; -import android.media.AudioManager; -import android.net.Uri; -import android.util.Log; - -import java.util.ArrayList; - -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; - -/** - * This class called by CordovaActivity to play and record audio. - * The file can be local or over a network using http. - * - * Audio formats supported (tested): - * .mp3, .wav - * - * Local audio files must reside in one of two places: - * android_asset: file name must start with /android_asset/sound.mp3 - * sdcard: file name is just sound.mp3 - */ -public class AudioHandler extends CordovaPlugin { - - public static String TAG = "AudioHandler"; - HashMap<String, AudioPlayer> players; // Audio player object - ArrayList<AudioPlayer> pausedForPhone; // Audio players that were paused when phone call came in - private int origVolumeStream = -1; - private CallbackContext messageChannel; - - /** - * Constructor. - */ - public AudioHandler() { - this.players = new HashMap<String, AudioPlayer>(); - this.pausedForPhone = new ArrayList<AudioPlayer>(); - } - - /** - * Executes the request and returns PluginResult. - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackContext The callback context used when calling back into JavaScript. - * @return A PluginResult object with a status and message. - */ - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - CordovaResourceApi resourceApi = webView.getResourceApi(); - PluginResult.Status status = PluginResult.Status.OK; - String result = ""; - - if (action.equals("startRecordingAudio")) { - String target = args.getString(1); - String fileUriStr; - try { - Uri targetUri = resourceApi.remapUri(Uri.parse(target)); - fileUriStr = targetUri.toString(); - } catch (IllegalArgumentException e) { - fileUriStr = target; - } - this.startRecordingAudio(args.getString(0), FileHelper.stripFileProtocol(fileUriStr)); - } - else if (action.equals("stopRecordingAudio")) { - this.stopRecordingAudio(args.getString(0)); - } - else if (action.equals("startPlayingAudio")) { - String target = args.getString(1); - String fileUriStr; - try { - Uri targetUri = resourceApi.remapUri(Uri.parse(target)); - fileUriStr = targetUri.toString(); - } catch (IllegalArgumentException e) { - fileUriStr = target; - } - this.startPlayingAudio(args.getString(0), FileHelper.stripFileProtocol(fileUriStr)); - } - else if (action.equals("seekToAudio")) { - this.seekToAudio(args.getString(0), args.getInt(1)); - } - else if (action.equals("pausePlayingAudio")) { - this.pausePlayingAudio(args.getString(0)); - } - else if (action.equals("stopPlayingAudio")) { - this.stopPlayingAudio(args.getString(0)); - } else if (action.equals("setVolume")) { - try { - this.setVolume(args.getString(0), Float.parseFloat(args.getString(1))); - } catch (NumberFormatException nfe) { - //no-op - } - } else if (action.equals("getCurrentPositionAudio")) { - float f = this.getCurrentPositionAudio(args.getString(0)); - callbackContext.sendPluginResult(new PluginResult(status, f)); - return true; - } - else if (action.equals("getDurationAudio")) { - float f = this.getDurationAudio(args.getString(0), args.getString(1)); - callbackContext.sendPluginResult(new PluginResult(status, f)); - return true; - } - else if (action.equals("create")) { - String id = args.getString(0); - String src = FileHelper.stripFileProtocol(args.getString(1)); - getOrCreatePlayer(id, src); - } - else if (action.equals("release")) { - boolean b = this.release(args.getString(0)); - callbackContext.sendPluginResult(new PluginResult(status, b)); - return true; - } - else if (action.equals("messageChannel")) { - messageChannel = callbackContext; - return true; - } - else { // Unrecognized action. - return false; - } - - callbackContext.sendPluginResult(new PluginResult(status, result)); - - return true; - } - - /** - * Stop all audio players and recorders. - */ - public void onDestroy() { - if (!players.isEmpty()) { - onLastPlayerReleased(); - } - for (AudioPlayer audio : this.players.values()) { - audio.destroy(); - } - this.players.clear(); - } - - /** - * Stop all audio players and recorders on navigate. - */ - @Override - public void onReset() { - onDestroy(); - } - - /** - * Called when a message is sent to plugin. - * - * @param id The message id - * @param data The message data - * @return Object to stop propagation or null - */ - public Object onMessage(String id, Object data) { - - // If phone message - if (id.equals("telephone")) { - - // If phone ringing, then pause playing - if ("ringing".equals(data) || "offhook".equals(data)) { - - // Get all audio players and pause them - for (AudioPlayer audio : this.players.values()) { - if (audio.getState() == AudioPlayer.STATE.MEDIA_RUNNING.ordinal()) { - this.pausedForPhone.add(audio); - audio.pausePlaying(); - } - } - - } - - // If phone idle, then resume playing those players we paused - else if ("idle".equals(data)) { - for (AudioPlayer audio : this.pausedForPhone) { - audio.startPlaying(null); - } - this.pausedForPhone.clear(); - } - } - return null; - } - - //-------------------------------------------------------------------------- - // LOCAL METHODS - //-------------------------------------------------------------------------- - - private AudioPlayer getOrCreatePlayer(String id, String file) { - AudioPlayer ret = players.get(id); - if (ret == null) { - if (players.isEmpty()) { - onFirstPlayerCreated(); - } - ret = new AudioPlayer(this, id, file); - players.put(id, ret); - } - return ret; - } - - /** - * Release the audio player instance to save memory. - * @param id The id of the audio player - */ - private boolean release(String id) { - AudioPlayer audio = players.remove(id); - if (audio == null) { - return false; - } - if (players.isEmpty()) { - onLastPlayerReleased(); - } - audio.destroy(); - return true; - } - - /** - * Start recording and save the specified file. - * @param id The id of the audio player - * @param file The name of the file - */ - public void startRecordingAudio(String id, String file) { - AudioPlayer audio = getOrCreatePlayer(id, file); - audio.startRecording(file); - } - - /** - * Stop recording and save to the file specified when recording started. - * @param id The id of the audio player - */ - public void stopRecordingAudio(String id) { - AudioPlayer audio = this.players.get(id); - if (audio != null) { - audio.stopRecording(); - } - } - - /** - * Start or resume playing audio file. - * @param id The id of the audio player - * @param file The name of the audio file. - */ - public void startPlayingAudio(String id, String file) { - AudioPlayer audio = getOrCreatePlayer(id, file); - audio.startPlaying(file); - } - - /** - * Seek to a location. - * @param id The id of the audio player - * @param milliseconds int: number of milliseconds to skip 1000 = 1 second - */ - public void seekToAudio(String id, int milliseconds) { - AudioPlayer audio = this.players.get(id); - if (audio != null) { - audio.seekToPlaying(milliseconds); - } - } - - /** - * Pause playing. - * @param id The id of the audio player - */ - public void pausePlayingAudio(String id) { - AudioPlayer audio = this.players.get(id); - if (audio != null) { - audio.pausePlaying(); - } - } - - /** - * Stop playing the audio file. - * @param id The id of the audio player - */ - public void stopPlayingAudio(String id) { - AudioPlayer audio = this.players.get(id); - if (audio != null) { - audio.stopPlaying(); - } - } - - /** - * Get current position of playback. - * @param id The id of the audio player - * @return position in msec - */ - public float getCurrentPositionAudio(String id) { - AudioPlayer audio = this.players.get(id); - if (audio != null) { - return (audio.getCurrentPosition() / 1000.0f); - } - return -1; - } - - /** - * Get the duration of the audio file. - * @param id The id of the audio player - * @param file The name of the audio file. - * @return The duration in msec. - */ - public float getDurationAudio(String id, String file) { - AudioPlayer audio = getOrCreatePlayer(id, file); - return audio.getDuration(file); - } - - /** - * Set the audio device to be used for playback. - * - * @param output 1=earpiece, 2=speaker - */ - @SuppressWarnings("deprecation") - public void setAudioOutputDevice(int output) { - AudioManager audiMgr = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE); - if (output == 2) { - audiMgr.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_SPEAKER, AudioManager.ROUTE_ALL); - } - else if (output == 1) { - audiMgr.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL); - } - else { - System.out.println("AudioHandler.setAudioOutputDevice() Error: Unknown output device."); - } - } - - /** - * Get the audio device to be used for playback. - * - * @return 1=earpiece, 2=speaker - */ - @SuppressWarnings("deprecation") - public int getAudioOutputDevice() { - AudioManager audiMgr = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE); - if (audiMgr.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_EARPIECE) { - return 1; - } - else if (audiMgr.getRouting(AudioManager.MODE_NORMAL) == AudioManager.ROUTE_SPEAKER) { - return 2; - } - else { - return -1; - } - } - - /** - * Set the volume for an audio device - * - * @param id The id of the audio player - * @param volume Volume to adjust to 0.0f - 1.0f - */ - public void setVolume(String id, float volume) { - AudioPlayer audio = this.players.get(id); - if (audio != null) { - audio.setVolume(volume); - } else { - System.out.println("AudioHandler.setVolume() Error: Unknown Audio Player " + id); - } - } - - private void onFirstPlayerCreated() { - origVolumeStream = cordova.getActivity().getVolumeControlStream(); - cordova.getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC); - } - - private void onLastPlayerReleased() { - if (origVolumeStream != -1) { - cordova.getActivity().setVolumeControlStream(origVolumeStream); - origVolumeStream = -1; - } - } - - void sendEventMessage(String action, JSONObject actionData) { - JSONObject message = new JSONObject(); - try { - message.put("action", action); - if (actionData != null) { - message.put(action, actionData); - } - } catch (JSONException e) { - Log.e(TAG, "Failed to create event message", e); - } - - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, message); - pluginResult.setKeepCallback(true); - if (messageChannel != null) { - messageChannel.sendPluginResult(pluginResult); - } - } -} diff --git a/plugins/org.apache.cordova.media/src/android/AudioPlayer.java b/plugins/org.apache.cordova.media/src/android/AudioPlayer.java deleted file mode 100644 index 7524c5b6..00000000 --- a/plugins/org.apache.cordova.media/src/android/AudioPlayer.java +++ /dev/null @@ -1,587 +0,0 @@ -/* - 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. -*/ -package org.apache.cordova.media; - -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.media.MediaPlayer.OnCompletionListener; -import android.media.MediaPlayer.OnErrorListener; -import android.media.MediaPlayer.OnPreparedListener; -import android.media.MediaRecorder; -import android.os.Environment; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -/** - * This class implements the audio playback and recording capabilities used by Cordova. - * It is called by the AudioHandler Cordova class. - * Only one file can be played or recorded per class instance. - * - * Local audio files must reside in one of two places: - * android_asset: file name must start with /android_asset/sound.mp3 - * sdcard: file name is just sound.mp3 - */ -public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener { - - // AudioPlayer modes - public enum MODE { NONE, PLAY, RECORD }; - - // AudioPlayer states - public enum STATE { MEDIA_NONE, - MEDIA_STARTING, - MEDIA_RUNNING, - MEDIA_PAUSED, - MEDIA_STOPPED, - MEDIA_LOADING - }; - - private static final String LOG_TAG = "AudioPlayer"; - - // AudioPlayer message ids - private static int MEDIA_STATE = 1; - private static int MEDIA_DURATION = 2; - private static int MEDIA_POSITION = 3; - private static int MEDIA_ERROR = 9; - - // Media error codes - private static int MEDIA_ERR_NONE_ACTIVE = 0; - private static int MEDIA_ERR_ABORTED = 1; -// private static int MEDIA_ERR_NETWORK = 2; -// private static int MEDIA_ERR_DECODE = 3; -// private static int MEDIA_ERR_NONE_SUPPORTED = 4; - - private AudioHandler handler; // The AudioHandler object - private String id; // The id of this player (used to identify Media object in JavaScript) - private MODE mode = MODE.NONE; // Playback or Recording mode - private STATE state = STATE.MEDIA_NONE; // State of recording or playback - - private String audioFile = null; // File name to play or record to - private float duration = -1; // Duration of audio - - private MediaRecorder recorder = null; // Audio recording object - private String tempFile = null; // Temporary recording file name - - private MediaPlayer player = null; // Audio player object - private boolean prepareOnly = true; // playback after file prepare flag - private int seekOnPrepared = 0; // seek to this location once media is prepared - - /** - * Constructor. - * - * @param handler The audio handler object - * @param id The id of this audio player - */ - public AudioPlayer(AudioHandler handler, String id, String file) { - this.handler = handler; - this.id = id; - this.audioFile = file; - this.recorder = new MediaRecorder(); - - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - this.tempFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmprecording.3gp"; - } else { - this.tempFile = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/tmprecording.3gp"; - } - - } - - /** - * Destroy player and stop audio playing or recording. - */ - public void destroy() { - // Stop any play or record - if (this.player != null) { - if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) { - this.player.stop(); - this.setState(STATE.MEDIA_STOPPED); - } - this.player.release(); - this.player = null; - } - if (this.recorder != null) { - this.stopRecording(); - this.recorder.release(); - this.recorder = null; - } - } - - /** - * Start recording the specified file. - * - * @param file The name of the file - */ - public void startRecording(String file) { - switch (this.mode) { - case PLAY: - Log.d(LOG_TAG, "AudioPlayer Error: Can't record in play mode."); - sendErrorStatus(MEDIA_ERR_ABORTED); - break; - case NONE: - this.audioFile = file; - this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC); - this.recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); // THREE_GPP); - this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); //AMR_NB); - this.recorder.setOutputFile(this.tempFile); - try { - this.recorder.prepare(); - this.recorder.start(); - this.setState(STATE.MEDIA_RUNNING); - return; - } catch (IllegalStateException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - - sendErrorStatus(MEDIA_ERR_ABORTED); - break; - case RECORD: - Log.d(LOG_TAG, "AudioPlayer Error: Already recording."); - sendErrorStatus(MEDIA_ERR_ABORTED); - } - } - - /** - * Save temporary recorded file to specified name - * - * @param file - */ - public void moveFile(String file) { - /* this is a hack to save the file as the specified name */ - File f = new File(this.tempFile); - - if (!file.startsWith("/")) { - if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - file = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + file; - } else { - file = "/data/data/" + handler.cordova.getActivity().getPackageName() + "/cache/" + file; - } - } - - String logMsg = "renaming " + this.tempFile + " to " + file; - Log.d(LOG_TAG, logMsg); - if (!f.renameTo(new File(file))) Log.e(LOG_TAG, "FAILED " + logMsg); - } - - /** - * Stop recording and save to the file specified when recording started. - */ - public void stopRecording() { - if (this.recorder != null) { - try{ - if (this.state == STATE.MEDIA_RUNNING) { - this.recorder.stop(); - this.setState(STATE.MEDIA_STOPPED); - } - this.recorder.reset(); - this.moveFile(this.audioFile); - } - catch (Exception e) { - e.printStackTrace(); - } - } - } - - //========================================================================== - // Playback - //========================================================================== - - /** - * Start or resume playing audio file. - * - * @param file The name of the audio file. - */ - public void startPlaying(String file) { - if (this.readyPlayer(file) && this.player != null) { - this.player.start(); - this.setState(STATE.MEDIA_RUNNING); - this.seekOnPrepared = 0; //insures this is always reset - } else { - this.prepareOnly = false; - } - } - - /** - * Seek or jump to a new time in the track. - */ - public void seekToPlaying(int milliseconds) { - if (this.readyPlayer(this.audioFile)) { - this.player.seekTo(milliseconds); - Log.d(LOG_TAG, "Send a onStatus update for the new seek"); - sendStatusChange(MEDIA_POSITION, null, (milliseconds / 1000.0f)); - } - else { - this.seekOnPrepared = milliseconds; - } - } - - /** - * Pause playing. - */ - public void pausePlaying() { - - // If playing, then pause - if (this.state == STATE.MEDIA_RUNNING && this.player != null) { - this.player.pause(); - this.setState(STATE.MEDIA_PAUSED); - } - else { - Log.d(LOG_TAG, "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal()); - sendErrorStatus(MEDIA_ERR_NONE_ACTIVE); - } - } - - /** - * Stop playing the audio file. - */ - public void stopPlaying() { - if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) { - this.player.pause(); - this.player.seekTo(0); - Log.d(LOG_TAG, "stopPlaying is calling stopped"); - this.setState(STATE.MEDIA_STOPPED); - } - else { - Log.d(LOG_TAG, "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal()); - sendErrorStatus(MEDIA_ERR_NONE_ACTIVE); - } - } - - /** - * Callback to be invoked when playback of a media source has completed. - * - * @param player The MediaPlayer that reached the end of the file - */ - public void onCompletion(MediaPlayer player) { - Log.d(LOG_TAG, "on completion is calling stopped"); - this.setState(STATE.MEDIA_STOPPED); - } - - /** - * Get current position of playback. - * - * @return position in msec or -1 if not playing - */ - public long getCurrentPosition() { - if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) { - int curPos = this.player.getCurrentPosition(); - sendStatusChange(MEDIA_POSITION, null, (curPos / 1000.0f)); - return curPos; - } - else { - return -1; - } - } - - /** - * Determine if playback file is streaming or local. - * It is streaming if file name starts with "http://" - * - * @param file The file name - * @return T=streaming, F=local - */ - public boolean isStreaming(String file) { - if (file.contains("http://") || file.contains("https://")) { - return true; - } - else { - return false; - } - } - - /** - * Get the duration of the audio file. - * - * @param file The name of the audio file. - * @return The duration in msec. - * -1=can't be determined - * -2=not allowed - */ - public float getDuration(String file) { - - // Can't get duration of recording - if (this.recorder != null) { - return (-2); // not allowed - } - - // If audio file already loaded and started, then return duration - if (this.player != null) { - return this.duration; - } - - // If no player yet, then create one - else { - this.prepareOnly = true; - this.startPlaying(file); - - // This will only return value for local, since streaming - // file hasn't been read yet. - return this.duration; - } - } - - /** - * Callback to be invoked when the media source is ready for playback. - * - * @param player The MediaPlayer that is ready for playback - */ - public void onPrepared(MediaPlayer player) { - // Listen for playback completion - this.player.setOnCompletionListener(this); - // seek to any location received while not prepared - this.seekToPlaying(this.seekOnPrepared); - // If start playing after prepared - if (!this.prepareOnly) { - this.player.start(); - this.setState(STATE.MEDIA_RUNNING); - this.seekOnPrepared = 0; //reset only when played - } else { - this.setState(STATE.MEDIA_STARTING); - } - // Save off duration - this.duration = getDurationInSeconds(); - // reset prepare only flag - this.prepareOnly = true; - - // Send status notification to JavaScript - sendStatusChange(MEDIA_DURATION, null, this.duration); - } - - /** - * By default Android returns the length of audio in mills but we want seconds - * - * @return length of clip in seconds - */ - private float getDurationInSeconds() { - return (this.player.getDuration() / 1000.0f); - } - - /** - * Callback to be invoked when there has been an error during an asynchronous operation - * (other errors will throw exceptions at method call time). - * - * @param player the MediaPlayer the error pertains to - * @param arg1 the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED) - * @param arg2 an extra code, specific to the error. - */ - public boolean onError(MediaPlayer player, int arg1, int arg2) { - Log.d(LOG_TAG, "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")"); - - // TODO: Not sure if this needs to be sent? - this.player.stop(); - this.player.release(); - - // Send error notification to JavaScript - sendErrorStatus(arg1); - return false; - } - - /** - * Set the state and send it to JavaScript. - * - * @param state - */ - private void setState(STATE state) { - if (this.state != state) { - sendStatusChange(MEDIA_STATE, null, (float)state.ordinal()); - } - this.state = state; - } - - /** - * Set the mode and send it to JavaScript. - * - * @param mode - */ - private void setMode(MODE mode) { - if (this.mode != mode) { - //mode is not part of the expected behavior, so no notification - //this.handler.webView.sendJavascript("cordova.require('org.apache.cordova.media.Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + mode + ");"); - } - this.mode = mode; - } - - /** - * Get the audio state. - * - * @return int - */ - public int getState() { - return this.state.ordinal(); - } - - /** - * Set the volume for audio player - * - * @param volume - */ - public void setVolume(float volume) { - this.player.setVolume(volume, volume); - } - - /** - * attempts to put the player in play mode - * @return true if in playmode, false otherwise - */ - private boolean playMode() { - switch(this.mode) { - case NONE: - this.setMode(MODE.PLAY); - break; - case PLAY: - break; - case RECORD: - Log.d(LOG_TAG, "AudioPlayer Error: Can't play in record mode."); - sendErrorStatus(MEDIA_ERR_ABORTED); - return false; //player is not ready - } - return true; - } - - /** - * attempts to initialize the media player for playback - * @param file the file to play - * @return false if player not ready, reports if in wrong mode or state - */ - private boolean readyPlayer(String file) { - if (playMode()) { - switch (this.state) { - case MEDIA_NONE: - if (this.player == null) { - this.player = new MediaPlayer(); - } - try { - this.loadAudioFile(file); - } catch (Exception e) { - sendErrorStatus(MEDIA_ERR_ABORTED); - } - return false; - case MEDIA_LOADING: - //cordova js is not aware of MEDIA_LOADING, so we send MEDIA_STARTING instead - Log.d(LOG_TAG, "AudioPlayer Loading: startPlaying() called during media preparation: " + STATE.MEDIA_STARTING.ordinal()); - this.prepareOnly = false; - return false; - case MEDIA_STARTING: - case MEDIA_RUNNING: - case MEDIA_PAUSED: - return true; - case MEDIA_STOPPED: - //if we are readying the same file - if (this.audioFile.compareTo(file) == 0) { - //reset the audio file - player.seekTo(0); - player.pause(); - return true; - } else { - //reset the player - this.player.reset(); - try { - this.loadAudioFile(file); - } catch (Exception e) { - sendErrorStatus(MEDIA_ERR_ABORTED); - } - //if we had to prepare the file, we won't be in the correct state for playback - return false; - } - default: - Log.d(LOG_TAG, "AudioPlayer Error: startPlaying() called during invalid state: " + this.state); - sendErrorStatus(MEDIA_ERR_ABORTED); - } - } - return false; - } - - /** - * load audio file - * @throws IOException - * @throws IllegalStateException - * @throws SecurityException - * @throws IllegalArgumentException - */ - private void loadAudioFile(String file) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException { - if (this.isStreaming(file)) { - this.player.setDataSource(file); - this.player.setAudioStreamType(AudioManager.STREAM_MUSIC); - //if it's a streaming file, play mode is implied - this.setMode(MODE.PLAY); - this.setState(STATE.MEDIA_STARTING); - this.player.setOnPreparedListener(this); - this.player.prepareAsync(); - } - else { - if (file.startsWith("/android_asset/")) { - String f = file.substring(15); - android.content.res.AssetFileDescriptor fd = this.handler.cordova.getActivity().getAssets().openFd(f); - this.player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); - } - else { - File fp = new File(file); - if (fp.exists()) { - FileInputStream fileInputStream = new FileInputStream(file); - this.player.setDataSource(fileInputStream.getFD()); - fileInputStream.close(); - } - else { - this.player.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/" + file); - } - } - this.setState(STATE.MEDIA_STARTING); - this.player.setOnPreparedListener(this); - this.player.prepare(); - - // Get duration - this.duration = getDurationInSeconds(); - } - } - - private void sendErrorStatus(int errorCode) { - sendStatusChange(MEDIA_ERROR, errorCode, null); - } - - private void sendStatusChange(int messageType, Integer additionalCode, Float value) { - - if (additionalCode != null && value != null) { - throw new IllegalArgumentException("Only one of additionalCode or value can be specified, not both"); - } - - JSONObject statusDetails = new JSONObject(); - try { - statusDetails.put("id", this.id); - statusDetails.put("msgType", messageType); - if (additionalCode != null) { - JSONObject code = new JSONObject(); - code.put("code", additionalCode.intValue()); - statusDetails.put("value", code); - } - else if (value != null) { - statusDetails.put("value", value.floatValue()); - } - } catch (JSONException e) { - Log.e(LOG_TAG, "Failed to create status details", e); - } - - this.handler.sendEventMessage("status", statusDetails); - } -} diff --git a/plugins/org.apache.cordova.media/src/android/FileHelper.java b/plugins/org.apache.cordova.media/src/android/FileHelper.java deleted file mode 100644 index e20752c6..00000000 --- a/plugins/org.apache.cordova.media/src/android/FileHelper.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - 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. - */ -package org.apache.cordova.media; - -import android.net.Uri; - -public class FileHelper { - - /** - * Removes the "file://" prefix from the given URI string, if applicable. - * If the given URI string doesn't have a "file://" prefix, it is returned unchanged. - * - * @param uriString the URI string to operate on - * @return a path without the "file://" prefix - */ - public static String stripFileProtocol(String uriString) { - if (uriString.startsWith("file://")) { - return Uri.parse(uriString).getPath(); - } - return uriString; - } -} diff --git a/plugins/org.apache.cordova.media/src/blackberry10/index.js b/plugins/org.apache.cordova.media/src/blackberry10/index.js deleted file mode 100644 index 1b9b7860..00000000 --- a/plugins/org.apache.cordova.media/src/blackberry10/index.js +++ /dev/null @@ -1,237 +0,0 @@ -/* - * - * 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 audioObjects = {}, - mediaErrorsHandled = false; - -// There is a bug in the webplatform handling of media error -// dialogs prior to 10.2. This function needs to be run once -// on the webview which plays audio to prevent freezing. -function handleMediaErrors() { - var webview = qnx.webplatform.getWebViews()[0], - handler = webview.onDialogRequested; - if (!mediaErrorsHandled) { - webview.allowWebEvent("DialogRequested"); - webview.onDialogRequested = undefined; - webview.onDialogRequested = function (eventArgs) { - var parsedArgs = JSON.parse(eventArgs); - if (parsedArgs.dialogType === 'MediaError') { - return '{"setPreventDefault": true}'; - } - handler(eventArgs); - }; - mediaErrorsHandled = true; - } -} - -module.exports = { - - create: function (success, fail, args, env) { - var result = new PluginResult(args, env), - id; - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - id = JSON.parse(decodeURIComponent(args[0])); - - if (!args[1]){ - audioObjects[id] = new Audio(); - } else { - audioObjects[id] = new Audio(JSON.parse(decodeURIComponent(args[1]))); - } - - handleMediaErrors(); - - result.ok(); - }, - - startPlayingAudio: function (success, fail, args, env) { - - var audio, - id, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - id = JSON.parse(decodeURIComponent(args[0])); - - audio = audioObjects[id]; - - if (!audio) { - result.error("Audio object has not been initialized"); - } else { - audio.play(); - result.ok(); - } - }, - - stopPlayingAudio: function (success, fail, args, env) { - - var audio, - id, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - id = JSON.parse(decodeURIComponent(args[0])); - - audio = audioObjects[id]; - - if (!audio) { - result.error("Audio Object has not been initialized"); - return; - } - - audio.pause(); - audio.currentTime = 0; - - result.ok(); - }, - - seekToAudio: function (success, fail, args, env) { - - var audio, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))]; - - if (!audio) { - result.error("Audio Object has not been initialized"); - } else if (!args[1]) { - result.error("Media seek time argument not found"); - } else { - try { - audio.currentTime = JSON.parse(decodeURIComponent(args[1])) / 1000; - result.ok(); - } catch (e) { - result.error("Error seeking audio: " + e); - } - } - }, - - pausePlayingAudio: function (success, fail, args, env) { - - var audio, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))]; - - if (!audio) { - result.error("Audio Object has not been initialized"); - return; - } - - audio.pause(); - }, - - getCurrentPositionAudio: function (success, fail, args, env) { - - var audio, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))]; - - if (!audio) { - result.error("Audio Object has not been initialized"); - return; - } - - result.ok(audio.currentTime); - }, - - getDuration: function (success, fail, args, env) { - - var audio, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - audio = audioObjects[JSON.parse(decodeURIComponent(args[0]))]; - - if (!audio) { - result.error("Audio Object has not been initialized"); - return; - } - - result.ok(audio.duration); - }, - - startRecordingAudio: function (success, fail, args, env) { - var result = new PluginResult(args, env); - result.error("Not supported"); - }, - - stopRecordingAudio: function (success, fail, args, env) { - var result = new PluginResult(args, env); - result.error("Not supported"); - }, - - release: function (success, fail, args, env) { - var audio, - id, - result = new PluginResult(args, env); - - if (!args[0]) { - result.error("Media Object id was not sent in arguments"); - return; - } - - id = JSON.parse(decodeURIComponent(args[0])); - - audio = audioObjects[id]; - - if (audio) { - if(audio.src !== ""){ - audio.src = undefined; - } - audioObjects[id] = undefined; - } - - result.ok(); - } -}; diff --git a/plugins/org.apache.cordova.media/src/ios/CDVSound.h b/plugins/org.apache.cordova.media/src/ios/CDVSound.h deleted file mode 100644 index 984924de..00000000 --- a/plugins/org.apache.cordova.media/src/ios/CDVSound.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - 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 <AudioToolbox/AudioServices.h> -#import <AVFoundation/AVFoundation.h> - -#import <Cordova/CDVPlugin.h> - -enum CDVMediaError { - MEDIA_ERR_ABORTED = 1, - MEDIA_ERR_NETWORK = 2, - MEDIA_ERR_DECODE = 3, - MEDIA_ERR_NONE_SUPPORTED = 4 -}; -typedef NSUInteger CDVMediaError; - -enum CDVMediaStates { - MEDIA_NONE = 0, - MEDIA_STARTING = 1, - MEDIA_RUNNING = 2, - MEDIA_PAUSED = 3, - MEDIA_STOPPED = 4 -}; -typedef NSUInteger CDVMediaStates; - -enum CDVMediaMsg { - MEDIA_STATE = 1, - MEDIA_DURATION = 2, - MEDIA_POSITION = 3, - MEDIA_ERROR = 9 -}; -typedef NSUInteger CDVMediaMsg; - -@interface CDVAudioPlayer : AVAudioPlayer -{ - NSString* mediaId; -} -@property (nonatomic, copy) NSString* mediaId; -@end - -@interface CDVAudioRecorder : AVAudioRecorder -{ - NSString* mediaId; -} -@property (nonatomic, copy) NSString* mediaId; -@end - -@interface CDVAudioFile : NSObject -{ - NSString* resourcePath; - NSURL* resourceURL; - CDVAudioPlayer* player; - CDVAudioRecorder* recorder; - NSNumber* volume; -} - -@property (nonatomic, strong) NSString* resourcePath; -@property (nonatomic, strong) NSURL* resourceURL; -@property (nonatomic, strong) CDVAudioPlayer* player; -@property (nonatomic, strong) NSNumber* volume; - -@property (nonatomic, strong) CDVAudioRecorder* recorder; - -@end - -@interface CDVSound : CDVPlugin <AVAudioPlayerDelegate, AVAudioRecorderDelegate> -{ - NSMutableDictionary* soundCache; - AVAudioSession* avSession; -} -@property (nonatomic, strong) NSMutableDictionary* soundCache; -@property (nonatomic, strong) AVAudioSession* avSession; - -- (void)startPlayingAudio:(CDVInvokedUrlCommand*)command; -- (void)pausePlayingAudio:(CDVInvokedUrlCommand*)command; -- (void)stopPlayingAudio:(CDVInvokedUrlCommand*)command; -- (void)seekToAudio:(CDVInvokedUrlCommand*)command; -- (void)release:(CDVInvokedUrlCommand*)command; -- (void)getCurrentPositionAudio:(CDVInvokedUrlCommand*)command; - -- (BOOL)hasAudioSession; - -// helper methods -- (NSURL*)urlForRecording:(NSString*)resourcePath; -- (NSURL*)urlForPlaying:(NSString*)resourcePath; - -- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId doValidation:(BOOL)bValidate forRecording:(BOOL)bRecord; -- (BOOL)prepareToPlay:(CDVAudioFile*)audioFile withId:(NSString*)mediaId; -- (NSString*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message; - -- (void)startRecordingAudio:(CDVInvokedUrlCommand*)command; -- (void)stopRecordingAudio:(CDVInvokedUrlCommand*)command; - -- (void)setVolume:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/org.apache.cordova.media/src/ios/CDVSound.m b/plugins/org.apache.cordova.media/src/ios/CDVSound.m deleted file mode 100644 index 309b2e29..00000000 --- a/plugins/org.apache.cordova.media/src/ios/CDVSound.m +++ /dev/null @@ -1,703 +0,0 @@ -/* - 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 "CDVSound.h" -#import "CDVFile.h" -#import <Cordova/NSArray+Comparisons.h> - -#define DOCUMENTS_SCHEME_PREFIX @"documents://" -#define HTTP_SCHEME_PREFIX @"http://" -#define HTTPS_SCHEME_PREFIX @"https://" -#define CDVFILE_PREFIX @"cdvfile://" -#define RECORDING_WAV @"wav" - -@implementation CDVSound - -@synthesize soundCache, avSession; - -// Maps a url for a resource path for recording -- (NSURL*)urlForRecording:(NSString*)resourcePath -{ - NSURL* resourceURL = nil; - NSString* filePath = nil; - NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; - - // first check for correct extension - if ([[resourcePath pathExtension] caseInsensitiveCompare:RECORDING_WAV] != NSOrderedSame) { - resourceURL = nil; - NSLog(@"Resource for recording must have %@ extension", RECORDING_WAV); - } else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) { - // try to find Documents:// resources - filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]]; - NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath); - } else if ([resourcePath hasPrefix:CDVFILE_PREFIX]) { - CDVFile *filePlugin = [self.commandDelegate getCommandInstance:@"File"]; - CDVFilesystemURL *url = [CDVFilesystemURL fileSystemURLWithString:resourcePath]; - filePath = [filePlugin filesystemPathForURL:url]; - if (filePath == nil) { - resourceURL = [NSURL URLWithString:resourcePath]; - } - } else { - // if resourcePath is not from FileSystem put in tmp dir, else attempt to use provided resource path - NSString* tmpPath = [NSTemporaryDirectory()stringByStandardizingPath]; - BOOL isTmp = [resourcePath rangeOfString:tmpPath].location != NSNotFound; - BOOL isDoc = [resourcePath rangeOfString:docsPath].location != NSNotFound; - if (!isTmp && !isDoc) { - // put in temp dir - filePath = [NSString stringWithFormat:@"%@/%@", tmpPath, resourcePath]; - } else { - filePath = resourcePath; - } - } - - if (filePath != nil) { - // create resourceURL - resourceURL = [NSURL fileURLWithPath:filePath]; - } - return resourceURL; -} - -// Maps a url for a resource path for playing -// "Naked" resource paths are assumed to be from the www folder as its base -- (NSURL*)urlForPlaying:(NSString*)resourcePath -{ - NSURL* resourceURL = nil; - NSString* filePath = nil; - - // first try to find HTTP:// or Documents:// resources - - if ([resourcePath hasPrefix:HTTP_SCHEME_PREFIX] || [resourcePath hasPrefix:HTTPS_SCHEME_PREFIX]) { - // if it is a http url, use it - NSLog(@"Will use resource '%@' from the Internet.", resourcePath); - resourceURL = [NSURL URLWithString:resourcePath]; - } else if ([resourcePath hasPrefix:DOCUMENTS_SCHEME_PREFIX]) { - NSString* docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; - filePath = [resourcePath stringByReplacingOccurrencesOfString:DOCUMENTS_SCHEME_PREFIX withString:[NSString stringWithFormat:@"%@/", docsPath]]; - NSLog(@"Will use resource '%@' from the documents folder with path = %@", resourcePath, filePath); - } else if ([resourcePath hasPrefix:CDVFILE_PREFIX]) { - CDVFile *filePlugin = [self.commandDelegate getCommandInstance:@"File"]; - CDVFilesystemURL *url = [CDVFilesystemURL fileSystemURLWithString:resourcePath]; - filePath = [filePlugin filesystemPathForURL:url]; - if (filePath == nil) { - resourceURL = [NSURL URLWithString:resourcePath]; - } - } else { - // attempt to find file path in www directory or LocalFileSystem.TEMPORARY directory - filePath = [self.commandDelegate pathForResource:resourcePath]; - if (filePath == nil) { - // see if this exists in the documents/temp directory from a previous recording - NSString* testPath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], resourcePath]; - if ([[NSFileManager defaultManager] fileExistsAtPath:testPath]) { - // inefficient as existence will be checked again below but only way to determine if file exists from previous recording - filePath = testPath; - NSLog(@"Will attempt to use file resource from LocalFileSystem.TEMPORARY directory"); - } else { - // attempt to use path provided - filePath = resourcePath; - NSLog(@"Will attempt to use file resource '%@'", filePath); - } - } else { - NSLog(@"Found resource '%@' in the web folder.", filePath); - } - } - // if the resourcePath resolved to a file path, check that file exists - if (filePath != nil) { - // create resourceURL - resourceURL = [NSURL fileURLWithPath:filePath]; - // try to access file - NSFileManager* fMgr = [NSFileManager defaultManager]; - if (![fMgr fileExistsAtPath:filePath]) { - resourceURL = nil; - NSLog(@"Unknown resource '%@'", resourcePath); - } - } - - return resourceURL; -} - -// Creates or gets the cached audio file resource object -- (CDVAudioFile*)audioFileForResource:(NSString*)resourcePath withId:(NSString*)mediaId doValidation:(BOOL)bValidate forRecording:(BOOL)bRecord -{ - BOOL bError = NO; - CDVMediaError errcode = MEDIA_ERR_NONE_SUPPORTED; - NSString* errMsg = @""; - NSString* jsString = nil; - CDVAudioFile* audioFile = nil; - NSURL* resourceURL = nil; - - if ([self soundCache] == nil) { - [self setSoundCache:[NSMutableDictionary dictionaryWithCapacity:1]]; - } else { - audioFile = [[self soundCache] objectForKey:mediaId]; - } - if (audioFile == nil) { - // validate resourcePath and create - if ((resourcePath == nil) || ![resourcePath isKindOfClass:[NSString class]] || [resourcePath isEqualToString:@""]) { - bError = YES; - errcode = MEDIA_ERR_ABORTED; - errMsg = @"invalid media src argument"; - } else { - audioFile = [[CDVAudioFile alloc] init]; - audioFile.resourcePath = resourcePath; - audioFile.resourceURL = nil; // validate resourceURL when actually play or record - [[self soundCache] setObject:audioFile forKey:mediaId]; - } - } - if (bValidate && (audioFile.resourceURL == nil)) { - if (bRecord) { - resourceURL = [self urlForRecording:resourcePath]; - } else { - resourceURL = [self urlForPlaying:resourcePath]; - } - if (resourceURL == nil) { - bError = YES; - errcode = MEDIA_ERR_ABORTED; - errMsg = [NSString stringWithFormat:@"Cannot use audio file from resource '%@'", resourcePath]; - } else { - audioFile.resourceURL = resourceURL; - } - } - - if (bError) { - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:errcode message:errMsg]]; - [self.commandDelegate evalJs:jsString]; - } - - return audioFile; -} - -// returns whether or not audioSession is available - creates it if necessary -- (BOOL)hasAudioSession -{ - BOOL bSession = YES; - - if (!self.avSession) { - NSError* error = nil; - - self.avSession = [AVAudioSession sharedInstance]; - if (error) { - // is not fatal if can't get AVAudioSession , just log the error - NSLog(@"error creating audio session: %@", [[error userInfo] description]); - self.avSession = nil; - bSession = NO; - } - } - return bSession; -} - -// helper function to create a error object string -- (NSString*)createMediaErrorWithCode:(CDVMediaError)code message:(NSString*)message -{ - NSMutableDictionary* errorDict = [NSMutableDictionary dictionaryWithCapacity:2]; - - [errorDict setObject:[NSNumber numberWithUnsignedInteger:code] forKey:@"code"]; - [errorDict setObject:message ? message:@"" forKey:@"message"]; - - NSData* jsonData = [NSJSONSerialization dataWithJSONObject:errorDict options:0 error:nil]; - return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; -} - -- (void)create:(CDVInvokedUrlCommand*)command -{ - NSString* mediaId = [command argumentAtIndex:0]; - NSString* resourcePath = [command argumentAtIndex:1]; - - CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId doValidation:NO forRecording:NO]; - - if (audioFile == nil) { - NSString* errorMessage = [NSString stringWithFormat:@"Failed to initialize Media file with path %@", resourcePath]; - NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMessage]]; - [self.commandDelegate evalJs:jsString]; - } else { - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - } -} - -- (void)setVolume:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - -#pragma unused(callbackId) - NSString* mediaId = [command argumentAtIndex:0]; - NSNumber* volume = [command argumentAtIndex:1 withDefault:[NSNumber numberWithFloat:1.0]]; - - if ([self soundCache] != nil) { - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - if (audioFile != nil) { - audioFile.volume = volume; - if (audioFile.player) { - audioFile.player.volume = [volume floatValue]; - } - [[self soundCache] setObject:audioFile forKey:mediaId]; - } - } - - // don't care for any callbacks -} - -- (void)startPlayingAudio:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - -#pragma unused(callbackId) - NSString* mediaId = [command argumentAtIndex:0]; - NSString* resourcePath = [command argumentAtIndex:1]; - NSDictionary* options = [command argumentAtIndex:2 withDefault:nil]; - - BOOL bError = NO; - NSString* jsString = nil; - - CDVAudioFile* audioFile = [self audioFileForResource:resourcePath withId:mediaId doValidation:YES forRecording:NO]; - if ((audioFile != nil) && (audioFile.resourceURL != nil)) { - if (audioFile.player == nil) { - bError = [self prepareToPlay:audioFile withId:mediaId]; - } - if (!bError) { - // audioFile.player != nil or player was successfully created - // get the audioSession and set the category to allow Playing when device is locked or ring/silent switch engaged - if ([self hasAudioSession]) { - NSError* __autoreleasing err = nil; - NSNumber* playAudioWhenScreenIsLocked = [options objectForKey:@"playAudioWhenScreenIsLocked"]; - BOOL bPlayAudioWhenScreenIsLocked = YES; - if (playAudioWhenScreenIsLocked != nil) { - bPlayAudioWhenScreenIsLocked = [playAudioWhenScreenIsLocked boolValue]; - } - - NSString* sessionCategory = bPlayAudioWhenScreenIsLocked ? AVAudioSessionCategoryPlayback : AVAudioSessionCategorySoloAmbient; - [self.avSession setCategory:sessionCategory error:&err]; - if (![self.avSession setActive:YES error:&err]) { - // other audio with higher priority that does not allow mixing could cause this to fail - NSLog(@"Unable to play audio: %@", [err localizedFailureReason]); - bError = YES; - } - } - if (!bError) { - NSLog(@"Playing audio sample '%@'", audioFile.resourcePath); - NSNumber* loopOption = [options objectForKey:@"numberOfLoops"]; - NSInteger numberOfLoops = 0; - if (loopOption != nil) { - numberOfLoops = [loopOption intValue] - 1; - } - audioFile.player.numberOfLoops = numberOfLoops; - if (audioFile.player.isPlaying) { - [audioFile.player stop]; - audioFile.player.currentTime = 0; - } - if (audioFile.volume != nil) { - audioFile.player.volume = [audioFile.volume floatValue]; - } - - [audioFile.player play]; - double position = round(audioFile.player.duration * 1000) / 1000; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);\n%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_DURATION, position, @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_RUNNING]; - [self.commandDelegate evalJs:jsString]; - } - } - if (bError) { - /* I don't see a problem playing previously recorded audio so removing this section - BG - NSError* error; - // try loading it one more time, in case the file was recorded previously - audioFile.player = [[ AVAudioPlayer alloc ] initWithContentsOfURL:audioFile.resourceURL error:&error]; - if (error != nil) { - NSLog(@"Failed to initialize AVAudioPlayer: %@\n", error); - audioFile.player = nil; - } else { - NSLog(@"Playing audio sample '%@'", audioFile.resourcePath); - audioFile.player.numberOfLoops = numberOfLoops; - [audioFile.player play]; - } */ - // error creating the session or player - // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_NONE_SUPPORTED]; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_NONE_SUPPORTED message:nil]]; - [self.commandDelegate evalJs:jsString]; - } - } - // else audioFile was nil - error already returned from audioFile for resource - return; -} - -- (BOOL)prepareToPlay:(CDVAudioFile*)audioFile withId:(NSString*)mediaId -{ - BOOL bError = NO; - NSError* __autoreleasing playerError = nil; - - // create the player - NSURL* resourceURL = audioFile.resourceURL; - - if ([resourceURL isFileURL]) { - audioFile.player = [[CDVAudioPlayer alloc] initWithContentsOfURL:resourceURL error:&playerError]; - } else { - NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:resourceURL]; - NSString* userAgent = [self.commandDelegate userAgent]; - if (userAgent) { - [request setValue:userAgent forHTTPHeaderField:@"User-Agent"]; - } - - NSURLResponse* __autoreleasing response = nil; - NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&playerError]; - if (playerError) { - NSLog(@"Unable to download audio from: %@", [resourceURL absoluteString]); - } else { - // bug in AVAudioPlayer when playing downloaded data in NSData - we have to download the file and play from disk - CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault); - CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef); - NSString* filePath = [NSString stringWithFormat:@"%@/%@", [NSTemporaryDirectory()stringByStandardizingPath], uuidString]; - CFRelease(uuidString); - CFRelease(uuidRef); - - [data writeToFile:filePath atomically:YES]; - NSURL* fileURL = [NSURL fileURLWithPath:filePath]; - audioFile.player = [[CDVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&playerError]; - } - } - - if (playerError != nil) { - NSLog(@"Failed to initialize AVAudioPlayer: %@\n", [playerError localizedDescription]); - audioFile.player = nil; - if (self.avSession) { - [self.avSession setActive:NO error:nil]; - } - bError = YES; - } else { - audioFile.player.mediaId = mediaId; - audioFile.player.delegate = self; - bError = ![audioFile.player prepareToPlay]; - } - return bError; -} - -- (void)stopPlayingAudio:(CDVInvokedUrlCommand*)command -{ - NSString* mediaId = [command argumentAtIndex:0]; - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - NSString* jsString = nil; - - if ((audioFile != nil) && (audioFile.player != nil)) { - NSLog(@"Stopped playing audio sample '%@'", audioFile.resourcePath); - [audioFile.player stop]; - audioFile.player.currentTime = 0; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED]; - } // ignore if no media playing - if (jsString) { - [self.commandDelegate evalJs:jsString]; - } -} - -- (void)pausePlayingAudio:(CDVInvokedUrlCommand*)command -{ - NSString* mediaId = [command argumentAtIndex:0]; - NSString* jsString = nil; - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - - if ((audioFile != nil) && (audioFile.player != nil)) { - NSLog(@"Paused playing audio sample '%@'", audioFile.resourcePath); - [audioFile.player pause]; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_PAUSED]; - } - // ignore if no media playing - - if (jsString) { - [self.commandDelegate evalJs:jsString]; - } -} - -- (void)seekToAudio:(CDVInvokedUrlCommand*)command -{ - // args: - // 0 = Media id - // 1 = path to resource - // 2 = seek to location in milliseconds - - NSString* mediaId = [command argumentAtIndex:0]; - - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - double position = [[command argumentAtIndex:1] doubleValue]; - - if ((audioFile != nil) && (audioFile.player != nil)) { - NSString* jsString; - double posInSeconds = position / 1000; - if (posInSeconds >= audioFile.player.duration) { - // The seek is past the end of file. Stop media and reset to beginning instead of seeking past the end. - [audioFile.player stop]; - audioFile.player.currentTime = 0; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);\n%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_POSITION, 0.0, @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED]; - // NSLog(@"seekToEndJsString=%@",jsString); - } else { - audioFile.player.currentTime = posInSeconds; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%f);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_POSITION, posInSeconds]; - // NSLog(@"seekJsString=%@",jsString); - } - - [self.commandDelegate evalJs:jsString]; - } -} - -- (void)release:(CDVInvokedUrlCommand*)command -{ - NSString* mediaId = [command argumentAtIndex:0]; - - if (mediaId != nil) { - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - if (audioFile != nil) { - if (audioFile.player && [audioFile.player isPlaying]) { - [audioFile.player stop]; - } - if (audioFile.recorder && [audioFile.recorder isRecording]) { - [audioFile.recorder stop]; - } - if (self.avSession) { - [self.avSession setActive:NO error:nil]; - self.avSession = nil; - } - [[self soundCache] removeObjectForKey:mediaId]; - NSLog(@"Media with id %@ released", mediaId); - } - } -} - -- (void)getCurrentPositionAudio:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - NSString* mediaId = [command argumentAtIndex:0]; - -#pragma unused(mediaId) - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - double position = -1; - - if ((audioFile != nil) && (audioFile.player != nil) && [audioFile.player isPlaying]) { - position = round(audioFile.player.currentTime * 1000) / 1000; - } - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:position]; - - NSString* jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%.3f);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_POSITION, position]; - [self.commandDelegate evalJs:jsString]; - [self.commandDelegate sendPluginResult:result callbackId:callbackId]; -} - -- (void)startRecordingAudio:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - -#pragma unused(callbackId) - - NSString* mediaId = [command argumentAtIndex:0]; - CDVAudioFile* audioFile = [self audioFileForResource:[command argumentAtIndex:1] withId:mediaId doValidation:YES forRecording:YES]; - __block NSString* jsString = nil; - __block NSString* errorMsg = @""; - - if ((audioFile != nil) && (audioFile.resourceURL != nil)) { - void (^startRecording)(void) = ^{ - NSError* __autoreleasing error = nil; - - if (audioFile.recorder != nil) { - [audioFile.recorder stop]; - audioFile.recorder = nil; - } - // get the audioSession and set the category to allow recording when device is locked or ring/silent switch engaged - if ([self hasAudioSession]) { - if (![self.avSession.category isEqualToString:AVAudioSessionCategoryPlayAndRecord]) { - [self.avSession setCategory:AVAudioSessionCategoryRecord error:nil]; - } - - if (![self.avSession setActive:YES error:&error]) { - // other audio with higher priority that does not allow mixing could cause this to fail - errorMsg = [NSString stringWithFormat:@"Unable to record audio: %@", [error localizedFailureReason]]; - // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_ABORTED]; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]]; - [self.commandDelegate evalJs:jsString]; - return; - } - } - - // create a new recorder for each start record - audioFile.recorder = [[CDVAudioRecorder alloc] initWithURL:audioFile.resourceURL settings:nil error:&error]; - - bool recordingSuccess = NO; - if (error == nil) { - audioFile.recorder.delegate = self; - audioFile.recorder.mediaId = mediaId; - recordingSuccess = [audioFile.recorder record]; - if (recordingSuccess) { - NSLog(@"Started recording audio sample '%@'", audioFile.resourcePath); - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_RUNNING]; - [self.commandDelegate evalJs:jsString]; - } - } - - if ((error != nil) || (recordingSuccess == NO)) { - if (error != nil) { - errorMsg = [NSString stringWithFormat:@"Failed to initialize AVAudioRecorder: %@\n", [error localizedFailureReason]]; - } else { - errorMsg = @"Failed to start recording using AVAudioRecorder"; - } - audioFile.recorder = nil; - if (self.avSession) { - [self.avSession setActive:NO error:nil]; - } - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]]; - [self.commandDelegate evalJs:jsString]; - } - }; - - SEL rrpSel = NSSelectorFromString(@"requestRecordPermission:"); - if ([self hasAudioSession] && [self.avSession respondsToSelector:rrpSel]) - { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [self.avSession performSelector:rrpSel withObject:^(BOOL granted){ - if (granted) { - startRecording(); - } else { - NSString* msg = @"Error creating audio session, microphone permission denied."; - NSLog(@"%@", msg); - audioFile.recorder = nil; - if (self.avSession) { - [self.avSession setActive:NO error:nil]; - } - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:msg]]; - [self.commandDelegate evalJs:jsString]; - } - }]; -#pragma clang diagnostic pop - } else { - startRecording(); - } - - } else { - // file did not validate - NSString* errorMsg = [NSString stringWithFormat:@"Could not record audio at '%@'", audioFile.resourcePath]; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_ABORTED message:errorMsg]]; - [self.commandDelegate evalJs:jsString]; - } -} - -- (void)stopRecordingAudio:(CDVInvokedUrlCommand*)command -{ - NSString* mediaId = [command argumentAtIndex:0]; - - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - NSString* jsString = nil; - - if ((audioFile != nil) && (audioFile.recorder != nil)) { - NSLog(@"Stopped recording audio sample '%@'", audioFile.resourcePath); - [audioFile.recorder stop]; - // no callback - that will happen in audioRecorderDidFinishRecording - } - // ignore if no media recording - if (jsString) { - [self.commandDelegate evalJs:jsString]; - } -} - -- (void)audioRecorderDidFinishRecording:(AVAudioRecorder*)recorder successfully:(BOOL)flag -{ - CDVAudioRecorder* aRecorder = (CDVAudioRecorder*)recorder; - NSString* mediaId = aRecorder.mediaId; - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - NSString* jsString = nil; - - if (audioFile != nil) { - NSLog(@"Finished recording audio sample '%@'", audioFile.resourcePath); - } - if (flag) { - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED]; - } else { - // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_DECODE]; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_DECODE message:nil]]; - } - if (self.avSession) { - [self.avSession setActive:NO error:nil]; - } - [self.commandDelegate evalJs:jsString]; -} - -- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)player successfully:(BOOL)flag -{ - CDVAudioPlayer* aPlayer = (CDVAudioPlayer*)player; - NSString* mediaId = aPlayer.mediaId; - CDVAudioFile* audioFile = [[self soundCache] objectForKey:mediaId]; - NSString* jsString = nil; - - if (audioFile != nil) { - NSLog(@"Finished playing audio sample '%@'", audioFile.resourcePath); - } - if (flag) { - audioFile.player.currentTime = 0; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_STATE, MEDIA_STOPPED]; - } else { - // jsString = [NSString stringWithFormat: @"%@(\"%@\",%d,%d);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, MEDIA_ERR_DECODE]; - jsString = [NSString stringWithFormat:@"%@(\"%@\",%d,%@);", @"cordova.require('org.apache.cordova.media.Media').onStatus", mediaId, MEDIA_ERROR, [self createMediaErrorWithCode:MEDIA_ERR_DECODE message:nil]]; - } - if (self.avSession) { - [self.avSession setActive:NO error:nil]; - } - [self.commandDelegate evalJs:jsString]; -} - -- (void)onMemoryWarning -{ - [[self soundCache] removeAllObjects]; - [self setSoundCache:nil]; - [self setAvSession:nil]; - - [super onMemoryWarning]; -} - -- (void)dealloc -{ - [[self soundCache] removeAllObjects]; -} - -- (void)onReset -{ - for (CDVAudioFile* audioFile in [[self soundCache] allValues]) { - if (audioFile != nil) { - if (audioFile.player != nil) { - [audioFile.player stop]; - audioFile.player.currentTime = 0; - } - if (audioFile.recorder != nil) { - [audioFile.recorder stop]; - } - } - } - - [[self soundCache] removeAllObjects]; -} - -@end - -@implementation CDVAudioFile - -@synthesize resourcePath; -@synthesize resourceURL; -@synthesize player, volume; -@synthesize recorder; - -@end -@implementation CDVAudioPlayer -@synthesize mediaId; - -@end - -@implementation CDVAudioRecorder -@synthesize mediaId; - -@end diff --git a/plugins/org.apache.cordova.media/src/tizen/MediaProxy.js b/plugins/org.apache.cordova.media/src/tizen/MediaProxy.js deleted file mode 100644 index c2ee4b07..00000000 --- a/plugins/org.apache.cordova.media/src/tizen/MediaProxy.js +++ /dev/null @@ -1,223 +0,0 @@ -/* - * - * 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 cordova = require('cordova'), - Media = require('org.apache.cordova.media.Media'); - -var MediaError = require('org.apache.cordova.media.MediaError'), - audioObjects = {}; - -module.exports = { - // Initiates the audio file - create:function(successCallback, errorCallback, args) { - var id = args[0], src = args[1]; - - console.log("media::create() - id =" + id + ", src =" + src); - - audioObjects[id] = new Audio(src); - - audioObjects[id].onStalledCB = function () { - console.log("media::onStalled()"); - - audioObjects[id].timer = window.setTimeout( - function () { - audioObjects[id].pause(); - - if (audioObjects[id].currentTime !== 0) - audioObjects[id].currentTime = 0; - - console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED); - - var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled"); - - Media.onStatus(id, Media.MEDIA_ERROR, err); - }, - 2000); - }; - - audioObjects[id].onEndedCB = function () { - console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED"); - - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); - }; - - audioObjects[id].onErrorCB = function () { - console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error); - - Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error); - }; - - audioObjects[id].onPlayCB = function () { - console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING"); - - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING); - }; - - audioObjects[id].onPlayingCB = function () { - console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING"); - - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); - }; - - audioObjects[id].onDurationChangeCB = function () { - console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " + audioObjects[id].duration); - - Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration); - }; - - audioObjects[id].onTimeUpdateCB = function () { - console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " + audioObjects[id].currentTime); - - Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime); - }; - - audioObjects[id].onCanPlayCB = function () { - console.log("media::onCanPlayCB()"); - - window.clearTimeout(audioObjects[id].timer); - - audioObjects[id].play(); - }; - - }, - - // Start playing the audio - startPlayingAudio:function(successCallback, errorCallback, args) { - var id = args[0], src = args[1], options = args[2]; - - console.log("media::startPlayingAudio() - id =" + id + ", src =" + src + ", options =" + options); - - audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB); - audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB); - audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB); - audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB); - audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB); - audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB); - audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB); - audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB); - - audioObjects[id].play(); - }, - - // Stops the playing audio - stopPlayingAudio:function(successCallback, errorCallback, args) { - var id = args[0]; - - window.clearTimeout(audioObjects[id].timer); - - audioObjects[id].pause(); - - if (audioObjects[id].currentTime !== 0) - audioObjects[id].currentTime = 0; - - console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED"); - - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); - - audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB); - audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB); - audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB); - audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB); - audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB); - audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB); - audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB); - audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB); - }, - - // Seeks to the position in the audio - seekToAudio:function(successCallback, errorCallback, args) { - var id = args[0], milliseconds = args[1]; - - console.log("media::seekToAudio()"); - - audioObjects[id].currentTime = milliseconds; - successCallback( audioObjects[id].currentTime); - }, - - // Pauses the playing audio - pausePlayingAudio:function(successCallback, errorCallback, args) { - var id = args[0]; - - console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED"); - - audioObjects[id].pause(); - - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED); - }, - - // Gets current position in the audio - getCurrentPositionAudio:function(successCallback, errorCallback, args) { - var id = args[0]; - console.log("media::getCurrentPositionAudio()"); - successCallback(audioObjects[id].currentTime); - }, - - // Start recording audio - startRecordingAudio:function(successCallback, errorCallback, args) { - var id = args[0], src = args[1]; - - console.log("media::startRecordingAudio() - id =" + id + ", src =" + src); - - function gotStreamCB(stream) { - audioObjects[id].src = webkitURL.createObjectURL(stream); - console.log("media::startRecordingAudio() - stream CB"); - } - - function gotStreamFailedCB(error) { - console.log("media::startRecordingAudio() - error CB:" + error.toString()); - } - - if (navigator.webkitGetUserMedia) { - audioObjects[id] = new Audio(); - navigator.webkitGetUserMedia('audio', gotStreamCB, gotStreamFailedCB); - } else { - console.log("webkitGetUserMedia not supported"); - } - successCallback(); - }, - - // Stop recording audio - stopRecordingAudio:function(successCallback, errorCallback, args) { - var id = args[0]; - - console.log("media::stopRecordingAudio() - id =" + id); - - audioObjects[id].pause(); - successCallback(); - }, - - // Release the media object - release:function(successCallback, errorCallback, args) { - var id = args[0]; - window.clearTimeout(audioObjects[id].timer); - console.log("media::release()"); - }, - - setVolume:function(successCallback, errorCallback, args) { - var id = args[0], volume = args[1]; - - console.log("media::setVolume()"); - - audioObjects[id].volume = volume; - } -}; - -require("cordova/tizen/commandProxy").add("Media", module.exports); diff --git a/plugins/org.apache.cordova.media/src/ubuntu/media.cpp b/plugins/org.apache.cordova.media/src/ubuntu/media.cpp deleted file mode 100644 index 2814b5b3..00000000 --- a/plugins/org.apache.cordova.media/src/ubuntu/media.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - * - * 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 "media.h" - -void Media::create(int scId, int ecId, const QString &id, const QString &src) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) != _id2Player.end()) { - _id2Player[id]->stop(); - _id2Player.remove(id); - } - - _id2Player[id] = QSharedPointer<Player>(new Player(id, src, this)); -} - -void Media::relase(int scId, int ecId, const QString &id) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - _id2Player.remove(id); -} - -void Media::startPlayingAudio(int scId, int ecId, const QString &id, const QString &src, QVariantMap options) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - Q_UNUSED(src); - Q_UNUSED(options); - - if (_id2Player.find(id) == _id2Player.end()) - return; - QSharedPointer<Player> player = _id2Player[id]; - player->play(); -} - -void Media::pausePlayingAudio(int scId, int ecId, const QString &id) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - QSharedPointer<Player> player = _id2Player[id]; - player->pause(); -} - -void Media::stopPlayingAudio(int scId, int ecId, const QString &id) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - QSharedPointer<Player> player = _id2Player[id]; - player->stop(); -} - -void Media::startRecordingAudio(int scId, int ecId, const QString &id, const QString &src) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - Q_UNUSED(src); - - if (_id2Player.find(id) == _id2Player.end()) - return; - QSharedPointer<Player> player = _id2Player[id]; - player->startRecording(); -} - -void Media::stopRecordingAudio(int scId, int ecId, const QString &id) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - QSharedPointer<Player> player = _id2Player[id]; - player->stopRecording(); -} - -void Media::getCurrentPositionAudio(int scId, int ecId, const QString &id) { - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - - QSharedPointer<Player> player = _id2Player[id]; - double position = player->getPosition(); - this->cb(scId, position); -} - -void Media::seekToAudio(int scId, int ecId, const QString &id, qint64 position) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - - QSharedPointer<Player> player = _id2Player[id]; - player->seekTo(position); -} - -void Media::setVolume(int scId, int ecId, const QString &id, int volume) { - Q_UNUSED(scId); - Q_UNUSED(ecId); - - if (_id2Player.find(id) == _id2Player.end()) - return; - QSharedPointer<Player> player = _id2Player[id]; - player->setVolume(volume); -} diff --git a/plugins/org.apache.cordova.media/src/ubuntu/media.h b/plugins/org.apache.cordova.media/src/ubuntu/media.h deleted file mode 100644 index c1f37122..00000000 --- a/plugins/org.apache.cordova.media/src/ubuntu/media.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -#ifndef MEDIA_H_789768978 -#define MEDIA_H_789768978 - -#include <QtMultimedia/QMediaPlayer> -#include <QtCore> -#include <QAudioRecorder> -#include <QtMultimedia/QAudioEncoderSettings> - -#include <cplugin.h> -#include <cordova.h> - -class Player; - -class Media: public CPlugin { - Q_OBJECT -public: - explicit Media(Cordova *cordova): CPlugin(cordova) { - } - - virtual const QString fullName() override { - return Media::fullID(); - } - - virtual const QString shortName() override { - return "Media"; - } - - static const QString fullID() { - return "Media"; - } - - enum State { - MEDIA_NONE = 0, - MEDIA_STARTING = 1, - MEDIA_RUNNING = 2, - MEDIA_PAUSED = 3, - MEDIA_STOPPED = 4 - }; - enum ErrorCode { - MEDIA_ERR_NONE_ACTIVE = 0, - MEDIA_ERR_ABORTED = 1, - MEDIA_ERR_NETWORK = 2, - MEDIA_ERR_DECODE = 3, - MEDIA_ERR_NONE_SUPPORTED = 4 - }; - - void execJS(const QString &js) { - m_cordova->execJS(js); - } -public slots: - void create(int scId, int ecId, const QString &id, const QString &src); - void relase(int scId, int ecId, const QString &id); - - void startRecordingAudio(int scId, int ecId, const QString &id, const QString &src); - void stopRecordingAudio(int scId, int ecId, const QString &id); - - void startPlayingAudio(int scId, int ecId, const QString &id, const QString &src, QVariantMap options); - void pausePlayingAudio(int scId, int ecId, const QString &id); - void stopPlayingAudio(int scId, int ecId, const QString &id); - void getCurrentPositionAudio(int scId, int ecId, const QString &id); - void seekToAudio(int scId, int ecId, const QString &id, qint64 position); - void setVolume(int scId, int ecId, const QString &id, int volume); - -private: - QMap<QString, QSharedPointer<Player> > _id2Player; -}; - -class Player: public QObject { - Q_OBJECT -public: - Player(const QString &id, QString src, Media *plugin): - _state(Media::MEDIA_NONE), - _src(src), - _mode(MODE_NONE), - _plugin(plugin), - _id(id), - _stateChanged(false) { - QUrl url(src, QUrl::TolerantMode); - - if (url.scheme().isEmpty()) { - QAudioEncoderSettings audioSettings; - - _recorder.setEncodingSettings(audioSettings); - _recorder.setOutputLocation(QFileInfo(src).absoluteFilePath()); - - _player.setMedia(QUrl::fromLocalFile(QFileInfo(src).absoluteFilePath())); - } else { - _player.setMedia(url); - } - QObject::connect(&_player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(onMediaStatusChanged(QMediaPlayer::MediaStatus))); - QObject::connect(&_recorder, SIGNAL(error(QMediaRecorder::Error)), this, SLOT(onError(QMediaRecorder::Error))); - - connect(&_timer, SIGNAL(timeout()), this, SLOT(reportPosition())); - } - - void startRecording() { - if (recordMode() && _state != Media::MEDIA_RUNNING) { - _recorder.record(); - setState(Media::MEDIA_RUNNING); - } - } - void stopRecording() { - if (recordMode() && _state == Media::MEDIA_RUNNING) { - _recorder.stop(); - setState(Media::MEDIA_STOPPED); - } - } - - void setVolume(int volume) { - _player.setVolume(volume); - } - - void play() { - if (playMode() && _state != Media::MEDIA_RUNNING) { - _player.play(); - setState(Media::MEDIA_RUNNING); - } - } - void pause() { - if (playMode() && _state == Media::MEDIA_RUNNING) { - _player.pause(); - setState(Media::MEDIA_PAUSED); - } - } - void stop() { - if (playMode() && (_state == Media::MEDIA_RUNNING || _state == Media::MEDIA_PAUSED)) { - _player.stop(); - setState(Media::MEDIA_STOPPED); - } - } - double getDuration() { - if (_mode == MODE_NONE || _player.duration() == -1) - return -1; - if (_mode != MODE_PLAY) - return -2; - return static_cast<double>(_player.duration()) / 1000.0; - } - double getPosition() { - if (_mode != MODE_PLAY) - return -1; - return static_cast<double>(_player.position()) / 1000.0; - } - bool seekTo(qint64 position) { - if (!_player.isSeekable()) - return false; - _player.setPosition(position * 1000); - return true; - } -private slots: - void reportPosition() { - double position = getPosition(); - _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_POSITION, %2)") - .arg(_id).arg(position)); - double duration = getDuration(); - _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_DURATION, %2)") - .arg(_id).arg(duration)); - - if (_stateChanged && !(_state == Media::MEDIA_RUNNING && (duration == -1 || position == 0))) { - qCritical() << _id << "POSITION" << position << ":" << duration; - _stateChanged = false; - _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_STATE, %2)").arg(_id).arg(_state)); - } - } - - void onMediaStatusChanged(QMediaPlayer::MediaStatus status) { - if (status == QMediaPlayer::InvalidMedia) { - reportError(Media::MEDIA_ERR_ABORTED, "AudioPlayer Error: The current media cannot be played."); - setState(Media::MEDIA_STOPPED); - } - if (status == QMediaPlayer::EndOfMedia) { - setState(Media::MEDIA_STOPPED); - seekTo(0); - } - } - void onError(QMediaRecorder::Error) { - reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Device is not ready or not available."); - setState(Media::MEDIA_STOPPED); - } - -private: - void reportError(int code, const QString &descr) { - Q_UNUSED(descr); - _plugin->execJS(QString("Media.onStatus('%1', Media.MEDIA_ERROR, {code: %2})") - .arg(_id).arg(code)); - } - - bool playMode() { - switch (_mode) { - case Player::MODE_NONE: - _mode = MODE_PLAY; - break; - case Player::MODE_PLAY: - break; - case Player::MODE_RECORD: - reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Can't play in record mode."); - return false; - break; - } - return true; - } - - bool recordMode() { - switch (_mode) { - case Player::MODE_NONE: - if (_recorder.outputLocation().isEmpty()) { - reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: unsupported output location."); - return false; - } - _mode = MODE_RECORD; - break; - case Player::MODE_PLAY: - reportError(Media::MEDIA_ERR_NONE_SUPPORTED, "AudioPlayer Error: Can't play in play mode."); - return false; - break; - case Player::MODE_RECORD: - break; - } - return true; - } - - void setState(Media::State state) { - _state = state; - _stateChanged = true; - _timer.start(250); - } - - QMediaPlayer _player; - - QAudioRecorder _recorder; - QTimer _timer; - - Media::State _state; - QString _src; - enum Mode { - MODE_NONE, - MODE_PLAY, - MODE_RECORD - }; - Mode _mode; - Media *_plugin; - QString _id; - - bool _stateChanged; -}; - -#endif diff --git a/plugins/org.apache.cordova.media/src/windows8/MediaProxy.js b/plugins/org.apache.cordova.media/src/windows8/MediaProxy.js deleted file mode 100644 index e7ec51b7..00000000 --- a/plugins/org.apache.cordova.media/src/windows8/MediaProxy.js +++ /dev/null @@ -1,217 +0,0 @@ -/* - * - * 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. - * -*/ - -/*global Windows:true */ - -var cordova = require('cordova'), - Media = require('org.apache.cordova.media.Media'); - -var MediaError = require('org.apache.cordova.media.MediaError'); - -var recordedFile; - -module.exports = { - mediaCaptureMrg:null, - - // Initiates the audio file - create:function(win, lose, args) { - var id = args[0]; - var src = args[1]; - var thisM = Media.get(id); - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING); - - Media.prototype.node = null; - - var fn = src.split('.').pop(); // gets the file extension - if (thisM.node === null) { - if (fn === 'mp3' || fn === 'wma' || fn === 'wav' || - fn === 'cda' || fn === 'adx' || fn === 'wm' || - fn === 'm3u' || fn === 'wmx' || fn === 'm4a') { - thisM.node = new Audio(src); - thisM.node.load(); - - var getDuration = function () { - var dur = thisM.node.duration; - if (isNaN(dur)) { - dur = -1; - } - Media.onStatus(id, Media.MEDIA_DURATION, dur); - }; - - thisM.node.onloadedmetadata = getDuration; - getDuration(); - } - else { - lose && lose({code:MediaError.MEDIA_ERR_ABORTED}); - } - } - }, - - // Start playing the audio - startPlayingAudio:function(win, lose, args) { - var id = args[0]; - //var src = args[1]; - //var options = args[2]; - - var thisM = Media.get(id); - // if Media was released, then node will be null and we need to create it again - if (!thisM.node) { - module.exports.create(win, lose, args); - } - - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); - - thisM.node.play(); - }, - - // Stops the playing audio - stopPlayingAudio:function(win, lose, args) { - var id = args[0]; - try { - (Media.get(id)).node.pause(); - (Media.get(id)).node.currentTime = 0; - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); - win(); - } catch (err) { - lose("Failed to stop: "+err); - } - }, - - // Seeks to the position in the audio - seekToAudio:function(win, lose, args) { - var id = args[0]; - var milliseconds = args[1]; - try { - (Media.get(id)).node.currentTime = milliseconds / 1000; - win(); - } catch (err) { - lose("Failed to seek: "+err); - } - }, - - // Pauses the playing audio - pausePlayingAudio:function(win, lose, args) { - var id = args[0]; - var thisM = Media.get(id); - try { - thisM.node.pause(); - Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED); - } catch (err) { - lose("Failed to pause: "+err); - } - }, - - // Gets current position in the audio - getCurrentPositionAudio:function(win, lose, args) { - var id = args[0]; - try { - var p = (Media.get(id)).node.currentTime; - Media.onStatus(id, Media.MEDIA_POSITION, p); - win(p); - } catch (err) { - lose(err); - } - }, - - // Start recording audio - startRecordingAudio:function(win, lose, args) { - var id = args[0]; - var src = args[1]; - - var normalizedSrc = src.replace(/\//g, '\\'); - var destPath = normalizedSrc.substr(0, normalizedSrc.lastIndexOf('\\')); - var destFileName = normalizedSrc.replace(destPath + '\\', ''); - - // Initialize device - Media.prototype.mediaCaptureMgr = null; - var thisM = (Media.get(id)); - var captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings(); - captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio; - thisM.mediaCaptureMgr = new Windows.Media.Capture.MediaCapture(); - thisM.mediaCaptureMgr.addEventListener("failed", lose); - - thisM.mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) { - thisM.mediaCaptureMgr.addEventListener("recordlimitationexceeded", lose); - thisM.mediaCaptureMgr.addEventListener("failed", lose); - - // Start recording - Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync(destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(function (newFile) { - recordedFile = newFile; - var encodingProfile = null; - switch (newFile.fileType) { - case '.m4a': - encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(Windows.Media.MediaProperties.AudioEncodingQuality.auto); - break; - case '.mp3': - encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.auto); - break; - case '.wma': - encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createWma(Windows.Media.MediaProperties.AudioEncodingQuality.auto); - break; - default: - lose("Invalid file type for record"); - break; - } - thisM.mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, newFile).done(win, lose); - }, lose); - }, lose); - }, - - // Stop recording audio - stopRecordingAudio:function(win, lose, args) { - var id = args[0]; - var thisM = Media.get(id); - - var normalizedSrc = thisM.src.replace(/\//g, '\\'); - var destPath = normalizedSrc.substr(0, normalizedSrc.lastIndexOf('\\')); - var destFileName = normalizedSrc.replace(destPath + '\\', ''); - - thisM.mediaCaptureMgr.stopRecordAsync().done(function () { - if (destPath) { - Windows.Storage.StorageFolder.getFolderFromPathAsync(destPath).done(function(destFolder) { - recordedFile.copyAsync(destFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(win, lose); - }, lose); - } else { - // if path is not defined, we leave recorded file in temporary folder (similar to iOS) - win(); - } - }, lose); - }, - - // Release the media object - release:function(win, lose, args) { - var id = args[0]; - var thisM = Media.get(id); - try { - delete thisM.node; - } catch (err) { - lose("Failed to release: "+err); - } - }, - setVolume:function(win, lose, args) { - var id = args[0]; - var volume = args[1]; - var thisM = Media.get(id); - thisM.volume = volume; - } -}; - -require("cordova/exec/proxy").add("Media",module.exports); diff --git a/plugins/org.apache.cordova.media/src/wp/AudioPlayer.cs b/plugins/org.apache.cordova.media/src/wp/AudioPlayer.cs deleted file mode 100644 index 882eb96e..00000000 --- a/plugins/org.apache.cordova.media/src/wp/AudioPlayer.cs +++ /dev/null @@ -1,647 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.IO; -using System.IO.IsolatedStorage; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Threading; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Audio; -using Microsoft.Xna.Framework.Media; -using Microsoft.Phone.Controls; -using System.Diagnostics; -using System.Windows.Resources; - -namespace WPCordovaClassLib.Cordova.Commands -{ - - /// <summary> - /// Implements audio record and play back functionality. - /// </summary> - internal class AudioPlayer : IDisposable - { - #region Constants - - // AudioPlayer states - private const int PlayerState_None = 0; - private const int PlayerState_Starting = 1; - private const int PlayerState_Running = 2; - private const int PlayerState_Paused = 3; - private const int PlayerState_Stopped = 4; - - // AudioPlayer messages - private const int MediaState = 1; - private const int MediaDuration = 2; - private const int MediaPosition = 3; - private const int MediaError = 9; - - // AudioPlayer errors - private const int MediaErrorPlayModeSet = 1; - private const int MediaErrorAlreadyRecording = 2; - private const int MediaErrorStartingRecording = 3; - private const int MediaErrorRecordModeSet = 4; - private const int MediaErrorStartingPlayback = 5; - private const int MediaErrorResumeState = 6; - private const int MediaErrorPauseState = 7; - private const int MediaErrorStopState = 8; - - //TODO: get rid of this callback, it should be universal - //private const string CallbackFunction = "CordovaMediaonStatus"; - - #endregion - - - /// <summary> - /// The AudioHandler object - /// </summary> - private Media handler; - - /// <summary> - /// Temporary buffer to store audio chunk - /// </summary> - private byte[] buffer; - - /// <summary> - /// Xna game loop dispatcher - /// </summary> - DispatcherTimer dtXna; - - - /// <summary> - /// Output buffer - /// </summary> - private MemoryStream memoryStream; - - /// <summary> - /// The id of this player (used to identify Media object in JavaScript) - /// </summary> - private String id; - - /// <summary> - /// State of recording or playback - /// </summary> - private int state = PlayerState_None; - - /// <summary> - /// File name to play or record to - /// </summary> - private String audioFile = null; - - /// <summary> - /// Duration of audio - /// </summary> - private double duration = -1; - - /// <summary> - /// Audio player object - /// </summary> - private MediaElement player = null; - - /// <summary> - /// Audio source - /// </summary> - private Microphone recorder; - - /// <summary> - /// Internal flag specified that we should only open audio w/o playing it - /// </summary> - private bool prepareOnly = false; - - /// <summary> - /// Creates AudioPlayer instance - /// </summary> - /// <param name="handler">Media object</param> - /// <param name="id">player id</param> - public AudioPlayer(Media handler, String id) - { - this.handler = handler; - this.id = id; - } - - - /// <summary> - /// Destroys player and stop audio playing or recording - /// </summary> - public void Dispose() - { - if (this.player != null) - { - this.stopPlaying(); - this.player = null; - } - if (this.recorder != null) - { - this.stopRecording(); - this.recorder = null; - } - - this.FinalizeXnaGameLoop(); - } - - private void InvokeCallback(int message, string value, bool removeHandler) - { - string args = string.Format("('{0}',{1},{2});", this.id, message, value); - string callback = @"(function(id,msg,value){ - try { - if (msg == Media.MEDIA_ERROR) { - value = {'code':value}; - } - Media.onStatus(id,msg,value); - } - catch(e) { - console.log('Error calling Media.onStatus :: ' + e); - } - })" + args; - this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false); - } - - private void InvokeCallback(int message, int value, bool removeHandler) - { - InvokeCallback(message, value.ToString(), removeHandler); - } - - private void InvokeCallback(int message, double value, bool removeHandler) - { - InvokeCallback(message, value.ToString(), removeHandler); - } - - /// <summary> - /// Starts recording, data is stored in memory - /// </summary> - /// <param name="filePath"></param> - public void startRecording(string filePath) - { - if (this.player != null) - { - InvokeCallback(MediaError, MediaErrorPlayModeSet, false); - } - else if (this.recorder == null) - { - try - { - this.audioFile = filePath; - this.InitializeXnaGameLoop(); - this.recorder = Microphone.Default; - this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500); - this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)]; - this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady); - MemoryStream stream = new MemoryStream(); - this.memoryStream = stream; - int numBits = 16; - int numBytes = numBits / 8; - - // inline version from AudioFormatsHelper - stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4); - stream.Write(BitConverter.GetBytes(0), 0, 4); - stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4); - stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4); - stream.Write(BitConverter.GetBytes(16), 0, 4); - stream.Write(BitConverter.GetBytes((short)1), 0, 2); - stream.Write(BitConverter.GetBytes((short)1), 0, 2); - stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4); - stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4); - stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2); - stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2); - stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4); - stream.Write(BitConverter.GetBytes(0), 0, 4); - - this.recorder.Start(); - FrameworkDispatcher.Update(); - this.SetState(PlayerState_Running); - } - catch (Exception) - { - InvokeCallback(MediaError, MediaErrorStartingRecording, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false); - } - } - else - { - InvokeCallback(MediaError, MediaErrorAlreadyRecording, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false); - } - } - - /// <summary> - /// Stops recording - /// </summary> - public void stopRecording() - { - if (this.recorder != null) - { - if (this.state == PlayerState_Running) - { - try - { - this.recorder.Stop(); - this.recorder.BufferReady -= recorderBufferReady; - this.recorder = null; - SaveAudioClipToLocalStorage(); - this.FinalizeXnaGameLoop(); - this.SetState(PlayerState_Stopped); - } - catch (Exception) - { - //TODO - } - } - } - } - - /// <summary> - /// Starts or resume playing audio file - /// </summary> - /// <param name="filePath">The name of the audio file</param> - /// <summary> - /// Starts or resume playing audio file - /// </summary> - /// <param name="filePath">The name of the audio file</param> - public void startPlaying(string filePath) - { - if (this.recorder != null) - { - InvokeCallback(MediaError, MediaErrorRecordModeSet, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false); - return; - } - - - if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0) - { - try - { - // this.player is a MediaElement, it must be added to the visual tree in order to play - PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame; - if (frame != null) - { - PhoneApplicationPage page = frame.Content as PhoneApplicationPage; - if (page != null) - { - Grid grid = page.FindName("LayoutRoot") as Grid; - if (grid != null) - { - - this.player = grid.FindName("playerMediaElement") as MediaElement; - if (this.player == null) // still null ? - { - this.player = new MediaElement(); - this.player.Name = "playerMediaElement"; - grid.Children.Add(this.player); - this.player.Visibility = Visibility.Visible; - } - if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing) - { - this.player.Stop(); // stop it! - } - - this.player.Source = null; // Garbage collect it. - this.player.MediaOpened += MediaOpened; - this.player.MediaEnded += MediaEnded; - this.player.MediaFailed += MediaFailed; - } - } - } - - this.audioFile = filePath; - - Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute); - if (uri.IsAbsoluteUri) - { - this.player.Source = uri; - } - else - { - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - if (!isoFile.FileExists(filePath)) - { - // try to unpack it from the dll into isolated storage - StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative)); - if (fileResourceStreamInfo != null) - { - using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream)) - { - byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length); - - string[] dirParts = filePath.Split('/'); - string dirName = ""; - for (int n = 0; n < dirParts.Length - 1; n++) - { - dirName += dirParts[n] + "/"; - } - if (!isoFile.DirectoryExists(dirName)) - { - isoFile.CreateDirectory(dirName); - } - - using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create)) - { - using (BinaryWriter writer = new BinaryWriter(outFile)) - { - writer.Write(data); - } - } - } - } - } - if (isoFile.FileExists(filePath)) - { - using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile)) - { - this.player.SetSource(stream); - } - } - else - { - InvokeCallback(MediaError, MediaErrorPlayModeSet, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false); - return; - } - } - } - this.SetState(PlayerState_Starting); - } - catch (Exception e) - { - Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message); - InvokeCallback(MediaError, MediaErrorStartingPlayback, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false); - } - } - else - { - if (this.state != PlayerState_Running) - { - this.player.Play(); - this.SetState(PlayerState_Running); - } - else - { - InvokeCallback(MediaError, MediaErrorResumeState, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false); - } - } - } - - /// <summary> - /// Callback to be invoked when the media source is ready for playback - /// </summary> - private void MediaOpened(object sender, RoutedEventArgs arg) - { - if (this.player != null) - { - this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds; - InvokeCallback(MediaDuration, this.duration, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false); - if (!this.prepareOnly) - { - this.player.Play(); - this.SetState(PlayerState_Running); - } - this.prepareOnly = false; - } - else - { - // TODO: occasionally MediaOpened is signalled, but player is null - } - } - - /// <summary> - /// Callback to be invoked when playback of a media source has completed - /// </summary> - private void MediaEnded(object sender, RoutedEventArgs arg) - { - this.SetState(PlayerState_Stopped); - } - - /// <summary> - /// Callback to be invoked when playback of a media source has failed - /// </summary> - private void MediaFailed(object sender, RoutedEventArgs arg) - { - player.Stop(); - InvokeCallback(MediaError, MediaErrorStartingPlayback, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false); - } - - /// <summary> - /// Seek or jump to a new time in the track - /// </summary> - /// <param name="milliseconds">The new track position</param> - public void seekToPlaying(int milliseconds) - { - if (this.player != null) - { - TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds); - this.player.Position = tsPos; - InvokeCallback(MediaPosition, milliseconds / 1000.0f, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false); - } - } - - /// <summary> - /// Set the volume of the player - /// </summary> - /// <param name="vol">volume 0.0-1.0, default value is 0.5</param> - public void setVolume(double vol) - { - if (this.player != null) - { - this.player.Volume = vol; - } - } - - /// <summary> - /// Pauses playing - /// </summary> - public void pausePlaying() - { - if (this.state == PlayerState_Running) - { - this.player.Pause(); - this.SetState(PlayerState_Paused); - } - else - { - InvokeCallback(MediaError, MediaErrorPauseState, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false); - } - } - - - /// <summary> - /// Stops playing the audio file - /// </summary> - public void stopPlaying() - { - if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused)) - { - this.player.Stop(); - - this.player.Position = new TimeSpan(0L); - this.SetState(PlayerState_Stopped); - } - //else // Why is it an error to call stop on a stopped media? - //{ - // this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false); - //} - } - - /// <summary> - /// Gets current position of playback - /// </summary> - /// <returns>current position</returns> - public double getCurrentPosition() - { - if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused)) - { - double currentPosition = this.player.Position.TotalSeconds; - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false); - return currentPosition; - } - else - { - return 0; - } - } - - /// <summary> - /// Gets the duration of the audio file - /// </summary> - /// <param name="filePath">The name of the audio file</param> - /// <returns>track duration</returns> - public double getDuration(string filePath) - { - if (this.recorder != null) - { - return (-2); - } - - if (this.player != null) - { - return this.duration; - - } - else - { - this.prepareOnly = true; - this.startPlaying(filePath); - return this.duration; - } - } - - /// <summary> - /// Sets the state and send it to JavaScript - /// </summary> - /// <param name="state">state</param> - private void SetState(int state) - { - if (this.state != state) - { - InvokeCallback(MediaState, state, false); - //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false); - } - - this.state = state; - } - - #region record methods - - /// <summary> - /// Copies data from recorder to memory storages and updates recording state - /// </summary> - /// <param name="sender"></param> - /// <param name="e"></param> - private void recorderBufferReady(object sender, EventArgs e) - { - this.recorder.GetData(this.buffer); - this.memoryStream.Write(this.buffer, 0, this.buffer.Length); - } - - /// <summary> - /// Writes audio data from memory to isolated storage - /// </summary> - /// <returns></returns> - private void SaveAudioClipToLocalStorage() - { - if (memoryStream == null || memoryStream.Length <= 0) - { - return; - } - - long position = memoryStream.Position; - memoryStream.Seek(4, SeekOrigin.Begin); - memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4); - memoryStream.Seek(40, SeekOrigin.Begin); - memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4); - memoryStream.Seek(position, SeekOrigin.Begin); - - try - { - using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) - { - string directory = Path.GetDirectoryName(audioFile); - - if (!isoFile.DirectoryExists(directory)) - { - isoFile.CreateDirectory(directory); - } - - this.memoryStream.Seek(0, SeekOrigin.Begin); - - using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile)) - { - this.memoryStream.CopyTo(fileStream); - } - } - } - catch (Exception) - { - //TODO: log or do something else - throw; - } - } - - #region Xna loop - /// <summary> - /// Special initialization required for the microphone: XNA game loop - /// </summary> - private void InitializeXnaGameLoop() - { - // Timer to simulate the XNA game loop (Microphone is from XNA) - this.dtXna = new DispatcherTimer(); - this.dtXna.Interval = TimeSpan.FromMilliseconds(33); - this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } }; - this.dtXna.Start(); - } - /// <summary> - /// Finalizes XNA game loop for microphone - /// </summary> - private void FinalizeXnaGameLoop() - { - // Timer to simulate the XNA game loop (Microphone is from XNA) - if (this.dtXna != null) - { - this.dtXna.Stop(); - this.dtXna = null; - } - } - - #endregion - - #endregion - } -} diff --git a/plugins/org.apache.cordova.media/src/wp/Media.cs b/plugins/org.apache.cordova.media/src/wp/Media.cs deleted file mode 100644 index aedd2bb6..00000000 --- a/plugins/org.apache.cordova.media/src/wp/Media.cs +++ /dev/null @@ -1,590 +0,0 @@ -/* - Licensed 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. -*/ - -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using System.Windows; -using System.Diagnostics; - -namespace WPCordovaClassLib.Cordova.Commands -{ - /// <summary> - /// Provides the ability to record and play back audio files on a device. - /// </summary> - public class Media : BaseCommand - { - /// <summary> - /// Audio player objects - /// </summary> - private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>(); - - /// <summary> - /// Represents Media action options. - /// </summary> - [DataContract] - public class MediaOptions - { - /// <summary> - /// Audio id - /// </summary> - [DataMember(Name = "id", IsRequired = true)] - public string Id { get; set; } - - /// <summary> - /// Path to audio file - /// </summary> - [DataMember(Name = "src")] - public string Src { get; set; } - - /// <summary> - /// New track position - /// </summary> - [DataMember(Name = "milliseconds")] - public int Milliseconds { get; set; } - - public string CallbackId { get; set; } - } - - /// <summary> - /// Releases the audio player instance to save memory. - /// </summary> - public void release(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - MediaOptions mediaOptions = new MediaOptions(); - - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - mediaOptions.Id = optionsString[0]; - callbackId = mediaOptions.CallbackId = optionsString[1]; - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - - if (!Media.players.ContainsKey(mediaOptions.Id)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false), callbackId); - return; - } - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - AudioPlayer audio = Media.players[mediaOptions.Id]; - Media.players.Remove(mediaOptions.Id); - audio.Dispose(); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true), mediaOptions.CallbackId); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), mediaOptions.CallbackId); - } - }); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - } - - private AudioPlayer GetOrCreatePlayerById(string id) - { - AudioPlayer audio = null; - - lock (Media.players) - { - if (!Media.players.TryGetValue(id, out audio)) - { - audio = new AudioPlayer(this, id); - Media.players.Add(id, audio); - Debug.WriteLine("Media Created in GetOrCreatePlayerById"); - } - } - - - - return audio; - } - - /// <summary> - /// Starts recording and save the specified file - /// </summary> - public void startRecordingAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - MediaOptions mediaOptions = new MediaOptions(); - - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - mediaOptions.Id = optionsString[0]; - mediaOptions.Src = optionsString[1]; - callbackId = mediaOptions.CallbackId = optionsString[2]; - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), mediaOptions.CallbackId); - return; - } - - if (mediaOptions != null) - { - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - AudioPlayer audio; - if (!Media.players.ContainsKey(mediaOptions.Id)) - { - audio = new AudioPlayer(this, mediaOptions.Id); - Media.players.Add(mediaOptions.Id, audio); - } - else - { - audio = Media.players[mediaOptions.Id]; - } - - if (audio != null) - { - audio.startRecording(mediaOptions.Src); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), mediaOptions.CallbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, - "Error accessing AudioPlayer for key " + mediaOptions.Id), mediaOptions.CallbackId); - } - - - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), mediaOptions.CallbackId); - } - - }); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), mediaOptions.CallbackId); - } - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - } - - /// <summary> - /// Stops recording and save to the file specified when recording started - /// </summary> - public void stopRecordingAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - - try - { - string[] optStrings = JSON.JsonHelper.Deserialize<string[]>(options); - string mediaId = optStrings[0]; - callbackId = optStrings[1]; - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - if (Media.players.ContainsKey(mediaId)) - { - AudioPlayer audio = Media.players[mediaId]; - audio.stopRecording(); - Media.players.Remove(mediaId); - } - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - }); - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - } - } - - public void setVolume(string options) // id,volume - { - string callbackId = this.CurrentCommandCallbackId; - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - string id = optionsString[0]; - double volume = 0.0d; - double.TryParse(optionsString[1], out volume); - - callbackId = optionsString[2]; - - if (Media.players.ContainsKey(id)) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - AudioPlayer player = Media.players[id]; - player.setVolume(volume); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - }); - } - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, - "Error parsing options into setVolume method"), callbackId); - } - } - - // Some Audio Notes: - // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported. - // While playing, a MediaElement stops all other media playback on the phone. - // Multiple MediaElement controls are NOT supported - - // Called when you create a new Media('blah.wav') object in JS. - public void create(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - MediaOptions mediaOptions; - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - mediaOptions = new MediaOptions(); - mediaOptions.Id = optionsString[0]; - mediaOptions.Src = optionsString[1]; - callbackId = mediaOptions.CallbackId = optionsString[2]; - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, - "Error parsing options into create method"), callbackId); - return; - } - - GetOrCreatePlayerById(mediaOptions.Id); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - } - - /// <summary> - /// Starts or resume playing audio file - /// </summary> - public void startPlayingAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - MediaOptions mediaOptions; - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - mediaOptions = new MediaOptions(); - mediaOptions.Id = optionsString[0]; - mediaOptions.Src = optionsString[1]; - int msec = 0; - if (int.TryParse(optionsString[2], out msec)) - { - mediaOptions.Milliseconds = msec; - } - callbackId = mediaOptions.CallbackId = optionsString[3]; - - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - - AudioPlayer audio = GetOrCreatePlayerById(mediaOptions.Id); - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - audio.startPlaying(mediaOptions.Src); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - }); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - } - - - /// <summary> - /// Seeks to a location - /// </summary> - public void seekToAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - MediaOptions mediaOptions; - - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - mediaOptions = new MediaOptions(); - mediaOptions.Id = optionsString[0]; - int msec = 0; - if (int.TryParse(optionsString[2], out msec)) - { - mediaOptions.Milliseconds = msec; - } - callbackId = mediaOptions.CallbackId = optionsString[3]; - - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - if (Media.players.ContainsKey(mediaOptions.Id)) - { - AudioPlayer audio = Media.players[mediaOptions.Id]; - audio.seekToPlaying(mediaOptions.Milliseconds); - } - else - { - Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id); - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - }); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - } - - /// <summary> - /// Pauses playing - /// </summary> - public void pausePlayingAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - string mediaId = optionsString[0]; - callbackId = optionsString[1]; - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - if (Media.players.ContainsKey(mediaId)) - { - AudioPlayer audio = Media.players[mediaId]; - audio.pausePlaying(); - } - else - { - Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId); - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message),callbackId); - } - }); - - - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId); - } - - - } - - - /// <summary> - /// Stops playing the audio file - /// </summary> - public void stopPlayingAudio(String options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - string[] optionsStrings = JSON.JsonHelper.Deserialize<string[]>(options); - string mediaId = optionsStrings[0]; - callbackId = optionsStrings[1]; - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - if (Media.players.ContainsKey(mediaId)) - { - AudioPlayer audio = Media.players[mediaId]; - audio.stopPlaying(); - } - else - { - Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId); - } - - DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - }); - - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - } - } - - /// <summary> - /// Gets current position of playback - /// </summary> - public void getCurrentPositionAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - string[] optionsStrings = JSON.JsonHelper.Deserialize<string[]>(options); - string mediaId = optionsStrings[0]; - callbackId = optionsStrings[1]; - Deployment.Current.Dispatcher.BeginInvoke(() => - { - try - { - if (Media.players.ContainsKey(mediaId)) - { - AudioPlayer audio = Media.players[mediaId]; - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()), callbackId); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1), callbackId); - } - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - }); - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - } - - - /// <summary> - /// Gets the duration of the audio file - /// </summary> - - [Obsolete("This method will be removed shortly")] - public void getDurationAudio(string options) - { - string callbackId = this.CurrentCommandCallbackId; - try - { - MediaOptions mediaOptions; - - try - { - string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options); - - mediaOptions = new MediaOptions(); - mediaOptions.Id = optionsString[0]; - mediaOptions.Src = optionsString[1]; - callbackId = mediaOptions.CallbackId = optionsString[2]; - } - catch (Exception) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId); - return; - } - - AudioPlayer audio; - if (Media.players.ContainsKey(mediaOptions.Id)) - { - audio = Media.players[mediaOptions.Id]; - } - else - { - Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id); - audio = new AudioPlayer(this, mediaOptions.Id); - Media.players.Add(mediaOptions.Id, audio); - } - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)), callbackId); - }); - } - catch (Exception e) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message), callbackId); - } - } - } -} diff --git a/plugins/org.apache.cordova.media/tests/plugin.xml b/plugins/org.apache.cordova.media/tests/plugin.xml deleted file mode 100644 index 5c20c50d..00000000 --- a/plugins/org.apache.cordova.media/tests/plugin.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:rim="http://www.blackberry.com/ns/widgets" - xmlns:android="http://schemas.android.com/apk/res/android" - id="org.apache.cordova.media.tests" - version="0.2.16"> - <name>Cordova Media Plugin Tests</name> - <license>Apache 2.0</license> - <js-module src="tests.js" name="tests"> - </js-module> -</plugin> diff --git a/plugins/org.apache.cordova.media/tests/tests.js b/plugins/org.apache.cordova.media/tests/tests.js deleted file mode 100644 index 3e8ad9f3..00000000 --- a/plugins/org.apache.cordova.media/tests/tests.js +++ /dev/null @@ -1,836 +0,0 @@ -/* - * - * 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. - * - */ - -exports.defineAutoTests = function () { - var failed = function (done, msg, error) { - var info = typeof msg == 'undefined' ? 'Unexpected error callback' : msg; - expect(true).toFailWithMessage(info + '\n' + JSON.stringify(error)); - done(); - }; - - var succeed = function (done, msg) { - var info = typeof msg == 'undefined' ? 'Unexpected success callback' : msg; - expect(true).toFailWithMessage(info); - done(); - }; - - describe('Media', function () { - - beforeEach(function () { - // Custom Matcher - jasmine.Expectation.addMatchers({ - toFailWithMessage : function () { - return { - compare : function (error, message) { - var pass = false; - return { - pass : pass, - message : message - }; - } - }; - } - }); - }); - - it("media.spec.1 should exist", function () { - expect(Media).toBeDefined(); - expect(typeof Media).toBe("function"); - }); - - it("media.spec.2 should have the following properties", function () { - var media1 = new Media("dummy"); - expect(media1.id).toBeDefined(); - expect(media1.src).toBeDefined(); - expect(media1._duration).toBeDefined(); - expect(media1._position).toBeDefined(); - media1.release(); - }); - - it("media.spec.3 should define constants for Media status", function () { - expect(Media).toBeDefined(); - expect(Media.MEDIA_NONE).toBe(0); - expect(Media.MEDIA_STARTING).toBe(1); - expect(Media.MEDIA_RUNNING).toBe(2); - expect(Media.MEDIA_PAUSED).toBe(3); - expect(Media.MEDIA_STOPPED).toBe(4); - }); - - it("media.spec.4 should define constants for Media errors", function () { - expect(MediaError).toBeDefined(); - expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0); - expect(MediaError.MEDIA_ERR_ABORTED).toBe(1); - expect(MediaError.MEDIA_ERR_NETWORK).toBe(2); - expect(MediaError.MEDIA_ERR_DECODE).toBe(3); - expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4); - }); - - it("media.spec.5 should contain a play function", function () { - var media1 = new Media(); - expect(media1.play).toBeDefined(); - expect(typeof media1.play).toBe('function'); - media1.release(); - }); - - it("media.spec.6 should contain a stop function", function () { - var media1 = new Media(); - expect(media1.stop).toBeDefined(); - expect(typeof media1.stop).toBe('function'); - media1.release(); - }); - - it("media.spec.7 should contain a seekTo function", function () { - var media1 = new Media(); - expect(media1.seekTo).toBeDefined(); - expect(typeof media1.seekTo).toBe('function'); - media1.release(); - }); - - it("media.spec.8 should contain a pause function", function () { - var media1 = new Media(); - expect(media1.pause).toBeDefined(); - expect(typeof media1.pause).toBe('function'); - media1.release(); - }); - - it("media.spec.9 should contain a getDuration function", function () { - var media1 = new Media(); - expect(media1.getDuration).toBeDefined(); - expect(typeof media1.getDuration).toBe('function'); - media1.release(); - }); - - it("media.spec.10 should contain a getCurrentPosition function", function () { - var media1 = new Media(); - expect(media1.getCurrentPosition).toBeDefined(); - expect(typeof media1.getCurrentPosition).toBe('function'); - media1.release(); - }); - - it("media.spec.11 should contain a startRecord function", function () { - var media1 = new Media(); - expect(media1.startRecord).toBeDefined(); - expect(typeof media1.startRecord).toBe('function'); - media1.release(); - }); - - it("media.spec.12 should contain a stopRecord function", function () { - var media1 = new Media(); - expect(media1.stopRecord).toBeDefined(); - expect(typeof media1.stopRecord).toBe('function'); - media1.release(); - }); - - it("media.spec.13 should contain a release function", function () { - var media1 = new Media(); - expect(media1.release).toBeDefined(); - expect(typeof media1.release).toBe('function'); - media1.release(); - }); - - it("media.spec.14 should contain a setVolume function", function () { - var media1 = new Media(); - expect(media1.setVolume).toBeDefined(); - expect(typeof media1.setVolume).toBe('function'); - media1.release(); - }); - - it("media.spec.15 should return MediaError for bad filename", function (done) { - var fileName = 'invalid.file.name'; - //Error callback it has an unexpected behavior under Windows Phone, - //it enters to the error callback several times, instead of just one walk-through - //JIRA issue related with all details: CB-7092 - //the conditional statement should be removed once the issue is fixed. - - //bb10 dialog pops up, preventing tests from running - if (cordova.platformId === 'blackberry10' || cordova.platformId === 'windowsphone') { - expect(true).toFailWithMessage('Platform does not support this feature'); - done(); - } else { - var badMedia = null; - badMedia = new Media(fileName, succeed.bind(null, done, ' badMedia = new Media , Unexpected succees callback, it should not create Media object with invalid file name'), function (result) { - expect(result).toBeDefined(); - expect(result.code).toBe(MediaError.MEDIA_ERR_ABORTED); - if (badMedia !== null) { - badMedia.release(); - } - done(); - }); - badMedia.play(); - } - }); - - it("media.spec.16 position should be set properly", function (done) { - var mediaFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3', - mediaState = Media.MEDIA_STOPPED, - successCallback, - flag = true, - statusChange = function (statusCode) { - if (statusCode == Media.MEDIA_RUNNING && flag) { - //flag variable used to ensure an extra security statement to ensure that the callback is processed only once, - //in case for some reason the statusChange callback is reached more than one time with the same status code. - //Some information about this kind of behavior it can be found at JIRA: CB-7099 - flag = false; - setTimeout(function () { - media1.getCurrentPosition(function (position) { - expect(position).toBeGreaterThan(0.0); - media1.stop(); - media1.release(); - done(); - }, failed.bind(null, done, 'media1.getCurrentPosition - Error getting media current position')); - }, 1000); - } - }, - media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile), statusChange); - media1.play(); - }); - - it("media.spec.17 duration should be set properly", function (done) { - if (cordova.platformId === 'blackberry10') { - expect(true).toFailWithMessage('Platform does not supported this feature'); - done(); - } - var mediaFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3', - mediaState = Media.MEDIA_STOPPED, - successCallback, - flag = true, - statusChange = function (statusCode) { - if (statusCode == Media.MEDIA_RUNNING && flag) { - //flag variable used to ensure an extra security statement to ensure that the callback is processed only once, - //in case for some reason the statusChange callback is reached more than one time with the same status code. - //Some information about this kind of behavior it can be found at JIRA: CB-7099. - flag = false; - setTimeout(function () { - expect(media1.getDuration()).toBeGreaterThan(0.0); - media1.stop(); - media1.release(); - done(); - }, 1000); - } - }, - media1 = new Media(mediaFile, successCallback, failed.bind(null, done, 'media1 = new Media - Error creating Media object. Media file: ' + mediaFile), statusChange); - media1.play(); - }); - }); -}; - -//****************************************************************************************** -//***************************************Manual Tests*************************************** -//****************************************************************************************** - -exports.defineManualTests = function (contentEl, createActionButton) { - //------------------------------------------------------------------------- - // Audio player - //------------------------------------------------------------------------- - var media1 = null; - var media1Timer = null; - var audioSrc = null; - var defaultaudio = "http://cordova.apache.org/downloads/BlueZedEx.mp3"; - - //Play audio function - function playAudio(url) { - console.log("playAudio()"); - console.log(" -- media=" + media1); - - var src = defaultaudio; - - if (url) { - src = url; - } - - // Stop playing if src is different from currently playing source - if (src !== audioSrc) { - if (media1 !== null) { - stopAudio(); - media1 = null; - } - } - - if (media1 === null) { - - // TEST STREAMING AUDIO PLAYBACK - //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3"; // works - //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work - //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works - //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work - //var src = "MusicSearch/mp3/train.mp3"; // works - //var src = "bryce.mp3"; // works - //var src = "/android_asset/www/bryce.mp3"; // works - - media1 = new Media(src, - function () { - console.log("playAudio():Audio Success"); - }, - function (err) { - console.log("playAudio():Audio Error: " + err.code); - setAudioStatus("Error: " + err.code); - }, - function (status) { - console.log("playAudio():Audio Status: " + status); - setAudioStatus(Media.MEDIA_MSG[status]); - - // If stopped, then stop getting current position - if (Media.MEDIA_STOPPED == status) { - clearInterval(media1Timer); - media1Timer = null; - setAudioPosition("0 sec"); - } - }); - } - audioSrc = src; - document.getElementById('durationValue').innerHTML = ""; - // Play audio - media1.play(); - if (media1Timer === null && media1.getCurrentPosition) { - media1Timer = setInterval( - function () { - media1.getCurrentPosition( - function (position) { - if (position >= 0.0) { - setAudioPosition(position + " sec"); - } - }, - function (e) { - console.log("Error getting pos=" + e); - setAudioPosition("Error: " + e); - }); - }, - 1000); - } - - // Get duration - var counter = 0; - var timerDur = setInterval( - function () { - counter = counter + 100; - if (counter > 2000) { - clearInterval(timerDur); - } - var dur = media1.getDuration(); - if (dur > 0) { - clearInterval(timerDur); - document.getElementById('durationValue').innerHTML = dur + " sec"; - } - }, 100); - } - - //Pause audio playback - function pauseAudio() { - console.log("pauseAudio()"); - if (media1) { - media1.pause(); - } - } - - //Stop audio - function stopAudio() { - console.log("stopAudio()"); - if (media1) { - media1.stop(); - } - clearInterval(media1Timer); - media1Timer = null; - } - - //Release audio - function releaseAudio() { - console.log("releaseAudio()"); - if (media1) { - media1.stop(); //imlied stop of playback, resets timer - media1.release(); - } - } - - //Set audio status - function setAudioStatus(status) { - document.getElementById('statusValue').innerHTML = status; - } - - //Set audio position - function setAudioPosition(position) { - document.getElementById('positionValue').innerHTML = position; - } - - //Seek audio - function seekAudio(mode) { - var time = document.getElementById("seekInput").value; - if (time === "") { - time = 5000; - } else { - time = time * 1000; //we expect the input to be in seconds - } - if (media1 === null) { - console.log("seekTo requested while media1 is null"); - if (audioSrc === null) { - audioSrc = defaultaudio; - } - media1 = new Media(audioSrc, - function () { - console.log("seekToAudio():Audio Success"); - }, - function (err) { - console.log("seekAudio():Audio Error: " + err.code); - setAudioStatus("Error: " + err.code); - }, - function (status) { - console.log("seekAudio():Audio Status: " + status); - setAudioStatus(Media.MEDIA_MSG[status]); - - // If stopped, then stop getting current position - if (Media.MEDIA_STOPPED == status) { - clearInterval(media1Timer); - media1Timer = null; - setAudioPosition("0 sec"); - } - }); - } - - media1.getCurrentPosition( - function (position) { - var deltat = time; - if (mode === "by") { - deltat = time + position * 1000; - } - media1.seekTo(deltat, - function () { - console.log("seekAudioTo():Audio Success"); - //force an update on the position display - updatePosition(); - }, - function (err) { - console.log("seekAudioTo():Audio Error: " + err.code); - }); - }, - function (e) { - console.log("Error getting pos=" + e); - setAudioPosition("Error: " + e); - }); - } - - //for forced updates of position after a successful seek - - function updatePosition() { - media1.getCurrentPosition( - function (position) { - if (position >= 0.0) { - setAudioPosition(position + " sec"); - } - }, - function (e) { - console.log("Error getting pos=" + e); - setAudioPosition("Error: " + e); - }); - } - - //------------------------------------------------------------------------- - // Audio recorder - //------------------------------------------------------------------------- - var mediaRec = null; - var recTime = 0; - var recordSrc = "myRecording.mp3"; - - //Record audio - function recordAudio() { - console.log("recordAudio()"); - console.log(" -- media=" + mediaRec); - if (mediaRec == null) { - var src = recordSrc; - mediaRec = new Media(src, - function () { - console.log("recordAudio():Audio Success"); - }, - function (err) { - console.log("recordAudio():Audio Error: " + err.code); - setAudioStatus("Error: " + err.code); - }, - function (status) { - console.log("recordAudio():Audio Status: " + status); - setAudioStatus(Media.MEDIA_MSG[status]); - }); - } - - // Record audio - mediaRec.startRecord(); - - // Stop recording after 10 sec - recTime = 0; - var recInterval = setInterval(function () { - recTime = recTime + 1; - setAudioPosition(recTime + " sec"); - if (recTime >= 10) { - clearInterval(recInterval); - if (mediaRec.stopAudioRecord) { - mediaRec.stopAudioRecord(); - } else { - mediaRec.stopRecord(); - } - console.log("recordAudio(): stop"); - } - }, 1000); - } - - //Play back recorded audio - function playRecording() { - playAudio(recordSrc); - } - - //Function to create a file for iOS recording - - function getRecordSrc() { - var fsFail = function (error) { - console.log("error creating file for iOS recording"); - }; - var gotFile = function (file) { - recordSrc = file.fullPath; - //console.log("recording Src: " + recordSrc); - }; - var gotFS = function (fileSystem) { - fileSystem.root.getFile("iOSRecording.wav", { - create : true - }, gotFile, fsFail); - }; - window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail); - } - - //Function to create a file for BB recording - function getRecordSrcBB() { - var fsFail = function (error) { - console.log("error creating file for BB recording"); - }; - var gotFile = function (file) { - recordSrc = file.fullPath; - }; - var gotFS = function (fileSystem) { - fileSystem.root.getFile("BBRecording.amr", { - create : true - }, gotFile, fsFail); - }; - window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail); - } - - //Function to create a file for Windows recording - function getRecordSrcWin() { - var fsFail = function (error) { - console.log("error creating file for Win recording"); - }; - var gotFile = function (file) { - recordSrc = file.fullPath.replace(/\//g, '\\'); - }; - var gotFS = function (fileSystem) { - fileSystem.root.getFile("WinRecording.m4a", { - create: true - }, gotFile, fsFail); - }; - window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fsFail); - } - -//Generate Dynamic Table - function generateTable(tableId, rows, cells, elements) { - var table = document.createElement('table'); - for (var r = 0; r < rows; r++) { - var row = table.insertRow(r); - for (var c = 0; c < cells; c++) { - var cell = row.insertCell(c); - cell.setAttribute("align", "center"); - for (var e in elements) { - if (elements[e].position.row == r && elements[e].position.cell == c) { - var htmlElement = document.createElement(elements[e].tag); - var content; - - if (elements[e].content !== "") { - content = document.createTextNode(elements[e].content); - htmlElement.appendChild(content); - } - if (elements[e].type) { - htmlElement.type = elements[e].type; - } - htmlElement.setAttribute("id", elements[e].id); - cell.appendChild(htmlElement); - } - } - } - } - table.setAttribute("align", "center"); - table.setAttribute("id", tableId); - return table; - } - -//Audio && Record Elements - var elementsResultsAudio= - [{ - id : "statusTag", - content : "Status:", - tag : "div", - position : { - row : 0, - cell : 0 - } - }, { - id : "statusValue", - content : "", - tag : "div", - position : { - row : 0, - cell : 2 - } - }, { - id : "durationTag", - content : "Duration:", - tag : "div", - position : { - row : 1, - cell : 0 - } - }, { - id : "durationValue", - content : "", - tag : "div", - position : { - row : 1, - cell : 2 - } - }, { - id : "positionTag", - content : "Position:", - tag : "div", - position : { - row : 2, - cell : 0 - } - }, { - id : "positionValue", - content : "", - tag : "div", - position : { - row : 2, - cell : 2 - } - }], - elementsAudio = - [{ - id : "playBtn", - content : "", - tag : "div", - position : { - row : 0, - cell : 0 - } - }, { - id : "pauseBtn", - content : "", - tag : "div", - position : { - row : 0, - cell : 1 - } - }, { - id : "stopBtn", - content : "", - tag : "div", - position : { - row : 1, - cell : 0 - } - }, { - id : "releaseBtn", - content : "", - tag : "div", - position : { - row : 1, - cell : 1 - } - }, { - id : "seekByBtn", - content : "", - tag : "div", - position : { - row : 2, - cell : 0 - } - }, { - id : "seekToBtn", - content : "", - tag : "div", - position : { - row : 2, - cell : 1 - } - }, { - id : "seekInput", - content : "", - tag : "input", - type : "number", - position : { - row : 2, - cell : 2 - } - } - ], - elementsRecord = - [{ - id : "recordbtn", - content : "", - tag : "div", - position : { - row : 1, - cell : 0 - } - }, { - id : "recordplayBtn", - content : "", - tag : "div", - position : { - row : 1, - cell : 1 - } - }, { - id : "recordpauseBtn", - content : "", - tag : "div", - position : { - row : 2, - cell : 0 - } - }, { - id : "recordstopBtn", - content : "", - tag : "div", - position : { - row : 2, - cell : 1 - } - } - ]; - - //Title audio results - var div = document.createElement('h2'); - div.appendChild(document.createTextNode('Audio')); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - //Generate and add results table - contentEl.appendChild(generateTable('info', 3, 3, elementsResultsAudio)); - - //Title audio actions - div = document.createElement('h2'); - div.appendChild(document.createTextNode('Actions')); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - //Generate and add buttons table - contentEl.appendChild(generateTable('audioActions', 3, 3, elementsAudio)); - createActionButton('Play', function () { - playAudio(); - }, 'playBtn'); - createActionButton('Pause', function () { - pauseAudio(); - }, 'pauseBtn'); - createActionButton('Stop', function () { - stopAudio(); - }, 'stopBtn'); - createActionButton('Release', function () { - releaseAudio(); - }, 'releaseBtn'); - createActionButton('Seek By', function () { - seekAudio('by'); - }, 'seekByBtn'); - createActionButton('Seek To', function () { - seekAudio('to'); - }, 'seekToBtn'); - //get Special path to record if iOS || Blackberry - if (cordova.platformId === 'ios') - getRecordSrc(); - else if (cordova.platformId === 'blackberry') - getRecordSrcBB(); - else if (cordova.platformId === 'windows' || cordova.platformId === 'windows8') - getRecordSrcWin(); - - //testing process and details - function addItemToList(_list, _text) - { - var item = document.createElement('li'); - item.appendChild(document.createTextNode(_text)); - _list.appendChild(item); - } - - div = document.createElement('h4'); - div.appendChild(document.createTextNode('Recommended Test Procedure')); - contentEl.appendChild(div); - - var list = document.createElement('ol'); - addItemToList(list, 'Press play - Will start playing audio. Status: Running, Duration: 61.333 sec, Position: Current position of audio track'); - addItemToList(list, 'Press pause - Will pause the audio. Status: Paused, Duration: 61.333 sec, Position: Position where track was paused'); - addItemToList(list, 'Press play - Will begin playing where track left off from the pause'); - addItemToList(list, 'Press stop - Will stop the audio. Status: Stopped, Duration: 61.333 sec, Position: 0 sec'); - addItemToList(list, 'Press play - Will begin playing the audio track from the beginning'); - addItemToList(list, 'Press release - Will stop the audio. Status: Stopped, Duration: 61.333 sec, Position: 0 sec'); - addItemToList(list, 'Press play - Will begin playing the audio track from the beginning'); - addItemToList(list, 'Type 10 in the text box beside Seek To button'); - addItemToList(list, 'Press seek by - Will jump 10 seconds ahead in the audio track. Position: should jump by 10 sec'); - addItemToList(list, 'Press stop if track is not already stopped'); - addItemToList(list, 'Type 30 in the text box beside Seek To button'); - addItemToList(list, 'Press play then seek to - Should jump to Position 30 sec'); - addItemToList(list, 'Press stop'); - addItemToList(list, 'Type 5 in the text box beside Seek To button'); - addItemToList(list, 'Press play, let play past 10 seconds then press seek to - should jump back to position 5 sec'); - - div = document.createElement('div'); - div.setAttribute("style", "background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto"); - div.appendChild(list); - contentEl.appendChild(div); - - //Title Record Audio - div = document.createElement('h2'); - div.appendChild(document.createTextNode('Record Audio')); - div.setAttribute("align", "center"); - contentEl.appendChild(div); - //Generate and add Record buttons table - contentEl.appendChild(generateTable('recordContent', 3, 3, elementsRecord)); - createActionButton('Record Audio \n 10 sec', function () { - recordAudio(); - }, 'recordbtn'); - createActionButton('Play', function () { - playRecording(); - }, 'recordplayBtn'); - createActionButton('Pause', function () { - pauseAudio(); - }, 'recordpauseBtn'); - createActionButton('Stop', function () { - stopAudio(); - }, 'recordstopBtn'); - - //testing process and details - div = document.createElement('h4'); - div.appendChild(document.createTextNode('Recommended Test Procedure')); - contentEl.appendChild(div); - - list = document.createElement('ol'); - addItemToList(list, 'Press Record Audio 10 sec - Will start recording audio for 10 seconds. Status: Running, Position: number of seconds recorded (will stop at 10)'); - addItemToList(list, 'Status will change to Stopped when finished recording'); - addItemToList(list, 'Press play - Will begin playing the recording. Status: Running, Duration: # of seconds of recording, Position: Current position of recording'); - addItemToList(list, 'Press stop - Will stop playing the recording. Status: Stopped, Duration: # of seconds of recording, Position: 0 sec'); - addItemToList(list, 'Press play - Will begin playing the recording from the beginning'); - addItemToList(list, 'Press pause - Will pause the playback of the recording. Status: Paused, Duration: # of seconds of recording, Position: Position where recording was paused'); - addItemToList(list, 'Press play - Will begin playing the recording from where it was paused'); - - div = document.createElement('div'); - div.setAttribute("style", "background:#B0C4DE;border:1px solid #FFA07A;margin:15px 6px 0px;min-width:295px;max-width:97%;padding:4px 0px 2px 10px;min-height:160px;max-height:200px;overflow:auto"); - div.appendChild(list); - contentEl.appendChild(div); -}; diff --git a/plugins/org.apache.cordova.media/www/Media.js b/plugins/org.apache.cordova.media/www/Media.js deleted file mode 100644 index a2ae738c..00000000 --- a/plugins/org.apache.cordova.media/www/Media.js +++ /dev/null @@ -1,216 +0,0 @@ -/* - * - * 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 argscheck = require('cordova/argscheck'), - utils = require('cordova/utils'), - exec = require('cordova/exec'); - -var mediaObjects = {}; - -/** - * This class provides access to the device media, interfaces to both sound and video - * - * @constructor - * @param src The file name or url to play - * @param successCallback The callback to be called when the file is done playing or recording. - * successCallback() - * @param errorCallback The callback to be called if there is an error. - * errorCallback(int errorCode) - OPTIONAL - * @param statusCallback The callback to be called when media status has changed. - * statusCallback(int statusCode) - OPTIONAL - */ -var Media = function(src, successCallback, errorCallback, statusCallback) { - argscheck.checkArgs('SFFF', 'Media', arguments); - this.id = utils.createUUID(); - mediaObjects[this.id] = this; - this.src = src; - this.successCallback = successCallback; - this.errorCallback = errorCallback; - this.statusCallback = statusCallback; - this._duration = -1; - this._position = -1; - exec(null, this.errorCallback, "Media", "create", [this.id, this.src]); -}; - -// Media messages -Media.MEDIA_STATE = 1; -Media.MEDIA_DURATION = 2; -Media.MEDIA_POSITION = 3; -Media.MEDIA_ERROR = 9; - -// Media states -Media.MEDIA_NONE = 0; -Media.MEDIA_STARTING = 1; -Media.MEDIA_RUNNING = 2; -Media.MEDIA_PAUSED = 3; -Media.MEDIA_STOPPED = 4; -Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"]; - -// "static" function to return existing objs. -Media.get = function(id) { - return mediaObjects[id]; -}; - -/** - * Start or resume playing audio file. - */ -Media.prototype.play = function(options) { - exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]); -}; - -/** - * Stop playing audio file. - */ -Media.prototype.stop = function() { - var me = this; - exec(function() { - me._position = 0; - }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]); -}; - -/** - * Seek or jump to a new time in the track.. - */ -Media.prototype.seekTo = function(milliseconds) { - var me = this; - exec(function(p) { - me._position = p; - }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]); -}; - -/** - * Pause playing audio file. - */ -Media.prototype.pause = function() { - exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]); -}; - -/** - * Get duration of an audio file. - * The duration is only set for audio that is playing, paused or stopped. - * - * @return duration or -1 if not known. - */ -Media.prototype.getDuration = function() { - return this._duration; -}; - -/** - * Get position of audio. - */ -Media.prototype.getCurrentPosition = function(success, fail) { - var me = this; - exec(function(p) { - me._position = p; - success(p); - }, fail, "Media", "getCurrentPositionAudio", [this.id]); -}; - -/** - * Start recording audio file. - */ -Media.prototype.startRecord = function() { - exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]); -}; - -/** - * Stop recording audio file. - */ -Media.prototype.stopRecord = function() { - exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]); -}; - -/** - * Release the resources. - */ -Media.prototype.release = function() { - exec(null, this.errorCallback, "Media", "release", [this.id]); -}; - -/** - * Adjust the volume. - */ -Media.prototype.setVolume = function(volume) { - exec(null, null, "Media", "setVolume", [this.id, volume]); -}; - -/** - * Audio has status update. - * PRIVATE - * - * @param id The media object id (string) - * @param msgType The 'type' of update this is - * @param value Use of value is determined by the msgType - */ -Media.onStatus = function(id, msgType, value) { - - var media = mediaObjects[id]; - - if(media) { - switch(msgType) { - case Media.MEDIA_STATE : - media.statusCallback && media.statusCallback(value); - if(value == Media.MEDIA_STOPPED) { - media.successCallback && media.successCallback(); - } - break; - case Media.MEDIA_DURATION : - media._duration = value; - break; - case Media.MEDIA_ERROR : - media.errorCallback && media.errorCallback(value); - break; - case Media.MEDIA_POSITION : - media._position = Number(value); - break; - default : - console.error && console.error("Unhandled Media.onStatus :: " + msgType); - break; - } - } - else { - console.error && console.error("Received Media.onStatus callback for unknown media :: " + id); - } - -}; - -module.exports = Media; - -function onMessageFromNative(msg) { - if (msg.action == 'status') { - Media.onStatus(msg.status.id, msg.status.msgType, msg.status.value); - } else { - throw new Error('Unknown media action' + msg.action); - } -} - -if (cordova.platformId === 'android' || cordova.platformId === 'amazon-fireos') { - - var channel = require('cordova/channel'); - - channel.createSticky('onMediaPluginReady'); - channel.waitForInitialization('onMediaPluginReady'); - - channel.onCordovaReady.subscribe(function() { - exec(onMessageFromNative, undefined, 'Media', 'messageChannel', []); - channel.initializationComplete('onMediaPluginReady'); - }); -} diff --git a/plugins/org.apache.cordova.media/www/MediaError.js b/plugins/org.apache.cordova.media/www/MediaError.js deleted file mode 100644 index 38002ac5..00000000 --- a/plugins/org.apache.cordova.media/www/MediaError.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * 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. - * -*/ - -/** - * This class contains information about any Media errors. -*/ -/* - According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror - We should never be creating these objects, we should just implement the interface - which has 1 property for an instance, 'code' - - instead of doing : - errorCallbackFunction( new MediaError(3,'msg') ); -we should simply use a literal : - errorCallbackFunction( {'code':3} ); - */ - - var _MediaError = window.MediaError; - - -if(!_MediaError) { - window.MediaError = _MediaError = function(code, msg) { - this.code = (typeof code != 'undefined') ? code : null; - this.message = msg || ""; // message is NON-standard! do not use! - }; -} - -_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0; -_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1; -_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2; -_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3; -_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4; -// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below. -// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes -_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4; - -module.exports = _MediaError; diff --git a/plugins/org.apache.cordova.statusbar/CONTRIBUTING.md b/plugins/org.apache.cordova.statusbar/CONTRIBUTING.md deleted file mode 100644 index f7dbcaba..00000000 --- a/plugins/org.apache.cordova.statusbar/CONTRIBUTING.md +++ /dev/null @@ -1,37 +0,0 @@ -<!-- -# -# 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! diff --git a/plugins/org.apache.cordova.statusbar/LICENSE b/plugins/org.apache.cordova.statusbar/LICENSE deleted file mode 100644 index 7a4a3ea2..00000000 --- a/plugins/org.apache.cordova.statusbar/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed 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.
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/NOTICE b/plugins/org.apache.cordova.statusbar/NOTICE deleted file mode 100644 index 8ec56a52..00000000 --- a/plugins/org.apache.cordova.statusbar/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache Cordova -Copyright 2012 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). diff --git a/plugins/org.apache.cordova.statusbar/README.md b/plugins/org.apache.cordova.statusbar/README.md deleted file mode 100644 index 8b91de98..00000000 --- a/plugins/org.apache.cordova.statusbar/README.md +++ /dev/null @@ -1,22 +0,0 @@ -<!--- - license: 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. ---> - -# org.apache.cordova.statusbar - -Plugin documentation: [doc/index.md](doc/index.md)
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/RELEASENOTES.md b/plugins/org.apache.cordova.statusbar/RELEASENOTES.md deleted file mode 100644 index 1dc12e11..00000000 --- a/plugins/org.apache.cordova.statusbar/RELEASENOTES.md +++ /dev/null @@ -1,68 +0,0 @@ -<!-- -# -# 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. -# ---> -# Release Notes - -### 0.1.5 (Apr 17, 2014) (First release as a core Cordova Plugin) -* CB-6316: Added README.md which point to the new location for docs -* CB-6316: Added license header to the documentation. Added README.md which point to the new location for docs -* CB-6316: Moved StatusBar plugin documentation to docs folder -* CB-6314: [android] Add StatusBar.isVisible support to Android -* CB-6460: Update license headers - -### 0.1.6 (Jun 05, 2014) -* CB-6783 - added StatusBarStyle config preference, updated docs (closes #9) -* CB-6812 Add license -* CB-6491 add CONTRIBUTING.md -* CB-6264 minor formatting issue -* Update docs with recent WP changes, remove 'clear' from the loist of named colors in documentation -* CB-6513 - Statusbar plugin for Android is not compiling - -### 0.1.7 (Aug 06, 2014) -* Add LICENSE and NOTICE -* Update statusbar.js -* Update backgroundColorByHexString function -* ios: Use a persistent callbackId instead of calling sendJs -* CB-6626 ios: Add a JS event for tapping on statusbar -* ios: Fix hide to adjust webview's frame only when status bar is not overlaying webview -* CB-6127 Updated translations for docs -* android: Fix StatusBar.initialize() not running on UI thread - -### 0.1.8 (Sep 17, 2014) -* CB-7549 [StatusBar][iOS 8] Landscape issue -* CB-7486 Remove StatusBarBackgroundColor intial preference (black background) so background will be initially transparent -* Renamed test dir, added nested plugin.xml -* added documentation for manual tests, moved background color test below overlay test -* CB-7195 ported statusbar tests to framework - -### 0.1.9 (Dec 02, 2014) -* Fix onload attribute within <feature> to be a <param> -* CB-8010 - Statusbar colour does not change to orange -* added checks for running on windows when StatusBar is NOT available -* CB-7986 Add cordova-plugin-statusbar support for **Windows Phone 8.1** -* CB-7977 Mention `deviceready` in plugin docs -* CB-7979 Each plugin doc should have a ## Installation section -* Inserting leading space after # for consistency -* CB-7549 - (Re-fix) `StatusBar` **iOS 8** Landscape issue (closes #15) -* CB-7700 cordova-plugin-statusbar documentation translation: cordova-plugin-statusbar -* CB-7571 Bump version of nested plugin to match parent plugin - -### 0.1.10 (Feb 04, 2015) -* CB-8351 ios: Use argumentForIndex rather than NSArray extension diff --git a/plugins/org.apache.cordova.statusbar/doc/de/index.md b/plugins/org.apache.cordova.statusbar/doc/de/index.md deleted file mode 100644 index 1c0ff3ce..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/de/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> Das `StatusBar` Objekt stellt einige Funktionen zum Anpassen des iOS und Android StatusBar. - -## "Einstellungen" - -#### config.xml - -* **StatusBarOverlaysWebView** (Boolean, der Standardwert ist True). Stellen Sie auf iOS 7 die Statusbar-Overlay oder keine Überlagerung der WebView beim Start. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (Farbe hex String, der Standardwert ist #000000). Legen Sie auf iOS 7 die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge (#RRGGBB) beim Start. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (Status Bar-Stil, der Standardwert ist Lightcontent). Legen Sie auf iOS 7 den Status-Bar-Stil. Verfügbaren Optionen Standard, Lightcontent, Blacktranslucent, Blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## Beim Start ausblenden - -Während der Laufzeit können Sie die StatusBar.hide-Funktion unten, aber die StatusBar beim Start der app versteckt werden soll, müssen Sie Ihre app Info.plist Datei ändern. - -Diese beiden Attribute hinzufügen/bearbeiten, wenn nicht vorhanden. Legen Sie **"Statusleiste ist anfangs ausgeblendet"** auf **"YES"** und **"View Controller-basierte Status Bar aussehen"** auf **"NO"**. Wenn Sie es manuell ohne Xcode bearbeiten, werden die Schlüssel und Werte: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## Methoden - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## Eigenschaften - -* StatusBar.isVisible - -## Berechtigungen - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -Stellen Sie auf iOS 7 Statusbar überlagern oder nicht überlagert die WebView. - - StatusBar.overlaysWebView(true); - - -## Beschreibung - -Auf iOS 7 zu der Statusbar wie iOS 6 erscheinen auf False festgelegt. Legen Sie die Stil und Hintergrund Farbe entsprechend mit den anderen Funktionen. - -## Unterstützte Plattformen - -* iOS - -## Kurzes Beispiel - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -Verwenden Sie die Standard-Statusbar (dunkle Text, für helle Hintergründe). - - StatusBar.styleDefault(); - - -## Unterstützte Plattformen - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -Verwenden Sie die LightContent-Statusbar (heller Text, für dunkle Hintergründe). - - StatusBar.styleLightContent(); - - -## Unterstützte Plattformen - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -Verwenden Sie die BlackTranslucent-Statusbar (heller Text, für dunkle Hintergründe). - - StatusBar.styleBlackTranslucent(); - - -## Unterstützte Plattformen - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -Verwenden Sie die BlackOpaque-Statusbar (heller Text, für dunkle Hintergründe). - - StatusBar.styleBlackOpaque(); - - -## Unterstützte Plattformen - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -Auf iOS 7 Wenn Sie StatusBar.statusBarOverlaysWebView auf False festlegen, können Sie die Hintergrundfarbe der Statusbar von Farbnamen festlegen. - - StatusBar.backgroundColorByName("red"); - - -Unterstützte Farbnamen sind: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## Unterstützte Plattformen - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -Legt die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge fest. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -CSS-Kurzschrift-Eigenschaften werden ebenfalls unterstützt. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -Auf iOS 7 Wenn Sie StatusBar.statusBarOverlaysWebView auf False festlegen, können Sie die Hintergrundfarbe der Statusbar von eine hexadezimale Zeichenfolge (#RRGGBB) festlegen. - -Auf WP7 und WP8 können Sie auch Werte wie #AARRGGBB, angeben wo AA einen alpha-Wert ist - -## Unterstützte Plattformen - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -Ausblenden der Statusleiste. - - StatusBar.hide(); - - -## Unterstützte Plattformen - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -Zeigt die Statusleiste. - - StatusBar.show(); - - -## Unterstützte Plattformen - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -Lesen Sie diese Eigenschaft, um festzustellen, ob die Statusbar sichtbar oder nicht ist. - - if (StatusBar.isVisible) { - // do something - } - - -## Unterstützte Plattformen - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/es/index.md b/plugins/org.apache.cordova.statusbar/doc/es/index.md deleted file mode 100644 index 13a7230f..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/es/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> El `StatusBar` objeto proporciona algunas funciones para personalizar el iOS y Android StatusBar. - -## Preferencias - -#### config.xml - -* **StatusBarOverlaysWebView** (boolean, true por defecto). En iOS 7, hacer la superposición statusbar o no superponer la WebView al inicio. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (cadena hexadecimal color, #000000 por defecto). En iOS 7, establecer el color de fondo de la barra de estado por una cadena hexadecimal (#RRGGBB) en el arranque. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (status bar estilo por defecto lightcontent). En iOS 7, definir el estilo de barra de estado. Por defecto las opciones disponibles, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## Escondido en el arranque - -Durante el tiempo de ejecución puede utilizar la función StatusBar.hide abajo, pero si quieres la barra de estado que está escondido en el inicio de la aplicación, se debe modificar el archivo Info.plist de su aplicación. - -Agregar/editar estos dos atributos si no está presente. Defina **"inicialmente se esconde la barra de estado"** a **"YES"** y **"Aparición de vista basado en controlador estatus bar"** a **"NO"**. Si se edita manualmente sin Xcode, las claves y valores son: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## Métodos - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## Propiedades - -* StatusBar.isVisible - -## Permisos - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -En iOS 7, hacer la barra de estado superposición o no superponer la vista Web. - - StatusBar.overlaysWebView(true); - - -## Descripción - -En iOS 7, establecida en false para que la barra de estado aparezca como iOS 6. Establece el color de fondo y estilo para utilizar las otras funciones. - -## Plataformas soportadas - -* iOS - -## Ejemplo rápido - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -Utilice la barra de estado por defecto (texto oscuro, para fondos de luz). - - StatusBar.styleDefault(); - - -## Plataformas soportadas - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -Utilice la barra de estado lightContent (texto ligero, para fondos oscuros). - - StatusBar.styleLightContent(); - - -## Plataformas soportadas - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -Utilice la barra de estado blackTranslucent (texto ligero, para fondos oscuros). - - StatusBar.styleBlackTranslucent(); - - -## Plataformas soportadas - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -Utilice la barra de estado blackOpaque (texto ligero, para fondos oscuros). - - StatusBar.styleBlackOpaque(); - - -## Plataformas soportadas - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -En iOS 7, al establecer StatusBar.statusBarOverlaysWebView a false, se puede establecer el color de fondo de la barra de estado nombre del color. - - StatusBar.backgroundColorByName("red"); - - -Nombres de los colores admitidos son: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## Plataformas soportadas - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -Establece el color de fondo de la barra de estado por una cadena hexadecimal. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -Propiedades CSS abreviada también son compatibles. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -En iOS 7, cuando se establece StatusBar.statusBarOverlaysWebView en false, se puede establecer el color de fondo de la barra de estado una cadena hexadecimal (#RRGGBB). - -En WP7 y WP8 también puede especificar valores como #AARRGGBB, donde AA es un valor alfa - -## Plataformas soportadas - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -Ocultar la barra de estado. - - StatusBar.hide(); - - -## Plataformas soportadas - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -Muestra la barra de estado. - - StatusBar.show(); - - -## Plataformas soportadas - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -Lea esta propiedad para ver si la barra de estado es visible o no. - - if (StatusBar.isVisible) { - // do something - } - - -## Plataformas soportadas - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/fr/index.md b/plugins/org.apache.cordova.statusbar/doc/fr/index.md deleted file mode 100644 index 28e4e103..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/fr/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> Le `StatusBar` objet fournit quelques fonctions pour personnaliser les iOS et Android StatusBar. - -## Préférences - -#### config.xml - -* **StatusBarOverlaysWebView** (boolean, la valeur par défaut true). Sur iOS 7, faire la superposition de statusbar ou pas superposition le WebView au démarrage. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (chaîne hexadécimale de couleur, par défaut, #000000). Sur iOS 7, définir la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale (#RRGGBB) au démarrage. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (style de barre de statut, par défaut, lightcontent). Sur iOS 7, définir le style de barre de statut. Par défaut les options disponibles, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## Cacher au démarrage - -Pendant l'exécution, vous pouvez utiliser la fonction StatusBar.hide en bas, mais si vous souhaitez que la barre d'État pour être caché au démarrage de l'application, vous devez modifier le fichier Info.plist de votre application. - -Ajouter/modifier ces deux attributs si n'est pas présent. **"Barre d'État est initialement masqué"** la valeur **"** Yes" et **"À l'apparence vue sur contrôleur statut bar"** la valeur **"Non"**. Si vous modifiez manuellement sans Xcode, les clés et les valeurs sont : - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## Méthodes - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## Propriétés - -* StatusBar.isVisible - -## Autorisations - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -Sur iOS 7, faire la statusbar superposition ou pas superposer le WebView. - - StatusBar.overlaysWebView(true); - - -## Description - -Sur iOS 7, la valeur false pour afficher la barre d'État comme iOS 6. Définissez la couleur de style et d'arrière-plan en fonction de l'utilisation des autres fonctions. - -## Plates-formes prises en charge - -* iOS - -## Petit exemple - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -Utilisez la barre de statut par défaut (texte sombre, pour les arrière-plans lumineux). - - StatusBar.styleDefault() ; - - -## Plates-formes prises en charge - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -Utilisez la barre d'État lightContent (texte clair, des arrière-plans sombres). - - StatusBar.styleLightContent(); - - -## Plates-formes prises en charge - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -Utilisez la barre d'État blackTranslucent (texte clair, des arrière-plans sombres). - - StatusBar.styleBlackTranslucent(); - - -## Plates-formes prises en charge - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -Utilisez la barre d'État blackOpaque (texte clair, des arrière-plans sombres). - - StatusBar.styleBlackOpaque(); - - -## Plates-formes prises en charge - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -Sur iOS 7, lorsque vous définissez StatusBar.statusBarOverlaysWebView sur false, vous pouvez définir la couleur d'arrière-plan de la barre d'État par nom de couleur. - - StatusBar.backgroundColorByName("red"); - - -Les noms de couleurs prises en charge sont : - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## Plates-formes prises en charge - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -Définit la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -Propriétés de raccourci CSS sont également pris en charge. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -Sur iOS 7, lorsque vous définissez StatusBar.statusBarOverlaysWebView sur false, vous pouvez définir la couleur d'arrière-plan de la barre d'État par une chaîne hexadécimale (#RRGGBB). - -Sur WP7 et WP8, vous pouvez également spécifier des valeurs comme #AARRGGBB, où AA représente une valeur alpha - -## Plates-formes prises en charge - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -Masquer la barre d'État. - - StatusBar.hide(); - - -## Plates-formes prises en charge - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -Affiche la barre d'État. - - StatusBar.show(); - - -## Plates-formes prises en charge - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -Lire cette propriété afin de voir si la barre d'État est visible ou non. - - if (StatusBar.isVisible) { - // do something - } - - -## Plates-formes prises en charge - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/index.md b/plugins/org.apache.cordova.statusbar/doc/index.md deleted file mode 100644 index 9955857a..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/index.md +++ /dev/null @@ -1,284 +0,0 @@ -<!--- - 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. ---> -# org.apache.cordova.statusbar - -StatusBar -====== - -> The `StatusBar` object provides some functions to customize the iOS and Android StatusBar. - - -## Installation - - cordova plugin add org.apache.cordova.statusbar - -Preferences ------------ - -#### config.xml - -- __StatusBarOverlaysWebView__ (boolean, defaults to true). On iOS 7, make the statusbar overlay or not overlay the WebView at startup. - - <preference name="StatusBarOverlaysWebView" value="true" /> - -- __StatusBarBackgroundColor__ (color hex string, defaults to #000000). On iOS 7, set the background color of the statusbar by a hex string (#RRGGBB) at startup. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - -- __StatusBarStyle__ (status bar style, defaults to lightcontent). On iOS 7, set the status bar style. Available options default, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - -Hiding at startup ------------ - -During runtime you can use the StatusBar.hide function below, but if you want the StatusBar to be hidden at app startup, you must modify your app's Info.plist file. - -Add/edit these two attributes if not present. Set **"Status bar is initially hidden"** to **"YES"** and set **"View controller-based status bar appearance"** to **"NO"**. If you edit it manually without Xcode, the keys and values are: - - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -Methods -------- -This plugin defines global `StatusBar` object. - -Although in the global scope, it is not available until after the `deviceready` event. - - document.addEventListener("deviceready", onDeviceReady, false); - function onDeviceReady() { - console.log(StatusBar); - } - -- StatusBar.overlaysWebView -- StatusBar.styleDefault -- StatusBar.styleLightContent -- StatusBar.styleBlackTranslucent -- StatusBar.styleBlackOpaque -- StatusBar.backgroundColorByName -- StatusBar.backgroundColorByHexString -- StatusBar.hide -- StatusBar.show - -Properties --------- - -- StatusBar.isVisible - -Permissions ------------ - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - -StatusBar.overlaysWebView -================= - -On iOS 7, make the statusbar overlay or not overlay the WebView. - - StatusBar.overlaysWebView(true); - -Description ------------ - -On iOS 7, set to false to make the statusbar appear like iOS 6. Set the style and background color to suit using the other functions. - - -Supported Platforms -------------------- - -- iOS - -Quick Example -------------- - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - -StatusBar.styleDefault -================= - -Use the default statusbar (dark text, for light backgrounds). - - StatusBar.styleDefault(); - - -Supported Platforms -------------------- - -- iOS -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - -StatusBar.styleLightContent -================= - -Use the lightContent statusbar (light text, for dark backgrounds). - - StatusBar.styleLightContent(); - - -Supported Platforms -------------------- - -- iOS -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - -StatusBar.styleBlackTranslucent -================= - -Use the blackTranslucent statusbar (light text, for dark backgrounds). - - StatusBar.styleBlackTranslucent(); - - -Supported Platforms -------------------- - -- iOS -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - -StatusBar.styleBlackOpaque -================= - -Use the blackOpaque statusbar (light text, for dark backgrounds). - - StatusBar.styleBlackOpaque(); - - -Supported Platforms -------------------- - -- iOS -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - - -StatusBar.backgroundColorByName -================= - -On iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by color name. - - StatusBar.backgroundColorByName("red"); - -Supported color names are: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -Supported Platforms -------------------- - -- iOS -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - -StatusBar.backgroundColorByHexString -================= - -Sets the background color of the statusbar by a hex string. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - -CSS shorthand properties are also supported. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - -On iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by a hex string (#RRGGBB). - -On WP7 and WP8 you can also specify values as #AARRGGBB, where AA is an alpha value - -Supported Platforms -------------------- - -- iOS -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - -StatusBar.hide -================= - -Hide the statusbar. - - StatusBar.hide(); - - -Supported Platforms -------------------- - -- iOS -- Android -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - -StatusBar.show -================= - -Shows the statusbar. - - StatusBar.show(); - - -Supported Platforms -------------------- - -- iOS -- Android -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - - -StatusBar.isVisible -================= - -Read this property to see if the statusbar is visible or not. - - if (StatusBar.isVisible) { - // do something - } - - -Supported Platforms -------------------- - -- iOS -- Android -- Windows Phone 7 -- Windows Phone 8 -- Windows Phone 8.1 - - diff --git a/plugins/org.apache.cordova.statusbar/doc/it/index.md b/plugins/org.apache.cordova.statusbar/doc/it/index.md deleted file mode 100644 index b40bcf5f..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/it/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> Il `StatusBar` oggetto fornisce alcune funzioni per personalizzare l'iOS e Android StatusBar. - -## Preferenze - -#### config.xml - -* **StatusBarOverlaysWebView** (boolean, default è true). IOS 7, rendono la statusbar sovrapposizione o la non sovrapposizione WebView all'avvio. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (stringa esadecimale colore, predefinito è #000000). IOS 7, impostare il colore di sfondo della barra di stato di una stringa esadecimale (#RRGGBB) all'avvio. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (status bar in stile, default è lightcontent). IOS 7, impostare lo stile di barra di stato. Predefinita di opzioni disponibili, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## Nascondendo all'avvio - -In fase di esecuzione è possibile utilizzare la funzione di StatusBar.hide qui sotto, ma se si desidera che la barra di stato venga nascosta all'avvio di app, è necessario modificare il file info. plist dell'app. - -Aggiungere o modificare questi due attributi, se non presente. Impostare la **"barra di stato è inizialmente nascosto"** a **"YES"** e **"Aspetto di vista basati su controller status bar"** a **"NO"**. Se si modifica manualmente senza Xcode, le chiavi e i valori sono: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## Metodi - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## Proprietà - -* StatusBar.isVisible - -## Autorizzazioni - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -IOS 7, rendono la statusbar sovrapposizione o non sovrapporre WebView. - - StatusBar.overlaysWebView(true); - - -## Descrizione - -IOS 7, impostato su false per rendere la barra di stato vengono visualizzati come iOS 6. Impostare il colore di sfondo e stile per soddisfare utilizzando altre funzioni. - -## Piattaforme supportate - -* iOS - -## Esempio rapido - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -Utilizzare la barra di stato predefinito (testo scuro, per sfondi di luce). - - StatusBar.styleDefault(); - - -## Piattaforme supportate - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -Utilizzare la barra di stato lightContent (testo in chiaro, per sfondi scuri). - - StatusBar.styleLightContent(); - - -## Piattaforme supportate - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -Utilizzare la barra di stato blackTranslucent (testo in chiaro, per sfondi scuri). - - StatusBar.styleBlackTranslucent(); - - -## Piattaforme supportate - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -Utilizzare la barra di stato blackOpaque (testo in chiaro, per sfondi scuri). - - StatusBar.styleBlackOpaque(); - - -## Piattaforme supportate - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -IOS 7, quando StatusBar.statusBarOverlaysWebView è impostata su false, è possibile impostare il colore di sfondo della barra di stato con il nome di colore. - - StatusBar.backgroundColorByName("red"); - - -Nomi di colore supportati sono: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## Piattaforme supportate - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -Imposta il colore di sfondo della barra di stato di una stringa esadecimale. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -Proprietà di scrittura stenografica CSS sono supportati anche. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -IOS 7, quando StatusBar.statusBarOverlaysWebView è impostata su false, è possibile impostare il colore di sfondo della barra di stato di una stringa esadecimale (#RRGGBB). - -Su WP7 e WP8 è inoltre possibile specificare i valori come #AARRGGBB, dove AA è un valore alfa - -## Piattaforme supportate - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -Nascondere la barra di stato. - - StatusBar.hide(); - - -## Piattaforme supportate - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -Mostra la barra di stato. - - StatusBar.show(); - - -## Piattaforme supportate - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -Leggere questa proprietà per vedere se la barra di stato è visibile o no. - - if (StatusBar.isVisible) { - // do something - } - - -## Piattaforme supportate - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/ja/index.md b/plugins/org.apache.cordova.statusbar/doc/ja/index.md deleted file mode 100644 index 7d6b976b..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/ja/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> `StatusBar`オブジェクトは、iOS と Android ステータス バーをカスタマイズするいくつかの機能を提供します。 - -## 基本設定 - -#### config.xml - -* **StatusBarOverlaysWebView**(ブール値、デフォルトは true)。IOS 7、起動時にステータスバー オーバーレイまたはないオーバーレイ、WebView を作る。 - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor**(色 16 進文字列、デフォルトは # 000000)。Ios 7、起動時に 16 進文字列 (#RRGGBB) でステータス バーの背景色を設定します。 - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle**(ステータス バーのスタイル、既定値は lightcontent)。Ios 7、ステータス バーのスタイルを設定します。使用可能なオプションのデフォルト、lightcontent、blacktranslucent、blackopaque。 - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## 起動時に非表示 - -実行時に下に、StatusBar.hide 関数を使用できますが、StatusBar アプリ起動時に非表示にする場合は、アプリの Info.plist ファイルを変更する必要があります。 - -これら 2 つの属性の追加/編集存在しない場合。 **「ステータス バーが非表示最初」** **"YES"**を設定し、 **「ビュー コント ローラー ベースのステータス バーの外観」** **"NO"**にします。 Xcode せず手動で編集する、キーと値は。 - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## メソッド - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## プロパティ - -* StatusBar.isVisible - -## アクセス許可 - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -IOS 7、statusbar オーバーレイまたはない WebView をオーバーレイします。 - - StatusBar.overlaysWebView(true); - - -## 説明 - -IOS 7、iOS の 6 のように表示されるステータスバーを false に設定します。他の関数の使用に合わせてスタイルや背景色を設定します。 - -## サポートされているプラットフォーム - -* iOS - -## 簡単な例 - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -既定ステータス バー (暗いテキスト、淡色の背景) を使用します。 - - StatusBar.styleDefault(); - - -## サポートされているプラットフォーム - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -LightContent ステータスバー (暗い背景の明るいテキスト) を使用します。 - - StatusBar.styleLightContent(); - - -## サポートされているプラットフォーム - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -BlackTranslucent ステータスバー (暗い背景の明るいテキスト) を使用します。 - - StatusBar.styleBlackTranslucent(); - - -## サポートされているプラットフォーム - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -BlackOpaque ステータスバー (暗い背景の明るいテキスト) を使用します。 - - StatusBar.styleBlackOpaque(); - - -## サポートされているプラットフォーム - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -Ios 7、StatusBar.statusBarOverlaysWebView を false に設定する場合はステータスバーの背景色の色の名前によって設定できます。 - - StatusBar.backgroundColorByName("red"); - - -サポートされている色の名前は次のとおりです。 - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## サポートされているプラットフォーム - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -16 進文字列をステータス バーの背景色を設定します。 - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -速記の CSS プロパティもサポートされています。 - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -Ios 7、StatusBar.statusBarOverlaysWebView を false に設定する場合はステータスバーの背景色を 16 進文字列 (#RRGGBB) で設定できます。 - -WP7 と WP8 も指定できます値 #AARRGGBB, AA は、アルファ値として - -## サポートされているプラットフォーム - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -ステータスバーを隠します。 - - StatusBar.hide(); - - -## サポートされているプラットフォーム - -* iOS -* アンドロイド -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -ステータス バーが表示されます。 - - StatusBar.show(); - - -## サポートされているプラットフォーム - -* iOS -* アンドロイド -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -このプロパティ、ステータスバーが表示されるかどうかをお読みください。 - - if (StatusBar.isVisible) { - // do something - } - - -## サポートされているプラットフォーム - -* iOS -* アンドロイド -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/ko/index.md b/plugins/org.apache.cordova.statusbar/doc/ko/index.md deleted file mode 100644 index e30ee891..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/ko/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> `StatusBar`개체 iOS와 안 드 로이드 상태 표시줄을 사용자 지정 하려면 몇 가지 기능을 제공 합니다. - -## 환경 설정 - -#### config.xml - -* **StatusBarOverlaysWebView** (boolean, 기본값: true)입니다. IOS 7, 시작 시 상태 표시줄 오버레이 또는 WebView 중첩 되지 확인 합니다. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (색상 16 진수 문자열 기본값: #000000). Ios 7, 시작 시 16 진수 문자열 (#RRGGBB) 상태 표시줄의 배경색을 설정 합니다. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (상태 표시줄 스타일, 기본값: lightcontent). Ios 7, 상태 표시줄 스타일을 설정 합니다. 사용 가능한 옵션 기본, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## 시작 시 숨기기 - -런타임 동안 아래의 StatusBar.hide 함수를 사용할 수 있습니다 하지만 당신이 원하는 응용 프로그램 시작 시 숨겨진 상태 표시줄, 응용 프로그램의 Info.plist 파일 수정 해야 합니다. - -추가 편집이 두 특성이 없는 경우. **"상태 표시줄 처음 숨겨진"** **"YES"** 로 설정 하 고 **"뷰 컨트롤러 기반 상태 표시줄 모양"** **"NO"**로 설정 합니다. Xcode, 열쇠 없이 수동으로 편집 하는 경우 값은: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## 메서드 - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## 속성 - -* StatusBar.isVisible - -## 사용 권한 - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -IOS 7, 오버레이 또는 하지 WebView 중첩 상태 표시줄을 확인 합니다. - - StatusBar.overlaysWebView(true); - - -## 설명 - -7 iOS, iOS 6 처럼 나타나는 상태 표시줄을 false로 설정 합니다. 다른 함수를 사용 하 여에 맞게 스타일과 배경 색상을 설정 합니다. - -## 지원 되는 플랫폼 - -* iOS - -## 빠른 예제 - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -기본 상태 표시줄 (어두운 텍스트, 밝은 배경에 대 한)를 사용 합니다. - - StatusBar.styleDefault(); - - -## 지원 되는 플랫폼 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -LightContent 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다. - - StatusBar.styleLightContent(); - - -## 지원 되는 플랫폼 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -BlackTranslucent 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다. - - StatusBar.styleBlackTranslucent(); - - -## 지원 되는 플랫폼 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -BlackOpaque 상태 표시줄 (어두운 배경에 대 한 가벼운 텍스트)을 사용 합니다. - - StatusBar.styleBlackOpaque(); - - -## 지원 되는 플랫폼 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -Ios 7, StatusBar.statusBarOverlaysWebView을 false로 설정 하면 설정할 수 있는 상태 표시줄의 배경색 색상 이름으로. - - StatusBar.backgroundColorByName("red"); - - -지원 되는 색 이름입니다. - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## 지원 되는 플랫폼 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -16 진수 문자열 상태 표시줄의 배경색을 설정합니다. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -CSS 대표 속성 지원 됩니다. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -Ios 7, StatusBar.statusBarOverlaysWebView을 false로 설정 하면 설정할 수 있는 상태 표시줄의 배경색 16 진수 문자열 (#RRGGBB)에 의해. - -WP7 및 WP8에 당신은 또한 #AARRGGBB, AA는 알파 값으로 값을 지정할 수 있습니다. - -## 지원 되는 플랫폼 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -숨기기 상태 표시줄. - - StatusBar.hide(); - - -## 지원 되는 플랫폼 - -* iOS -* 안 드 로이드 -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -상태 표시줄을 표시합니다. - - StatusBar.show(); - - -## 지원 되는 플랫폼 - -* iOS -* 안 드 로이드 -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -이 속성을 상태 표시줄 표시 되는 경우 읽기. - - if (StatusBar.isVisible) { - // do something - } - - -## 지원 되는 플랫폼 - -* iOS -* 안 드 로이드 -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/pl/index.md b/plugins/org.apache.cordova.statusbar/doc/pl/index.md deleted file mode 100644 index af69ebdf..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/pl/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> `StatusBar`Obiekt zawiera kilka funkcji, aby dostosować iOS i Android StatusBar. - -## Preferencje - -#### config.xml - -* **StatusBarOverlaysWebView** (boolean, domyślnie na wartość true). Na iOS 7 zrobić nakładki stanu lub nie nakładki widoku sieci Web podczas uruchamiania. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (kolor szesnastkowy ciąg, domyślnie #000000). Na iOS 7 ustawić kolor tła stanu przez ciąg szesnastkowy (#RRGGBB) przy starcie systemu. - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (stan styl paska, domyślnie lightcontent.) Na iOS 7 ustawić styl paska stanu. Dostępne opcje domyślne, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## Przy starcie - -Podczas uruchamiania można użyć funkcji StatusBar.hide poniżej, ale jeśli chcesz StatusBar ukryty w uruchamiania aplikacji, należy zmodyfikować plik Info.plist Twojej aplikacji. - -Dodawanie/edycja tych dwóch atrybutów jeśli nie obecny. Ustawianie **"pasek stanu jest początkowo ukryte"** na **"Tak"** i **"Oparte na kontroler stanu paska wygląd"** na **"Nie"**. Jeśli możesz go edytować ręcznie bez Xcode, kluczy i wartości są: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## Metody - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## Właściwości - -* StatusBar.isVisible - -## Uprawnienia - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -Na iOS 7 zrobić statusbar nakładki lub nie nakładka widoku sieci Web. - - StatusBar.overlaysWebView(true); - - -## Opis - -Na iOS 7 zestaw do false, aby na pasku stanu pojawia się jak iOS 6. Ustaw kolor tła i styl do korzystania z innych funkcji. - -## Obsługiwane platformy - -* iOS - -## Szybki przykład - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -Użyj domyślnego stanu (ciemny tekst, teł światła). - - StatusBar.styleDefault(); - - -## Obsługiwane platformy - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -Użyj lightContent stanu (światło tekst, ciemne tło). - - StatusBar.styleLightContent(); - - -## Obsługiwane platformy - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -Użyj blackTranslucent stanu (światło tekst, ciemne tło). - - StatusBar.styleBlackTranslucent(); - - -## Obsługiwane platformy - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -Użyj blackOpaque stanu (światło tekst, ciemne tło). - - StatusBar.styleBlackOpaque(); - - -## Obsługiwane platformy - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -Na iOS 7 gdy zostanie ustawiona wartość false, StatusBar.statusBarOverlaysWebView można ustawić kolor tła stanu przez nazwę koloru. - - StatusBar.backgroundColorByName("red"); - - -Nazwy kolorów obsługiwane są: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## Obsługiwane platformy - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -Ustawia kolor tła stanu przez ciąg szesnastkowy. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -Obsługiwane są również właściwości CSS. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -Na iOS 7 gdy zostanie ustawiona wartość false, StatusBar.statusBarOverlaysWebView można ustawić kolor tła stanu przez ciąg szesnastkowy (#RRGGBB). - -Na WP7 i WP8 można również określić wartości jako #AARRGGBB, gdzie AA jest wartością alfa - -## Obsługiwane platformy - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -Ukryj pasek stanu. - - StatusBar.hide(); - - -## Obsługiwane platformy - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -Pokazuje pasek stanu. - - StatusBar.show(); - - -## Obsługiwane platformy - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -Czytać tej właściwość, aby sprawdzić, czy stanu jest widoczne lub nie. - - if (StatusBar.isVisible) { - // do something - } - - -## Obsługiwane platformy - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/ru/index.md b/plugins/org.apache.cordova.statusbar/doc/ru/index.md deleted file mode 100644 index 511ed65d..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/ru/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> Объект `StatusBar` предоставляет некоторые функции для настройки статусной панели на iOS и Android. - -## Настройки - -#### config.xml - -* **StatusBarOverlaysWebView** (логическое значение, по умолчанию true). В iOS 7 определяет необходимо ли сделать наложение статусной панели на WebView при запуске или нет. - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor** (шестнадцатеричная строка цвета, значения по умолчанию #000000). На iOS 7 установит цвет фона статусной панели при запуске, на основании шестнадцатеричной строки цвета (#RRGGBB). - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **StatusBarStyle** (статус бар стиль, по умолчанию lightcontent). На iOS 7 установите стиль строки состояния. Доступные параметры по умолчанию, lightcontent, blacktranslucent, blackopaque. - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## Скрытие при запуске - -Во время выполнения можно использовать функцию StatusBar.hide ниже, но если вы хотите StatusBar быть скрыты при запуске приложения, необходимо изменить файл Info.plist вашего приложения. - -Добавьте/измените эти два атрибута, если они не присутствуют или отличаются от нижеуказанных значений. Установите значение **«Status bar is initially hidden»** равное **«YES»** и установите значение **«View controller-based status bar appearance»** на **«NO»**. Если вы измените его вручную без Xcode, ключи и значения являются следующими: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## Методы - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## Параметры - -* StatusBar.isVisible - -## Разрешения - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -На iOS 7 Сделайте statusbar overlay или не поверх WebView. - - StatusBar.overlaysWebView(true); - - -## Описание - -На iOS 7 Установите значение false чтобы сделать statusbar появляются как iOS 6. Задайте стиль и цвет фона в соответствии с использованием других функций. - -## Поддерживаемые платформы - -* iOS - -## Краткий пример - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -Используйте по умолчанию statusbar (темный текст, для легких стола). - - StatusBar.styleDefault(); - - -## Поддерживаемые платформы - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -Используйте lightContent statusbar (светлый текст, на темном фоне). - - StatusBar.styleLightContent(); - - -## Поддерживаемые платформы - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -Используйте blackTranslucent statusbar (светлый текст, на темном фоне). - - StatusBar.styleBlackTranslucent(); - - -## Поддерживаемые платформы - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -Используйте blackOpaque statusbar (светлый текст, на темном фоне). - - StatusBar.styleBlackOpaque(); - - -## Поддерживаемые платформы - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -На iOS 7 когда StatusBar.statusBarOverlaysWebView присвоено значение false, можно задать цвет фона для объекта statusbar по имени цвета. - - StatusBar.backgroundColorByName("red"); - - -Имена поддерживаемых цветов являются: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## Поддерживаемые платформы - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -Задает цвет фона для объекта statusbar, шестнадцатеричная строка. - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -Также поддерживаются свойства CSS стенографию. - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -На iOS 7 когда StatusBar.statusBarOverlaysWebView присвоено значение false, можно задать цвет фона для объекта statusbar, шестнадцатеричная строка (#RRGGBB). - -На WP7 и WP8 также можно указать значения как #AARRGGBB, где AA — это альфа-значение - -## Поддерживаемые платформы - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -Скройте строку состояния statusbar. - - StatusBar.hide(); - - -## Поддерживаемые платформы - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -Показывает строку состояния statusbar. - - StatusBar.show(); - - -## Поддерживаемые платформы - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -Чтение это свойство, чтобы увидеть, если statusbar является видимым или нет. - - if (StatusBar.isVisible) { - // do something - } - - -## Поддерживаемые платформы - -* iOS -* Android -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/doc/zh/index.md b/plugins/org.apache.cordova.statusbar/doc/zh/index.md deleted file mode 100644 index f2eaadd0..00000000 --- a/plugins/org.apache.cordova.statusbar/doc/zh/index.md +++ /dev/null @@ -1,238 +0,0 @@ -<!--- - 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. ---> - -# org.apache.cordova.statusbar - -# StatusBar - -> `StatusBar`物件提供了一些功能,自訂的 iOS 和 Android 狀態列。 - -## 首選項 - -#### config.xml - -* **StatusBarOverlaysWebView**(布林值,預設值為 true)。在 iOS 7,使狀態列覆蓋或不覆蓋 web 視圖在啟動時。 - - <preference name="StatusBarOverlaysWebView" value="true" /> - - -* **StatusBarBackgroundColor**(顏色十六進位字串,預設值為 #000000)。在 iOS 7,通過一個十六進位字串 (#RRGGBB) 在啟動時設置狀態列的背景色。 - - <preference name="StatusBarBackgroundColor" value="#000000" /> - - -* **狀態列**(狀態列樣式,預設值為 lightcontent)。在 iOS 7,設置的狀態橫條圖樣式。可用的選項預設,lightcontent,blacktranslucent,blackopaque。 - - <preference name="StatusBarStyle" value="lightcontent" /> - - -## 在啟動時隱藏 - -在運行時期間,你可以使用 StatusBar.hide 函數下面,但如果你想要顯示狀態列隱藏在應用程式啟動時,你必須修改你的應用程式的 Info.plist 檔。 - -添加編輯這兩個屬性,如果不存在。 將**"狀態列最初隱藏"**設置為**"YES"**和**"視圖基於控制器的狀態列外觀"**設置為**"否"**。 如果您手動編輯它沒有 Xcode,鍵和值是: - - <key>UIStatusBarHidden</key> - <true/> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> - - -## 方法 - -* StatusBar.overlaysWebView -* StatusBar.styleDefault -* StatusBar.styleLightContent -* StatusBar.styleBlackTranslucent -* StatusBar.styleBlackOpaque -* StatusBar.backgroundColorByName -* StatusBar.backgroundColorByHexString -* StatusBar.hide -* StatusBar.show - -## 屬性 - -* StatusBar.isVisible - -## 許可權 - -#### config.xml - - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" onload="true" /> - </feature> - - -# StatusBar.overlaysWebView - -在 iOS 7,使狀態列覆蓋或不覆蓋 web 視圖。 - - StatusBar.overlaysWebView(true); - - -## 描述 - -在 iOS 7,設置為 false,使狀態列出現像 iOS 6。設置的樣式和背景的顏色,以適應使用其他函數。 - -## 支援的平臺 - -* iOS - -## 快速的示例 - - StatusBar.overlaysWebView(true); - StatusBar.overlaysWebView(false); - - -# StatusBar.styleDefault - -使用預設狀態列 (淺色背景深色文本)。 - - StatusBar.styleDefault() ; - - -## 支援的平臺 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleLightContent - -使用 lightContent 狀態列 (光文本,為深色的背景)。 - - StatusBar.styleLightContent(); - - -## 支援的平臺 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackTranslucent - -使用 blackTranslucent 狀態列 (光文本,為深色的背景)。 - - StatusBar.styleBlackTranslucent(); - - -## 支援的平臺 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.styleBlackOpaque - -使用 blackOpaque 狀態列 (光文本,為深色的背景)。 - - StatusBar.styleBlackOpaque(); - - -## 支援的平臺 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByName - -在 iOS 7,當你將 StatusBar.statusBarOverlaysWebView 設置為 false,你可以設置狀態列的背景顏色由顏色名稱。 - - StatusBar.backgroundColorByName("red"); - - -支援的顏色名稱是: - - black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown - - -## 支援的平臺 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.backgroundColorByHexString - -由十六進位字串設置狀態列的背景色。 - - StatusBar.backgroundColorByHexString("#C0C0C0"); - - -此外支援 CSS 速記屬性。 - - StatusBar.backgroundColorByHexString("#333"); // => #333333 - StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB - - -在 iOS 7,當你將 StatusBar.statusBarOverlaysWebView 設置為 false,你可以設置狀態列的背景顏色由十六進位字串 (#RRGGBB)。 - -WP7 和 WP8 您還可以指定值為 #AARRGGBB,其中 AA 是 Alpha 值 - -## 支援的平臺 - -* iOS -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.hide - -隱藏狀態列。 - - StatusBar.hide(); - - -## 支援的平臺 - -* iOS -* 安卓系統 -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.show - -顯示狀態列。 - - StatusBar.show(); - - -## 支援的平臺 - -* iOS -* 安卓系統 -* Windows Phone 7 -* Windows Phone 8 - -# StatusBar.isVisible - -讀取此屬性,以看看是否狀態列是可見的或不。 - - if (StatusBar.isVisible) { - // do something - } - - -## 支援的平臺 - -* iOS -* 安卓系統 -* Windows Phone 7 -* Windows Phone 8
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/package.json b/plugins/org.apache.cordova.statusbar/package.json deleted file mode 100644 index 4e5ce417..00000000 --- a/plugins/org.apache.cordova.statusbar/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": "0.1.10", - "name": "org.apache.cordova.statusbar", - "cordova_name": "StatusBar", - "description": "Cordova StatusBar Plugin", - "license": "Apache 2.0", - "keywords": [ - "cordova", - "statusbar" - ], - "platforms": [ - "android", - "ios", - "wp7", - "wp8", - "windows" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ], - "englishdoc": "<!---\n Licensed to the Apache Software Foundation (ASF) under one\n or more contributor license agreements. See the NOTICE file\n distributed with this work for additional information\n regarding copyright ownership. The ASF licenses this file\n to you under the Apache License, Version 2.0 (the\n \"License\"); you may not use this file except in compliance\n with the License. You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing,\n software distributed under the License is distributed on an\n \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n KIND, either express or implied. See the License for the\n specific language governing permissions and limitations\n under the License.\n-->\n# org.apache.cordova.statusbar\n\nStatusBar\n======\n\n> The `StatusBar` object provides some functions to customize the iOS and Android StatusBar.\n\n\n## Installation\n\n cordova plugin add org.apache.cordova.statusbar\n\nPreferences\n-----------\n\n#### config.xml\n\n- __StatusBarOverlaysWebView__ (boolean, defaults to true). On iOS 7, make the statusbar overlay or not overlay the WebView at startup.\n\n <preference name=\"StatusBarOverlaysWebView\" value=\"true\" />\n\n- __StatusBarBackgroundColor__ (color hex string, defaults to #000000). On iOS 7, set the background color of the statusbar by a hex string (#RRGGBB) at startup.\n\n <preference name=\"StatusBarBackgroundColor\" value=\"#000000\" />\n\n- __StatusBarStyle__ (status bar style, defaults to lightcontent). On iOS 7, set the status bar style. Available options default, lightcontent, blacktranslucent, blackopaque.\n\n <preference name=\"StatusBarStyle\" value=\"lightcontent\" />\n\nHiding at startup\n-----------\n\nDuring runtime you can use the StatusBar.hide function below, but if you want the StatusBar to be hidden at app startup, you must modify your app's Info.plist file.\n\nAdd/edit these two attributes if not present. Set **\"Status bar is initially hidden\"** to **\"YES\"** and set **\"View controller-based status bar appearance\"** to **\"NO\"**. If you edit it manually without Xcode, the keys and values are:\n\n\n\t<key>UIStatusBarHidden</key>\n\t<true/>\n\t<key>UIViewControllerBasedStatusBarAppearance</key>\n\t<false/>\n\n\nMethods\n-------\nThis plugin defines global `StatusBar` object.\n\nAlthough in the global scope, it is not available until after the `deviceready` event.\n\n document.addEventListener(\"deviceready\", onDeviceReady, false);\n function onDeviceReady() {\n console.log(StatusBar);\n }\n\n- StatusBar.overlaysWebView\n- StatusBar.styleDefault\n- StatusBar.styleLightContent\n- StatusBar.styleBlackTranslucent\n- StatusBar.styleBlackOpaque\n- StatusBar.backgroundColorByName\n- StatusBar.backgroundColorByHexString\n- StatusBar.hide\n- StatusBar.show\n\nProperties\n--------\n\n- StatusBar.isVisible\n\nPermissions\n-----------\n\n#### config.xml\n\n <feature name=\"StatusBar\">\n <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\" />\n </feature>\n\nStatusBar.overlaysWebView\n=================\n\nOn iOS 7, make the statusbar overlay or not overlay the WebView.\n\n StatusBar.overlaysWebView(true);\n\nDescription\n-----------\n\nOn iOS 7, set to false to make the statusbar appear like iOS 6. Set the style and background color to suit using the other functions.\n\n\nSupported Platforms\n-------------------\n\n- iOS\n\nQuick Example\n-------------\n\n StatusBar.overlaysWebView(true);\n StatusBar.overlaysWebView(false);\n\nStatusBar.styleDefault\n=================\n\nUse the default statusbar (dark text, for light backgrounds).\n\n StatusBar.styleDefault();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.styleLightContent\n=================\n\nUse the lightContent statusbar (light text, for dark backgrounds).\n\n StatusBar.styleLightContent();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.styleBlackTranslucent\n=================\n\nUse the blackTranslucent statusbar (light text, for dark backgrounds).\n\n StatusBar.styleBlackTranslucent();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.styleBlackOpaque\n=================\n\nUse the blackOpaque statusbar (light text, for dark backgrounds).\n\n StatusBar.styleBlackOpaque();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\n\nStatusBar.backgroundColorByName\n=================\n\nOn iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by color name.\n\n StatusBar.backgroundColorByName(\"red\");\n\nSupported color names are:\n\n black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.backgroundColorByHexString\n=================\n\nSets the background color of the statusbar by a hex string.\n\n StatusBar.backgroundColorByHexString(\"#C0C0C0\");\n\nCSS shorthand properties are also supported.\n\n StatusBar.backgroundColorByHexString(\"#333\"); // => #333333\n StatusBar.backgroundColorByHexString(\"#FAB\"); // => #FFAABB\n\nOn iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by a hex string (#RRGGBB).\n\nOn WP7 and WP8 you can also specify values as #AARRGGBB, where AA is an alpha value\n\nSupported Platforms\n-------------------\n\n- iOS\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.hide\n=================\n\nHide the statusbar.\n\n StatusBar.hide();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\nStatusBar.show\n=================\n\nShows the statusbar.\n\n StatusBar.show();\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\n\nStatusBar.isVisible\n=================\n\nRead this property to see if the statusbar is visible or not.\n\n if (StatusBar.isVisible) {\n \t// do something\n }\n\n\nSupported Platforms\n-------------------\n\n- iOS\n- Android\n- Windows Phone 7\n- Windows Phone 8\n- Windows Phone 8.1\n\n\n" -}
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/plugin.xml b/plugins/org.apache.cordova.statusbar/plugin.xml deleted file mode 100644 index 01b04e0b..00000000 --- a/plugins/org.apache.cordova.statusbar/plugin.xml +++ /dev/null @@ -1,93 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:rim="http://www.blackberry.com/ns/widgets" - xmlns:android="http://schemas.android.com/apk/res/android" - id="org.apache.cordova.statusbar" - version="0.1.10"> - <name>StatusBar</name> - <description>Cordova StatusBar Plugin</description> - <license>Apache 2.0</license> - <keywords>cordova,statusbar</keywords> - - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <js-module src="www/statusbar.js" name="statusbar"> - <clobbers target="window.StatusBar" /> - </js-module> - - <platform name="android"> - <source-file src="src/android/StatusBar.java" target-dir="src/org/apache/cordova/statusbar" /> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="StatusBar"> - <param name="android-package" value="org.apache.cordova.statusbar.StatusBar" /> - <param name="onload" value="true" /> - </feature> - </config-file> - </platform> - - <!-- ios --> - <platform name="ios"> - - <config-file target="config.xml" parent="/*"> - <feature name="StatusBar"> - <param name="ios-package" value="CDVStatusBar" /> - <param name="onload" value="true" /> - </feature> - <preference name="StatusBarOverlaysWebView" value="true" /> - <preference name="StatusBarStyle" value="lightcontent" /> - </config-file> - - <header-file src="src/ios/CDVStatusBar.h" /> - <source-file src="src/ios/CDVStatusBar.m" /> - - </platform> - - <!-- wp7 --> - <platform name="wp7"> - <config-file target="config.xml" parent="/*"> - <feature name="StatusBar"> - <param name="wp-package" value="StatusBar"/> - </feature> - </config-file> - <source-file src="src/wp/StatusBar.cs" /> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="StatusBar"> - <param name="wp-package" value="StatusBar"/> - </feature> - </config-file> - <source-file src="src/wp/StatusBar.cs" /> - </platform> - - <!-- windows --> - <platform name="windows"> - <js-module src="src/windows/StatusBarProxy.js" name="StatusBarProxy"> - <runs /> - </js-module> - </platform> -</plugin> diff --git a/plugins/org.apache.cordova.statusbar/src/android/StatusBar.java b/plugins/org.apache.cordova.statusbar/src/android/StatusBar.java deleted file mode 100644 index e4f748f9..00000000 --- a/plugins/org.apache.cordova.statusbar/src/android/StatusBar.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - * -*/ -package org.apache.cordova.statusbar; - -import android.app.Activity; -import android.util.Log; -import android.view.Window; -import android.view.WindowManager; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaArgs; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.PluginResult; -import org.json.JSONException; - -public class StatusBar extends CordovaPlugin { - private static final String TAG = "StatusBar"; - - /** - * Sets the context of the Command. This can then be used to do things like - * get file paths associated with the Activity. - * - * @param cordova The context of the main Activity. - * @param webView The CordovaWebView Cordova is running in. - */ - @Override - public void initialize(final CordovaInterface cordova, CordovaWebView webView) { - Log.v(TAG, "StatusBar: initialization"); - super.initialize(cordova, webView); - - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - // Clear flag FLAG_FORCE_NOT_FULLSCREEN which is set initially - // by the Cordova. - Window window = cordova.getActivity().getWindow(); - window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); - } - }); - } - - /** - * Executes the request and returns PluginResult. - * - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackContext The callback id used when calling back into JavaScript. - * @return True if the action was valid, false otherwise. - */ - @Override - public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException { - Log.v(TAG, "Executing action: " + action); - final Activity activity = this.cordova.getActivity(); - final Window window = activity.getWindow(); - if ("_ready".equals(action)) { - boolean statusBarVisible = (window.getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0; - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, statusBarVisible)); - } - - if ("show".equals(action)) { - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - } - }); - return true; - } - - if ("hide".equals(action)) { - this.cordova.getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - } - }); - return true; - } - - return false; - } -} diff --git a/plugins/org.apache.cordova.statusbar/src/ios/CDVStatusBar.h b/plugins/org.apache.cordova.statusbar/src/ios/CDVStatusBar.h deleted file mode 100644 index 84f37fa7..00000000 --- a/plugins/org.apache.cordova.statusbar/src/ios/CDVStatusBar.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - 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 <Cordova/CDVPlugin.h> -#import <Cordova/CDVInvokedUrlCommand.h> - -@interface CDVStatusBar : CDVPlugin { - @protected - BOOL _statusBarOverlaysWebView; - UIView* _statusBarBackgroundView; - BOOL _uiviewControllerBasedStatusBarAppearance; - UIColor* _statusBarBackgroundColor; - NSString* _eventsCallbackId; -} - -@property (atomic, assign) BOOL statusBarOverlaysWebView; - -- (void) overlaysWebView:(CDVInvokedUrlCommand*)command; - -- (void) styleDefault:(CDVInvokedUrlCommand*)command; -- (void) styleLightContent:(CDVInvokedUrlCommand*)command; -- (void) styleBlackTranslucent:(CDVInvokedUrlCommand*)command; -- (void) styleBlackOpaque:(CDVInvokedUrlCommand*)command; - -- (void) backgroundColorByName:(CDVInvokedUrlCommand*)command; -- (void) backgroundColorByHexString:(CDVInvokedUrlCommand*)command; - -- (void) hide:(CDVInvokedUrlCommand*)command; -- (void) show:(CDVInvokedUrlCommand*)command; - -- (void) _ready:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/org.apache.cordova.statusbar/src/ios/CDVStatusBar.m b/plugins/org.apache.cordova.statusbar/src/ios/CDVStatusBar.m deleted file mode 100644 index d2bd708d..00000000 --- a/plugins/org.apache.cordova.statusbar/src/ios/CDVStatusBar.m +++ /dev/null @@ -1,458 +0,0 @@ -/* - 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. - */ - -/* - NOTE: plugman/cordova cli should have already installed this, - but you need the value UIViewControllerBasedStatusBarAppearance - in your Info.plist as well to set the styles in iOS 7 - */ - -#import "CDVStatusBar.h" -#import <objc/runtime.h> -#import <Cordova/CDVViewController.h> - -static const void *kHideStatusBar = &kHideStatusBar; -static const void *kStatusBarStyle = &kStatusBarStyle; - -@interface CDVViewController (StatusBar) - -@property (nonatomic, retain) id sb_hideStatusBar; -@property (nonatomic, retain) id sb_statusBarStyle; - -@end - -@implementation CDVViewController (StatusBar) - -@dynamic sb_hideStatusBar; -@dynamic sb_statusBarStyle; - -- (id)sb_hideStatusBar { - return objc_getAssociatedObject(self, kHideStatusBar); -} - -- (void)setSb_hideStatusBar:(id)newHideStatusBar { - objc_setAssociatedObject(self, kHideStatusBar, newHideStatusBar, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (id)sb_statusBarStyle { - return objc_getAssociatedObject(self, kStatusBarStyle); -} - -- (void)setSb_statusBarStyle:(id)newStatusBarStyle { - objc_setAssociatedObject(self, kStatusBarStyle, newStatusBarStyle, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (BOOL) prefersStatusBarHidden { - return [self.sb_hideStatusBar boolValue]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return (UIStatusBarStyle)[self.sb_statusBarStyle intValue]; -} - -@end - - -@interface CDVStatusBar () <UIScrollViewDelegate> -- (void)fireTappedEvent; -- (void)updateIsVisible:(BOOL)visible; -@end - -@implementation CDVStatusBar - -- (id)settingForKey:(NSString*)key -{ - return [self.commandDelegate.settings objectForKey:[key lowercaseString]]; -} - -- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context -{ - if ([keyPath isEqual:@"statusBarHidden"]) { - NSNumber* newValue = [change objectForKey:NSKeyValueChangeNewKey]; - [self updateIsVisible:![newValue boolValue]]; - } -} - -- (void)pluginInitialize -{ - BOOL isiOS7 = (IsAtLeastiOSVersion(@"7.0")); - - // init - NSNumber* uiviewControllerBasedStatusBarAppearance = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIViewControllerBasedStatusBarAppearance"]; - _uiviewControllerBasedStatusBarAppearance = (uiviewControllerBasedStatusBarAppearance == nil || [uiviewControllerBasedStatusBarAppearance boolValue]) && isiOS7; - - // observe the statusBarHidden property - [[UIApplication sharedApplication] addObserver:self forKeyPath:@"statusBarHidden" options:NSKeyValueObservingOptionNew context:NULL]; - - _statusBarOverlaysWebView = YES; // default - - [self initializeStatusBarBackgroundView]; - - self.viewController.view.autoresizesSubviews = YES; - - NSString* setting; - - setting = @"StatusBarOverlaysWebView"; - if ([self settingForKey:setting]) { - self.statusBarOverlaysWebView = [(NSNumber*)[self settingForKey:setting] boolValue]; - } - - setting = @"StatusBarBackgroundColor"; - if ([self settingForKey:setting]) { - [self _backgroundColorByHexString:[self settingForKey:setting]]; - } - - setting = @"StatusBarStyle"; - if ([self settingForKey:setting]) { - [self setStatusBarStyle:[self settingForKey:setting]]; - } - - // blank scroll view to intercept status bar taps - self.webView.scrollView.scrollsToTop = NO; - UIScrollView *fakeScrollView = [[UIScrollView alloc] initWithFrame:UIScreen.mainScreen.bounds]; - fakeScrollView.delegate = self; - fakeScrollView.scrollsToTop = YES; - [self.viewController.view addSubview:fakeScrollView]; // Add scrollview to the view heirarchy so that it will begin accepting status bar taps - [self.viewController.view sendSubviewToBack:fakeScrollView]; // Send it to the very back of the view heirarchy - fakeScrollView.contentSize = CGSizeMake(UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height * 2.0f); // Make the scroll view longer than the screen itself - fakeScrollView.contentOffset = CGPointMake(0.0f, UIScreen.mainScreen.bounds.size.height); // Scroll down so a tap will take scroll view back to the top -} - -- (void)onReset { - _eventsCallbackId = nil; -} - -- (void)fireTappedEvent { - if (_eventsCallbackId == nil) { - return; - } - NSDictionary* payload = @{@"type": @"tap"}; - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:payload]; - [result setKeepCallbackAsBool:YES]; - [self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId]; -} - -- (void)updateIsVisible:(BOOL)visible { - if (_eventsCallbackId == nil) { - return; - } - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:visible]; - [result setKeepCallbackAsBool:YES]; - [self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId]; -} - - -- (void) _ready:(CDVInvokedUrlCommand*)command -{ - _eventsCallbackId = command.callbackId; - [self updateIsVisible:![UIApplication sharedApplication].statusBarHidden]; -} - -- (void) initializeStatusBarBackgroundView -{ - CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; - statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation]; - - _statusBarBackgroundView = [[UIView alloc] initWithFrame:statusBarFrame]; - _statusBarBackgroundView.backgroundColor = _statusBarBackgroundColor; - _statusBarBackgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin); - _statusBarBackgroundView.autoresizesSubviews = YES; -} - -- (CGRect) invertFrameIfNeeded:(CGRect)rect orientation:(UIInterfaceOrientation)orientation { - // landscape is where (width > height). On iOS < 8, we need to invert since frames are - // always in Portrait context - if (UIDeviceOrientationIsLandscape(orientation) && (rect.size.width < rect.size.height) ) { - CGFloat temp = rect.size.width; - rect.size.width = rect.size.height; - rect.size.height = temp; - rect.origin = CGPointZero; - } - - return rect; -} - -- (void) setStatusBarOverlaysWebView:(BOOL)statusBarOverlaysWebView -{ - // we only care about the latest iOS version or a change in setting - if (!IsAtLeastiOSVersion(@"7.0") || statusBarOverlaysWebView == _statusBarOverlaysWebView) { - return; - } - - CGRect bounds = [[UIScreen mainScreen] bounds]; - - if (statusBarOverlaysWebView) { - - [_statusBarBackgroundView removeFromSuperview]; - if (UIDeviceOrientationIsLandscape(self.viewController.interfaceOrientation)) { - self.webView.frame = CGRectMake(0, 0, bounds.size.height, bounds.size.width); - } else { - self.webView.frame = bounds; - } - - } else { - - CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; - statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation]; - - [self initializeStatusBarBackgroundView]; - - CGRect frame = self.webView.frame; - frame.origin.y = statusBarFrame.size.height; - frame.size.height -= statusBarFrame.size.height; - - self.webView.frame = frame; - [self.webView.superview addSubview:_statusBarBackgroundView]; - } - - _statusBarOverlaysWebView = statusBarOverlaysWebView; -} - -- (BOOL) statusBarOverlaysWebView -{ - return _statusBarOverlaysWebView; -} - -- (void) overlaysWebView:(CDVInvokedUrlCommand*)command -{ - id value = [command argumentAtIndex:0]; - if (!([value isKindOfClass:[NSNumber class]])) { - value = [NSNumber numberWithBool:YES]; - } - - self.statusBarOverlaysWebView = [value boolValue]; -} - -- (void) refreshStatusBarAppearance -{ - SEL sel = NSSelectorFromString(@"setNeedsStatusBarAppearanceUpdate"); - if ([self.viewController respondsToSelector:sel]) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [self.viewController performSelector:sel withObject:nil]; -#pragma clang diagnostic pop - } -} - -- (void) setStyleForStatusBar:(UIStatusBarStyle)style -{ - if (_uiviewControllerBasedStatusBarAppearance) { - CDVViewController* vc = (CDVViewController*)self.viewController; - vc.sb_statusBarStyle = [NSNumber numberWithInt:style]; - [self refreshStatusBarAppearance]; - - } else { - [[UIApplication sharedApplication] setStatusBarStyle:style]; - } -} - -- (void) setStatusBarStyle:(NSString*)statusBarStyle -{ - // default, lightContent, blackTranslucent, blackOpaque - NSString* lcStatusBarStyle = [statusBarStyle lowercaseString]; - - if ([lcStatusBarStyle isEqualToString:@"default"]) { - [self styleDefault:nil]; - } else if ([lcStatusBarStyle isEqualToString:@"lightcontent"]) { - [self styleLightContent:nil]; - } else if ([lcStatusBarStyle isEqualToString:@"blacktranslucent"]) { - [self styleBlackTranslucent:nil]; - } else if ([lcStatusBarStyle isEqualToString:@"blackopaque"]) { - [self styleBlackOpaque:nil]; - } -} - -- (void) styleDefault:(CDVInvokedUrlCommand*)command -{ - [self setStyleForStatusBar:UIStatusBarStyleDefault]; -} - -- (void) styleLightContent:(CDVInvokedUrlCommand*)command -{ - [self setStyleForStatusBar:UIStatusBarStyleLightContent]; -} - -- (void) styleBlackTranslucent:(CDVInvokedUrlCommand*)command -{ - [self setStyleForStatusBar:UIStatusBarStyleBlackTranslucent]; -} - -- (void) styleBlackOpaque:(CDVInvokedUrlCommand*)command -{ - [self setStyleForStatusBar:UIStatusBarStyleBlackOpaque]; -} - -- (void) backgroundColorByName:(CDVInvokedUrlCommand*)command -{ - id value = [command argumentAtIndex:0]; - if (!([value isKindOfClass:[NSString class]])) { - value = @"black"; - } - - SEL selector = NSSelectorFromString([value stringByAppendingString:@"Color"]); - if ([UIColor respondsToSelector:selector]) { - _statusBarBackgroundView.backgroundColor = [UIColor performSelector:selector]; - } -} - -- (void) _backgroundColorByHexString:(NSString*)hexString -{ - unsigned int rgbValue = 0; - NSScanner* scanner = [NSScanner scannerWithString:hexString]; - [scanner setScanLocation:1]; - [scanner scanHexInt:&rgbValue]; - - _statusBarBackgroundColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; - _statusBarBackgroundView.backgroundColor = _statusBarBackgroundColor; -} - -- (void) backgroundColorByHexString:(CDVInvokedUrlCommand*)command -{ - NSString* value = [command argumentAtIndex:0]; - if (!([value isKindOfClass:[NSString class]])) { - value = @"#000000"; - } - - if (![value hasPrefix:@"#"] || [value length] < 7) { - return; - } - - [self _backgroundColorByHexString:value]; -} - -- (void) hideStatusBar -{ - if (_uiviewControllerBasedStatusBarAppearance) { - CDVViewController* vc = (CDVViewController*)self.viewController; - vc.sb_hideStatusBar = [NSNumber numberWithBool:YES]; - [self refreshStatusBarAppearance]; - - } else { - UIApplication* app = [UIApplication sharedApplication]; - [app setStatusBarHidden:YES]; - } -} - -- (void) hide:(CDVInvokedUrlCommand*)command -{ - UIApplication* app = [UIApplication sharedApplication]; - - if (!app.isStatusBarHidden) - { - self.viewController.wantsFullScreenLayout = YES; - CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; - - [self hideStatusBar]; - - if (IsAtLeastiOSVersion(@"7.0")) { - [_statusBarBackgroundView removeFromSuperview]; - } - - if (!_statusBarOverlaysWebView) { - - CGRect frame = self.webView.frame; - frame.origin.y = 0; - if (!self.statusBarOverlaysWebView) { - if (UIDeviceOrientationIsLandscape(self.viewController.interfaceOrientation)) { - frame.size.height += statusBarFrame.size.width; - } else { - frame.size.height += statusBarFrame.size.height; - } - } - - self.webView.frame = frame; - } - - _statusBarBackgroundView.hidden = YES; - } -} - -- (void) showStatusBar -{ - if (_uiviewControllerBasedStatusBarAppearance) { - CDVViewController* vc = (CDVViewController*)self.viewController; - vc.sb_hideStatusBar = [NSNumber numberWithBool:NO]; - [self refreshStatusBarAppearance]; - - } else { - UIApplication* app = [UIApplication sharedApplication]; - [app setStatusBarHidden:NO]; - } -} - -- (void) show:(CDVInvokedUrlCommand*)command -{ - UIApplication* app = [UIApplication sharedApplication]; - - if (app.isStatusBarHidden) - { - BOOL isIOS7 = (IsAtLeastiOSVersion(@"7.0")); - self.viewController.wantsFullScreenLayout = isIOS7; - - [self showStatusBar]; - - if (isIOS7) { - CGRect frame = self.webView.frame; - self.viewController.view.frame = [[UIScreen mainScreen] bounds]; - - CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame; - statusBarFrame = [self invertFrameIfNeeded:statusBarFrame orientation:self.viewController.interfaceOrientation]; - - if (!self.statusBarOverlaysWebView) { - - // there is a possibility that when the statusbar was hidden, it was in a different orientation - // from the current one. Therefore we need to expand the statusBarBackgroundView as well to the - // statusBar's current size - CGRect sbBgFrame = _statusBarBackgroundView.frame; - frame.origin.y = statusBarFrame.size.height; - frame.size.height -= statusBarFrame.size.height; - sbBgFrame.size = statusBarFrame.size; - - _statusBarBackgroundView.frame = sbBgFrame; - [self.webView.superview addSubview:_statusBarBackgroundView]; - } - - self.webView.frame = frame; - - } else { - - CGRect bounds = [[UIScreen mainScreen] applicationFrame]; - self.viewController.view.frame = bounds; - } - - _statusBarBackgroundView.hidden = NO; - } -} - -- (void) dealloc -{ - [[UIApplication sharedApplication] removeObserver:self forKeyPath:@"statusBarHidden"]; -} - - -#pragma mark - UIScrollViewDelegate - -- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView -{ - [self fireTappedEvent]; - return NO; -} - -@end diff --git a/plugins/org.apache.cordova.statusbar/src/windows/StatusBarProxy.js b/plugins/org.apache.cordova.statusbar/src/windows/StatusBarProxy.js deleted file mode 100644 index 57700999..00000000 --- a/plugins/org.apache.cordova.statusbar/src/windows/StatusBarProxy.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * 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 isSupported = true; // we assume - -function getViewStatusBar() { - if(isSupported) { - var ViewMan = Windows.UI.ViewManagement; // quick alias to save char - if( ViewMan.StatusBar && - ViewMan.StatusBar.getForCurrentView ) { - return ViewMan.StatusBar.getForCurrentView(); - } - else { - isSupported = false; // so we won't check again - } - } - return null; -} - -function hexToRgb(hex) { - // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") - var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - hex = hex.replace(shorthandRegex, function (m, r, g, b) { - return r + r + g + g + b + b; - }); - - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16) - } : null; -} - -module.exports = { - _ready: function(win, fail) { - win(statusBar.occludedRect.height !== 0); - }, - - overlaysWebView: function () { - // not supported - }, - - styleDefault: function () { - // dark text ( to be used on a light background ) - getViewStatusBar().foregroundColor = { a: 0, r: 0, g: 0, b: 0 }; - }, - - styleLightContent: function () { - // light text ( to be used on a dark background ) - getViewStatusBar().foregroundColor = { a: 0, r: 255, g: 255, b: 255 }; - }, - - styleBlackTranslucent: function () { - // #88000000 ? Apple says to use lightContent instead - return this.styleLightContent(); - }, - - styleBlackOpaque: function () { - // #FF000000 ? Apple says to use lightContent instead - return this.styleLightContent(); - }, - - backgroundColorByHexString: function (win, fail, args) { - var rgb = hexToRgb(args[0]); - var statusBar = getViewStatusBar(); - if(statusBar) { - statusBar.backgroundColor = { a: 0, r: rgb.r, g: rgb.g, b: rgb.b }; - statusBar.backgroundOpacity = 1; - } - }, - - show: function (win, fail) { - getViewStatusBar().showAsync().done(win, fail); - }, - - hide: function (win, fail) { - getViewStatusBar().hideAsync().done(win, fail); - } -}; - -require("cordova/exec/proxy").add("StatusBar", module.exports); diff --git a/plugins/org.apache.cordova.statusbar/src/wp/StatusBar.cs b/plugins/org.apache.cordova.statusbar/src/wp/StatusBar.cs deleted file mode 100644 index ec83ca8e..00000000 --- a/plugins/org.apache.cordova.statusbar/src/wp/StatusBar.cs +++ /dev/null @@ -1,141 +0,0 @@ -/* - Licensed 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. -*/ - - -using Microsoft.Phone.Shell; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Threading; -using System.Windows; -using System.Windows.Media; -using System.Windows.Threading; - - -/* - * http://www.idev101.com/code/User_Interface/StatusBar.html - * https://developer.apple.com/library/ios/documentation/userexperience/conceptual/transitionguide/Bars.html - * https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html#//apple_ref/c/econst/UIStatusBarStyleDefault - * */ - - -namespace WPCordovaClassLib.Cordova.Commands -{ - public class StatusBar : BaseCommand - { - - // returns an argb value, if the hex is only rgb, it will be full opacity - protected Color ColorFromHex(string hexString) - { - string cleanHex = hexString.Replace("#", "").Replace("0x", ""); - // turn #FFF into #FFFFFF - if (cleanHex.Length == 3) - { - cleanHex = "" + cleanHex[0] + cleanHex[0] + cleanHex[1] + cleanHex[1] + cleanHex[2] + cleanHex[2]; - } - // add an alpha 100% if it is missing - if (cleanHex.Length == 6) - { - cleanHex = "FF" + cleanHex; - } - int argb = Int32.Parse(cleanHex, NumberStyles.HexNumber); - Color clr = Color.FromArgb((byte)((argb & 0xff000000) >> 0x18), - (byte)((argb & 0xff0000) >> 0x10), - (byte)((argb & 0xff00) >> 8), - (byte)(argb & 0xff)); - return clr; - } - - public void _ready(string options) - { - Deployment.Current.Dispatcher.BeginInvoke(() => - { - bool isVis = SystemTray.IsVisible; - // TODO: pass this to JS - //Debug.WriteLine("Result::" + res); - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isVis)); - }); - } - - public void overlaysWebView(string options) - { //exec(null, null, "StatusBar", "overlaysWebView", [doOverlay]); - // string arg = JSON.JsonHelper.Deserialize<string[]>(options)[0]; - } - - public void styleDefault(string options) - { //exec(null, null, "StatusBar", "styleDefault", []); - Deployment.Current.Dispatcher.BeginInvoke(() => - { - SystemTray.ForegroundColor = Colors.Black; - }); - } - - public void styleLightContent(string options) - { //exec(null, null, "StatusBar", "styleLightContent", []); - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - SystemTray.ForegroundColor = Colors.White; - }); - } - - public void styleBlackTranslucent(string options) - { //exec(null, null, "StatusBar", "styleBlackTranslucent", []); - styleLightContent(options); - } - - public void styleBlackOpaque(string options) - { //exec(null, null, "StatusBar", "styleBlackOpaque", []); - styleLightContent(options); - } - - public void backgroundColorByName(string options) - { //exec(null, null, "StatusBar", "backgroundColorByName", [colorname]); - // this should NOT be called, js should now be using/converting color names to hex - } - - public void backgroundColorByHexString(string options) - { //exec(null, null, "StatusBar", "backgroundColorByHexString", [hexString]); - string argb = JSON.JsonHelper.Deserialize<string[]>(options)[0]; - - Color clr = ColorFromHex(argb); - - Deployment.Current.Dispatcher.BeginInvoke(() => - { - SystemTray.Opacity = clr.A / 255.0d; - SystemTray.BackgroundColor = clr; - - }); - } - - public void hide(string options) - { //exec(null, null, "StatusBar", "hide", []); - Deployment.Current.Dispatcher.BeginInvoke(() => - { - SystemTray.IsVisible = false; - }); - - } - - public void show(string options) - { //exec(null, null, "StatusBar", "show", []); - Deployment.Current.Dispatcher.BeginInvoke(() => - { - SystemTray.IsVisible = true; - }); - } - } -}
\ No newline at end of file diff --git a/plugins/org.apache.cordova.statusbar/tests/plugin.xml b/plugins/org.apache.cordova.statusbar/tests/plugin.xml deleted file mode 100644 index 69b7e10f..00000000 --- a/plugins/org.apache.cordova.statusbar/tests/plugin.xml +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - 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. ---> - -<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" - xmlns:rim="http://www.blackberry.com/ns/widgets" - xmlns:android="http://schemas.android.com/apk/res/android" - id="org.apache.cordova.statusbar.tests" - version="0.1.10"> - <name>Cordova StatusBar Plugin Tests</name> - <license>Apache 2.0</license> - - <js-module src="tests.js" name="tests"> - </js-module> -</plugin> diff --git a/plugins/org.apache.cordova.statusbar/tests/tests.js b/plugins/org.apache.cordova.statusbar/tests/tests.js deleted file mode 100644 index 8b409eca..00000000 --- a/plugins/org.apache.cordova.statusbar/tests/tests.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * - * 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. - * -*/ - -exports.defineManualTests = function (contentEl, createActionButton) { - function log(msg) { - var el = document.getElementById("info"); - var logLine = document.createElement('div'); - logLine.innerHTML = msg; - el.appendChild(logLine); - } - - function doShow() { - StatusBar.show(); - log('StatusBar.isVisible=' + StatusBar.isVisible); - } - - function doHide() { - StatusBar.hide(); - log('StatusBar.isVisible=' + StatusBar.isVisible); - } - - function doColor1() { - log('set color=red'); - StatusBar.backgroundColorByName('red'); - } - - function doColor2() { - log('set style=translucent black'); - StatusBar.styleBlackTranslucent(); - } - - function doColor3() { - log('set style=default'); - StatusBar.styleDefault(); - } - - var showOverlay = true; - function doOverlay() { - showOverlay = !showOverlay; - StatusBar.overlaysWebView(showOverlay); - log('Set overlay=' + showOverlay); - } - - /******************************************************************************/ - - contentEl.innerHTML = '<div id="info"></div>' + - 'Also: tapping bar on iOS should emit a log.' + - '<div id="action-show"></div>' + - 'Expected result: Status bar will be visible' + - '</p> <div id="action-hide"></div>' + - 'Expected result: Status bar will be hidden' + - '</p> <div id="action-color2"></div>' + - 'Expected result: Status bar text will be a light (white) color' + - '</p> <div id="action-color3"></div>' + - 'Expected result: Status bar text will be a dark (black) color' + - '</p> <div id="action-overlays"></div>' + - 'Expected result:<br>Overlay true = status bar will lay on top of web view content<br>Overlay false = status bar will be separate from web view and will not cover content' + - '</p> <div id="action-color1"></div>' + - 'Expected result: If overlay false, background color for status bar will be red'; - - log('StatusBar.isVisible=' + StatusBar.isVisible); - window.addEventListener('statusTap', function () { - log('tap!'); - }, false); - - createActionButton("Show", function () { - doShow(); - }, 'action-show'); - - createActionButton("Hide", function () { - doHide(); - }, 'action-hide'); - - createActionButton("Style=red (background)", function () { - doColor1(); - }, 'action-color1'); - - createActionButton("Style=translucent black", function () { - doColor2(); - }, 'action-color2'); - - createActionButton("Style=default", function () { - doColor3(); - }, 'action-color3'); - - createActionButton("Toggle Overlays", function () { - doOverlay(); - }, 'action-overlays'); -}; diff --git a/plugins/org.apache.cordova.statusbar/www/statusbar.js b/plugins/org.apache.cordova.statusbar/www/statusbar.js deleted file mode 100644 index 7ebca302..00000000 --- a/plugins/org.apache.cordova.statusbar/www/statusbar.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * 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 exec = require('cordova/exec'); - -var namedColors = { - "black": "#000000", - "darkGray": "#A9A9A9", - "lightGray": "#D3D3D3", - "white": "#FFFFFF", - "gray": "#808080", - "red": "#FF0000", - "green": "#00FF00", - "blue": "#0000FF", - "cyan": "#00FFFF", - "yellow": "#FFFF00", - "magenta": "#FF00FF", - "orange": "#FFA500", - "purple": "#800080", - "brown": "#A52A2A" -}; - -var StatusBar = { - - isVisible: true, - - overlaysWebView: function (doOverlay) { - exec(null, null, "StatusBar", "overlaysWebView", [doOverlay]); - }, - - styleDefault: function () { - // dark text ( to be used on a light background ) - exec(null, null, "StatusBar", "styleDefault", []); - }, - - styleLightContent: function () { - // light text ( to be used on a dark background ) - exec(null, null, "StatusBar", "styleLightContent", []); - }, - - styleBlackTranslucent: function () { - // #88000000 ? Apple says to use lightContent instead - exec(null, null, "StatusBar", "styleBlackTranslucent", []); - }, - - styleBlackOpaque: function () { - // #FF000000 ? Apple says to use lightContent instead - exec(null, null, "StatusBar", "styleBlackOpaque", []); - }, - - backgroundColorByName: function (colorname) { - return StatusBar.backgroundColorByHexString(namedColors[colorname]); - }, - - backgroundColorByHexString: function (hexString) { - if (hexString.charAt(0) !== "#") { - hexString = "#" + hexString; - } - - if (hexString.length === 4) { - var split = hexString.split(""); - hexString = "#" + split[1] + split[1] + split[2] + split[2] + split[3] + split[3]; - } - - exec(null, null, "StatusBar", "backgroundColorByHexString", [hexString]); - }, - - hide: function () { - exec(null, null, "StatusBar", "hide", []); - StatusBar.isVisible = false; - }, - - show: function () { - exec(null, null, "StatusBar", "show", []); - StatusBar.isVisible = true; - } - -}; - -// prime it -exec(function (res) { - if (typeof res == 'object') { - if (res.type == 'tap') { - cordova.fireWindowEvent('statusTap'); - } - } else { - StatusBar.isVisible = res; - } -}, null, "StatusBar", "_ready", []); - -module.exports = StatusBar; diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/README.md b/plugins/org.devgeeks.Canvas2ImagePlugin/README.md deleted file mode 100644 index 022f8ab1..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/README.md +++ /dev/null @@ -1,53 +0,0 @@ -Canvas2ImagePlugin -============ - -This plugin allows you to save the contents of an HTML canvas tag to the iOS Photo Library, Android Gallery or WindowsPhone 8 Photo Album from your app. - -See an example project using it here: [https://github.com/devgeeks/Canvas2ImageDemo](https://github.com/devgeeks/Canvas2ImageDemo) - note: this app does not work in wp8. - -Installation ------------- - -### For Cordova 3.0.x: - -1. To add this plugin just type: `cordova plugin add https://github.com/devgeeks/Canvas2ImagePlugin.git` or `phonegap local plugin add https://github.com/devgeeks/Canvas2ImagePlugin.git` -2. To remove this plugin type: `cordova plugin remove org.devgeeks.Canvas2ImagePlugin` or `phonegap local plugin remove org.devgeeks.Canvas2ImagePlugin` - -### NOTE: For older versions of Cordova (You will probably have to use tag 0.2.0) - -Usage: ------- - -Call the `window.canvas2ImagePlugin.saveImageDataToLibrary()` method using success and error callbacks and the id attribute or the element object of the canvas to save: - -### Example -```html -<canvas id="myCanvas" width="165px" height="145px"></canvas> -``` - -```javascript -function onDeviceReady() -{ - window.canvas2ImagePlugin.saveImageDataToLibrary( - function(msg){ - console.log(msg); - }, - function(err){ - console.log(err); - }, - document.getElementById('myCanvas') - ); -} -``` - -## License - -The MIT License - -Copyright (c) 2011 Tommy-Carlos Williams (http://github.com/devgeeks) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/plugin.xml b/plugins/org.devgeeks.Canvas2ImagePlugin/plugin.xml deleted file mode 100644 index 657a04dc..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/plugin.xml +++ /dev/null @@ -1,70 +0,0 @@ -<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="org.devgeeks.Canvas2ImagePlugin" - version="0.6.0"> - - <name>Canvas 2 Image</name> - - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <description>This plugin allows you to save the contents of an HTML canvas tag to the iOS Photo Library, or Android Gallery from your app.</description> - <author>Tommy-Carlos Williams - tommy@devgeeks.org</author> - <keywords>canvas,image,photo library</keywords> - - <license>MIT</license> - - <js-module src="www/Canvas2ImagePlugin.js" name="Canvas2ImagePlugin"> - <clobbers target="window.canvas2ImagePlugin" /> - </js-module> - - <!-- ios --> - <platform name="ios"> - <config-file target="config.xml" parent="/*"> - <feature name="Canvas2ImagePlugin"> - <param name="ios-package" value="Canvas2ImagePlugin"/> - <param name="onload" value="true" /> - </feature> - </config-file> - - <header-file src="src/ios/Canvas2ImagePlugin.h" /> - - <source-file src="src/ios/Canvas2ImagePlugin.m" - compiler-flags="-fno-objc-arc" /> - </platform> - - <!-- android --> - <platform name="android"> - - <config-file target="AndroidManifest.xml" parent="/*"> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - </config-file> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="Canvas2ImagePlugin" > - <param name="android-package" value="org.devgeeks.Canvas2ImagePlugin.Canvas2ImagePlugin"/> - </feature> - </config-file> - - <source-file src="src/android/Canvas2ImagePlugin.java" - target-dir="src/org/devgeeks/Canvas2ImagePlugin" /> - - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="Canvas2ImagePlugin"> - <param name="wp-package" value="Canvas2ImagePlugin"/> - <param name="onload" value="true" /> - </feature> - </config-file> - - <config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities"> - <Capability Name="ID_CAP_MEDIALIB_PHOTO" /> - </config-file> - - <source-file src="src/wp8/Canvas2ImagePlugin.cs" /> - </platform> -</plugin> diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/src/android/Canvas2ImagePlugin.java b/plugins/org.devgeeks.Canvas2ImagePlugin/src/android/Canvas2ImagePlugin.java deleted file mode 100644 index 90118c0b..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/src/android/Canvas2ImagePlugin.java +++ /dev/null @@ -1,126 +0,0 @@ -package org.devgeeks.Canvas2ImagePlugin; - -import java.io.File; -import java.io.FileOutputStream; -import java.util.Calendar; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaPlugin; - -import org.json.JSONArray; -import org.json.JSONException; - -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.util.Base64; -import android.util.Log; - -/** - * Canvas2ImagePlugin.java - * - * Android implementation of the Canvas2ImagePlugin for iOS. - * Inspirated by Joseph's "Save HTML5 Canvas Image to Gallery" plugin - * http://jbkflex.wordpress.com/2013/06/19/save-html5-canvas-image-to-gallery-phonegap-android-plugin/ - * - * @author Vegard Løkken <vegard@headspin.no> - */ -public class Canvas2ImagePlugin extends CordovaPlugin { - public static final String ACTION = "saveImageDataToLibrary"; - - @Override - public boolean execute(String action, JSONArray data, - CallbackContext callbackContext) throws JSONException { - - if (action.equals(ACTION)) { - - String base64 = data.optString(0); - if (base64.equals("")) // isEmpty() requires API level 9 - callbackContext.error("Missing base64 string"); - - // Create the bitmap from the base64 string - Log.d("Canvas2ImagePlugin", base64); - byte[] decodedString = Base64.decode(base64, Base64.DEFAULT); - Bitmap bmp = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); - if (bmp == null) { - callbackContext.error("The image could not be decoded"); - } else { - - // Save the image - File imageFile = savePhoto(bmp); - if (imageFile == null) - callbackContext.error("Error while saving image"); - - // Update image gallery - scanPhoto(imageFile); - - callbackContext.success(imageFile.toString()); - } - - return true; - } else { - return false; - } - } - - private File savePhoto(Bitmap bmp) { - File retVal = null; - - try { - Calendar c = Calendar.getInstance(); - String date = "" + c.get(Calendar.DAY_OF_MONTH) - + c.get(Calendar.MONTH) - + c.get(Calendar.YEAR) - + c.get(Calendar.HOUR_OF_DAY) - + c.get(Calendar.MINUTE) - + c.get(Calendar.SECOND); - - String deviceVersion = Build.VERSION.RELEASE; - Log.i("Canvas2ImagePlugin", "Android version " + deviceVersion); - int check = deviceVersion.compareTo("2.3.3"); - - File folder; - /* - * File path = Environment.getExternalStoragePublicDirectory( - * Environment.DIRECTORY_PICTURES ); //this throws error in Android - * 2.2 - */ - if (check >= 1) { - folder = Environment - .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); - - if(!folder.exists()) { - folder.mkdirs(); - } - } else { - folder = Environment.getExternalStorageDirectory(); - } - - File imageFile = new File(folder, "c2i_" + date.toString() + ".png"); - - FileOutputStream out = new FileOutputStream(imageFile); - bmp.compress(Bitmap.CompressFormat.PNG, 100, out); - out.flush(); - out.close(); - - retVal = imageFile; - } catch (Exception e) { - Log.e("Canvas2ImagePlugin", "An exception occured while saving image: " - + e.toString()); - } - return retVal; - } - - /* Invoke the system's media scanner to add your photo to the Media Provider's database, - * making it available in the Android Gallery application and to other apps. */ - private void scanPhoto(File imageFile) - { - Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - Uri contentUri = Uri.fromFile(imageFile); - mediaScanIntent.setData(contentUri); - cordova.getActivity().sendBroadcast(mediaScanIntent); - } -} diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/src/ios/Canvas2ImagePlugin.h b/plugins/org.devgeeks.Canvas2ImagePlugin/src/ios/Canvas2ImagePlugin.h deleted file mode 100644 index ef7bc567..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/src/ios/Canvas2ImagePlugin.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Canvas2ImagePlugin.h -// Canvas2ImagePlugin PhoneGap/Cordova plugin -// -// Created by Tommy-Carlos Williams on 29/03/12. -// Copyright (c) 2012 Tommy-Carlos Williams. All rights reserved. -// MIT Licensed -// - - -#import <Cordova/CDVPlugin.h> - -@interface Canvas2ImagePlugin : CDVPlugin -{ - NSString* callbackId; -} - -@property (nonatomic, copy) NSString* callbackId; - -- (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/src/ios/Canvas2ImagePlugin.m b/plugins/org.devgeeks.Canvas2ImagePlugin/src/ios/Canvas2ImagePlugin.m deleted file mode 100644 index 734ee006..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/src/ios/Canvas2ImagePlugin.m +++ /dev/null @@ -1,58 +0,0 @@ -// -// Canvas2ImagePlugin.m -// Canvas2ImagePlugin PhoneGap/Cordova plugin -// -// Created by Tommy-Carlos Williams on 29/03/12. -// Copyright (c) 2012 Tommy-Carlos Williams. All rights reserved. -// MIT Licensed -// - -#import "Canvas2ImagePlugin.h" -#import <Cordova/CDV.h> - -@implementation Canvas2ImagePlugin -@synthesize callbackId; - -//-(CDVPlugin*) initWithWebView:(UIWebView*)theWebView -//{ -// self = (Canvas2ImagePlugin*)[super initWithWebView:theWebView]; -// return self; -//} - -- (void)saveImageDataToLibrary:(CDVInvokedUrlCommand*)command -{ - self.callbackId = command.callbackId; - NSData* imageData = [NSData dataFromBase64String:[command.arguments objectAtIndex:0]]; - - UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease]; - UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); - -} - -- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo -{ - // Was there an error? - if (error != NULL) - { - // Show error message... - NSLog(@"ERROR: %@",error); - CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_ERROR messageAsString:error.description]; - [self.webView stringByEvaluatingJavaScriptFromString:[result toErrorCallbackString: self.callbackId]]; - } - else // No errors - { - // Show message image successfully saved - NSLog(@"IMAGE SAVED!"); - CDVPluginResult* result = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsString:@"Image saved"]; - [self.webView stringByEvaluatingJavaScriptFromString:[result toSuccessCallbackString: self.callbackId]]; - } -} - -- (void)dealloc -{ - [callbackId release]; - [super dealloc]; -} - - -@end diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/src/wp8/Canvas2ImagePlugin.cs b/plugins/org.devgeeks.Canvas2ImagePlugin/src/wp8/Canvas2ImagePlugin.cs deleted file mode 100644 index 6376348c..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/src/wp8/Canvas2ImagePlugin.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.Xna.Framework.Media; -using System; -using System.IO; -using System.Text; -using WPCordovaClassLib.Cordova; -using WPCordovaClassLib.Cordova.Commands; -using WPCordovaClassLib.Cordova.JSON; - -public class Canvas2ImagePlugin : BaseCommand -{ - public Canvas2ImagePlugin() - { - } - - public void saveImageDataToLibrary(string jsonArgs) - { - try - { - var options = JsonHelper.Deserialize<string[]>(jsonArgs); - - string imageData = options[0]; - byte[] imageBytes = Convert.FromBase64String(imageData); - - using (var imageStream = new MemoryStream(imageBytes)) - { - imageStream.Seek(0, SeekOrigin.Begin); - - string fileName = String.Format("c2i_{0:yyyyMMdd_HHmmss}", DateTime.Now); - var library = new MediaLibrary(); - var picture = library.SavePicture(fileName, imageStream); - - if (picture.Name.Contains(fileName)) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.OK, - "Image saved: " + picture.Name)); - } - else - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, - "Failed to save image: " + picture.Name)); - } - } - } - catch (Exception ex) - { - DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message)); - } - } -} diff --git a/plugins/org.devgeeks.Canvas2ImagePlugin/www/Canvas2ImagePlugin.js b/plugins/org.devgeeks.Canvas2ImagePlugin/www/Canvas2ImagePlugin.js deleted file mode 100644 index a5ee9fcf..00000000 --- a/plugins/org.devgeeks.Canvas2ImagePlugin/www/Canvas2ImagePlugin.js +++ /dev/null @@ -1,27 +0,0 @@ -// -// Canvas2ImagePlugin.js -// Canvas2ImagePlugin PhoneGap/Cordova plugin -// -// Created by Tommy-Carlos Williams on 29/03/12. -// Copyright (c) 2012 Tommy-Carlos Williams. All rights reserved. -// MIT Licensed -// - - module.exports = { - - saveImageDataToLibrary:function(successCallback, failureCallback, canvasId) { - // successCallback required - if (typeof successCallback != "function") { - console.log("Canvas2ImagePlugin Error: successCallback is not a function"); - } - else if (typeof failureCallback != "function") { - console.log("Canvas2ImagePlugin Error: failureCallback is not a function"); - } - else { - var canvas = (typeof canvasId === "string") ? document.getElementById(canvasId) : canvasId; - var imageData = canvas.toDataURL().replace(/data:image\/png;base64,/,''); - return cordova.exec(successCallback, failureCallback, "Canvas2ImagePlugin","saveImageDataToLibrary",[imageData]); - } - } - }; - diff --git a/plugins/phonegap-plugin-push/CHANGELOG.md b/plugins/phonegap-plugin-push/CHANGELOG.md deleted file mode 100644 index 82e294c6..00000000 --- a/plugins/phonegap-plugin-push/CHANGELOG.md +++ /dev/null @@ -1,161 +0,0 @@ -# Change Log - -## [1.3.0](https://github.com/phonegap/phonegap-plugin-push/tree/1.3.0) (2015-09-21) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.2.3...1.3.0) - -**Implemented enhancements:** - -- How to use GCM 3.0 with this plugin? [\#127](https://github.com/phonegap/phonegap-plugin-push/issues/127) -- Android: possibility to send a notification with a title and without message [\#122](https://github.com/phonegap/phonegap-plugin-push/issues/122) -- Enhancement - Led, Vibration Pattern, Priority on Android [\#105](https://github.com/phonegap/phonegap-plugin-push/issues/105) - -**Fixed bugs:** - -- It is using in gcm data.additionalData ? [\#126](https://github.com/phonegap/phonegap-plugin-push/issues/126) -- iOS notification from cold boot [\#117](https://github.com/phonegap/phonegap-plugin-push/issues/117) -- Notification LED is not working [\#97](https://github.com/phonegap/phonegap-plugin-push/issues/97) - -**Closed issues:** - -- Know which version is used in build service [\#151](https://github.com/phonegap/phonegap-plugin-push/issues/151) -- Registration is not working in IOS9 [\#150](https://github.com/phonegap/phonegap-plugin-push/issues/150) -- build fail on android [\#149](https://github.com/phonegap/phonegap-plugin-push/issues/149) -- iconColor does not set icon background on Android [\#146](https://github.com/phonegap/phonegap-plugin-push/issues/146) -- Prevent windows toast notification when in foreground [\#145](https://github.com/phonegap/phonegap-plugin-push/issues/145) -- How to implement push notification for ios with this plug-in? [\#143](https://github.com/phonegap/phonegap-plugin-push/issues/143) -- After installing this plugin I can't build on Android [\#141](https://github.com/phonegap/phonegap-plugin-push/issues/141) -- version 1.2.3 [\#134](https://github.com/phonegap/phonegap-plugin-push/issues/134) -- New inbox style on android [\#131](https://github.com/phonegap/phonegap-plugin-push/issues/131) -- impossible to install the phonegap-plugin-push Error [\#130](https://github.com/phonegap/phonegap-plugin-push/issues/130) -- Hello, i am developing a cordova app which requires push notifications to be sent to users android phone, so i tried using this new phonegap push plugin as old one is deprecated, and it keeps giving me an error in console: Uncaught ReferenceError: module is not defined --- Line 154 Push.js and i dont have much experience with cordova, so can anyone assist me ? [\#128](https://github.com/phonegap/phonegap-plugin-push/issues/128) -- INVALID\_REGISTRATION when http post request with to IOS [\#123](https://github.com/phonegap/phonegap-plugin-push/issues/123) -- Andriod :More than 2 notifications in status bar it is not works. [\#121](https://github.com/phonegap/phonegap-plugin-push/issues/121) -- Release notes for 1.2.x [\#119](https://github.com/phonegap/phonegap-plugin-push/issues/119) -- Google cloud messaging GCM - Push Notification not being sent \(Server Side\) [\#110](https://github.com/phonegap/phonegap-plugin-push/issues/110) - -## [1.2.3](https://github.com/phonegap/phonegap-plugin-push/tree/1.2.3) (2015-09-08) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.2.2...1.2.3) - -**Fixed bugs:** - -- Notification not showing..... [\#101](https://github.com/phonegap/phonegap-plugin-push/issues/101) -- Same data payload for messages with action buttons [\#90](https://github.com/phonegap/phonegap-plugin-push/issues/90) - -**Closed issues:** - -- Notification doesn't show the app icon [\#112](https://github.com/phonegap/phonegap-plugin-push/issues/112) -- Notification doesn't show the app icon [\#111](https://github.com/phonegap/phonegap-plugin-push/issues/111) -- Issue with plugin facebook connect [\#107](https://github.com/phonegap/phonegap-plugin-push/issues/107) -- Cordova Support [\#99](https://github.com/phonegap/phonegap-plugin-push/issues/99) -- Uncaught ReferenceError: cordova is not defined, http://localhost:8100/lib/push.js, Line: 7 [\#98](https://github.com/phonegap/phonegap-plugin-push/issues/98) -- Notifications never received on Android [\#96](https://github.com/phonegap/phonegap-plugin-push/issues/96) -- How know the way the app was launched [\#95](https://github.com/phonegap/phonegap-plugin-push/issues/95) -- Android, example doesn't work when it goes into background [\#94](https://github.com/phonegap/phonegap-plugin-push/issues/94) -- Utilizing push plugin [\#91](https://github.com/phonegap/phonegap-plugin-push/issues/91) - -## [1.2.2](https://github.com/phonegap/phonegap-plugin-push/tree/1.2.2) (2015-08-31) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.2.1...1.2.2) - -**Closed issues:** - -- PushPlugin notification icon is too big [\#88](https://github.com/phonegap/phonegap-plugin-push/issues/88) - -## [1.2.1](https://github.com/phonegap/phonegap-plugin-push/tree/1.2.1) (2015-08-31) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.2.0...1.2.1) - -**Implemented enhancements:** - -- Question about GCM Notifications and data in the message payload [\#87](https://github.com/phonegap/phonegap-plugin-push/issues/87) - -**Fixed bugs:** - -- Notification callback for pushes without a message [\#80](https://github.com/phonegap/phonegap-plugin-push/issues/80) - -**Closed issues:** - -- Android: No notification displayed on device. Notification event never called. [\#86](https://github.com/phonegap/phonegap-plugin-push/issues/86) -- it seem no wp8 version for now [\#56](https://github.com/phonegap/phonegap-plugin-push/issues/56) - -## [1.2.0](https://github.com/phonegap/phonegap-plugin-push/tree/1.2.0) (2015-08-25) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.1.1...1.2.0) - -**Implemented enhancements:** - -- Implement Inbox style for Android [\#74](https://github.com/phonegap/phonegap-plugin-push/issues/74) -- multi-line text support [\#63](https://github.com/phonegap/phonegap-plugin-push/issues/63) - -**Fixed bugs:** - -- Pushes being deleted from notification bar when cold start [\#67](https://github.com/phonegap/phonegap-plugin-push/issues/67) - -**Closed issues:** - -- oficial push plugin and windows and wp8 compatibility [\#71](https://github.com/phonegap/phonegap-plugin-push/issues/71) -- On Android, GCMIntentService.onError\(\) doesn't get passed to the JavaScript "error" event [\#65](https://github.com/phonegap/phonegap-plugin-push/issues/65) -- Android: add property to vibrate phone on received notification [\#61](https://github.com/phonegap/phonegap-plugin-push/issues/61) -- push.on =\> "registration" will trigger twice times that only in iOS [\#57](https://github.com/phonegap/phonegap-plugin-push/issues/57) - -## [1.1.1](https://github.com/phonegap/phonegap-plugin-push/tree/1.1.1) (2015-07-27) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.1.0...1.1.1) - -## [1.1.0](https://github.com/phonegap/phonegap-plugin-push/tree/1.1.0) (2015-07-27) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.0.1...1.1.0) - -**Implemented enhancements:** - -- iOS doesn't add foreground key [\#41](https://github.com/phonegap/phonegap-plugin-push/issues/41) -- Android: Notification icon problem [\#20](https://github.com/phonegap/phonegap-plugin-push/issues/20) -- iOS badge number [\#18](https://github.com/phonegap/phonegap-plugin-push/issues/18) -- How i can set icons for push notifications in status bar and push view in android [\#14](https://github.com/phonegap/phonegap-plugin-push/issues/14) -- Support Win8.1 + Phone 8.1 Universal Apps \(WNS\), drop support for WP8.0 \(MPNS\) [\#13](https://github.com/phonegap/phonegap-plugin-push/issues/13) - -**Fixed bugs:** - -- iOS only reads out "aps" payload [\#29](https://github.com/phonegap/phonegap-plugin-push/issues/29) -- Event not fired when in background [\#24](https://github.com/phonegap/phonegap-plugin-push/issues/24) -- Custom notification sound in background mode? [\#17](https://github.com/phonegap/phonegap-plugin-push/issues/17) - -**Closed issues:** - -- iOS only receives first notification in foreground [\#42](https://github.com/phonegap/phonegap-plugin-push/issues/42) -- Cannot register on iOS [\#30](https://github.com/phonegap/phonegap-plugin-push/issues/30) -- Fix Android paths in src folder [\#23](https://github.com/phonegap/phonegap-plugin-push/issues/23) -- PushNotification not defined [\#21](https://github.com/phonegap/phonegap-plugin-push/issues/21) -- Error trying to remove the plugin [\#19](https://github.com/phonegap/phonegap-plugin-push/issues/19) -- Handling multiple notifications on Android devices [\#12](https://github.com/phonegap/phonegap-plugin-push/issues/12) -- PGB \(build.phonegap.com\) problem [\#11](https://github.com/phonegap/phonegap-plugin-push/issues/11) -- reporting location via gcm [\#6](https://github.com/phonegap/phonegap-plugin-push/issues/6) - -**Merged pull requests:** - -- Updating Readme to document toast capable setting [\#47](https://github.com/phonegap/phonegap-plugin-push/pull/47) ([rakatyal](https://github.com/rakatyal)) -- fix issue \#41 [\#44](https://github.com/phonegap/phonegap-plugin-push/pull/44) ([Deminetix](https://github.com/Deminetix)) -- fix issue \#42 [\#43](https://github.com/phonegap/phonegap-plugin-push/pull/43) ([Deminetix](https://github.com/Deminetix)) -- Adding hyperlinks to README [\#40](https://github.com/phonegap/phonegap-plugin-push/pull/40) ([rakatyal](https://github.com/rakatyal)) -- Updating Readme [\#37](https://github.com/phonegap/phonegap-plugin-push/pull/37) ([rakatyal](https://github.com/rakatyal)) -- Adding windows support to plugin [\#36](https://github.com/phonegap/phonegap-plugin-push/pull/36) ([rakatyal](https://github.com/rakatyal)) -- Raghav/update [\#35](https://github.com/phonegap/phonegap-plugin-push/pull/35) ([rakatyal](https://github.com/rakatyal)) -- Adding behavior for different notification types [\#28](https://github.com/phonegap/phonegap-plugin-push/pull/28) ([rakatyal](https://github.com/rakatyal)) -- Initial commit to add support for windows universal platform [\#15](https://github.com/phonegap/phonegap-plugin-push/pull/15) ([rakatyal](https://github.com/rakatyal)) - -## [1.0.1](https://github.com/phonegap/phonegap-plugin-push/tree/1.0.1) (2015-06-08) -[Full Changelog](https://github.com/phonegap/phonegap-plugin-push/compare/1.0.0...1.0.1) - -**Closed issues:** - -- documentation "senderId" correction [\#10](https://github.com/phonegap/phonegap-plugin-push/issues/10) -- add to our ci page [\#9](https://github.com/phonegap/phonegap-plugin-push/issues/9) -- Update installation instructions [\#7](https://github.com/phonegap/phonegap-plugin-push/issues/7) - -## [1.0.0](https://github.com/phonegap/phonegap-plugin-push/tree/1.0.0) (2015-06-05) -**Closed issues:** - -- Update code using enabledRemoteNotificationTypes because it is “not supported in iOS 8” [\#8](https://github.com/phonegap/phonegap-plugin-push/issues/8) -- Register method not working [\#4](https://github.com/phonegap/phonegap-plugin-push/issues/4) -- Publish plugin to npm [\#3](https://github.com/phonegap/phonegap-plugin-push/issues/3) -- Update example to use new API [\#2](https://github.com/phonegap/phonegap-plugin-push/issues/2) -- Lowercase Example/ directory [\#1](https://github.com/phonegap/phonegap-plugin-push/issues/1) - - - -\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/MIT-LICENSE b/plugins/phonegap-plugin-push/MIT-LICENSE deleted file mode 100644 index 55ab5e39..00000000 --- a/plugins/phonegap-plugin-push/MIT-LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright 2012 Bob Easterday, Adobe Systems - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/README.md b/plugins/phonegap-plugin-push/README.md deleted file mode 100644 index bd706cb4..00000000 --- a/plugins/phonegap-plugin-push/README.md +++ /dev/null @@ -1,519 +0,0 @@ -#phonegap-plugin-push [](https://travis-ci.org/phonegap/phonegap-plugin-push) - -> Register and receive push notifications - -## Installation - -This requires phonegap/cordova CLI 5.0+ ( current stable v1.3.0 ) - -``` -phonegap plugin add phonegap-plugin-push -``` -or - -``` -cordova plugin add phonegap-plugin-push -``` - -It is also possible to install via repo url directly ( unstable ) - -``` -phonegap plugin add https://github.com/phonegap/phonegap-plugin-push -``` - -or - -``` -cordova plugin add https://github.com/phonegap/phonegap-plugin-push -``` - -## Supported Platforms - -- Android -- iOS -- Windows Universal - -## Quick Example - -```javascript - var push = PushNotification.init({ "android": {"senderID": "12345679"}, - "ios": {"alert": "true", "badge": "true", "sound": "true"}, "windows": {} } ); - - push.on('registration', function(data) { - // data.registrationId - }); - - push.on('notification', function(data) { - // data.message, - // data.title, - // data.count, - // data.sound, - // data.image, - // data.additionalData - }); - - push.on('error', function(e) { - // e.message - }); -``` - -## API - -### PushNotification.init(options) - -Parameter | Description ---------- | ------------ -`options` | `JSON Object` platform specific initialization options. -`options.android` | `JSON Object` Android specific initialization options. -`options.android.senderID` | `String` Maps to the project number in the Google Developer Console. -`options.android.icon` | `String` Optional. The name of a drawable resource to use as the small-icon. -`options.android.iconColor` | `String` Optional. Sets the background color of the small icon on Android 5.0 and greater. [Supported Formats](http://developer.android.com/reference/android/graphics/Color.html#parseColor(java.lang.String)) -`options.android.sound` | `Boolean` Optional. If `true` it plays the sound specified in the push data or the default system sound. Default is `true`. -`options.android.vibrate` | `Boolean` Optional. If `true` the device vibrates on receipt of notification. Default is `true`. -`options.android.clearNotifications` | `Boolean` Optional. If `true` the app clears all pending notifications when it is closed. Default is `true`. -`options.ios` | `JSON Object` iOS specific initialization options. -`options.ios.alert` | `Boolean` Optional. If `true` the device shows an alert on receipt of notification. Default is `false`. -`options.ios.badge` | `Boolean` Optional. If `true` the device sets the badge number on receipt of notification. Default is `false`. -`options.ios.sound` | `Boolean` Optional. If `true` the device plays a sound on receipt of notification. Default is `false`. -`options.windows` | `JSON Object` Windows specific initialization options. - -#### Returns - -- Instance of `PushNotification`. - -#### Example - -```javascript - var push = PushNotification.init({ "android": {"senderID": "12345679"}, - "ios": {"alert": "true", "badge": "true", "sound": "true"}, "windows": {} } ); -``` - -### push.on(event, callback) - -Parameter | Description ---------- | ------------ -`event` | `String` Name of the event to listen to. See below for all the event names. -`callback` | `Function` is called when the event is triggered. - -### push.on('registration', callback) - -The event `registration` will be triggered on each successful registration with the 3rd party push service. - -Callback Parameter | Description ------------------- | ----------- -`data.registrationId` | `String` The registration ID provided by the 3rd party remote push service. - -#### Example - -```javascript -push.on('registration', function(data) { - // data.registrationId -}); -``` - -### push.on('notification', callback) - -The event `notification` will be triggered each time a push notification is received by a 3rd party push service on the device. - -Callback Parameter | Description ------------------- | ----------- -`data.message` | `String` The text of the push message sent from the 3rd party service. -`data.title` | `String` The optional title of the push message sent from the 3rd party service. -`data.count` | `String` The number of messages to be displayed in the badge iOS or message count in the notification shade in Android. For windows, it represents the value in the badge notification which could be a number or a status glyph. -`data.sound` | `String` The name of the sound file to be played upon receipt of the notification. -`data.image` | `String` The path of the image file to be displayed in the notification. -`data.additionalData` | `JSON Object` An optional collection of data sent by the 3rd party push service that does not fit in the above properties. -`data.additionalData.foreground` | `Boolean` Whether the notification was received while the app was in the foreground - -#### Example - -```javascript - push.on('notification', function(data) { - // data.message, - // data.title, - // data.count, - // data.sound, - // data.image, - // data.additionalData - }); -``` - -### push.on('error', callback) - -The event `error` will trigger when an internal error occurs and the cache is aborted. - -Callback Parameter | Description ------------------- | ----------- -`e` | `Error` Standard JavaScript error object that describes the error. - -#### Example - -```javascript -push.on('error', function(e) { - // e.message -}); -``` - -### push.unregister(successHandler, errorHandler) - -The unregister method is used when the application no longer wants to receive push notifications. - -#### Example - -```javascript -push.unregister(successHandler, errorHandler); -``` - -### push.setApplicationIconBadgeNumber(successHandler, errorHandler, count) - iOS only - -Set the badge count visible when the app is not running - -The `count` is an integer indicating what number should show up in the badge. Passing 0 will clear the badge. Each `notification` event contains a `data.count` value which can be used to set the badge to correct number. - -#### Example - -```javascript -push.setApplicationIconBadgeNumber(successHandler, errorHandler, count); -``` - -## PhoneGap Build Support - -Including this plugin in a project that is built by PhoneGap Build is as easy as adding: - -``` -<gap:plugin name="phonegap-plugin-push" source="npm" /> -``` - -into your apps `config.xml` file. PhoneGap Build will pick up the latest version of phonegap-plugin-push published on npm. If you want to specify a particular version of the plugin you can add the `version` attribute to the `gap` tag. - -``` -<gap:plugin name="phonegap-plugin-push" source="npm" version="1.2.3" /> -``` - -Note: version 1.3.0 of this plugin begins to use Gradle to install the Android Support Framework. Gradle is not yet supported on PhoneGap Build so please use version 1.2.3 when building your app on PhoneGap Build. - -## Android Behaviour - -### Images - -By default the icon displayed in your push notification will be your apps icon. So when you initialize the plugin like this: - -```javascript - var push = PushNotification.init({ "android": {"senderID": "12345679"}, - "ios": {"alert": "true", "badge": "true", "sound": "true"}, "windows": {} } ); -``` - -The result will look much like this: - - - -This is because Android now uses Material design and the default icon for push will be completely white. - -In order to get a better user experience you can specify an alternate icon and background color to be shown when receiving a push notification. The code would look like this: - -```javascript - var push = PushNotification.init({ - "android": { - "senderID": "123456789", "icon": "phonegap", "iconColor": "blue"}, - "ios": {"alert": "true", "badge": "true", "sound": "true"}, "windows": {} - }); -``` - -Where *icon* is the name of an image in the Android *drawables* folder. Writing a hook to describe how to copy an image to the Android *drawables* folder is out of scope for this README but there is an [excellent tutorial](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/) that you can copy. - -*iconColor* is one of the supported formats #RRGGBB or #AARRGGBB or one of the following names: 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', 'yellow', 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', 'aqua', 'fuchsia', 'lime', 'maroon', 'navy', 'olive', 'purple', 'silver', 'teal'. *iconColor* is supported on Android 5.0 and greater. - -Please follow the [Android icon design guidelines](https://www.google.com/design/spec/style/icons.html#) when creating your icon. - - - -Additionally, each push can include a large icon which is used to personalize each push. The location of the image may one of three types. - -The first is the *drawables* folder in your app. This JSON sent from GCM: - -```javascript -{ - title:"Large Icon", - message: "Loaded from drawables folder", - image: "twitter" -} -``` - -Would look for the *twitter* image in the drawables folder and produce the following notification. - - - -The second is the *assets* folder in your app. This JSON sent from GCM: - -```javascript -{ - title:"Large Icon", - message: "Loaded from assets folder", - image: "www/image/logo.png" -} -``` - -Would look for the *logo.png* file in the assets/www/img folder. Since your apps www folder gets copied into the Android assets folder it is an excellent spot to store the images without needing to write a hook to copy them to the *drawables* folder. It produces the following notification. - - - - -The third is the remote *URL*. This JSON sent from GCM: - -```javascript -{ - title:"Large Icon", - message: "Loaded from URL", - image: "https://dl.dropboxusercontent.com/u/887989/antshot.png" -} -``` - -Produces the following notification. - - - -### Sound - -In order for your your notification to play a custom sound you will need to add the files to your Android project's `res/raw` directory. Then send the follow JSON from GCM: - -```javascript -{ - title:"Sound Test", - message: "Loaded res/raw", - soundname: "test" -} -``` - -*Note:* when you specify the custom sound file name omit the file's extension. - -### Stacking - -By default when using this plugin on Android each notification that your app receives will replace the previous notification in the shade. - -If you want to see multiple notifications in the shade you will need to provide a notification ID as part of the push data sent to the app. For instance if you send: - -```javascript -{ - title: "Test Push", - message: "Push number 1" -} -``` - -Followed by: - -```javascript -{ - title: "Test Push", - message: "Push number 2" -} -``` - -You will only see "Push number 2" in the shade. However, if you send: - -```javascript -{ - title: "Test Push", - message: "Push number 1", - notId: 1 -} -``` - -and: - -```javascript -{ - title: "Test Push", - message: "Push number 2", - notId: 2 -} -``` - -You will only see both "Push number 1" and "Push number 2" in the shade. - -### Inbox Stacking ### - -A better alternative to stacking your notifications is to use the inbox style to have up to 8 lines of notification text in a single notification. If you send the following JSON from GCM you will see: - -```javascript -{ - title:"My Title", - message: "My first message", - style: "inbox", - summaryText: "There are %n% notifications" -} -``` - -It will produce a normal looking notification: - - - -But, if you follow it up with subsequent notifications like: - -```javascript -{ - title:"My Title", - message: "My second message", - style: "inbox", - summaryText: "There are %n% notifications" -} -``` - -You will get an inbox view so you can display multiple notifications in a single panel. - - - -If you use `%n%` in the `summaryText` of the JSON coming down from GCM it will be replaced by the number of messages that are currently in the queue. - -### Action Buttons - -Your notification can include action buttons. If you wish to include an icon along with the button name they must be placed in the `res/drawable` directory of your Android project. Then you can send the following JSON from GCM: - -```javascript -{ - title:"AUX Scrum", - message: "Scrum: Daily touchbase @ 10am Please be on time so we can cover everything on the agenda.", - actions: [ - { icon: "emailGuests", title: "EMAIL GUESTS", callback: "app.emailGuests"}, - { icon: "snooze", title: "SNOOZE", callback: "app.snooze"}, - ] -} -``` - -This will produce the following notification in your tray: - - - -If your users clicks on the main body of the notification your app will be opened. However if they click on either of the action buttons the app will open (or start) and the specified JavaScript callback will be executed. In this case it is `app.emailGuests` and `app.snooze` respectively. - -### Led in Notifications - -You can use a Led notifcation and choose the color of it. Just add a `ledColor` field in your notification in the ARGB format array: - -```javascript -{ - title:"Green LED", - message: "This is my message with a Green LED", - ledColor: [0, 0, 255, 0] -} -``` - -### Vibration Pattern in Notifications - -You can set a Vibration Pattern for your notifications. Just add a `vibrationPattern` field in your notification: - -```javascript -{ - title:"Vibration Pattern", - message: "Device should wait for 2 seconds, vibrate for 1 second then be silent for 500 ms then vibrate for 500 ms", - vibrationPattern: [2000, 1000, 500, 500] -} -``` - -### Priority in Notifications - -You can set a priority parameter for your notifications. Just add a `priority` field in your notification. -2: minimum, -1: low, 0: default , 1: high, 2: maximum priority: - -```javascript -{ - title:"This is a maximum priority Notification", - message: "This notification should appear in front of all others", - priority: 2 -} -``` - -### Picture Messages - -Perhaps you want to include a large picture in the notification that you are sending to your users. Luckily you can do that too buy sending the following JSON from GCM. - -```javascript -{ - title:"Big Picture", - message: "This is my big picture message", - style: "picture", - picture: "http://36.media.tumblr.com/c066cc2238103856c9ac506faa6f3bc2/tumblr_nmstmqtuo81tssmyno1_1280.jpg", - summaryText: "The internet is built on cat pictures" -} -``` - -This will produce the following notification in your tray: - - - -## iOS Behaviour - -### Sound - -In order for your your notification to play a custom sound you will need to add the files to root of your iOS project. The files must be in the proper format. See the [Local and Remote Notification Programming Guide](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html#//apple_ref/doc/uid/TP40008194-CH103-SW6) for more info on proper file formats and how to convert existing sound files. - -Then send the follow JSON from APNS: - -```javascript -{ - "aps": { - "alert": "Test sound", - "sound": "sub.caf" - } -} -``` - -## Windows Behaviour - -###Notifications - -The plugin supports all types of windows platform notifications namely [Tile, Toast, Badge and Raw](https://msdn.microsoft.com/en-us/library/windows/apps/Hh779725.aspx). The API supports the basic cases of the notification templates with title corresponding to the first text element and message corresponding to the second if title is present else the first one. The image corresponds to the first image element of the notification xml. - -The count is present only for the badge notification in which it represent the value of the notification which could be a number from 0-99 or a status glyph. - -For advanced templates and usage, the notification object is included in [`data.additionalData.pushNotificationReceivedEventArgs`](https://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.pushnotifications.pushnotificationreceivedeventargs). - -### Setting Toast Capable Option for Windows - -This plugin automatically sets the toast capable flag to be true for Cordova 5.1.1+. For lower versions, you must declare that it is Toast Capable in your app's manifest file. - -### Disabling the default processing of notifications by Windows - -The default handling can be disabled by setting the 'cancel' property in the notification object. - -``` -data.additionalData.pushNotificationReceivedEventArgs.cancel = true -``` - -## Native Requirements - -- There should be no dependency on any other plugins. -- All platforms should use the same API! - -## Running Tests - -``` -npm test -``` - -## Contributing - -### Editor Config - -The project uses [.editorconfig](http://editorconfig.org/) to define the coding -style of each file. We recommend that you install the Editor Config extension -for your preferred IDE. - -### JSHint - -The project uses [.jshint](http://jshint.com/docs) to define the JavaScript -coding conventions. Most editors now have a JSHint add-on to provide on-save -or on-edit linting. - -#### Install JSHint for vim - -1. Install [jshint](https://www.npmjs.com/package/jshint). -1. Install [jshint.vim](https://github.com/wookiehangover/jshint.vim). - -#### Install JSHint for Sublime - -1. Install [Package Control](https://packagecontrol.io/installation) -1. Restart Sublime -1. Type `CMD+SHIFT+P` -1. Type _Install Package_ -1. Type _JSHint Gutter_ -1. Sublime -> Preferences -> Package Settings -> JSHint Gutter -1. Set `lint_on_load` and `lint_on_save` to `true` diff --git a/plugins/phonegap-plugin-push/example/server/pushADM.js b/plugins/phonegap-plugin-push/example/server/pushADM.js deleted file mode 100644 index 746e4ac8..00000000 --- a/plugins/phonegap-plugin-push/example/server/pushADM.js +++ /dev/null @@ -1,158 +0,0 @@ - - - -// Client ID and Client Secret received from ADM -// For more info, see: https://developer.amazon.com/public/apis/engage/device-messaging/tech-docs/02-obtaining-adm-credentials -var CLIENT_ID = "amzn1.application-oa2-client.8e838f6629554e26ae3f43a6c663cd60"; -var CLIENT_SECRET = "0af96083320f5d70dc4f358cc783ac65a22e78b297ba257df34d5f723f24543f"; - -// Registration ID, received on device after it registers with ADM server -var REGISTRATION_IDS = ["amzn1.adm-registration.v2.Y29tLmFtYXpvbi5EZXZpY2VNZXNzYWdpbmcuUmVnaXN0cmF0aW9uSWRFbmNyeXB0aW9uS2V5ITEhOE9rZ2h5TXlhVEFFczg2ejNWL3JMcmhTa255Uk5BclhBbE1XMFZzcnU1aFF6cTlvdU5FbVEwclZmdk5oTFBVRXVDN1luQlRSNnRVRUViREdQSlBvSzRNaXVRRUlyUy9NYWZCYS9VWTJUaGZwb3ZVTHhlRTM0MGhvampBK01hVktsMEhxakdmQStOSXRjUXBTQUhNU1NlVVVUVkFreVRhRTBCYktaQ2ZkUFdqSmIwcHgzRDhMQnllVXdxQ2EwdHNXRmFVNklYL0U4UXovcHg0K3Jjb25VbVFLRUVVOFVabnh4RDhjYmtIcHd1ZThiekorbGtzR2taMG95cC92Y3NtZytrcTRPNjhXUUpiZEk3QzFvQThBRTFWWXM2NHkyMjdYVGV5RlhhMWNHS0k9IW5GNEJMSXNleC9xbWpHSU52NnczY0E9PQ"]; - -// Message payload to be sent to client -var payload = { - data: { - message: "PushPlugin works!!", - sound: "beep.wav", - url: "http://www.amazon.com", - timeStamp: new Date().toISOString(), - foo: "baz" - }, - consolidationKey: "my app", - expiresAfter: 3600 -}; - - -//********************************* - - -var https = require("https"); -var querystring = require("querystring"); - - -if(CLIENT_ID == "" || CLIENT_SECRET == "" || REGISTRATION_IDS.length == 0){ - console.log("******************\nSetup Error: \nYou need to edit the pushADM.js file and enter your ADM credentials and device registration ID(s).\n******************"); - process.exit(1); -} - - -// Get access token from server, and use it to post message to device -getAccessToken(function(accessToken){ - - for(var i = 0; i < REGISTRATION_IDS.length; i++){ - - var registrationID = REGISTRATION_IDS[i]; - - postMessage(accessToken, registrationID, payload); - } - -}); - - - - -// Query OAuth server for access token -// For more info, see: https://developer.amazon.com/public/apis/engage/device-messaging/tech-docs/05-requesting-an-access-token - -function getAccessToken(callback){ - - console.log("Requesting access token from server..."); - - var credentials = { - scope: "messaging:push", - grant_type: "client_credentials", - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET - } - - var post_data = querystring.stringify(credentials); - - var post_options = { - host: "api.amazon.com", - port: "443", - path: "/auth/O2/token", - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" - } - }; - - var req = https.request(post_options, function(res) { - - var data = ""; - - res.on("data", function (chunk) { - data += chunk; - }); - - res.on("end", function() { - console.log("\nAccess token response:", data); - var accessToken = JSON.parse(data).access_token; - callback(accessToken); - }); - - }); - - req.on("error", function(e) { - console.log("\nProblem with access token request: ", e.message); - }); - - req.write(post_data); - req.end(); - -} - - -// Post message payload to ADM server -// For more info, see: https://developer.amazon.com/public/apis/engage/device-messaging/tech-docs/06-sending-a-message - -function postMessage(accessToken, registrationID, payload){ - - if(accessToken == undefined || registrationID == undefined || payload == undefined){ - return; - } - - console.log("\nSending message..."); - - var post_data = JSON.stringify(payload); - - var api_path = "/messaging/registrations/" + registrationID + "/messages"; - - var post_options = { - host: "api.amazon.com", - port: "443", - path: api_path, - method: "POST", - headers: { - "Authorization": "Bearer " + accessToken, - "X-Amzn-Type-Version": "com.amazon.device.messaging.ADMMessage@1.0", - "X-Amzn-Accept-Type" : "com.amazon.device.messaging.ADMSendResult@1.0", - "Content-Type": "application/json", - "Accept": "application/json", - } - }; - - var req = https.request(post_options, function(res) { - - var data = ""; - - res.on("data", function (chunk) { - data += chunk; - }); - - res.on("end", function() { - console.log("\nSend message response: ", data); - }); - - }); - - req.on("error", function(e) { - console.log("\nProblem with send message request: ", e.message); - }); - - req.write(post_data); - req.end(); - -} - - diff --git a/plugins/phonegap-plugin-push/example/server/pushAPNS.rb b/plugins/phonegap-plugin-push/example/server/pushAPNS.rb deleted file mode 100644 index 45a69a7d..00000000 --- a/plugins/phonegap-plugin-push/example/server/pushAPNS.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'rubygems' -require 'pushmeup' - - -APNS.host = 'gateway.sandbox.push.apple.com' -APNS.port = 2195 -APNS.pem = '</path/to/my/certificate/ck.pem>' -APNS.pass = '<myCertificatePassword>' - -device_token = '<device token gleaned from xcode console>' -# APNS.send_notification(device_token, 'Hello iPhone!' ) -APNS.send_notification(device_token, :alert => 'PushPlugin works!!', :badge => 1, :sound => 'beep.wav') diff --git a/plugins/phonegap-plugin-push/example/server/pushGCM.rb b/plugins/phonegap-plugin-push/example/server/pushGCM.rb deleted file mode 100644 index e1efce5e..00000000 --- a/plugins/phonegap-plugin-push/example/server/pushGCM.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'rubygems' -require 'pushmeup' -GCM.host = 'https://android.googleapis.com/gcm/send' -GCM.format = :json -GCM.key = "API_KEY_GOES_HERE" -destination = ["REGISTRATION_ID_GOES_HERE"] -data = {:message => "PhoneGap Build rocks!", :msgcnt => "1", :soundname => "beep.wav"} - -GCM.send_notification( destination, data) diff --git a/plugins/phonegap-plugin-push/example/www/beep.wav b/plugins/phonegap-plugin-push/example/www/beep.wav Binary files differdeleted file mode 100644 index bdadf530..00000000 --- a/plugins/phonegap-plugin-push/example/www/beep.wav +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/css/index.css b/plugins/phonegap-plugin-push/example/www/css/index.css deleted file mode 100644 index 51daa797..00000000 --- a/plugins/phonegap-plugin-push/example/www/css/index.css +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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. - */ -* { - -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */ -} - -body { - -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ - -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ - -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */ - background-color:#E4E4E4; - background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); - background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); - background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); - background-image:-webkit-gradient( - linear, - left top, - left bottom, - color-stop(0, #A7A7A7), - color-stop(0.51, #E4E4E4) - ); - background-attachment:fixed; - font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif; - font-size:12px; - height:100%; - margin:0px; - padding:0px; - text-transform:uppercase; - width:100%; -} - -/* Portrait layout (default) */ -.app { - background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */ - position:absolute; /* position in the center of the screen */ - left:50%; - top:50%; - height:50px; /* text area height */ - width:225px; /* text area width */ - text-align:center; - padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */ - margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */ - /* offset horizontal: half of text area width */ -} - -/* Landscape layout (with min-width) */ -@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) { - .app { - background-position:left center; - padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */ - margin:-90px 0px 0px -198px; /* offset vertical: half of image height */ - /* offset horizontal: half of image width and text area width */ - } -} - -h1 { - font-size:24px; - font-weight:normal; - margin:0px; - overflow:visible; - padding:0px; - text-align:center; -} - -.event { - border-radius:4px; - -webkit-border-radius:4px; - color:#FFFFFF; - font-size:12px; - margin:0px 30px; - padding:2px 0px; -} - -.event.listening { - background-color:#333333; - display:block; -} - -.event.received { - background-color:#4B946A; - display:none; -} - -@keyframes fade { - from { opacity: 1.0; } - 50% { opacity: 0.4; } - to { opacity: 1.0; } -} - -@-webkit-keyframes fade { - from { opacity: 1.0; } - 50% { opacity: 0.4; } - to { opacity: 1.0; } -} - -.blink { - animation:fade 3000ms infinite; - -webkit-animation:fade 3000ms infinite; -} diff --git a/plugins/phonegap-plugin-push/example/www/css/materialize.min.css b/plugins/phonegap-plugin-push/example/www/css/materialize.min.css deleted file mode 100644 index e956485c..00000000 --- a/plugins/phonegap-plugin-push/example/www/css/materialize.min.css +++ /dev/null @@ -1,16 +0,0 @@ -/*! - * Materialize v0.96.1 (http://materializecss.com) - * Copyright 2014-2015 Materialize - * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) - */ -.materialize-red.lighten-5{background-color:#fdeaeb !important}.materialize-red-text.text-lighten-5{color:#fdeaeb !important}.materialize-red.lighten-4{background-color:#f8c1c3 !important}.materialize-red-text.text-lighten-4{color:#f8c1c3 !important}.materialize-red.lighten-3{background-color:#f3989b !important}.materialize-red-text.text-lighten-3{color:#f3989b !important}.materialize-red.lighten-2{background-color:#ee6e73 !important}.materialize-red-text.text-lighten-2{color:#ee6e73 !important}.materialize-red.lighten-1{background-color:#ea454b !important}.materialize-red-text.text-lighten-1{color:#ea454b !important}.materialize-red{background-color:#e51c23 !important}.materialize-red-text{color:#e51c23 !important}.materialize-red.darken-1{background-color:#d0181e !important}.materialize-red-text.text-darken-1{color:#d0181e !important}.materialize-red.darken-2{background-color:#b9151b !important}.materialize-red-text.text-darken-2{color:#b9151b !important}.materialize-red.darken-3{background-color:#a21318 !important}.materialize-red-text.text-darken-3{color:#a21318 !important}.materialize-red.darken-4{background-color:#8b1014 !important}.materialize-red-text.text-darken-4{color:#8b1014 !important}.red.lighten-5{background-color:#FFEBEE !important}.red-text.text-lighten-5{color:#FFEBEE !important}.red.lighten-4{background-color:#FFCDD2 !important}.red-text.text-lighten-4{color:#FFCDD2 !important}.red.lighten-3{background-color:#EF9A9A !important}.red-text.text-lighten-3{color:#EF9A9A !important}.red.lighten-2{background-color:#E57373 !important}.red-text.text-lighten-2{color:#E57373 !important}.red.lighten-1{background-color:#EF5350 !important}.red-text.text-lighten-1{color:#EF5350 !important}.red{background-color:#F44336 !important}.red-text{color:#F44336 !important}.red.darken-1{background-color:#E53935 !important}.red-text.text-darken-1{color:#E53935 !important}.red.darken-2{background-color:#D32F2F !important}.red-text.text-darken-2{color:#D32F2F !important}.red.darken-3{background-color:#C62828 !important}.red-text.text-darken-3{color:#C62828 !important}.red.darken-4{background-color:#B71C1C !important}.red-text.text-darken-4{color:#B71C1C !important}.red.accent-1{background-color:#FF8A80 !important}.red-text.text-accent-1{color:#FF8A80 !important}.red.accent-2{background-color:#FF5252 !important}.red-text.text-accent-2{color:#FF5252 !important}.red.accent-3{background-color:#FF1744 !important}.red-text.text-accent-3{color:#FF1744 !important}.red.accent-4{background-color:#D50000 !important}.red-text.text-accent-4{color:#D50000 !important}.pink.lighten-5{background-color:#fce4ec !important}.pink-text.text-lighten-5{color:#fce4ec !important}.pink.lighten-4{background-color:#f8bbd0 !important}.pink-text.text-lighten-4{color:#f8bbd0 !important}.pink.lighten-3{background-color:#f48fb1 !important}.pink-text.text-lighten-3{color:#f48fb1 !important}.pink.lighten-2{background-color:#f06292 !important}.pink-text.text-lighten-2{color:#f06292 !important}.pink.lighten-1{background-color:#ec407a !important}.pink-text.text-lighten-1{color:#ec407a !important}.pink{background-color:#e91e63 !important}.pink-text{color:#e91e63 !important}.pink.darken-1{background-color:#d81b60 !important}.pink-text.text-darken-1{color:#d81b60 !important}.pink.darken-2{background-color:#c2185b !important}.pink-text.text-darken-2{color:#c2185b !important}.pink.darken-3{background-color:#ad1457 !important}.pink-text.text-darken-3{color:#ad1457 !important}.pink.darken-4{background-color:#880e4f !important}.pink-text.text-darken-4{color:#880e4f !important}.pink.accent-1{background-color:#ff80ab !important}.pink-text.text-accent-1{color:#ff80ab !important}.pink.accent-2{background-color:#ff4081 !important}.pink-text.text-accent-2{color:#ff4081 !important}.pink.accent-3{background-color:#f50057 !important}.pink-text.text-accent-3{color:#f50057 !important}.pink.accent-4{background-color:#c51162 !important}.pink-text.text-accent-4{color:#c51162 !important}.purple.lighten-5{background-color:#f3e5f5 !important}.purple-text.text-lighten-5{color:#f3e5f5 !important}.purple.lighten-4{background-color:#e1bee7 !important}.purple-text.text-lighten-4{color:#e1bee7 !important}.purple.lighten-3{background-color:#ce93d8 !important}.purple-text.text-lighten-3{color:#ce93d8 !important}.purple.lighten-2{background-color:#ba68c8 !important}.purple-text.text-lighten-2{color:#ba68c8 !important}.purple.lighten-1{background-color:#ab47bc !important}.purple-text.text-lighten-1{color:#ab47bc !important}.purple{background-color:#9c27b0 !important}.purple-text{color:#9c27b0 !important}.purple.darken-1{background-color:#8e24aa !important}.purple-text.text-darken-1{color:#8e24aa !important}.purple.darken-2{background-color:#7b1fa2 !important}.purple-text.text-darken-2{color:#7b1fa2 !important}.purple.darken-3{background-color:#6a1b9a !important}.purple-text.text-darken-3{color:#6a1b9a !important}.purple.darken-4{background-color:#4a148c !important}.purple-text.text-darken-4{color:#4a148c !important}.purple.accent-1{background-color:#ea80fc !important}.purple-text.text-accent-1{color:#ea80fc !important}.purple.accent-2{background-color:#e040fb !important}.purple-text.text-accent-2{color:#e040fb !important}.purple.accent-3{background-color:#d500f9 !important}.purple-text.text-accent-3{color:#d500f9 !important}.purple.accent-4{background-color:#aa00ff !important}.purple-text.text-accent-4{color:#aa00ff !important}.deep-purple.lighten-5{background-color:#ede7f6 !important}.deep-purple-text.text-lighten-5{color:#ede7f6 !important}.deep-purple.lighten-4{background-color:#d1c4e9 !important}.deep-purple-text.text-lighten-4{color:#d1c4e9 !important}.deep-purple.lighten-3{background-color:#b39ddb !important}.deep-purple-text.text-lighten-3{color:#b39ddb !important}.deep-purple.lighten-2{background-color:#9575cd !important}.deep-purple-text.text-lighten-2{color:#9575cd !important}.deep-purple.lighten-1{background-color:#7e57c2 !important}.deep-purple-text.text-lighten-1{color:#7e57c2 !important}.deep-purple{background-color:#673ab7 !important}.deep-purple-text{color:#673ab7 !important}.deep-purple.darken-1{background-color:#5e35b1 !important}.deep-purple-text.text-darken-1{color:#5e35b1 !important}.deep-purple.darken-2{background-color:#512da8 !important}.deep-purple-text.text-darken-2{color:#512da8 !important}.deep-purple.darken-3{background-color:#4527a0 !important}.deep-purple-text.text-darken-3{color:#4527a0 !important}.deep-purple.darken-4{background-color:#311b92 !important}.deep-purple-text.text-darken-4{color:#311b92 !important}.deep-purple.accent-1{background-color:#b388ff !important}.deep-purple-text.text-accent-1{color:#b388ff !important}.deep-purple.accent-2{background-color:#7c4dff !important}.deep-purple-text.text-accent-2{color:#7c4dff !important}.deep-purple.accent-3{background-color:#651fff !important}.deep-purple-text.text-accent-3{color:#651fff !important}.deep-purple.accent-4{background-color:#6200ea !important}.deep-purple-text.text-accent-4{color:#6200ea !important}.indigo.lighten-5{background-color:#e8eaf6 !important}.indigo-text.text-lighten-5{color:#e8eaf6 !important}.indigo.lighten-4{background-color:#c5cae9 !important}.indigo-text.text-lighten-4{color:#c5cae9 !important}.indigo.lighten-3{background-color:#9fa8da !important}.indigo-text.text-lighten-3{color:#9fa8da !important}.indigo.lighten-2{background-color:#7986cb !important}.indigo-text.text-lighten-2{color:#7986cb !important}.indigo.lighten-1{background-color:#5c6bc0 !important}.indigo-text.text-lighten-1{color:#5c6bc0 !important}.indigo{background-color:#3f51b5 !important}.indigo-text{color:#3f51b5 !important}.indigo.darken-1{background-color:#3949ab !important}.indigo-text.text-darken-1{color:#3949ab !important}.indigo.darken-2{background-color:#303f9f !important}.indigo-text.text-darken-2{color:#303f9f !important}.indigo.darken-3{background-color:#283593 !important}.indigo-text.text-darken-3{color:#283593 !important}.indigo.darken-4{background-color:#1a237e !important}.indigo-text.text-darken-4{color:#1a237e !important}.indigo.accent-1{background-color:#8c9eff !important}.indigo-text.text-accent-1{color:#8c9eff !important}.indigo.accent-2{background-color:#536dfe !important}.indigo-text.text-accent-2{color:#536dfe !important}.indigo.accent-3{background-color:#3d5afe !important}.indigo-text.text-accent-3{color:#3d5afe !important}.indigo.accent-4{background-color:#304ffe !important}.indigo-text.text-accent-4{color:#304ffe !important}.blue.lighten-5{background-color:#E3F2FD !important}.blue-text.text-lighten-5{color:#E3F2FD !important}.blue.lighten-4{background-color:#BBDEFB !important}.blue-text.text-lighten-4{color:#BBDEFB !important}.blue.lighten-3{background-color:#90CAF9 !important}.blue-text.text-lighten-3{color:#90CAF9 !important}.blue.lighten-2{background-color:#64B5F6 !important}.blue-text.text-lighten-2{color:#64B5F6 !important}.blue.lighten-1{background-color:#42A5F5 !important}.blue-text.text-lighten-1{color:#42A5F5 !important}.blue{background-color:#2196F3 !important}.blue-text{color:#2196F3 !important}.blue.darken-1{background-color:#1E88E5 !important}.blue-text.text-darken-1{color:#1E88E5 !important}.blue.darken-2{background-color:#1976D2 !important}.blue-text.text-darken-2{color:#1976D2 !important}.blue.darken-3{background-color:#1565C0 !important}.blue-text.text-darken-3{color:#1565C0 !important}.blue.darken-4{background-color:#0D47A1 !important}.blue-text.text-darken-4{color:#0D47A1 !important}.blue.accent-1{background-color:#82B1FF !important}.blue-text.text-accent-1{color:#82B1FF !important}.blue.accent-2{background-color:#448AFF !important}.blue-text.text-accent-2{color:#448AFF !important}.blue.accent-3{background-color:#2979FF !important}.blue-text.text-accent-3{color:#2979FF !important}.blue.accent-4{background-color:#2962FF !important}.blue-text.text-accent-4{color:#2962FF !important}.light-blue.lighten-5{background-color:#e1f5fe !important}.light-blue-text.text-lighten-5{color:#e1f5fe !important}.light-blue.lighten-4{background-color:#b3e5fc !important}.light-blue-text.text-lighten-4{color:#b3e5fc !important}.light-blue.lighten-3{background-color:#81d4fa !important}.light-blue-text.text-lighten-3{color:#81d4fa !important}.light-blue.lighten-2{background-color:#4fc3f7 !important}.light-blue-text.text-lighten-2{color:#4fc3f7 !important}.light-blue.lighten-1{background-color:#29b6f6 !important}.light-blue-text.text-lighten-1{color:#29b6f6 !important}.light-blue{background-color:#03a9f4 !important}.light-blue-text{color:#03a9f4 !important}.light-blue.darken-1{background-color:#039be5 !important}.light-blue-text.text-darken-1{color:#039be5 !important}.light-blue.darken-2{background-color:#0288d1 !important}.light-blue-text.text-darken-2{color:#0288d1 !important}.light-blue.darken-3{background-color:#0277bd !important}.light-blue-text.text-darken-3{color:#0277bd !important}.light-blue.darken-4{background-color:#01579b !important}.light-blue-text.text-darken-4{color:#01579b !important}.light-blue.accent-1{background-color:#80d8ff !important}.light-blue-text.text-accent-1{color:#80d8ff !important}.light-blue.accent-2{background-color:#40c4ff !important}.light-blue-text.text-accent-2{color:#40c4ff !important}.light-blue.accent-3{background-color:#00b0ff !important}.light-blue-text.text-accent-3{color:#00b0ff !important}.light-blue.accent-4{background-color:#0091ea !important}.light-blue-text.text-accent-4{color:#0091ea !important}.cyan.lighten-5{background-color:#e0f7fa !important}.cyan-text.text-lighten-5{color:#e0f7fa !important}.cyan.lighten-4{background-color:#b2ebf2 !important}.cyan-text.text-lighten-4{color:#b2ebf2 !important}.cyan.lighten-3{background-color:#80deea !important}.cyan-text.text-lighten-3{color:#80deea !important}.cyan.lighten-2{background-color:#4dd0e1 !important}.cyan-text.text-lighten-2{color:#4dd0e1 !important}.cyan.lighten-1{background-color:#26c6da !important}.cyan-text.text-lighten-1{color:#26c6da !important}.cyan{background-color:#00bcd4 !important}.cyan-text{color:#00bcd4 !important}.cyan.darken-1{background-color:#00acc1 !important}.cyan-text.text-darken-1{color:#00acc1 !important}.cyan.darken-2{background-color:#0097a7 !important}.cyan-text.text-darken-2{color:#0097a7 !important}.cyan.darken-3{background-color:#00838f !important}.cyan-text.text-darken-3{color:#00838f !important}.cyan.darken-4{background-color:#006064 !important}.cyan-text.text-darken-4{color:#006064 !important}.cyan.accent-1{background-color:#84ffff !important}.cyan-text.text-accent-1{color:#84ffff !important}.cyan.accent-2{background-color:#18ffff !important}.cyan-text.text-accent-2{color:#18ffff !important}.cyan.accent-3{background-color:#00e5ff !important}.cyan-text.text-accent-3{color:#00e5ff !important}.cyan.accent-4{background-color:#00b8d4 !important}.cyan-text.text-accent-4{color:#00b8d4 !important}.teal.lighten-5{background-color:#e0f2f1 !important}.teal-text.text-lighten-5{color:#e0f2f1 !important}.teal.lighten-4{background-color:#b2dfdb !important}.teal-text.text-lighten-4{color:#b2dfdb !important}.teal.lighten-3{background-color:#80cbc4 !important}.teal-text.text-lighten-3{color:#80cbc4 !important}.teal.lighten-2{background-color:#4db6ac !important}.teal-text.text-lighten-2{color:#4db6ac !important}.teal.lighten-1{background-color:#26a69a !important}.teal-text.text-lighten-1{color:#26a69a !important}.teal{background-color:#009688 !important}.teal-text{color:#009688 !important}.teal.darken-1{background-color:#00897b !important}.teal-text.text-darken-1{color:#00897b !important}.teal.darken-2{background-color:#00796b !important}.teal-text.text-darken-2{color:#00796b !important}.teal.darken-3{background-color:#00695c !important}.teal-text.text-darken-3{color:#00695c !important}.teal.darken-4{background-color:#004d40 !important}.teal-text.text-darken-4{color:#004d40 !important}.teal.accent-1{background-color:#a7ffeb !important}.teal-text.text-accent-1{color:#a7ffeb !important}.teal.accent-2{background-color:#64ffda !important}.teal-text.text-accent-2{color:#64ffda !important}.teal.accent-3{background-color:#1de9b6 !important}.teal-text.text-accent-3{color:#1de9b6 !important}.teal.accent-4{background-color:#00bfa5 !important}.teal-text.text-accent-4{color:#00bfa5 !important}.green.lighten-5{background-color:#E8F5E9 !important}.green-text.text-lighten-5{color:#E8F5E9 !important}.green.lighten-4{background-color:#C8E6C9 !important}.green-text.text-lighten-4{color:#C8E6C9 !important}.green.lighten-3{background-color:#A5D6A7 !important}.green-text.text-lighten-3{color:#A5D6A7 !important}.green.lighten-2{background-color:#81C784 !important}.green-text.text-lighten-2{color:#81C784 !important}.green.lighten-1{background-color:#66BB6A !important}.green-text.text-lighten-1{color:#66BB6A !important}.green{background-color:#4CAF50 !important}.green-text{color:#4CAF50 !important}.green.darken-1{background-color:#43A047 !important}.green-text.text-darken-1{color:#43A047 !important}.green.darken-2{background-color:#388E3C !important}.green-text.text-darken-2{color:#388E3C !important}.green.darken-3{background-color:#2E7D32 !important}.green-text.text-darken-3{color:#2E7D32 !important}.green.darken-4{background-color:#1B5E20 !important}.green-text.text-darken-4{color:#1B5E20 !important}.green.accent-1{background-color:#B9F6CA !important}.green-text.text-accent-1{color:#B9F6CA !important}.green.accent-2{background-color:#69F0AE !important}.green-text.text-accent-2{color:#69F0AE !important}.green.accent-3{background-color:#00E676 !important}.green-text.text-accent-3{color:#00E676 !important}.green.accent-4{background-color:#00C853 !important}.green-text.text-accent-4{color:#00C853 !important}.light-green.lighten-5{background-color:#f1f8e9 !important}.light-green-text.text-lighten-5{color:#f1f8e9 !important}.light-green.lighten-4{background-color:#dcedc8 !important}.light-green-text.text-lighten-4{color:#dcedc8 !important}.light-green.lighten-3{background-color:#c5e1a5 !important}.light-green-text.text-lighten-3{color:#c5e1a5 !important}.light-green.lighten-2{background-color:#aed581 !important}.light-green-text.text-lighten-2{color:#aed581 !important}.light-green.lighten-1{background-color:#9ccc65 !important}.light-green-text.text-lighten-1{color:#9ccc65 !important}.light-green{background-color:#8bc34a !important}.light-green-text{color:#8bc34a !important}.light-green.darken-1{background-color:#7cb342 !important}.light-green-text.text-darken-1{color:#7cb342 !important}.light-green.darken-2{background-color:#689f38 !important}.light-green-text.text-darken-2{color:#689f38 !important}.light-green.darken-3{background-color:#558b2f !important}.light-green-text.text-darken-3{color:#558b2f !important}.light-green.darken-4{background-color:#33691e !important}.light-green-text.text-darken-4{color:#33691e !important}.light-green.accent-1{background-color:#ccff90 !important}.light-green-text.text-accent-1{color:#ccff90 !important}.light-green.accent-2{background-color:#b2ff59 !important}.light-green-text.text-accent-2{color:#b2ff59 !important}.light-green.accent-3{background-color:#76ff03 !important}.light-green-text.text-accent-3{color:#76ff03 !important}.light-green.accent-4{background-color:#64dd17 !important}.light-green-text.text-accent-4{color:#64dd17 !important}.lime.lighten-5{background-color:#f9fbe7 !important}.lime-text.text-lighten-5{color:#f9fbe7 !important}.lime.lighten-4{background-color:#f0f4c3 !important}.lime-text.text-lighten-4{color:#f0f4c3 !important}.lime.lighten-3{background-color:#e6ee9c !important}.lime-text.text-lighten-3{color:#e6ee9c !important}.lime.lighten-2{background-color:#dce775 !important}.lime-text.text-lighten-2{color:#dce775 !important}.lime.lighten-1{background-color:#d4e157 !important}.lime-text.text-lighten-1{color:#d4e157 !important}.lime{background-color:#cddc39 !important}.lime-text{color:#cddc39 !important}.lime.darken-1{background-color:#c0ca33 !important}.lime-text.text-darken-1{color:#c0ca33 !important}.lime.darken-2{background-color:#afb42b !important}.lime-text.text-darken-2{color:#afb42b !important}.lime.darken-3{background-color:#9e9d24 !important}.lime-text.text-darken-3{color:#9e9d24 !important}.lime.darken-4{background-color:#827717 !important}.lime-text.text-darken-4{color:#827717 !important}.lime.accent-1{background-color:#f4ff81 !important}.lime-text.text-accent-1{color:#f4ff81 !important}.lime.accent-2{background-color:#eeff41 !important}.lime-text.text-accent-2{color:#eeff41 !important}.lime.accent-3{background-color:#c6ff00 !important}.lime-text.text-accent-3{color:#c6ff00 !important}.lime.accent-4{background-color:#aeea00 !important}.lime-text.text-accent-4{color:#aeea00 !important}.yellow.lighten-5{background-color:#fffde7 !important}.yellow-text.text-lighten-5{color:#fffde7 !important}.yellow.lighten-4{background-color:#fff9c4 !important}.yellow-text.text-lighten-4{color:#fff9c4 !important}.yellow.lighten-3{background-color:#fff59d !important}.yellow-text.text-lighten-3{color:#fff59d !important}.yellow.lighten-2{background-color:#fff176 !important}.yellow-text.text-lighten-2{color:#fff176 !important}.yellow.lighten-1{background-color:#ffee58 !important}.yellow-text.text-lighten-1{color:#ffee58 !important}.yellow{background-color:#ffeb3b !important}.yellow-text{color:#ffeb3b !important}.yellow.darken-1{background-color:#fdd835 !important}.yellow-text.text-darken-1{color:#fdd835 !important}.yellow.darken-2{background-color:#fbc02d !important}.yellow-text.text-darken-2{color:#fbc02d !important}.yellow.darken-3{background-color:#f9a825 !important}.yellow-text.text-darken-3{color:#f9a825 !important}.yellow.darken-4{background-color:#f57f17 !important}.yellow-text.text-darken-4{color:#f57f17 !important}.yellow.accent-1{background-color:#ffff8d !important}.yellow-text.text-accent-1{color:#ffff8d !important}.yellow.accent-2{background-color:#ffff00 !important}.yellow-text.text-accent-2{color:#ffff00 !important}.yellow.accent-3{background-color:#ffea00 !important}.yellow-text.text-accent-3{color:#ffea00 !important}.yellow.accent-4{background-color:#ffd600 !important}.yellow-text.text-accent-4{color:#ffd600 !important}.amber.lighten-5{background-color:#fff8e1 !important}.amber-text.text-lighten-5{color:#fff8e1 !important}.amber.lighten-4{background-color:#ffecb3 !important}.amber-text.text-lighten-4{color:#ffecb3 !important}.amber.lighten-3{background-color:#ffe082 !important}.amber-text.text-lighten-3{color:#ffe082 !important}.amber.lighten-2{background-color:#ffd54f !important}.amber-text.text-lighten-2{color:#ffd54f !important}.amber.lighten-1{background-color:#ffca28 !important}.amber-text.text-lighten-1{color:#ffca28 !important}.amber{background-color:#ffc107 !important}.amber-text{color:#ffc107 !important}.amber.darken-1{background-color:#ffb300 !important}.amber-text.text-darken-1{color:#ffb300 !important}.amber.darken-2{background-color:#ffa000 !important}.amber-text.text-darken-2{color:#ffa000 !important}.amber.darken-3{background-color:#ff8f00 !important}.amber-text.text-darken-3{color:#ff8f00 !important}.amber.darken-4{background-color:#ff6f00 !important}.amber-text.text-darken-4{color:#ff6f00 !important}.amber.accent-1{background-color:#ffe57f !important}.amber-text.text-accent-1{color:#ffe57f !important}.amber.accent-2{background-color:#ffd740 !important}.amber-text.text-accent-2{color:#ffd740 !important}.amber.accent-3{background-color:#ffc400 !important}.amber-text.text-accent-3{color:#ffc400 !important}.amber.accent-4{background-color:#ffab00 !important}.amber-text.text-accent-4{color:#ffab00 !important}.orange.lighten-5{background-color:#fff3e0 !important}.orange-text.text-lighten-5{color:#fff3e0 !important}.orange.lighten-4{background-color:#ffe0b2 !important}.orange-text.text-lighten-4{color:#ffe0b2 !important}.orange.lighten-3{background-color:#ffcc80 !important}.orange-text.text-lighten-3{color:#ffcc80 !important}.orange.lighten-2{background-color:#ffb74d !important}.orange-text.text-lighten-2{color:#ffb74d !important}.orange.lighten-1{background-color:#ffa726 !important}.orange-text.text-lighten-1{color:#ffa726 !important}.orange{background-color:#ff9800 !important}.orange-text{color:#ff9800 !important}.orange.darken-1{background-color:#fb8c00 !important}.orange-text.text-darken-1{color:#fb8c00 !important}.orange.darken-2{background-color:#f57c00 !important}.orange-text.text-darken-2{color:#f57c00 !important}.orange.darken-3{background-color:#ef6c00 !important}.orange-text.text-darken-3{color:#ef6c00 !important}.orange.darken-4{background-color:#e65100 !important}.orange-text.text-darken-4{color:#e65100 !important}.orange.accent-1{background-color:#ffd180 !important}.orange-text.text-accent-1{color:#ffd180 !important}.orange.accent-2{background-color:#ffab40 !important}.orange-text.text-accent-2{color:#ffab40 !important}.orange.accent-3{background-color:#ff9100 !important}.orange-text.text-accent-3{color:#ff9100 !important}.orange.accent-4{background-color:#ff6d00 !important}.orange-text.text-accent-4{color:#ff6d00 !important}.deep-orange.lighten-5{background-color:#fbe9e7 !important}.deep-orange-text.text-lighten-5{color:#fbe9e7 !important}.deep-orange.lighten-4{background-color:#ffccbc !important}.deep-orange-text.text-lighten-4{color:#ffccbc !important}.deep-orange.lighten-3{background-color:#ffab91 !important}.deep-orange-text.text-lighten-3{color:#ffab91 !important}.deep-orange.lighten-2{background-color:#ff8a65 !important}.deep-orange-text.text-lighten-2{color:#ff8a65 !important}.deep-orange.lighten-1{background-color:#ff7043 !important}.deep-orange-text.text-lighten-1{color:#ff7043 !important}.deep-orange{background-color:#ff5722 !important}.deep-orange-text{color:#ff5722 !important}.deep-orange.darken-1{background-color:#f4511e !important}.deep-orange-text.text-darken-1{color:#f4511e !important}.deep-orange.darken-2{background-color:#e64a19 !important}.deep-orange-text.text-darken-2{color:#e64a19 !important}.deep-orange.darken-3{background-color:#d84315 !important}.deep-orange-text.text-darken-3{color:#d84315 !important}.deep-orange.darken-4{background-color:#bf360c !important}.deep-orange-text.text-darken-4{color:#bf360c !important}.deep-orange.accent-1{background-color:#ff9e80 !important}.deep-orange-text.text-accent-1{color:#ff9e80 !important}.deep-orange.accent-2{background-color:#ff6e40 !important}.deep-orange-text.text-accent-2{color:#ff6e40 !important}.deep-orange.accent-3{background-color:#ff3d00 !important}.deep-orange-text.text-accent-3{color:#ff3d00 !important}.deep-orange.accent-4{background-color:#dd2c00 !important}.deep-orange-text.text-accent-4{color:#dd2c00 !important}.brown.lighten-5{background-color:#efebe9 !important}.brown-text.text-lighten-5{color:#efebe9 !important}.brown.lighten-4{background-color:#d7ccc8 !important}.brown-text.text-lighten-4{color:#d7ccc8 !important}.brown.lighten-3{background-color:#bcaaa4 !important}.brown-text.text-lighten-3{color:#bcaaa4 !important}.brown.lighten-2{background-color:#a1887f !important}.brown-text.text-lighten-2{color:#a1887f !important}.brown.lighten-1{background-color:#8d6e63 !important}.brown-text.text-lighten-1{color:#8d6e63 !important}.brown{background-color:#795548 !important}.brown-text{color:#795548 !important}.brown.darken-1{background-color:#6d4c41 !important}.brown-text.text-darken-1{color:#6d4c41 !important}.brown.darken-2{background-color:#5d4037 !important}.brown-text.text-darken-2{color:#5d4037 !important}.brown.darken-3{background-color:#4e342e !important}.brown-text.text-darken-3{color:#4e342e !important}.brown.darken-4{background-color:#3e2723 !important}.brown-text.text-darken-4{color:#3e2723 !important}.blue-grey.lighten-5{background-color:#eceff1 !important}.blue-grey-text.text-lighten-5{color:#eceff1 !important}.blue-grey.lighten-4{background-color:#cfd8dc !important}.blue-grey-text.text-lighten-4{color:#cfd8dc !important}.blue-grey.lighten-3{background-color:#b0bec5 !important}.blue-grey-text.text-lighten-3{color:#b0bec5 !important}.blue-grey.lighten-2{background-color:#90a4ae !important}.blue-grey-text.text-lighten-2{color:#90a4ae !important}.blue-grey.lighten-1{background-color:#78909c !important}.blue-grey-text.text-lighten-1{color:#78909c !important}.blue-grey{background-color:#607d8b !important}.blue-grey-text{color:#607d8b !important}.blue-grey.darken-1{background-color:#546e7a !important}.blue-grey-text.text-darken-1{color:#546e7a !important}.blue-grey.darken-2{background-color:#455a64 !important}.blue-grey-text.text-darken-2{color:#455a64 !important}.blue-grey.darken-3{background-color:#37474f !important}.blue-grey-text.text-darken-3{color:#37474f !important}.blue-grey.darken-4{background-color:#263238 !important}.blue-grey-text.text-darken-4{color:#263238 !important}.grey.lighten-5{background-color:#fafafa !important}.grey-text.text-lighten-5{color:#fafafa !important}.grey.lighten-4{background-color:#f5f5f5 !important}.grey-text.text-lighten-4{color:#f5f5f5 !important}.grey.lighten-3{background-color:#eeeeee !important}.grey-text.text-lighten-3{color:#eeeeee !important}.grey.lighten-2{background-color:#e0e0e0 !important}.grey-text.text-lighten-2{color:#e0e0e0 !important}.grey.lighten-1{background-color:#bdbdbd !important}.grey-text.text-lighten-1{color:#bdbdbd !important}.grey{background-color:#9e9e9e !important}.grey-text{color:#9e9e9e !important}.grey.darken-1{background-color:#757575 !important}.grey-text.text-darken-1{color:#757575 !important}.grey.darken-2{background-color:#616161 !important}.grey-text.text-darken-2{color:#616161 !important}.grey.darken-3{background-color:#424242 !important}.grey-text.text-darken-3{color:#424242 !important}.grey.darken-4{background-color:#212121 !important}.grey-text.text-darken-4{color:#212121 !important}.shades.black{background-color:#000000 !important}.shades-text.text-black{color:#000000 !important}.shades.white{background-color:#FFFFFF !important}.shades-text.text-white{color:#FFFFFF !important}.shades.transparent{background-color:transparent !important}.shades-text.text-transparent{color:transparent !important}.black{background-color:#000000 !important}.black-text{color:#000000 !important}.white{background-color:#FFFFFF !important}.white-text{color:#FFFFFF !important}.transparent{background-color:transparent !important}.transparent-text{color:transparent !important}/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}html input[type="button"],button,input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit}ul{list-style-type:none}a{color:#039be5;text-decoration:none;-webkit-tap-highlight-color:transparent}.valign-wrapper{display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-flex-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center}.valign-wrapper .valign{display:block}ul{padding:0}ul li{list-style-type:none}.clearfix{clear:both}.z-depth-1,nav,.card-panel,.card,.toast,.btn,.btn-large,.btn-floating,.dropdown-content,.collapsible,.side-nav{-webkit-box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);-moz-box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)}.z-depth-1-half,.btn:hover,.btn-large:hover,.btn-floating:hover{-webkit-box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);-moz-box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15)}.z-depth-2{-webkit-box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);-moz-box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);box-shadow:0 8px 17px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)}.z-depth-3{-webkit-box-shadow:0 12px 15px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);-moz-box-shadow:0 12px 15px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);box-shadow:0 12px 15px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19)}.z-depth-4,.modal{-webkit-box-shadow:0 16px 28px 0 rgba(0,0,0,0.22),0 25px 55px 0 rgba(0,0,0,0.21);-moz-box-shadow:0 16px 28px 0 rgba(0,0,0,0.22),0 25px 55px 0 rgba(0,0,0,0.21);box-shadow:0 16px 28px 0 rgba(0,0,0,0.22),0 25px 55px 0 rgba(0,0,0,0.21)}.z-depth-5{-webkit-box-shadow:0 27px 24px 0 rgba(0,0,0,0.2),0 40px 77px 0 rgba(0,0,0,0.22);-moz-box-shadow:0 27px 24px 0 rgba(0,0,0,0.2),0 40px 77px 0 rgba(0,0,0,0.22);box-shadow:0 27px 24px 0 rgba(0,0,0,0.2),0 40px 77px 0 rgba(0,0,0,0.22)}.divider{height:1px;overflow:hidden;background-color:#e0e0e0}blockquote{margin:20px 0;padding-left:1.5rem;border-left:5px solid #EF9A9A}i{line-height:inherit}i.left{float:left;margin-right:15px}i.right{float:right;margin-left:15px}i.tiny{font-size:1rem}i.small{font-size:2rem}i.medium{font-size:4rem}i.large{font-size:6rem}img.responsive-img,video.responsive-video{max-width:100%;height:auto}.pagination li{font-size:1.2rem;float:left;width:30px;height:30px;margin:0 10px;border-radius:2px;text-align:center}.pagination li a{color:#444}.pagination li.active a{color:#fff}.pagination li.active{background-color:#ee6e73}.pagination li.disabled a{color:#999}.pagination li i{font-size:2rem;line-height:1.8rem}.parallax-container{position:relative;overflow:hidden;height:500px}.parallax{position:absolute;top:0;left:0;right:0;bottom:0;z-index:-1}.parallax img{display:none;position:absolute;left:50%;bottom:0;min-width:100%;min-height:100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);transform:translateX(-50%)}.pin-top,.pin-bottom{position:relative}.pinned{position:fixed !important}ul.staggered-list li{opacity:0}.fade-in{opacity:0;transform-origin:0 50%}@media only screen and (max-width : 600px){.hide-on-small-only,.hide-on-small-and-down{display:none !important;}}@media only screen and (max-width : 992px){.hide-on-med-and-down{display:none !important;}}@media only screen and (min-width : 601px){.hide-on-med-and-up{display:none !important;}}@media only screen and (min-width: 600px) and (max-width: 992px){.hide-on-med-only{display:none !important;}}@media only screen and (min-width : 993px){.hide-on-large-only{display:none !important;}}@media only screen and (min-width : 993px){.show-on-large{display:initial !important;}}@media only screen and (min-width: 600px) and (max-width: 992px){.show-on-medium{display:initial !important;}}@media only screen and (max-width : 600px){.show-on-small{display:initial !important;}}@media only screen and (min-width : 601px){.show-on-medium-and-up{display:initial !important;}}@media only screen and (max-width : 992px){.show-on-medium-and-down{display:initial !important;}}@media only screen and (max-width : 600px){.center-on-small-only{text-align:center;}}footer.page-footer{margin-top:20px;padding-top:20px;background-color:#ee6e73}footer.page-footer .footer-copyright{overflow:hidden;height:50px;line-height:50px;color:rgba(255,255,255,0.8);background-color:rgba(51,51,51,0.08)}table,th,td{border:none}table{width:100%;display:table}table.bordered tr{border-bottom:1px solid #d0d0d0}table.striped tbody tr:nth-child(odd){background-color:#f2f2f2}table.hoverable tbody tr{-webkit-transition:background-color .25s ease;-moz-transition:background-color .25s ease;-o-transition:background-color .25s ease;-ms-transition:background-color .25s ease;transition:background-color .25s ease}table.hoverable tbody tr:hover{background-color:#f2f2f2}table.centered thead tr th,table.centered tbody tr td{text-align:center}thead{border-bottom:1px solid #d0d0d0}td,th{padding:15px 5px;display:table-cell;text-align:left;vertical-align:middle;border-radius:2px}@media only screen and (max-width : 992px){table.responsive-table{width:100%;border-collapse:collapse;border-spacing:0;display:block;position:relative}table.responsive-table th,table.responsive-table td{margin:0;vertical-align:top}table.responsive-table th{text-align:left}table.responsive-table thead{display:block;float:left}table.responsive-table thead tr{display:block;padding:0 10px 0 0}table.responsive-table thead tr th::before{content:"\00a0"}table.responsive-table tbody{display:block;width:auto;position:relative;overflow-x:auto;white-space:nowrap}table.responsive-table tbody tr{display:inline-block;vertical-align:top}table.responsive-table th{display:block;text-align:right}table.responsive-table td{display:block;min-height:1.25em;text-align:left}table.responsive-table tr{padding:0 10px}table.responsive-table thead{border:0;border-right:1px solid #d0d0d0}table.responsive-table.bordered th{border-bottom:0;border-left:0}table.responsive-table.bordered td{border-left:0;border-right:0;border-bottom:0}table.responsive-table.bordered tr{border:0}table.responsive-table.bordered tbody tr{border-right:1px solid #d0d0d0}}.collection{margin:0.5rem 0 1rem 0;border:1px solid #e0e0e0;border-radius:2px;overflow:hidden;position:relative}.collection .collection-item{background-color:#fff;line-height:1.5rem;padding:10px 20px;margin:0;border-bottom:1px solid #e0e0e0}.collection .collection-item.avatar{height:84px;padding-left:72px;position:relative}.collection .collection-item.avatar .circle{position:absolute;width:42px;height:42px;overflow:hidden;left:15px;display:inline-block;vertical-align:middle}.collection .collection-item.avatar i.circle{font-size:18px;line-height:42px;color:#fff;background-color:#999;text-align:center}.collection .collection-item.avatar .title{font-size:16px}.collection .collection-item.avatar p{margin:0}.collection .collection-item.avatar .secondary-content{position:absolute;top:16px;right:16px}.collection .collection-item:last-child{border-bottom:none}.collection .collection-item.active{background-color:#26a69a;color:#eafaf9}.collection a.collection-item{display:block;-webkit-transition:0.25s;-moz-transition:0.25s;-o-transition:0.25s;-ms-transition:0.25s;transition:0.25s;color:#26a69a}.collection a.collection-item:not(.active):hover{background-color:#ddd}.collection.with-header .collection-header{background-color:#fff;border-bottom:1px solid #e0e0e0;padding:10px 20px}.collection.with-header .collection-item{padding-left:30px}.secondary-content{float:right;color:#26a69a}span.badge{min-width:3rem;padding:0 6px;text-align:center;font-size:1rem;line-height:inherit;color:#757575;position:absolute;right:15px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}span.badge.new{font-weight:300;font-size:0.8rem;color:#fff;background-color:#26a69a;border-radius:2px}span.badge.new:after{content:" new"}.video-container{position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden}.video-container.no-controls{padding-top:0}.video-container iframe,.video-container object,.video-container embed{position:absolute;top:0;left:0;width:100%;height:100%}.progress{position:relative;height:4px;display:block;width:100%;background-color:#acece6;border-radius:2px;margin:0.5rem 0 1rem 0;overflow:hidden}.progress .determinate{position:absolute;background-color:inherit;top:0;bottom:0;background-color:#26a69a;-webkit-transition:width .3s linear;-moz-transition:width .3s linear;-o-transition:width .3s linear;-ms-transition:width .3s linear;transition:width .3s linear}.progress .indeterminate{background-color:#26a69a}.progress .indeterminate:before{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;-moz-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;-ms-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;-o-animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;animation:indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite}.progress .indeterminate:after{content:'';position:absolute;background-color:inherit;top:0;left:0;bottom:0;will-change:left, right;-webkit-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-moz-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-ms-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-o-animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;animation:indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;-webkit-animation-delay:1.15s;-moz-animation-delay:1.15s;-ms-animation-delay:1.15s;-o-animation-delay:1.15s;animation-delay:1.15s}@-webkit-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-moz-keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@keyframes indeterminate{0%{left:-35%;right:100%}60%{left:100%;right:-90%}100%{left:100%;right:-90%}}@-webkit-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@-moz-keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}@keyframes indeterminate-short{0%{left:-200%;right:100%}60%{left:107%;right:-8%}100%{left:107%;right:-8%}}.hide{display:none !important}.left-align{text-align:left}.right-align{text-align:right}.center,.center-align{text-align:center}.left{float:left !important}.right{float:right !important}.no-select,input[type=range],input[type=range]+.thumb{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.circle{border-radius:50%}.center-block{display:block;margin-left:auto;margin-right:auto}.truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.no-padding{padding:0 !important}@font-face{font-family:"Material-Design-Icons";src:url("../font/material-design-icons/Material-Design-Icons.eot?#iefix") format("embedded-opentype"),url("../font/material-design-icons/Material-Design-Icons.woff2") format("woff2"),url("../font/material-design-icons/Material-Design-Icons.woff") format("woff"),url("../font/material-design-icons/Material-Design-Icons.ttf") format("truetype"),url("../font/material-design-icons/Material-Design-Icons.svg#Material-Design-Icons") format("svg");font-weight:normal;font-style:normal;}[class^="mdi-"],[class*=" mdi-"]{font-family:"Material-Design-Icons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.mdi-action-3d-rotation:before{content:"\e600"}.mdi-action-accessibility:before{content:"\e601"}.mdi-action-account-balance:before{content:"\e602"}.mdi-action-account-balance-wallet:before{content:"\e603"}.mdi-action-account-box:before{content:"\e604"}.mdi-action-account-child:before{content:"\e605"}.mdi-action-account-circle:before{content:"\e606"}.mdi-action-add-shopping-cart:before{content:"\e607"}.mdi-action-alarm:before{content:"\e608"}.mdi-action-alarm-add:before{content:"\e609"}.mdi-action-alarm-off:before{content:"\e60a"}.mdi-action-alarm-on:before{content:"\e60b"}.mdi-action-android:before{content:"\e60c"}.mdi-action-announcement:before{content:"\e60d"}.mdi-action-aspect-ratio:before{content:"\e60e"}.mdi-action-assessment:before{content:"\e60f"}.mdi-action-assignment:before{content:"\e610"}.mdi-action-assignment-ind:before{content:"\e611"}.mdi-action-assignment-late:before{content:"\e612"}.mdi-action-assignment-return:before{content:"\e613"}.mdi-action-assignment-returned:before{content:"\e614"}.mdi-action-assignment-turned-in:before{content:"\e615"}.mdi-action-autorenew:before{content:"\e616"}.mdi-action-backup:before{content:"\e617"}.mdi-action-book:before{content:"\e618"}.mdi-action-bookmark:before{content:"\e619"}.mdi-action-bookmark-outline:before{content:"\e61a"}.mdi-action-bug-report:before{content:"\e61b"}.mdi-action-cached:before{content:"\e61c"}.mdi-action-class:before{content:"\e61d"}.mdi-action-credit-card:before{content:"\e61e"}.mdi-action-dashboard:before{content:"\e61f"}.mdi-action-delete:before{content:"\e620"}.mdi-action-description:before{content:"\e621"}.mdi-action-dns:before{content:"\e622"}.mdi-action-done:before{content:"\e623"}.mdi-action-done-all:before{content:"\e624"}.mdi-action-event:before{content:"\e625"}.mdi-action-exit-to-app:before{content:"\e626"}.mdi-action-explore:before{content:"\e627"}.mdi-action-extension:before{content:"\e628"}.mdi-action-face-unlock:before{content:"\e629"}.mdi-action-favorite:before{content:"\e62a"}.mdi-action-favorite-outline:before{content:"\e62b"}.mdi-action-find-in-page:before{content:"\e62c"}.mdi-action-find-replace:before{content:"\e62d"}.mdi-action-flip-to-back:before{content:"\e62e"}.mdi-action-flip-to-front:before{content:"\e62f"}.mdi-action-get-app:before{content:"\e630"}.mdi-action-grade:before{content:"\e631"}.mdi-action-group-work:before{content:"\e632"}.mdi-action-help:before{content:"\e633"}.mdi-action-highlight-remove:before{content:"\e634"}.mdi-action-history:before{content:"\e635"}.mdi-action-home:before{content:"\e636"}.mdi-action-https:before{content:"\e637"}.mdi-action-info:before{content:"\e638"}.mdi-action-info-outline:before{content:"\e639"}.mdi-action-input:before{content:"\e63a"}.mdi-action-invert-colors:before{content:"\e63b"}.mdi-action-label:before{content:"\e63c"}.mdi-action-label-outline:before{content:"\e63d"}.mdi-action-language:before{content:"\e63e"}.mdi-action-launch:before{content:"\e63f"}.mdi-action-list:before{content:"\e640"}.mdi-action-lock:before{content:"\e641"}.mdi-action-lock-open:before{content:"\e642"}.mdi-action-lock-outline:before{content:"\e643"}.mdi-action-loyalty:before{content:"\e644"}.mdi-action-markunread-mailbox:before{content:"\e645"}.mdi-action-note-add:before{content:"\e646"}.mdi-action-open-in-browser:before{content:"\e647"}.mdi-action-open-in-new:before{content:"\e648"}.mdi-action-open-with:before{content:"\e649"}.mdi-action-pageview:before{content:"\e64a"}.mdi-action-payment:before{content:"\e64b"}.mdi-action-perm-camera-mic:before{content:"\e64c"}.mdi-action-perm-contact-cal:before{content:"\e64d"}.mdi-action-perm-data-setting:before{content:"\e64e"}.mdi-action-perm-device-info:before{content:"\e64f"}.mdi-action-perm-identity:before{content:"\e650"}.mdi-action-perm-media:before{content:"\e651"}.mdi-action-perm-phone-msg:before{content:"\e652"}.mdi-action-perm-scan-wifi:before{content:"\e653"}.mdi-action-picture-in-picture:before{content:"\e654"}.mdi-action-polymer:before{content:"\e655"}.mdi-action-print:before{content:"\e656"}.mdi-action-query-builder:before{content:"\e657"}.mdi-action-question-answer:before{content:"\e658"}.mdi-action-receipt:before{content:"\e659"}.mdi-action-redeem:before{content:"\e65a"}.mdi-action-report-problem:before{content:"\e65b"}.mdi-action-restore:before{content:"\e65c"}.mdi-action-room:before{content:"\e65d"}.mdi-action-schedule:before{content:"\e65e"}.mdi-action-search:before{content:"\e65f"}.mdi-action-settings:before{content:"\e660"}.mdi-action-settings-applications:before{content:"\e661"}.mdi-action-settings-backup-restore:before{content:"\e662"}.mdi-action-settings-bluetooth:before{content:"\e663"}.mdi-action-settings-cell:before{content:"\e664"}.mdi-action-settings-display:before{content:"\e665"}.mdi-action-settings-ethernet:before{content:"\e666"}.mdi-action-settings-input-antenna:before{content:"\e667"}.mdi-action-settings-input-component:before{content:"\e668"}.mdi-action-settings-input-composite:before{content:"\e669"}.mdi-action-settings-input-hdmi:before{content:"\e66a"}.mdi-action-settings-input-svideo:before{content:"\e66b"}.mdi-action-settings-overscan:before{content:"\e66c"}.mdi-action-settings-phone:before{content:"\e66d"}.mdi-action-settings-power:before{content:"\e66e"}.mdi-action-settings-remote:before{content:"\e66f"}.mdi-action-settings-voice:before{content:"\e670"}.mdi-action-shop:before{content:"\e671"}.mdi-action-shopping-basket:before{content:"\e672"}.mdi-action-shopping-cart:before{content:"\e673"}.mdi-action-shop-two:before{content:"\e674"}.mdi-action-speaker-notes:before{content:"\e675"}.mdi-action-spellcheck:before{content:"\e676"}.mdi-action-star-rate:before{content:"\e677"}.mdi-action-stars:before{content:"\e678"}.mdi-action-store:before{content:"\e679"}.mdi-action-subject:before{content:"\e67a"}.mdi-action-swap-horiz:before{content:"\e67b"}.mdi-action-swap-vert:before{content:"\e67c"}.mdi-action-swap-vert-circle:before{content:"\e67d"}.mdi-action-system-update-tv:before{content:"\e67e"}.mdi-action-tab:before{content:"\e67f"}.mdi-action-tab-unselected:before{content:"\e680"}.mdi-action-theaters:before{content:"\e681"}.mdi-action-thumb-down:before{content:"\e682"}.mdi-action-thumbs-up-down:before{content:"\e683"}.mdi-action-thumb-up:before{content:"\e684"}.mdi-action-toc:before{content:"\e685"}.mdi-action-today:before{content:"\e686"}.mdi-action-track-changes:before{content:"\e687"}.mdi-action-translate:before{content:"\e688"}.mdi-action-trending-down:before{content:"\e689"}.mdi-action-trending-neutral:before{content:"\e68a"}.mdi-action-trending-up:before{content:"\e68b"}.mdi-action-turned-in:before{content:"\e68c"}.mdi-action-turned-in-not:before{content:"\e68d"}.mdi-action-verified-user:before{content:"\e68e"}.mdi-action-view-agenda:before{content:"\e68f"}.mdi-action-view-array:before{content:"\e690"}.mdi-action-view-carousel:before{content:"\e691"}.mdi-action-view-column:before{content:"\e692"}.mdi-action-view-day:before{content:"\e693"}.mdi-action-view-headline:before{content:"\e694"}.mdi-action-view-list:before{content:"\e695"}.mdi-action-view-module:before{content:"\e696"}.mdi-action-view-quilt:before{content:"\e697"}.mdi-action-view-stream:before{content:"\e698"}.mdi-action-view-week:before{content:"\e699"}.mdi-action-visibility:before{content:"\e69a"}.mdi-action-visibility-off:before{content:"\e69b"}.mdi-action-wallet-giftcard:before{content:"\e69c"}.mdi-action-wallet-membership:before{content:"\e69d"}.mdi-action-wallet-travel:before{content:"\e69e"}.mdi-action-work:before{content:"\e69f"}.mdi-alert-error:before{content:"\e6a0"}.mdi-alert-warning:before{content:"\e6a1"}.mdi-av-album:before{content:"\e6a2"}.mdi-av-timer:before{content:"\e6a3"}.mdi-av-closed-caption:before{content:"\e6a4"}.mdi-av-equalizer:before{content:"\e6a5"}.mdi-av-explicit:before{content:"\e6a6"}.mdi-av-fast-forward:before{content:"\e6a7"}.mdi-av-fast-rewind:before{content:"\e6a8"}.mdi-av-games:before{content:"\e6a9"}.mdi-av-hearing:before{content:"\e6aa"}.mdi-av-high-quality:before{content:"\e6ab"}.mdi-av-loop:before{content:"\e6ac"}.mdi-av-mic:before{content:"\e6ad"}.mdi-av-mic-none:before{content:"\e6ae"}.mdi-av-mic-off:before{content:"\e6af"}.mdi-av-movie:before{content:"\e6b0"}.mdi-av-my-library-add:before{content:"\e6b1"}.mdi-av-my-library-books:before{content:"\e6b2"}.mdi-av-my-library-music:before{content:"\e6b3"}.mdi-av-new-releases:before{content:"\e6b4"}.mdi-av-not-interested:before{content:"\e6b5"}.mdi-av-pause:before{content:"\e6b6"}.mdi-av-pause-circle-fill:before{content:"\e6b7"}.mdi-av-pause-circle-outline:before{content:"\e6b8"}.mdi-av-play-arrow:before{content:"\e6b9"}.mdi-av-play-circle-fill:before{content:"\e6ba"}.mdi-av-play-circle-outline:before{content:"\e6bb"}.mdi-av-playlist-add:before{content:"\e6bc"}.mdi-av-play-shopping-bag:before{content:"\e6bd"}.mdi-av-queue:before{content:"\e6be"}.mdi-av-queue-music:before{content:"\e6bf"}.mdi-av-radio:before{content:"\e6c0"}.mdi-av-recent-actors:before{content:"\e6c1"}.mdi-av-repeat:before{content:"\e6c2"}.mdi-av-repeat-one:before{content:"\e6c3"}.mdi-av-replay:before{content:"\e6c4"}.mdi-av-shuffle:before{content:"\e6c5"}.mdi-av-skip-next:before{content:"\e6c6"}.mdi-av-skip-previous:before{content:"\e6c7"}.mdi-av-snooze:before{content:"\e6c8"}.mdi-av-stop:before{content:"\e6c9"}.mdi-av-subtitles:before{content:"\e6ca"}.mdi-av-surround-sound:before{content:"\e6cb"}.mdi-av-videocam:before{content:"\e6cc"}.mdi-av-videocam-off:before{content:"\e6cd"}.mdi-av-video-collection:before{content:"\e6ce"}.mdi-av-volume-down:before{content:"\e6cf"}.mdi-av-volume-mute:before{content:"\e6d0"}.mdi-av-volume-off:before{content:"\e6d1"}.mdi-av-volume-up:before{content:"\e6d2"}.mdi-av-web:before{content:"\e6d3"}.mdi-communication-business:before{content:"\e6d4"}.mdi-communication-call:before{content:"\e6d5"}.mdi-communication-call-end:before{content:"\e6d6"}.mdi-communication-call-made:before{content:"\e6d7"}.mdi-communication-call-merge:before{content:"\e6d8"}.mdi-communication-call-missed:before{content:"\e6d9"}.mdi-communication-call-received:before{content:"\e6da"}.mdi-communication-call-split:before{content:"\e6db"}.mdi-communication-chat:before{content:"\e6dc"}.mdi-communication-clear-all:before{content:"\e6dd"}.mdi-communication-comment:before{content:"\e6de"}.mdi-communication-contacts:before{content:"\e6df"}.mdi-communication-dialer-sip:before{content:"\e6e0"}.mdi-communication-dialpad:before{content:"\e6e1"}.mdi-communication-dnd-on:before{content:"\e6e2"}.mdi-communication-email:before{content:"\e6e3"}.mdi-communication-forum:before{content:"\e6e4"}.mdi-communication-import-export:before{content:"\e6e5"}.mdi-communication-invert-colors-off:before{content:"\e6e6"}.mdi-communication-invert-colors-on:before{content:"\e6e7"}.mdi-communication-live-help:before{content:"\e6e8"}.mdi-communication-location-off:before{content:"\e6e9"}.mdi-communication-location-on:before{content:"\e6ea"}.mdi-communication-message:before{content:"\e6eb"}.mdi-communication-messenger:before{content:"\e6ec"}.mdi-communication-no-sim:before{content:"\e6ed"}.mdi-communication-phone:before{content:"\e6ee"}.mdi-communication-portable-wifi-off:before{content:"\e6ef"}.mdi-communication-quick-contacts-dialer:before{content:"\e6f0"}.mdi-communication-quick-contacts-mail:before{content:"\e6f1"}.mdi-communication-ring-volume:before{content:"\e6f2"}.mdi-communication-stay-current-landscape:before{content:"\e6f3"}.mdi-communication-stay-current-portrait:before{content:"\e6f4"}.mdi-communication-stay-primary-landscape:before{content:"\e6f5"}.mdi-communication-stay-primary-portrait:before{content:"\e6f6"}.mdi-communication-swap-calls:before{content:"\e6f7"}.mdi-communication-textsms:before{content:"\e6f8"}.mdi-communication-voicemail:before{content:"\e6f9"}.mdi-communication-vpn-key:before{content:"\e6fa"}.mdi-content-add:before{content:"\e6fb"}.mdi-content-add-box:before{content:"\e6fc"}.mdi-content-add-circle:before{content:"\e6fd"}.mdi-content-add-circle-outline:before{content:"\e6fe"}.mdi-content-archive:before{content:"\e6ff"}.mdi-content-backspace:before{content:"\e700"}.mdi-content-block:before{content:"\e701"}.mdi-content-clear:before{content:"\e702"}.mdi-content-content-copy:before{content:"\e703"}.mdi-content-content-cut:before{content:"\e704"}.mdi-content-content-paste:before{content:"\e705"}.mdi-content-create:before{content:"\e706"}.mdi-content-drafts:before{content:"\e707"}.mdi-content-filter-list:before{content:"\e708"}.mdi-content-flag:before{content:"\e709"}.mdi-content-forward:before{content:"\e70a"}.mdi-content-gesture:before{content:"\e70b"}.mdi-content-inbox:before{content:"\e70c"}.mdi-content-link:before{content:"\e70d"}.mdi-content-mail:before{content:"\e70e"}.mdi-content-markunread:before{content:"\e70f"}.mdi-content-redo:before{content:"\e710"}.mdi-content-remove:before{content:"\e711"}.mdi-content-remove-circle:before{content:"\e712"}.mdi-content-remove-circle-outline:before{content:"\e713"}.mdi-content-reply:before{content:"\e714"}.mdi-content-reply-all:before{content:"\e715"}.mdi-content-report:before{content:"\e716"}.mdi-content-save:before{content:"\e717"}.mdi-content-select-all:before{content:"\e718"}.mdi-content-send:before{content:"\e719"}.mdi-content-sort:before{content:"\e71a"}.mdi-content-text-format:before{content:"\e71b"}.mdi-content-undo:before{content:"\e71c"}.mdi-device-access-alarm:before{content:"\e71d"}.mdi-device-access-alarms:before{content:"\e71e"}.mdi-device-access-time:before{content:"\e71f"}.mdi-device-add-alarm:before{content:"\e720"}.mdi-device-airplanemode-off:before{content:"\e721"}.mdi-device-airplanemode-on:before{content:"\e722"}.mdi-device-battery-20:before{content:"\e723"}.mdi-device-battery-30:before{content:"\e724"}.mdi-device-battery-50:before{content:"\e725"}.mdi-device-battery-60:before{content:"\e726"}.mdi-device-battery-80:before{content:"\e727"}.mdi-device-battery-90:before{content:"\e728"}.mdi-device-battery-alert:before{content:"\e729"}.mdi-device-battery-charging-20:before{content:"\e72a"}.mdi-device-battery-charging-30:before{content:"\e72b"}.mdi-device-battery-charging-50:before{content:"\e72c"}.mdi-device-battery-charging-60:before{content:"\e72d"}.mdi-device-battery-charging-80:before{content:"\e72e"}.mdi-device-battery-charging-90:before{content:"\e72f"}.mdi-device-battery-charging-full:before{content:"\e730"}.mdi-device-battery-full:before{content:"\e731"}.mdi-device-battery-std:before{content:"\e732"}.mdi-device-battery-unknown:before{content:"\e733"}.mdi-device-bluetooth:before{content:"\e734"}.mdi-device-bluetooth-connected:before{content:"\e735"}.mdi-device-bluetooth-disabled:before{content:"\e736"}.mdi-device-bluetooth-searching:before{content:"\e737"}.mdi-device-brightness-auto:before{content:"\e738"}.mdi-device-brightness-high:before{content:"\e739"}.mdi-device-brightness-low:before{content:"\e73a"}.mdi-device-brightness-medium:before{content:"\e73b"}.mdi-device-data-usage:before{content:"\e73c"}.mdi-device-developer-mode:before{content:"\e73d"}.mdi-device-devices:before{content:"\e73e"}.mdi-device-dvr:before{content:"\e73f"}.mdi-device-gps-fixed:before{content:"\e740"}.mdi-device-gps-not-fixed:before{content:"\e741"}.mdi-device-gps-off:before{content:"\e742"}.mdi-device-location-disabled:before{content:"\e743"}.mdi-device-location-searching:before{content:"\e744"}.mdi-device-multitrack-audio:before{content:"\e745"}.mdi-device-network-cell:before{content:"\e746"}.mdi-device-network-wifi:before{content:"\e747"}.mdi-device-nfc:before{content:"\e748"}.mdi-device-now-wallpaper:before{content:"\e749"}.mdi-device-now-widgets:before{content:"\e74a"}.mdi-device-screen-lock-landscape:before{content:"\e74b"}.mdi-device-screen-lock-portrait:before{content:"\e74c"}.mdi-device-screen-lock-rotation:before{content:"\e74d"}.mdi-device-screen-rotation:before{content:"\e74e"}.mdi-device-sd-storage:before{content:"\e74f"}.mdi-device-settings-system-daydream:before{content:"\e750"}.mdi-device-signal-cellular-0-bar:before{content:"\e751"}.mdi-device-signal-cellular-1-bar:before{content:"\e752"}.mdi-device-signal-cellular-2-bar:before{content:"\e753"}.mdi-device-signal-cellular-3-bar:before{content:"\e754"}.mdi-device-signal-cellular-4-bar:before{content:"\e755"}.mdi-device-signal-cellular-connected-no-internet-0-bar:before{content:"\e756"}.mdi-device-signal-cellular-connected-no-internet-1-bar:before{content:"\e757"}.mdi-device-signal-cellular-connected-no-internet-2-bar:before{content:"\e758"}.mdi-device-signal-cellular-connected-no-internet-3-bar:before{content:"\e759"}.mdi-device-signal-cellular-connected-no-internet-4-bar:before{content:"\e75a"}.mdi-device-signal-cellular-no-sim:before{content:"\e75b"}.mdi-device-signal-cellular-null:before{content:"\e75c"}.mdi-device-signal-cellular-off:before{content:"\e75d"}.mdi-device-signal-wifi-0-bar:before{content:"\e75e"}.mdi-device-signal-wifi-1-bar:before{content:"\e75f"}.mdi-device-signal-wifi-2-bar:before{content:"\e760"}.mdi-device-signal-wifi-3-bar:before{content:"\e761"}.mdi-device-signal-wifi-4-bar:before{content:"\e762"}.mdi-device-signal-wifi-off:before{content:"\e763"}.mdi-device-storage:before{content:"\e764"}.mdi-device-usb:before{content:"\e765"}.mdi-device-wifi-lock:before{content:"\e766"}.mdi-device-wifi-tethering:before{content:"\e767"}.mdi-editor-attach-file:before{content:"\e768"}.mdi-editor-attach-money:before{content:"\e769"}.mdi-editor-border-all:before{content:"\e76a"}.mdi-editor-border-bottom:before{content:"\e76b"}.mdi-editor-border-clear:before{content:"\e76c"}.mdi-editor-border-color:before{content:"\e76d"}.mdi-editor-border-horizontal:before{content:"\e76e"}.mdi-editor-border-inner:before{content:"\e76f"}.mdi-editor-border-left:before{content:"\e770"}.mdi-editor-border-outer:before{content:"\e771"}.mdi-editor-border-right:before{content:"\e772"}.mdi-editor-border-style:before{content:"\e773"}.mdi-editor-border-top:before{content:"\e774"}.mdi-editor-border-vertical:before{content:"\e775"}.mdi-editor-format-align-center:before{content:"\e776"}.mdi-editor-format-align-justify:before{content:"\e777"}.mdi-editor-format-align-left:before{content:"\e778"}.mdi-editor-format-align-right:before{content:"\e779"}.mdi-editor-format-bold:before{content:"\e77a"}.mdi-editor-format-clear:before{content:"\e77b"}.mdi-editor-format-color-fill:before{content:"\e77c"}.mdi-editor-format-color-reset:before{content:"\e77d"}.mdi-editor-format-color-text:before{content:"\e77e"}.mdi-editor-format-indent-decrease:before{content:"\e77f"}.mdi-editor-format-indent-increase:before{content:"\e780"}.mdi-editor-format-italic:before{content:"\e781"}.mdi-editor-format-line-spacing:before{content:"\e782"}.mdi-editor-format-list-bulleted:before{content:"\e783"}.mdi-editor-format-list-numbered:before{content:"\e784"}.mdi-editor-format-paint:before{content:"\e785"}.mdi-editor-format-quote:before{content:"\e786"}.mdi-editor-format-size:before{content:"\e787"}.mdi-editor-format-strikethrough:before{content:"\e788"}.mdi-editor-functions:before{content:"\e789"}.mdi-editor-format-textdirection-l-to-r:before{content:"\e78a"}.mdi-editor-format-underline:before{content:"\e78b"}.mdi-editor-format-textdirection-r-to-l:before{content:"\e78c"}.mdi-editor-insert-chart:before{content:"\e78d"}.mdi-editor-insert-comment:before{content:"\e78e"}.mdi-editor-insert-drive-file:before{content:"\e78f"}.mdi-editor-insert-emoticon:before{content:"\e790"}.mdi-editor-insert-invitation:before{content:"\e791"}.mdi-editor-insert-link:before{content:"\e792"}.mdi-editor-insert-photo:before{content:"\e793"}.mdi-editor-merge-type:before{content:"\e794"}.mdi-editor-mode-comment:before{content:"\e795"}.mdi-editor-mode-edit:before{content:"\e796"}.mdi-editor-publish:before{content:"\e797"}.mdi-editor-vertical-align-bottom:before{content:"\e798"}.mdi-editor-vertical-align-center:before{content:"\e799"}.mdi-editor-vertical-align-top:before{content:"\e79a"}.mdi-editor-wrap-text:before{content:"\e79b"}.mdi-file-attachment:before{content:"\e79c"}.mdi-file-cloud:before{content:"\e79d"}.mdi-file-cloud-circle:before{content:"\e79e"}.mdi-file-cloud-done:before{content:"\e79f"}.mdi-file-cloud-download:before{content:"\e7a0"}.mdi-file-cloud-off:before{content:"\e7a1"}.mdi-file-cloud-queue:before{content:"\e7a2"}.mdi-file-cloud-upload:before{content:"\e7a3"}.mdi-file-file-download:before{content:"\e7a4"}.mdi-file-file-upload:before{content:"\e7a5"}.mdi-file-folder:before{content:"\e7a6"}.mdi-file-folder-open:before{content:"\e7a7"}.mdi-file-folder-shared:before{content:"\e7a8"}.mdi-hardware-cast:before{content:"\e7a9"}.mdi-hardware-cast-connected:before{content:"\e7aa"}.mdi-hardware-computer:before{content:"\e7ab"}.mdi-hardware-desktop-mac:before{content:"\e7ac"}.mdi-hardware-desktop-windows:before{content:"\e7ad"}.mdi-hardware-dock:before{content:"\e7ae"}.mdi-hardware-gamepad:before{content:"\e7af"}.mdi-hardware-headset:before{content:"\e7b0"}.mdi-hardware-headset-mic:before{content:"\e7b1"}.mdi-hardware-keyboard:before{content:"\e7b2"}.mdi-hardware-keyboard-alt:before{content:"\e7b3"}.mdi-hardware-keyboard-arrow-down:before{content:"\e7b4"}.mdi-hardware-keyboard-arrow-left:before{content:"\e7b5"}.mdi-hardware-keyboard-arrow-right:before{content:"\e7b6"}.mdi-hardware-keyboard-arrow-up:before{content:"\e7b7"}.mdi-hardware-keyboard-backspace:before{content:"\e7b8"}.mdi-hardware-keyboard-capslock:before{content:"\e7b9"}.mdi-hardware-keyboard-control:before{content:"\e7ba"}.mdi-hardware-keyboard-hide:before{content:"\e7bb"}.mdi-hardware-keyboard-return:before{content:"\e7bc"}.mdi-hardware-keyboard-tab:before{content:"\e7bd"}.mdi-hardware-keyboard-voice:before{content:"\e7be"}.mdi-hardware-laptop:before{content:"\e7bf"}.mdi-hardware-laptop-chromebook:before{content:"\e7c0"}.mdi-hardware-laptop-mac:before{content:"\e7c1"}.mdi-hardware-laptop-windows:before{content:"\e7c2"}.mdi-hardware-memory:before{content:"\e7c3"}.mdi-hardware-mouse:before{content:"\e7c4"}.mdi-hardware-phone-android:before{content:"\e7c5"}.mdi-hardware-phone-iphone:before{content:"\e7c6"}.mdi-hardware-phonelink:before{content:"\e7c7"}.mdi-hardware-phonelink-off:before{content:"\e7c8"}.mdi-hardware-security:before{content:"\e7c9"}.mdi-hardware-sim-card:before{content:"\e7ca"}.mdi-hardware-smartphone:before{content:"\e7cb"}.mdi-hardware-speaker:before{content:"\e7cc"}.mdi-hardware-tablet:before{content:"\e7cd"}.mdi-hardware-tablet-android:before{content:"\e7ce"}.mdi-hardware-tablet-mac:before{content:"\e7cf"}.mdi-hardware-tv:before{content:"\e7d0"}.mdi-hardware-watch:before{content:"\e7d1"}.mdi-image-add-to-photos:before{content:"\e7d2"}.mdi-image-adjust:before{content:"\e7d3"}.mdi-image-assistant-photo:before{content:"\e7d4"}.mdi-image-audiotrack:before{content:"\e7d5"}.mdi-image-blur-circular:before{content:"\e7d6"}.mdi-image-blur-linear:before{content:"\e7d7"}.mdi-image-blur-off:before{content:"\e7d8"}.mdi-image-blur-on:before{content:"\e7d9"}.mdi-image-brightness-1:before{content:"\e7da"}.mdi-image-brightness-2:before{content:"\e7db"}.mdi-image-brightness-3:before{content:"\e7dc"}.mdi-image-brightness-4:before{content:"\e7dd"}.mdi-image-brightness-5:before{content:"\e7de"}.mdi-image-brightness-6:before{content:"\e7df"}.mdi-image-brightness-7:before{content:"\e7e0"}.mdi-image-brush:before{content:"\e7e1"}.mdi-image-camera:before{content:"\e7e2"}.mdi-image-camera-alt:before{content:"\e7e3"}.mdi-image-camera-front:before{content:"\e7e4"}.mdi-image-camera-rear:before{content:"\e7e5"}.mdi-image-camera-roll:before{content:"\e7e6"}.mdi-image-center-focus-strong:before{content:"\e7e7"}.mdi-image-center-focus-weak:before{content:"\e7e8"}.mdi-image-collections:before{content:"\e7e9"}.mdi-image-colorize:before{content:"\e7ea"}.mdi-image-color-lens:before{content:"\e7eb"}.mdi-image-compare:before{content:"\e7ec"}.mdi-image-control-point:before{content:"\e7ed"}.mdi-image-control-point-duplicate:before{content:"\e7ee"}.mdi-image-crop:before{content:"\e7ef"}.mdi-image-crop-3-2:before{content:"\e7f0"}.mdi-image-crop-5-4:before{content:"\e7f1"}.mdi-image-crop-7-5:before{content:"\e7f2"}.mdi-image-crop-16-9:before{content:"\e7f3"}.mdi-image-crop-din:before{content:"\e7f4"}.mdi-image-crop-free:before{content:"\e7f5"}.mdi-image-crop-landscape:before{content:"\e7f6"}.mdi-image-crop-original:before{content:"\e7f7"}.mdi-image-crop-portrait:before{content:"\e7f8"}.mdi-image-crop-square:before{content:"\e7f9"}.mdi-image-dehaze:before{content:"\e7fa"}.mdi-image-details:before{content:"\e7fb"}.mdi-image-edit:before{content:"\e7fc"}.mdi-image-exposure:before{content:"\e7fd"}.mdi-image-exposure-minus-1:before{content:"\e7fe"}.mdi-image-exposure-minus-2:before{content:"\e7ff"}.mdi-image-exposure-plus-1:before{content:"\e800"}.mdi-image-exposure-plus-2:before{content:"\e801"}.mdi-image-exposure-zero:before{content:"\e802"}.mdi-image-filter:before{content:"\e803"}.mdi-image-filter-1:before{content:"\e804"}.mdi-image-filter-2:before{content:"\e805"}.mdi-image-filter-3:before{content:"\e806"}.mdi-image-filter-4:before{content:"\e807"}.mdi-image-filter-5:before{content:"\e808"}.mdi-image-filter-6:before{content:"\e809"}.mdi-image-filter-7:before{content:"\e80a"}.mdi-image-filter-8:before{content:"\e80b"}.mdi-image-filter-9:before{content:"\e80c"}.mdi-image-filter-9-plus:before{content:"\e80d"}.mdi-image-filter-b-and-w:before{content:"\e80e"}.mdi-image-filter-center-focus:before{content:"\e80f"}.mdi-image-filter-drama:before{content:"\e810"}.mdi-image-filter-frames:before{content:"\e811"}.mdi-image-filter-hdr:before{content:"\e812"}.mdi-image-filter-none:before{content:"\e813"}.mdi-image-filter-tilt-shift:before{content:"\e814"}.mdi-image-filter-vintage:before{content:"\e815"}.mdi-image-flare:before{content:"\e816"}.mdi-image-flash-auto:before{content:"\e817"}.mdi-image-flash-off:before{content:"\e818"}.mdi-image-flash-on:before{content:"\e819"}.mdi-image-flip:before{content:"\e81a"}.mdi-image-gradient:before{content:"\e81b"}.mdi-image-grain:before{content:"\e81c"}.mdi-image-grid-off:before{content:"\e81d"}.mdi-image-grid-on:before{content:"\e81e"}.mdi-image-hdr-off:before{content:"\e81f"}.mdi-image-hdr-on:before{content:"\e820"}.mdi-image-hdr-strong:before{content:"\e821"}.mdi-image-hdr-weak:before{content:"\e822"}.mdi-image-healing:before{content:"\e823"}.mdi-image-image:before{content:"\e824"}.mdi-image-image-aspect-ratio:before{content:"\e825"}.mdi-image-iso:before{content:"\e826"}.mdi-image-landscape:before{content:"\e827"}.mdi-image-leak-add:before{content:"\e828"}.mdi-image-leak-remove:before{content:"\e829"}.mdi-image-lens:before{content:"\e82a"}.mdi-image-looks:before{content:"\e82b"}.mdi-image-looks-3:before{content:"\e82c"}.mdi-image-looks-4:before{content:"\e82d"}.mdi-image-looks-5:before{content:"\e82e"}.mdi-image-looks-6:before{content:"\e82f"}.mdi-image-looks-one:before{content:"\e830"}.mdi-image-looks-two:before{content:"\e831"}.mdi-image-loupe:before{content:"\e832"}.mdi-image-movie-creation:before{content:"\e833"}.mdi-image-nature:before{content:"\e834"}.mdi-image-nature-people:before{content:"\e835"}.mdi-image-navigate-before:before{content:"\e836"}.mdi-image-navigate-next:before{content:"\e837"}.mdi-image-palette:before{content:"\e838"}.mdi-image-panorama:before{content:"\e839"}.mdi-image-panorama-fisheye:before{content:"\e83a"}.mdi-image-panorama-horizontal:before{content:"\e83b"}.mdi-image-panorama-vertical:before{content:"\e83c"}.mdi-image-panorama-wide-angle:before{content:"\e83d"}.mdi-image-photo:before{content:"\e83e"}.mdi-image-photo-album:before{content:"\e83f"}.mdi-image-photo-camera:before{content:"\e840"}.mdi-image-photo-library:before{content:"\e841"}.mdi-image-portrait:before{content:"\e842"}.mdi-image-remove-red-eye:before{content:"\e843"}.mdi-image-rotate-left:before{content:"\e844"}.mdi-image-rotate-right:before{content:"\e845"}.mdi-image-slideshow:before{content:"\e846"}.mdi-image-straighten:before{content:"\e847"}.mdi-image-style:before{content:"\e848"}.mdi-image-switch-camera:before{content:"\e849"}.mdi-image-switch-video:before{content:"\e84a"}.mdi-image-tag-faces:before{content:"\e84b"}.mdi-image-texture:before{content:"\e84c"}.mdi-image-timelapse:before{content:"\e84d"}.mdi-image-timer:before{content:"\e84e"}.mdi-image-timer-3:before{content:"\e84f"}.mdi-image-timer-10:before{content:"\e850"}.mdi-image-timer-auto:before{content:"\e851"}.mdi-image-timer-off:before{content:"\e852"}.mdi-image-tonality:before{content:"\e853"}.mdi-image-transform:before{content:"\e854"}.mdi-image-tune:before{content:"\e855"}.mdi-image-wb-auto:before{content:"\e856"}.mdi-image-wb-cloudy:before{content:"\e857"}.mdi-image-wb-incandescent:before{content:"\e858"}.mdi-image-wb-irradescent:before{content:"\e859"}.mdi-image-wb-sunny:before{content:"\e85a"}.mdi-maps-beenhere:before{content:"\e85b"}.mdi-maps-directions:before{content:"\e85c"}.mdi-maps-directions-bike:before{content:"\e85d"}.mdi-maps-directions-bus:before{content:"\e85e"}.mdi-maps-directions-car:before{content:"\e85f"}.mdi-maps-directions-ferry:before{content:"\e860"}.mdi-maps-directions-subway:before{content:"\e861"}.mdi-maps-directions-train:before{content:"\e862"}.mdi-maps-directions-transit:before{content:"\e863"}.mdi-maps-directions-walk:before{content:"\e864"}.mdi-maps-flight:before{content:"\e865"}.mdi-maps-hotel:before{content:"\e866"}.mdi-maps-layers:before{content:"\e867"}.mdi-maps-layers-clear:before{content:"\e868"}.mdi-maps-local-airport:before{content:"\e869"}.mdi-maps-local-atm:before{content:"\e86a"}.mdi-maps-local-attraction:before{content:"\e86b"}.mdi-maps-local-bar:before{content:"\e86c"}.mdi-maps-local-cafe:before{content:"\e86d"}.mdi-maps-local-car-wash:before{content:"\e86e"}.mdi-maps-local-convenience-store:before{content:"\e86f"}.mdi-maps-local-drink:before{content:"\e870"}.mdi-maps-local-florist:before{content:"\e871"}.mdi-maps-local-gas-station:before{content:"\e872"}.mdi-maps-local-grocery-store:before{content:"\e873"}.mdi-maps-local-hospital:before{content:"\e874"}.mdi-maps-local-hotel:before{content:"\e875"}.mdi-maps-local-laundry-service:before{content:"\e876"}.mdi-maps-local-library:before{content:"\e877"}.mdi-maps-local-mall:before{content:"\e878"}.mdi-maps-local-movies:before{content:"\e879"}.mdi-maps-local-offer:before{content:"\e87a"}.mdi-maps-local-parking:before{content:"\e87b"}.mdi-maps-local-pharmacy:before{content:"\e87c"}.mdi-maps-local-phone:before{content:"\e87d"}.mdi-maps-local-pizza:before{content:"\e87e"}.mdi-maps-local-play:before{content:"\e87f"}.mdi-maps-local-post-office:before{content:"\e880"}.mdi-maps-local-print-shop:before{content:"\e881"}.mdi-maps-local-restaurant:before{content:"\e882"}.mdi-maps-local-see:before{content:"\e883"}.mdi-maps-local-shipping:before{content:"\e884"}.mdi-maps-local-taxi:before{content:"\e885"}.mdi-maps-location-history:before{content:"\e886"}.mdi-maps-map:before{content:"\e887"}.mdi-maps-my-location:before{content:"\e888"}.mdi-maps-navigation:before{content:"\e889"}.mdi-maps-pin-drop:before{content:"\e88a"}.mdi-maps-place:before{content:"\e88b"}.mdi-maps-rate-review:before{content:"\e88c"}.mdi-maps-restaurant-menu:before{content:"\e88d"}.mdi-maps-satellite:before{content:"\e88e"}.mdi-maps-store-mall-directory:before{content:"\e88f"}.mdi-maps-terrain:before{content:"\e890"}.mdi-maps-traffic:before{content:"\e891"}.mdi-navigation-apps:before{content:"\e892"}.mdi-navigation-arrow-back:before{content:"\e893"}.mdi-navigation-arrow-drop-down:before{content:"\e894"}.mdi-navigation-arrow-drop-down-circle:before{content:"\e895"}.mdi-navigation-arrow-drop-up:before{content:"\e896"}.mdi-navigation-arrow-forward:before{content:"\e897"}.mdi-navigation-cancel:before{content:"\e898"}.mdi-navigation-check:before{content:"\e899"}.mdi-navigation-chevron-left:before{content:"\e89a"}.mdi-navigation-chevron-right:before{content:"\e89b"}.mdi-navigation-close:before{content:"\e89c"}.mdi-navigation-expand-less:before{content:"\e89d"}.mdi-navigation-expand-more:before{content:"\e89e"}.mdi-navigation-fullscreen:before{content:"\e89f"}.mdi-navigation-fullscreen-exit:before{content:"\e8a0"}.mdi-navigation-menu:before{content:"\e8a1"}.mdi-navigation-more-horiz:before{content:"\e8a2"}.mdi-navigation-more-vert:before{content:"\e8a3"}.mdi-navigation-refresh:before{content:"\e8a4"}.mdi-navigation-unfold-less:before{content:"\e8a5"}.mdi-navigation-unfold-more:before{content:"\e8a6"}.mdi-notification-adb:before{content:"\e8a7"}.mdi-notification-bluetooth-audio:before{content:"\e8a8"}.mdi-notification-disc-full:before{content:"\e8a9"}.mdi-notification-dnd-forwardslash:before{content:"\e8aa"}.mdi-notification-do-not-disturb:before{content:"\e8ab"}.mdi-notification-drive-eta:before{content:"\e8ac"}.mdi-notification-event-available:before{content:"\e8ad"}.mdi-notification-event-busy:before{content:"\e8ae"}.mdi-notification-event-note:before{content:"\e8af"}.mdi-notification-folder-special:before{content:"\e8b0"}.mdi-notification-mms:before{content:"\e8b1"}.mdi-notification-more:before{content:"\e8b2"}.mdi-notification-network-locked:before{content:"\e8b3"}.mdi-notification-phone-bluetooth-speaker:before{content:"\e8b4"}.mdi-notification-phone-forwarded:before{content:"\e8b5"}.mdi-notification-phone-in-talk:before{content:"\e8b6"}.mdi-notification-phone-locked:before{content:"\e8b7"}.mdi-notification-phone-missed:before{content:"\e8b8"}.mdi-notification-phone-paused:before{content:"\e8b9"}.mdi-notification-play-download:before{content:"\e8ba"}.mdi-notification-play-install:before{content:"\e8bb"}.mdi-notification-sd-card:before{content:"\e8bc"}.mdi-notification-sim-card-alert:before{content:"\e8bd"}.mdi-notification-sms:before{content:"\e8be"}.mdi-notification-sms-failed:before{content:"\e8bf"}.mdi-notification-sync:before{content:"\e8c0"}.mdi-notification-sync-disabled:before{content:"\e8c1"}.mdi-notification-sync-problem:before{content:"\e8c2"}.mdi-notification-system-update:before{content:"\e8c3"}.mdi-notification-tap-and-play:before{content:"\e8c4"}.mdi-notification-time-to-leave:before{content:"\e8c5"}.mdi-notification-vibration:before{content:"\e8c6"}.mdi-notification-voice-chat:before{content:"\e8c7"}.mdi-notification-vpn-lock:before{content:"\e8c8"}.mdi-social-cake:before{content:"\e8c9"}.mdi-social-domain:before{content:"\e8ca"}.mdi-social-group:before{content:"\e8cb"}.mdi-social-group-add:before{content:"\e8cc"}.mdi-social-location-city:before{content:"\e8cd"}.mdi-social-mood:before{content:"\e8ce"}.mdi-social-notifications:before{content:"\e8cf"}.mdi-social-notifications-none:before{content:"\e8d0"}.mdi-social-notifications-off:before{content:"\e8d1"}.mdi-social-notifications-on:before{content:"\e8d2"}.mdi-social-notifications-paused:before{content:"\e8d3"}.mdi-social-pages:before{content:"\e8d4"}.mdi-social-party-mode:before{content:"\e8d5"}.mdi-social-people:before{content:"\e8d6"}.mdi-social-people-outline:before{content:"\e8d7"}.mdi-social-person:before{content:"\e8d8"}.mdi-social-person-add:before{content:"\e8d9"}.mdi-social-person-outline:before{content:"\e8da"}.mdi-social-plus-one:before{content:"\e8db"}.mdi-social-poll:before{content:"\e8dc"}.mdi-social-public:before{content:"\e8dd"}.mdi-social-school:before{content:"\e8de"}.mdi-social-share:before{content:"\e8df"}.mdi-social-whatshot:before{content:"\e8e0"}.mdi-toggle-check-box:before{content:"\e8e1"}.mdi-toggle-check-box-outline-blank:before{content:"\e8e2"}.mdi-toggle-radio-button-off:before{content:"\e8e3"}.mdi-toggle-radio-button-on:before{content:"\e8e4"}.container{padding:0 1.5rem;margin:0 auto;max-width:1280px;width:90%}@media only screen and (min-width : 601px){.container{width:85%}}@media only screen and (min-width : 993px){.container{width:70%}}.container .row{margin-left:-0.75rem;margin-right:-0.75rem}.section{padding-top:1rem;padding-bottom:1rem}.section.no-pad{padding:0}.section.no-pad-bot{padding-bottom:0}.section.no-pad-top{padding-top:0}.row{margin-left:auto;margin-right:auto;margin-bottom:20px}.row:after{content:"";display:table;clear:both}.row .col{float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0 0.75rem}.row .col.s1{width:8.33333%;margin-left:0}.row .col.s2{width:16.66667%;margin-left:0}.row .col.s3{width:25%;margin-left:0}.row .col.s4{width:33.33333%;margin-left:0}.row .col.s5{width:41.66667%;margin-left:0}.row .col.s6{width:50%;margin-left:0}.row .col.s7{width:58.33333%;margin-left:0}.row .col.s8{width:66.66667%;margin-left:0}.row .col.s9{width:75%;margin-left:0}.row .col.s10{width:83.33333%;margin-left:0}.row .col.s11{width:91.66667%;margin-left:0}.row .col.s12{width:100%;margin-left:0}.row .col.offset-s1{margin-left:8.33333%}.row .col.offset-s2{margin-left:16.66667%}.row .col.offset-s3{margin-left:25%}.row .col.offset-s4{margin-left:33.33333%}.row .col.offset-s5{margin-left:41.66667%}.row .col.offset-s6{margin-left:50%}.row .col.offset-s7{margin-left:58.33333%}.row .col.offset-s8{margin-left:66.66667%}.row .col.offset-s9{margin-left:75%}.row .col.offset-s10{margin-left:83.33333%}.row .col.offset-s11{margin-left:91.66667%}.row .col.offset-s12{margin-left:100%}@media only screen and (min-width : 601px){.row .col.m1{width:8.33333%;margin-left:0}.row .col.m2{width:16.66667%;margin-left:0}.row .col.m3{width:25%;margin-left:0}.row .col.m4{width:33.33333%;margin-left:0}.row .col.m5{width:41.66667%;margin-left:0}.row .col.m6{width:50%;margin-left:0}.row .col.m7{width:58.33333%;margin-left:0}.row .col.m8{width:66.66667%;margin-left:0}.row .col.m9{width:75%;margin-left:0}.row .col.m10{width:83.33333%;margin-left:0}.row .col.m11{width:91.66667%;margin-left:0}.row .col.m12{width:100%;margin-left:0}.row .col.offset-m1{margin-left:8.33333%}.row .col.offset-m2{margin-left:16.66667%}.row .col.offset-m3{margin-left:25%}.row .col.offset-m4{margin-left:33.33333%}.row .col.offset-m5{margin-left:41.66667%}.row .col.offset-m6{margin-left:50%}.row .col.offset-m7{margin-left:58.33333%}.row .col.offset-m8{margin-left:66.66667%}.row .col.offset-m9{margin-left:75%}.row .col.offset-m10{margin-left:83.33333%}.row .col.offset-m11{margin-left:91.66667%}.row .col.offset-m12{margin-left:100%}}@media only screen and (min-width : 993px){.row .col.l1{width:8.33333%;margin-left:0}.row .col.l2{width:16.66667%;margin-left:0}.row .col.l3{width:25%;margin-left:0}.row .col.l4{width:33.33333%;margin-left:0}.row .col.l5{width:41.66667%;margin-left:0}.row .col.l6{width:50%;margin-left:0}.row .col.l7{width:58.33333%;margin-left:0}.row .col.l8{width:66.66667%;margin-left:0}.row .col.l9{width:75%;margin-left:0}.row .col.l10{width:83.33333%;margin-left:0}.row .col.l11{width:91.66667%;margin-left:0}.row .col.l12{width:100%;margin-left:0}.row .col.offset-l1{margin-left:8.33333%}.row .col.offset-l2{margin-left:16.66667%}.row .col.offset-l3{margin-left:25%}.row .col.offset-l4{margin-left:33.33333%}.row .col.offset-l5{margin-left:41.66667%}.row .col.offset-l6{margin-left:50%}.row .col.offset-l7{margin-left:58.33333%}.row .col.offset-l8{margin-left:66.66667%}.row .col.offset-l9{margin-left:75%}.row .col.offset-l10{margin-left:83.33333%}.row .col.offset-l11{margin-left:91.66667%}.row .col.offset-l12{margin-left:100%}}nav{color:#fff;background-color:#ee6e73;width:100%;height:56px;line-height:56px}nav a{color:#fff}nav .nav-wrapper{position:relative;height:100%}nav .nav-wrapper i{display:block;font-size:2rem}@media only screen and (min-width : 993px){nav a.button-collapse{display:none}}nav .button-collapse{float:left;position:relative;z-index:1;height:56px}nav .button-collapse i{font-size:2.7rem;height:56px;line-height:56px}nav .brand-logo{position:absolute;color:#fff;display:inline-block;font-size:2.1rem;padding:0}nav .brand-logo.center{left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%)}@media only screen and (max-width : 992px){nav .brand-logo{left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%);transform:translateX(-50%);}}nav .brand-logo.right{right:0.5rem;padding:0}nav ul{margin:0}nav ul li{-webkit-transition:background-color .3s;-moz-transition:background-color .3s;-o-transition:background-color .3s;-ms-transition:background-color .3s;transition:background-color .3s;float:left;padding:0}nav ul li:hover,nav ul li.active{background-color:rgba(0,0,0,0.1)}nav ul a{font-size:1rem;color:#fff;display:block;padding:0 15px}nav ul.left{float:left}nav .input-field{margin:0}nav .input-field input{height:100%;font-size:1.2rem;border:none;padding-left:2rem}nav .input-field input:focus,nav .input-field input[type=text]:valid,nav .input-field input[type=password]:valid,nav .input-field input[type=email]:valid,nav .input-field input[type=url]:valid,nav .input-field input[type=date]:valid{border:none;box-shadow:none}nav .input-field label{top:0;left:0}nav .input-field label i{color:rgba(255,255,255,0.7);-webkit-transition:color .3s;-moz-transition:color .3s;-o-transition:color .3s;-ms-transition:color .3s;transition:color .3s}nav .input-field label.active i{color:#fff}nav .input-field label.active{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}.navbar-fixed{position:relative;height:56px;z-index:998}.navbar-fixed nav{position:fixed}@media only screen and (min-width : 601px){nav,nav .nav-wrapper i,nav a.button-collapse,nav a.button-collapse i{height:64px;line-height:64px}.navbar-fixed{height:64px}}@font-face{font-family:"Roboto";src:url("../font/roboto/Roboto-Thin.woff2") format("woff2"),url("../font/roboto/Roboto-Thin.woff") format("woff"),url("../font/roboto/Roboto-Thin.ttf") format("truetype");font-weight:200;}@font-face{font-family:"Roboto";src:url("../font/roboto/Roboto-Light.woff2") format("woff2"),url("../font/roboto/Roboto-Light.woff") format("woff"),url("../font/roboto/Roboto-Light.ttf") format("truetype");font-weight:300;}@font-face{font-family:"Roboto";src:url("../font/roboto/Roboto-Regular.woff2") format("woff2"),url("../font/roboto/Roboto-Regular.woff") format("woff"),url("../font/roboto/Roboto-Regular.ttf") format("truetype");font-weight:400;}@font-face{font-family:"Roboto";src:url("../font/roboto/Roboto-Medium.woff2") format("woff2"),url("../font/roboto/Roboto-Medium.woff") format("woff"),url("../font/roboto/Roboto-Medium.ttf") format("truetype");font-weight:500;}@font-face{font-family:"Roboto";src:url("../font/roboto/Roboto-Bold.woff2") format("woff2"),url("../font/roboto/Roboto-Bold.woff") format("woff"),url("../font/roboto/Roboto-Bold.ttf") format("truetype");font-weight:700;}a{text-decoration:none}html{line-height:1.5;font-family:"Roboto", sans-serif;font-weight:normal;color:rgba(0,0,0,0.87)}@media only screen and (min-width: 0){html{font-size:14px;}}@media only screen and (min-width: 992px){html{font-size:14.5px;}}@media only screen and (min-width: 1200px){html{font-size:15px;}}h1,h2,h3,h4,h5,h6{font-weight:400}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{font-size:4.2rem;line-height:4.62rem;margin:2.1rem 0 1.68rem 0}h2{font-size:3.56rem;line-height:3.916rem;margin:1.78rem 0 1.424rem 0}h3{font-size:2.92rem;line-height:3.212rem;margin:1.46rem 0 1.168rem 0}h4{font-size:2.28rem;line-height:2.508rem;margin:1.14rem 0 0.912rem 0}h5{font-size:1.64rem;line-height:1.804rem;margin:0.82rem 0 0.656rem 0}h6{font-size:1rem;line-height:1.1rem;margin:0.5rem 0 0.4rem 0}em{font-style:italic}strong{font-weight:500}small{font-size:75%}.light,footer.page-footer .footer-copyright{font-weight:300}.thin{font-weight:200}.flow-text{font-weight:300}@media only screen and (min-width: 360px){.flow-text{font-size:1.2rem;}}@media only screen and (min-width: 0px){.flow-text{line-height:.8rem;}}@media only screen and (min-width: 390px){.flow-text{font-size:1.224rem;}}@media only screen and (min-width: 30px){.flow-text{line-height:.904rem;}}@media only screen and (min-width: 420px){.flow-text{font-size:1.248rem;}}@media only screen and (min-width: 60px){.flow-text{line-height:1.008rem;}}@media only screen and (min-width: 450px){.flow-text{font-size:1.272rem;}}@media only screen and (min-width: 90px){.flow-text{line-height:1.112rem;}}@media only screen and (min-width: 480px){.flow-text{font-size:1.296rem;}}@media only screen and (min-width: 120px){.flow-text{line-height:1.216rem;}}@media only screen and (min-width: 510px){.flow-text{font-size:1.32rem;}}@media only screen and (min-width: 150px){.flow-text{line-height:1.32rem;}}@media only screen and (min-width: 540px){.flow-text{font-size:1.344rem;}}@media only screen and (min-width: 180px){.flow-text{line-height:1.424rem;}}@media only screen and (min-width: 570px){.flow-text{font-size:1.368rem;}}@media only screen and (min-width: 210px){.flow-text{line-height:1.528rem;}}@media only screen and (min-width: 600px){.flow-text{font-size:1.392rem;}}@media only screen and (min-width: 240px){.flow-text{line-height:1.632rem;}}@media only screen and (min-width: 630px){.flow-text{font-size:1.416rem;}}@media only screen and (min-width: 270px){.flow-text{line-height:1.736rem;}}@media only screen and (min-width: 660px){.flow-text{font-size:1.44rem;}}@media only screen and (min-width: 300px){.flow-text{line-height:1.84rem;}}@media only screen and (min-width: 690px){.flow-text{font-size:1.464rem;}}@media only screen and (min-width: 330px){.flow-text{line-height:1.944rem;}}@media only screen and (min-width: 720px){.flow-text{font-size:1.488rem;}}@media only screen and (min-width: 360px){.flow-text{line-height:2.048rem;}}@media only screen and (min-width: 750px){.flow-text{font-size:1.512rem;}}@media only screen and (min-width: 390px){.flow-text{line-height:2.152rem;}}@media only screen and (min-width: 780px){.flow-text{font-size:1.536rem;}}@media only screen and (min-width: 420px){.flow-text{line-height:2.256rem;}}@media only screen and (min-width: 810px){.flow-text{font-size:1.56rem;}}@media only screen and (min-width: 450px){.flow-text{line-height:2.36rem;}}@media only screen and (min-width: 840px){.flow-text{font-size:1.584rem;}}@media only screen and (min-width: 480px){.flow-text{line-height:2.464rem;}}@media only screen and (min-width: 870px){.flow-text{font-size:1.608rem;}}@media only screen and (min-width: 510px){.flow-text{line-height:2.568rem;}}@media only screen and (min-width: 900px){.flow-text{font-size:1.632rem;}}@media only screen and (min-width: 540px){.flow-text{line-height:2.672rem;}}@media only screen and (min-width: 930px){.flow-text{font-size:1.656rem;}}@media only screen and (min-width: 570px){.flow-text{line-height:2.776rem;}}@media only screen and (min-width: 960px){.flow-text{font-size:1.68rem;}}@media only screen and (min-width: 600px){.flow-text{line-height:2.88rem;}}.card-panel{padding:20px;margin:0.5rem 0 1rem 0;border-radius:2px;background-color:#fff}.card{position:relative;overflow:hidden;margin:0.5rem 0 1rem 0;background-color:#fff;border-radius:2px}.card .card-title{color:#fff;font-size:24px;font-weight:300}.card .card-title.activator{cursor:pointer}.card.small,.card.medium,.card.large{position:relative}.card.small .card-image,.card.medium .card-image,.card.large .card-image{overflow:hidden}.card.small .card-content,.card.medium .card-content,.card.large .card-content{overflow:hidden}.card.small .card-action,.card.medium .card-action,.card.large .card-action{position:absolute;bottom:0;left:0;right:0}.card.small{height:300px}.card.small .card-image{height:150px}.card.small .card-content{height:150px}.card.medium{height:400px}.card.medium .card-image{height:250px}.card.medium .card-content{height:150px}.card.large{height:500px}.card.large .card-image{height:330px}.card.large .card-content{height:170px}.card .card-image{position:relative}.card .card-image img{border-radius:2px 2px 0 0;position:relative;left:0;right:0;top:0;bottom:0;width:100%}.card .card-image .card-title{position:absolute;bottom:0;left:0;padding:20px}.card .card-content{padding:20px;border-radius:0 0 2px 2px}.card .card-content p{margin:0;color:inherit}.card .card-content .card-title{line-height:48px}.card .card-action{border-top:1px solid rgba(160,160,160,0.2);padding:20px}.card .card-action a{color:#ffab40;margin-right:20px;-webkit-transition:color .3s ease;-moz-transition:color .3s ease;-o-transition:color .3s ease;-ms-transition:color .3s ease;transition:color .3s ease;text-transform:uppercase}.card .card-action a:hover{color:#ffd8a6}.card .card-reveal{padding:20px;position:absolute;background-color:#FFF;width:100%;overflow-y:auto;top:100%;height:100%;z-index:1;display:none}.card .card-reveal .card-title{cursor:pointer;display:block}#toast-container{display:block;position:fixed;z-index:1001}@media only screen and (max-width : 600px){#toast-container{min-width:100%;bottom:0%;}}@media only screen and (min-width : 601px) and (max-width : 992px){#toast-container{min-width:30%;left:5%;bottom:7%;}}@media only screen and (min-width : 993px){#toast-container{min-width:8%;top:10%;right:7%;}}.toast{border-radius:2px;top:0;width:auto;clear:both;margin-top:10px;position:relative;max-width:100%;height:48px;line-height:48px;background-color:#323232;padding:0 25px;font-size:1.1rem;font-weight:300;color:#fff;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-flex-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;-webkit-justify-content:space-between;justify-content:space-between}.toast .btn,.toast .btn-large,.toast .btn-flat{margin:0;margin-left:3rem}.toast.rounded{border-radius:24px}@media only screen and (max-width : 600px){.toast{width:100%;border-radius:0;}}@media only screen and (min-width : 601px) and (max-width : 992px){.toast{float:left;}}@media only screen and (min-width : 993px){.toast{float:right;}}.tabs{position:relative;height:48px;background-color:#fff;margin:0 auto;width:100%;white-space:nowrap}.tabs .tab{display:block;float:left;text-align:center;line-height:48px;height:48px;padding:0 20px;margin:0;text-transform:uppercase;letter-spacing:.8px;width:15%}.tabs .tab a{color:#ee6e73;display:block;width:100%;height:100%;-webkit-transition:color .28s ease;-moz-transition:color .28s ease;-o-transition:color .28s ease;-ms-transition:color .28s ease;transition:color .28s ease}.tabs .tab a:hover{color:#f9c9cb}.tabs .indicator{position:absolute;bottom:0;height:2px;background-color:#f6b2b5;will-change:left, right}.tabs .tab{padding:0}.material-tooltip{padding:10px 8px;font-size:1rem;z-index:1000;background-color:transparent;border-radius:2px;color:#fff;min-height:36px;line-height:1rem;opacity:0;display:none;position:absolute;text-align:center;overflow:hidden;left:0;top:0;will-change:top, left}.backdrop{position:absolute;opacity:0;display:none;height:7px;width:14px;border-radius:0 0 14px 14px;background-color:#323232;z-index:-1;-webkit-transform-origin:50% 10%;-moz-transform-origin:50% 10%;-ms-transform-origin:50% 10%;-o-transform-origin:50% 10%;transform-origin:50% 10%;will-change:transform, opacity}.btn,.btn-large,.btn-flat{border:none;border-radius:2px;display:inline-block;height:36px;line-height:36px;outline:0;padding:0 2rem;text-transform:uppercase;vertical-align:middle;-webkit-tap-highlight-color:transparent}.btn.disabled,.disabled.btn-large,.btn-floating.disabled,.btn-large.disabled,.btn:disabled,.btn-large:disabled,.btn-large:disabled,.btn-floating:disabled{background-color:#DFDFDF;box-shadow:none;color:#9F9F9F;cursor:default}.btn.disabled *,.disabled.btn-large *,.btn-floating.disabled *,.btn-large.disabled *,.btn:disabled *,.btn-large:disabled *,.btn-large:disabled *,.btn-floating:disabled *{pointer-events:none}.btn.disabled:hover,.disabled.btn-large:hover,.btn-floating.disabled:hover,.btn-large.disabled:hover,.btn:disabled:hover,.btn-large:disabled:hover,.btn-large:disabled:hover,.btn-floating:disabled:hover{background-color:#DFDFDF;color:#9F9F9F}.btn i,.btn-large i,.btn-floating i,.btn-large i,.btn-flat i{font-size:1.3rem;line-height:inherit}.btn,.btn-large{text-decoration:none;color:#FFF;background-color:#26a69a;text-align:center;letter-spacing:.5px;-webkit-transition:.2s ease-out;-moz-transition:.2s ease-out;-o-transition:.2s ease-out;-ms-transition:.2s ease-out;transition:.2s ease-out;cursor:pointer}.btn:hover,.btn-large:hover{background-color:#2bbbad}.btn-floating{display:inline-block;color:#FFF;position:relative;overflow:hidden;z-index:1;width:37px;height:37px;line-height:37px;padding:0;background-color:#26a69a;border-radius:50%;transition:.3s;cursor:pointer;vertical-align:middle}.btn-floating i{width:inherit;display:inline-block;text-align:center;color:#FFF;font-size:1.6rem;line-height:37px}.btn-floating:before{border-radius:0}.btn-floating.btn-large{width:55.5px;height:55.5px}.btn-floating.btn-large i{line-height:55.5px}button.btn-floating{border:none}.fixed-action-btn{position:fixed;right:23px;bottom:23px;padding-top:15px;margin-bottom:0;z-index:998}.fixed-action-btn ul{left:0;right:0;text-align:center;position:absolute;bottom:64px}.fixed-action-btn ul li{margin-bottom:15px}.fixed-action-btn ul a.btn-floating{opacity:0}.btn-flat{box-shadow:none;background-color:transparent;color:#343434;cursor:pointer}.btn-flat.disabled{color:#b3b3b3;cursor:default}.btn-large{height:54px;line-height:56px}.btn-large i{font-size:1.6rem}.dropdown-content{background-color:#FFFFFF;margin:0;display:none;min-width:100px;max-height:650px;overflow-y:auto;opacity:0;position:absolute;white-space:nowrap;z-index:1;will-change:width, height}.dropdown-content li{clear:both;color:rgba(0,0,0,0.87);cursor:pointer;line-height:1.5rem;width:100%;text-align:left;text-transform:none}.dropdown-content li:hover,.dropdown-content li.active{background-color:#eee}.dropdown-content li>a,.dropdown-content li>span{font-size:1.2rem;color:#26a69a;display:block;padding:1rem 1rem}/*! - * Waves v0.6.0 - * http://fian.my.id/Waves - * - * Copyright 2014 Alfiana E. Sibuea and other contributors - * Released under the MIT license - * https://github.com/fians/Waves/blob/master/LICENSE - */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;vertical-align:middle;z-index:1;will-change:opacity, transform;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;-ms-transition:all .3s ease-out;transition:all .3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,0.2);-webkit-transition:all 0.7s ease-out;-moz-transition:all 0.7s ease-out;-o-transition:all 0.7s ease-out;-ms-transition:all 0.7s ease-out;transition:all 0.7s ease-out;-webkit-transition-property:-webkit-transform, opacity;-moz-transition-property:-moz-transform, opacity;-o-transition-property:-o-transform, opacity;transition-property:transform, opacity;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,0.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,0.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,0.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,0.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,0.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,0.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,0.7)}.waves-notransition{-webkit-transition:none !important;-moz-transition:none !important;-o-transition:none !important;-ms-transition:none !important;transition:none !important}.waves-circle{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);-webkit-mask-image:-webkit-radial-gradient(circle, white 100%, black 100%)}.waves-input-wrapper{border-radius:0.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-circle{text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-block{display:block}a.waves-effect .waves-ripple{z-index:-1}.modal{display:none;position:fixed;left:0;right:0;background-color:#fafafa;padding:0;max-height:70%;width:55%;margin:auto;overflow-y:auto;z-index:1000;border-radius:2px;-webkit-transform:translate(0);-moz-transform:translate(0);-ms-transform:translate(0);-o-transform:translate(0);transform:translate(0);will-change:top, opacity}@media only screen and (max-width : 992px){.modal{width:80%;}}.modal h1,.modal h2,.modal h3,.modal h4{margin-top:0}.modal .modal-content{padding:24px}.modal .modal-footer{border-radius:0 0 2px 2px;background-color:#fafafa;padding:4px 6px;height:56px;width:100%}.modal .modal-footer .btn,.modal .modal-footer .btn-large,.modal .modal-footer .btn-flat{float:right;margin:6px 0}#lean-overlay{position:fixed;z-index:999;top:0;left:0;bottom:0;right:0;height:115%;width:100%;background:#000;display:none;will-change:opacity}.modal.modal-fixed-footer{padding:0;height:70%}.modal.modal-fixed-footer .modal-content{position:fixed;max-height:100%;padding-bottom:64px;width:100%;overflow-y:auto}.modal.modal-fixed-footer .modal-footer{border-top:1px solid rgba(0,0,0,0.1);position:fixed;bottom:0}.modal.bottom-sheet{top:auto;bottom:-100%;margin:0;width:100%;max-height:45%;border-radius:0;will-change:bottom, opacity}.collapsible{border-top:1px solid #ddd;border-right:1px solid #ddd;border-left:1px solid #ddd;margin:0.5rem 0 1rem 0}.collapsible-header{display:block;cursor:pointer;height:3rem;line-height:3rem;padding:0 1rem;background-color:#fff;border-bottom:1px solid #ddd}.collapsible-header i{width:2rem;font-size:1.6rem;line-height:3rem;display:block;float:left;text-align:center;margin-right:1rem}.collapsible-body{overflow:hidden;display:none;border-bottom:1px solid #ddd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.collapsible-body p{margin:0;padding:2rem}.side-nav .collapsible{border:none;box-shadow:none}.side-nav .collapsible li{padding:0}.side-nav .collapsible-header{background-color:transparent;border:none;line-height:inherit;height:inherit;margin:0 1rem}.side-nav .collapsible-header i{line-height:inherit}.side-nav .collapsible-body{border:0;background-color:#FFF}.side-nav .collapsible-body li a{margin:0 1rem 0 2rem}.collapsible.popout{border:none;box-shadow:none}.collapsible.popout>li{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12);transform:scaleX(.92) translate3d(0, 0, 0);transition:margin .35s cubic-bezier(0.25, 0.46, 0.45, 0.94),transform .35s cubic-bezier(0.25, 0.46, 0.45, 0.94)}.collapsible.popout>li:hover{will-change:margin, transform}.collapsible.popout>li.active{box-shadow:0 5px 11px 0 rgba(0,0,0,0.18),0 4px 15px 0 rgba(0,0,0,0.15);margin:16px 0;transform:scaleX(1) translate3d(0, 0, 0)}.materialboxed{cursor:zoom-in;position:relative;-webkit-transition:opacity .4s;-moz-transition:opacity .4s;-o-transition:opacity .4s;-ms-transition:opacity .4s;transition:opacity .4s}.materialboxed:hover{will-change:left, top, width, height}.materialboxed:hover:not(.active){opacity:.8}.materialboxed.active{cursor:zoom-out}#materialbox-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#292929;z-index:999;will-change:opacity}.materialbox-caption{position:fixed;display:none;color:#fff;line-height:50px;bottom:0;width:100%;text-align:center;padding:0% 15%;height:50px;z-index:1000;-webkit-font-smoothing:antialiased}select:focus{outline:1px solid #c9f3ef}button:focus{outline:none;background-color:#2ab7a9}label{font-size:0.8rem;color:#9e9e9e}::-webkit-input-placeholder{color:#d1d1d1}:-moz-placeholder{color:#d1d1d1}::-moz-placeholder{color:#d1d1d1}:-ms-input-placeholder{color:#d1d1d1}input[type=text],input[type=password],input[type=email],input[type=url],input[type=time],input[type=date],input[type=datetime-local],input[type=tel],input[type=number],input[type=search],textarea.materialize-textarea{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:3rem;width:100%;font-size:1rem;margin:0 0 15px 0;padding:0;box-shadow:none;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;transition:all .3s}input[type=text]:disabled,input[type=text][readonly="readonly"],input[type=password]:disabled,input[type=password][readonly="readonly"],input[type=email]:disabled,input[type=email][readonly="readonly"],input[type=url]:disabled,input[type=url][readonly="readonly"],input[type=time]:disabled,input[type=time][readonly="readonly"],input[type=date]:disabled,input[type=date][readonly="readonly"],input[type=datetime-local]:disabled,input[type=datetime-local][readonly="readonly"],input[type=tel]:disabled,input[type=tel][readonly="readonly"],input[type=number]:disabled,input[type=number][readonly="readonly"],input[type=search]:disabled,input[type=search][readonly="readonly"],textarea.materialize-textarea:disabled,textarea.materialize-textarea[readonly="readonly"]{color:rgba(0,0,0,0.26);border-bottom:1px dotted rgba(0,0,0,0.26)}input[type=text]:disabled+label,input[type=text][readonly="readonly"]+label,input[type=password]:disabled+label,input[type=password][readonly="readonly"]+label,input[type=email]:disabled+label,input[type=email][readonly="readonly"]+label,input[type=url]:disabled+label,input[type=url][readonly="readonly"]+label,input[type=time]:disabled+label,input[type=time][readonly="readonly"]+label,input[type=date]:disabled+label,input[type=date][readonly="readonly"]+label,input[type=datetime-local]:disabled+label,input[type=datetime-local][readonly="readonly"]+label,input[type=tel]:disabled+label,input[type=tel][readonly="readonly"]+label,input[type=number]:disabled+label,input[type=number][readonly="readonly"]+label,input[type=search]:disabled+label,input[type=search][readonly="readonly"]+label,textarea.materialize-textarea:disabled+label,textarea.materialize-textarea[readonly="readonly"]+label{color:rgba(0,0,0,0.26)}input[type=text]:focus:not([readonly]),input[type=password]:focus:not([readonly]),input[type=email]:focus:not([readonly]),input[type=url]:focus:not([readonly]),input[type=time]:focus:not([readonly]),input[type=date]:focus:not([readonly]),input[type=datetime-local]:focus:not([readonly]),input[type=tel]:focus:not([readonly]),input[type=number]:focus:not([readonly]),input[type=search]:focus:not([readonly]),textarea.materialize-textarea:focus:not([readonly]){border-bottom:1px solid #26a69a;box-shadow:0 1px 0 0 #26a69a}input[type=text]:focus:not([readonly])+label,input[type=password]:focus:not([readonly])+label,input[type=email]:focus:not([readonly])+label,input[type=url]:focus:not([readonly])+label,input[type=time]:focus:not([readonly])+label,input[type=date]:focus:not([readonly])+label,input[type=datetime-local]:focus:not([readonly])+label,input[type=tel]:focus:not([readonly])+label,input[type=number]:focus:not([readonly])+label,input[type=search]:focus:not([readonly])+label,textarea.materialize-textarea:focus:not([readonly])+label{color:#26a69a}input[type=text].valid,input[type=text]:focus.valid,input[type=password].valid,input[type=password]:focus.valid,input[type=email].valid,input[type=email]:focus.valid,input[type=url].valid,input[type=url]:focus.valid,input[type=time].valid,input[type=time]:focus.valid,input[type=date].valid,input[type=date]:focus.valid,input[type=datetime-local].valid,input[type=datetime-local]:focus.valid,input[type=tel].valid,input[type=tel]:focus.valid,input[type=number].valid,input[type=number]:focus.valid,input[type=search].valid,input[type=search]:focus.valid,textarea.materialize-textarea.valid,textarea.materialize-textarea:focus.valid{border-bottom:1px solid #4CAF50;box-shadow:0 1px 0 0 #4CAF50}input[type=text].invalid,input[type=text]:focus.invalid,input[type=password].invalid,input[type=password]:focus.invalid,input[type=email].invalid,input[type=email]:focus.invalid,input[type=url].invalid,input[type=url]:focus.invalid,input[type=time].invalid,input[type=time]:focus.invalid,input[type=date].invalid,input[type=date]:focus.invalid,input[type=datetime-local].invalid,input[type=datetime-local]:focus.invalid,input[type=tel].invalid,input[type=tel]:focus.invalid,input[type=number].invalid,input[type=number]:focus.invalid,input[type=search].invalid,input[type=search]:focus.invalid,textarea.materialize-textarea.invalid,textarea.materialize-textarea:focus.invalid{border-bottom:1px solid #F44336;box-shadow:0 1px 0 0 #F44336}.input-field{position:relative;margin-top:1rem}.input-field label{color:#9e9e9e;position:absolute;top:0.8rem;left:0.75rem;font-size:1rem;cursor:text;-webkit-transition:.2s ease-out;-moz-transition:.2s ease-out;-o-transition:.2s ease-out;-ms-transition:.2s ease-out;transition:.2s ease-out}.input-field label.active{font-size:0.8rem;-webkit-transform:translateY(-140%);-moz-transform:translateY(-140%);-ms-transform:translateY(-140%);-o-transform:translateY(-140%);transform:translateY(-140%)}.input-field .prefix{position:absolute;width:3rem;font-size:2rem;-webkit-transition:color .2s;-moz-transition:color .2s;-o-transition:color .2s;-ms-transition:color .2s;transition:color .2s}.input-field .prefix.active{color:#26a69a}.input-field .prefix ~ input,.input-field .prefix ~ textarea{margin-left:3rem;width:92%;width:calc(100% - 3rem)}.input-field .prefix ~ textarea{padding-top:.8rem}.input-field .prefix ~ label{margin-left:3rem}@media only screen and (max-width : 992px){.input-field .prefix ~ input{width:86%;width:calc(100% - 3rem)}}@media only screen and (max-width : 600px){.input-field .prefix ~ input{width:80%;width:calc(100% - 3rem)}}.input-field input[type=search]{display:block;line-height:inherit;padding-left:4rem;width:calc(100% - 4rem)}.input-field input[type=search]:focus{background-color:#FFF;border:0;box-shadow:none;color:#444}.input-field input[type=search]:focus+label i,.input-field input[type=search]:focus ~ .mdi-navigation-close{color:#444}.input-field input[type=search]+label{left:1rem}.input-field input[type=search] ~ .mdi-navigation-close{position:absolute;top:0;right:1rem;color:transparent;cursor:pointer;font-size:2rem;transition:.3s color}textarea{width:100%;height:3rem;background-color:transparent}textarea.materialize-textarea{overflow-y:hidden;padding:1.6rem 0;resize:none;min-height:3rem}.hiddendiv{display:none;white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;padding-top:1.2rem}[type="radio"]:not(:checked),[type="radio"]:checked{position:absolute;left:-9999px;visibility:hidden}[type="radio"]:not(:checked)+label,[type="radio"]:checked+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-transition:.28s ease;-moz-transition:.28s ease;-o-transition:.28s ease;-ms-transition:.28s ease;transition:.28s ease;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}[type="radio"]+label:before,[type="radio"]+label:after{content:'';position:absolute;left:0;top:0;margin:4px;width:16px;height:16px;z-index:0;-webkit-transition:.28s ease;-moz-transition:.28s ease;-o-transition:.28s ease;-ms-transition:.28s ease;transition:.28s ease}[type="radio"]:not(:checked)+label:before{border-radius:50%;border:2px solid #5a5a5a}[type="radio"]:not(:checked)+label:after{border-radius:50%;border:2px solid #5a5a5a;z-index:-1;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0)}[type="radio"]:checked+label:before{border-radius:50%;border:2px solid transparent}[type="radio"]:checked+label:after{border-radius:50%;border:2px solid #26a69a;background-color:#26a69a;z-index:0;-webkit-transform:scale(1.02);-moz-transform:scale(1.02);-ms-transform:scale(1.02);-o-transform:scale(1.02);transform:scale(1.02)}[type="radio"].with-gap:checked+label:before{border-radius:50%;border:2px solid #26a69a}[type="radio"].with-gap:checked+label:after{border-radius:50%;border:2px solid #26a69a;background-color:#26a69a;z-index:0;-webkit-transform:scale(.5);-moz-transform:scale(.5);-ms-transform:scale(.5);-o-transform:scale(.5);transform:scale(.5)}[type="radio"]:disabled:not(:checked)+label:before,[type="radio"]:disabled:checked+label:before{background-color:transparent;border-color:rgba(0,0,0,0.26)}[type="radio"]:disabled+label{color:rgba(0,0,0,0.26)}[type="radio"]:disabled:not(:checked)+label:hover:before{border-color:rgba(0,0,0,0.26)}form p{margin-bottom:10px;text-align:left}form p:last-child{margin-bottom:0}[type="checkbox"]:not(:checked),[type="checkbox"]:checked{position:absolute;left:-9999px}[type="checkbox"]{}[type="checkbox"]+label{position:relative;padding-left:35px;cursor:pointer;display:inline-block;height:25px;line-height:25px;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}[type="checkbox"]+label:before{content:'';position:absolute;top:0;left:0;width:18px;height:18px;z-index:0;border:2px solid #5a5a5a;border-radius:1px;margin-top:2px;-webkit-transition:0.2s;-moz-transition:0.2s;-o-transition:0.2s;-ms-transition:0.2s;transition:0.2s}[type="checkbox"]:not(:checked):disabled+label:before{border:none;background-color:rgba(0,0,0,0.26)}[type="checkbox"]:checked+label:before{top:-4px;left:-3px;width:12px;height:22px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #26a69a;border-bottom:2px solid #26a69a;-webkit-transform:rotate(40deg);-moz-transform:rotate(40deg);-ms-transform:rotate(40deg);-o-transform:rotate(40deg);transform:rotate(40deg);-webkit-backface-visibility:hidden;-webkit-transform-origin:100% 100%;-moz-transform-origin:100% 100%;-ms-transform-origin:100% 100%;-o-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:checked:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);border-bottom:2px solid rgba(0,0,0,0.26)}[type="checkbox"]:indeterminate+label:before{left:-10px;top:-11px;width:10px;height:22px;border-top:none;border-left:none;border-right:2px solid #26a69a;border-bottom:none;-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);-webkit-backface-visibility:hidden;-webkit-transform-origin:100% 100%;-moz-transform-origin:100% 100%;-ms-transform-origin:100% 100%;-o-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"]:indeterminate:disabled+label:before{border-right:2px solid rgba(0,0,0,0.26);background-color:transparent}[type="checkbox"].filled-in+label:after{border-radius:2px}[type="checkbox"].filled-in+label:before,[type="checkbox"].filled-in+label:after{content:'';left:0;position:absolute;transition:border .25s,background-color .25s,width .2s .1s,height .2s .1s,top .2s .1s,left .2s .1s;z-index:1}[type="checkbox"].filled-in:not(:checked)+label:before{width:0;height:0;border:3px solid transparent;left:6px;top:10px;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:20% 40%;transform-origin:100% 100%}[type="checkbox"].filled-in:not(:checked)+label:after{height:20px;width:20px;background-color:transparent;border:2px solid #5a5a5a;top:0px;z-index:0}[type="checkbox"].filled-in:checked+label:before{top:0;left:1px;width:8px;height:13px;border-top:2px solid transparent;border-left:2px solid transparent;border-right:2px solid #fff;border-bottom:2px solid #fff;-webkit-transform:rotateZ(37deg);transform:rotateZ(37deg);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}[type="checkbox"].filled-in:checked+label:after{top:0px;width:20px;height:20px;border:2px solid #26a69a;background-color:#26a69a;z-index:0}[type="checkbox"].filled-in:disabled:not(:checked)+label:before{background-color:transparent;border:2px solid transparent}[type="checkbox"].filled-in:disabled:not(:checked)+label:after{border-color:transparent;background-color:#BDBDBD}[type="checkbox"].filled-in:disabled:checked+label:before{background-color:transparent}[type="checkbox"].filled-in:disabled:checked+label:after{background-color:#BDBDBD;border-color:#BDBDBD}.switch,.switch *{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none}.switch label{cursor:pointer}.switch label input[type=checkbox]{opacity:0;width:0;height:0}.switch label input[type=checkbox]:checked+.lever{background-color:#84c7c1}.switch label input[type=checkbox]:checked+.lever:after{background-color:#26a69a}.switch label .lever{content:"";display:inline-block;position:relative;width:40px;height:15px;background-color:#818181;border-radius:15px;margin-right:10px;transition:background 0.3s ease;vertical-align:middle;margin:0 16px}.switch label .lever:after{content:"";position:absolute;display:inline-block;width:21px;height:21px;background-color:#F1F1F1;border-radius:21px;box-shadow:0 1px 3px 1px rgba(0,0,0,0.4);left:-5px;top:-3px;transition:left 0.3s ease,background 0.3s ease,box-shadow 0.1s ease}input[type=checkbox]:checked:not(:disabled) ~ .lever:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(38,166,154,0.1)}input[type=checkbox]:not(:disabled) ~ .lever:active:after{box-shadow:0 1px 3px 1px rgba(0,0,0,0.4),0 0 0 15px rgba(0,0,0,0.08)}.switch label input[type=checkbox]:checked+.lever:after{left:24px}.switch input[type=checkbox][disabled]+.lever{cursor:default}.switch label input[type=checkbox][disabled]+.lever:after,.switch label input[type=checkbox][disabled]:checked+.lever:after{background-color:#BDBDBD}.select-label{position:absolute}.select-wrapper{position:relative}.select-wrapper input.select-dropdown{position:relative;cursor:pointer;background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;outline:none;height:3rem;line-height:3rem;width:100%;font-size:1rem;margin:0 0 15px 0;padding:0;display:block}.select-wrapper .mdi-navigation-arrow-drop-down{color:initial;position:absolute;right:0;top:0;font-size:23px}.select-wrapper .mdi-navigation-arrow-drop-down.disabled{color:rgba(0,0,0,0.26)}.select-wrapper+label{position:absolute;top:-14px;font-size:0.8rem}select{display:none}select.browser-default{display:block}select:disabled{color:rgba(0,0,0,0.3)}.select-wrapper input.select-dropdown:disabled{color:rgba(0,0,0,0.3);cursor:default;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;border-bottom:1px solid rgba(0,0,0,0.3)}.select-wrapper i{color:rgba(0,0,0,0.3)}.select-dropdown li.disabled{color:rgba(0,0,0,0.3);background-color:transparent}.file-field{position:relative}.file-field input.file-path{margin-left:100px;width:calc(100% - 100px)}.file-field .btn,.file-field .btn-large{position:absolute;top:0;left:0;height:3rem;line-height:3rem}.file-field span{cursor:pointer}.file-field input[type=file]{position:absolute;top:0;right:0;left:0;bottom:0;width:100%;margin:0;padding:0;font-size:20px;cursor:pointer;opacity:0;filter:alpha(opacity=0)}.range-field{position:relative}input[type=range],input[type=range]+.thumb{cursor:pointer}input[type=range]{position:relative;background-color:transparent;border:none;outline:none;width:100%;margin:15px 0px;padding:0}input[type=range]+.thumb{position:absolute;border:none;height:0;width:0;border-radius:50%;background-color:#26a69a;top:10px;margin-left:-6px;-webkit-transform-origin:50% 50%;-moz-transform-origin:50% 50%;-ms-transform-origin:50% 50%;-o-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}input[type=range]+.thumb .value{display:block;width:30px;text-align:center;color:#26a69a;font-size:0;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}input[type=range]+.thumb.active{border-radius:50% 50% 50% 0}input[type=range]+.thumb.active .value{color:#fff;margin-left:-1px;margin-top:8px;font-size:10px}input[type=range]:focus{outline:none}input[type=range]{-webkit-appearance:none}input[type=range]::-webkit-slider-runnable-track{height:3px;background:#c2c0c2;border:none}input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:14px;width:14px;border-radius:50%;background-color:#26a69a;transform-origin:50% 50%;margin:-5px 0 0 0;-webkit-transition:0.3s;-moz-transition:0.3s;-o-transition:0.3s;-ms-transition:0.3s;transition:0.3s}input[type=range]:focus::-webkit-slider-runnable-track{background:#ccc}input[type=range]{border:1px solid white}input[type=range]::-moz-range-track{height:3px;background:#ddd;border:none}input[type=range]::-moz-range-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a;margin-top:-5px}input[type=range]:-moz-focusring{outline:1px solid white;outline-offset:-1px}input[type=range]:focus::-moz-range-track{background:#ccc}input[type=range]::-ms-track{height:3px;background:transparent;border-color:transparent;border-width:6px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#777}input[type=range]::-ms-fill-upper{background:#ddd}input[type=range]::-ms-thumb{border:none;height:14px;width:14px;border-radius:50%;background:#26a69a}input[type=range]:focus::-ms-fill-lower{background:#888}input[type=range]:focus::-ms-fill-upper{background:#ccc}select{background-color:rgba(255,255,255,0.9);width:100%;padding:5px;border:1px solid #f2f2f2;border-radius:2px;height:3rem}.table-of-contents.fixed{position:fixed}.table-of-contents li{padding:2px 0}.table-of-contents a{display:inline-block;font-weight:300;color:#757575;padding-left:20px;height:1.5rem;line-height:1.5rem;letter-spacing:.4;display:inline-block}.table-of-contents a:hover{color:#a8a8a8;padding-left:19px;border-left:1px solid #ea4a4f}.table-of-contents a.active{font-weight:500;padding-left:18px;border-left:2px solid #ea4a4f}.side-nav{position:fixed;width:240px;left:-105%;top:0;margin:0;height:100%;height:calc(100% + 60px);height:-moz-calc(100%);padding-bottom:60px;background-color:#FFF;z-index:999;overflow-y:auto;will-change:left}.side-nav.right-aligned{will-change:right;right:-105%;left:auto}.side-nav .collapsible{margin:0}.side-nav li{float:none;padding:0 15px}.side-nav li:hover,.side-nav li.active{background-color:#ddd}.side-nav a{color:#444;display:block;font-size:1rem;height:64px;line-height:64px;padding:0 15px}.drag-target{height:100%;width:10px;position:fixed;top:0;z-index:998}.side-nav.fixed a{display:block;padding:0 15px;color:#444}.side-nav.fixed{left:0;position:fixed}.side-nav.fixed.right-aligned{right:0;left:auto}@media only screen and (max-width : 992px){.side-nav.fixed{left:-105%}.side-nav.fixed.right-aligned{right:-105%;left:auto}}.side-nav .collapsible-body li.active,.side-nav.fixed .collapsible-body li.active{background-color:#ee6e73}.side-nav .collapsible-body li.active a,.side-nav.fixed .collapsible-body li.active a{color:#fff}#sidenav-overlay{position:fixed;top:0;left:0;right:0;height:120vh;background-color:rgba(0,0,0,0.5);z-index:997;will-change:opacity}.preloader-wrapper{display:inline-block;position:relative;width:48px;height:48px}.preloader-wrapper.small{width:36px;height:36px}.preloader-wrapper.big{width:64px;height:64px}.preloader-wrapper.active{-webkit-animation:container-rotate 1568ms linear infinite;animation:container-rotate 1568ms linear infinite}@-webkit-keyframes container-rotate{to{-webkit-transform:rotate(360deg)}}@keyframes container-rotate{to{transform:rotate(360deg)}}.spinner-layer{position:absolute;width:100%;height:100%;opacity:0}.spinner-blue,.spinner-blue-only{border-color:#4285f4}.spinner-red,.spinner-red-only{border-color:#db4437}.spinner-yellow,.spinner-yellow-only{border-color:#f4b400}.spinner-green,.spinner-green-only{border-color:#0f9d58}.active .spinner-layer.spinner-blue{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,blue-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-red{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,red-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-yellow{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,yellow-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-green{-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both,green-fade-in-out 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .spinner-layer.spinner-blue-only,.active .spinner-layer.spinner-red-only,.active .spinner-layer.spinner-yellow-only,.active .spinner-layer.spinner-green-only{opacity:1;-webkit-animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:fill-unfill-rotate 5332ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes fill-unfill-rotate{12.5%{-webkit-transform:rotate(135deg)}25%{-webkit-transform:rotate(270deg)}37.5%{-webkit-transform:rotate(405deg)}50%{-webkit-transform:rotate(540deg)}62.5%{-webkit-transform:rotate(675deg)}75%{-webkit-transform:rotate(810deg)}87.5%{-webkit-transform:rotate(945deg)}to{-webkit-transform:rotate(1080deg)}}@keyframes fill-unfill-rotate{12.5%{transform:rotate(135deg)}25%{transform:rotate(270deg)}37.5%{transform:rotate(405deg)}50%{transform:rotate(540deg)}62.5%{transform:rotate(675deg)}75%{transform:rotate(810deg)}87.5%{transform:rotate(945deg)}to{transform:rotate(1080deg)}}@-webkit-keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@keyframes blue-fade-in-out{from{opacity:1}25%{opacity:1}26%{opacity:0}89%{opacity:0}90%{opacity:1}100%{opacity:1}}@-webkit-keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@keyframes red-fade-in-out{from{opacity:0}15%{opacity:0}25%{opacity:1}50%{opacity:1}51%{opacity:0}}@-webkit-keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@keyframes yellow-fade-in-out{from{opacity:0}40%{opacity:0}50%{opacity:1}75%{opacity:1}76%{opacity:0}}@-webkit-keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}@keyframes green-fade-in-out{from{opacity:0}65%{opacity:0}75%{opacity:1}90%{opacity:1}100%{opacity:0}}.gap-patch{position:absolute;top:0;left:45%;width:10%;height:100%;overflow:hidden;border-color:inherit}.gap-patch .circle{width:1000%;left:-450%}.circle-clipper{display:inline-block;position:relative;width:50%;height:100%;overflow:hidden;border-color:inherit}.circle-clipper .circle{width:200%;height:100%;border-width:3px;border-style:solid;border-color:inherit;border-bottom-color:transparent !important;border-radius:50%;-webkit-animation:none;animation:none;position:absolute;top:0;right:0;bottom:0}.circle-clipper.left .circle{left:0;border-right-color:transparent !important;-webkit-transform:rotate(129deg);transform:rotate(129deg)}.circle-clipper.right .circle{left:-100%;border-left-color:transparent !important;-webkit-transform:rotate(-129deg);transform:rotate(-129deg)}.active .circle-clipper.left .circle{-webkit-animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:left-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}.active .circle-clipper.right .circle{-webkit-animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both;animation:right-spin 1333ms cubic-bezier(0.4, 0, 0.2, 1) infinite both}@-webkit-keyframes left-spin{from{-webkit-transform:rotate(130deg)}50%{-webkit-transform:rotate(-5deg)}to{-webkit-transform:rotate(130deg)}}@keyframes left-spin{from{transform:rotate(130deg)}50%{transform:rotate(-5deg)}to{transform:rotate(130deg)}}@-webkit-keyframes right-spin{from{-webkit-transform:rotate(-130deg)}50%{-webkit-transform:rotate(5deg)}to{-webkit-transform:rotate(-130deg)}}@keyframes right-spin{from{transform:rotate(-130deg)}50%{transform:rotate(5deg)}to{transform:rotate(-130deg)}}#spinnerContainer.cooldown{-webkit-animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1);animation:container-rotate 1568ms linear infinite,fade-out 400ms cubic-bezier(0.4, 0, 0.2, 1)}@-webkit-keyframes fade-out{from{opacity:1}to{opacity:0}}@keyframes fade-out{from{opacity:1}to{opacity:0}}.slider{position:relative;height:440px;width:100%}.slider.fullscreen{height:100%;width:100%;position:absolute;top:0;left:0;right:0;bottom:0}.slider.fullscreen ul.slides{height:100%}.slider.fullscreen ul.indicators{z-index:2;bottom:30px}.slider .slides{background-color:#9e9e9e;margin:0;height:400px}.slider .slides li{opacity:0;position:absolute;top:0;left:0;z-index:1;width:100%;height:inherit;overflow:hidden}.slider .slides li img{height:100%;width:100%;background-size:cover;background-position:center}.slider .slides li .caption{color:#fff;position:absolute;top:15%;left:15%;width:70%;opacity:0}.slider .slides li .caption p{color:#e0e0e0}.slider .slides li.active{z-index:2}.slider .indicators{position:absolute;text-align:center;left:0;right:0;bottom:0;margin:0}.slider .indicators .indicator-item{display:inline-block;position:relative;cursor:pointer;height:16px;width:16px;margin:0 12px;background-color:#e0e0e0;-webkit-transition:background-color .3s;-moz-transition:background-color .3s;-o-transition:background-color .3s;-ms-transition:background-color .3s;transition:background-color .3s;border-radius:50%}.slider .indicators .indicator-item.active{background-color:#4CAF50}.picker{font-size:16px;text-align:left;line-height:1.2;color:#000000;position:absolute;z-index:10000;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.picker__input{cursor:default}.picker__input.picker__input--active{border-color:#0089ec}.picker__holder{width:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}/*! - * Default mobile-first, responsive styling for pickadate.js - * Demo: http://amsul.github.io/pickadate.js - */.picker__holder,.picker__frame{bottom:0;left:0;right:0;top:100%}.picker__holder{position:fixed;-webkit-transition:background 0.15s ease-out,top 0s 0.15s;-moz-transition:background 0.15s ease-out,top 0s 0.15s;transition:background 0.15s ease-out,top 0s 0.15s;-webkit-backface-visibility:hidden}.picker__frame{position:absolute;margin:0 auto;min-width:256px;max-width:300px;max-height:350px;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";filter:alpha(opacity=0);-moz-opacity:0;opacity:0;-webkit-transition:all 0.15s ease-out;-moz-transition:all 0.15s ease-out;transition:all 0.15s ease-out}@media (min-height: 28.875em){.picker__frame{overflow:visible;top:auto;bottom:-100%;max-height:80%}}@media (min-height: 40.125em){.picker__frame{margin-bottom:7.5%}}.picker__wrap{display:table;width:100%;height:100%}@media (min-height: 28.875em){.picker__wrap{display:block}}.picker__box{background:#ffffff;display:table-cell;vertical-align:middle}@media (min-height: 28.875em){.picker__box{display:block;border:1px solid #777777;border-top-color:#898989;border-bottom-width:0;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;-webkit-box-shadow:0 12px 36px 16px rgba(0,0,0,0.24);-moz-box-shadow:0 12px 36px 16px rgba(0,0,0,0.24);box-shadow:0 12px 36px 16px rgba(0,0,0,0.24)}}.picker--opened .picker__holder{top:0;background:transparent;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#1E000000,endColorstr=#1E000000)";zoom:1;background:rgba(0,0,0,0.32);-webkit-transition:background 0.15s ease-out;-moz-transition:background 0.15s ease-out;transition:background 0.15s ease-out}.picker--opened .picker__frame{top:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";filter:alpha(opacity=100);-moz-opacity:1;opacity:1}@media (min-height: 35.875em){.picker--opened .picker__frame{top:10%;bottom:20% auto}}.picker__input.picker__input--active{border-color:#E3F2FD}.picker__frame{margin:0 auto;max-width:325px}@media (min-height: 38.875em){.picker--opened .picker__frame{top:10%;bottom:auto}}.picker__box{padding:0 1em}.picker__header{text-align:center;position:relative;margin-top:.75em}.picker__month,.picker__year{display:inline-block;margin-left:.25em;margin-right:.25em}.picker__select--month,.picker__select--year{height:2em;padding:0;margin-left:.25em;margin-right:.25em}.picker__select--month.browser-default{display:inline;background-color:#FFFFFF;width:40%}.picker__select--year.browser-default{display:inline;background-color:#FFFFFF;width:25%}.picker__select--month:focus,.picker__select--year:focus{border-color:rgba(0,0,0,0.05)}.picker__nav--prev,.picker__nav--next{position:absolute;padding:.5em 1.25em;width:1em;height:1em;box-sizing:content-box;top:-0.25em}.picker__nav--prev{left:-1em;padding-right:1.25em}.picker__nav--next{right:-1em;padding-left:1.25em}.picker__nav--disabled,.picker__nav--disabled:hover,.picker__nav--disabled:before,.picker__nav--disabled:before:hover{cursor:default;background:none;border-right-color:#f5f5f5;border-left-color:#f5f5f5}.picker__table{text-align:center;border-collapse:collapse;border-spacing:0;table-layout:fixed;font-size:1rem;width:100%;margin-top:.75em;margin-bottom:.5em}.picker__table th,.picker__table td{text-align:center}.picker__table td{margin:0;padding:0}.picker__weekday{width:14.285714286%;font-size:.75em;padding-bottom:.25em;color:#999999;font-weight:500}@media (min-height: 33.875em){.picker__weekday{padding-bottom:.5em}}.picker__day--today{position:relative;color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day--disabled:before{border-top-color:#aaaaaa}.picker__day--infocus:hover{cursor:pointer;color:#000;font-weight:500}.picker__day--outfocus{display:none;padding:.75rem 0;color:#fff}.picker__day--outfocus:hover{cursor:pointer;color:#dddddd;font-weight:500}.picker__day--highlighted:hover,.picker--focused .picker__day--highlighted{cursor:pointer}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(.75);-moz-transform:scale(.75);-ms-transform:scale(.75);-o-transform:scale(.75);transform:scale(.75);background:#0089ec;color:#ffffff}.picker__day--disabled,.picker__day--disabled:hover,.picker--focused .picker__day--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__day--highlighted.picker__day--disabled,.picker__day--highlighted.picker__day--disabled:hover{background:#bbbbbb}.picker__footer{text-align:center;display:flex;align-items:center;justify-content:space-between}.picker__button--today,.picker__button--clear,.picker__button--close{border:1px solid #ffffff;background:#ffffff;font-size:.8em;padding:.66em 0;font-weight:bold;width:33%;display:inline-block;vertical-align:bottom}.picker__button--today:hover,.picker__button--clear:hover,.picker__button--close:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-bottom-color:#b1dcfb}.picker__button--today:focus,.picker__button--clear:focus,.picker__button--close:focus{background:#b1dcfb;border-color:rgba(0,0,0,0.05);outline:none}.picker__button--today:before,.picker__button--clear:before,.picker__button--close:before{position:relative;display:inline-block;height:0}.picker__button--today:before,.picker__button--clear:before{content:" ";margin-right:.45em}.picker__button--today:before{top:-0.05em;width:0;border-top:0.66em solid #0059bc;border-left:.66em solid transparent}.picker__button--clear:before{top:-0.25em;width:.66em;border-top:3px solid #ee2200}.picker__button--close:before{content:"\D7";top:-0.1em;vertical-align:top;font-size:1.1em;margin-right:.35em;color:#777777}.picker__button--today[disabled],.picker__button--today[disabled]:hover{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default}.picker__button--today[disabled]:before{border-top-color:#aaaaaa}.picker__box{border-radius:2px;overflow:hidden}.picker__date-display{text-align:center;background-color:#26a69a;color:#fff;padding-bottom:15px;font-weight:300}.picker__nav--prev:hover,.picker__nav--next:hover{cursor:pointer;color:#000000;background:#a1ded8}.picker__weekday-display{background-color:#1f897f;padding:10px;font-weight:200;letter-spacing:.5;font-size:1rem;margin-bottom:15px}.picker__month-display{text-transform:uppercase;font-size:2rem}.picker__day-display{font-size:4.5rem;font-weight:400}.picker__year-display{font-size:1.8rem;color:rgba(255,255,255,0.4)}.picker__box{padding:0}.picker__calendar-container{padding:0 1rem}.picker__calendar-container thead{border:none}.picker__table{margin-top:0;margin-bottom:.5em}.picker__day--infocus{color:#595959;letter-spacing:-.3;padding:.75rem 0;font-weight:400;border:1px solid transparent}.picker__day.picker__day--today{color:#26a69a}.picker__day.picker__day--today.picker__day--selected{color:#fff}.picker__weekday{font-size:.9rem}.picker__day--selected,.picker__day--selected:hover,.picker--focused .picker__day--selected{border-radius:50%;-webkit-transform:scale(.9);-moz-transform:scale(.9);-ms-transform:scale(.9);-o-transform:scale(.9);transform:scale(.9);background-color:#26a69a;color:#ffffff}.picker__day--selected.picker__day--outfocus,.picker__day--selected:hover.picker__day--outfocus,.picker--focused .picker__day--selected.picker__day--outfocus{background-color:#a1ded8}.picker__footer{text-align:right;padding:5px 10px}.picker__close,.picker__today{font-size:1.1rem;padding:0 1rem;color:#26a69a}.picker__nav--prev:before,.picker__nav--next:before{content:" ";border-top:.5em solid transparent;border-bottom:.5em solid transparent;border-right:0.75em solid #676767;width:0;height:0;display:block;margin:0 auto}.picker__nav--next:before{border-right:0;border-left:0.75em solid #676767}button.picker__today:focus,button.picker__clear:focus,button.picker__close:focus{background-color:#a1ded8}.picker__list{list-style:none;padding:0.75em 0 4.2em;margin:0}.picker__list-item{border-bottom:1px solid #dddddd;border-top:1px solid #dddddd;margin-bottom:-1px;position:relative;background:#ffffff;padding:.75em 1.25em}@media (min-height: 46.75em){.picker__list-item{padding:.5em 1em}}.picker__list-item:hover{cursor:pointer;color:#000000;background:#b1dcfb;border-color:#0089ec;z-index:10}.picker__list-item--highlighted{border-color:#0089ec;z-index:10}.picker__list-item--highlighted:hover,.picker--focused .picker__list-item--highlighted{cursor:pointer;color:#000000;background:#b1dcfb}.picker__list-item--selected,.picker__list-item--selected:hover,.picker--focused .picker__list-item--selected{background:#0089ec;color:#ffffff;z-index:10}.picker__list-item--disabled,.picker__list-item--disabled:hover,.picker--focused .picker__list-item--disabled{background:#f5f5f5;border-color:#f5f5f5;color:#dddddd;cursor:default;border-color:#dddddd;z-index:auto}.picker--time .picker__button--clear{display:block;width:80%;margin:1em auto 0;padding:1em 1.25em;background:none;border:0;font-weight:500;font-size:.67em;text-align:center;text-transform:uppercase;color:#666}.picker--time .picker__button--clear:hover,.picker--time .picker__button--clear:focus{color:#000000;background:#b1dcfb;background:#ee2200;border-color:#ee2200;cursor:pointer;color:#ffffff;outline:none}.picker--time .picker__button--clear:before{top:-0.25em;color:#666;font-size:1.25em;font-weight:bold}.picker--time .picker__button--clear:hover:before,.picker--time .picker__button--clear:focus:before{color:#ffffff}.picker--time .picker__frame{min-width:256px;max-width:320px}.picker--time .picker__box{font-size:1em;background:#f2f2f2;padding:0}@media (min-height: 40.125em){.picker--time .picker__box{margin-bottom:5em}}
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/LICENSE.txt b/plugins/phonegap-plugin-push/example/www/font/material-design-icons/LICENSE.txt deleted file mode 100644 index 542f6537..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/LICENSE.txt +++ /dev/null @@ -1,428 +0,0 @@ -https://github.com/google/material-design-icons/blob/master/LICENSE -https://github.com/FezVrasta/bootstrap-material-design/blob/master/fonts/LICENSE.txt - -Attribution-ShareAlike 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More_considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-ShareAlike 4.0 International Public -License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - l. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - m. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - - including for purposes of Section 3(b); and - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public licenses. -Notwithstanding, Creative Commons may elect to apply one of its public -licenses to material it publishes and in those instances will be -considered the "Licensor." Except for the limited purpose of indicating -that material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the public -licenses. - -Creative Commons may be contacted at creativecommons.org. diff --git a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.eot b/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.eot Binary files differdeleted file mode 100644 index a097ba68..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.eot +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.svg b/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.svg deleted file mode 100644 index 0b2c2c24..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.svg +++ /dev/null @@ -1,751 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata>Generated by IcoMoon</metadata> -<defs> -<font id="Material-Design-Icons" horiz-adv-x="1024"> -<font-face units-per-em="1024" ascent="960" descent="-64" /> -<missing-glyph horiz-adv-x="1024" /> -<glyph unicode=" " d="" horiz-adv-x="512" /> -<glyph unicode="" d="M320.64 43.307c-139.307 66.133-239.36 201.6-254.507 362.027h-64c21.76-262.827 241.493-469.333 509.867-469.333 9.6 0 18.773 0.853 28.16 1.493l-162.56 162.773-56.96-56.96zM358.613 321.707c-8.107 0-15.573 1.067-22.4 3.627-6.613 2.347-12.373 5.76-17.067 10.027s-8.32 9.6-10.88 15.573c-2.56 6.187-3.84 12.8-3.84 20.053h-55.467c0-15.36 2.987-28.8 8.96-40.533s13.867-21.547 23.893-29.227c10.027-7.893 21.547-13.653 34.773-17.707 13.227-4.267 26.88-6.187 41.387-6.187 15.787 0 30.507 2.133 44.16 6.4s25.387 10.667 35.413 18.987 17.707 18.56 23.467 30.72c5.547 12.16 8.533 26.027 8.533 41.6 0 8.32-1.067 16.213-2.987 23.893-2.133 7.68-5.333 14.933-9.6 21.76-4.48 6.827-10.24 12.8-17.28 18.347-7.040 5.333-15.787 9.813-25.813 13.44 8.533 3.84 16 8.533 22.4 14.080s11.733 11.52 16 17.707c4.267 6.4 7.467 12.8 9.6 19.627s3.2 13.653 3.2 20.267c0 15.573-2.56 29.227-7.68 40.96s-12.373 21.547-21.76 29.44c-9.387 7.893-20.48 13.867-33.707 17.92-13.653 4.267-28.16 6.187-43.947 6.187-15.36 0-29.653-2.347-42.667-6.827s-24.107-10.88-33.493-18.987c-9.387-8.107-16.64-17.707-21.973-28.8s-7.893-23.253-7.893-36.267h55.467c0 7.253 1.28 13.653 3.84 19.2 2.56 5.76 6.187 10.667 10.667 14.507 4.48 4.053 10.027 7.253 16.213 9.387s13.013 3.413 20.267 3.413c17.067 0 29.653-4.48 37.973-13.227s12.373-21.12 12.373-36.907c0-7.68-1.067-14.507-3.413-20.693s-5.76-11.52-10.453-16c-4.693-4.48-10.667-7.893-17.493-10.453-7.040-2.56-15.36-3.84-24.747-3.84h-32.853v-43.733h32.853c9.387 0 17.92-1.067 25.387-3.2s13.867-5.333 19.2-10.027c5.333-4.48 9.387-10.24 12.373-17.067 2.773-6.827 4.267-14.933 4.267-24.32 0-17.28-4.907-30.507-14.933-39.68-9.6-8.96-23.040-13.44-40.32-13.44zM723.84 574.507c-13.44 14.080-29.653 24.96-48.427 32.64-18.987 7.68-39.68 11.52-62.507 11.52h-100.907v-341.333h97.92c23.68 0 45.013 3.84 64.427 11.52s35.84 18.56 49.493 32.64c13.653 14.080 24.32 31.147 31.573 50.987 7.467 19.84 11.093 42.24 11.093 66.987v16.853c0 24.747-3.84 46.933-11.307 66.987s-17.92 37.12-31.36 51.2zM706.987 439.253c0-17.707-1.92-33.92-6.187-48-4.053-14.293-10.027-26.24-18.133-36.053s-18.133-17.28-30.293-22.613c-12.16-5.12-26.24-7.893-42.453-7.893h-38.613v246.187h41.6c30.72 0 53.973-9.813 70.187-29.227 16-19.627 24.107-47.787 24.107-84.907v-17.493zM512 960c-9.6 0-18.773-0.853-28.16-1.493l162.56-162.773 56.747 56.747c139.52-65.92 239.573-201.387 254.72-361.813h64c-21.76 262.827-241.493 469.333-509.867 469.333z" /> -<glyph unicode="" d="M512 874.667c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333 38.187 85.333 85.333 85.333zM896 576h-256v-554.667h-85.333v256h-85.333v-256h-85.333v554.667h-256v85.333h768v-85.333z" /> -<glyph unicode="" d="M170.667 533.333v-298.667h128v298.667h-128zM426.667 533.333v-298.667h128v298.667h-128zM85.333 21.333h810.667v128h-810.667v-128zM682.667 533.333v-298.667h128v298.667h-128zM490.667 917.333l-405.333-213.333v-85.333h810.667v85.333l-405.333 213.333z" /> -<glyph unicode="" d="M896 192v-42.667c0-47.147-38.187-85.333-85.333-85.333h-597.333c-47.147 0-85.333 38.187-85.333 85.333v597.333c0 47.147 38.187 85.333 85.333 85.333h597.333c47.147 0 85.333-38.187 85.333-85.333v-42.667h-384c-47.147 0-85.333-38.187-85.333-85.333v-341.333c0-47.147 38.187-85.333 85.333-85.333h384zM512 277.333h426.667v341.333h-426.667v-341.333zM682.667 384c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M128 746.667v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333zM640 576c0-70.827-57.387-128-128-128s-128 57.173-128 128c0 70.613 57.387 128 128 128s128-57.387 128-128zM256 234.667c0 85.333 170.667 132.267 256 132.267s256-46.933 256-132.267v-42.667h-512v42.667z" /> -<glyph unicode="" d="M704 448c58.88 0 106.24 47.787 106.24 106.667s-47.36 106.667-106.24 106.667c-58.88 0-106.667-47.787-106.667-106.667s47.787-106.667 106.667-106.667zM384 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-70.613 0-128-57.387-128-128s57.387-128 128-128zM704 362.667c-78.293 0-234.667-39.253-234.667-117.333v-96h469.333v96c0 78.080-156.373 117.333-234.667 117.333zM384 405.333c-99.627 0-298.667-49.92-298.667-149.333v-106.667h298.667v96c0 36.267 14.293 99.627 101.12 148.053-37.12 7.893-73.173 11.947-101.12 11.947z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 746.667c70.613 0 128-57.387 128-128 0-70.827-57.387-128-128-128s-128 57.173-128 128c0 70.613 57.387 128 128 128zM512 140.8c-106.88 0-200.747 54.613-256 137.387 1.067 84.693 170.88 131.413 256 131.413s254.72-46.72 256-131.413c-55.253-82.773-149.12-137.387-256-137.387z" /> -<glyph unicode="" d="M469.333 576h85.333v128h128v85.333h-128v128h-85.333v-128h-128v-85.333h128v-128zM298.667 192c-47.147 0-84.907-38.187-84.907-85.333s37.76-85.333 84.907-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM725.333 192c-47.147 0-84.907-38.187-84.907-85.333s37.76-85.333 84.907-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM306.133 330.667c0 1.92 0.427 3.627 1.28 5.12l38.4 69.547h317.867c32 0 59.947 17.707 74.667 43.947l164.693 299.093-74.667 40.96h-0.213l-47.147-85.333-117.547-213.333h-299.307l-5.547 11.52-136.32 287.147-40.32 85.333h-139.307v-85.333h85.333l153.6-323.627-57.813-104.533c-6.613-12.373-10.453-26.24-10.453-41.173 0-47.147 38.187-85.333 85.333-85.333h512v85.333h-493.867c-5.973 0-10.667 4.693-10.667 10.667z" /> -<glyph unicode="" d="M938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM336.213 815.36l-54.827 65.28-196.053-164.48 54.827-65.28 196.053 164.48zM533.333 618.667h-64v-256l202.453-121.813 32.213 52.693-170.667 101.12v224zM511.787 789.333c-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384-171.947 384-384.213 384zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.547-298.667-298.667-298.667z" /> -<glyph unicode="" d="M336.213 815.36l-54.827 65.28-196.053-164.48 54.827-65.28 196.053 164.48zM938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM511.787 789.333c-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384-171.947 384-384.213 384zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.547-298.667-298.667-298.667zM554.667 576h-85.333v-128h-128v-85.333h128v-128h85.333v128h128v85.333h-128v128z" /> -<glyph unicode="" d="M512 704c164.907 0 298.667-133.76 298.667-298.667 0-36.053-6.613-70.4-18.347-102.4l64.853-64.853c24.747 50.56 38.827 107.307 38.827 167.253 0 212.053-171.947 384-384.213 384-59.947 0-116.48-14.080-167.253-38.613l65.067-65.067c32 11.733 66.347 18.347 102.4 18.347zM938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM124.587 862.080l-54.4-54.187 56.747-56.747-47.36-39.68 60.587-60.587 47.36 39.68 34.133-34.133c-58.24-67.413-93.653-155.093-93.653-251.093 0-212.053 171.52-384 383.787-384 96.213 0 183.893 35.627 251.093 93.867l93.867-93.867 54.187 54.4-786.347 786.347zM702.72 175.36c-51.84-42.88-118.187-68.693-190.72-68.693-164.907 0-298.667 133.76-298.667 298.667 0 72.533 25.813 138.88 68.693 190.72l420.693-420.693zM341.973 820.267l-60.587 60.587-36.267-30.507 60.587-60.587 36.267 30.507z" /> -<glyph unicode="" d="M938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM336.213 815.36l-54.827 65.28-196.053-164.48 54.827-65.28 196.053 164.48zM511.787 789.333c-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384-171.947 384-384.213 384zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.547-298.667-298.667-298.667zM449.493 340.267l-90.453 90.453-45.227-45.227 135.68-135.68 256.213 256.213-45.227 45.227-210.987-210.987z" /> -<glyph unicode="" d="M256 192c0-23.467 19.2-42.667 42.667-42.667h42.667v-149.333c0-35.413 28.587-64 64-64s64 28.587 64 64v149.333h85.333v-149.333c0-35.413 28.587-64 64-64s64 28.587 64 64v149.333h42.667c23.467 0 42.667 19.2 42.667 42.667v426.667h-512v-426.667zM149.333 618.667c-35.413 0-64-28.587-64-64v-298.667c0-35.413 28.587-64 64-64s64 28.587 64 64v298.667c0 35.413-28.587 64-64 64zM874.667 618.667c-35.413 0-64-28.587-64-64v-298.667c0-35.413 28.587-64 64-64s64 28.587 64 64v298.667c0 35.413-28.587 64-64 64zM662.613 867.84l55.68 55.68c8.32 8.32 8.32 21.76 0 30.080s-21.76 8.32-30.080 0l-63.147-62.933c-34.133 16.853-72.32 26.667-113.067 26.667-40.96 0-79.36-9.813-113.707-26.88l-63.36 63.36c-8.32 8.32-21.76 8.32-30.080 0s-8.32-21.76 0-30.080l55.893-55.893c-63.36-46.72-104.747-121.813-104.747-206.507h512c0 84.907-41.6 160-105.387 206.507zM426.667 746.667h-42.667v42.667h42.667v-42.667zM640 746.667h-42.667v42.667h42.667v-42.667z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM554.667 490.667h-85.333v256h85.333v-256zM554.667 320h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M810.667 448h-85.333v-128h-128v-85.333h213.333v213.333zM298.667 576h128v85.333h-213.333v-213.333h85.333v128zM896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 148.693h-768v598.613h768v-598.613z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM384 234.667h-85.333v298.667h85.333v-298.667zM554.667 234.667h-85.333v426.667h85.333v-426.667zM725.333 234.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M810.667 832h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 832c23.467 0 42.667-18.987 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 18.987-42.667 42.667 19.2 42.667 42.667 42.667zM597.333 234.667h-298.667v85.333h298.667v-85.333zM725.333 405.333h-426.667v85.333h426.667v-85.333zM725.333 576h-426.667v85.333h426.667v-85.333z" /> -<glyph unicode="" d="M810.667 832h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 832c23.467 0 42.667-18.987 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 18.987-42.667 42.667 19.2 42.667 42.667 42.667zM512 661.333c70.613 0 128-57.387 128-128 0-70.827-57.387-128-128-128s-128 57.173-128 128c0 70.613 57.387 128 128 128zM768 149.333h-512v59.733c0 85.333 170.667 132.267 256 132.267s256-46.933 256-132.267v-59.733z" /> -<glyph unicode="" d="M810.667 832h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM554.667 192h-85.333v85.333h85.333v-85.333zM554.667 362.667h-85.333v256h85.333v-256zM512 746.667c-23.467 0-42.667 18.987-42.667 42.667s19.2 42.667 42.667 42.667 42.667-18.987 42.667-42.667-19.2-42.667-42.667-42.667z" /> -<glyph unicode="" d="M810.667 832h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 832c23.467 0 42.667-18.987 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 18.987-42.667 42.667 19.2 42.667 42.667 42.667zM682.667 320h-170.667v-128l-213.333 213.333 213.333 213.333v-128h170.667v-170.667z" /> -<glyph unicode="" d="M810.667 832h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 832c23.467 0 42.667-18.987 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 18.987-42.667 42.667 19.2 42.667 42.667 42.667zM512 192l-213.333 213.333h128v170.667h170.667v-170.667h128l-213.333-213.333z" /> -<glyph unicode="" d="M810.667 832h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 832c23.467 0 42.667-18.987 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 18.987-42.667 42.667 19.2 42.667 42.667 42.667zM426.667 234.667l-170.667 170.667 60.373 60.373 110.293-110.293 280.96 280.96 60.373-60.373-341.333-341.333z" /> -<glyph unicode="" d="M512 704v-128l170.667 170.667-170.667 170.667v-128c-188.587 0-341.333-152.747-341.333-341.333 0-66.987 19.627-129.067 52.907-181.76l62.293 62.293c-18.987 35.627-29.867 76.16-29.867 119.467 0 141.44 114.56 256 256 256zM800.427 629.76l-62.293-62.293c18.987-35.627 29.867-76.16 29.867-119.467 0-141.44-114.56-256-256-256v128l-170.667-170.667 170.667-170.667v128c188.587 0 341.333 152.747 341.333 341.333 0 66.987-19.627 129.067-52.907 181.76z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84zM597.333 405.333v-170.667h-170.667v170.667h-128l213.333 213.333 213.333-213.333h-128z" /> -<glyph unicode="" d="M768 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM256 789.333h213.333v-341.333l-106.667 64-106.667-64v341.333z" /> -<glyph unicode="" d="M725.333 832h-426.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667 298.667 128 298.667-128v682.667c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M725.333 832h-426.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667 298.667 128 298.667-128v682.667c0 47.147-38.187 85.333-85.333 85.333zM725.333 192l-213.333 92.8-213.333-92.8v554.667h426.667v-554.667z" /> -<glyph unicode="" d="M853.333 618.667h-119.893c-19.2 33.28-45.653 62.080-77.44 83.627l69.333 69.333-60.373 60.373-92.8-92.8c-19.2 4.693-39.467 7.467-60.16 7.467s-40.96-2.773-60.16-7.467l-92.8 92.8-60.373-60.373 69.333-69.333c-31.787-21.547-58.24-50.347-77.44-83.627h-119.893v-85.333h89.173c-2.347-13.867-3.84-28.16-3.84-42.667v-42.667h-85.333v-85.333h85.333v-42.667c0-14.507 1.493-28.8 3.84-42.667h-89.173v-85.333h119.893c44.16-76.373 126.72-128 221.44-128s177.28 51.627 221.44 128h119.893v85.333h-89.173c2.347 13.867 3.84 28.16 3.84 42.667v42.667h85.333v85.333h-85.333v42.667c0 14.507-1.493 28.8-3.84 42.667h89.173v85.333zM597.333 277.333h-170.667v85.333h170.667v-85.333zM597.333 448h-170.667v85.333h170.667v-85.333z" /> -<glyph unicode="" d="M810.667 618.667l-170.667-170.667h128c0-141.44-114.56-256-256-256-43.307 0-83.84 10.88-119.68 29.653l-62.293-62.293c52.907-33.067 114.987-52.693 181.973-52.693 188.587 0 341.333 152.747 341.333 341.333h128l-170.667 170.667zM256 448c0 141.44 114.56 256 256 256 43.307 0 83.84-10.88 119.68-29.653l62.293 62.293c-52.907 33.067-114.987 52.693-181.973 52.693-188.587 0-341.333-152.747-341.333-341.333h-128l170.667-170.667 170.667 170.667h-128z" /> -<glyph unicode="" d="M768 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM256 789.333h213.333v-341.333l-106.667 64-106.667-64v341.333z" /> -<glyph unicode="" d="M170.667 448h682.667v-256h-682.667zM853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 192h-682.667v256h682.667v-256zM853.333 618.667h-682.667v85.333h682.667v-85.333z" /> -<glyph unicode="" d="M128 405.333h341.333v426.667h-341.333v-426.667zM128 64h341.333v256h-341.333v-256zM554.667 64h341.333v426.667h-341.333v-426.667zM554.667 832v-256h341.333v256h-341.333z" /> -<glyph unicode="" d="M256 149.333c0-47.147 38.187-85.333 85.333-85.333h341.333c47.147 0 85.333 38.187 85.333 85.333v512h-512v-512zM810.667 789.333h-149.333l-42.667 42.667h-213.333l-42.667-42.667h-149.333v-85.333h597.333v85.333z" /> -<glyph unicode="" d="M597.333 874.667h-341.333c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667c0-47.147 37.76-85.333 84.907-85.333h512.427c47.147 0 85.333 38.187 85.333 85.333v512l-256 256zM682.667 192h-341.333v85.333h341.333v-85.333zM682.667 362.667h-341.333v85.333h341.333v-85.333zM554.667 576v234.667l234.667-234.667h-234.667z" /> -<glyph unicode="" d="M853.333 405.333h-682.667c-23.467 0-42.667-19.2-42.667-42.667v-256c0-23.467 19.2-42.667 42.667-42.667h682.667c23.467 0 42.667 19.2 42.667 42.667v256c0 23.467-19.2 42.667-42.667 42.667zM298.667 149.333c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM853.333 832h-682.667c-23.467 0-42.667-19.2-42.667-42.667v-256c0-23.467 19.2-42.667 42.667-42.667h682.667c23.467 0 42.667 19.2 42.667 42.667v256c0 23.467-19.2 42.667-42.667 42.667zM298.667 576c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M384 270.080l-177.92 177.92-60.373-60.373 238.293-238.293 512 512-60.373 60.373z" /> -<glyph unicode="" d="M768 661.333l-60.373 60.373-270.507-270.72 60.373-60.373 270.507 270.72zM949.12 721.707l-451.84-451.627-177.92 177.92-60.373-60.373 238.293-238.293 512 512-60.16 60.373zM17.707 387.627l238.293-238.293 60.373 60.373-238.293 238.293-60.373-60.373z" /> -<glyph unicode="" d="M725.333 448h-213.333v-213.333h213.333v213.333zM682.667 917.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333h-42.667v85.333h-85.333zM810.667 149.333h-597.333v469.333h597.333v-469.333z" /> -<glyph unicode="" d="M430.293 295.040l60.373-60.373 213.333 213.333-213.333 213.333-60.373-60.373 110.293-110.293h-412.587v-85.333h412.587l-110.293-110.293zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-170.667h85.333v170.667h597.333v-597.333h-597.333v170.667h-85.333v-170.667c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M512 494.933c-25.813 0-46.933-21.12-46.933-46.933s21.12-46.933 46.933-46.933c26.027 0 46.933 21.12 46.933 46.933s-20.907 46.933-46.933 46.933zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667 0-235.52 190.933-426.667 426.667-426.667s426.667 191.147 426.667 426.667c0 235.733-190.933 426.667-426.667 426.667zM605.44 354.56l-349.44-162.56 162.56 349.44 349.44 162.56-162.56-349.44z" /> -<glyph unicode="" d="M874.667 490.667h-64v170.667c0 47.147-38.187 85.333-85.333 85.333h-170.667v64c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667v-64h-170.667c-47.147 0-84.907-38.187-84.907-85.333l-0.213-162.133h63.787c63.573 0 115.2-51.627 115.2-115.2s-51.627-115.2-115.2-115.2h-63.787l-0.213-162.133c0-47.147 38.187-85.333 85.333-85.333h162.133v64c0 63.573 51.627 115.2 115.2 115.2s115.2-51.627 115.2-115.2v-64h162.133c47.147 0 85.333 38.187 85.333 85.333v170.667h64c58.88 0 106.667 47.787 106.667 106.667s-47.787 106.667-106.667 106.667z" /> -<glyph unicode="" d="M626.987 230.187c-31.787-24.533-72.533-38.187-114.987-38.187s-83.2 13.653-114.987 38.187c-9.173 7.253-22.613 5.547-29.867-3.84s-5.547-22.613 3.84-29.867c39.040-30.293 89.173-47.147 141.013-47.147s101.973 16.853 141.013 47.147c9.387 7.253 11.093 20.693 3.84 29.867-7.253 9.387-20.693 11.093-29.867 3.84zM405.333 426.667c0-23.564-19.103-42.667-42.667-42.667s-42.667 19.103-42.667 42.667c0 23.564 19.103 42.667 42.667 42.667s42.667-19.103 42.667-42.667zM512 960c-282.667 0-512-229.333-512-512s229.333-512 512-512 512 229.333 512 512-229.333 512-512 512zM851.627 327.68c-46.507-159.573-182.187-275.413-343.040-275.413-161.067 0-296.96 116.267-343.253 276.267-50.773 4.267-90.667 50.347-90.667 107.093 0 54.187 36.48 98.773 83.84 106.453v0.213c89.173 62.507 162.347 148.907 174.72 215.467l0.213-0.213v0.64c57.813-112 268.8-221.44 504.533-215.893 4.267 0.64 8.32 1.493 12.587 1.493 54.4 0 98.56-48.427 98.56-108.16 0.213-59.307-43.52-107.52-97.493-107.947zM704 426.667c0-23.564-19.103-42.667-42.667-42.667s-42.667 19.103-42.667 42.667c0 23.564 19.103 42.667 42.667 42.667s42.667-19.103 42.667-42.667z" /> -<glyph unicode="" d="M512 49.067l-61.867 56.107c-219.733 199.467-364.8 331.093-364.8 492.16 0 131.627 103.040 234.667 234.667 234.667 74.24 0 145.493-34.56 192-88.96 46.507 54.4 117.76 88.96 192 88.96 131.627 0 234.667-103.040 234.667-234.667 0-161.067-145.067-292.693-364.8-492.16l-61.867-56.107z" /> -<glyph unicode="" d="M704 832c-74.24 0-145.493-34.56-192-88.96-46.507 54.4-117.76 88.96-192 88.96-131.627 0-234.667-103.040-234.667-234.667 0-161.067 145.067-292.693 364.8-492.16l61.867-56.107 61.867 56.107c219.733 199.467 364.8 331.093 364.8 492.16 0 131.627-103.040 234.667-234.667 234.667zM516.48 168.32l-4.48-4.053-4.48 4.053c-202.88 184.107-336.853 305.707-336.853 429.013 0 85.12 64.213 149.333 149.333 149.333 65.707 0 129.707-42.453 152.107-100.693h79.573c22.613 58.24 86.613 100.693 152.32 100.693 85.12 0 149.333-64.213 149.333-149.333 0-123.307-133.973-244.907-336.853-429.013z" /> -<glyph unicode="" d="M853.333 124.373v494.293l-256 256h-341.333c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667c0-47.147 37.76-85.333 84.907-85.333h512.427c18.987 0 36.48 6.4 50.56 17.067l-189.227 189.227c-33.493-22.4-73.813-35.627-117.333-35.627-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333c0-43.52-13.227-83.84-35.413-117.547l163.413-163.413zM384 405.333c0-70.613 57.387-128 128-128s128 57.387 128 128-57.387 128-128 128-128-57.387-128-128z" /> -<glyph unicode="" d="M469.333 704c58.88 0 112.213-23.893 150.827-62.507l-108.16-108.16h256v256l-87.467-87.467c-53.973 53.973-128.64 87.467-211.2 87.467-150.4 0-274.56-111.36-295.253-256h86.187c19.84 97.28 105.813 170.667 209.067 170.667zM709.973 314.24c28.373 38.613 47.573 84.267 54.613 133.76h-86.187c-19.84-97.28-105.813-170.667-209.067-170.667-58.88 0-112.213 23.893-150.827 62.507l108.16 108.16h-256v-256l87.467 87.467c53.973-53.973 128.64-87.467 211.2-87.467 66.133 0 127.147 21.76 176.64 58.24l207.36-207.147 63.573 63.573-206.933 207.573z" /> -<glyph unicode="" d="M384 661.333h-85.333v-85.333h85.333v85.333zM384 490.667h-85.333v-85.333h85.333v85.333zM384 832c-47.147 0-85.333-38.187-85.333-85.333h85.333v85.333zM554.667 320h-85.333v-85.333h85.333v85.333zM810.667 832v-85.333h85.333c0 47.147-38.187 85.333-85.333 85.333zM554.667 832h-85.333v-85.333h85.333v85.333zM384 234.667v85.333h-85.333c0-47.147 38.187-85.333 85.333-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM810.667 234.667c47.147 0 85.333 38.187 85.333 85.333h-85.333v-85.333zM213.333 661.333h-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512v85.333h-512v512zM640 746.667h85.333v85.333h-85.333v-85.333zM640 234.667h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M128 405.333h85.333v85.333h-85.333v-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM213.333 64v85.333h-85.333c0-47.147 38.187-85.333 85.333-85.333zM128 576h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM810.667 832h-426.667c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 320h-426.667v426.667h426.667v-426.667zM469.333 64h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M810.667 576h-170.667v256h-256v-256h-170.667l298.667-298.667 298.667 298.667zM213.333 192v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M512 223.147l263.68-159.147-69.76 299.947 232.747 201.6-306.773 26.453-119.893 282.667-119.893-282.667-306.773-26.453 232.747-201.6-69.76-299.947z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667 0-235.52 190.933-426.667 426.667-426.667s426.667 191.147 426.667 426.667c0 235.733-190.933 426.667-426.667 426.667zM341.333 213.333c-58.88 0-106.667 47.787-106.667 106.667s47.787 106.667 106.667 106.667 106.667-47.787 106.667-106.667-47.787-106.667-106.667-106.667zM405.333 618.667c0 58.88 47.787 106.667 106.667 106.667s106.667-47.787 106.667-106.667-47.787-106.667-106.667-106.667-106.667 47.787-106.667 106.667zM682.667 213.333c-58.88 0-106.667 47.787-106.667 106.667s47.787 106.667 106.667 106.667 106.667-47.787 106.667-106.667-47.787-106.667-106.667-106.667z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM554.667 149.333h-85.333v85.333h85.333v-85.333zM642.773 479.787l-38.187-39.253c-30.72-30.72-49.92-56.533-49.92-120.533h-85.333v21.333c0 47.147 19.2 89.813 49.92 120.747l53.12 53.76c15.36 15.36 24.96 36.693 24.96 60.16 0 47.147-38.187 85.333-85.333 85.333s-85.333-38.187-85.333-85.333h-85.333c0 94.293 76.373 170.667 170.667 170.667s170.667-76.373 170.667-170.667c0-37.547-15.147-71.467-39.893-96.213z" /> -<glyph unicode="" d="M622.293 618.667l-110.293-110.293-110.293 110.293-60.373-60.373 110.293-110.293-110.293-110.293 60.373-60.373 110.293 110.293 110.293-110.293 60.373 60.373-110.293 110.293 110.293 110.293-60.373 60.373zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M554.453 832c-212.267 0-383.787-171.947-383.787-384h-128l166.187-166.187 2.987-6.187 172.16 172.373h-128c0 164.907 133.76 298.667 298.667 298.667s298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667c-82.56 0-157.013 33.707-210.987 87.68l-60.373-60.373c69.333-69.547 165.12-112.64 271.147-112.64 212.267 0 384.213 171.947 384.213 384s-171.947 384-384.213 384zM512 618.667v-213.333l182.613-108.373 30.72 51.84-149.333 88.533v181.333h-64z" /> -<glyph unicode="" d="M426.667 106.667v256h170.667v-256h213.333v341.333h128l-426.667 384-426.667-384h128v-341.333z" /> -<glyph unicode="" d="M768 618.667h-42.667v85.333c0 117.76-95.573 213.333-213.333 213.333s-213.333-95.573-213.333-213.333v-85.333h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM512 234.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM644.267 618.667h-264.533v85.333c0 72.96 59.307 132.267 132.267 132.267s132.267-59.307 132.267-132.267v-85.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM554.667 234.667h-85.333v256h85.333v-256zM554.667 576h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M469.333 234.667h85.333v256h-85.333v-256zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333zM469.333 576h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M896 831.573h-768c-47.147 0-85.333-38.187-85.333-85.333v-170.24h85.333v171.093h768v-598.613h-768v171.52h-85.333v-171.093c0-47.147 38.187-84.48 85.333-84.48h768c47.147 0 85.333 37.547 85.333 84.48v597.333c0 47.147-38.187 85.333-85.333 85.333zM469.333 277.333l170.667 170.667-170.667 170.667v-128h-426.667v-85.333h426.667v-128z" /> -<glyph unicode="" d="M753.28 621.653l-241.28 241.493-241.28-241.493c-133.333-133.333-133.333-349.44 0-482.773 66.56-66.56 154.027-100.053 241.28-100.053s174.72 33.28 241.28 100.053c133.333 133.333 133.333 349.44 0 482.773zM512 124.373c-68.48 0-132.693 26.667-180.907 75.093-48.427 48.213-75.093 112.427-75.093 180.907s26.667 132.693 75.093 181.12l180.907 180.907v-618.027z" /> -<glyph unicode="" d="M752.427 710.613c-15.573 21.76-40.96 36.053-69.76 36.053l-469.333-0.427c-47.147 0-85.333-37.76-85.333-84.907v-426.667c0-47.147 38.187-84.907 85.333-84.907l469.333-0.427c28.8 0 54.187 14.293 69.76 36.053l186.24 262.613-186.24 262.613z" /> -<glyph unicode="" d="M752.427 710.613c-15.573 21.76-40.96 36.053-69.76 36.053l-469.333-0.427c-47.147 0-85.333-37.76-85.333-84.907v-426.667c0-47.147 38.187-84.907 85.333-84.907l469.333-0.427c28.8 0 54.187 14.293 69.76 36.053l186.24 262.613-186.24 262.613zM682.667 234.667h-469.333v426.667h469.333l151.253-213.333-151.253-213.333z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM807.253 618.667h-125.867c-13.867 53.333-33.28 104.533-58.88 151.893 78.507-26.88 143.787-81.28 184.747-151.893zM512 787.84c35.627-51.2 63.36-108.16 81.493-169.173h-162.987c18.133 61.013 45.867 117.973 81.493 169.173zM181.76 362.667c-7.040 27.307-11.093 55.893-11.093 85.333s4.053 58.027 11.093 85.333h144c-3.413-27.947-5.76-56.32-5.76-85.333s2.347-57.387 5.973-85.333h-144.213zM216.533 277.333h125.867c13.867-53.333 33.28-104.533 58.88-152.107-78.507 26.88-143.787 81.493-184.747 152.107zM342.4 618.667h-125.867c40.96 70.613 106.24 125.227 184.747 152.107-25.6-47.573-45.013-98.773-58.88-152.107zM512 108.16c-35.413 51.2-63.147 108.16-81.493 169.173h162.987c-18.347-61.013-46.080-117.973-81.493-169.173zM611.84 362.667h-199.68c-4.053 27.947-6.827 56.32-6.827 85.333s2.773 57.387 6.827 85.333h199.68c4.053-27.947 6.827-56.32 6.827-85.333s-2.773-57.387-6.827-85.333zM622.72 125.44c25.6 47.573 45.013 98.56 58.88 151.893h125.867c-41.173-70.613-106.453-125.013-184.747-151.893zM698.027 362.667c3.413 27.947 5.973 56.32 5.973 85.333s-2.347 57.387-5.973 85.333h144c7.040-27.307 11.307-55.893 11.307-85.333s-4.053-58.027-11.307-85.333h-144z" /> -<glyph unicode="" d="M810.667 149.333h-597.333v597.333h298.667v85.333h-298.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v298.667h-85.333v-298.667zM597.333 832v-85.333h152.96l-419.413-419.413 60.373-60.373 419.413 419.413v-152.96h85.333v298.667h-298.667z" /> -<glyph unicode="" d="M128 405.333h85.333v85.333h-85.333v-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM128 576h85.333v85.333h-85.333v-85.333zM298.667 405.333h597.333v85.333h-597.333v-85.333zM298.667 234.667h597.333v85.333h-597.333v-85.333zM298.667 661.333v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M768 618.667h-42.667v85.333c0 117.76-95.573 213.333-213.333 213.333s-213.333-95.573-213.333-213.333v-85.333h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM512 234.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM644.267 618.667h-264.533v85.333c0 72.96 59.307 132.267 132.267 132.267s132.267-59.307 132.267-132.267v-85.333z" /> -<glyph unicode="" d="M512 234.667c47.147 0 85.333 38.187 85.333 85.333s-38.187 85.333-85.333 85.333-85.333-38.187-85.333-85.333 38.187-85.333 85.333-85.333zM768 618.667h-42.667v85.333c0 117.76-95.573 213.333-213.333 213.333s-213.333-95.573-213.333-213.333h81.067c0 72.96 59.307 132.267 132.267 132.267s132.267-59.307 132.267-132.267v-85.333h-388.267c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM768 106.667h-512v426.667h512v-426.667z" /> -<glyph unicode="" d="M768 618.667h-42.667v85.333c0 117.76-95.573 213.333-213.333 213.333s-213.333-95.573-213.333-213.333v-85.333h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM512 836.267c72.96 0 132.267-59.307 132.267-132.267v-85.333h-260.267v85.333h-4.267c0 72.96 59.307 132.267 132.267 132.267zM768 106.667h-512v426.667h512v-426.667zM512 234.667c47.147 0 85.333 38.187 85.333 85.333s-38.187 85.333-85.333 85.333-85.333-38.187-85.333-85.333 38.187-85.333 85.333-85.333z" /> -<glyph unicode="" d="M913.493 465.92l-383.787 383.787c-15.36 15.36-36.693 24.96-60.373 24.96h-298.667c-47.147 0-85.333-38.187-85.333-85.333v-298.667c0-23.68 9.6-45.013 25.173-60.373l384-384c15.36-15.36 36.693-24.96 60.16-24.96 23.68 0 45.013 9.6 60.373 24.96l298.667 298.667c15.36 15.573 24.96 36.907 24.96 60.373 0 23.68-9.6 45.013-25.173 60.587zM234.667 661.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM736.853 308.48l-182.187-182.187-182.187 182.187c-19.2 19.413-31.147 46.080-31.147 75.52 0 58.88 47.787 106.667 106.667 106.667 29.44 0 56.32-11.947 75.52-31.36l31.147-31.147 31.147 31.147c19.413 19.413 46.080 31.36 75.52 31.36 58.88 0 106.667-47.787 106.667-106.667 0-29.44-11.947-56.107-31.147-75.52z" /> -<glyph unicode="" d="M853.333 704h-426.667v-256h-85.333v341.333h256v170.667h-341.333v-256h-85.333c-46.933 0-85.333-38.4-85.333-85.333v-512c0-46.933 38.4-85.333 85.333-85.333h682.667c46.933 0 85.333 38.4 85.333 85.333v512c0 46.933-38.4 85.333-85.333 85.333z" /> -<glyph unicode="" d="M597.333 874.667h-341.333c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667c0-47.147 37.76-85.333 84.907-85.333h512.427c47.147 0 85.333 38.187 85.333 85.333v512l-256 256zM682.667 277.333h-128v-128h-85.333v128h-128v85.333h128v128h85.333v-128h128v-85.333zM554.667 576v234.667l234.667-234.667h-234.667z" /> -<glyph unicode="" d="M810.667 789.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h170.667v85.333h-170.667v426.667h597.333v-426.667h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM512 533.333l-170.667-170.667h128v-256h85.333v256h128l-170.667 170.667z" /> -<glyph unicode="" d="M810.667 149.333h-597.333v597.333h298.667v85.333h-298.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v298.667h-85.333v-298.667zM597.333 832v-85.333h152.96l-419.413-419.413 60.373-60.373 419.413 419.413v-152.96h85.333v298.667h-298.667z" /> -<glyph unicode="" d="M426.667 576h170.667v128h128l-213.333 213.333-213.333-213.333h128v-128zM384 533.333h-128v128l-213.333-213.333 213.333-213.333v128h128v170.667zM981.333 448l-213.333 213.333v-128h-128v-170.667h128v-128l213.333 213.333zM597.333 320h-170.667v-128h-128l213.333-213.333 213.333 213.333h-128v128z" /> -<glyph unicode="" d="M469.333 618.667c-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128-57.387 128-128 128zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM750.293 149.333l-163.413 163.413c-33.707-22.187-74.027-35.413-117.547-35.413-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333c0-43.52-13.227-83.84-35.413-117.547l163.413-163.413-60.373-60.373z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 192h-682.667v256h682.667v-256zM853.333 618.667h-682.667v85.333h682.667v-85.333z" /> -<glyph unicode="" d="M853.333 746.667h-135.253l-78.080 85.333h-256l-78.080-85.333h-135.253c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h298.667v89.173c-120.96 20.48-213.333 125.653-213.333 252.16h85.333c0-94.080 76.587-170.667 170.667-170.667s170.667 76.587 170.667 170.667h85.333c0-126.507-92.373-231.68-213.333-252.16v-89.173h298.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM597.333 405.333c0-47.147-38.187-85.333-85.333-85.333s-85.333 38.187-85.333 85.333v170.667c0 47.147 38.187 85.333 85.333 85.333s85.333-38.187 85.333-85.333v-170.667z" /> -<glyph unicode="" d="M810.667 832h-42.667v85.333h-85.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 704c70.613 0 128-57.387 128-128 0-70.827-57.387-128-128-128s-128 57.173-128 128c0 70.613 57.387 128 128 128zM768 192h-512v42.667c0 85.333 170.667 132.267 256 132.267s256-46.933 256-132.267v-42.667z" /> -<glyph unicode="" d="M810.24 469.333c14.507 0 29.013-1.28 43.093-3.2v493.867l-853.333-853.333h493.44c-1.92 14.080-3.2 28.16-3.2 42.667 0 176.64 143.36 320 320 320zM968.747 128.427c0.853 6.827 1.493 13.653 1.493 20.907 0 7.040-0.64 14.080-1.493 20.907l45.013 35.2c4.053 3.2 5.12 8.96 2.56 13.653l-42.667 73.813c-2.56 4.693-8.32 6.4-13.013 4.693l-53.12-21.333c-11.093 8.533-23.040 15.573-36.053 20.907l-7.893 56.533c-0.853 5.12-5.333 8.96-10.667 8.96h-85.333c-5.333 0-9.813-3.84-10.453-8.96l-7.893-56.533c-13.013-5.333-24.96-12.587-36.053-20.907l-53.12 21.333c-4.907 1.92-10.453 0-13.013-4.693l-42.667-73.813c-2.773-4.693-1.493-10.453 2.56-13.653l45.013-35.2c-0.853-6.827-1.493-13.867-1.493-20.907s0.64-14.080 1.493-20.907l-45.013-35.2c-4.053-3.2-5.12-8.96-2.56-13.653l42.667-73.813c2.773-4.693 8.32-6.4 13.013-4.693l53.12 21.333c11.093-8.533 23.040-15.573 36.053-20.907l7.893-56.533c0.853-5.12 5.333-8.96 10.453-8.96h85.333c5.333 0 9.6 3.84 10.453 8.96l7.893 56.533c13.013 5.333 24.96 12.587 36.053 20.907l53.12-21.333c4.907-1.92 10.453 0 13.013 4.693l42.667 73.813c2.773 4.693 1.493 10.453-2.56 13.653l-44.8 35.2zM810.24 85.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M554.667 661.333h-85.333v-85.333h85.333v85.333zM554.667 490.667h-85.333v-256h85.333v256zM725.333 916.907l-426.667 0.427c-47.147 0-85.333-38.187-85.333-85.333v-768c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v768c0 47.147-38.187 84.907-85.333 84.907zM725.333 149.333h-426.667v597.333h426.667v-597.333z" /> -<glyph unicode="" d="M512 708.267c49.493 0 89.6-40.107 89.6-89.6s-40.107-89.6-89.6-89.6-89.6 40.107-89.6 89.6 40.107 89.6 89.6 89.6zM512 324.267c126.933 0 260.267-62.080 260.267-89.6v-46.933h-520.533v46.933c0 27.52 133.333 89.6 260.267 89.6zM512 789.333c-94.293 0-170.667-76.373-170.667-170.667 0-94.080 76.373-170.667 170.667-170.667s170.667 76.587 170.667 170.667c0 94.293-76.373 170.667-170.667 170.667zM512 405.333c-113.707 0-341.333-56.96-341.333-170.667v-128h682.667v128c0 113.707-227.627 170.667-341.333 170.667z" /> -<glyph unicode="" d="M85.333 704h-85.333v-213.333h0.427l-0.427-384c0-47.147 38.187-85.333 85.333-85.333h768v85.333h-768v597.333zM938.667 789.333h-341.333l-85.333 85.333h-256c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM298.667 320l192 256 149.333-192.213 106.667 128.213 149.333-192h-597.333z" /> -<glyph unicode="" d="M853.333 298.667c-53.12 0-104.533 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.293c11.733 11.733 15.147 28.587 10.453 43.307-15.787 47.787-24.32 99.2-24.32 152.32 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.467 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667zM512 832v-426.667l128 128h256v298.667h-384z" /> -<glyph unicode="" d="M512 832c-215.253 0-377.813-78.933-512-180.693l512-629.973 512 629.333c-134.187 101.547-296.747 181.333-512 181.333zM554.667 277.333h-85.333v256h85.333v-256zM469.333 618.667v85.333h85.333v-85.333h-85.333z" /> -<glyph unicode="" d="M810.667 661.333h-341.333v-256h341.333v256zM896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-84.48 85.333-84.48h768c47.147 0 85.333 37.547 85.333 84.48v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 148.693h-768v598.613h768v-598.613z" /> -<glyph unicode="" d="M810.667 789.333h-170.667l-336.853-538.88-111.147 197.547 192 341.333h-170.667l-192-341.333 192-341.333h170.667l336.853 538.88 111.147-197.547-192-341.333h170.667l192 341.333z" /> -<glyph unicode="" d="M810.667 618.667h-597.333c-70.613 0-128-57.387-128-128v-256h170.667v-170.667h512v170.667h170.667v256c0 70.613-57.387 128-128 128zM682.667 149.333h-341.333v213.333h341.333v-213.333zM810.667 448c-23.68 0-42.667 18.987-42.667 42.667s18.987 42.667 42.667 42.667c23.68 0 42.667-18.987 42.667-42.667s-18.987-42.667-42.667-42.667zM768 832h-512v-170.667h512v170.667z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM533.333 661.333h-64v-256l223.787-134.4 32.213 52.48-192 113.92z" /> -<glyph unicode="" d="M896 704h-85.333v-384h-554.667v-85.333c0-23.467 19.2-42.667 42.667-42.667h469.333l170.667-170.667v640c0 23.467-19.2 42.667-42.667 42.667zM725.333 448v384c0 23.467-19.2 42.667-42.667 42.667h-554.667c-23.467 0-42.667-19.2-42.667-42.667v-597.333l170.667 170.667h426.667c23.467 0 42.667 19.2 42.667 42.667z" /> -<glyph unicode="" d="M768 234.667h-512v85.333h512v-85.333zM768 405.333h-512v85.333h512v-85.333zM768 576h-512v85.333h512v-85.333zM128 21.333l64 64 64-64 64 64 64-64 64 64 64-64 64 64 64-64 64 64 64-64 64 64 64-64v853.333l-64-64-64 64-64-64-64 64-64-64-64 64-64-64-64 64-64-64-64 64-64-64-64 64v-853.333z" /> -<glyph unicode="" d="M853.333 704h-93.227c4.693 13.44 7.893 27.52 7.893 42.667 0 70.613-57.387 128-128 128-44.587 0-83.84-22.827-106.667-57.387l-21.333-29.013-21.333 29.013c-22.827 34.56-62.080 57.387-106.667 57.387-70.613 0-128-57.387-128-128 0-15.147 2.987-29.227 7.893-42.667h-93.227c-47.147 0-84.907-38.187-84.907-85.333l-0.427-469.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM640 789.333c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM384 789.333c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM853.333 149.333h-682.667v85.333h682.667v-85.333zM853.333 362.667h-682.667v256h216.747l-88.747-120.96 69.333-49.707 144 196.053 42.667-58.027 101.333-138.027 69.333 49.707-88.747 120.96h216.747v-256z" /> -<glyph unicode="" d="M42.667 64h938.667l-469.333 810.667-469.333-810.667zM554.667 192h-85.333v85.333h85.333v-85.333zM554.667 362.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M554.453 832c-212.267 0-383.787-171.947-383.787-384h-128l166.187-166.187 2.987-6.187 172.16 172.373h-128c0 164.907 133.76 298.667 298.667 298.667s298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667c-82.56 0-157.013 33.707-210.987 87.68l-60.373-60.373c69.333-69.547 165.12-112.64 271.147-112.64 212.267 0 384.213 171.947 384.213 384s-171.947 384-384.213 384zM512 618.667v-213.333l182.613-108.373 30.72 51.84-149.333 88.533v181.333h-64z" /> -<glyph unicode="" d="M512 874.667c-164.907 0-298.667-133.76-298.667-298.667 0-224 298.667-554.667 298.667-554.667s298.667 330.667 298.667 554.667c0 164.907-133.76 298.667-298.667 298.667zM512 469.333c-58.88 0-106.667 47.787-106.667 106.667s47.787 106.667 106.667 106.667 106.667-47.787 106.667-106.667-47.787-106.667-106.667-106.667z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM533.333 661.333h-64v-256l223.787-134.4 32.213 52.48-192 113.92z" /> -<glyph unicode="" d="M661.333 362.667h-33.92l-11.733 11.733c41.813 48.427 66.987 111.36 66.987 180.267 0 153.173-124.16 277.333-277.333 277.333s-277.333-124.16-277.333-277.333 124.16-277.333 277.333-277.333c68.907 0 131.84 25.173 180.267 66.773l11.733-11.733v-33.707l213.333-212.907 63.573 63.573-212.907 213.333zM405.333 362.667c-106.027 0-192 85.973-192 192s85.973 192 192 192 192-85.973 192-192-85.973-192-192-192z" /> -<glyph unicode="" d="M829.013 406.4c1.707 13.653 2.987 27.52 2.987 41.6s-1.28 27.947-2.987 41.6l90.24 70.613c8.107 6.4 10.453 17.92 5.12 27.307l-85.333 147.84c-5.333 9.173-16.427 13.013-26.027 9.173l-106.24-42.88c-21.973 16.853-46.080 31.147-72.107 42.027l-16 113.067c-1.92 10.027-10.667 17.92-21.333 17.92h-170.667c-10.667 0-19.413-7.893-21.12-17.92l-16-113.067c-26.027-10.88-50.133-24.96-72.107-42.027l-106.24 42.88c-9.6 3.627-20.693 0-26.027-9.173l-85.333-147.84c-5.333-9.173-2.987-20.693 5.12-27.307l90.027-70.613c-1.707-13.653-2.987-27.52-2.987-41.6s1.28-27.947 2.987-41.6l-90.027-70.613c-8.107-6.4-10.453-17.92-5.12-27.307l85.333-147.84c5.333-9.173 16.427-13.013 26.027-9.173l106.24 42.88c21.973-16.853 46.080-31.147 72.107-42.027l16-113.067c1.707-10.027 10.453-17.92 21.12-17.92h170.667c10.667 0 19.413 7.893 21.12 17.92l16 113.067c26.027 10.88 50.133 24.96 72.107 42.027l106.24-42.88c9.6-3.627 20.693 0 26.027 9.173l85.333 147.84c5.333 9.173 2.987 20.693-5.12 27.307l-90.027 70.613zM512 298.667c-82.56 0-149.333 66.773-149.333 149.333s66.773 149.333 149.333 149.333 149.333-66.773 149.333-149.333-66.773-149.333-149.333-149.333z" /> -<glyph unicode="" d="M512 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM736 448c0-9.813-0.853-19.627-2.133-29.227l63.147-49.493c5.547-4.48 7.253-12.587 3.413-18.987l-59.733-103.467c-3.627-6.4-11.52-8.96-18.347-6.4l-74.453 30.080c-15.36-11.947-32.213-21.76-50.56-29.44l-11.093-79.147c-0.853-7.040-7.040-12.587-14.507-12.587h-119.467c-7.467 0-13.653 5.547-14.72 12.587l-11.093 79.147c-18.133 7.467-34.987 17.493-50.56 29.44l-74.24-29.867c-6.827-2.56-14.507 0-18.347 6.4l-59.733 103.467c-3.84 6.4-2.133 14.507 3.413 18.987l63.147 49.28c-1.28 9.6-2.133 19.2-2.133 29.227 0 9.813 0.853 19.627 2.133 29.227l-63.147 49.28c-5.547 4.48-7.253 12.587-3.413 18.987l59.733 103.467c3.84 6.4 11.52 8.96 18.347 6.4l74.24-29.867c15.36 11.733 32.213 21.76 50.56 29.44l11.093 79.147c1.067 7.040 7.253 12.587 14.72 12.587h119.467c7.467 0 13.653-5.547 14.72-12.587l11.093-79.147c18.133-7.467 34.987-17.493 50.56-29.44l74.24 29.867c6.827 2.56 14.507 0 18.347-6.4l59.733-103.467c3.84-6.4 2.133-14.507-3.413-18.987l-63.147-49.493c1.28-9.387 2.133-19.2 2.133-29.013z" /> -<glyph unicode="" d="M597.333 448c0 47.147-38.187 85.333-85.333 85.333s-85.333-38.187-85.333-85.333 38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333zM512 832c-212.053 0-384-171.947-384-384h-128l170.667-170.667 170.667 170.667h-128c0 164.907 133.76 298.667 298.667 298.667s298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667c-64.64 0-124.16 20.693-173.227 55.68l-60.373-61.227c64.853-49.92 145.707-79.787 233.6-79.787 212.053 0 384 171.947 384 384s-171.947 384-384 384z" /> -<glyph unicode="" d="M469.333-64h85.333v85.333h-85.333v-85.333zM298.667-64h85.333v85.333h-85.333v-85.333zM640-64h85.333v85.333h-85.333v-85.333zM755.413 716.587l-243.413 243.413h-42.667v-323.627l-195.627 195.627-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 195.627 195.627v-323.627h42.667l243.413 243.413-183.040 183.253 183.040 183.253zM554.667 796.587l80.213-80.213-80.213-80v160.213zM634.88 350.080l-80.213-80v160.213l80.213-80.213z" /> -<glyph unicode="" d="M298.667-64h85.333v85.333h-85.333v-85.333zM469.333-64h85.333v85.333h-85.333v-85.333zM640-64h85.333v85.333h-85.333v-85.333zM682.667 959.573l-341.333 0.427c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h341.333c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 84.907-85.333 84.907zM682.667 277.333h-341.333v512h341.333v-512z" /> -<glyph unicode="" d="M896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 148.693h-768v598.613h768v-598.613zM341.333 277.333h106.667l64-64 64 64h106.667v106.667l64 64-64 64v106.667h-106.667l-64 64-64-64h-106.667v-106.667l-64-64 64-64v-106.667zM512 576c70.613 0 128-57.387 128-128s-57.387-128-128-128v256z" /> -<glyph unicode="" d="M331.52 671.573l-65.707 54.4-230.827-277.973 230.827-278.187 65.707 54.4-185.6 223.787 185.6 223.573zM298.667 405.333h85.333v85.333h-85.333v-85.333zM725.333 490.667h-85.333v-85.333h85.333v85.333zM469.333 405.333h85.333v85.333h-85.333v-85.333zM758.187 726.187l-65.707-54.4 185.6-223.787-185.6-223.573 65.707-54.4 230.827 277.973-230.827 278.187z" /> -<glyph unicode="" d="M512 746.667c-164.907 0-298.667-133.76-298.667-298.667h85.333c0 117.76 95.573 213.333 213.333 213.333s213.333-95.573 213.333-213.333h85.333c0 164.907-133.76 298.667-298.667 298.667zM554.667 350.293c37.547 16.427 64 53.973 64 97.707 0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667c0-43.733 26.453-81.28 64-97.707v-140.587l-145.707-145.707 60.373-60.373 128 128 128-128 60.373 60.373-145.707 145.707v140.587zM512 917.333c-259.2 0-469.333-210.133-469.333-469.333h85.333c0 212.053 171.947 384 384 384s384-171.947 384-384h85.333c0 259.2-210.133 469.333-469.333 469.333z" /> -<glyph unicode="" d="M213.333 874.667c0 23.467-18.987 42.667-42.667 42.667s-42.667-19.2-42.667-42.667v-170.667h-85.333v-256h256v256h-85.333v170.667zM384 277.333c0-55.68 35.84-102.613 85.333-120.107v-178.56h85.333v178.56c49.493 17.707 85.333 64.427 85.333 120.107v85.333h-256v-85.333zM42.667 277.333c0-55.68 35.84-102.613 85.333-120.107v-178.56h85.333v178.56c49.493 17.707 85.333 64.427 85.333 120.107v85.333h-256v-85.333zM896 704v170.667c0 23.467-18.987 42.667-42.667 42.667s-42.667-19.2-42.667-42.667v-170.667h-85.333v-256h256v256h-85.333zM554.667 874.667c0 23.467-18.987 42.667-42.667 42.667s-42.667-19.2-42.667-42.667v-170.667h-85.333v-256h256v256h-85.333v170.667zM725.333 277.333c0-55.68 35.84-102.613 85.333-120.107v-178.56h85.333v178.56c49.493 17.707 85.333 64.427 85.333 120.107v85.333h-256v-85.333z" /> -<glyph unicode="" d="M213.333 874.667c0 23.467-18.987 42.667-42.667 42.667s-42.667-19.2-42.667-42.667v-170.667h-85.333v-256h256v256h-85.333v170.667zM384 277.333c0-55.68 35.84-102.613 85.333-120.107v-178.56h85.333v178.56c49.493 17.707 85.333 64.427 85.333 120.107v85.333h-256v-85.333zM42.667 277.333c0-55.68 35.84-102.613 85.333-120.107v-178.56h85.333v178.56c49.493 17.707 85.333 64.427 85.333 120.107v85.333h-256v-85.333zM896 704v170.667c0 23.467-18.987 42.667-42.667 42.667s-42.667-19.2-42.667-42.667v-170.667h-85.333v-256h256v256h-85.333zM554.667 874.667c0 23.467-18.987 42.667-42.667 42.667s-42.667-19.2-42.667-42.667v-170.667h-85.333v-256h256v256h-85.333v170.667zM725.333 277.333c0-55.68 35.84-102.613 85.333-120.107v-178.56h85.333v178.56c49.493 17.707 85.333 64.427 85.333 120.107v85.333h-256v-85.333z" /> -<glyph unicode="" d="M768 661.333v128c0 47.147-38.187 85.333-85.333 85.333h-341.333c-47.147 0-85.333-38.187-85.333-85.333v-128h-42.667v-256l128-256v-128h341.333v128l128 256v256h-42.667zM341.333 789.333h341.333v-128h-85.333v85.333h-42.667v-85.333h-85.333v85.333h-42.667v-85.333h-85.333v128z" /> -<glyph unicode="" d="M341.333 469.333c0 35.413-28.587 64-64 64s-64-28.587-64-64 28.587-64 64-64 64 28.587 64 64zM640 682.667c0 35.413-28.587 64-64 64h-128c-35.413 0-64-28.587-64-64s28.587-64 64-64h128c35.413 0 64 28.587 64 64zM362.667 320c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM512 917.333c-258.773 0-469.333-210.56-469.333-469.333s210.56-469.333 469.333-469.333 469.333 210.56 469.333 469.333-210.56 469.333-469.333 469.333zM512 64c-211.84 0-384 172.373-384 384s172.16 384 384 384 384-172.373 384-384-172.16-384-384-384zM746.667 533.333c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM661.333 320c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64z" /> -<glyph unicode="" d="M512.213 725.333l-85.547-106.667h170.667l-85.12 106.667zM768 533.333v-170.667l106.667 85.12-106.667 85.547zM256 533.333l-106.667-85.547 106.667-85.12v170.667zM597.333 277.333h-170.667l85.547-106.667 85.12 106.667zM896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 148.693h-768v598.613h768v-598.613z" /> -<glyph unicode="" d="M554.667 576h-85.333v-85.333h85.333v85.333zM725.333 576h-85.333v-85.333h85.333v85.333zM853.333 298.667c-53.12 0-104.32 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.68 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667zM810.667 576v-85.333h85.333v85.333h-85.333z" /> -<glyph unicode="" d="M298.667-64h85.333v85.333h-85.333v-85.333zM469.333-64h85.333v85.333h-85.333v-85.333zM554.667 874.667h-85.333v-426.667h85.333v426.667zM706.773 770.773l-61.653-61.653c73.6-45.013 122.88-125.867 122.88-218.453 0-141.44-114.56-256-256-256s-256 114.56-256 256c0 92.587 49.28 173.44 122.88 218.453l-61.653 61.653c-88.533-61.653-146.56-164.053-146.56-280.107 0-188.587 152.747-341.333 341.333-341.333s341.333 152.747 341.333 341.333c0 116.053-58.027 218.453-146.56 280.107zM640-64h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M640 576h-256c-23.68 0-42.667-19.2-42.667-42.667v-512c0-23.467 18.987-42.667 42.667-42.667h256c23.68 0 42.667 19.2 42.667 42.667v512c0 23.467-18.987 42.667-42.667 42.667zM512 320c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM300.8 701.867l60.373-60.373c38.613 38.613 91.947 62.507 150.827 62.507s112.213-23.893 150.827-62.507l60.373 60.373c-53.973 53.973-128.64 87.467-211.2 87.467s-157.227-33.493-211.2-87.467zM512 960c-129.493 0-246.827-52.48-331.947-137.387l60.373-60.373c69.547 69.547 165.547 112.427 271.573 112.427s202.027-42.88 271.573-112.427l60.373 60.373c-85.12 84.907-202.453 137.387-331.947 137.387z" /> -<glyph unicode="" d="M298.667-64h85.333v85.333h-85.333v-85.333zM512 405.333c70.613 0 127.573 57.387 127.573 128l0.427 256c0 70.827-57.173 128-128 128-70.613 0-128-57.173-128-128v-256c0-70.613 57.387-128 128-128zM469.333-64h85.333v85.333h-85.333v-85.333zM640-64h85.333v85.333h-85.333v-85.333zM810.667 533.333h-72.533c0-128-108.16-217.6-226.133-217.6-117.76 0-226.133 89.6-226.133 217.6h-72.533c0-145.707 116.053-266.027 256-286.72v-139.947h85.333v139.947c139.947 20.693 256 141.013 256 286.72z" /> -<glyph unicode="" d="M682.667 704v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-85.333h-256v-554.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v554.667h-256zM426.667 789.333h170.667v-85.333h-170.667v85.333zM384 192v384l320-170.667-320-213.333z" /> -<glyph unicode="" d="M734.293 576l-186.88 279.68c-8.107 12.373-21.76 18.133-35.413 18.133s-27.307-5.973-35.413-18.133l-186.88-279.68h-204.373c-23.467 0-42.667-19.2-42.667-42.667 0-4.053 0.64-7.893 1.493-11.52l108.16-395.52c10.027-35.84 43.093-62.293 82.347-62.293h554.667c39.253 0 72.32 26.453 82.133 62.507l108.16 395.52c1.067 3.413 1.707 7.253 1.707 11.307 0 23.467-19.2 42.667-42.667 42.667h-204.373zM384 576l128 187.733 128-187.733h-256zM512 234.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M298.667 192c-47.147 0-84.907-38.187-84.907-85.333s37.76-85.333 84.907-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM42.667 874.667v-85.333h85.333l153.387-323.627-57.6-104.533c-6.613-12.373-10.453-26.24-10.453-41.173 0-47.147 38.187-85.333 85.333-85.333h512v85.333h-493.867c-5.973 0-10.667 4.693-10.667 10.667 0 1.92 0.427 3.627 1.28 5.12l38.187 69.547h317.867c32 0 59.947 17.707 74.667 43.947l152.533 276.907c3.413 5.973 5.333 13.013 5.333 20.48 0 23.68-19.2 42.667-42.667 42.667h-630.827l-40.533 85.333h-139.307zM725.333 192c-47.147 0-84.907-38.187-84.907-85.333s37.76-85.333 84.907-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M768 746.667v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-85.333h-213.333v-469.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v469.333h-213.333zM512 832h170.667v-85.333h-170.667v85.333zM512 320v298.667l234.667-128-234.667-170.667zM128 576h-85.333v-469.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333h-682.667v469.333z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM341.333 362.667h-85.333v85.333h85.333v-85.333zM341.333 490.667h-85.333v85.333h85.333v-85.333zM341.333 618.667h-85.333v85.333h85.333v-85.333zM640 362.667h-213.333v85.333h213.333v-85.333zM768 490.667h-341.333v85.333h341.333v-85.333zM768 618.667h-341.333v85.333h341.333v-85.333z" /> -<glyph unicode="" d="M530.987 277.333h89.173l-217.813 554.667h-79.147l-218.027-554.667h89.173l48 128h240.853l47.787-128zM274.347 490.667l88.32 235.733 88.32-235.733h-176.64zM920.96 465.707l-344.96-344.96-156.587 156.587-60.373-60.373 216.96-216.96 405.333 405.333-60.373 60.373z" /> -<glyph unicode="" d="M512 349.867l158.293-115.2-60.587 186.027 158.293 112.64h-194.133l-61.867 192-61.867-192h-194.133l158.293-112.64-60.373-186.027z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM692.48 192l-180.48 108.8-180.48-108.8 47.787 205.227-159.147 138.027 209.92 17.92 81.92 193.493 81.92-193.493 209.92-17.92-159.147-138.027 47.787-205.227z" /> -<glyph unicode="" d="M853.333 789.333h-682.667v-85.333h682.667v85.333zM896 362.667v85.333l-42.667 213.333h-682.667l-42.667-213.333v-85.333h42.667v-256h426.667v256h170.667v-256h85.333v256h42.667zM512 192h-256v170.667h256v-170.667z" /> -<glyph unicode="" d="M597.333 234.667h-426.667v-85.333h426.667v85.333zM853.333 576h-682.667v-85.333h682.667v85.333zM170.667 320h682.667v85.333h-682.667v-85.333zM170.667 746.667v-85.333h682.667v85.333h-682.667z" /> -<glyph unicode="" d="M298.24 490.667l-170.24-170.667 170.24-170.667v128h299.093v85.333h-299.093v128zM896 576l-170.24 170.667v-128h-299.093v-85.333h299.093v-128l170.24 170.667z" /> -<glyph unicode="" d="M682.667 234.24v299.093h-85.333v-299.093h-128l170.667-170.24 170.667 170.24h-128zM384 832l-170.667-170.24h128v-299.093h85.333v299.093h128l-170.667 170.24z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM277.333 576l149.333 149.333 149.333-149.333h-106.667v-170.667h-85.333v170.667h-106.667zM746.667 320l-149.333-149.333-149.333 149.333h106.667v170.667h85.333v-170.667h106.667z" /> -<glyph unicode="" d="M512 266.667l170.667 170.667h-128v384h-85.333v-384h-128l170.667-170.667zM896 821.333h-256v-84.693h256v-598.613h-768v598.613h256v84.693h-256c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 149.333h-768v597.333h426.667v-170.667h341.333v-426.667z" /> -<glyph unicode="" d="M42.667 576h85.333v85.333h-85.333v-85.333zM42.667 405.333h85.333v85.333h-85.333v-85.333zM42.667 746.667h85.333v85.333c-47.147 0-85.333-38.187-85.333-85.333zM384 64h85.333v85.333h-85.333v-85.333zM42.667 234.667h85.333v85.333h-85.333v-85.333zM128 64v85.333h-85.333c0-47.147 38.187-85.333 85.333-85.333zM896 832h-341.333v-256h426.667v170.667c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h85.333v85.333h-85.333v-85.333zM384 746.667h85.333v85.333h-85.333v-85.333zM213.333 64h85.333v85.333h-85.333v-85.333zM213.333 746.667h85.333v85.333h-85.333v-85.333zM896 64c47.147 0 85.333 38.187 85.333 85.333h-85.333v-85.333zM896 405.333h85.333v85.333h-85.333v-85.333zM554.667 64h85.333v85.333h-85.333v-85.333zM725.333 64h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M768 832v-85.333h-85.333v85.333h-341.333v-85.333h-85.333v85.333h-85.333v-768h85.333v85.333h85.333v-85.333h341.333v85.333h85.333v-85.333h85.333v768h-85.333zM341.333 234.667h-85.333v85.333h85.333v-85.333zM341.333 405.333h-85.333v85.333h85.333v-85.333zM341.333 576h-85.333v85.333h85.333v-85.333zM768 234.667h-85.333v85.333h85.333v-85.333zM768 405.333h-85.333v85.333h85.333v-85.333zM768 576h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M640 832h-384c-35.413 0-65.707-21.547-78.507-52.053l-128.64-300.8c-3.84-9.813-6.187-20.267-6.187-31.147v-81.707l0.427-0.427-0.427-3.2c0-47.147 38.187-85.333 85.333-85.333h269.44l-40.747-194.987c-0.853-4.267-1.493-8.747-1.493-13.44 0-17.707 7.253-33.707 18.773-45.227l45.44-45.013 280.96 280.96c15.36 15.573 24.96 36.907 24.96 60.373v426.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 832v-512h170.667v512h-170.667z" /> -<glyph unicode="" d="M512 704c0 23.467-19.2 42.667-42.667 42.667h-221.227l28.373 135.467c0.64 3.2 1.067 6.613 1.067 10.027 0 13.227-5.333 25.173-14.080 33.92l-33.92 33.92-210.773-210.773c-11.52-11.52-18.773-27.52-18.773-45.227v-277.333c0-35.413 28.587-64 64-64h288c26.453 0 49.28 16 58.88 39.040l96.64 225.707c2.773 7.253 4.48 14.933 4.48 23.253v53.333zM960 533.333h-288c-26.453 0-49.28-16-58.88-39.040l-96.64-225.707c-2.773-7.253-4.48-14.933-4.48-23.253v-53.333c0-23.467 19.2-42.667 42.667-42.667h221.227l-28.373-135.467c-0.64-3.2-1.067-6.613-1.067-10.027 0-13.227 5.333-25.173 14.080-33.92l33.92-33.92 210.773 210.773c11.52 11.52 18.773 27.52 18.773 45.227v277.333c0 35.413-28.587 64-64 64z" /> -<glyph unicode="" d="M42.667 64h170.667v512h-170.667v-512zM981.333 533.333c0 47.147-38.187 85.333-85.333 85.333h-269.44l40.747 194.987c0.853 4.267 1.493 8.747 1.493 13.44 0 17.707-7.253 33.707-18.773 45.227l-45.44 45.013-280.96-280.96c-15.36-15.573-24.96-36.907-24.96-60.373v-426.667c0-47.147 38.187-85.333 85.333-85.333h384c35.413 0 65.707 21.547 78.507 52.053l128.64 300.8c3.84 9.813 6.187 20.267 6.187 31.147v81.707l-0.427 0.427 0.427 3.2z" /> -<glyph unicode="" d="M128 576h597.333v85.333h-597.333v-85.333zM128 405.333h597.333v85.333h-597.333v-85.333zM128 234.667h597.333v85.333h-597.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM810.667 661.333v-85.333h85.333v85.333h-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M810.667 832h-42.667v85.333h-85.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v469.333h597.333v-469.333zM298.667 533.333h213.333v-213.333h-213.333z" /> -<glyph unicode="" d="M813.653 749.653l-60.373-60.373c61.867-61.653 100.053-146.987 100.053-241.28 0-188.587-152.747-341.333-341.333-341.333s-341.333 152.747-341.333 341.333c0 174.080 130.347 317.44 298.667 338.347v-86.187c-120.96-20.267-213.333-125.44-213.333-252.16 0-141.44 114.56-256 256-256s256 114.56 256 256c0 70.613-28.587 134.613-74.88 181.12l-60.373-60.373c30.72-30.933 49.92-73.6 49.92-120.747 0-94.293-76.373-170.667-170.667-170.667s-170.667 76.373-170.667 170.667c0 79.36 54.613 145.707 128 164.693v-91.093c-25.387-14.72-42.667-42.027-42.667-73.6 0-47.147 38.187-85.333 85.333-85.333s85.333 38.187 85.333 85.333c0 31.573-17.28 58.667-42.667 73.6v353.067h-42.667c-235.733 0-426.667-190.933-426.667-426.667 0-235.52 190.933-426.667 426.667-426.667 235.52 0 426.667 191.147 426.667 426.667 0 117.76-47.787 224.427-125.013 301.653z" /> -<glyph unicode="" d="M549.12 316.8l-108.373 107.093 1.28 1.28c74.24 82.773 127.147 177.92 158.293 278.613h125.013v85.547h-298.667v85.333h-85.333v-85.333h-298.667v-84.907h476.587c-28.8-82.347-73.813-160.427-135.253-228.693-39.68 44.16-72.533 92.16-98.56 142.933h-85.333c31.147-69.547 73.813-135.253 127.147-194.56l-216.96-214.4 60.373-60.373 213.333 213.333 132.693-132.693 32.427 86.827zM789.333 533.333h-85.333l-192-512h85.333l48 128h202.667l48-128h85.333l-192 512zM677.333 234.667l69.333 184.96 69.333-184.96h-138.667z" /> -<glyph unicode="" d="M682.667 192l97.92 97.92-208.213 208-170.667-170.667-316.373 316.373 60.373 60.373 256-256 170.667 170.667 268.373-268.587 97.92 97.92v-256z" /> -<glyph unicode="" d="M938.667 448l-170.667 170.667v-128h-640v-85.333h640v-128z" /> -<glyph unicode="" d="M682.667 704l97.92-97.92-208.213-208-170.667 170.667-316.373-316.373 60.373-60.373 256 256 170.667-170.667 268.373 268.587 97.92-97.92v256z" /> -<glyph unicode="" d="M725.333 832h-426.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667 298.667 128 298.667-128v682.667c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M725.333 832h-426.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667 298.667 128 298.667-128v682.667c0 47.147-38.187 85.333-85.333 85.333zM725.333 192l-213.333 92.8-213.333-92.8v554.667h426.667v-554.667z" /> -<glyph unicode="" d="M512 917.333l-384-170.667v-256c0-237.013 163.627-458.027 384-512 220.373 53.973 384 274.987 384 512v256l-384 170.667zM426.667 234.667l-170.667 170.667 60.373 60.373 110.293-110.293 280.96 280.96 60.373-60.373-341.333-341.333z" /> -<glyph unicode="" d="M853.333 405.333h-725.333c-23.467 0-42.667-19.2-42.667-42.667v-256c0-23.467 19.2-42.667 42.667-42.667h725.333c23.467 0 42.667 19.2 42.667 42.667v256c0 23.467-19.2 42.667-42.667 42.667zM853.333 832h-725.333c-23.467 0-42.667-19.2-42.667-42.667v-256c0-23.467 19.2-42.667 42.667-42.667h725.333c23.467 0 42.667 19.2 42.667 42.667v256c0 23.467-19.2 42.667-42.667 42.667z" /> -<glyph unicode="" d="M170.667 192h128v554.667h-128v-554.667zM768 746.667v-554.667h128v554.667h-128zM341.333 192h384v554.667h-384v-554.667z" /> -<glyph unicode="" d="M298.667 149.333h426.667v640h-426.667v-640zM85.333 234.667h170.667v469.333h-170.667v-469.333zM768 704v-469.333h170.667v469.333h-170.667z" /> -<glyph unicode="" d="M426.667 192h213.333v554.667h-213.333v-554.667zM170.667 192h213.333v554.667h-213.333v-554.667zM682.667 746.667v-554.667h213.333v554.667h-213.333z" /> -<glyph unicode="" d="M85.333 64h810.667v128h-810.667v-128zM853.333 618.667h-725.333c-23.467 0-42.667-19.2-42.667-42.667v-256c0-23.467 19.2-42.667 42.667-42.667h725.333c23.467 0 42.667 19.2 42.667 42.667v256c0 23.467-19.2 42.667-42.667 42.667zM85.333 832v-128h810.667v128h-810.667z" /> -<glyph unicode="" d="M170.667 320h725.333v85.333h-725.333v-85.333zM170.667 149.333h725.333v85.333h-725.333v-85.333zM170.667 490.667h725.333v85.333h-725.333v-85.333zM170.667 746.667v-85.333h725.333v85.333h-725.333z" /> -<glyph unicode="" d="M170.667 362.667h170.667v170.667h-170.667v-170.667zM170.667 149.333h170.667v170.667h-170.667v-170.667zM170.667 576h170.667v170.667h-170.667v-170.667zM384 362.667h512v170.667h-512v-170.667zM384 149.333h512v170.667h-512v-170.667zM384 746.667v-170.667h512v170.667h-512z" /> -<glyph unicode="" d="M170.667 490.667h213.333v256h-213.333v-256zM170.667 192h213.333v256h-213.333v-256zM426.667 192h213.333v256h-213.333v-256zM682.667 192h213.333v256h-213.333v-256zM426.667 490.667h213.333v256h-213.333v-256zM682.667 746.667v-256h213.333v256h-213.333z" /> -<glyph unicode="" d="M426.667 192h213.333v256h-213.333v-256zM170.667 192h213.333v554.667h-213.333v-554.667zM682.667 192h213.333v256h-213.333v-256zM426.667 746.667v-256h469.333v256h-469.333z" /> -<glyph unicode="" d="M170.667 192h725.333v256h-725.333v-256zM170.667 746.667v-256h725.333v256h-725.333z" /> -<glyph unicode="" d="M256 746.667h-128c-23.467 0-42.667-19.2-42.667-42.667v-512c0-23.467 19.2-42.667 42.667-42.667h128c23.467 0 42.667 19.2 42.667 42.667v512c0 23.467-19.2 42.667-42.667 42.667zM853.333 746.667h-128c-23.467 0-42.667-19.2-42.667-42.667v-512c0-23.467 19.2-42.667 42.667-42.667h128c23.467 0 42.667 19.2 42.667 42.667v512c0 23.467-19.2 42.667-42.667 42.667zM554.667 746.667h-128c-23.467 0-42.667-19.2-42.667-42.667v-512c0-23.467 19.2-42.667 42.667-42.667h128c23.467 0 42.667 19.2 42.667 42.667v512c0 23.467-19.2 42.667-42.667 42.667z" /> -<glyph unicode="" d="M512 768c-213.333 0-395.52-132.693-469.333-320 73.813-187.307 256-320 469.333-320 213.547 0 395.52 132.693 469.333 320-73.813 187.307-255.787 320-469.333 320zM512 234.667c-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333-95.573-213.333-213.333-213.333zM512 576c-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128-57.387 128-128 128z" /> -<glyph unicode="" d="M512 661.333c117.76 0 213.333-95.573 213.333-213.333 0-27.52-5.547-53.76-15.147-77.867l124.8-124.8c64.427 53.76 115.2 123.307 146.56 202.667-74.027 187.307-256 320-469.547 320-59.733 0-116.907-10.667-170.027-29.867l92.16-91.947c24.107 9.387 50.347 15.147 77.867 15.147zM85.333 777.6l116.693-116.693c-70.4-55.040-126.080-128.213-159.36-212.907 73.813-187.307 256-320 469.333-320 66.133 0 129.28 12.8 187.093 36.053l18.133-18.133 124.373-124.587 54.4 54.187-756.267 756.48-54.4-54.4zM321.28 541.867l65.92-65.92c-1.92-9.173-3.2-18.347-3.2-27.947 0-70.613 57.387-128 128-128 9.6 0 18.773 1.28 27.733 3.2l65.92-65.92c-28.373-14.080-59.947-22.613-93.653-22.613-117.76 0-213.333 95.573-213.333 213.333 0 33.707 8.533 65.28 22.613 93.867zM504.96 575.36l134.4-134.4 0.64 7.040c0 70.613-57.387 128-128 128l-7.040-0.64z" /> -<glyph unicode="" d="M853.333 704h-93.227c4.693 13.44 7.893 27.733 7.893 42.667 0 70.613-57.387 128-128 128-44.587 0-83.84-22.827-106.667-57.387l-21.333-29.013-21.333 29.013c-22.827 34.56-62.080 57.387-106.667 57.387-70.613 0-128-57.387-128-128 0-14.933 2.987-29.227 7.893-42.667h-93.227c-47.147 0-84.907-38.187-84.907-85.333l-0.427-469.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM640 789.333c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM384 789.333c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM853.333 149.333h-682.667v85.333h682.667v-85.333zM853.333 362.667h-682.667v256h216.747l-88.747-120.96 69.333-49.707 144 196.053 42.667-58.027 101.333-138.027 69.333 49.707-88.747 120.96h216.747v-256z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-469.333c0-47.147 38.187-85.333 85.333-85.333h170.667v-213.333l170.667 85.333 170.667-85.333v213.333h170.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM853.333 320h-682.667v85.333h682.667v-85.333zM853.333 533.333h-682.667v256h682.667v-256z" /> -<glyph unicode="" d="M853.333 704h-128v85.333c0 47.147-38.187 85.333-85.333 85.333h-256c-47.147 0-85.333-38.187-85.333-85.333v-85.333h-128c-47.147 0-85.333-38.187-85.333-85.333v-469.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM384 789.333h256v-85.333h-256v85.333zM853.333 149.333h-682.667v85.333h682.667v-85.333zM853.333 362.667h-682.667v256h128v-85.333h85.333v85.333h256v-85.333h85.333v85.333h128v-256z" /> -<glyph unicode="" d="M1024 960v-1024h-1024v1024h1024zM1045.333 981.333h-1066.667v-1066.667h1066.667v1066.667zM853.333 704h-170.667v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-85.333h-170.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-469.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM597.333 704h-170.667v85.333h170.667v-85.333z" /> -<glyph unicode="" d="M512 874.667c-235.52 0-426.667-190.933-426.667-426.667s191.147-426.667 426.667-426.667 426.667 190.933 426.667 426.667-191.147 426.667-426.667 426.667zM554.667 234.667h-85.333v85.333h85.333v-85.333zM554.667 405.333h-85.333v256h85.333v-256z" /> -<glyph unicode="" d="M42.667 64h938.667l-469.333 810.667-469.333-810.667zM554.667 192h-85.333v85.333h85.333v-85.333zM554.667 362.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 256c-106.027 0-192 85.973-192 192s85.973 192 192 192 192-85.973 192-192-85.973-192-192-192zM512 490.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667z" /> -<glyph unicode="" d="M469.333 234.667c0-23.467 19.2-42.667 42.667-42.667s42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667zM469.333 832v-170.667h85.333v81.92c144.64-20.693 256-144.853 256-295.253 0-164.907-133.76-298.667-298.667-298.667s-298.667 133.76-298.667 298.667c0 71.68 25.173 137.173 67.2 188.8l231.467-231.467 60.373 60.373-290.133 290.133-0.427-0.853c-93.227-69.973-153.813-181.333-153.813-306.987 0-212.053 171.52-384 383.787-384s384.213 171.947 384.213 384-171.947 384-384.213 384h-42.453zM768 448c0 23.467-19.2 42.667-42.667 42.667s-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667zM256 448c0-23.467 19.2-42.667 42.667-42.667s42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667z" /> -<glyph unicode="" d="M810.667 789.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM469.333 490.667h-64v21.333h-85.333v-128h85.333v21.333h64v-42.667c0-23.467-18.987-42.667-42.667-42.667h-128c-23.68 0-42.667 19.2-42.667 42.667v170.667c0 23.467 18.987 42.667 42.667 42.667h128c23.68 0 42.667-19.2 42.667-42.667v-42.667zM768 490.667h-64v21.333h-85.333v-128h85.333v21.333h64v-42.667c0-23.467-18.987-42.667-42.667-42.667h-128c-23.68 0-42.667 19.2-42.667 42.667v170.667c0 23.467 18.987 42.667 42.667 42.667h128c23.68 0 42.667-19.2 42.667-42.667v-42.667z" /> -<glyph unicode="" d="M426.667 106.667h170.667v682.667h-170.667v-682.667zM170.667 106.667h170.667v341.333h-170.667v-341.333zM682.667 576v-469.333h170.667v469.333h-170.667z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM640 576h-170.667v-85.333h170.667v-85.333h-170.667v-85.333h170.667v-85.333h-256v426.667h256v-85.333z" /> -<glyph unicode="" d="M170.667 192l362.667 256-362.667 256v-512zM554.667 704v-512l362.667 256-362.667 256z" /> -<glyph unicode="" d="M469.333 192v512l-362.667-256 362.667-256zM490.667 448l362.667-256v512l-362.667-256z" /> -<glyph unicode="" d="M640 640v234.667h-256v-234.667l128-128 128 128zM320 576h-234.667v-256h234.667l128 128-128 128zM384 256v-234.667h256v234.667l-128 128-128-128zM704 576l-128-128 128-128h234.667v256h-234.667z" /> -<glyph unicode="" d="M725.333 106.667c-12.16 0-24.107 2.56-32.64 6.4-30.080 16-51.84 37.76-72.96 101.76-21.973 66.347-62.72 97.707-102.187 128.213-33.707 26.027-68.693 52.907-98.773 107.733-22.4 40.96-34.773 85.547-34.773 125.227 0 119.68 93.653 213.333 213.333 213.333s213.333-93.653 213.333-213.333h85.333c0 167.467-131.2 298.667-298.667 298.667s-298.667-131.2-298.667-298.667c0-53.973 16.213-113.067 45.44-166.4 38.827-70.613 84.693-105.813 121.6-134.4 34.56-26.667 59.52-45.867 73.173-87.253 25.6-77.44 58.667-121.173 116.267-151.467 22.187-10.027 45.653-15.147 70.187-15.147 94.080 0 170.667 76.587 170.667 170.667h-85.333c0-47.147-38.187-85.333-85.333-85.333zM325.76 847.573l-60.373 60.373c-84.907-84.907-137.387-202.24-137.387-331.947s52.48-247.040 137.387-331.947l60.373 60.373c-69.547 69.547-112.427 165.547-112.427 271.573s42.88 202.027 112.427 271.573zM490.667 576c0-58.88 47.787-106.667 106.667-106.667s106.667 47.787 106.667 106.667-47.787 106.667-106.667 106.667-106.667-47.787-106.667-106.667z" /> -<glyph unicode="" d="M810.667 789.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM469.333 320h-64v85.333h-85.333v-85.333h-64v256h64v-106.667h85.333v106.667h64v-256zM768 362.667c0-23.467-18.987-42.667-42.667-42.667h-32v-64h-64v64h-32c-23.68 0-42.667 19.2-42.667 42.667v170.667c0 23.467 18.987 42.667 42.667 42.667h128c23.68 0 42.667-19.2 42.667-42.667v-170.667zM618.667 384h85.333v128h-85.333v-128z" /> -<glyph unicode="" d="M512 789.333v128l-170.667-170.667 170.667-170.667v128c141.44 0 256-114.56 256-256 0-43.307-10.88-83.84-29.653-119.68l62.293-62.293c33.067 52.907 52.693 114.987 52.693 181.973 0 188.587-152.747 341.333-341.333 341.333zM512 192c-141.44 0-256 114.56-256 256 0 43.307 10.88 83.84 29.653 119.68l-62.293 62.293c-33.067-52.907-52.693-114.987-52.693-181.973 0-188.587 152.747-341.333 341.333-341.333v-128l170.667 170.667-170.667 170.667v-128z" /> -<glyph unicode="" d="M512 362.667c70.613 0 127.573 57.387 127.573 128l0.427 256c0 70.827-57.173 128-128 128-70.613 0-128-57.173-128-128v-256c0-70.613 57.387-128 128-128zM738.133 490.667c0-128-108.16-217.6-226.133-217.6-117.76 0-226.133 89.6-226.133 217.6h-72.533c0-145.707 116.053-266.027 256-286.72v-139.947h85.333v139.947c139.947 20.693 256 141.013 256 286.72h-72.533z" /> -<glyph unicode="" d="M512 362.667c70.613 0 127.573 57.387 127.573 128l0.427 256c0 70.827-57.173 128-128 128-70.613 0-128-57.173-128-128v-256c0-70.613 57.387-128 128-128zM460.8 750.933c0 28.16 23.040 51.2 51.2 51.2s51.2-23.040 51.2-51.2l-0.427-264.533c0-28.16-22.827-51.2-50.773-51.2-28.16 0-51.2 23.040-51.2 51.2v264.533zM738.133 490.667c0-128-108.16-217.6-226.133-217.6-117.76 0-226.133 89.6-226.133 217.6h-72.533c0-145.707 116.053-266.027 256-286.72v-139.947h85.333v139.947c139.947 20.693 256 141.013 256 286.72h-72.533z" /> -<glyph unicode="" d="M810.667 490.667h-72.533c0-31.787-6.613-61.227-18.56-87.467l52.48-52.48c24.32 41.6 38.613 89.173 38.613 139.947zM639.36 483.627c0 2.347 0.64 4.693 0.64 7.040v256c0 70.827-57.387 128-128 128s-128-57.173-128-128v-7.893l255.36-255.147zM182.4 832l-54.4-54.4 256.427-256.427v-30.72c0-70.613 56.96-128 127.573-128 9.6 0 18.773 1.28 27.733 3.2l70.827-70.827c-30.507-14.080-64-21.973-98.56-21.973-117.76 0-226.133 89.6-226.133 217.6h-72.533c0-145.707 116.053-266.027 256-286.72v-139.733h85.333v139.947c38.613 5.76 75.307 19.2 108.373 38.613l178.56-178.56 54.4 54.187-713.6 713.813z" /> -<glyph unicode="" d="M768 789.333l85.333-170.667h-128l-85.333 170.667h-85.333l85.333-170.667h-128l-85.333 170.667h-85.333l85.333-170.667h-128l-85.333 170.667h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v597.333h-170.667z" /> -<glyph unicode="" d="M170.667 704h-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333zM853.333 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM810.667 490.667h-170.667v-170.667h-85.333v170.667h-170.667v85.333h170.667v170.667h85.333v-170.667h170.667v-85.333z" /> -<glyph unicode="" d="M170.667 704h-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333zM853.333 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM810.667 490.667h-426.667v85.333h426.667v-85.333zM640 320h-256v85.333h256v-85.333zM810.667 661.333h-426.667v85.333h426.667v-85.333z" /> -<glyph unicode="" d="M853.333 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM768 661.333h-128v-234.667c0-58.88-47.787-106.667-106.667-106.667s-106.667 47.787-106.667 106.667 47.787 106.667 106.667 106.667c24.107 0 46.080-8.32 64-21.76v235.093h170.667v-85.333zM170.667 704h-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333z" /> -<glyph unicode="" d="M981.333 448l-104.107 118.613 14.507 157.227-154.027 34.773-80.64 135.68-145.067-62.293-145.067 62.293-80.64-135.68-154.027-34.773 14.507-157.227-104.107-118.613 104.107-118.613-14.507-157.227 154.027-34.773 80.64-135.68 145.067 62.293 145.067-62.293 80.64 135.68 154.027 34.773-14.507 157.227 104.107 118.613zM554.667 234.667h-85.333v85.333h85.333v-85.333zM554.667 405.333h-85.333v256h85.333v-256z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333 0 78.933 27.093 151.253 71.893 209.067l478.507-478.507c-57.813-44.8-130.133-71.893-209.067-71.893zM781.44 238.933l-478.507 478.507c57.813 44.8 130.133 71.893 209.067 71.893 188.587 0 341.333-152.747 341.333-341.333 0-78.933-27.093-151.253-71.893-209.067z" /> -<glyph unicode="" d="M256 149.333h170.667v597.333h-170.667v-597.333zM597.333 746.667v-597.333h170.667v597.333h-170.667z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM469.333 277.333h-85.333v341.333h85.333v-341.333zM640 277.333h-85.333v341.333h85.333v-341.333z" /> -<glyph unicode="" d="M384 277.333h85.333v341.333h-85.333v-341.333zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333zM554.667 277.333h85.333v341.333h-85.333v-341.333z" /> -<glyph unicode="" d="M341.333 746.667v-597.333l469.333 298.667z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM426.667 256v384l256-192-256-192z" /> -<glyph unicode="" d="M426.667 256l256 192-256 192v-384zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M597.333 533.333h-512v-85.333h512v85.333zM597.333 704h-512v-85.333h512v85.333zM768 362.667v170.667h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667zM85.333 277.333h341.333v85.333h-341.333v-85.333z" /> -<glyph unicode="" d="M682.667 704v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-85.333h-256v-554.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v554.667h-256zM426.667 789.333h170.667v-85.333h-170.667v85.333zM384 192v384l320-170.667-320-213.333z" /> -<glyph unicode="" d="M170.667 704h-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333zM853.333 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM810.667 490.667h-170.667v-170.667h-85.333v170.667h-170.667v85.333h170.667v170.667h85.333v-170.667h170.667v-85.333z" /> -<glyph unicode="" d="M640 704h-512v-85.333h512v85.333zM640 533.333h-512v-85.333h512v85.333zM128 277.333h341.333v85.333h-341.333v-85.333zM725.333 704v-349.227c-13.44 4.907-27.52 7.893-42.667 7.893-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128v384h128v85.333h-213.333z" /> -<glyph unicode="" d="M138.027 697.6c-30.933-12.16-52.693-43.307-52.693-78.933v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333h-498.987l352.64 142.293-29.44 71.040-539.52-219.733zM298.667 106.667c-70.613 0-128 57.387-128 128s57.387 128 128 128 128-57.387 128-128-57.387-128-128-128zM853.333 448h-85.333v85.333h-85.333v-85.333h-512v170.667h682.667v-170.667z" /> -<glyph unicode="" d="M896 746.667v-597.333h85.333v597.333h-85.333zM725.333 149.333h85.333v597.333h-85.333v-597.333zM597.333 746.667h-512c-23.467 0-42.667-19.2-42.667-42.667v-512c0-23.467 19.2-42.667 42.667-42.667h512c23.467 0 42.667 19.2 42.667 42.667v512c0 23.467-19.2 42.667-42.667 42.667zM341.333 629.333c52.907 0 96-43.093 96-96 0-53.12-43.093-96-96-96s-96 42.88-96 96c0 52.907 43.093 96 96 96zM533.333 234.667h-384v32c0 64 128 96 192 96s192-32 192-96v-32z" /> -<glyph unicode="" d="M298.667 661.333h426.667v-128l170.667 170.667-170.667 170.667v-128h-512v-256h85.333v170.667zM725.333 234.667h-426.667v128l-170.667-170.667 170.667-170.667v128h512v256h-85.333v-170.667z" /> -<glyph unicode="" d="M298.667 661.333h426.667v-128l170.667 170.667-170.667 170.667v-128h-512v-256h85.333v170.667zM725.333 234.667h-426.667v128l-170.667-170.667 170.667-170.667v128h512v256h-85.333v-170.667zM554.667 320v256h-42.667l-85.333-42.667v-42.667h64v-170.667h64z" /> -<glyph unicode="" d="M512 746.667v170.667l-213.333-213.333 213.333-213.333v170.667c141.44 0 256-114.56 256-256s-114.56-256-256-256-256 114.56-256 256h-85.333c0-188.587 152.747-341.333 341.333-341.333s341.333 152.747 341.333 341.333-152.747 341.333-341.333 341.333z" /> -<glyph unicode="" d="M451.627 568.747l-220.587 220.587-60.373-60.373 220.587-220.587 60.373 60.373zM618.667 789.333l87.253-87.253-535.253-535.040 60.373-60.373 535.253 535.253 87.040-87.253v234.667h-234.667zM632.747 387.627l-60.373-60.373 133.547-133.547-87.253-87.040h234.667v234.667l-87.253-87.253-133.333 133.547z" /> -<glyph unicode="" d="M256 192l362.667 256-362.667 256v-512zM682.667 704v-512h85.333v512h-85.333z" /> -<glyph unicode="" d="M256 704h85.333v-512h-85.333zM405.333 448l362.667-256v512z" /> -<glyph unicode="" d="M336.213 815.36l-54.827 65.28-196.053-164.48 54.827-65.28 196.053 164.48zM938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM511.787 789.333c-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384-171.947 384-384.213 384zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.547-298.667-298.667-298.667zM384 490.667h154.667l-154.667-179.2v-76.8h256v85.333h-154.667l154.667 179.2v76.8h-256v-85.333z" /> -<glyph unicode="" d="M256 704h512v-512h-512z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM170.667 448h170.667v-85.333h-170.667v85.333zM597.333 192h-426.667v85.333h426.667v-85.333zM853.333 192h-170.667v85.333h170.667v-85.333zM853.333 362.667h-426.667v85.333h426.667v-85.333z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM330.88 266.88l-60.373-60.373c-66.347 66.773-99.84 154.027-99.84 241.493s33.493 174.72 100.053 241.28l60.373-60.373c-49.92-49.707-75.093-115.413-75.093-180.907s24.96-131.2 74.88-181.12zM512 277.333c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667 170.667-76.373 170.667-170.667-76.373-170.667-170.667-170.667zM753.28 206.72l-60.373 60.373c50.133 49.707 75.093 115.413 75.093 180.907s-25.173 131.2-74.88 181.12l60.373 60.373c66.347-66.773 99.84-154.027 99.84-241.493s-33.493-174.72-100.053-241.28zM512 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M725.333 512v149.333c0 23.467-19.2 42.667-42.667 42.667h-512c-23.467 0-42.667-19.2-42.667-42.667v-426.667c0-23.467 19.2-42.667 42.667-42.667h512c23.467 0 42.667 19.2 42.667 42.667v149.333l170.667-170.667v469.333l-170.667-170.667z" /> -<glyph unicode="" d="M896 682.667l-170.667-170.667v149.333c0 23.467-19.2 42.667-42.667 42.667h-263.68l477.013-477.013v455.68zM139.733 874.667l-54.4-54.4 116.267-116.267h-30.933c-23.467 0-42.667-19.2-42.667-42.667v-426.667c0-23.467 19.2-42.667 42.667-42.667h512c8.747 0 16.427 3.2 23.253 7.893l135.893-135.893 54.187 54.4-756.267 756.267z" /> -<glyph unicode="" d="M170.667 704h-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333zM853.333 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM512 341.333v384l256-192-256-192z" /> -<glyph unicode="" d="M789.333 448c0 75.307-43.52 140.373-106.667 171.733v-343.68c63.147 31.573 106.667 96.64 106.667 171.947zM213.333 576v-256h170.667l213.333-213.333v682.667l-213.333-213.333h-170.667z" /> -<glyph unicode="" d="M298.667 576v-256h170.667l213.333-213.333v682.667l-213.333-213.333h-170.667z" /> -<glyph unicode="" d="M704 448c0 75.307-43.52 140.373-106.667 171.733v-94.293l104.747-104.747c1.28 8.96 1.92 18.133 1.92 27.307zM810.667 448c0-40.107-8.747-77.867-23.040-112.64l64.64-64.64c27.733 53.12 43.733 113.28 43.733 177.28 0 182.613-127.787 335.36-298.667 374.187v-88.107c123.307-36.693 213.333-150.827 213.333-286.080zM182.4 832l-54.4-54.4 201.6-201.6h-201.6v-256h170.667l213.333-213.333v286.933l181.547-181.547c-28.587-21.973-60.8-39.68-96.213-50.347v-88.107c58.667 13.44 112.213 40.32 157.227 77.227l87.040-86.827 54.4 54.4-713.6 713.6zM512 789.333l-89.173-89.173 89.173-89.173v178.347z" /> -<glyph unicode="" d="M128 576v-256h170.667l213.333-213.333v682.667l-213.333-213.333h-170.667zM704 448c0 75.307-43.52 140.373-106.667 171.733v-343.68c63.147 31.573 106.667 96.64 106.667 171.947zM597.333 822.187v-88.107c123.307-36.693 213.333-150.827 213.333-286.080s-90.027-249.387-213.333-286.080v-88.107c170.88 38.827 298.667 191.36 298.667 374.187s-127.787 335.36-298.667 374.187z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM640 192h-469.333v170.667h469.333v-170.667zM640 405.333h-469.333v170.667h469.333v-170.667zM853.333 192h-170.667v384h170.667v-384z" /> -<glyph unicode="" d="M512 661.333v170.667h-426.667v-768h853.333v597.333h-426.667zM256 149.333h-85.333v85.333h85.333v-85.333zM256 320h-85.333v85.333h85.333v-85.333zM256 490.667h-85.333v85.333h85.333v-85.333zM256 661.333h-85.333v85.333h85.333v-85.333zM426.667 149.333h-85.333v85.333h85.333v-85.333zM426.667 320h-85.333v85.333h85.333v-85.333zM426.667 490.667h-85.333v85.333h85.333v-85.333zM426.667 661.333h-85.333v85.333h85.333v-85.333zM853.333 149.333h-341.333v85.333h85.333v85.333h-85.333v85.333h85.333v85.333h-85.333v85.333h341.333v-426.667zM768 490.667h-85.333v-85.333h85.333v85.333zM768 320h-85.333v-85.333h85.333v85.333z" /> -<glyph unicode="" d="M282.667 499.413c61.44-120.747 160.213-219.52 281.173-280.96l93.867 94.080c11.733 11.733 28.587 15.147 43.307 10.453 47.787-15.787 99.2-24.32 152.32-24.32 23.68 0 42.667-18.987 42.667-42.667v-149.333c0-23.68-18.987-42.667-42.667-42.667-400.64 0-725.333 324.693-725.333 725.333 0 23.68 19.2 42.667 42.667 42.667h149.333c23.68 0 42.667-18.987 42.667-42.667 0-53.12 8.533-104.533 24.32-152.32 4.693-14.72 1.28-31.573-10.453-43.307l-93.867-94.293z" /> -<glyph unicode="" d="M512 576c-68.48 0-134.4-10.667-196.267-30.72v-132.48c0-16.853-9.813-31.36-23.893-38.4-41.6-20.907-79.787-47.573-113.707-78.933-7.68-7.467-18.133-12.16-29.867-12.16s-22.4 4.693-30.080 12.587l-105.6 105.6c-7.893 7.893-12.587 18.56-12.587 30.293s4.693 22.4 12.587 30.293c129.92 123.52 305.92 199.253 499.413 199.253s369.493-75.733 499.413-199.253c7.893-7.68 12.587-18.56 12.587-30.293s-4.693-22.4-12.587-30.080l-105.6-105.6c-7.68-7.68-18.347-12.587-30.080-12.587-11.52 0-22.187 4.693-29.867 12.16-33.92 31.36-72.107 58.027-113.707 78.933-14.080 7.040-23.893 21.547-23.893 38.4v132.48c-61.867 19.84-127.787 30.507-196.267 30.507z" /> -<glyph unicode="" d="M384 746.667v-85.333h280.96l-494.293-494.293 60.373-60.373 494.293 494.293v-280.96h85.333v426.667z" /> -<glyph unicode="" d="M725.333 88.96l60.373 60.373-145.707 145.707-60.373-60.373 145.707-145.707zM320 618.667h149.333v-238.293l-231.040-231.040 60.373-60.373 256 256v273.707h149.333l-192 192-192-192z" /> -<glyph unicode="" d="M835.627 661.333l-323.627-323.627-238.293 238.293h195.627v85.333h-341.333v-341.333h85.333v195.627l298.667-298.667 384 384z" /> -<glyph unicode="" d="M853.333 728.96l-60.373 60.373-494.293-494.293v280.96h-85.333v-426.667h426.667v85.333h-280.96z" /> -<glyph unicode="" d="M597.333 789.333l97.92-97.92-122.88-122.667 60.373-60.373 122.667 122.88 97.92-97.92v256zM426.667 789.333h-256v-256l97.92 97.92 200.747-200.96v-323.627h85.333v359.040l-225.92 225.707z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM256 576h512v-85.333h-512v85.333zM597.333 362.667h-341.333v85.333h341.333v-85.333zM768 618.667h-512v85.333h512v-85.333z" /> -<glyph unicode="" d="M213.333 405.333h597.333v85.333h-597.333v-85.333zM128 234.667h597.333v85.333h-597.333v-85.333zM298.667 661.333v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M938.24 789.333c0 47.147-37.76 85.333-84.907 85.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h597.333l170.667-170.667-0.427 768zM768 362.667h-512v85.333h512v-85.333zM768 490.667h-512v85.333h512v-85.333zM768 618.667h-512v85.333h512v-85.333z" /> -<glyph unicode="" d="M853.333 960h-682.667v-85.333h682.667v85.333zM170.667-64h682.667v85.333h-682.667v-85.333zM853.333 789.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM512 672c52.907 0 96-43.093 96-96 0-53.12-43.093-96-96-96s-96 42.88-96 96c0 52.907 43.093 96 96 96zM725.333 234.667h-426.667v64c0 71.040 142.293 106.667 213.333 106.667s213.333-35.627 213.333-106.667v-64z" /> -<glyph unicode="" d="M725.333 832h-42.667v-213.333h42.667v213.333zM640 746.667h-85.333v42.667h85.333v42.667h-128v-128h85.333v-42.667h-85.333v-42.667h128v128zM768 832v-213.333h42.667v85.333h85.333v128h-128zM853.333 746.667h-42.667v42.667h42.667v-42.667zM853.333 298.667c-53.12 0-104.32 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.747 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.68 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667z" /> -<glyph unicode="" d="M512 149.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM256 917.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM256 661.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM256 405.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 746.667c47.147 0 85.333 38.187 85.333 85.333s-38.187 85.333-85.333 85.333-85.333-38.187-85.333-85.333 38.187-85.333 85.333-85.333zM512 405.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 405.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 661.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM512 661.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM512 917.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333 0 78.933 27.093 151.253 71.893 209.067l478.507-478.507c-57.813-44.8-130.133-71.893-209.067-71.893zM781.44 238.933l-478.507 478.507c57.813 44.8 130.133 71.893 209.067 71.893 188.587 0 341.333-152.747 341.333-341.333 0-78.933-27.093-151.253-71.893-209.067z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 618.667l-341.333-213.333-341.333 213.333v85.333l341.333-213.333 341.333 213.333v-85.333z" /> -<glyph unicode="" d="M896 704h-85.333v-384h-554.667v-85.333c0-23.467 19.2-42.667 42.667-42.667h469.333l170.667-170.667v640c0 23.467-19.2 42.667-42.667 42.667zM725.333 448v384c0 23.467-19.2 42.667-42.667 42.667h-554.667c-23.467 0-42.667-19.2-42.667-42.667v-597.333l170.667 170.667h426.667c23.467 0 42.667 19.2 42.667 42.667z" /> -<glyph unicode="" d="M384 832l-170.667-170.24h128v-299.093h85.333v299.093h128l-170.667 170.24zM682.667 234.24v299.093h-85.333v-299.093h-128l170.667-170.24 170.667 170.24h-128z" /> -<glyph unicode="" d="M880.853 69.333l-698.667 698.667-54.187-54.4 118.613-118.613c-108.8-133.973-100.693-331.307 23.893-456.107 66.56-66.56 154.027-100.053 241.28-100.053 76.16 0 152.32 25.387 214.613 75.947l115.2-114.773 54.4 54.4-15.147 14.933zM512 124.373c-68.48 0-132.693 26.667-180.907 74.88-48.427 48.427-75.093 112.64-75.093 181.12 0 56.32 18.347 109.653 51.627 153.813l204.373-204.587v-205.227zM512 742.4v-195.413l309.547-309.547c58.24 126.080 35.84 280.32-68.267 384.427l-241.28 241.28-158.080-158.080 60.373-60.373 97.707 97.707z" /> -<glyph unicode="" d="M753.28 621.653l-241.28 241.493-241.28-241.493c-133.333-133.333-133.333-349.44 0-482.773 66.56-66.56 154.027-100.053 241.28-100.053s174.72 33.28 241.28 100.053c133.333 133.333 133.333 349.44 0 482.773zM512 124.373c-68.48 0-132.693 26.667-180.907 75.093-48.427 48.213-75.093 112.427-75.093 180.907s26.667 132.693 75.093 181.12l180.907 180.907v-618.027z" /> -<glyph unicode="" d="M810.667 874.667h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h170.667l128-128 128 128h170.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM554.667 192h-85.333v85.333h85.333v-85.333zM642.773 522.453l-38.187-39.253c-30.72-30.72-49.92-56.533-49.92-120.533h-85.333v21.333c0 47.147 19.2 89.813 49.92 120.747l53.12 53.76c15.36 15.36 24.96 36.693 24.96 60.16 0 47.147-38.187 85.333-85.333 85.333s-85.333-38.187-85.333-85.333h-85.333c0 94.293 76.373 170.667 170.667 170.667s170.667-76.373 170.667-170.667c0-37.547-15.147-71.467-39.893-96.213z" /> -<glyph unicode="" d="M512 682.667c58.88 0 106.667-47.787 106.667-106.667 0-31.36-13.867-59.307-35.413-78.933l154.88-154.88c41.6 79.36 72.533 161.92 72.533 233.813 0 164.907-133.76 298.667-298.667 298.667-84.48 0-160.64-35.2-214.827-91.52l135.893-135.893c19.413 21.547 47.573 35.413 78.933 35.413zM698.667 273.067l-559.147 558.933-54.187-54.4 135.68-135.68c-4.907-21.12-7.68-43.093-7.68-65.92 0-224 298.667-554.667 298.667-554.667s71.253 78.933 144 185.6l142.933-142.933 54.4 54.4-154.667 154.667z" /> -<glyph unicode="" d="M512 874.667c-164.907 0-298.667-133.76-298.667-298.667 0-224 298.667-554.667 298.667-554.667s298.667 330.667 298.667 554.667c0 164.907-133.76 298.667-298.667 298.667zM512 469.333c-58.88 0-106.667 47.787-106.667 106.667s47.787 106.667 106.667 106.667 106.667-47.787 106.667-106.667-47.787-106.667-106.667-106.667z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM768 362.667h-512v85.333h512v-85.333zM768 490.667h-512v85.333h512v-85.333zM768 618.667h-512v85.333h512v-85.333z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-768l170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M810.24 746.667c0 47.147-37.76 85.333-84.907 85.333h-298.667l-99.84-99.84 483.84-483.84-0.427 498.347zM155.733 794.453l-54.187-54.187 111.787-112v-478.933c0-47.147 38.187-85.333 85.333-85.333h427.093c14.933 0 28.8 4.267 40.96 10.88l80.213-80.213 54.187 54.4-745.387 745.387z" /> -<glyph unicode="" d="M282.667 499.413c61.44-120.747 160.213-219.52 281.173-280.96l93.867 94.080c11.733 11.733 28.587 15.147 43.307 10.453 47.787-15.787 99.2-24.32 152.32-24.32 23.68 0 42.667-18.987 42.667-42.667v-149.333c0-23.68-18.987-42.667-42.667-42.667-400.64 0-725.333 324.693-725.333 725.333 0 23.68 19.2 42.667 42.667 42.667h149.333c23.68 0 42.667-18.987 42.667-42.667 0-53.12 8.533-104.533 24.32-152.32 4.693-14.72 1.28-31.573-10.453-43.307l-93.867-94.293z" /> -<glyph unicode="" d="M749.227 352.427c11.947 29.44 18.773 61.653 18.773 95.573 0 141.44-114.56 256-256 256-33.92 0-66.133-6.827-95.787-18.773l69.333-69.333c8.747 1.493 17.493 2.773 26.453 2.773 94.293 0 170.667-76.373 170.667-170.667 0-9.173-0.853-18.133-2.347-26.667l68.907-68.907zM512 789.333c188.587 0 341.333-152.747 341.333-341.333 0-57.813-14.933-111.787-40.32-159.36l62.72-62.72c39.68 64.64 62.933 140.587 62.933 222.080 0 235.733-191.147 426.667-426.667 426.667-81.493 0-157.44-23.253-222.080-62.933l62.293-62.293c47.573 25.387 101.973 39.893 159.787 39.893zM139.52 853.333l-54.187-54.4 89.813-89.813c-56.107-72.107-89.813-162.56-89.813-261.12 0-157.653 85.76-295.040 213.12-368.853l42.667 73.813c-101.76 58.88-170.453 168.96-170.453 295.040 0 74.88 24.32 144 65.28 200.32l61.227-61.227c-26.027-40.107-41.173-87.68-41.173-139.093 0-94.72 51.413-177.067 127.787-221.44l43.093 74.24c-50.987 29.653-85.547 84.053-85.547 147.2 0 27.52 7.253 53.12 18.773 76.16l67.413-67.413-0.853-8.747c0-47.147 38.187-85.333 85.333-85.333l8.747 0.853 320.853-320.853 54.4 54.4-756.48 756.267z" /> -<glyph unicode="" d="M938.667 832h-853.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h853.333c47.147 0 84.907 38.187 84.907 85.333l0.427 597.333c0 47.147-38.187 85.333-85.333 85.333zM341.333 704c70.613 0 128-57.387 128-128 0-70.827-57.387-128-128-128s-128 57.173-128 128c0 70.613 57.387 128 128 128zM597.333 192h-512v42.667c0 85.333 170.667 132.267 256 132.267s256-46.933 256-132.267v-42.667zM761.6 362.667h69.973l64.427-85.333-85.12-85.12c-55.68 41.813-97.28 101.333-116.48 170.453-7.467 27.307-11.733 55.68-11.733 85.333s4.267 58.027 11.947 85.333c18.987 69.12 60.587 128.64 116.48 170.453l84.907-85.12-64.427-85.333h-69.973c-9.387-26.667-14.933-55.467-14.933-85.333s5.333-58.667 14.933-85.333z" /> -<glyph unicode="" d="M896 618.667v42.667l-128-85.333-128 85.333v-42.667l128-85.333 128 85.333zM938.667 832h-853.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h853.333c47.147 0 84.907 38.187 84.907 85.333l0.427 597.333c0 47.147-38.187 85.333-85.333 85.333zM341.333 704c70.613 0 128-57.387 128-128 0-70.827-57.387-128-128-128s-128 57.173-128 128c0 70.613 57.387 128 128 128zM597.333 192h-512v42.667c0 85.333 170.667 132.267 256 132.267s256-46.933 256-132.267v-42.667zM938.667 448h-341.333v256h341.333v-256z" /> -<glyph unicode="" d="M1011.413 248.747c-129.92 123.52-305.92 199.253-499.413 199.253s-369.493-75.733-499.413-199.253c-7.893-7.68-12.587-18.56-12.587-30.293s4.693-22.4 12.587-30.080l105.6-105.6c7.68-7.68 18.347-12.587 30.080-12.587 11.52 0 22.187 4.693 29.867 12.16 33.92 31.36 72.107 58.027 113.707 78.933 14.080 7.040 23.893 21.547 23.893 38.4v132.48c61.867 19.84 127.787 30.507 196.267 30.507s134.4-10.667 196.267-30.72v-132.48c0-16.853 9.813-31.36 23.893-38.4 41.6-20.907 80-47.573 113.707-78.933 7.68-7.467 18.133-12.16 29.867-12.16s22.4 4.693 30.293 12.587l105.6 105.6c7.68 7.68 12.587 18.347 12.587 30.080-0.213 11.947-4.907 22.827-12.8 30.507zM902.827 693.12l-60.373 60.373-151.893-151.893 60.373-60.373s147.2 150.187 151.893 151.893zM554.667 874.667h-85.333v-213.333h85.333v213.333zM273.067 541.227l60.373 60.373-151.893 151.893-60.373-60.373c4.693-1.707 151.893-151.893 151.893-151.893z" /> -<glyph unicode="" d="M43.093 661.333l-0.427-426.667c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333h-768c-47.147 0-84.907-38.187-84.907-85.333zM810.667 661.333v-426.667h-597.333v426.667h597.333z" /> -<glyph unicode="" d="M725.333 916.907l-426.667 0.427c-47.147 0-84.907-38.187-84.907-85.333v-768c0-47.147 37.76-85.333 84.907-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v768c0 47.147-38.187 84.907-85.333 84.907zM725.333 149.333h-426.667v597.333h426.667v-597.333z" /> -<glyph unicode="" d="M43.093 661.333l-0.427-426.667c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333h-768c-47.147 0-84.907-38.187-84.907-85.333zM810.667 661.333v-426.667h-597.333v426.667h597.333z" /> -<glyph unicode="" d="M725.333 916.907l-426.667 0.427c-47.147 0-84.907-38.187-84.907-85.333v-768c0-47.147 37.76-85.333 84.907-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v768c0 47.147-38.187 84.907-85.333 84.907zM725.333 149.333h-426.667v597.333h426.667v-597.333z" /> -<glyph unicode="" d="M768 789.333l-170.667-170.667h128v-298.667c0-47.147-38.187-85.333-85.333-85.333s-85.333 38.187-85.333 85.333v298.667c0 94.080-76.587 170.667-170.667 170.667s-170.667-76.587-170.667-170.667v-298.667h-128l170.667-170.667 170.667 170.667h-128v298.667c0 47.147 38.187 85.333 85.333 85.333s85.333-38.187 85.333-85.333v-298.667c0-94.080 76.587-170.667 170.667-170.667s170.667 76.587 170.667 170.667v298.667h128l-170.667 170.667z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM384 490.667h-85.333v85.333h85.333v-85.333zM554.667 490.667h-85.333v85.333h85.333v-85.333zM725.333 490.667h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M789.333 704c-129.707 0-234.667-104.96-234.667-234.667 0-56.747 20.053-108.8 53.547-149.333h-192.64c33.493 40.533 53.547 92.587 53.547 149.333 0 129.707-104.96 234.667-234.667 234.667s-234.453-104.96-234.453-234.667 104.96-234.667 234.667-234.667h554.667c129.707 0 234.667 104.96 234.667 234.667s-104.96 234.667-234.667 234.667zM234.667 320c-82.56 0-149.333 66.773-149.333 149.333s66.773 149.333 149.333 149.333 149.333-66.773 149.333-149.333-66.773-149.333-149.333-149.333zM789.333 320c-82.56 0-149.333 66.773-149.333 149.333s66.773 149.333 149.333 149.333 149.333-66.773 149.333-149.333-66.773-149.333-149.333-149.333z" /> -<glyph unicode="" d="M539.733 533.333c-35.2 99.413-129.707 170.667-241.067 170.667-141.44 0-256-114.56-256-256s114.56-256 256-256c111.36 0 205.867 71.253 241.067 170.667h185.6v-170.667h170.667v170.667h85.333v170.667h-441.6zM298.667 362.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M810.667 405.333h-256v-256h-85.333v256h-256v85.333h256v256h85.333v-256h256v-85.333z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM725.333 405.333h-170.667v-170.667h-85.333v170.667h-170.667v85.333h170.667v170.667h85.333v-170.667h170.667v-85.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM725.333 405.333h-170.667v-170.667h-85.333v170.667h-170.667v85.333h170.667v170.667h85.333v-170.667h170.667v-85.333z" /> -<glyph unicode="" d="M554.667 661.333h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667v170.667zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M876.587 737.067l-59.093 71.68c-11.947 14.080-29.653 23.253-49.493 23.253h-512c-19.84 0-37.547-9.173-49.28-23.253l-59.093-71.68c-12.373-14.933-19.627-33.707-19.627-54.4v-533.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v533.333c0 20.693-7.253 39.467-19.413 54.4zM512 213.333l-234.667 234.667h149.333v85.333h170.667v-85.333h149.333l-234.667-234.667zM218.667 746.667l34.773 42.667h512l39.893-42.667h-586.667z" /> -<glyph unicode="" d="M938.667 832h-640c-29.44 0-52.693-14.933-68.053-37.547l-230.613-346.24 230.613-346.24c15.36-22.613 38.613-37.973 68.053-37.973h640c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 295.040l-60.373-60.373-152.96 152.96-152.96-152.96-60.373 60.373 152.96 152.96-152.96 152.96 60.373 60.373 152.96-152.96 152.96 152.96 60.373-60.373-152.96-152.96 152.96-152.96z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM170.667 448c0 188.587 152.747 341.333 341.333 341.333 78.933 0 151.253-27.093 209.067-71.893l-478.507-478.507c-44.8 57.813-71.893 130.133-71.893 209.067zM512 106.667c-78.933 0-151.253 27.093-209.067 71.893l478.507 478.507c44.8-57.813 71.893-130.133 71.893-209.067 0-188.587-152.747-341.333-341.333-341.333z" /> -<glyph unicode="" d="M810.667 686.293l-60.373 60.373-238.293-238.293-238.293 238.293-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 238.293 238.293 238.293-238.293 60.373 60.373-238.293 238.293z" /> -<glyph unicode="" d="M682.667 917.333h-512c-47.147 0-85.333-38.187-85.333-85.333v-597.333h85.333v597.333h512v85.333zM810.667 746.667h-469.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h469.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 64h-469.333v597.333h469.333v-597.333z" /> -<glyph unicode="" d="M411.307 634.027c9.6 21.333 15.36 45.013 15.36 69.973 0 94.293-76.373 170.667-170.667 170.667s-170.667-76.373-170.667-170.667 76.373-170.667 170.667-170.667c24.96 0 48.64 5.76 69.973 15.36l100.693-100.693-100.693-100.693c-21.333 9.6-45.013 15.36-69.973 15.36-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667c0 24.96-5.76 48.64-15.36 69.973l100.693 100.693 298.667-298.667h128v42.667l-527.36 527.36zM256 618.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM256 106.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM512 426.667c-11.733 0-21.333 9.6-21.333 21.333s9.6 21.333 21.333 21.333 21.333-9.6 21.333-21.333-9.6-21.333-21.333-21.333zM810.667 832l-256-256 85.333-85.333 298.667 298.667v42.667z" /> -<glyph unicode="" d="M810.667 874.667h-178.56c-17.493 49.493-64.427 85.333-120.107 85.333s-102.613-35.84-120.107-85.333h-178.56c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM512 874.667c23.467 0 42.667-18.987 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 18.987-42.667 42.667 19.2 42.667 42.667 42.667zM810.667 106.667h-597.333v682.667h85.333v-128h426.667v128h85.333v-682.667z" /> -<glyph unicode="" d="M128 224v-160h160l472.107 472.107-160 160-472.107-472.107zM883.413 659.413c16.64 16.64 16.64 43.733 0 60.373l-99.627 99.627c-16.64 16.64-43.733 16.64-60.373 0l-78.080-78.080 160-160 78.080 78.080z" /> -<glyph unicode="" d="M938.24 618.667c0 30.72-16 57.387-40.107 72.533l-386.133 226.133-386.133-226.133c-24.107-15.147-40.533-41.813-40.533-72.533v-426.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333l-0.427 426.667zM512 405.333l-352.427 220.373 352.427 206.293 352.427-206.293-352.427-220.373z" /> -<glyph unicode="" d="M426.667 192h170.667v85.333h-170.667v-85.333zM128 704v-85.333h768v85.333h-768zM256 405.333h512v85.333h-512v-85.333z" /> -<glyph unicode="" d="M614.4 704l-17.067 85.333h-384v-725.333h85.333v298.667h238.933l17.067-85.333h298.667v426.667z" /> -<glyph unicode="" d="M512 618.667v170.667l341.333-341.333-341.333-341.333v170.667h-341.333v341.333z" /> -<glyph unicode="" d="M196.053 666.24c29.867 30.507 59.733 57.813 73.173 52.267 21.12-8.747-0.427-44.373-12.8-65.067-10.667-17.92-122.027-165.76-122.027-269.227 0-54.613 20.267-99.84 57.387-127.147 32-23.68 74.027-30.933 112.64-19.627 45.653 13.44 83.2 59.52 130.56 117.973 51.627 63.573 120.747 146.773 174.080 146.773 69.547 0 70.4-43.093 75.093-76.587-161.707-27.733-229.76-156.8-229.76-229.547s61.44-132.053 136.747-132.053c69.333 0 183.253 56.747 200.107 260.267h104.747v106.667h-105.387c-6.4 70.4-46.507 178.987-171.947 178.987-96 0-178.56-81.493-210.56-121.387-24.747-30.933-87.68-105.6-97.493-116.267-10.88-12.587-28.8-35.84-47.573-35.84-18.987 0-30.507 35.627-15.573 82.133 14.933 46.72 59.733 122.027 78.933 149.973 33.493 48.64 55.253 82.133 55.253 139.947 0 93.867-69.973 123.307-107.093 123.307-56.32 0-105.387-42.667-116.267-53.547-15.147-15.36-27.947-27.947-37.333-39.467l75.093-72.533zM592.427 168.32c-13.227 0-31.36 11.093-31.36 30.933 0 25.6 30.933 93.867 122.667 117.973-13.227-114.987-61.44-148.907-91.307-148.907z" /> -<glyph unicode="" d="M810.667 832h-597.76c-47.147 0-84.48-38.187-84.48-85.333l-0.427-597.333c0-47.147 37.76-85.333 84.907-85.333h597.76c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 320h-170.667c0-70.613-57.387-128-128-128s-128 57.387-128 128h-171.093v426.667h597.76v-426.667zM682.667 533.333h-85.333v128h-170.667v-128h-85.333l170.667-170.667 170.667 170.667z" /> -<glyph unicode="" d="M166.4 448c0 72.96 59.307 132.267 132.267 132.267h170.667v81.067h-170.667c-117.76 0-213.333-95.573-213.333-213.333s95.573-213.333 213.333-213.333h170.667v81.067h-170.667c-72.96 0-132.267 59.307-132.267 132.267zM341.333 405.333h341.333v85.333h-341.333v-85.333zM725.333 661.333h-170.667v-81.067h170.667c72.96 0 132.267-59.307 132.267-132.267s-59.307-132.267-132.267-132.267h-170.667v-81.067h170.667c117.76 0 213.333 95.573 213.333 213.333s-95.573 213.333-213.333 213.333z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 618.667l-341.333-213.333-341.333 213.333v85.333l341.333-213.333 341.333 213.333v-85.333z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 618.667l-341.333-213.333-341.333 213.333v85.333l341.333-213.333 341.333 213.333v-85.333z" /> -<glyph unicode="" d="M784.853 507.733c-78.507 68.907-181.333 110.933-294.187 110.933-198.4 0-366.293-129.28-424.96-308.053l100.907-33.28c44.8 136.32 172.8 234.667 324.053 234.667 83.413 0 159.147-30.72 218.24-80.427l-154.24-154.24h384v384l-153.813-153.6z" /> -<glyph unicode="" d="M810.667 405.333h-597.333v85.333h597.333v-85.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM725.333 405.333h-426.667v85.333h426.667v-85.333z" /> -<glyph unicode="" d="M298.667 490.667v-85.333h426.667v85.333h-426.667zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M426.667 576v170.667l-298.667-298.667 298.667-298.667v174.933c213.333 0 362.667-68.267 469.333-217.6-42.667 213.333-170.667 426.667-469.333 469.333z" /> -<glyph unicode="" d="M298.667 618.667v128l-298.667-298.667 298.667-298.667v128l-170.667 170.667 170.667 170.667zM554.667 576v170.667l-298.667-298.667 298.667-298.667v174.933c213.333 0 362.667-68.267 469.333-217.6-42.667 213.333-170.667 426.667-469.333 469.333z" /> -<glyph unicode="" d="M671.147 832h-318.293l-224.853-224.853v-318.080l224.853-225.067h318.080l225.067 224.853v318.293l-224.853 224.853zM512 221.867c-30.507 0-55.467 24.747-55.467 55.467 0 30.507 24.96 55.467 55.467 55.467s55.467-24.747 55.467-55.467c0-30.72-24.96-55.467-55.467-55.467zM554.667 405.333h-85.333v256h85.333v-256z" /> -<glyph unicode="" d="M725.333 832h-512c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v512l-170.667 170.667zM512 149.333c-70.613 0-128 57.387-128 128s57.387 128 128 128 128-57.387 128-128-57.387-128-128-128zM640 576h-426.667v170.667h426.667v-170.667z" /> -<glyph unicode="" d="M128 746.667h85.333v85.333c-47.147 0-85.333-38.187-85.333-85.333zM128 405.333h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM128 576h85.333v85.333h-85.333v-85.333zM554.667 832h-85.333v-85.333h85.333v85.333zM810.667 832v-85.333h85.333c0 47.147-38.187 85.333-85.333 85.333zM213.333 64v85.333h-85.333c0-47.147 38.187-85.333 85.333-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM384 832h-85.333v-85.333h85.333v85.333zM469.333 64h85.333v85.333h-85.333v-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 64c47.147 0 85.333 38.187 85.333 85.333h-85.333v-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM640 746.667h85.333v85.333h-85.333v-85.333zM298.667 234.667h426.667v426.667h-426.667v-426.667zM384 576h256v-256h-256v256z" /> -<glyph unicode="" d="M85.76 64l895.573 384-895.573 384-0.427-298.667 640-85.333-640-85.333z" /> -<glyph unicode="" d="M128 192h256v85.333h-256v-85.333zM128 704v-85.333h768v85.333h-768zM128 405.333h512v85.333h-512v-85.333z" /> -<glyph unicode="" d="M213.333 234.667v-85.333h597.333v85.333h-597.333zM405.333 413.867h213.333l38.4-93.867h89.6l-202.667 469.333h-64l-202.667-469.333h89.6l38.4 93.867zM512 704.853l79.787-214.187h-159.573l79.787 214.187z" /> -<glyph unicode="" d="M533.333 618.667c-112.853 0-215.68-42.027-294.4-110.933l-153.6 153.6v-384h384l-154.24 154.24c59.093 49.707 134.827 80.427 218.24 80.427 151.253 0 279.253-98.347 324.053-234.667l100.907 33.28c-58.667 178.773-226.56 308.053-424.96 308.053z" /> -<glyph unicode="" d="M938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM336.213 815.36l-54.827 65.28-196.053-164.48 54.827-65.28 196.053 164.48zM533.333 618.667h-64v-256l202.453-121.813 32.213 52.693-170.667 101.12v224zM511.787 789.333c-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384-171.947 384-384.213 384zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.547-298.667-298.667-298.667z" /> -<glyph unicode="" d="M938.667 714.667l-196.267 164.267-55.467-66.133 196.267-164.267 55.467 66.133zM334.933 814.933l-55.467 66.133-194.133-166.4 55.467-66.133 194.133 166.4zM533.333 618.667h-64v-256l202.667-121.6 32 53.333-170.667 100.267v224zM512 789.333c-213.333 0-384-172.8-384-384s170.667-384 384-384c211.2 0 384 172.8 384 384s-172.8 384-384 384zM512 106.667c-164.267 0-298.667 134.4-298.667 298.667s134.4 298.667 298.667 298.667 298.667-134.4 298.667-298.667c0-166.4-134.4-298.667-298.667-298.667z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM533.333 661.333h-64v-256l223.787-134.4 32.213 52.48-192 113.92z" /> -<glyph unicode="" d="M336.213 815.36l-54.827 65.28-196.053-164.48 54.827-65.28 196.053 164.48zM938.667 715.947l-196.053 164.48-54.827-65.28 196.053-164.48 54.827 65.28zM511.787 789.333c-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384-171.947 384-384.213 384zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.547-298.667-298.667-298.667zM554.667 576h-85.333v-128h-128v-85.333h128v-128h85.333v128h128v85.333h-128v128z" /> -<glyph unicode="" d="M554.667 576v234.667c0 35.413-28.587 64-64 64s-64-28.587-64-64v-157.013l333.867-333.867 135.467-42.453v85.333l-341.333 213.333zM128 734.933l212.693-212.693-255.36-159.573v-85.333l341.333 106.667v-234.667l-85.333-64v-64l149.333 42.667 149.333-42.667v64l-85.333 64v158.933l244.267-244.267 54.4 54.4-670.933 670.933-54.4-54.4z" /> -<glyph unicode="" d="M896 277.333v85.333l-341.333 213.333v234.667c0 35.413-28.587 64-64 64s-64-28.587-64-64v-234.667l-341.333-213.333v-85.333l341.333 106.667v-234.667l-85.333-64v-64l149.333 42.667 149.333-42.667v64l-85.333 64v234.667l341.333-106.667z" /> -<glyph unicode="" d="M298.667 234.667v-156.373c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v156.373h-426.88zM725.333 732.373c0 31.573-25.387 56.96-56.96 56.96h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-497.707h426.667v497.707z" /> -<glyph unicode="" d="M725.333 732.373c0 31.573-25.387 56.96-56.96 56.96h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-412.373h426.667v412.373zM298.667 320v-241.707c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v241.707h-426.88z" /> -<glyph unicode="" d="M725.333 732.373c0 31.573-25.387 56.96-56.96 56.96h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-327.040h426.667v327.040zM298.667 405.333v-327.040c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v327.040h-426.88z" /> -<glyph unicode="" d="M725.333 732.373c0 31.573-25.387 56.96-56.96 56.96h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-241.707h426.667v241.707zM298.667 490.667v-412.373c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v412.373h-426.88z" /> -<glyph unicode="" d="M725.333 732.373c0 31.573-25.387 56.96-56.96 56.96h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-156.373h426.667v156.373zM298.667 576v-497.707c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v497.707h-426.88z" /> -<glyph unicode="" d="M725.333 732.373c0 31.573-25.387 56.96-56.96 56.96h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-113.707h426.667v113.707zM298.667 618.667v-540.373c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v540.373h-426.88z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-654.293c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v654.293c-0.213 31.573-25.6 56.96-57.173 56.96zM554.667 192h-85.333v85.333h85.333v-85.333zM554.667 362.667h-85.333v213.333h85.333v-213.333z" /> -<glyph unicode="" d="M469.333 106.667v128h-170.667v-156.373c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v156.373h-187.733l-68.48-128zM668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-497.707h170.667v106.667h-85.333l170.667 320v-234.667h85.333l-102.4-192h187.733v497.707c0 31.573-25.387 56.96-56.96 56.96z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-391.040h85.333l170.667 320v-234.667h85.333l-45.44-85.333h130.773v391.040c0 31.573-25.387 56.96-56.96 56.96zM469.333 106.667v234.667h-170.667v-263.040c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v263.040h-130.773l-125.44-234.667z" /> -<glyph unicode="" d="M617.173 384l-147.84-277.333v234.667h-85.333l22.827 42.667h-108.16v-305.707c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v305.707h-108.373zM668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-348.373h108.16l147.84 277.333v-234.667h85.333l-22.827-42.667h108.16v348.373c0 31.573-25.387 56.96-56.96 56.96z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-241.707h164.907l91.093 170.667v-170.667h170.667v241.707c0 31.573-25.387 56.96-56.96 56.96zM554.667 426.667h85.333l-170.667-320v234.667h-85.333l79.573 149.333h-164.907v-412.373c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v412.373h-170.667v-64z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-156.373h210.56l45.44 85.333v-85.333h170.667v156.373c0 31.573-25.387 56.96-56.96 56.96zM554.667 426.667h85.333l-170.667-320v234.667h-85.333l125.227 234.667h-210.56v-497.707c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v497.707h-170.667v-149.333z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-113.707h233.173l22.827 42.667v-42.667h170.667v113.707c0 31.573-25.387 56.96-56.96 56.96zM554.667 426.667h85.333l-170.667-320v234.667h-85.333l147.84 277.333h-233.173v-540.373c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v540.373h-170.667v-192z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-654.293c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v654.293c-0.213 31.573-25.6 56.96-57.173 56.96zM469.333 106.667v234.667h-85.333l170.667 320v-234.667h85.333l-170.667-320z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-654.293c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v654.293c-0.213 31.573-25.6 56.96-57.173 56.96z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-654.293c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v654.293c-0.213 31.573-25.6 56.96-57.173 56.96z" /> -<glyph unicode="" d="M668.373 789.333h-71.040v85.333h-170.667v-85.333h-71.040c-31.573 0-56.96-25.387-56.96-56.96v-654.293c0-31.36 25.387-56.96 56.96-56.96h312.96c31.36 0 56.96 25.387 56.96 56.96v654.293c-0.213 31.573-25.6 56.96-57.173 56.96zM552.533 194.133h-81.067v81.067h81.067v-81.067zM610.133 418.56s-16.213-17.92-28.587-30.293c-20.693-20.693-35.413-48.853-35.413-68.267h-68.267c0 35.413 19.627 65.067 39.68 85.12l39.68 40.32c11.52 11.52 18.773 27.52 18.773 45.227 0 35.413-28.587 64-64 64s-64-28.587-64-64h-64c0 70.613 57.387 128 128 128s128-57.387 128-128c0-28.16-11.307-53.76-29.867-72.107z" /> -<glyph unicode="" d="M755.413 631.253l-243.413 243.413h-42.667v-323.627l-195.627 195.627-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 195.627 195.627v-323.627h42.667l243.413 243.413-183.040 183.253 183.040 183.253zM554.667 711.253l80.213-80.213-80.213-80v160.213zM634.88 264.747l-80.213-80v160.427l80.213-80.427z" /> -<glyph unicode="" d="M298.667 448l-85.333 85.333-85.333-85.333 85.333-85.333 85.333 85.333zM755.413 631.253l-243.413 243.413h-42.667v-323.627l-195.627 195.627-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 195.627 195.627v-323.627h42.667l243.413 243.413-183.040 183.253 183.040 183.253zM554.667 711.253l80.213-80.213-80.213-80v160.213zM634.88 264.747l-80.213-80v160.427l80.213-80.427zM810.667 533.333l-85.333-85.333 85.333-85.333 85.333 85.333-85.333 85.333z" /> -<glyph unicode="" d="M554.667 707.627l80.213-80.213-68.267-68.267 60.373-60.373 128.64 128.64-243.627 243.627h-42.667v-214.613l85.333-85.333v136.533zM231.040 785.707l-60.373-60.373 280.96-280.96-238.293-238.293 60.373-60.373 195.627 195.627v-323.627h42.667l183.253 183.253 97.92-97.92 60.16 60.373-622.293 622.293zM554.667 181.12v160.213l80.213-80.213-80.213-80z" /> -<glyph unicode="" d="M607.573 447.573l98.987-98.987c11.947 30.933 18.773 64.427 18.773 99.413 0 34.773-6.613 68.053-18.347 98.773l-99.413-99.2zM833.28 673.493l-53.973-53.973c26.667-51.413 42.027-109.653 42.027-171.733s-15.36-120.107-42.027-171.733l51.2-51.2c41.173 66.133 65.493 143.573 65.493 226.773 0 81.493-23.253 157.227-62.72 221.867zM670.080 631.253l-243.413 243.413h-42.667v-323.627l-195.627 195.627-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 195.627 195.627v-323.627h42.667l243.413 243.413-183.040 183.253 183.040 183.253zM469.333 711.253l80.213-80.213-80.213-80v160.213zM549.547 264.747l-80.213-80v160.427l80.213-80.427z" /> -<glyph unicode="" d="M462.933 420.267h98.133l-49.067 155.733-49.067-155.733zM853.333 589.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893l141.44 141.44-141.44 141.44zM610.133 277.333l-29.867 85.333h-136.533l-29.867-85.333h-81.067l136.533 384h85.333l136.533-384h-81.067z" /> -<glyph unicode="" d="M853.333 589.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893l141.44 141.44-141.44 141.44zM512 192c-141.44 0-256 114.56-256 256s114.56 256 256 256 256-114.56 256-256-114.56-256-256-256zM512 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667z" /> -<glyph unicode="" d="M853.333 306.56l141.44 141.44-141.44 141.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893zM512 192c-141.44 0-256 114.56-256 256s114.56 256 256 256 256-114.56 256-256-114.56-256-256-256z" /> -<glyph unicode="" d="M853.333 306.56l141.44 141.44-141.44 141.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893zM512 192v512c141.44 0 256-114.56 256-256s-114.56-256-256-256z" /> -<glyph unicode="" d="M554.667 872.533v-129.28c144.64-20.693 256-144.853 256-295.253 0-38.187-7.467-74.667-20.48-108.16l110.933-65.493c23.68 53.12 37.547 111.573 37.547 173.653 0 221.227-168.32 402.987-384 424.533zM512 149.333c-164.907 0-298.667 133.76-298.667 298.667 0 150.4 111.36 274.56 256 295.253v129.28c-215.893-21.333-384-203.307-384-424.533 0-235.733 190.72-426.667 426.453-426.667 141.227 0 266.027 68.907 343.68 174.507l-110.72 65.28c-54.613-68.053-138.453-111.787-232.747-111.787z" /> -<glyph unicode="" d="M298.667 743.040h426.667v-85.333h85.333v170.667c0 47.147-38.187 84.907-85.333 84.907l-426.667 0.427c-47.147 0-85.333-38.187-85.333-85.333v-170.667h85.333v85.333zM657.707 248.747l195.627 195.627-195.627 195.627-60.373-60.373 135.253-135.253-135.253-135.467 60.373-60.16zM426.667 308.907l-135.253 135.253 135.253 135.467-60.373 60.373-195.627-195.627 195.627-195.627 60.373 60.16zM725.333 145.707h-426.667v85.333h-85.333v-170.667c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v170.667h-85.333v-85.333z" /> -<glyph unicode="" d="M170.667 704h768v85.333h-768c-47.147 0-85.333-38.187-85.333-85.333v-469.333h-85.333v-128h597.333v128h-426.667v469.333zM981.333 618.667h-256c-23.467 0-42.667-19.2-42.667-42.667v-426.667c0-23.467 19.2-42.667 42.667-42.667h256c23.467 0 42.667 19.2 42.667 42.667v426.667c0 23.467-19.2 42.667-42.667 42.667zM938.667 234.667h-170.667v298.667h170.667v-298.667z" /> -<glyph unicode="" d="M896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h213.333v-85.333h341.333v85.333h213.333c47.147 0 84.907 38.187 84.907 85.333l0.427 512c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-768v512h768v-512zM810.667 618.667h-469.333v-85.333h469.333v85.333zM810.667 448h-469.333v-85.333h469.333v85.333zM298.667 618.667h-85.333v-85.333h85.333v85.333zM298.667 448h-85.333v-85.333h85.333v85.333z" /> -<glyph unicode="" d="M512 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667zM893.44 490.667c-19.627 177.92-160.853 319.147-338.773 338.773v87.893h-85.333v-87.893c-177.92-19.627-319.147-160.853-338.773-338.773h-87.893v-85.333h87.893c19.627-177.92 160.853-319.147 338.773-338.773v-87.893h85.333v87.893c177.92 19.627 319.147 160.853 338.773 338.773h87.893v85.333h-87.893zM512 149.333c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667z" /> -<glyph unicode="" d="M893.44 490.667c-19.627 177.92-160.853 319.147-338.773 338.773v87.893h-85.333v-87.893c-177.92-19.627-319.147-160.853-338.773-338.773h-87.893v-85.333h87.893c19.627-177.92 160.853-319.147 338.773-338.773v-87.893h85.333v87.893c177.92 19.627 319.147 160.853 338.773 338.773h87.893v85.333h-87.893zM512 149.333c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667z" /> -<glyph unicode="" d="M893.44 490.667c-19.627 177.92-160.853 319.147-338.773 338.773v87.893h-85.333v-87.893c-48.213-5.333-93.44-19.84-134.613-41.387l64-64c34.987 14.507 73.173 22.613 113.28 22.613 164.907 0 298.667-133.76 298.667-298.667 0-40.107-8.107-78.293-22.4-113.28l64-64c21.547 41.173 35.84 86.4 41.173 134.613h87.893v85.333h-87.893zM128 777.6l86.827-86.827c-45.653-55.893-75.947-124.587-84.267-200.107h-87.893v-85.333h87.893c19.627-177.92 160.853-319.147 338.773-338.773v-87.893h85.333v87.893c75.52 8.32 144.213 38.827 200.107 84.48l86.827-87.040 54.4 54.187-713.6 713.813-54.4-54.4zM693.973 211.627c-50.347-38.827-113.28-62.293-181.973-62.293-164.907 0-298.667 133.76-298.667 298.667 0 68.693 23.467 131.627 62.293 181.973l418.347-418.347z" /> -<glyph unicode="" d="M893.44 487.040c-19.627 177.92-160.853 319.147-338.773 338.773v87.893h-85.333v-87.893c-48.213-5.333-93.44-19.84-134.613-41.387l64-64c34.987 14.293 73.173 22.4 113.28 22.4 164.907 0 298.667-133.76 298.667-298.667 0-40.107-8.107-78.293-22.4-113.28l64-64c21.547 41.173 35.84 86.4 41.173 134.613h87.893v85.333h-87.893zM128 773.973l86.827-86.827c-45.653-55.893-76.16-124.587-84.48-200.107h-87.68v-85.333h87.893c19.627-177.92 160.853-319.147 338.773-338.773v-87.893h85.333v87.893c75.52 8.32 144.213 38.827 200.107 84.48l87.040-87.040 54.187 54.187-713.6 713.813-54.4-54.4zM693.973 208c-50.347-38.827-113.493-62.293-181.973-62.293-164.907 0-298.667 133.76-298.667 298.667 0 68.693 23.467 131.627 62.293 181.973l418.347-418.347z" /> -<glyph unicode="" d="M893.44 487.040c-19.627 177.92-160.853 319.147-338.773 338.773v87.893h-85.333v-87.893c-177.92-19.627-319.147-160.853-338.773-338.773h-87.893v-85.333h87.893c19.627-177.92 160.853-319.147 338.773-338.773v-87.893h85.333v87.893c177.92 19.627 319.147 160.853 338.773 338.773h87.893v85.333h-87.893zM512 145.707c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667z" /> -<glyph unicode="" d="M298.667 192h85.333v512h-85.333v-512zM469.333 21.333h85.333v853.333h-85.333v-853.333zM128 362.667h85.333v170.667h-85.333v-170.667zM640 192h85.333v512h-85.333v-512zM810.667 533.333v-170.667h85.333v170.667h-85.333z" /> -<glyph unicode="" d="M85.333 21.333h853.333v853.333zM725.333 661.333l-640-640h640z" /> -<glyph unicode="" d="M512.427 43.093l496.213 618.24c-19.2 14.507-210.133 170.667-496.64 170.667s-477.44-156.16-496.64-170.667l496.64-618.667 0.427 0.427zM150.827 492.587l361.173-449.92 0.427 0.427 360.96 449.493c-18.347 14.080-156.16 126.080-361.387 126.080-205.44 0-343.040-112-361.173-126.080z" /> -<glyph unicode="" d="M853.333 871.040h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM853.333 103.040h-682.667v682.667h682.667v-682.667zM768 700.373h-213.333c-47.147 0-85.333-38.187-85.333-85.333v-97.067c-25.387-14.72-42.667-42.027-42.667-73.6 0-47.147 38.187-85.333 85.333-85.333s85.333 38.187 85.333 85.333c0 31.573-17.28 58.667-42.667 73.6v97.067h128v-341.333h-341.333v341.333h85.333v85.333h-170.667v-512h512v512z" /> -<glyph unicode="" d="M170.667 789.333h298.667v85.333h-298.667c-47.147 0-85.333-38.187-85.333-85.333v-298.667h85.333v298.667zM426.667 405.333l-170.667-213.333h512l-128 170.667-86.613-115.627-126.72 158.293zM725.333 597.333c0 35.413-28.587 64-64 64s-64-28.587-64-64 28.587-64 64-64 64 28.587 64 64zM853.333 874.667h-298.667v-85.333h298.667v-298.667h85.333v298.667c0 47.147-38.187 85.333-85.333 85.333zM853.333 106.667h-298.667v-85.333h298.667c47.147 0 85.333 38.187 85.333 85.333v298.667h-85.333v-298.667zM170.667 405.333h-85.333v-298.667c0-47.147 38.187-85.333 85.333-85.333h298.667v85.333h-298.667v298.667z" /> -<glyph unicode="" d="M554.667 405.333v-341.333h341.333v341.333h-341.333zM128 64h341.333v341.333h-341.333v-341.333zM128 832v-341.333h341.333v341.333h-341.333zM710.613 888.107l-241.28-241.493 241.28-241.28 241.28 241.28-241.28 241.493z" /> -<glyph unicode="" d="M896 746.667h-768c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 234.667h-597.333v426.667h597.333v-426.667zM426.667 277.333h170.667c23.68 0 42.667 19.2 42.667 42.667v128c0 23.467-18.987 42.667-42.667 42.667v42.667c0 47.147-38.187 85.333-85.333 85.333s-85.333-38.187-85.333-85.333v-42.667c-23.68 0-42.667-19.2-42.667-42.667v-128c0-23.467 18.987-42.667 42.667-42.667zM460.8 533.333c0 28.373 22.827 51.2 51.2 51.2s51.2-23.040 51.2-51.2v-42.667h-102.4v42.667z" /> -<glyph unicode="" d="M426.667 277.333h170.667c23.68 0 42.667 19.2 42.667 42.667v128c0 23.467-18.987 42.667-42.667 42.667v42.667c0 47.147-38.187 85.333-85.333 85.333s-85.333-38.187-85.333-85.333v-42.667c-23.68 0-42.667-19.2-42.667-42.667v-128c0-23.467 18.987-42.667 42.667-42.667zM460.8 533.333c0 28.373 22.827 51.2 51.2 51.2s51.2-23.040 51.2-51.2v-42.667h-102.4v42.667zM725.333 917.333h-426.667c-47.147 0-85.333-38.187-85.333-85.333v-768c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v768c0 47.147-38.187 85.333-85.333 85.333zM725.333 149.333h-426.667v597.333h426.667v-597.333z" /> -<glyph unicode="" d="M992.213 415.147l-109.653 109.653-60.373-60.373 94.507-94.507-241.28-241.28-482.773 482.773 241.28 241.28 89.387-89.387 60.373 60.373-104.533 104.533c-24.96 24.96-65.493 24.96-90.453 0l-271.573-271.573c-24.96-24.96-24.96-65.493 0-90.453l512.853-512.853c24.96-24.96 65.493-24.96 90.453 0l271.573 271.573c25.173 24.747 25.173 65.28 0.213 90.24zM361.173 85.973c-139.307 66.133-239.36 201.6-254.507 362.027h-64c21.76-262.827 241.493-469.333 509.867-469.333 9.6 0 18.773 0.853 28.373 1.493l-162.773 162.773-56.96-56.96zM682.667 576h213.333c23.68 0 42.667 19.2 42.667 42.667v170.667c0 23.467-18.987 42.667-42.667 42.667v21.333c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667v-21.333c-23.68 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 18.987-42.667 42.667-42.667zM716.8 853.333c0 40.107 32.427 72.533 72.533 72.533s72.533-32.427 72.533-72.533v-21.333h-145.067v21.333z" /> -<glyph unicode="" d="M703.36 852.693c139.307-66.133 239.36-201.6 254.507-362.027h64c-21.76 262.827-241.493 469.333-509.867 469.333-9.6 0-18.773-0.853-28.373-1.493l162.773-162.773 56.96 56.96zM436.48 885.547c-24.96 24.96-65.493 24.96-90.453 0l-271.573-271.573c-24.96-24.96-24.96-65.493 0-90.453l512.853-512.853c24.96-24.96 65.493-24.96 90.453 0l271.573 271.573c24.96 24.96 24.96 65.493 0 90.453l-512.853 512.853zM632.747 55.893l-513.067 512.853 271.573 271.573 512.853-512.853-271.36-271.573zM320.64 43.307c-139.307 66.133-239.36 201.6-254.507 362.027h-64c21.76-262.827 241.493-469.333 509.867-469.333 9.6 0 18.773 0.853 28.373 1.493l-162.773 162.773-56.96-56.96z" /> -<glyph unicode="" d="M768 874.667h-341.333l-255.147-256-0.853-512c0-46.933 38.4-85.333 85.333-85.333h512c46.933 0 85.333 38.4 85.333 85.333v682.667c0 46.933-38.4 85.333-85.333 85.333zM512 618.667h-85.333v170.667h85.333v-170.667zM640 618.667h-85.333v170.667h85.333v-170.667zM768 618.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M384 277.333h277.333c58.88 0 106.667 47.787 106.667 106.667s-47.787 106.667-106.667 106.667h-2.133c-10.453 72.32-72.107 128-147.2 128-59.733 0-110.933-35.413-134.827-86.187h-7.040c-64.213-6.827-114.133-61.227-114.133-127.147 0-70.613 57.387-128 128-128zM896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 148.693h-768v598.613h768v-598.613z" /> -<glyph unicode="" d="M85.333 21.333h853.333v853.333z" /> -<glyph unicode="" d="M85.333 21.333h853.333v853.333zM512 448l-426.667-426.667h426.667z" /> -<glyph unicode="" d="M85.333 21.333h853.333v853.333zM597.333 533.333l-512-512h512z" /> -<glyph unicode="" d="M85.333 21.333h853.333v853.333zM725.333 661.333l-640-640h640z" /> -<glyph unicode="" d="M85.333 21.333h853.333v853.333z" /> -<glyph unicode="" d="M938.667 618.667v256l-853.333-853.333h682.667v597.333zM853.333 21.333h85.333v85.333h-85.333v-85.333zM853.333 533.333v-341.333h85.333v341.333h-85.333z" /> -<glyph unicode="" d="M938.667 618.667v256l-853.333-853.333h682.667v597.333zM853.333 533.333v-341.333h85.333v341.333h-85.333zM512 21.333v426.667l-426.667-426.667h426.667zM853.333 21.333h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M938.667 618.667v256l-853.333-853.333h682.667v597.333zM597.333 21.333v512l-512-512h512zM853.333 533.333v-341.333h85.333v341.333h-85.333zM853.333 21.333h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M938.667 618.667v256l-853.333-853.333h682.667v597.333zM725.333 21.333v640l-640-640h640zM853.333 533.333v-341.333h85.333v341.333h-85.333zM853.333 21.333h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M853.333 192h85.333v341.333h-85.333v-341.333zM853.333 21.333h85.333v85.333h-85.333v-85.333zM85.333 21.333h682.667v597.333h170.667v256l-853.333-853.333z" /> -<glyph unicode="" d="M810.24 746.667c0 47.147-37.76 85.333-84.907 85.333h-298.667l-99.84-99.84 483.84-483.84-0.427 498.347zM155.733 794.453l-54.187-54.187 111.787-112v-478.933c0-47.147 38.187-85.333 85.333-85.333h427.093c14.933 0 28.8 4.267 40.96 10.88l80.213-80.213 54.187 54.4-745.387 745.387z" /> -<glyph unicode="" d="M853.333 668.587v-561.92h-561.92l561.92 561.92zM938.667 874.667l-853.333-853.333h853.333v853.333z" /> -<glyph unicode="" d="M896 917.333l-366.507-366.507 366.507-366.507v733.013zM203.733 768l-54.4-54.187 271.573-271.573-378.24-378.24h756.267l85.333-85.333 54.4 54.4-734.933 734.933z" /> -<glyph unicode="" d="M512.427 43.093l496.213 618.24c-19.2 14.507-210.133 170.667-496.64 170.667s-477.44-156.16-496.64-170.667l496.64-618.667 0.427 0.427z" /> -<glyph unicode="" d="M512.427 43.093l496.213 618.24c-19.2 14.507-210.133 170.667-496.64 170.667s-477.44-156.16-496.64-170.667l496.64-618.667 0.427 0.427zM284.587 325.973l227.413-283.307 0.213 0.213 227.2 283.093c-11.307 8.747-98.133 79.36-227.413 79.36s-216.107-70.613-227.413-79.36z" /> -<glyph unicode="" d="M512.427 43.093l496.213 618.24c-19.2 14.507-210.133 170.667-496.64 170.667s-477.44-156.16-496.64-170.667l496.64-618.667 0.427 0.427zM204.373 426.027l307.627-383.36 0.213 0.427 307.413 382.933c-15.36 11.947-132.693 107.307-307.627 107.307s-292.267-95.36-307.627-107.307z" /> -<glyph unicode="" d="M512.427 43.093l496.213 618.24c-19.2 14.507-210.133 170.667-496.64 170.667s-477.44-156.16-496.64-170.667l496.64-618.667 0.427 0.427zM150.827 492.587l361.173-449.92 0.427 0.427 360.96 449.493c-18.347 14.080-156.16 126.080-361.387 126.080-205.44 0-343.040-112-361.173-126.080z" /> -<glyph unicode="" d="M512.427 43.093l496.213 618.24c-19.2 14.507-210.133 170.667-496.64 170.667s-477.44-156.16-496.64-170.667l496.64-618.667 0.427 0.427z" /> -<glyph unicode="" d="M1008.64 661.333c-19.2 14.507-210.133 170.667-496.64 170.667-64.213 0-123.307-8.107-177.067-20.48l440.747-440.32 232.96 290.133zM139.733 898.347l-54.4-54.4 87.68-87.68c-91.307-42.027-147.627-87.467-157.653-95.147l496.64-618.453 0.427 0.427 166.4 207.36 141.44-141.44 54.4 54.4-734.933 734.933z" /> -<glyph unicode="" d="M85.333 106.667h853.333v170.667h-853.333v-170.667zM170.667 234.667h85.333v-85.333h-85.333v85.333zM85.333 789.333v-170.667h853.333v170.667h-853.333zM256 661.333h-85.333v85.333h85.333v-85.333zM85.333 362.667h853.333v170.667h-853.333v-170.667zM170.667 490.667h85.333v-85.333h-85.333v85.333z" /> -<glyph unicode="" d="M640 661.333v-170.667h42.667v-85.333h-128v341.333h85.333l-128 170.667-128-170.667h85.333v-341.333h-128v88.32c30.080 15.573 51.2 46.080 51.2 82.347 0 51.84-42.027 93.867-93.867 93.867s-93.867-42.027-93.867-93.867c0-36.267 21.12-66.773 51.2-82.347v-88.32c0-47.147 38.187-85.333 85.333-85.333h128v-130.133c-30.293-15.573-51.2-46.72-51.2-83.2 0-51.84 42.027-93.867 93.867-93.867s93.867 42.027 93.867 93.867c0 36.48-20.907 67.627-51.2 83.2v130.133h128c47.147 0 85.333 38.187 85.333 85.333v85.333h42.667v170.667h-170.667z" /> -<glyph unicode="" d="M874.667 554.667c11.947 0 23.253-1.707 34.773-3.413l114.56 152.747c-142.72 107.093-320 170.667-512 170.667s-369.28-63.573-512-170.667l512-682.667 149.333 199.040v120.96c0 117.76 95.573 213.333 213.333 213.333zM981.333 277.333v64c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667v-64c-23.467 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 19.2-42.667 42.667-42.667h213.333c23.467 0 42.667 19.2 42.667 42.667v170.667c0 23.467-19.2 42.667-42.667 42.667zM938.667 277.333h-128v64c0 35.413 28.587 64 64 64s64-28.587 64-64v-64z" /> -<glyph unicode="" d="M512 490.667c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 405.333c0 141.44-114.56 256-256 256s-256-114.56-256-256c0-94.72 51.413-177.067 127.787-221.44l43.093 74.24c-50.987 29.653-85.547 84.053-85.547 147.2 0 94.293 76.373 170.667 170.667 170.667s170.667-76.373 170.667-170.667c0-63.147-34.56-117.547-85.547-146.987l43.093-74.24c76.373 44.16 127.787 126.507 127.787 221.227zM512 832c-235.733 0-426.667-190.933-426.667-426.667 0-157.653 85.76-295.040 213.12-368.853l42.667 73.813c-101.76 58.88-170.453 168.96-170.453 295.040 0 188.587 152.747 341.333 341.333 341.333s341.333-152.747 341.333-341.333c0-126.080-68.693-236.16-170.453-295.253l42.667-73.813c127.36 74.027 213.12 211.413 213.12 369.067 0 235.733-191.147 426.667-426.667 426.667z" /> -<glyph unicode="" d="M704 704v-490.667c0-94.293-76.373-170.667-170.667-170.667s-170.667 76.373-170.667 170.667v533.333c0 58.88 47.787 106.667 106.667 106.667s106.667-47.787 106.667-106.667v-448c0-23.467-18.987-42.667-42.667-42.667s-42.667 19.2-42.667 42.667v405.333h-64v-405.333c0-58.88 47.787-106.667 106.667-106.667s106.667 47.787 106.667 106.667v448c0 94.293-76.373 170.667-170.667 170.667s-170.667-76.373-170.667-170.667v-533.333c0-129.707 105.173-234.667 234.667-234.667s234.667 104.96 234.667 234.667v490.667h-64z" /> -<glyph unicode="" d="M503.467 494.933c-96.853 25.173-128 50.987-128 91.52 0 46.507 42.88 79.147 115.2 79.147 75.947 0 104.107-36.267 106.667-89.6h94.293c-2.773 73.6-47.787 140.587-136.96 162.56v93.44h-128v-92.16c-82.773-18.133-149.333-71.467-149.333-154.027 0-98.56 81.707-147.627 200.533-176.213 106.88-25.6 128-62.933 128-103.040 0-29.227-20.693-76.16-115.2-76.16-87.893 0-122.667 39.467-127.147 89.6h-94.080c5.333-93.44 75.093-145.707 157.227-163.413v-92.587h128v91.733c82.987 16 149.333 64 149.333 151.68 0 120.747-103.68 162.133-200.533 187.52z" /> -<glyph unicode="" d="M128 832v-768h768v768h-768zM469.333 149.333h-256v256h256v-256zM469.333 490.667h-256v256h256v-256zM810.667 149.333h-256v256h256v-256zM810.667 490.667h-256v256h256v-256z" /> -<glyph unicode="" d="M384 490.667h-85.333v-85.333h85.333v85.333zM554.667 320h-85.333v-85.333h85.333v85.333zM384 832h-85.333v-85.333h85.333v85.333zM554.667 490.667h-85.333v-85.333h85.333v85.333zM213.333 832h-85.333v-85.333h85.333v85.333zM554.667 661.333h-85.333v-85.333h85.333v85.333zM725.333 490.667h-85.333v-85.333h85.333v85.333zM554.667 832h-85.333v-85.333h85.333v85.333zM725.333 832h-85.333v-85.333h85.333v85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM213.333 661.333h-85.333v-85.333h85.333v85.333zM810.667 832v-85.333h85.333v85.333h-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM213.333 490.667h-85.333v-85.333h85.333v85.333zM128 64h768v85.333h-768v-85.333zM213.333 320h-85.333v-85.333h85.333v85.333z" /> -<glyph unicode="" d="M298.667 746.667h85.333v85.333h-85.333v-85.333zM298.667 405.333h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM469.333 234.667h85.333v85.333h-85.333v-85.333zM469.333 64h85.333v85.333h-85.333v-85.333zM128 64h85.333v85.333h-85.333v-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM128 405.333h85.333v85.333h-85.333v-85.333zM128 576h85.333v85.333h-85.333v-85.333zM128 746.667h85.333v85.333h-85.333v-85.333zM469.333 405.333h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 64h85.333v85.333h-85.333v-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM469.333 576h85.333v85.333h-85.333v-85.333zM810.667 832v-85.333h85.333v85.333h-85.333zM469.333 746.667h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM640 405.333h85.333v85.333h-85.333v-85.333zM640 746.667h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M757.333 661.333l-160 160-426.667-426.667v-160h160l426.667 426.667zM883.413 787.413c16.64 16.64 16.64 43.733 0 60.373l-99.627 99.627c-16.64 16.64-43.733 16.64-60.373 0l-83.413-83.413 160-160 83.413 83.413zM0 106.667h1024v-170.667h-1024z" /> -<glyph unicode="" d="M128 64h85.333v85.333h-85.333v-85.333zM213.333 661.333h-85.333v-85.333h85.333v85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM213.333 832h-85.333v-85.333h85.333v85.333zM384 832h-85.333v-85.333h85.333v85.333zM725.333 832h-85.333v-85.333h85.333v85.333zM554.667 661.333h-85.333v-85.333h85.333v85.333zM554.667 832h-85.333v-85.333h85.333v85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM469.333 64h85.333v85.333h-85.333v-85.333zM128 405.333h768v85.333h-768v-85.333zM810.667 832v-85.333h85.333v85.333h-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM469.333 234.667h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM810.667 64h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M128 64h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM213.333 661.333h-85.333v-85.333h85.333v85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM384 832h-85.333v-85.333h85.333v85.333zM213.333 832h-85.333v-85.333h85.333v85.333zM725.333 832h-85.333v-85.333h85.333v85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM810.667 832v-85.333h85.333v85.333h-85.333zM640 64h85.333v85.333h-85.333v-85.333zM554.667 832h-85.333v-341.333h-341.333v-85.333h341.333v-341.333h85.333v341.333h341.333v85.333h-341.333v341.333zM810.667 64h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M469.333 64h85.333v85.333h-85.333v-85.333zM469.333 234.667h85.333v85.333h-85.333v-85.333zM469.333 746.667h85.333v85.333h-85.333v-85.333zM469.333 576h85.333v85.333h-85.333v-85.333zM469.333 405.333h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM298.667 746.667h85.333v85.333h-85.333v-85.333zM298.667 405.333h85.333v85.333h-85.333v-85.333zM128 64h85.333v768h-85.333v-768zM810.667 576h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM810.667 832v-85.333h85.333v85.333h-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 64h85.333v85.333h-85.333v-85.333zM640 405.333h85.333v85.333h-85.333v-85.333zM640 746.667h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M554.667 661.333h-85.333v-85.333h85.333v85.333zM554.667 490.667h-85.333v-85.333h85.333v85.333zM725.333 490.667h-85.333v-85.333h85.333v85.333zM128 832v-768h768v768h-768zM810.667 149.333h-597.333v597.333h597.333v-597.333zM554.667 320h-85.333v-85.333h85.333v85.333zM384 490.667h-85.333v-85.333h85.333v85.333z" /> -<glyph unicode="" d="M298.667 64h85.333v85.333h-85.333v-85.333zM128 746.667h85.333v85.333h-85.333v-85.333zM298.667 746.667h85.333v85.333h-85.333v-85.333zM298.667 405.333h85.333v85.333h-85.333v-85.333zM128 64h85.333v85.333h-85.333v-85.333zM469.333 64h85.333v85.333h-85.333v-85.333zM128 405.333h85.333v85.333h-85.333v-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM128 576h85.333v85.333h-85.333v-85.333zM469.333 234.667h85.333v85.333h-85.333v-85.333zM640 405.333h85.333v85.333h-85.333v-85.333zM810.667 832v-768h85.333v768h-85.333zM640 64h85.333v85.333h-85.333v-85.333zM640 746.667h85.333v85.333h-85.333v-85.333zM469.333 405.333h85.333v85.333h-85.333v-85.333zM469.333 746.667h85.333v85.333h-85.333v-85.333zM469.333 576h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M640 64h85.333v85.333h-85.333v-85.333zM810.667 64h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM469.333 64h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM128 832v-768h85.333v682.667h682.667v85.333h-768zM810.667 576h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M298.667 64h85.333v85.333h-85.333v-85.333zM298.667 405.333h85.333v85.333h-85.333v-85.333zM469.333 405.333h85.333v85.333h-85.333v-85.333zM469.333 64h85.333v85.333h-85.333v-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM128 64h85.333v85.333h-85.333v-85.333zM128 405.333h85.333v85.333h-85.333v-85.333zM128 576h85.333v85.333h-85.333v-85.333zM469.333 234.667h85.333v85.333h-85.333v-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM128 832v-85.333h768v85.333h-768zM810.667 234.667h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM469.333 576h85.333v85.333h-85.333v-85.333zM810.667 64h85.333v85.333h-85.333v-85.333zM640 405.333h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M128 576h85.333v85.333h-85.333v-85.333zM128 746.667h85.333v85.333h-85.333v-85.333zM298.667 64h85.333v85.333h-85.333v-85.333zM298.667 405.333h85.333v85.333h-85.333v-85.333zM128 405.333h85.333v85.333h-85.333v-85.333zM128 64h85.333v85.333h-85.333v-85.333zM128 234.667h85.333v85.333h-85.333v-85.333zM298.667 746.667h85.333v85.333h-85.333v-85.333zM810.667 234.667h85.333v85.333h-85.333v-85.333zM469.333 64h85.333v768h-85.333v-768zM810.667 64h85.333v85.333h-85.333v-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 832v-85.333h85.333v85.333h-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM640 746.667h85.333v85.333h-85.333v-85.333zM640 64h85.333v85.333h-85.333v-85.333zM640 405.333h85.333v85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M298.667 320v-85.333h426.667v85.333h-426.667zM128 64h768v85.333h-768v-85.333zM128 405.333h768v85.333h-768v-85.333zM298.667 661.333v-85.333h426.667v85.333h-426.667zM128 832v-85.333h768v85.333h-768z" /> -<glyph unicode="" d="M128 64h768v85.333h-768v-85.333zM128 234.667h768v85.333h-768v-85.333zM128 405.333h768v85.333h-768v-85.333zM128 576h768v85.333h-768v-85.333zM128 832v-85.333h768v85.333h-768z" /> -<glyph unicode="" d="M640 320h-512v-85.333h512v85.333zM640 661.333h-512v-85.333h512v85.333zM128 405.333h768v85.333h-768v-85.333zM128 64h768v85.333h-768v-85.333zM128 832v-85.333h768v85.333h-768z" /> -<glyph unicode="" d="M128 64h768v85.333h-768v-85.333zM384 234.667h512v85.333h-512v-85.333zM128 405.333h768v85.333h-768v-85.333zM384 576h512v85.333h-512v-85.333zM128 832v-85.333h768v85.333h-768z" /> -<glyph unicode="" d="M665.6 499.627c41.173 28.8 70.4 75.307 70.4 119.040 0 96.213-74.453 170.667-170.667 170.667h-266.667v-597.333h300.373c89.387 0 158.293 72.533 158.293 161.707 0 64.853-36.907 120.107-91.733 145.92zM426.667 682.667h128c35.413 0 64-28.587 64-64s-28.587-64-64-64h-128v128zM576 298.667h-149.333v128h149.333c35.413 0 64-28.587 64-64s-28.587-64-64-64z" /> -<glyph unicode="" d="M139.52 746.667l-54.187-54.4 297.387-297.387-105.387-245.547h128l66.987 156.16 241.493-241.493 54.187 54.4-628.48 628.267zM256 746.667v-7.68l120.32-120.32h102.187l-30.72-71.467 89.6-89.6 69.12 161.067h246.827v128h-597.333z" /> -<glyph unicode="" d="M706.56 578.56l-381.44 381.44-60.373-60.373 101.547-101.547-219.52-219.52c-24.96-24.96-24.96-65.493 0-90.453l234.667-234.667c12.373-12.587 28.8-18.773 45.227-18.773s32.853 6.187 45.227 18.773l234.667 234.667c24.96 24.96 24.96 65.493 0 90.453zM222.080 533.333l204.587 204.373 204.587-204.373h-409.173zM810.667 469.333s-85.333-92.373-85.333-149.333c0-47.147 38.187-85.333 85.333-85.333s85.333 38.187 85.333 85.333c0 56.96-85.333 149.333-85.333 149.333zM0 106.667h1024v-170.667h-1024z" /> -<glyph unicode="" d="M768 362.667c0 170.667-256 460.8-256 460.8s-56.747-64.427-116.693-150.187l366.293-366.293c4.053 17.92 6.4 36.48 6.4 55.68zM730.453 229.547l-505.6 505.6-54.187-54.4 141.653-141.653c-32.64-62.293-56.32-124.8-56.32-176.427 0-141.44 114.56-256 256-256 64.853 0 123.733 24.32 168.747 64l112.427-112.427 54.187 54.4-116.907 116.907z" /> -<glyph unicode="" d="M0 106.667h1024v-170.667h-1024zM469.333 832l-234.667-597.333h96l48 128h266.667l48-128h96l-234.667 597.333h-85.333zM410.667 448l101.333 270.293 101.333-270.293h-202.667z" /> -<glyph unicode="" d="M469.333 234.667h426.667v85.333h-426.667v-85.333zM128 448l170.667-170.667v341.333l-170.667-170.667zM128 64h768v85.333h-768v-85.333zM128 832v-85.333h768v85.333h-768zM469.333 576h426.667v85.333h-426.667v-85.333zM469.333 405.333h426.667v85.333h-426.667v-85.333z" /> -<glyph unicode="" d="M128 64h768v85.333h-768v-85.333zM128 618.667v-341.333l170.667 170.667-170.667 170.667zM469.333 234.667h426.667v85.333h-426.667v-85.333zM128 832v-85.333h768v85.333h-768zM469.333 576h426.667v85.333h-426.667v-85.333zM469.333 405.333h426.667v85.333h-426.667v-85.333z" /> -<glyph unicode="" d="M426.667 789.333v-128h94.507l-146.347-341.333h-118.827v-128h341.333v128h-94.507l146.347 341.333h118.827v128z" /> -<glyph unicode="" d="M256 661.333h106.667l-149.333 149.333-149.333-149.333h106.667v-426.667h-106.667l149.333-149.333 149.333 149.333h-106.667v426.667zM426.667 746.667v-85.333h512v85.333h-512zM426.667 149.333h512v85.333h-512v-85.333zM426.667 405.333h512v85.333h-512v-85.333z" /> -<glyph unicode="" d="M170.667 512c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM170.667 768c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM170.667 248.96c-31.36 0-56.96-25.387-56.96-56.96s25.6-56.96 56.96-56.96 56.96 25.387 56.96 56.96-25.6 56.96-56.96 56.96zM298.667 149.333h597.333v85.333h-597.333v-85.333zM298.667 405.333h597.333v85.333h-597.333v-85.333zM298.667 746.667v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M85.333 234.667h85.333v-21.333h-42.667v-42.667h42.667v-21.333h-85.333v-42.667h128v170.667h-128v-42.667zM128 618.667h42.667v170.667h-85.333v-42.667h42.667v-128zM85.333 490.667h76.8l-76.8-89.6v-38.4h128v42.667h-76.8l76.8 89.6v38.4h-128v-42.667zM298.667 746.667v-85.333h597.333v85.333h-597.333zM298.667 149.333h597.333v85.333h-597.333v-85.333zM298.667 405.333h597.333v85.333h-597.333v-85.333z" /> -<glyph unicode="" d="M768 789.333v42.667c0 23.467-19.2 42.667-42.667 42.667h-512c-23.467 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 19.2-42.667 42.667-42.667h512c23.467 0 42.667 19.2 42.667 42.667v42.667h42.667v-170.667h-426.667v-469.333c0-23.467 19.2-42.667 42.667-42.667h85.333c23.467 0 42.667 19.2 42.667 42.667v384h341.333v341.333h-128z" /> -<glyph unicode="" d="M256 234.667h128l85.333 170.667v256h-256v-256h128zM597.333 234.667h128l85.333 170.667v256h-256v-256h128z" /> -<glyph unicode="" d="M384 789.333v-128h213.333v-512h128v512h213.333v128h-554.667zM128 448h128v-298.667h128v298.667h128v128h-384v-128z" /> -<glyph unicode="" d="M426.667 149.333h170.667v128h-170.667v-128zM213.333 789.333v-128h213.333v-128h170.667v128h213.333v128h-597.333zM128 362.667h768v85.333h-768v-85.333z" /> -<glyph unicode="" d="M768 789.333h-512v-85.333l277.333-256-277.333-256v-85.333h512v128h-298.667l213.333 213.333-213.333 213.333h298.667z" /> -<glyph unicode="" d="M384 533.333v-213.333h85.333v469.333h85.333v-469.333h85.333v469.333h85.333v85.333h-341.333c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667zM896 192l-170.667 170.667v-128h-512v-85.333h512v-128l170.667 170.667z" /> -<glyph unicode="" d="M512 234.667c141.44 0 256 114.56 256 256v341.333h-106.667v-341.333c0-82.56-66.773-149.333-149.333-149.333s-149.333 66.773-149.333 149.333v341.333h-106.667v-341.333c0-141.44 114.56-256 256-256zM213.333 149.333v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M426.667 533.333v-213.333h85.333v469.333h85.333v-469.333h85.333v469.333h85.333v85.333h-341.333c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667zM341.333 234.667v128l-170.667-170.667 170.667-170.667v128h512v85.333h-512z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM384 234.667h-85.333v298.667h85.333v-298.667zM554.667 234.667h-85.333v426.667h85.333v-426.667zM725.333 234.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h597.333l170.667-170.667v768c0 47.147-38.187 85.333-85.333 85.333zM768 362.667h-512v85.333h512v-85.333zM768 490.667h-512v85.333h512v-85.333zM768 618.667h-512v85.333h512v-85.333z" /> -<glyph unicode="" d="M256 874.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-682.667c0-47.147 37.76-85.333 84.907-85.333h512.427c47.147 0 85.333 38.187 85.333 85.333v512l-256 256h-341.333zM554.667 576v234.667l234.667-234.667h-234.667z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM661.333 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM362.667 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM512 213.333c99.413 0 183.68 62.080 217.813 149.333h-435.627c34.133-87.253 118.4-149.333 217.813-149.333z" /> -<glyph unicode="" d="M725.333 448h-213.333v-213.333h213.333v213.333zM682.667 917.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333h-42.667v85.333h-85.333zM810.667 149.333h-597.333v469.333h597.333v-469.333z" /> -<glyph unicode="" d="M166.4 448c0 72.96 59.307 132.267 132.267 132.267h170.667v81.067h-170.667c-117.76 0-213.333-95.573-213.333-213.333s95.573-213.333 213.333-213.333h170.667v81.067h-170.667c-72.96 0-132.267 59.307-132.267 132.267zM341.333 405.333h341.333v85.333h-341.333v-85.333zM725.333 661.333h-170.667v-81.067h170.667c72.96 0 132.267-59.307 132.267-132.267s-59.307-132.267-132.267-132.267h-170.667v-81.067h170.667c117.76 0 213.333 95.573 213.333 213.333s-95.573 213.333-213.333 213.333z" /> -<glyph unicode="" d="M896 149.333v597.333c0 47.147-38.187 85.333-85.333 85.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333zM362.667 384l106.667-128.213 149.333 192.213 192-256h-597.333l149.333 192z" /> -<glyph unicode="" d="M725.333 88.96l60.373 60.373-145.707 145.707-60.373-60.373 145.707-145.707zM320 618.667h149.333v-238.293l-231.040-231.040 60.373-60.373 256 256v273.707h149.333l-192 192-192-192z" /> -<glyph unicode="" d="M938.24 789.333c0 47.147-37.76 85.333-84.907 85.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h597.333l170.667-170.667-0.427 768z" /> -<glyph unicode="" d="M128 224v-160h160l472.107 472.107-160 160-472.107-472.107zM883.413 659.413c16.64 16.64 16.64 43.733 0 60.373l-99.627 99.627c-16.64 16.64-43.733 16.64-60.373 0l-78.080-78.080 160-160 78.080 78.080z" /> -<glyph unicode="" d="M213.333 789.333v-85.333h597.333v85.333h-597.333zM213.333 362.667h170.667v-256h256v256h170.667l-298.667 298.667-298.667-298.667z" /> -<glyph unicode="" d="M682.667 405.333h-128v426.667h-85.333v-426.667h-128l170.667-170.667 170.667 170.667zM170.667 149.333v-85.333h682.667v85.333h-682.667z" /> -<glyph unicode="" d="M341.333 149.333h128v-170.667h85.333v170.667h128l-170.667 170.667-170.667-170.667zM682.667 746.667h-128v170.667h-85.333v-170.667h-128l170.667-170.667 170.667 170.667zM170.667 490.667v-85.333h682.667v85.333h-682.667z" /> -<glyph unicode="" d="M341.333 490.667h128v-426.667h85.333v426.667h128l-170.667 170.667-170.667-170.667zM170.667 832v-85.333h682.667v85.333h-682.667z" /> -<glyph unicode="" d="M170.667 149.333h256v85.333h-256v-85.333zM853.333 746.667h-682.667v-85.333h682.667v85.333zM725.333 490.667h-554.667v-85.333h565.333c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333h-96v85.333l-128-128 128-128v85.333h85.333c94.080 0 170.667 76.587 170.667 170.667s-76.587 170.667-170.667 170.667z" /> -<glyph unicode="" d="M320 192c-129.707 0-234.667 105.173-234.667 234.667s104.96 234.667 234.667 234.667h448c94.293 0 170.667-76.373 170.667-170.667s-76.373-170.667-170.667-170.667h-362.667c-58.88 0-106.667 47.787-106.667 106.667s47.787 106.667 106.667 106.667h320v-64h-320c-23.467 0-42.667-18.987-42.667-42.667s19.2-42.667 42.667-42.667h362.667c58.88 0 106.667 47.787 106.667 106.667s-47.787 106.667-106.667 106.667h-448c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667h405.333v-64h-405.333z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM704 277.333h-362.667c-70.613 0-128 57.387-128 128s57.387 128 128 128l5.76-0.64c18.987 73.813 85.333 128.64 164.907 128.64 94.293 0 170.667-76.373 170.667-170.667h21.333c58.88 0 106.667-47.787 106.667-106.667s-47.787-106.667-106.667-106.667z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84zM426.667 234.667l-149.333 149.333 60.373 60.373 88.96-88.96 220.8 220.8 60.373-60.373-281.173-281.173z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84zM725.333 405.333l-213.333-213.333-213.333 213.333h128v170.667h170.667v-170.667h128z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-62.933 0-121.6-18.56-171.093-49.92l62.293-62.293c32.64 16.853 69.547 26.88 108.8 26.88 129.707 0 234.667-104.96 234.667-234.667v-21.333h64c70.613 0 128-57.387 128-128 0-48.427-27.093-90.027-66.773-111.787l61.867-61.867c54.4 38.613 90.24 101.76 90.24 173.653 0 112.64-87.68 203.947-198.187 211.84zM128 734.933l117.333-116.907c-136.107-5.76-245.333-117.76-245.333-255.36 0-141.44 114.56-256 256-256h500.267l85.333-85.333 54.4 54.187-713.6 713.813-54.4-54.4zM329.6 533.333l341.333-341.333h-414.933c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667h73.6z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84zM810.667 192h-554.667c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667h30.293c27.947 98.347 118.187 170.667 225.707 170.667 129.707 0 234.667-104.96 234.667-234.667v-21.333h64c70.613 0 128-57.387 128-128s-57.387-128-128-128z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84zM597.333 405.333v-170.667h-170.667v170.667h-128l213.333 213.333 213.333-213.333h-128z" /> -<glyph unicode="" d="M810.667 576h-170.667v256h-256v-256h-170.667l298.667-298.667 298.667 298.667zM213.333 192v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M384 277.333h256v256h170.667l-298.667 298.667-298.667-298.667h170.667zM213.333 192h597.333v-85.333h-597.333z" /> -<glyph unicode="" d="M426.667 789.333h-256c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333h-341.333l-85.333 85.333z" /> -<glyph unicode="" d="M853.333 704h-341.333l-85.333 85.333h-256c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM853.333 192h-682.667v426.667h682.667v-426.667z" /> -<glyph unicode="" d="M853.333 704h-341.333l-85.333 85.333h-256c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM640 576c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333 38.187 85.333 85.333 85.333zM810.667 234.667h-341.333v42.667c0 56.96 113.707 85.333 170.667 85.333s170.667-28.373 170.667-85.333v-42.667z" /> -<glyph unicode="" d="M896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-128h85.333v128h768v-597.333h-298.667v-85.333h298.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM42.667 192v-128h128c0 70.613-57.387 128-128 128zM42.667 362.667v-85.333c117.76 0 213.333-95.573 213.333-213.333h85.333c0 164.907-133.76 298.667-298.667 298.667zM42.667 533.333v-85.333c212.053 0 384-171.947 384-384h85.333c0 259.2-210.133 469.333-469.333 469.333z" /> -<glyph unicode="" d="M42.667 192v-128h128c0 70.613-57.387 128-128 128zM42.667 362.667v-85.333c117.76 0 213.333-95.573 213.333-213.333h85.333c0 164.907-133.76 298.667-298.667 298.667zM810.667 661.333h-597.333v-69.76c168.96-54.613 302.293-187.947 356.907-356.907h240.427v426.667zM42.667 533.333v-85.333c212.053 0 384-171.947 384-384h85.333c0 259.2-210.133 469.333-469.333 469.333zM896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-128h85.333v128h768v-597.333h-298.667v-85.333h298.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M853.333 192c47.147 0 84.907 38.187 84.907 85.333l0.427 426.667c0 47.147-38.187 85.333-85.333 85.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h-170.667v-85.333h1024v85.333h-170.667zM170.667 704h682.667v-426.667h-682.667v426.667z" /> -<glyph unicode="" d="M896 874.667h-768c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h298.667l-85.333-128v-42.667h341.333v42.667l-85.333 128h298.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM896 362.667h-768v426.667h768v-426.667z" /> -<glyph unicode="" d="M896 874.667h-768c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h298.667v-85.333h-85.333v-85.333h341.333v85.333h-85.333v85.333h298.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM896 277.333h-768v512h768v-512z" /> -<glyph unicode="" d="M341.333-21.333h341.333v85.333h-341.333v-85.333zM682.667 916.907l-341.333 0.427c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h341.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 84.907-85.333 84.907zM682.667 320h-341.333v426.667h341.333v-426.667z" /> -<glyph unicode="" d="M640 640v234.667h-256v-234.667l128-128 128 128zM320 576h-234.667v-256h234.667l128 128-128 128zM384 256v-234.667h256v234.667l-128 128-128-128zM704 576l-128-128 128-128h234.667v256h-234.667z" /> -<glyph unicode="" d="M512 917.333c-212.053 0-384-171.947-384-384v-298.667c0-70.613 57.387-128 128-128h128v341.333h-170.667v85.333c0 164.907 133.76 298.667 298.667 298.667s298.667-133.76 298.667-298.667v-85.333h-170.667v-341.333h128c70.613 0 128 57.387 128 128v298.667c0 212.053-171.947 384-384 384z" /> -<glyph unicode="" d="M512 917.333c-212.053 0-384-171.947-384-384v-298.667c0-70.613 57.387-128 128-128h128v341.333h-170.667v85.333c0 164.907 133.76 298.667 298.667 298.667s298.667-133.76 298.667-298.667v-85.333h-170.667v-341.333h170.667v-42.667h-298.667v-85.333h256c70.613 0 128 57.387 128 128v426.667c0 212.053-171.947 384-384 384z" /> -<glyph unicode="" d="M853.333 746.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-426.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM469.333 618.667h85.333v-85.333h-85.333v85.333zM469.333 490.667h85.333v-85.333h-85.333v85.333zM341.333 618.667h85.333v-85.333h-85.333v85.333zM341.333 490.667h85.333v-85.333h-85.333v85.333zM298.667 405.333h-85.333v85.333h85.333v-85.333zM298.667 533.333h-85.333v85.333h85.333v-85.333zM682.667 234.667h-341.333v85.333h341.333v-85.333zM682.667 405.333h-85.333v85.333h85.333v-85.333zM682.667 533.333h-85.333v85.333h85.333v-85.333zM810.667 405.333h-85.333v85.333h85.333v-85.333zM810.667 533.333h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M661.333 512c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM362.667 512c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM512 213.333c111.36 0 205.867 71.253 241.067 170.667h-482.133c35.2-99.413 129.707-170.667 241.067-170.667zM511.787 896c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 128c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333z" /> -<glyph unicode="" d="M316.373 609.707l195.627-195.627 195.627 195.627 60.373-60.373-256-256-256 256z" /> -<glyph unicode="" d="M657.707 263.040l-195.627 195.627 195.627 195.627-60.373 60.373-256-256 256-256z" /> -<glyph unicode="" d="M366.293 257.707l195.627 195.627-195.627 195.627 60.373 60.373 256-256-256-256z" /> -<glyph unicode="" d="M316.373 302.293l195.627 195.627 195.627-195.627 60.373 60.373-256 256-256-256z" /> -<glyph unicode="" d="M896 490.667h-604.587l152.96 152.96-60.373 60.373-256-256 256-256 60.373 60.373-152.96 152.96h604.587z" /> -<glyph unicode="" d="M512 600.96l195.627-195.627 60.373 60.373-256 256-256-256 60.373-60.373 195.627 195.627zM256 192h512v85.333h-512v-85.333z" /> -<glyph unicode="" d="M256 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM512 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M853.333 832h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-426.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM469.333 704h85.333v-85.333h-85.333v85.333zM469.333 576h85.333v-85.333h-85.333v85.333zM341.333 704h85.333v-85.333h-85.333v85.333zM341.333 576h85.333v-85.333h-85.333v85.333zM298.667 490.667h-85.333v85.333h85.333v-85.333zM298.667 618.667h-85.333v85.333h85.333v-85.333zM682.667 320h-341.333v85.333h341.333v-85.333zM682.667 490.667h-85.333v85.333h85.333v-85.333zM682.667 618.667h-85.333v85.333h85.333v-85.333zM810.667 490.667h-85.333v85.333h85.333v-85.333zM810.667 618.667h-85.333v85.333h85.333v-85.333zM512-21.333l170.667 170.667h-341.333l170.667-170.667z" /> -<glyph unicode="" d="M810.667 661.333v-170.667h-561.92l152.96 152.96-60.373 60.373-256-256 256-256 60.373 60.373-152.96 152.96h647.253v256z" /> -<glyph unicode="" d="M494.293 643.627l152.96-152.96h-604.587v-85.333h604.587l-152.96-152.96 60.373-60.373 256 256-256 256-60.373-60.373zM853.333 704v-512h85.333v512h-85.333z" /> -<glyph unicode="" d="M512 320c70.613 0 127.573 57.387 127.573 128l0.427 256c0 70.827-57.173 128-128 128-70.613 0-128-57.173-128-128v-256c0-70.613 57.387-128 128-128zM738.133 448c0-128-108.16-217.6-226.133-217.6-117.76 0-226.133 89.6-226.133 217.6h-72.533c0-145.707 116.053-266.027 256-286.72v-139.947h85.333v139.947c139.947 20.693 256 141.013 256 286.72h-72.533z" /> -<glyph unicode="" d="M853.333 192c46.933 0 85.333 38.4 85.333 85.333v426.667c0 46.933-38.4 85.333-85.333 85.333h-682.667c-46.933 0-85.333-38.4-85.333-85.333v-426.667c0-46.933 38.4-85.333 85.333-85.333h-170.667v-85.333h1024v85.333h-170.667zM170.667 704h682.667v-426.667h-682.667v426.667z" /> -<glyph unicode="" d="M938.667 192v640h-853.333v-640h-85.333v-85.333h1024v85.333h-85.333zM597.333 192h-170.667v42.667h170.667v-42.667zM853.333 320h-682.667v426.667h682.667v-426.667z" /> -<glyph unicode="" d="M853.333 192c47.147 0 84.907 38.187 84.907 85.333l0.427 469.333c0 47.147-38.187 85.333-85.333 85.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-469.333c0-47.147 38.187-85.333 85.333-85.333h-170.667c0-47.147 38.187-85.333 85.333-85.333h853.333c47.147 0 85.333 38.187 85.333 85.333h-170.667zM170.667 746.667h682.667v-469.333h-682.667v469.333zM512 149.333c-23.467 0-42.667 19.2-42.667 42.667s19.2 42.667 42.667 42.667 42.667-19.2 42.667-42.667-19.2-42.667-42.667-42.667z" /> -<glyph unicode="" d="M853.333 192v42.667c47.147 0 84.907 38.187 84.907 85.333l0.427 426.667c0 47.147-38.187 85.333-85.333 85.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333v-42.667h-170.667v-85.333h1024v85.333h-170.667zM170.667 746.667h682.667v-426.667h-682.667v426.667z" /> -<glyph unicode="" d="M640 576h-256v-256h256v256zM554.667 405.333h-85.333v85.333h85.333v-85.333zM896 490.667v85.333h-85.333v85.333c0 47.147-38.187 85.333-85.333 85.333h-85.333v85.333h-85.333v-85.333h-85.333v85.333h-85.333v-85.333h-85.333c-47.147 0-85.333-38.187-85.333-85.333v-85.333h-85.333v-85.333h85.333v-85.333h-85.333v-85.333h85.333v-85.333c0-47.147 38.187-85.333 85.333-85.333h85.333v-85.333h85.333v85.333h85.333v-85.333h85.333v85.333h85.333c47.147 0 85.333 38.187 85.333 85.333v85.333h85.333v85.333h-85.333v85.333h85.333zM725.333 234.667h-426.667v426.667h426.667v-426.667z" /> -<glyph unicode="" d="M554.667 914.347v-338.347h298.667c0 174.080-130.347 317.44-298.667 338.347zM170.667 320c0-188.587 152.747-341.333 341.333-341.333s341.333 152.747 341.333 341.333v170.667h-682.667v-170.667zM469.333 914.347c-168.32-20.907-298.667-164.267-298.667-338.347h298.667v338.347z" /> -<glyph unicode="" d="M682.667 917.333h-341.333c-70.613 0-128-57.387-128-128v-682.667c0-70.613 57.387-128 128-128h341.333c70.613 0 128 57.387 128 128v682.667c0 70.613-57.387 128-128 128zM597.333 64h-170.667v42.667h170.667v-42.667zM736 192h-448v597.333h448v-597.333z" /> -<glyph unicode="" d="M661.333 917.333h-341.333c-58.88 0-106.667-47.787-106.667-106.667v-725.333c0-58.88 47.787-106.667 106.667-106.667h341.333c58.88 0 106.667 47.787 106.667 106.667v725.333c0 58.88-47.787 106.667-106.667 106.667zM490.667 21.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM682.667 192h-384v597.333h384v-597.333z" /> -<glyph unicode="" d="M170.667 704h768v85.333h-768c-47.147 0-85.333-38.187-85.333-85.333v-469.333h-85.333v-128h597.333v128h-426.667v469.333zM981.333 618.667h-256c-23.467 0-42.667-19.2-42.667-42.667v-426.667c0-23.467 19.2-42.667 42.667-42.667h256c23.467 0 42.667 19.2 42.667 42.667v426.667c0 23.467-19.2 42.667-42.667 42.667zM938.667 234.667h-170.667v298.667h170.667v-298.667z" /> -<glyph unicode="" d="M938.667 704v85.333h-647.68l85.333-85.333h562.347zM81.92 889.813l-54.4-54.4 77.44-77.44c-11.947-14.72-19.627-33.493-19.627-53.973v-469.333h-85.333v-128h756.48l100.48-100.48 54.187 54.4-829.227 829.227zM170.667 692.267l457.813-457.6h-457.813v457.6zM981.333 618.667h-256c-23.467 0-42.667-19.2-42.667-42.667v-178.347l85.333-85.333v221.013h170.667v-298.667h-93.013l128-128h7.68c23.467 0 42.667 19.2 42.667 42.667v426.667c0 23.467-19.2 42.667-42.667 42.667z" /> -<glyph unicode="" d="M512 917.333l-384-170.667v-256c0-237.013 163.627-458.027 384-512 220.373 53.973 384 274.987 384 512v256l-384 170.667zM512 448.427h298.667c-22.613-175.787-139.733-332.373-298.667-381.227v380.8h-298.667v243.2l298.667 132.693v-375.467z" /> -<glyph unicode="" d="M852.907 789.333c0 47.147-37.76 85.333-84.907 85.333h-341.333l-256-256v-512c0-47.147 38.187-85.333 85.333-85.333h512.427c47.147 0 84.907 38.187 84.907 85.333l-0.427 682.667zM384 149.333h-85.333v85.333h85.333v-85.333zM725.333 149.333h-85.333v85.333h85.333v-85.333zM384 320h-85.333v170.667h85.333v-170.667zM554.667 149.333h-85.333v170.667h85.333v-170.667zM554.667 405.333h-85.333v85.333h85.333v-85.333zM725.333 320h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M725.333 916.907l-426.667 0.427c-47.147 0-85.333-38.187-85.333-85.333v-768c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v768c0 47.147-38.187 84.907-85.333 84.907zM725.333 149.333h-426.667v597.333h426.667v-597.333z" /> -<glyph unicode="" d="M725.333 874.667h-426.667c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-84.907 85.333-84.907l426.667-0.427c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM512 789.333c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333 38.187 85.333 85.333 85.333zM512 106.667c-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333-95.573-213.333-213.333-213.333zM512 448c-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128-57.387 128-128 128z" /> -<glyph unicode="" d="M896 789.333h-768c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 84.907 38.187 84.907 85.333l0.427 512c0 47.147-38.187 85.333-85.333 85.333zM810.667 192h-597.333v512h597.333v-512z" /> -<glyph unicode="" d="M768 960h-512c-70.613 0-128-57.387-128-128v-768c0-70.613 57.387-128 128-128h512c70.613 0 128 57.387 128 128v768c0 70.613-57.387 128-128 128zM597.333 21.333h-170.667v42.667h170.667v-42.667zM821.333 149.333h-618.667v682.667h618.667v-682.667z" /> -<glyph unicode="" d="M789.333 960h-597.333c-58.88 0-106.667-47.787-106.667-106.667v-810.667c0-58.88 47.787-106.667 106.667-106.667h597.333c58.88 0 106.667 47.787 106.667 106.667v810.667c0 58.88-47.787 106.667-106.667 106.667zM490.667-21.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM810.667 149.333h-640v682.667h640v-682.667z" /> -<glyph unicode="" d="M896 832h-768c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h213.333v-85.333h341.333v85.333h213.333c47.147 0 84.907 38.187 84.907 85.333l0.427 512c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-768v512h768v-512z" /> -<glyph unicode="" d="M853.333 448c0 108.587-50.773 205.227-129.92 267.733l-40.747 244.267h-341.333l-40.747-244.267c-79.147-62.507-129.92-159.147-129.92-267.733s50.773-205.227 129.92-267.733l40.747-244.267h341.333l40.747 244.267c79.147 62.507 129.92 159.147 129.92 267.733zM256 448c0 141.44 114.56 256 256 256s256-114.56 256-256-114.56-256-256-256-256 114.56-256 256z" /> -<glyph unicode="" d="M170.667 704h-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333zM853.333 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM810.667 490.667h-170.667v-170.667h-85.333v170.667h-170.667v85.333h170.667v170.667h85.333v-170.667h170.667v-85.333z" /> -<glyph unicode="" d="M512 874.667c-235.307 0-426.667-191.36-426.667-426.667s191.36-426.667 426.667-426.667 426.667 191.36 426.667 426.667-191.36 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333zM640 448c0-70.613-57.387-128-128-128s-128 57.387-128 128 57.387 128 128 128 128-57.387 128-128z" /> -<glyph unicode="" d="M614.4 704l-17.067 85.333h-384v-725.333h85.333v298.667h238.933l17.067-85.333h298.667v426.667z" /> -<glyph unicode="" d="M512 832v-395.733c-20.053 7.040-41.387 11.733-64 11.733-106.027 0-192-85.973-192-192s85.973-192 192-192c98.773 0 179.2 74.88 189.867 170.667h2.133v469.333h170.667v128h-298.667z" /> -<glyph unicode="" d="M426.667 576c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM426.667 405.333c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM298.667 554.667c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM426.667 256c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM298.667 384c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM426.667 640c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM597.333 576c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM597.333 640c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM725.333 384c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM725.333 554.667c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM597.333 256c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM597.333 405.333c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667z" /> -<glyph unicode="" d="M213.333 213.333c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM384 405.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM384 576c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM128 64h768v85.333h-768v-85.333zM213.333 554.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM213.333 384c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM384 234.667c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM725.333 256c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM128 832v-85.333h768v85.333h-768zM725.333 597.333c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM725.333 426.667c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM554.667 576c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM554.667 405.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM554.667 234.667c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667z" /> -<glyph unicode="" d="M597.333 661.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM588.8 470.187c2.773-0.427 5.547-0.853 8.533-0.853 35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64c0-2.987 0.427-5.76 0.853-8.747 3.84-28.16 26.24-50.56 54.613-54.4zM597.333 810.667c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM426.667 810.667c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM896 512c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM426.667 661.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM768 320c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM768 490.667c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM768 661.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM597.333 85.333c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM106.667 734.933l161.493-161.493c-4.053 1.28-7.893 2.56-12.16 2.56-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667c0 4.267-1.28 8.107-2.347 12.16l119.893-119.893c-30.507-5.12-53.547-31.147-53.547-62.933 0-35.413 28.587-64 64-64 31.787 0 57.813 23.040 62.933 53.333l119.893-119.893c-3.84 1.28-7.893 2.56-12.16 2.56-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667c0 4.267-1.28 8.107-2.347 12.16l161.28-161.493 54.4 54.4-692.267 692.267-54.4-54.4zM426.667 234.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM896 384c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM256 405.333c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM128 554.667c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM426.667 85.333c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM256 234.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM128 384c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333z" /> -<glyph unicode="" d="M256 405.333c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM256 234.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM256 576c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM128 554.667c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM256 746.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM896 512c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM597.333 661.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM597.333 810.667c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM128 384c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM426.667 85.333c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM426.667 810.667c11.733 0 21.333 9.6 21.333 21.333s-9.6 21.333-21.333 21.333-21.333-9.6-21.333-21.333 9.6-21.333 21.333-21.333zM426.667 661.333c23.467 0 42.667 19.2 42.667 42.667s-19.2 42.667-42.667 42.667-42.667-19.2-42.667-42.667 19.2-42.667 42.667-42.667zM426.667 426.667c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM768 405.333c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM768 234.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM768 576c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM768 746.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM896 384c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM597.333 234.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM597.333 85.333c-11.733 0-21.333-9.6-21.333-21.333s9.6-21.333 21.333-21.333 21.333 9.6 21.333 21.333-9.6 21.333-21.333 21.333zM426.667 597.333c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM426.667 234.667c-23.467 0-42.667-19.2-42.667-42.667s19.2-42.667 42.667-42.667 42.667 19.2 42.667 42.667-19.2 42.667-42.667 42.667zM597.333 426.667c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64zM597.333 597.333c-35.413 0-64-28.587-64-64s28.587-64 64-64 64 28.587 64 64-28.587 64-64 64z" /> -<glyph unicode="" d="M938.667 448c0-235.641-191.025-426.667-426.667-426.667s-426.667 191.025-426.667 426.667c0 235.641 191.025 426.667 426.667 426.667s426.667-191.025 426.667-426.667z" /> -<glyph unicode="" d="M426.667 874.667c-77.867 0-150.613-21.12-213.333-57.6 127.36-73.813 213.333-211.2 213.333-369.067s-85.973-295.253-213.333-369.067c62.72-36.48 135.467-57.6 213.333-57.6 235.733 0 426.667 190.933 426.667 426.667s-190.933 426.667-426.667 426.667z" /> -<glyph unicode="" d="M384 874.667c-44.587 0-87.68-6.827-128-19.627 173.013-54.4 298.667-216.107 298.667-407.040s-125.653-352.64-298.667-407.040c40.32-12.587 83.413-19.627 128-19.627 235.733 0 426.667 190.933 426.667 426.667s-190.933 426.667-426.667 426.667z" /> -<glyph unicode="" d="M853.333 589.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893l141.44 141.44-141.44 141.44zM512 192c-38.187 0-74.24 8.533-106.667 23.467 88.107 40.533 149.333 129.28 149.333 232.533s-61.227 192-149.333 232.533c32.427 14.933 68.48 23.467 106.667 23.467 141.44 0 256-114.56 256-256s-114.56-256-256-256z" /> -<glyph unicode="" d="M853.333 306.56l141.44 141.44-141.44 141.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893zM512 192c-141.44 0-256 114.56-256 256s114.56 256 256 256 256-114.56 256-256-114.56-256-256-256z" /> -<glyph unicode="" d="M853.333 306.56l141.44 141.44-141.44 141.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893zM512 192v512c141.44 0 256-114.56 256-256s-114.56-256-256-256z" /> -<glyph unicode="" d="M853.333 589.44v199.893h-199.893l-141.44 141.44-141.44-141.44h-199.893v-199.893l-141.44-141.44 141.44-141.44v-199.893h199.893l141.44-141.44 141.44 141.44h199.893v199.893l141.44 141.44-141.44 141.44zM512 192c-141.44 0-256 114.56-256 256s114.56 256 256 256 256-114.56 256-256-114.56-256-256-256zM512 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667z" /> -<glyph unicode="" d="M298.667 362.667c-70.613 0-128-57.387-128-128 0-55.893-49.28-85.333-85.333-85.333 39.253-52.053 106.453-85.333 170.667-85.333 94.293 0 170.667 76.373 170.667 170.667 0 70.613-57.387 128-128 128zM883.413 762.453l-56.96 56.96c-16.64 16.64-43.733 16.64-60.373 0l-382.080-382.080 117.333-117.333 382.080 382.080c16.853 16.853 16.853 43.733 0 60.373z" /> -<glyph unicode="" d="M401.067 512l203.307 352.213c-29.653 6.613-60.587 10.453-92.373 10.453-102.4 0-196.053-36.053-269.653-96.213l156.373-270.72 2.347 4.267zM919.040 576c-39.253 124.8-134.4 224.427-255.787 270.507l-156.16-270.507h411.947zM930.133 533.333h-319.573l12.373-21.333 203.307-352c69.547 75.947 112.427 176.853 112.427 288 0 29.227-2.987 57.813-8.533 85.333zM364.16 448l-166.4 288c-69.547-75.947-112.427-176.853-112.427-288 0-29.227 2.987-57.813 8.533-85.333h319.573l-49.28 85.333zM104.96 320c39.253-124.8 134.4-224.427 255.787-270.507l156.16 270.507h-411.947zM585.813 320l-166.4-288.213c29.867-6.613 60.8-10.453 92.587-10.453 102.4 0 196.053 36.053 269.653 96.213l-156.373 270.72-39.467-68.267z" /> -<glyph unicode="" d="M648.533 448c0-75.405-61.128-136.533-136.533-136.533s-136.533 61.128-136.533 136.533c0 75.405 61.128 136.533 136.533 136.533s136.533-61.128 136.533-136.533zM384 874.667l-78.080-85.333h-135.253c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333h-135.253l-78.080 85.333h-256zM512 234.667c-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333-95.573-213.333-213.333-213.333z" /> -<glyph unicode="" d="M426.667 106.667h-213.333v-85.333h213.333v-85.333l128 128-128 128v-85.333zM597.333 106.667v-85.333h213.333v85.333h-213.333zM512 618.667c47.147 0 85.333 38.187 85.333 85.333s-38.187 85.333-85.333 85.333-85.12-38.187-85.12-85.333c0.213-47.147 37.973-85.333 85.12-85.333zM725.333 960h-426.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM298.667 874.667h426.667v-448c0 71.040-142.293 106.667-213.333 106.667s-213.333-35.627-213.333-106.667v448z" /> -<glyph unicode="" d="M426.667 106.667h-213.333v-85.333h213.333v-85.333l128 128-128 128v-85.333zM597.333 106.667v-85.333h213.333v85.333h-213.333zM725.333 960h-426.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM511.787 704c-47.147 0-85.12 38.187-85.12 85.333s37.973 85.333 85.12 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M597.333 746.667c0 47.147-38.187 85.333-85.333 85.333h-42.667v42.667c0 23.467-19.2 42.667-42.667 42.667h-170.667c-23.467 0-42.667-19.2-42.667-42.667v-42.667h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-640c0-47.147 38.187-85.333 85.333-85.333h341.333c47.147 0 85.333 38.187 85.333 85.333h341.333v640h-341.333zM512 192h-85.333v85.333h85.333v-85.333zM512 576h-85.333v85.333h85.333v-85.333zM682.667 192h-85.333v85.333h85.333v-85.333zM682.667 576h-85.333v85.333h85.333v-85.333zM853.333 192h-85.333v85.333h85.333v-85.333zM853.333 576h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M512 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667zM213.333 320h-85.333v-170.667c0-47.147 38.187-85.333 85.333-85.333h170.667v85.333h-170.667v170.667zM213.333 746.667h170.667v85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-170.667h85.333v170.667zM810.667 832h-170.667v-85.333h170.667v-170.667h85.333v170.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333v170.667h-85.333v-170.667z" /> -<glyph unicode="" d="M213.333 320h-85.333v-170.667c0-47.147 38.187-85.333 85.333-85.333h170.667v85.333h-170.667v170.667zM213.333 746.667h170.667v85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-170.667h85.333v170.667zM810.667 832h-170.667v-85.333h170.667v-170.667h85.333v170.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333v170.667h-85.333v-170.667zM512 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667zM512 362.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M938.667 277.333v512c0 47.147-38.187 85.333-85.333 85.333h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333zM469.333 448l86.613-115.627 126.72 158.293 170.667-213.333h-512l128 170.667zM85.333 704v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333h-85.333z" /> -<glyph unicode="" d="M883.413 719.787l-99.627 99.627c-16.64 16.64-43.733 16.64-60.373 0l-133.333-133.333-81.707 81.92-60.373-60.373 60.587-60.587-380.587-380.373v-202.667h202.667l380.587 380.587 60.373-60.587 60.373 60.373-81.92 81.92 133.333 133.333c16.853 16.64 16.853 43.52 0 60.16zM295.253 149.333l-81.92 81.92 344.107 344.107 81.92-81.92-344.107-344.107z" /> -<glyph unicode="" d="M512 832c-212.053 0-384-171.947-384-384s171.947-384 384-384c35.413 0 64 28.587 64 64 0 16.64-6.187 31.573-16.64 42.88-10.027 11.307-16 26.027-16 42.453 0 35.413 28.587 64 64 64h75.307c117.76 0 213.333 95.573 213.333 213.333 0 188.587-171.947 341.333-384 341.333zM277.333 448c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM405.333 618.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM618.667 618.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 448c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M426.667 832h-213.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h213.333v-85.333h85.333v938.667h-85.333v-85.333zM426.667 192h-213.333l213.333 256v-256zM810.667 832h-213.333v-85.333h213.333v-554.667l-213.333 256v-384h213.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M554.667 661.333h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667v170.667zM512 874.667c-235.307 0-426.667-191.36-426.667-426.667s191.36-426.667 426.667-426.667 426.667 191.36 426.667 426.667-191.36 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M682.667 618.667h-85.333v-128h-128v-85.333h128v-128h85.333v128h128v85.333h-128zM85.333 448c0 119.040 70.187 221.653 171.093 269.653v91.947c-149.12-52.48-256.427-194.56-256.427-361.6s107.307-309.12 256.427-361.6v91.947c-100.907 48-171.093 150.613-171.093 269.653zM640 832c-211.84 0-384-172.16-384-384s172.16-384 384-384 384 172.16 384 384-172.16 384-384 384zM640 149.333c-164.693 0-298.667 133.973-298.667 298.667s133.973 298.667 298.667 298.667 298.667-133.973 298.667-298.667-133.973-298.667-298.667-298.667z" /> -<glyph unicode="" d="M725.333 320h85.333v341.333c0 47.147-38.187 85.333-85.333 85.333h-341.333v-85.333h341.333v-341.333zM298.667 234.667v682.667h-85.333v-170.667h-170.667v-85.333h170.667v-426.667c0-47.147 38.187-85.333 85.333-85.333h426.667v-170.667h85.333v170.667h170.667v85.333h-682.667z" /> -<glyph unicode="" d="M810.667 789.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM810.667 192h-597.333v512h597.333v-512z" /> -<glyph unicode="" d="M810.667 746.667h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 234.667h-597.333v426.667h597.333v-426.667z" /> -<glyph unicode="" d="M810.667 661.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-256c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v256c0 47.147-38.187 85.333-85.333 85.333zM810.667 320h-597.333v256h597.333v-256z" /> -<glyph unicode="" d="M810.667 704h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-341.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v341.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 277.333h-597.333v341.333h597.333v-341.333z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M128 746.667v-170.667h85.333v170.667h170.667v85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333zM213.333 320h-85.333v-170.667c0-47.147 38.187-85.333 85.333-85.333h170.667v85.333h-170.667v170.667zM810.667 149.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333v170.667h-85.333v-170.667zM810.667 832h-170.667v-85.333h170.667v-170.667h85.333v170.667c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M810.667 746.667h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-426.667c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 234.667h-597.333v426.667h597.333v-426.667z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v597.333h597.333v-597.333zM595.84 435.84l-117.333-151.040-83.84 100.693-117.333-150.827h469.333l-150.827 201.173z" /> -<glyph unicode="" d="M725.333 832h-426.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM725.333 149.333h-426.667v597.333h426.667v-597.333z" /> -<glyph unicode="" d="M768 789.333h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM768 192h-512v512h512v-512z" /> -<glyph unicode="" d="M85.333 298.667v-85.333h853.333v85.333h-853.333zM85.333 512v-85.333h853.333v85.333h-853.333zM85.333 725.333v-85.333h853.333v85.333h-853.333z" /> -<glyph unicode="" d="M128 789.333l384-682.667 384 682.667h-768zM272 704h480l-240-426.667-240 426.667z" /> -<glyph unicode="" d="M128 224v-160h160l472.107 472.107-160 160-472.107-472.107zM883.413 659.413c16.64 16.64 16.64 43.733 0 60.373l-99.627 99.627c-16.64 16.64-43.733 16.64-60.373 0l-78.080-78.080 160-160 78.080 78.080z" /> -<glyph unicode="" d="M640 234.667v-85.333h85.333v85.333h85.333v85.333h-85.333v85.333h-85.333v-85.333h-85.333v-85.333h85.333zM853.333 874.667h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM213.333 746.667h256v-85.333h-256v85.333zM853.333 106.667h-682.667l682.667 682.667v-682.667z" /> -<glyph unicode="" d="M170.667 490.667v-85.333h341.333v85.333h-341.333zM810.667 192h-85.333v453.333l-128-43.733v72.533l200.533 72.533h12.8v-554.667z" /> -<glyph unicode="" d="M641.92 264.96l122.24 130.773c16 16.853 30.72 33.493 44.373 50.133 13.44 16.64 25.173 33.28 34.987 49.707 9.813 16.64 17.493 33.067 22.827 49.707 5.547 16.64 8.32 33.493 8.32 50.56 0 22.827-3.84 43.52-11.52 62.293-7.68 18.56-18.773 34.56-33.493 47.573s-32.64 23.040-53.973 30.293c-21.333 7.040-45.653 10.667-72.96 10.667-29.44 0-55.893-4.48-78.933-13.653s-42.453-21.547-58.24-37.333-27.733-34.347-35.84-55.467c-7.68-20.053-11.52-41.6-11.947-64.213h91.307c0.213 13.227 1.92 25.813 5.547 37.12 3.84 12.373 9.6 23.040 17.28 32s17.28 15.787 28.8 20.907c11.733 4.907 25.387 7.467 41.173 7.467 13.013 0 24.533-2.133 34.56-6.613s18.56-10.453 25.387-18.133c6.827-7.68 12.16-17.067 15.787-27.52 3.627-10.667 5.333-22.187 5.333-34.773 0-9.173-1.28-18.56-3.627-27.733s-6.4-19.2-12.373-29.867c-5.973-10.667-13.867-22.4-23.68-35.413-9.813-12.8-22.4-27.52-37.333-44.16l-178.133-194.347v-62.933h368.213v72.96h-254.080zM85.333 490.667v-85.333h341.333v85.333h-341.333z" /> -<glyph unicode="" d="M426.667 661.333h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667v170.667zM853.333 192h-85.333v453.333l-128-43.733v72.533l200.533 72.533h12.8v-554.667z" /> -<glyph unicode="" d="M684.587 264.96l122.24 130.773c16 16.853 30.72 33.493 44.373 50.133 13.44 16.64 25.173 33.28 34.987 49.707 9.813 16.64 17.493 33.067 22.827 49.707 5.547 16.64 8.32 33.493 8.32 50.56 0 22.827-3.84 43.52-11.52 62.293-7.68 18.56-18.773 34.56-33.493 47.573s-32.64 23.040-53.973 30.293c-21.333 7.040-45.653 10.667-72.96 10.667-29.44 0-55.893-4.48-78.933-13.653s-42.453-21.547-58.24-37.333-27.733-34.347-35.84-55.467c-7.68-20.053-11.52-41.6-11.947-64.213h91.307c0.213 13.227 1.92 25.813 5.547 37.12 3.84 12.373 9.6 23.040 17.28 32s17.28 15.787 28.8 20.907c11.733 4.907 25.387 7.467 41.173 7.467 13.013 0 24.533-2.133 34.56-6.613s18.56-10.453 25.387-18.133c6.827-7.68 12.16-17.067 15.787-27.52 3.627-10.667 5.333-22.187 5.333-34.773 0-9.173-1.28-18.56-3.627-27.733s-6.4-19.2-12.373-29.867c-5.973-10.667-13.867-22.4-23.68-35.413-9.813-12.8-22.4-27.52-37.333-44.16l-178.133-194.347v-62.933h368.213v72.96h-254.080zM341.333 661.333h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667v170.667z" /> -<glyph unicode="" d="M688.64 426.667c0-42.667-4.267-78.933-12.587-108.8s-20.267-53.973-35.627-72.747c-15.36-18.56-33.92-32.213-55.467-40.533s-45.653-12.587-72.32-12.587c-26.453 0-50.56 4.267-72.32 12.587s-40.32 21.973-55.893 40.533c-15.573 18.56-27.733 42.88-36.053 72.747-8.533 29.867-12.8 66.133-12.8 108.8v87.040c0 42.667 4.267 78.933 12.587 108.587s20.267 53.76 35.84 72.107c15.36 18.347 33.92 31.787 55.68 39.893s45.867 12.16 72.32 12.16c26.667 0 50.987-4.053 72.747-12.16s40.32-21.547 55.893-39.893c15.36-18.347 27.307-42.453 35.84-72.107 8.32-29.653 12.587-65.92 12.587-108.587v-87.040zM598.613 527.573c0 27.52-1.92 50.56-5.76 69.12s-9.387 33.707-16.853 45.227c-7.467 11.52-16.427 19.84-27.307 24.747-10.667 5.12-23.040 7.68-36.907 7.68s-26.24-2.56-36.907-7.68c-10.88-5.12-19.84-13.44-27.307-24.747-7.467-11.52-13.013-26.667-16.853-45.227s-5.76-41.813-5.76-69.12v-113.92c0-27.093 1.92-50.347 5.973-69.333s9.6-34.56 17.067-46.293c7.467-11.947 16.64-20.48 27.52-26.027 10.88-5.333 23.253-8.107 37.12-8.107 14.080 0 26.453 2.773 37.12 8.107s19.627 14.080 26.88 26.027c7.253 11.947 12.8 27.307 16.427 46.293s5.547 42.24 5.547 69.333v113.92z" /> -<glyph unicode="" d="M681.173 521.173l-117.333-151.040-83.84 100.693-117.333-150.827h469.333l-150.827 201.173zM128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM597.333 320h85.333v426.667h-170.667v-85.333h85.333v-341.333zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM725.333 405.333h-170.667v85.333h85.333c47.147 0 85.333 38.187 85.333 85.333v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667v-85.333h170.667v-85.333h-85.333c-47.147 0-85.333-38.187-85.333-85.333v-170.667h256v85.333z" /> -<glyph unicode="" d="M896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM725.333 405.333v64c0 35.413-28.587 64-64 64 35.413 0 64 28.587 64 64v64c0 47.147-38.187 85.333-85.333 85.333h-170.667v-85.333h170.667v-85.333h-85.333v-85.333h85.333v-85.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM640 320h85.333v426.667h-85.333v-170.667h-85.333v170.667h-85.333v-256h170.667v-170.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM725.333 405.333v85.333c0 47.147-38.187 85.333-85.333 85.333h-85.333v85.333h170.667v85.333h-256v-256h170.667v-85.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM554.667 320h85.333c47.147 0 85.333 38.187 85.333 85.333v85.333c0 47.147-38.187 85.333-85.333 85.333h-85.333v85.333h170.667v85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-256c0-47.147 38.187-85.333 85.333-85.333zM554.667 490.667h85.333v-85.333h-85.333v85.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM554.667 320l170.667 341.333v85.333h-256v-85.333h170.667l-170.667-341.333h85.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM554.667 320h85.333c47.147 0 85.333 38.187 85.333 85.333v64c0 35.413-28.587 64-64 64 35.413 0 64 28.587 64 64v64c0 47.147-38.187 85.333-85.333 85.333h-85.333c-47.147 0-85.333-38.187-85.333-85.333v-64c0-35.413 28.587-64 64-64-35.413 0-64-28.587-64-64v-64c0-47.147 38.187-85.333 85.333-85.333zM554.667 661.333h85.333v-85.333h-85.333v85.333zM554.667 490.667h85.333v-85.333h-85.333v85.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333zM640 746.667h-85.333c-47.147 0-85.333-38.187-85.333-85.333v-85.333c0-47.147 38.187-85.333 85.333-85.333h85.333v-85.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333v256c0 47.147-38.187 85.333-85.333 85.333zM640 576h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM597.333 448v170.667c0 47.147-38.187 85.333-85.333 85.333h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-42.667c0-47.147 38.187-85.333 85.333-85.333h42.667v-42.667h-128v-85.333h128c47.147 0 85.333 38.187 85.333 85.333zM469.333 576v42.667h42.667v-42.667h-42.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 576h-85.333v85.333h-85.333v-85.333h-85.333v-85.333h85.333v-85.333h85.333v85.333h85.333v-256h-597.333v597.333h597.333v-256z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333l-298.667 341.333v-341.333h-298.667l298.667 341.333v256h298.667v-597.333z" /> -<glyph unicode="" d="M213.333 320h-85.333v-170.667c0-47.147 38.187-85.333 85.333-85.333h170.667v85.333h-170.667v170.667zM213.333 746.667h170.667v85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-170.667h85.333v170.667zM810.667 832h-170.667v-85.333h170.667v-170.667h85.333v170.667c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-170.667v-85.333h170.667c47.147 0 85.333 38.187 85.333 85.333v170.667h-85.333v-170.667zM512 576c-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128-57.387 128-128 128z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-229.973-69.973-283.52-172.16-128.427-13.653-228.48-122.453-228.48-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.467 203.947-198.187 211.84zM810.667 192h-554.667c-94.080 0-170.667 76.587-170.667 170.667s76.587 170.667 170.667 170.667 170.667-76.587 170.667-170.667h85.333c0 117.76-79.573 216.533-187.733 246.4 42.88 57.387 110.933 94.933 187.733 94.933 129.493 0 234.667-105.173 234.667-234.667v-21.333h64c70.613 0 128-57.387 128-128s-57.387-128-128-128z" /> -<glyph unicode="" d="M853.333 789.333h-170.667l-170.667 170.667-170.667-170.667h-170.667c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM853.333 106.667h-682.667v597.333h192.64l150.187 149.333 148.48-149.333h191.36v-597.333zM768 618.667h-512v-426.667h512z" /> -<glyph unicode="" d="M597.333 704l-160-213.333 121.6-162.133-68.267-51.2c-72.107 96-192 256-192 256l-256-341.333h938.667l-384 512z" /> -<glyph unicode="" d="M128 746.667h-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667v85.333h-682.667v682.667zM896 917.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM896 234.667h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M469.333 786.347v86.187c-85.76-8.533-163.84-42.667-227.2-94.293l60.8-60.8c47.36 36.48 104.107 61.227 166.4 68.907zM781.867 778.24c-63.147 51.627-141.44 85.76-227.2 94.293v-86.187c62.293-7.893 119.040-32.427 166.4-69.12l60.8 61.013zM850.347 490.667h86.187c-8.533 85.76-42.667 163.84-94.293 227.2l-60.8-60.8c36.48-47.36 61.227-104.107 68.907-166.4zM242.773 657.067l-60.8 60.8c-51.84-63.36-85.973-141.44-94.507-227.2h86.187c7.893 62.293 32.427 119.040 69.12 166.4zM173.653 405.333h-86.187c8.533-85.76 42.667-163.84 94.293-227.2l60.8 60.8c-36.48 47.36-61.013 104.32-68.907 166.4zM640 448c0 70.613-57.387 128-128 128s-128-57.387-128-128 57.387-128 128-128 128 57.387 128 128zM781.227 239.147l60.8-60.8c51.84 63.147 85.973 141.227 94.507 226.987h-86.187c-7.68-62.080-32.427-119.040-69.12-166.187zM554.667 109.653v-86.187c85.76 8.533 163.84 42.667 227.2 94.293l-60.8 60.8c-47.36-36.48-104.107-61.013-166.4-68.907zM242.133 117.76c63.36-51.627 141.44-85.76 227.2-94.293v86.187c-62.293 7.893-119.040 32.427-166.4 69.12l-60.8-61.013z" /> -<glyph unicode="" d="M797.653 430.933c-11.947 6.827-24.32 12.373-36.693 17.067 12.373 4.693 24.747 10.24 36.693 17.067 81.92 47.36 127.573 133.333 127.787 221.653-76.587 43.947-173.867 47.36-255.787 0-11.947-6.827-22.827-14.72-33.28-23.253 2.133 13.44 3.627 26.667 3.627 40.533 0 94.72-51.627 177.28-128 221.44-76.373-44.16-128-126.72-128-221.44 0-13.867 1.28-27.093 3.413-40.32-10.453 8.32-21.333 16.213-33.28 23.253-81.92 47.36-179.2 43.947-255.787 0 0.213-88.32 45.867-174.293 127.787-221.653 11.947-6.827 24.32-12.373 36.693-17.067-12.373-4.693-24.747-10.24-36.693-17.067-81.92-47.36-127.573-133.333-127.787-221.653 76.587-43.947 173.867-47.36 255.787 0 11.947 6.827 22.827 14.72 33.28 23.253-1.92-13.653-3.413-26.88-3.413-40.747 0-94.72 51.627-177.28 128-221.44 76.373 44.373 128 126.72 128 221.44 0 13.867-1.493 27.093-3.413 40.32 10.453-8.32 21.333-16.213 33.28-23.253 81.92-47.36 179.2-43.947 255.787 0-0.213 88.533-45.867 174.507-128 221.867zM512 277.333c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667 170.667-76.373 170.667-170.667-76.373-170.667-170.667-170.667z" /> -<glyph unicode="" d="M298.667 490.667h-256v-85.333h256v85.333zM391.253 629.12l-90.453 90.453-60.373-60.373 90.453-90.453 60.373 60.373zM554.667 917.333h-85.333v-256h85.333v256zM783.573 659.2l-60.373 60.373-90.453-90.453 60.373-60.373 90.453 90.453zM725.333 490.667v-85.333h256v85.333h-256zM512 576c-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128-57.387 128-128 128zM632.747 266.88l90.453-90.453 60.373 60.373-90.453 90.453-60.373-60.373zM240.427 236.8l60.373-60.373 90.453 90.453-60.373 60.373-90.453-90.453zM469.333-21.333h85.333v256h-85.333v-256z" /> -<glyph unicode="" d="M128 874.667v-512h128v-384l298.667 512h-170.667l170.667 384h-426.667zM810.667 874.667h-85.333l-136.533-384h81.067l29.867 85.333h136.533l29.867-85.333h81.067l-136.533 384zM718.933 633.6l49.067 155.733 49.067-155.733h-98.133z" /> -<glyph unicode="" d="M139.733 832l-54.4-54.4 213.333-213.333v-158.933h128v-384l152.96 262.187 176.64-176.853 54.4 54.187-670.933 671.147zM725.333 533.333h-170.667l170.667 341.333h-426.667v-93.013l360.96-360.96 65.707 112.64z" /> -<glyph unicode="" d="M298.667 874.667v-469.333h128v-384l298.667 512h-170.667l170.667 341.333z" /> -<glyph unicode="" d="M640 64h85.333v85.333h-85.333v-85.333zM810.667 576h85.333v85.333h-85.333v-85.333zM128 746.667v-597.333c0-47.147 38.187-85.333 85.333-85.333h170.667v85.333h-170.667v597.333h170.667v85.333h-170.667c-47.147 0-85.333-38.187-85.333-85.333zM810.667 832v-85.333h85.333c0 47.147-38.187 85.333-85.333 85.333zM469.333-21.333h85.333v938.667h-85.333v-938.667zM810.667 234.667h85.333v85.333h-85.333v-85.333zM640 746.667h85.333v85.333h-85.333v-85.333zM810.667 405.333h85.333v85.333h-85.333v-85.333zM810.667 64c47.147 0 85.333 38.187 85.333 85.333h-85.333v-85.333z" /> -<glyph unicode="" d="M469.333 576h85.333v-85.333h-85.333zM384 490.667h85.333v-85.333h-85.333zM554.667 490.667h85.333v-85.333h-85.333zM640 576h85.333v-85.333h-85.333zM298.667 576h85.333v-85.333h-85.333zM810.667 832h-597.333c-46.933 0-85.333-38.4-85.333-85.333v-597.333c0-46.933 38.4-85.333 85.333-85.333h597.333c46.933 0 85.333 38.4 85.333 85.333v597.333c0 46.933-38.4 85.333-85.333 85.333zM384 192h-85.333v85.333h85.333v-85.333zM554.667 192h-85.333v85.333h85.333v-85.333zM725.333 192h-85.333v85.333h85.333v-85.333zM810.667 490.667h-85.333v-85.333h85.333v-85.333h-85.333v85.333h-85.333v-85.333h-85.333v85.333h-85.333v-85.333h-85.333v85.333h-85.333v-85.333h-85.333v85.333h85.333v85.333h-85.333v256h597.333v-256z" /> -<glyph unicode="" d="M426.667 448c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM256 618.667c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM256 277.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 618.667c47.147 0 85.333 38.187 85.333 85.333s-38.187 85.333-85.333 85.333-85.333-38.187-85.333-85.333 38.187-85.333 85.333-85.333zM597.333 277.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 448c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM597.333 618.667c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM426.667 789.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M341.333 789.333v-62.080l85.333-85.333v147.413h170.667v-170.667h-147.413l85.333-85.333h62.080v-62.080l85.333-85.333v147.413h170.667v-170.667h-147.413l85.333-85.333h62.080v-62.080l85.333-85.333v659.413c0 47.147-38.187 85.333-85.333 85.333h-659.413l85.333-85.333h62.080zM682.667 789.333h170.667v-170.667h-170.667v170.667zM54.4 905.6l-54.4-54.187 85.333-85.333v-659.413c0-47.147 38.187-85.333 85.333-85.333h659.413l85.333-85.333 54.187 54.4-915.2 915.2zM426.667 424.747l62.080-62.080h-62.080v62.080zM170.667 680.747l62.080-62.080h-62.080v62.080zM341.333 106.667h-170.667v170.667h170.667v-170.667zM341.333 362.667h-170.667v170.667h147.413l23.253-23.253v-147.413zM597.333 106.667h-170.667v170.667h147.413l23.253-23.253v-147.413zM682.667 106.667v62.080l62.080-62.080h-62.080z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM341.333 106.667h-170.667v170.667h170.667v-170.667zM341.333 362.667h-170.667v170.667h170.667v-170.667zM341.333 618.667h-170.667v170.667h170.667v-170.667zM597.333 106.667h-170.667v170.667h170.667v-170.667zM597.333 362.667h-170.667v170.667h170.667v-170.667zM597.333 618.667h-170.667v170.667h170.667v-170.667zM853.333 106.667h-170.667v170.667h170.667v-170.667zM853.333 362.667h-170.667v170.667h170.667v-170.667zM853.333 618.667h-170.667v170.667h170.667v-170.667z" /> -<glyph unicode="" d="M768 234.667l-628.48 628.267-54.187-54.187 170.667-170.667v-147.413h-85.333v170.667h-85.333v-426.667h85.333v170.667h85.333v-170.667h85.333v318.080l42.667-42.667v-275.413h170.667c28.587 0 53.547 14.080 69.12 35.627l270.293-270.293 54.187 54.4-180.267 180.267zM554.667 320h-85.333v104.747l85.333-85.333v-19.413zM768 405.333h42.667l34.987-139.52 30.933-31.147h62.080l-50.773 178.133c29.867 13.227 50.773 43.093 50.773 77.867v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667v-232.747l85.333-85.333v62.080zM768 576h85.333v-85.333h-85.333v85.333zM640 471.253v104.747c0 47.147-38.187 85.333-85.333 85.333h-104.747l190.080-190.080z" /> -<glyph unicode="" d="M256 490.667h-85.333v170.667h-85.333v-426.667h85.333v170.667h85.333v-170.667h85.333v426.667h-85.333v-170.667zM554.667 661.333h-170.667v-426.667h170.667c47.147 0 85.333 38.187 85.333 85.333v256c0 47.147-38.187 85.333-85.333 85.333zM554.667 320h-85.333v256h85.333v-256zM938.667 490.667v85.333c0 47.147-38.187 85.333-85.333 85.333h-170.667v-426.667h85.333v170.667h42.667l42.667-170.667h85.333l-50.773 178.133c29.867 13.227 50.773 43.093 50.773 77.867zM853.333 490.667h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M725.333 704c-141.44 0-256-114.56-256-256s114.56-256 256-256 256 114.56 256 256-114.56 256-256 256zM213.333 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667zM213.333 362.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M213.333 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667zM725.333 704c-141.44 0-256-114.56-256-256s114.56-256 256-256 256 114.56 256 256-114.56 256-256 256zM725.333 277.333c-94.293 0-170.667 76.373-170.667 170.667s76.373 170.667 170.667 170.667 170.667-76.373 170.667-170.667-76.373-170.667-170.667-170.667z" /> -<glyph unicode="" d="M756.48 447.147l169.813 169.813c16.64 16.64 16.64 43.733 0 60.373l-184.96 184.96c-16.64 16.64-43.733 16.64-60.373 0l-169.813-169.813-169.813 169.6c-8.32 8.32-19.2 12.587-30.080 12.587s-21.76-4.267-30.080-12.587l-185.173-184.96c-16.64-16.64-16.64-43.733 0-60.373l169.813-169.813-169.813-169.6c-16.64-16.64-16.64-43.733 0-60.373l184.96-184.96c16.64-16.64 43.733-16.64 60.373 0l169.813 169.813 169.813-169.813c8.32-8.32 19.2-12.587 30.080-12.587s21.76 4.267 30.080 12.587l184.96 184.96c16.64 16.64 16.64 43.733 0 60.373l-169.6 169.813zM512 576c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM311.040 492.373l-154.667 154.667 154.88 154.88 154.667-154.667-154.88-154.88zM426.667 405.333c-23.467 0-42.667 19.2-42.667 42.667s19.2 42.667 42.667 42.667 42.667-19.2 42.667-42.667-19.2-42.667-42.667-42.667zM512 320c-23.467 0-42.667 19.2-42.667 42.667s19.2 42.667 42.667 42.667 42.667-19.2 42.667-42.667-19.2-42.667-42.667-42.667zM597.333 490.667c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM711.040 92.373l-154.667 154.667 154.88 154.88 154.667-154.667-154.88-154.88z" /> -<glyph unicode="" d="M896 149.333v597.333c0 47.147-38.187 85.333-85.333 85.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333zM362.667 384l106.667-128.213 149.333 192.213 192-256h-597.333l149.333 192z" /> -<glyph unicode="" d="M682.667 533.333h-85.333v-85.333h85.333v85.333zM682.667 362.667h-85.333v-85.333h85.333v85.333zM341.333 533.333h-85.333v-85.333h85.333v85.333zM512 533.333h-85.333v-85.333h85.333v85.333zM853.333 789.333h-682.667c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 192h-682.667v512h682.667v-512z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM234.667 640h85.333v85.333h64v-85.333h85.333v-64h-85.333v-85.333h-64v85.333h-85.333v64zM810.667 149.333h-597.333l597.333 597.333v-597.333zM725.333 234.667v64h-213.333v-64h213.333z" /> -<glyph unicode="" d="M597.333 704l-160-213.333 121.6-162.133-68.267-51.2c-72.107 96-192 256-192 256l-256-341.333h938.667l-384 512z" /> -<glyph unicode="" d="M256 832h-128v-128c70.613 0 128 57.387 128 128zM597.333 832h-85.333c0-212.053-171.947-384-384-384v-85.333c259.2 0 469.333 210.133 469.333 469.333zM426.667 832h-85.333c0-117.76-95.573-213.333-213.333-213.333v-85.333c164.907 0 298.667 133.76 298.667 298.667zM426.667 64h85.333c0 212.053 171.947 384 384 384v85.333c-259.2 0-469.333-210.133-469.333-469.333zM768 64h128v128c-70.613 0-128-57.387-128-128zM597.333 64h85.333c0 117.76 95.573 213.333 213.333 213.333v85.333c-164.907 0-298.667-133.76-298.667-298.667z" /> -<glyph unicode="" d="M426.667 832h-85.333c0-15.573-1.92-30.72-5.12-45.44l68.053-68.053c14.293 35.2 22.4 73.387 22.4 113.493zM128 777.6l121.173-121.173c-34.56-23.68-76.16-37.76-121.173-37.76v-85.333c68.693 0 131.627 23.467 181.973 62.293l60.8-60.8c-65.92-54.187-150.613-86.827-242.773-86.827v-85.333c115.84 0 221.653 42.027 303.36 111.573l106.88-106.88c-69.547-81.707-111.573-187.52-111.573-303.36h85.333c0 92.16 32.64 176.853 86.827 242.987l60.8-60.8c-38.827-50.56-62.293-113.493-62.293-182.187h85.333c0 45.013 14.080 86.613 37.973 121.173l121.173-121.173 54.187 54.4-713.6 713.6-54.4-54.4zM597.333 832h-85.333c0-64-16-124.373-43.733-177.493l62.507-62.507c42.027 70.4 66.56 152.107 66.56 240zM850.56 272.213c14.72 3.2 29.867 5.12 45.44 5.12v85.333c-40.107 0-78.293-8.107-113.28-22.4l67.84-68.053zM656 466.773l62.507-62.507c53.12 27.733 113.493 43.733 177.493 43.733v85.333c-87.893 0-169.6-24.533-240-66.56z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667z" /> -<glyph unicode="" d="M512 533.333c-164.693 0-298.667-133.973-298.667-298.667h85.333c0 117.547 95.787 213.333 213.333 213.333s213.333-95.787 213.333-213.333h85.333c0 164.693-133.973 298.667-298.667 298.667zM512 704c-258.773 0-469.333-210.56-469.333-469.333h85.333c0 211.627 172.373 384 384 384s384-172.373 384-384h85.333c0 258.773-210.56 469.333-469.333 469.333z" /> -<glyph unicode="" d="M810.88 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM640.213 512c0-35.413-28.587-64-64-64 35.413 0 64-28.587 64-64v-64c0-47.147-38.187-85.333-85.333-85.333h-170.667v85.333h170.667v85.333h-85.333v85.333h85.333v85.333h-170.667v85.333h170.667c47.147 0 85.333-38.187 85.333-85.333v-64z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM640 234.667h-85.333v170.667h-170.667v256h85.333v-170.667h85.333v170.667h85.333v-426.667z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM640 576h-170.667v-85.333h85.333c47.147 0 85.333-38.187 85.333-85.333v-85.333c0-47.147-38.187-85.333-85.333-85.333h-170.667v85.333h170.667v85.333h-170.667v256h256v-85.333z" /> -<glyph unicode="" d="M469.333 320h85.333v85.333h-85.333v-85.333zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM640 576h-170.667v-85.333h85.333c47.147 0 85.333-38.187 85.333-85.333v-85.333c0-47.147-38.187-85.333-85.333-85.333h-85.333c-47.147 0-85.333 38.187-85.333 85.333v256c0 47.147 38.187 85.333 85.333 85.333h170.667v-85.333z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM597.333 234.667h-85.333v341.333h-85.333v85.333h170.667v-426.667z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM640 490.667c0-47.147-38.187-85.333-85.333-85.333h-85.333v-85.333h170.667v-85.333h-256v170.667c0 47.147 38.187 85.333 85.333 85.333h85.333v85.333h-170.667v85.333h170.667c47.147 0 85.333-38.187 85.333-85.333v-85.333z" /> -<glyph unicode="" d="M554.667 661.333h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667v170.667zM512 874.667c-235.307 0-426.667-191.36-426.667-426.667s191.36-426.667 426.667-426.667h341.333c47.147 0 85.333 38.187 85.333 85.333v341.333c0 235.307-191.36 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M768 789.333l85.333-170.667h-128l-85.333 170.667h-85.333l85.333-170.667h-128l-85.333 170.667h-85.333l85.333-170.667h-128l-85.333 170.667h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v597.333h-170.667z" /> -<glyph unicode="" d="M554.667 272.213c148.267 17.493 263.253 143.36 263.253 296.32 0 164.907-133.76 298.667-298.667 298.667s-298.667-133.76-298.667-298.667c0-147.84 107.52-270.293 248.747-294.187v-167.68h-256v-85.333h597.333v85.333h-256v165.547z" /> -<glyph unicode="" d="M945.92 568.747c0 164.907-133.76 298.667-298.667 298.667s-298.667-133.76-298.667-298.667c0-147.84 107.52-270.293 248.747-294.187v-167.893h-341.333v128h42.667v170.667c0 23.467-19.2 42.667-42.667 42.667h-128c-23.467 0-42.667-19.2-42.667-42.667v-170.667h42.667v-213.333h682.667v85.333h-128v165.547c148.267 17.493 263.253 143.573 263.253 296.533zM192 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64z" /> -<glyph unicode="" d="M657.707 643.627l-60.373 60.373-256-256 256-256 60.373 60.373-195.627 195.627z" /> -<glyph unicode="" d="M426.667 704l-60.373-60.373 195.627-195.627-195.627-195.627 60.373-60.373 256 256z" /> -<glyph unicode="" d="M512 832c-212.053 0-384-171.947-384-384s171.947-384 384-384c35.413 0 64 28.587 64 64 0 16.64-6.187 31.573-16.64 42.88-10.027 11.307-16 26.027-16 42.453 0 35.413 28.587 64 64 64h75.307c117.76 0 213.333 95.573 213.333 213.333 0 188.587-171.947 341.333-384 341.333zM277.333 448c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM405.333 618.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM618.667 618.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 448c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M981.333 192v512c0 47.147-38.187 85.333-85.333 85.333h-768c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333zM362.667 426.667l106.667-128.213 149.333 192.213 192-256h-597.333l149.333 192z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.16 0-341.333 153.173-341.333 341.333s153.173 341.333 341.333 341.333 341.333-153.173 341.333-341.333-153.173-341.333-341.333-341.333z" /> -<glyph unicode="" d="M853.333 680.747v-465.493c-110.72 32.853-225.28 49.493-341.333 49.493s-230.4-16.64-341.333-49.493v465.493c110.72-32.853 225.28-49.493 341.333-49.493s230.4 16.64 341.333 49.493zM914.347 789.333c-4.053 0-8.533-0.853-13.227-2.56-125.44-46.72-257.28-70.187-389.12-70.187s-263.68 23.467-389.12 70.187c-4.693 1.707-9.173 2.56-13.44 2.56-14.080 0-24.107-10.027-24.107-26.667v-629.333c0.213-16.64 10.027-26.667 24.107-26.667 4.053 0 8.533 0.853 13.227 2.56 125.44 46.72 257.28 70.187 389.12 70.187s263.68-23.467 389.12-70.187c4.693-1.707 9.173-2.56 13.227-2.56 14.080 0 24.32 10.027 24.107 26.667v629.333c0.427 16.64-9.813 26.667-23.893 26.667z" /> -<glyph unicode="" d="M850.773 58.88c-46.72 125.44-70.187 257.28-70.187 389.12s23.467 263.68 70.187 389.12c1.707 4.693 2.56 9.173 2.56 13.44 0 14.080-10.027 24.107-26.667 24.107h-629.333c-16.64-0.213-26.667-10.027-26.667-24.107 0-4.053 0.853-8.533 2.56-13.227 46.72-125.44 70.187-257.28 70.187-389.12s-23.467-263.68-70.187-389.12c-1.707-4.907-2.56-9.387-2.56-13.653 0-14.080 10.027-24.107 26.667-24.107h629.333c16.64 0 26.667 10.24 26.667 24.32 0 4.053-0.853 8.533-2.56 13.227zM279.253 106.667c32.853 110.72 49.493 225.28 49.493 341.333s-16.64 230.4-49.493 341.333h465.493c-32.853-110.72-49.493-225.28-49.493-341.333s16.64-230.4 49.493-341.333h-465.493z" /> -<glyph unicode="" d="M512 704c104.533 0 200.96-8.32 311.040-27.093 20.053-76.16 30.293-153.173 30.293-228.907s-10.24-152.747-30.293-228.907c-110.080-18.773-206.507-27.093-311.040-27.093s-200.96 8.32-311.040 27.093c-20.053 76.16-30.293 153.173-30.293 228.907s10.24 152.747 30.293 228.907c110.080 18.773 206.507 27.093 311.040 27.093zM512 789.333c-116.48 0-222.933-10.24-339.413-30.72l-39.467-7.040-10.667-38.187c-24.747-88.32-37.12-176.853-37.12-265.387s12.373-177.067 37.12-265.387l10.667-38.187 39.467-7.040c116.48-20.48 222.933-30.72 339.413-30.72s222.933 10.24 339.413 30.72l39.467 7.040 10.667 38.187c24.747 88.32 37.12 176.853 37.12 265.387s-12.373 177.067-37.12 265.387l-10.667 38.187-39.467 7.040c-116.48 20.48-222.933 30.72-339.413 30.72z" /> -<glyph unicode="" d="M896 149.333v597.333c0 47.147-38.187 85.333-85.333 85.333h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333zM362.667 384l106.667-128.213 149.333 192.213 192-256h-597.333l149.333 192z" /> -<glyph unicode="" d="M768 874.667h-512c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 85.333-85.333 85.333zM256 789.333h213.333v-341.333l-106.667 64-106.667-64v341.333zM256 149.333l128 164.48 91.52-109.867 128 164.907 164.48-219.52h-512z" /> -<glyph unicode="" d="M648.533 448c0-75.405-61.128-136.533-136.533-136.533s-136.533 61.128-136.533 136.533c0 75.405 61.128 136.533 136.533 136.533s136.533-61.128 136.533-136.533zM384 874.667l-78.080-85.333h-135.253c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333h-135.253l-78.080 85.333h-256zM512 234.667c-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333-95.573-213.333-213.333-213.333z" /> -<glyph unicode="" d="M938.667 277.333v512c0 47.147-38.187 85.333-85.333 85.333h-512c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333zM469.333 448l86.613-115.627 126.72 158.293 170.667-213.333h-512l128 170.667zM85.333 704v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333v85.333h-597.333v597.333h-85.333z" /> -<glyph unicode="" d="M512 437.333c52.907 0 96 42.88 96 96 0 52.907-43.093 96-96 96s-96-43.093-96-96c0-53.12 43.093-96 96-96zM704 266.667c0 64-128 96-192 96s-192-32-192-96v-32h384v32zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M512 768c-213.333 0-395.52-132.693-469.333-320 73.813-187.307 256-320 469.333-320s395.52 132.693 469.333 320c-73.813 187.307-255.787 320-469.333 320zM512 234.667c-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333-95.573-213.333-213.333-213.333zM512 576c-70.613 0-128-57.387-128-128s57.387-128 128-128 128 57.387 128 128-57.387 128-128 128z" /> -<glyph unicode="" d="M303.36 596.267l-60.373 60.373c-38.4-49.493-62.080-106.667-69.333-165.973h86.187c6.187 37.333 20.693 73.387 43.52 105.6zM259.84 405.333h-86.187c7.253-59.307 30.933-116.48 69.333-165.973l60.373 60.373c-22.827 32.213-37.333 68.267-43.52 105.6zM302.933 178.56c49.493-38.613 107.093-61.44 166.4-68.693v86.187c-37.333 6.187-73.173 20.907-105.173 43.733l-61.227-61.227zM554.667 786.347v130.987l-194.133-194.133 194.133-189.867v166.827c120.96-20.267 213.333-125.44 213.333-252.16s-92.373-231.893-213.333-252.16v-86.187c168.32 21.12 298.667 164.267 298.667 338.347s-130.347 317.227-298.667 338.347z" /> -<glyph unicode="" d="M663.467 723.2l-194.133 194.133v-130.987c-168.32-20.907-298.667-164.267-298.667-338.347s130.347-317.44 298.667-338.347v86.187c-120.96 20.267-213.333 125.44-213.333 252.16s92.373 231.893 213.333 252.16v-166.827l194.133 189.867zM850.347 490.667c-7.253 59.307-30.933 116.48-69.333 165.973l-60.373-60.373c22.827-32.213 37.333-68.267 43.52-105.6h86.187zM554.667 196.053v-86.4c59.307 7.253 116.907 30.293 166.4 68.693l-61.227 61.227c-32-22.613-67.84-37.12-105.173-43.52zM720.64 299.733l60.373-60.373c38.4 49.493 62.080 106.667 69.333 165.973h-86.187c-6.187-37.333-20.693-73.387-43.52-105.6z" /> -<glyph unicode="" d="M426.667 618.667v-341.333l213.333 170.667-213.333 170.667zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v597.333h597.333v-597.333z" /> -<glyph unicode="" d="M896 704h-768c-47.147 0-85.333-38.187-85.333-85.333v-341.333c0-47.147 38.187-85.333 85.333-85.333h768c47.147 0 85.333 38.187 85.333 85.333v341.333c0 47.147-38.187 85.333-85.333 85.333zM896 277.333h-768v341.333h85.333v-170.667h85.333v170.667h85.333v-170.667h85.333v170.667h85.333v-170.667h85.333v170.667h85.333v-170.667h85.333v170.667h85.333v-341.333z" /> -<glyph unicode="" d="M107.947 121.387l57.387-23.68v385.067l-103.467-249.813c-17.92-43.307 2.773-93.44 46.080-111.573zM939.947 279.68l-211.627 510.507c-13.227 32-44.373 51.84-77.013 52.48-11.307 0.213-22.827-1.92-34.133-6.4l-314.24-130.133c-32-13.227-51.627-44.16-52.48-76.8-0.213-11.52 1.707-23.040 6.4-34.347l211.413-510.507c13.44-32.427 44.8-52.053 78.080-52.48 11.093 0 22.187 1.92 33.067 6.4l314.24 130.133c43.307 17.92 64.213 67.84 46.293 111.147zM336 586.667c-23.467 0-42.667 19.2-42.667 42.667s19.2 42.667 42.667 42.667 42.667-19.2 42.667-42.667-19.2-42.667-42.667-42.667zM250.667 117.333c0-46.933 38.4-85.333 85.333-85.333h62.080l-147.413 355.84v-270.507z" /> -<glyph unicode="" d="M853.333 789.333h-135.253l-78.080 85.333h-256l-78.080-85.333h-135.253c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM640 298.667v106.667h-256v-106.667l-149.333 149.333 149.333 149.333v-106.667h256v106.667l149.333-149.333-149.333-149.333z" /> -<glyph unicode="" d="M768 554.667v149.333c0 23.467-18.987 42.667-42.667 42.667h-597.333c-23.68 0-42.667-19.2-42.667-42.667v-512c0-23.467 18.987-42.667 42.667-42.667h597.333c23.68 0 42.667 19.2 42.667 42.667v149.333l170.667-170.667v554.667l-170.667-170.667zM554.667 298.667v106.667h-256v-106.667l-149.333 149.333 149.333 149.333v-106.667h256v106.667l149.333-149.333-149.333-149.333z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM661.333 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM362.667 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM512 213.333c99.413 0 183.68 62.080 217.813 149.333h-435.627c34.133-87.253 118.4-149.333 217.813-149.333z" /> -<glyph unicode="" d="M832.427 828.8l-701.227-701.227c3.84-14.72 11.307-27.947 21.76-38.4l0.213-0.213c10.453-10.453 23.68-17.92 38.4-21.76l701.227 701.227c-7.893 29.44-30.933 52.48-60.373 60.373zM506.88 832l-378.88-378.88v-120.747l499.627 499.627h-120.747zM213.333 832c-46.933 0-85.333-38.4-85.333-85.333v-85.547l170.88 170.88h-85.547zM810.667 64c23.467 0 44.8 9.6 60.16 24.96 15.573 15.573 25.173 36.907 25.173 60.373v85.547l-170.88-170.88h85.547zM396.373 64h120.747l378.88 378.88v120.747l-499.627-499.627z" /> -<glyph unicode="" d="M693.12 629.12c-50.133 49.92-115.627 74.88-181.12 74.88v-256l-181.12-181.12c100.053-100.053 261.973-100.053 362.027 0s100.053 262.187 0.213 362.24zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 191.147 426.667 426.667c0 235.733-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333z" /> -<glyph unicode="" d="M640 917.333h-256v-85.333h256v85.333zM469.333 362.667h85.333v256h-85.333v-256zM811.733 644.907l60.8 60.8c-18.347 21.973-38.4 42.027-60.373 60.373l-60.8-60.8c-65.493 52.48-148.907 84.053-239.573 84.053-212.267 0-383.787-171.947-383.787-384s171.52-384 383.787-384 384.213 171.947 384.213 384c0 90.667-31.573 173.867-84.267 239.573zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667z" /> -<glyph unicode="" d="M495.36 406.4c-6.827 10.24-15.573 19.627-26.24 27.947-10.88 8.32-23.893 14.933-39.467 20.267 13.013 5.76 24.32 13.013 34.133 21.333 9.813 8.533 17.92 17.493 24.32 27.093s11.307 19.627 14.72 30.080c3.2 10.453 4.907 20.693 4.907 30.933 0 23.68-4.053 44.373-11.733 62.507-7.893 17.92-18.987 33.067-33.28 45.013s-31.36 21.12-51.413 27.307c-20.053 6.187-42.027 9.173-66.133 9.173-23.467 0-45.013-3.413-64.853-10.453s-36.907-16.64-51.2-29.013c-14.293-12.373-25.387-27.093-33.493-43.947s-11.947-35.413-11.947-55.253h84.48c0 10.88 1.92 20.693 5.973 29.44s9.387 16.213 16.427 22.187c7.040 6.187 15.147 10.88 24.747 14.293s19.84 5.12 30.933 5.12c26.027 0 45.227-6.613 58.027-20.053 12.587-13.44 18.987-32 18.987-56.107 0-11.52-1.707-22.187-5.12-31.573-3.413-9.6-8.747-17.707-16-24.32-7.253-6.827-16.213-11.947-26.88-15.787s-23.253-5.76-37.973-5.76h-50.133v-66.773h50.133c14.293 0 27.307-1.707 38.827-4.907s21.333-8.32 29.44-15.147c8.107-6.827 14.293-15.573 18.773-26.027s6.613-22.827 6.613-37.333c0-26.453-7.467-46.72-22.613-60.587s-35.627-20.907-61.867-20.907c-12.587 0-23.893 1.707-34.133 5.333s-18.987 8.747-26.027 15.36c-7.253 6.613-12.8 14.507-16.64 23.893-4.053 9.173-5.973 19.413-5.973 30.72h-85.12c0-23.467 4.48-44.16 13.653-61.867 8.96-17.92 21.12-32.853 36.48-44.8s33.067-20.907 53.12-26.88c20.053-5.973 41.173-8.96 63.147-8.96 24.107 0 46.507 3.413 67.413 9.813 20.693 6.613 38.827 16.213 53.973 28.8s27.093 28.16 35.627 46.72c8.533 18.56 12.8 39.68 12.8 63.36 0 12.587-1.493 24.747-4.693 36.48-3.2 11.947-8.107 23.040-14.72 33.28zM890.667 347.093c-6.187 12.16-15.147 22.613-26.88 31.573s-26.24 16.427-43.093 22.613c-17.067 6.187-36.267 11.52-57.6 16-14.933 3.2-27.093 6.4-36.907 9.813-9.813 3.2-17.707 6.827-23.467 10.667s-9.813 8.32-12.16 13.013c-2.347 4.693-3.413 10.24-3.413 16.427s1.28 11.947 3.84 17.707c2.56 5.547 6.4 10.453 11.52 14.72s11.52 7.68 19.413 10.24c7.68 2.56 16.853 3.84 27.307 3.84 10.667 0 20.053-1.493 28.16-4.693 8.107-2.987 14.933-7.253 20.267-12.587 5.547-5.333 9.6-11.307 12.373-17.92 2.773-6.827 4.053-13.653 4.053-20.693h83.2c0 16.64-3.413 32.213-10.027 46.507-6.827 14.293-16.427 26.88-29.227 37.547s-28.373 18.987-46.72 24.96c-18.56 6.187-39.253 9.173-62.507 9.173-21.973 0-41.813-2.987-59.307-8.96-17.707-5.973-32.64-14.293-45.227-24.533-12.373-10.24-21.973-22.187-28.587-35.84s-10.027-27.947-10.027-42.88c0-15.573 3.2-29.227 9.813-41.173 6.4-11.947 15.573-22.187 27.307-30.933s25.6-16.213 42.027-22.4c16.213-6.187 34.347-11.307 54.187-15.36 16.64-3.413 30.080-7.040 40.533-10.88s18.347-8.107 24.107-12.587c5.76-4.48 9.6-9.173 11.52-14.293s2.987-10.667 2.987-16.64c0-13.44-5.76-24.32-17.067-32.64-11.52-8.32-28.16-12.587-49.92-12.587-9.387 0-18.56 1.067-27.307 3.2-8.96 2.133-16.853 5.547-23.893 10.453-7.040 4.693-12.8 11.093-17.493 18.773-4.48 7.68-7.253 17.28-7.893 28.8h-80.853c0-15.36 3.413-30.293 10.027-45.013s16.64-27.947 29.867-39.467c13.227-11.733 29.653-21.12 49.067-28.16 19.413-7.253 42.027-10.88 67.2-10.88 22.613 0 43.093 2.773 61.653 8.107 18.56 5.547 34.347 13.227 47.36 23.040 13.227 10.027 23.253 21.76 30.293 35.413s10.667 28.8 10.667 45.227c0 16.853-3.2 31.147-9.173 43.307z" /> -<glyph unicode="" d="M0 630.827v-71.893l128 42.667v-409.6h85.333v512h-10.88l-202.453-73.173zM1014.827 347.093c-6.187 12.16-15.147 22.613-26.88 31.573s-26.24 16.427-43.093 22.613c-17.067 6.187-36.267 11.52-57.6 16-14.933 3.2-27.093 6.4-36.907 9.813-9.813 3.2-17.707 6.827-23.467 10.667s-9.813 8.32-12.16 13.013c-2.347 4.693-3.413 10.24-3.413 16.427s1.28 11.947 3.84 17.707c2.56 5.547 6.4 10.453 11.52 14.72s11.52 7.68 19.413 10.24c7.68 2.56 16.853 3.84 27.307 3.84 10.667 0 20.053-1.493 28.16-4.693 8.107-2.987 14.933-7.253 20.267-12.587 5.547-5.333 9.6-11.307 12.373-17.92 2.773-6.827 4.053-13.653 4.053-20.693h83.2c0 16.64-3.413 32.213-10.027 46.507s-16.427 26.88-29.227 37.547c-12.8 10.667-28.373 18.987-46.72 24.96-18.56 6.187-39.253 9.173-62.293 9.173-21.973 0-41.813-2.987-59.307-8.96-17.707-5.973-32.64-14.293-45.227-24.533-12.373-10.24-21.973-22.187-28.587-35.84s-10.027-27.947-10.027-42.88c0-15.573 3.2-29.227 9.813-41.173 6.4-11.947 15.573-22.187 27.307-30.933s25.6-16.213 42.027-22.4c16.213-6.187 34.347-11.307 54.187-15.36 16.64-3.413 30.080-7.040 40.533-10.88s18.347-8.107 24.107-12.587c5.76-4.48 9.6-9.173 11.52-14.293s2.987-10.667 2.987-16.64c0-13.44-5.76-24.32-17.067-32.64-11.52-8.32-28.16-12.587-49.92-12.587-9.387 0-18.56 1.067-27.307 3.2-8.96 2.133-16.853 5.547-23.893 10.453-7.040 4.693-12.8 11.093-17.493 18.773-4.48 7.68-7.253 17.28-7.893 28.8h-80.853c0-15.36 3.413-30.293 10.027-45.013s16.64-27.947 29.867-39.467c13.227-11.733 29.653-21.12 49.067-28.16 19.413-7.253 42.027-10.88 67.2-10.88 22.613 0 43.093 2.773 61.653 8.107 18.56 5.547 34.347 13.227 47.36 23.040 13.227 10.027 23.253 21.76 30.293 35.413s10.667 28.8 10.667 45.227c-0.213 16.853-3.2 31.147-9.387 43.307zM589.653 659.413c-14.507 17.28-32 29.653-52.267 37.333-20.48 7.68-43.093 11.52-68.267 11.52-24.747 0-47.36-3.84-67.84-11.52s-37.973-20.053-52.267-37.333c-14.507-17.28-25.6-39.893-33.493-67.627-7.893-27.947-11.733-61.867-11.733-101.973v-81.707c0-40.107 4.053-74.24 11.947-102.187 8.107-27.947 19.413-50.773 33.92-68.267 14.72-17.493 32.213-30.293 52.48-38.187 20.48-7.893 43.093-11.733 67.84-11.733 24.96 0 47.787 4.053 68.053 11.733 20.267 7.893 37.547 20.48 52.053 38.187 14.293 17.493 25.6 40.32 33.493 68.267s11.733 62.080 11.733 102.187v81.707c0 40.107-4.053 74.027-11.733 101.973-8.107 27.733-19.413 50.347-33.92 67.627zM550.613 395.733c0-25.6-1.707-47.147-5.12-65.067s-8.747-32.427-15.573-43.52-15.36-19.2-25.173-24.32c-10.027-5.12-21.547-7.68-34.773-7.68-13.013 0-24.533 2.56-34.773 7.68s-18.773 13.227-25.813 24.32c-7.040 11.093-12.373 25.6-16 43.52s-5.547 39.467-5.547 65.067v106.88c0 25.813 1.707 47.36 5.333 64.853s8.96 31.573 15.787 42.453c7.040 10.88 15.573 18.56 25.6 23.253s21.547 7.040 34.56 7.040c13.013 0 24.533-2.347 34.56-7.040s18.56-12.587 25.6-23.253c7.040-10.88 12.16-24.96 15.787-42.453s5.333-39.253 5.333-64.853v-106.88z" /> -<glyph unicode="" d="M512 789.333c-94.293 0-170.667-76.373-170.667-170.667 0-94.080 76.373-170.667 170.667-170.667s170.667 76.587 170.667 170.667c0 94.293-76.373 170.667-170.667 170.667zM512 362.667c-113.707 0-341.333-56.96-341.333-170.667v-85.333h682.667v85.333c0 113.707-227.627 170.667-341.333 170.667z" /> -<glyph unicode="" d="M812.16 765.867l-60.8-60.8c-65.493 52.693-148.907 84.267-239.573 84.267-78.080 0-150.4-23.467-210.987-63.36l62.080-62.080c43.947 25.387 94.72 40.107 149.12 40.107 164.907 0 298.667-133.76 298.667-298.667 0-54.4-14.72-105.173-40.107-149.12l62.080-62.080c39.893 60.587 63.36 133.12 63.36 211.2 0 90.667-31.573 173.867-84.267 239.573l60.8 60.8-60.373 60.16zM640 917.333h-256v-85.333h256v85.333zM469.333 557.44l85.333-85.333v146.56h-85.333v-61.227zM128.853 789.333l-54.4-54.187 117.547-117.547c-40.32-60.8-64-133.76-64-212.267 0-212.053 171.52-384 383.787-384 78.507 0 151.467 23.68 212.267 64l106.667-106.667 54.187 54.4-756.053 756.267zM512 106.667c-164.907 0-298.667 133.76-298.667 298.667 0 54.827 14.933 106.027 40.747 150.187l408.107-408.107c-44.16-25.813-95.36-40.747-150.187-40.747z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM469.333 109.653c-168.32 20.907-298.667 164.267-298.667 338.347s130.347 317.44 298.667 338.347v-676.693zM554.667 786.347c43.947-5.547 85.333-19.2 122.453-39.68h-122.453v39.68zM554.667 661.333h223.573c10.667-13.44 20.48-27.733 29.013-42.667h-252.587v42.667zM554.667 533.333h287.573c3.627-13.867 6.4-28.16 8.32-42.667h-295.893v42.667zM554.667 109.653v39.68h122.453c-37.12-20.48-78.507-34.133-122.453-39.68zM778.24 234.667h-223.573v42.667h252.587c-8.533-14.933-18.347-29.227-29.013-42.667zM842.24 362.667h-287.573v42.667h295.68c-1.707-14.507-4.693-28.8-8.107-42.667z" /> -<glyph unicode="" d="M938.667 192v85.333h-597.333v512h85.333l-128 128-128-128h85.333v-85.333h-170.667v-85.333h170.667v-341.333c0-47.147 38.187-85.333 85.333-85.333h341.333v-85.333h-85.333l128-128 128 128h-85.333v85.333h170.667zM426.667 618.667h256v-256h85.333v256c0 47.147-38.187 85.333-85.333 85.333h-256v-85.333z" /> -<glyph unicode="" d="M128 234.667v-85.333h256v85.333h-256zM128 746.667v-85.333h426.667v85.333h-426.667zM554.667 64v85.333h341.333v85.333h-341.333v85.333h-85.333v-256h85.333zM298.667 576v-85.333h-170.667v-85.333h170.667v-85.333h85.333v256h-85.333zM896 405.333v85.333h-426.667v-85.333h426.667zM640 576h85.333v85.333h170.667v85.333h-170.667v85.333h-85.333v-256z" /> -<glyph unicode="" d="M292.267 420.267h98.133l-49.067 155.733-49.067-155.733zM938.667 661.333l-51.413-268.373-63.787 268.373h-68.267l-63.573-268.373-51.627 268.373h-32.427c-62.507 77.867-158.507 128-266.24 128-188.587 0-341.333-152.747-341.333-341.333s152.747-341.333 341.333-341.333c133.76 0 249.173 77.013 305.28 189.013l4.053-18.347h74.667l64 260.267 64-260.267h74.667l87.467 384h-76.8zM439.467 277.333l-29.867 85.333h-136.533l-29.867-85.333h-81.067l136.533 384h85.333l136.533-384h-81.067z" /> -<glyph unicode="" d="M825.813 531.84c-29.013 146.773-158.507 257.493-313.813 257.493-123.307 0-230.187-69.973-283.733-172.16-128.213-13.867-228.267-122.453-228.267-254.507 0-141.44 114.56-256 256-256h554.667c117.76 0 213.333 95.573 213.333 213.333 0 112.64-87.68 203.947-198.187 211.84z" /> -<glyph unicode="" d="M151.467 169.173l60.373-60.373 76.587 76.587-60.373 60.373-76.587-76.587zM469.333 2.133h85.333v125.867h-85.333v-125.867zM170.667 512h-128v-85.333h128v85.333zM640 690.773v205.227h-256v-205.227c-76.373-44.373-128-126.72-128-221.44 0-141.44 114.56-256 256-256s256 114.56 256 256c0 94.72-51.627 177.28-128 221.44zM853.333 512v-85.333h128v85.333h-128zM735.787 185.387l76.587-76.587 60.373 60.373-76.587 76.587-60.373-60.373z" /> -<glyph unicode="" d="M213.333 341.333h597.333v256h-597.333v-256zM469.333 936.533v-125.867h85.333v125.867h-85.333zM812.16 829.867l-76.587-76.587 60.373-60.373 76.587 76.587-60.373 60.373zM554.667 2.133v125.867h-85.333v-125.867h85.333zM872.533 169.173l-76.587 76.587-60.373-60.373 76.587-76.587 60.373 60.373zM151.467 769.493l76.587-76.587 60.373 60.373-76.587 76.587-60.373-60.373zM211.84 108.8l76.587 76.587-60.373 60.373-76.587-76.587 60.373-60.373z" /> -<glyph unicode="" d="M288.213 753.28l-76.373 76.587-60.373-60.373 76.587-76.587 60.16 60.373zM170.667 512h-128v-85.333h128v85.333zM554.667 936.533h-85.333v-125.867h85.333v125.867zM872.533 769.493l-60.373 60.373-76.587-76.587 60.373-60.373 76.587 76.587zM735.787 185.387l76.587-76.587 60.373 60.373-76.587 76.587-60.373-60.373zM853.333 512v-85.333h128v85.333h-128zM512 725.333c-141.44 0-256-114.56-256-256s114.56-256 256-256 256 114.56 256 256-114.56 256-256 256zM469.333 2.133h85.333v125.867h-85.333v-125.867zM151.467 169.173l60.373-60.373 76.587 76.587-60.373 60.373-76.587-76.587z" /> -<glyph unicode="" d="M810.667 917.333h-597.333c-47.147 0-84.907-38.187-84.907-85.333l-0.427-551.893c0-29.44 14.933-55.467 37.547-70.827l346.24-230.613 346.24 230.613c22.613 15.36 37.547 41.387 37.547 70.827l0.427 551.893c0 47.147-38.187 85.333-85.333 85.333zM426.667 277.333l-213.333 213.333 60.373 60.373 152.96-152.96 323.627 323.627 60.373-60.373-384-384z" /> -<glyph unicode="" d="M926.080 478.080l-384 384c-16.64 16.64-43.733 16.64-60.16 0l-384-384c-16.64-16.64-16.64-43.733 0-60.373l384-384c16.64-16.64 43.733-16.64 60.373 0l384 384c16.64 16.853 16.64 43.733-0.213 60.373zM597.333 341.333v106.667h-170.667v-128h-85.333v170.667c0 23.68 18.987 42.667 42.667 42.667h213.333v106.667l149.333-149.333-149.333-149.333z" /> -<glyph unicode="" d="M682.667 755.2c42.24 0 76.8 34.347 76.8 76.8s-34.56 76.8-76.8 76.8c-42.453 0-76.8-34.347-76.8-76.8s34.347-76.8 76.8-76.8zM810.667 448c-117.76 0-213.333-95.573-213.333-213.333s95.573-213.333 213.333-213.333 213.333 95.573 213.333 213.333-95.573 213.333-213.333 213.333zM810.667 85.333c-82.56 0-149.333 66.773-149.333 149.333s66.773 149.333 149.333 149.333 149.333-66.773 149.333-149.333-66.773-149.333-149.333-149.333zM631.467 533.333h179.2v76.8h-136.533l-82.56 139.307c-12.587 21.333-35.84 35.627-62.507 35.627-20.053 0-38.187-8.107-51.2-21.333l-157.867-157.653c-13.227-13.227-21.333-31.36-21.333-51.413 0-26.88 14.293-49.493 36.267-62.72l142.933-86.613v-213.333h76.8v276.48l-96 71.253 98.987 99.413 73.813-105.813zM213.333 448c-117.76 0-213.333-95.573-213.333-213.333s95.573-213.333 213.333-213.333 213.333 95.573 213.333 213.333-95.573 213.333-213.333 213.333zM213.333 85.333c-82.56 0-149.333 66.773-149.333 149.333s66.773 149.333 149.333 149.333 149.333-66.773 149.333-149.333-66.773-149.333-149.333-149.333z" /> -<glyph unicode="" d="M170.667 277.333c0-37.76 16.64-71.253 42.667-94.72v-75.947c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v42.667h341.333v-42.667c0-23.467 18.987-42.667 42.667-42.667h42.667c23.467 0 42.667 19.2 42.667 42.667v75.947c26.027 23.467 42.667 56.96 42.667 94.72v426.667c0 149.333-152.747 170.667-341.333 170.667s-341.333-21.333-341.333-170.667v-426.667zM320 234.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM704 234.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM768 490.667h-512v213.333h512v-213.333z" /> -<glyph unicode="" d="M807.253 703.573c-8.747 25.173-32.64 43.093-60.587 43.093h-469.333c-27.947 0-51.84-17.92-60.587-43.093l-88.747-255.573v-341.333c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v42.667h512v-42.667c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v341.333l-88.747 255.573zM277.333 277.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 277.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM213.333 490.667l64 192h469.333l64-192h-597.333z" /> -<glyph unicode="" d="M853.333 64c-59.307 0-118.613 20.053-170.667 56.533-104.107-72.96-237.227-72.96-341.333 0-52.053-36.48-111.36-56.533-170.667-56.533h-85.333v-85.333h85.333c58.667 0 116.907 14.72 170.667 42.453 107.52-55.253 233.813-55.253 341.333 0 53.76-27.52 112-42.453 170.667-42.453h85.333v85.333h-85.333zM168.32 149.333h2.347c68.267 0 129.067 37.547 170.667 85.333 41.6-47.787 102.4-85.333 170.667-85.333s129.067 37.547 170.667 85.333c41.813-47.787 102.187-85.333 170.667-85.333h2.347l80.853 285.227c3.627 10.88 2.56 22.827-2.56 33.067-5.333 10.24-14.507 17.92-25.6 21.12l-55.040 18.133v197.12c0 47.147-38.187 85.333-85.333 85.333h-128v128h-256v-128h-128c-47.147 0-85.333-38.187-85.333-85.333v-197.12l-54.827-17.92c-11.093-3.413-20.267-10.88-25.6-21.12s-6.187-22.187-2.56-33.067l80.64-285.44zM256 704h512v-169.173l-256 83.84-256-83.84v169.173z" /> -<glyph unicode="" d="M512 874.667c-188.587 0-341.333-21.333-341.333-170.667v-405.333c0-82.56 66.987-149.333 149.333-149.333l-64-64v-21.333h512v21.333l-64 64c82.56 0 149.333 66.773 149.333 149.333v405.333c0 149.333-152.747 170.667-341.333 170.667zM320 234.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM469.333 490.667h-213.333v213.333h213.333v-213.333zM704 234.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM768 490.667h-213.333v213.333h213.333v-213.333z" /> -<glyph unicode="" d="M170.667 298.667c0-82.56 66.987-149.333 149.333-149.333l-64-64v-21.333h512v21.333l-64 64c82.56 0 149.333 66.773 149.333 149.333v448c0 149.333-152.747 170.667-341.333 170.667s-341.333-21.333-341.333-170.667v-448zM512 234.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM768 533.333h-512v213.333h512v-213.333z" /> -<glyph unicode="" d="M512 874.667c-188.587 0-341.333-21.333-341.333-170.667v-405.333c0-82.56 66.987-149.333 149.333-149.333l-64-64v-21.333h512v21.333l-64 64c82.56 0 149.333 66.773 149.333 149.333v405.333c0 149.333-152.747 170.667-341.333 170.667zM320 234.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM469.333 490.667h-213.333v213.333h213.333v-213.333zM704 234.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM768 490.667h-213.333v213.333h213.333v-213.333z" /> -<glyph unicode="" d="M597.333 797.867c42.24 0 76.8 34.347 76.8 76.8s-34.56 76.8-76.8 76.8c-42.453 0-76.8-34.347-76.8-76.8s34.347-76.8 76.8-76.8zM602.453 533.333h208.213v76.8h-154.667l-85.333 142.080c-12.587 21.333-35.84 35.413-62.293 35.413-7.253 0-14.293-1.067-20.907-2.987l-231.467-72.107v-221.867h76.8v156.373l89.813 27.947-166.613-653.653h76.8l122.453 346.027 99.413-132.693v-213.333h76.8v273.28l-106.24 193.707 31.36 122.453 45.867-77.44z" /> -<glyph unicode="" d="M896 277.333v85.333l-341.333 213.333v234.667c0 35.413-28.587 64-64 64s-64-28.587-64-64v-234.667l-341.333-213.333v-85.333l341.333 106.667v-234.667l-85.333-64v-64l149.333 42.667 149.333-42.667v64l-85.333 64v234.667l341.333-106.667z" /> -<glyph unicode="" d="M298.667 405.333c70.613 0 128 57.387 128 128s-57.387 128-128 128-128-57.387-128-128 57.387-128 128-128zM810.667 661.333h-341.333v-298.667h-341.333v384h-85.333v-640h85.333v128h768v-128h85.333v384c0 94.293-76.373 170.667-170.667 170.667z" /> -<glyph unicode="" d="M511.787 168.96l-314.667 244.693-69.12-53.76 384-298.667 384 298.667-69.547 53.973-314.667-244.907zM512 277.333l384 298.667-384 298.667-384-298.667 69.547-53.973 314.453-244.693z" /> -<glyph unicode="" d="M845.227 320.427l50.773 39.467-60.8 60.8-50.773-39.467 60.8-60.8zM826.24 521.6l69.76 54.4-384 298.667-124.373-96.64 336-336 102.613 79.573zM139.733 917.333l-54.4-54.4 180.053-180.053-137.387-106.88 69.547-53.973 314.453-244.693 89.387 69.547 60.8-60.8-150.613-117.12-314.453 244.693-69.12-53.76 384-298.667 210.987 164.267 161.493-161.493 54.187 54.4-798.933 798.933z" /> -<glyph unicode="" d="M896 277.333v85.333l-341.333 213.333v234.667c0 35.413-28.587 64-64 64s-64-28.587-64-64v-234.667l-341.333-213.333v-85.333l341.333 106.667v-234.667l-85.333-64v-64l149.333 42.667 149.333-42.667v64l-85.333 64v234.667l341.333-106.667z" /> -<glyph unicode="" d="M469.333 234.667h85.333v42.667h42.667c23.467 0 42.667 19.2 42.667 42.667v128c0 23.467-19.2 42.667-42.667 42.667h-128v42.667h170.667v85.333h-85.333v42.667h-85.333v-42.667h-42.667c-23.467 0-42.667-19.2-42.667-42.667v-128c0-23.467 19.2-42.667 42.667-42.667h128v-42.667h-170.667v-85.333h85.333v-42.667zM853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 192h-682.667v512h682.667v-512z" /> -<glyph unicode="" d="M853.333 448c0 47.147 38.187 85.333 85.333 85.333v170.667c0 47.147-38.187 85.333-85.333 85.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.213-170.667c47.147-0.213 85.12-38.4 85.12-85.333 0-47.147-38.187-85.333-85.12-85.333l-0.213-170.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v170.667c-47.147 0-85.333 38.187-85.333 85.333zM664.747 243.2l-152.747 98.133-152.747-98.133 46.080 175.573-140.373 114.773 181.12 10.667 65.92 168.32 65.92-168.32 181.12-10.667-140.373-114.773 46.080-175.573z" /> -<glyph unicode="" d="M469.333 405.333v-256h-213.333v-85.333h512v85.333h-213.333v256l341.333 341.333v85.333h-768v-85.333l341.333-341.333zM320 661.333l-85.333 85.333h554.667l-85.333-85.333h-384z" /> -<glyph unicode="" d="M853.333 832h-682.667v-426.667c0-94.293 76.373-170.667 170.667-170.667h256c94.293 0 170.667 76.373 170.667 170.667v128h85.333c47.147 0 85.333 38.187 85.333 85.333v128c0 47.147-38.187 85.333-85.333 85.333zM853.333 618.667h-85.333v128h85.333v-128zM85.333 64h768v85.333h-768v-85.333z" /> -<glyph unicode="" d="M725.333 746.667c35.413 0 64 28.587 64 64 0 42.667-64 115.2-64 115.2s-64-72.533-64-115.2c0-35.413 28.587-64 64-64zM512 746.667c35.413 0 64 28.587 64 64 0 42.667-64 115.2-64 115.2s-64-72.533-64-115.2c0-35.413 28.587-64 64-64zM298.667 746.667c35.413 0 64 28.587 64 64 0 42.667-64 115.2-64 115.2s-64-72.533-64-115.2c0-35.413 28.587-64 64-64zM807.253 618.24c-8.747 25.173-32.64 43.093-60.587 43.093h-469.333c-27.947 0-51.84-17.92-60.587-43.093l-88.747-255.573v-341.333c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v42.667h512v-42.667c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v341.333l-88.747 255.573zM277.333 192c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 192c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM213.333 405.333l64 192h469.333l64-192h-597.333z" /> -<glyph unicode="" d="M810.667 661.333v128h-597.333v-128h-128v-554.667h341.333v170.667h170.667v-170.667h341.333v554.667h-128zM469.333 533.333h-85.333v-42.667h85.333v-42.667h-128v128h85.333v42.667h-85.333v42.667h128v-128zM682.667 448h-42.667v85.333h-85.333v128h42.667v-85.333h42.667v85.333h42.667v-213.333z" /> -<glyph unicode="" d="M128 874.667l85.973-778.027c4.907-42.453 40.96-75.307 84.693-75.307h426.667c43.733 0 79.787 32.853 84.693 75.307l85.973 778.027h-768zM512 149.333c-70.613 0-128 57.387-128 128 0 85.333 128 230.4 128 230.4s128-145.067 128-230.4c0-70.613-57.387-128-128-128zM781.867 618.667h-539.733l-18.773 170.667h577.493l-18.987-170.667z" /> -<glyph unicode="" d="M512 21.333c212.053 0 384 171.947 384 384-212.053 0-384-171.947-384-384zM239.147 522.667c0-58.88 47.787-106.667 106.667-106.667 22.4 0 43.307 7.040 60.373 18.773l-0.853-8.107c0-58.88 47.787-106.667 106.667-106.667s106.667 47.787 106.667 106.667l-0.853 8.107c17.28-11.947 37.973-18.773 60.373-18.773 58.88 0 106.667 47.787 106.667 106.667 0 42.453-24.96 78.933-61.013 96 35.84 17.067 61.013 53.547 61.013 96 0 58.88-47.787 106.667-106.667 106.667-22.4 0-43.307-7.040-60.373-18.773l0.853 8.107c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667l0.853-8.107c-17.28 11.947-37.973 18.773-60.373 18.773-58.88 0-106.667-47.787-106.667-106.667 0-42.453 24.96-78.933 61.013-96-36.053-17.067-61.013-53.547-61.013-96zM512 725.333c58.88 0 106.667-47.787 106.667-106.667s-47.787-106.667-106.667-106.667-106.667 47.787-106.667 106.667 47.787 106.667 106.667 106.667zM128 405.333c0-212.053 171.947-384 384-384 0 212.053-171.947 384-384 384z" /> -<glyph unicode="" d="M843.52 651.52l0.64 0.64-158.933 158.507-45.227-45.227 90.027-90.027c-40.107-15.36-68.693-53.973-68.693-99.413 0-58.88 47.787-106.667 106.667-106.667 15.147 0 29.653 3.2 42.667 8.96v-307.627c0-23.467-19.2-42.667-42.667-42.667s-42.667 19.2-42.667 42.667v192c0 47.147-38.187 85.333-85.333 85.333h-42.667v298.667c0 47.147-38.187 85.333-85.333 85.333h-256c-47.147 0-85.333-38.187-85.333-85.333v-682.667h426.667v320h64v-213.333c0-58.88 47.787-106.667 106.667-106.667s106.667 47.787 106.667 106.667v405.333c0 29.44-11.947 56.107-31.147 75.52zM512 533.333h-256v213.333h256v-213.333zM768 533.333c-23.467 0-42.667 19.2-42.667 42.667s19.2 42.667 42.667 42.667 42.667-19.2 42.667-42.667-19.2-42.667-42.667-42.667z" /> -<glyph unicode="" d="M298.667 192c-47.147 0-84.907-38.187-84.907-85.333s37.76-85.333 84.907-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM42.667 874.667v-85.333h85.333l153.387-323.627-57.6-104.533c-6.613-12.373-10.453-26.24-10.453-41.173 0-47.147 38.187-85.333 85.333-85.333h512v85.333h-493.867c-5.973 0-10.667 4.693-10.667 10.667 0 1.92 0.427 3.627 1.28 5.12l38.187 69.547h317.867c32 0 59.947 17.707 74.667 43.947l152.533 276.907c3.413 5.973 5.333 13.013 5.333 20.48 0 23.68-19.2 42.667-42.667 42.667h-630.827l-40.533 85.333h-139.307zM725.333 192c-47.147 0-84.907-38.187-84.907-85.333s37.76-85.333 84.907-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM768 362.667h-170.667v-170.667h-170.667v170.667h-170.667v170.667h170.667v170.667h170.667v-170.667h170.667v-170.667z" /> -<glyph unicode="" d="M298.667 405.333c70.613 0 128 57.387 128 128s-57.387 128-128 128-128-57.387-128-128 57.387-128 128-128zM810.667 661.333h-341.333v-298.667h-341.333v384h-85.333v-640h85.333v128h768v-128h85.333v384c0 94.293-76.373 170.667-170.667 170.667z" /> -<glyph unicode="" d="M391.253 241.92c66.56-66.56 174.72-66.56 241.28 0s66.56 174.72 0 241.28l-241.28-241.28zM768 874.24l-512 0.427c-47.147 0-85.333-38.187-85.333-85.333v-682.667c0-47.147 38.187-85.333 85.333-85.333h512c47.147 0 85.333 38.187 85.333 85.333v682.667c0 47.147-38.187 84.907-85.333 84.907zM426.667 789.333c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM298.667 789.333c23.467 0 42.667-19.2 42.667-42.667s-19.2-42.667-42.667-42.667-42.667 19.2-42.667 42.667 19.2 42.667 42.667 42.667zM512 106.667c-141.44 0-256 114.56-256 256s114.56 256 256 256 256-114.56 256-256-114.56-256-256-256z" /> -<glyph unicode="" d="M512 467.413c-100.907 93.653-235.52 151.253-384 151.253v-469.333c148.48 0 283.093-57.6 384-151.253 100.907 93.653 235.52 151.253 384 151.253v469.333c-148.48 0-283.093-57.6-384-151.253zM512 618.667c70.613 0 128 57.387 128 128s-57.387 128-128 128-128-57.387-128-128 57.387-128 128-128z" /> -<glyph unicode="" d="M810.667 704h-85.333c0 117.76-95.573 213.333-213.333 213.333s-213.333-95.573-213.333-213.333h-85.333c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM512 832c70.613 0 128-57.387 128-128h-256c0 70.613 57.387 128 128 128zM512 405.333c-117.76 0-213.333 95.573-213.333 213.333h85.333c0-70.613 57.387-128 128-128s128 57.387 128 128h85.333c0-117.76-95.573-213.333-213.333-213.333z" /> -<glyph unicode="" d="M768 832v-85.333h-85.333v85.333h-341.333v-85.333h-85.333v85.333h-85.333v-768h85.333v85.333h85.333v-85.333h341.333v85.333h85.333v-85.333h85.333v768h-85.333zM341.333 234.667h-85.333v85.333h85.333v-85.333zM341.333 405.333h-85.333v85.333h85.333v-85.333zM341.333 576h-85.333v85.333h85.333v-85.333zM768 234.667h-85.333v85.333h85.333v-85.333zM768 405.333h-85.333v85.333h85.333v-85.333zM768 576h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M913.493 465.92l-383.787 383.787c-15.573 15.36-36.907 24.96-60.373 24.96h-298.667c-47.147 0-85.333-38.187-85.333-85.333v-298.667c0-23.68 9.6-45.013 25.173-60.373l384-384c15.36-15.36 36.693-24.96 60.16-24.96s45.013 9.6 60.373 24.96l298.667 298.667c15.36 15.573 24.96 36.907 24.96 60.373 0 23.68-9.6 45.013-25.173 60.587zM234.667 661.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M554.667 832h-298.667v-768h170.667v256h128c141.44 0 256 114.56 256 256s-114.56 256-256 256zM563.2 490.667h-136.533v170.667h136.533c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M896 746.667h-112.853l48.853 134.187-100.267 36.48-62.080-170.667h-541.653v-85.333l85.333-256-85.333-256v-85.333h768v85.333l-85.333 256 85.333 256v85.333zM682.667 362.667h-128v-128h-85.333v128h-128v85.333h128v128h85.333v-128h128v-85.333z" /> -<glyph unicode="" d="M282.667 499.413c61.44-120.747 160.213-219.52 281.173-280.96l93.867 94.080c11.733 11.733 28.587 15.147 43.307 10.453 47.787-15.787 99.2-24.32 152.32-24.32 23.68 0 42.667-18.987 42.667-42.667v-149.333c0-23.68-18.987-42.667-42.667-42.667-400.64 0-725.333 324.693-725.333 725.333 0 23.68 19.2 42.667 42.667 42.667h149.333c23.68 0 42.667-18.987 42.667-42.667 0-53.12 8.533-104.533 24.32-152.32 4.693-14.72 1.28-31.573-10.453-43.307l-93.867-94.293z" /> -<glyph unicode="" d="M512 874.667c-152.107 0-289.067-65.92-383.573-170.667l383.573-682.667 383.787 682.453c-94.507 104.96-231.467 170.88-383.787 170.88zM298.667 661.333c0 47.147 38.187 85.333 85.333 85.333s85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333zM512 320c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M853.333 448c0 47.147 38.187 85.333 85.333 85.333v170.667c0 47.147-38.187 85.333-85.333 85.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.213-170.667c47.147-0.213 85.12-38.4 85.12-85.333 0-47.147-38.187-85.333-85.12-85.333l-0.213-170.667c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v170.667c-47.147 0-85.333 38.187-85.333 85.333zM664.747 243.2l-152.747 98.133-152.747-98.133 46.080 175.573-140.373 114.773 181.12 10.667 65.92 168.32 65.92-168.32 181.12-10.667-140.373-114.773 46.080-175.573z" /> -<glyph unicode="" d="M853.333 789.333h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM853.333 618.667l-341.333-213.333-341.333 213.333v85.333l341.333-213.333 341.333 213.333v-85.333z" /> -<glyph unicode="" d="M810.667 618.667h-597.333c-70.613 0-128-57.387-128-128v-256h170.667v-170.667h512v170.667h170.667v256c0 70.613-57.387 128-128 128zM682.667 149.333h-341.333v213.333h341.333v-213.333zM810.667 448c-23.68 0-42.667 18.987-42.667 42.667s18.987 42.667 42.667 42.667c23.68 0 42.667-18.987 42.667-42.667s-18.987-42.667-42.667-42.667zM768 832h-512v-170.667h512v170.667z" /> -<glyph unicode="" d="M345.6 390.613l120.747 120.747-299.307 299.307c-66.56-66.56-66.56-174.72 0-241.28l178.56-178.773zM635.093 468.053c65.067-30.507 157.013-8.96 224.853 58.88 81.707 81.707 97.28 198.4 34.773 260.907-62.72 62.507-179.627 46.933-261.12-34.773-67.84-67.84-89.173-159.787-58.88-224.853-94.933-94.72-416.64-416.427-416.64-416.427l60.373-60.373 293.547 293.547 293.547-293.547 60.373 60.373-293.547 293.547 62.72 62.72z" /> -<glyph unicode="" d="M648.533 448c0-75.405-61.128-136.533-136.533-136.533s-136.533 61.128-136.533 136.533c0 75.405 61.128 136.533 136.533 136.533s136.533-61.128 136.533-136.533zM384 874.667l-78.080-85.333h-135.253c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333h-135.253l-78.080 85.333h-256zM512 234.667c-117.76 0-213.333 95.573-213.333 213.333s95.573 213.333 213.333 213.333 213.333-95.573 213.333-213.333-95.573-213.333-213.333-213.333z" /> -<glyph unicode="" d="M853.333 618.667h-128v170.667h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-469.333h85.333c0-70.613 57.387-128 128-128s128 57.387 128 128h256c0-70.613 57.387-128 128-128s128 57.387 128 128h85.333v213.333l-128 170.667zM256 170.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM832 554.667l83.84-106.667h-190.507v106.667h106.667zM768 170.667c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M807.253 703.573c-8.747 25.173-32.64 43.093-60.587 43.093h-106.667v85.333h-256v-85.333h-106.667c-27.947 0-51.84-17.92-60.587-43.093l-88.747-255.573v-341.333c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v42.667h512v-42.667c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v341.333l-88.747 255.573zM277.333 277.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 277.333c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM213.333 490.667l64 192h469.333l64-192h-597.333z" /> -<glyph unicode="" d="M810.667 874.667h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h170.667l128-128 128 128h170.667c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM512 733.867c63.573 0 115.2-51.627 115.2-115.2s-51.627-115.2-115.2-115.2c-63.573 0-115.2 51.627-115.2 115.2s51.627 115.2 115.2 115.2zM768 277.333h-512v38.4c0 85.333 170.667 132.267 256 132.267s256-46.933 256-132.267v-38.4z" /> -<glyph unicode="" d="M874.667 832c-2.347 0-4.48-0.213-6.613-1.067l-228.053-88.533-256 89.6-240.427-81.067c-8.96-2.987-15.573-10.667-15.573-20.48v-645.12c0-11.733 9.6-21.333 21.333-21.333 2.347 0 4.48 0.213 6.613 1.067l228.053 88.533 256-89.6 240.64 80.853c8.96 3.2 15.36 10.88 15.36 20.693v645.12c0 11.733-9.6 21.333-21.333 21.333zM640 149.333l-256 89.813v507.52l256-89.813v-507.52z" /> -<glyph unicode="" d="M512 618.667c-94.293 0-170.667-76.373-170.667-170.667s76.373-170.667 170.667-170.667 170.667 76.373 170.667 170.667-76.373 170.667-170.667 170.667zM893.44 490.667c-19.627 177.92-160.853 319.147-338.773 338.773v87.893h-85.333v-87.893c-177.92-19.627-319.147-160.853-338.773-338.773h-87.893v-85.333h87.893c19.627-177.92 160.853-319.147 338.773-338.773v-87.893h85.333v87.893c177.92 19.627 319.147 160.853 338.773 338.773h87.893v85.333h-87.893zM512 149.333c-164.907 0-298.667 133.76-298.667 298.667s133.76 298.667 298.667 298.667 298.667-133.76 298.667-298.667-133.76-298.667-298.667-298.667z" /> -<glyph unicode="" d="M512 874.667l-320-780.587 30.080-30.080 289.92 128 289.92-128 30.080 30.080z" /> -<glyph unicode="" d="M768 618.667c0 141.44-114.56 256-256 256s-256-114.56-256-256c0-192 256-469.333 256-469.333s256 277.333 256 469.333zM426.667 618.667c0 47.147 38.187 85.333 85.333 85.333s85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333zM213.333 106.667v-85.333h597.333v85.333h-597.333z" /> -<glyph unicode="" d="M512 874.667c-164.907 0-298.667-133.76-298.667-298.667 0-224 298.667-554.667 298.667-554.667s298.667 330.667 298.667 554.667c0 164.907-133.76 298.667-298.667 298.667zM512 469.333c-58.88 0-106.667 47.787-106.667 106.667s47.787 106.667 106.667 106.667 106.667-47.787 106.667-106.667-47.787-106.667-106.667-106.667z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM256 362.667v105.6l293.547 293.547c8.32 8.32 21.76 8.32 30.080 0l75.52-75.52c8.32-8.32 8.32-21.76 0-30.080l-293.547-293.547h-105.6zM768 362.667h-320l85.333 85.333h234.667v-85.333z" /> -<glyph unicode="" d="M345.6 390.613l120.747 120.747-299.307 299.307c-66.56-66.56-66.56-174.72 0-241.28l178.56-178.773zM635.093 468.053c65.067-30.507 157.013-8.96 224.853 58.88 81.707 81.707 97.28 198.4 34.773 260.907-62.72 62.507-179.627 46.933-261.12-34.773-67.84-67.84-89.173-159.787-58.88-224.853-94.933-94.72-416.64-416.427-416.64-416.427l60.373-60.373 293.547 293.547 293.547-293.547 60.373 60.373-293.547 293.547 62.72 62.72z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM213.333 747.093h128c0-70.613-57.387-128.427-128-128.427v128.427zM213.333 448v85.333c117.76 0 213.333 96 213.333 213.76h85.333c0-164.907-133.76-299.093-298.667-299.093zM213.333 192l149.333 192 106.667-128.213 149.333 192.213 192-256h-597.333z" /> -<glyph unicode="" d="M853.333 789.333h-682.667v-85.333h682.667v85.333zM896 362.667v85.333l-42.667 213.333h-682.667l-42.667-213.333v-85.333h42.667v-256h426.667v256h170.667v-256h85.333v256h42.667zM512 192h-256v170.667h256v-170.667z" /> -<glyph unicode="" d="M597.333 704l-160-213.333 121.6-162.133-68.267-51.2c-72.107 96-192 256-192 256l-256-341.333h938.667l-384 512z" /> -<glyph unicode="" d="M853.333 533.333h-128v48.64c73.6 18.987 128 85.12 128 164.693h-128v42.667c0 23.467-18.987 42.667-42.667 42.667h-341.333c-23.467 0-42.667-19.2-42.667-42.667v-42.667h-128c0-79.36 54.613-145.707 128-164.693v-48.64h-128c0-79.36 54.613-145.707 128-164.693v-48.64h-128c0-79.36 54.613-145.707 128-164.693v-48.64c0-23.467 19.2-42.667 42.667-42.667h341.333c23.68 0 42.667 19.2 42.667 42.667v48.64c73.6 18.987 128 85.12 128 164.693h-128v48.64c73.6 18.987 128 85.333 128 164.693zM512 149.333c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM512 362.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333zM512 576c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M170.667 618.667h170.667v170.667h-170.667v-170.667zM426.667 106.667h170.667v170.667h-170.667v-170.667zM170.667 106.667h170.667v170.667h-170.667v-170.667zM170.667 362.667h170.667v170.667h-170.667v-170.667zM426.667 362.667h170.667v170.667h-170.667v-170.667zM682.667 789.333v-170.667h170.667v170.667h-170.667zM426.667 618.667h170.667v170.667h-170.667v-170.667zM682.667 362.667h170.667v170.667h-170.667v-170.667zM682.667 106.667h170.667v170.667h-170.667v-170.667z" /> -<glyph unicode="" d="M853.333 490.667h-519.253l238.293 238.293-60.373 60.373-341.333-341.333 341.333-341.333 60.373 60.373-238.293 238.293h519.253v85.333z" /> -<glyph unicode="" d="M298.667 533.333l213.333-213.333 213.333 213.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 362.667l-170.667 170.667h341.333l-170.667-170.667z" /> -<glyph unicode="" d="M298.667 362.667l213.333 213.333 213.333-213.333z" /> -<glyph unicode="" d="M512 789.333l-60.373-60.373 238.293-238.293h-519.253v-85.333h519.253l-238.293-238.293 60.373-60.373 341.333 341.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM725.333 295.040l-60.373-60.373-152.96 152.96-152.96-152.96-60.373 60.373 152.96 152.96-152.96 152.96 60.373 60.373 152.96-152.96 152.96 152.96 60.373-60.373-152.96-152.96 152.96-152.96z" /> -<glyph unicode="" d="M384 270.080l-177.92 177.92-60.373-60.373 238.293-238.293 512 512-60.373 60.373z" /> -<glyph unicode="" d="M657.707 643.627l-60.373 60.373-256-256 256-256 60.373 60.373-195.627 195.627z" /> -<glyph unicode="" d="M426.667 704l-60.373-60.373 195.627-195.627-195.627-195.627 60.373-60.373 256 256z" /> -<glyph unicode="" d="M810.667 686.293l-60.373 60.373-238.293-238.293-238.293 238.293-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 238.293 238.293 238.293-238.293 60.373 60.373-238.293 238.293z" /> -<glyph unicode="" d="M512 618.667l-256-256 60.373-60.373 195.627 195.627 195.627-195.627 60.373 60.373z" /> -<glyph unicode="" d="M707.627 593.707l-195.627-195.627-195.627 195.627-60.373-60.373 256-256 256 256z" /> -<glyph unicode="" d="M298.667 362.667h-85.333v-213.333h213.333v85.333h-128v128zM213.333 533.333h85.333v128h128v85.333h-213.333v-213.333zM725.333 234.667h-128v-85.333h213.333v213.333h-85.333v-128zM597.333 746.667v-85.333h128v-128h85.333v213.333h-213.333z" /> -<glyph unicode="" d="M213.333 277.333h128v-128h85.333v213.333h-213.333v-85.333zM341.333 618.667h-128v-85.333h213.333v213.333h-85.333v-128zM597.333 149.333h85.333v128h128v85.333h-213.333v-213.333zM682.667 618.667v128h-85.333v-213.333h213.333v85.333h-128z" /> -<glyph unicode="" d="M128 192h768v85.333h-768v-85.333zM128 405.333h768v85.333h-768v-85.333zM128 704v-85.333h768v85.333h-768z" /> -<glyph unicode="" d="M256 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM768 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM512 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M512 618.667c47.147 0 85.333 38.187 85.333 85.333s-38.187 85.333-85.333 85.333-85.333-38.187-85.333-85.333 38.187-85.333 85.333-85.333zM512 533.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333zM512 277.333c-47.147 0-85.333-38.187-85.333-85.333s38.187-85.333 85.333-85.333 85.333 38.187 85.333 85.333-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M753.067 689.067c-61.653 61.867-146.773 100.267-241.067 100.267-188.587 0-340.907-152.747-340.907-341.333s152.32-341.333 340.907-341.333c158.933 0 292.053 108.8 329.813 256h-88.747c-35.2-99.413-129.493-170.667-241.067-170.667-141.44 0-256 114.56-256 256s114.56 256 256 256c70.613 0 133.973-29.44 180.267-75.733l-137.6-137.6h298.667v298.667l-100.267-100.267z" /> -<glyph unicode="" d="M316.373 167.040l60.373-60.373 135.253 135.253 135.253-135.253 60.373 60.373-195.627 195.627-195.627-195.627zM707.627 728.96l-60.373 60.373-135.253-135.253-135.253 135.253-60.373-60.373 195.627-195.627 195.627 195.627z" /> -<glyph unicode="" d="M512 711.253l135.253-135.253 60.373 60.373-195.627 195.627-195.627-195.627 60.373-60.373 135.253 135.253zM512 184.747l-135.253 135.253-60.373-60.373 195.627-195.627 195.627 195.627-60.373 60.373-135.253-135.253z" /> -<glyph unicode="" d="M213.333 277.333c0-164.907 133.76-298.667 298.667-298.667s298.667 133.76 298.667 298.667v170.667h-597.333v-170.667zM688 773.547l89.6 89.6-35.2 35.2-98.347-98.347c-40.107 19.84-84.48 32-132.053 32s-91.947-12.16-132.053-32l-98.347 98.347-35.2-35.2 89.6-89.6c-74.027-54.187-122.667-141.227-122.667-240.213v-42.667h597.333v42.667c0 98.987-48.64 186.027-122.667 240.213zM384 576c-23.68 0-42.667 19.2-42.667 42.667s18.987 42.667 42.667 42.667c23.68 0 42.667-19.2 42.667-42.667s-18.987-42.667-42.667-42.667zM640 576c-23.68 0-42.667 19.2-42.667 42.667s18.987 42.667 42.667 42.667c23.68 0 42.667-19.2 42.667-42.667s-18.987-42.667-42.667-42.667z" /> -<glyph unicode="" d="M607.573 447.573l98.987-98.987c11.947 30.933 18.773 64.427 18.773 99.413 0 34.773-6.613 68.053-18.347 98.773l-99.413-99.2zM833.28 673.493l-53.973-53.973c26.667-51.413 42.027-109.653 42.027-171.733s-15.36-120.107-42.027-171.733l51.2-51.2c41.173 66.133 65.493 143.573 65.493 226.773 0 81.493-23.253 157.227-62.72 221.867zM670.080 631.253l-243.413 243.413h-42.667v-323.627l-195.627 195.627-60.373-60.373 238.293-238.293-238.293-238.293 60.373-60.373 195.627 195.627v-323.627h42.667l243.413 243.413-183.040 183.253 183.040 183.253zM469.333 711.253l80.213-80.213-80.213-80v160.213zM549.547 264.747l-80.213-80v160.427l80.213-80.427z" /> -<glyph unicode="" d="M853.333 277.333h85.333v85.333h-85.333v-85.333zM853.333 661.333v-213.333h85.333v213.333h-85.333zM426.667 789.333c-188.587 0-341.333-152.747-341.333-341.333s152.747-341.333 341.333-341.333 341.333 152.747 341.333 341.333-152.747 341.333-341.333 341.333zM426.667 362.667c-47.147 0-85.333 38.187-85.333 85.333s38.187 85.333 85.333 85.333 85.333-38.187 85.333-85.333-38.187-85.333-85.333-85.333z" /> -<glyph unicode="" d="M512 874.667c-234.667 0-426.667-192-426.667-426.667s192-426.667 426.667-426.667 426.667 192 426.667 426.667-192 426.667-426.667 426.667zM170.667 448c0 187.733 153.6 341.333 341.333 341.333 78.933 0 151.467-27.733 209.067-72.533l-477.867-477.867c-44.8 57.6-72.533 130.133-72.533 209.067zM512 106.667c-78.933 0-151.467 27.733-209.067 72.533l477.867 477.867c44.8-57.6 72.533-130.133 72.533-209.067 0-187.733-153.6-341.333-341.333-341.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333 0 78.933 27.093 151.253 71.893 209.067l478.507-478.507c-57.813-44.8-130.133-71.893-209.067-71.893zM781.44 238.933l-478.507 478.507c57.813 44.8 130.133 71.893 209.067 71.893 188.587 0 341.333-152.747 341.333-341.333 0-78.933-27.093-151.253-71.893-209.067z" /> -<glyph unicode="" d="M807.253 746.24c-8.747 25.173-32.64 43.093-60.587 43.093h-469.333c-27.947 0-51.84-17.92-60.587-43.093l-88.747-255.573v-341.333c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v42.667h512v-42.667c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v341.333l-88.747 255.573zM277.333 320c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 320c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM213.333 533.333l64 192h469.333l64-192h-597.333z" /> -<glyph unicode="" d="M705.28 488.107l-45.227 45.227-208.213-208.213-90.453 90.453-45.227-45.227 135.68-135.68 253.44 253.44zM810.667 832h-42.667v85.333h-85.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v469.333h597.333v-469.333z" /> -<glyph unicode="" d="M397.227 234.667l104.107 104.107 104.107-104.107 45.227 45.227-104.107 104.107 104.107 104.107-45.227 45.227-104.107-104.107-104.107 104.107-45.227-45.227 104.107-104.107-104.107-104.107 45.227-45.227zM810.667 832h-42.667v85.333h-85.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v469.333h597.333v-469.333z" /> -<glyph unicode="" d="M725.333 533.333h-426.667v-85.333h426.667v85.333zM810.667 832h-42.667v85.333h-85.333v-85.333h-341.333v85.333h-85.333v-85.333h-42.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM810.667 149.333h-597.333v469.333h597.333v-469.333zM597.333 362.667h-298.667v-85.333h298.667v85.333z" /> -<glyph unicode="" d="M853.333 704h-341.333l-85.333 85.333h-256c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v426.667c0 47.147-38.187 85.333-85.333 85.333zM579.413 192l-152.747 89.387-152.747-89.387 40.32 173.653-134.827 116.693 177.707 15.36 69.547 163.627 69.333-163.627 177.707-15.36-134.827-116.693 40.533-173.653z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM213.333 362.667l149.333 192 106.667-128.213 149.333 192.213 192-256h-597.333z" /> -<glyph unicode="" d="M938.667 832h-640c-29.44 0-52.693-14.933-68.053-37.547l-230.613-346.24 230.613-346.24c15.36-22.613 41.387-37.973 70.827-37.973h637.227c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM384 384c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM597.333 384c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM810.667 384c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64z" /> -<glyph unicode="" d="M832 533.333c7.253 0 14.293-1.28 21.333-2.133v386.133l-810.667-810.667h554.667v128c0 37.76 16.427 71.893 42.667 95.36v11.307c0 105.813 86.187 192 192 192zM938.667 277.333v64c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667v-64c-23.467 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 19.2-42.667 42.667-42.667h213.333c23.467 0 42.667 19.2 42.667 42.667v170.667c0 23.467-19.2 42.667-42.667 42.667zM896 277.333h-128v64c0 35.413 28.587 64 64 64s64-28.587 64-64v-64z" /> -<glyph unicode="" d="M627.413 554.667l97.92 97.92v-161.92h21.333l121.813 121.813-91.733 91.52 91.52 91.52-121.6 121.813h-21.333v-161.92l-97.92 97.92-30.080-30.080 119.253-119.253-119.253-119.253 30.080-30.080zM768 835.627l40.107-40.107-40.107-40.107v80.213zM768 652.587l40.107-40.107-40.107-40.107v80.213zM853.333 298.667c-53.12 0-104.32 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.68 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667z" /> -<glyph unicode="" d="M768 490.667l213.333 213.333-213.333 213.333v-128h-170.667v-170.667h170.667v-128zM853.333 298.667c-53.12 0-104.32 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48.213-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.68 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667z" /> -<glyph unicode="" d="M853.333 298.667c-53.12 0-104.32 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.68 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667zM810.667 448h85.333c0 212.053-171.947 384-384 384v-85.333c164.907 0 298.667-133.76 298.667-298.667zM640 448h85.333c0 117.76-95.573 213.333-213.333 213.333v-85.333c70.613 0 128-57.387 128-128z" /> -<glyph unicode="" d="M853.333 298.667c-53.12 0-104.533 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.467 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667zM853.333 789.333v21.333c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667v-21.333c-23.68 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 18.987-42.667 42.667-42.667h213.333c23.68 0 42.667 19.2 42.667 42.667v170.667c0 23.467-18.987 42.667-42.667 42.667zM819.2 789.333h-145.067v21.333c0 40.107 32.427 72.533 72.533 72.533s72.533-32.427 72.533-72.533v-21.333z" /> -<glyph unicode="" d="M277.333 725.333l234.667-234.667 298.667 298.667-42.667 42.667-256-256-192 192h149.333v64h-256v-256h64v149.333zM1011.413 248.747c-129.92 123.52-305.92 199.253-499.413 199.253s-369.493-75.733-499.413-199.253c-7.893-7.893-12.587-18.56-12.587-30.293s4.693-22.4 12.587-30.080l105.6-105.813c7.68-7.68 18.347-12.587 30.293-12.587 11.52 0 22.187 4.693 29.867 12.16 33.707 31.36 72.107 58.027 113.707 79.147 14.080 7.040 23.893 21.547 23.893 38.4v132.48c61.653 19.84 127.573 30.507 196.053 30.507s134.4-10.667 196.267-30.72v-132.48c0-16.853 9.813-31.36 23.893-38.4 41.6-20.907 80-47.573 113.707-79.147 7.68-7.467 18.133-12.16 29.867-12.16s22.4 4.693 30.293 12.587l105.6 105.813c7.68 7.68 12.587 18.347 12.587 30.080s-4.907 22.613-12.8 30.507z" /> -<glyph unicode="" d="M725.333 832h-85.333v-298.667h85.333v298.667zM853.333 298.667c-53.12 0-104.32 8.533-152.32 24.32-14.72 4.693-31.573 1.28-43.307-10.453l-93.867-94.080c-120.96 61.44-219.52 160.213-281.173 280.96l93.867 94.080c11.733 11.733 15.147 28.587 10.453 43.307-15.787 48-24.32 99.413-24.32 152.533 0 23.68-18.987 42.667-42.667 42.667h-149.333c-23.68 0-42.667-18.987-42.667-42.667 0-400.64 324.693-725.333 725.333-725.333 23.68 0 42.667 18.987 42.667 42.667v149.333c0 23.68-18.987 42.667-42.667 42.667zM810.667 832v-298.667h85.333v298.667h-85.333z" /> -<glyph unicode="" d="M853.333 704h-170.667v85.333l-85.333 85.333h-170.667l-85.333-85.333v-85.333h-170.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-469.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM426.667 789.333h170.667v-85.333h-170.667v85.333zM512 149.333l-213.333 213.333h128v170.667h170.667v-170.667h128l-213.333-213.333z" /> -<glyph unicode="" d="M853.333 704h-170.667v85.333l-85.333 85.333h-170.667l-85.333-85.333v-85.333h-170.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-469.333c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v469.333c0 47.147-38.187 85.333-85.333 85.333zM426.667 789.333h170.667v-85.333h-170.667v85.333zM448 213.333l-149.333 149.333 60.373 60.373 88.96-88.96 220.8 220.8 60.373-60.373-281.173-281.173z" /> -<glyph unicode="" d="M768 874.667h-341.333l-255.147-256-0.853-512c0-46.933 38.4-85.333 85.333-85.333h512c46.933 0 85.333 38.4 85.333 85.333v682.667c0 46.933-38.4 85.333-85.333 85.333zM512 618.667h-85.333v170.667h85.333v-170.667zM640 618.667h-85.333v170.667h85.333v-170.667zM768 618.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M768 874.667h-341.333l-254.933-256-1.067-512c0-46.933 38.4-85.333 85.333-85.333h512c46.933 0 85.333 38.4 85.333 85.333v682.667c0 46.933-38.4 85.333-85.333 85.333zM554.667 234.667h-85.333v85.333h85.333v-85.333zM554.667 405.333h-85.333v213.333h85.333v-213.333z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM384 490.667h-85.333v85.333h85.333v-85.333zM554.667 490.667h-85.333v85.333h85.333v-85.333zM725.333 490.667h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM554.667 362.667h-85.333v85.333h85.333v-85.333zM554.667 533.333h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M512 789.333v128l-170.667-170.667 170.667-170.667v128c141.44 0 256-114.56 256-256 0-43.307-10.88-83.84-29.653-119.68l62.293-62.293c33.067 52.907 52.693 114.987 52.693 181.973 0 188.587-152.747 341.333-341.333 341.333zM512 192c-141.44 0-256 114.56-256 256 0 43.307 10.88 83.84 29.653 119.68l-62.293 62.293c-33.067-52.907-52.693-114.987-52.693-181.973 0-188.587 152.747-341.333 341.333-341.333v-128l170.667 170.667-170.667 170.667v-128z" /> -<glyph unicode="" d="M426.667 689.067v89.173c-34.133-8.747-65.92-22.827-95.147-40.96l62.507-62.507c10.453 5.333 21.333 10.453 32.64 14.293zM122.24 729.173l100.48-100.48c-32.853-52.48-52.053-114.133-52.053-180.693 0-94.293 38.613-179.2 100.48-240.853l-100.48-100.48h256v256l-95.36-95.36c-46.507 46.293-75.307 110.080-75.307 180.693 0 42.667 10.667 82.773 29.227 118.187l344.96-344.96c-10.453-5.547-21.333-10.453-32.64-14.507v-88.96c34.133 8.747 65.92 22.827 95.147 40.96l100.693-100.693 54.4 54.4-671.36 671.147-54.187-54.4zM853.333 789.333h-256v-256l95.36 95.36c46.507-46.293 75.307-110.080 75.307-180.693 0-42.667-10.667-82.773-29.227-118.187l62.507-62.507c32.853 52.48 52.053 114.133 52.053 180.693 0 94.293-38.613 179.2-100.48 240.853l100.48 100.48z" /> -<glyph unicode="" d="M128 448c0-94.293 38.827-179.2 100.48-240.853l-100.48-100.48h256v256l-95.36-95.36c-46.507 46.293-75.307 110.080-75.307 180.693 0 111.36 71.253 205.867 170.667 241.067v89.173c-147.2-37.973-256-171.307-256-330.24zM469.333 234.667h85.333v85.333h-85.333v-85.333zM896 789.333h-256v-256l95.36 95.36c46.507-46.293 75.307-110.080 75.307-180.693 0-111.36-71.253-205.867-170.667-241.067v-88.96c147.2 37.76 256 171.093 256 330.027 0 94.293-38.827 179.2-100.48 240.853l100.48 100.48zM469.333 405.333h85.333v256h-85.333v-256z" /> -<glyph unicode="" d="M725.333 916.907l-426.667 0.427c-47.147 0-85.333-38.187-85.333-85.333v-768c0-47.147 38.187-85.333 85.333-85.333h426.667c47.147 0 85.333 38.187 85.333 85.333v768c0 47.147-38.187 84.907-85.333 84.907zM725.333 149.333h-426.667v597.333h426.667v-597.333zM682.667 405.333h-128v213.333h-85.333v-213.333h-128l170.667-170.667 170.667 170.667z" /> -<glyph unicode="" d="M85.333 277.333v-85.333c117.76 0 213.333-95.573 213.333-213.333h85.333c0 164.907-133.76 298.667-298.667 298.667zM85.333 106.667v-128h128c0 70.613-57.387 128-128 128zM85.333 448v-85.333c212.053 0 384-171.947 384-384h85.333c0 259.2-210.133 469.333-469.333 469.333zM725.333 916.907l-426.667 0.427c-47.147 0-85.333-38.187-85.333-85.333v-314.453c29.44-7.040 58.027-15.787 85.333-27.307v256.427h426.667v-554.667h-129.28c22.187-53.12 35.84-110.72 40.533-170.667h88.747c47.147 0 85.333 38.187 85.333 85.333v725.333c0 47.147-38.187 84.907-85.333 84.907z" /> -<glyph unicode="" d="M807.253 746.24c-8.747 25.173-32.64 43.093-60.587 43.093h-469.333c-27.947 0-51.84-17.92-60.587-43.093l-88.747-255.573v-341.333c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v42.667h512v-42.667c0-23.467 19.2-42.667 42.667-42.667h42.667c23.68 0 42.667 19.2 42.667 42.667v341.333l-88.747 255.573zM277.333 320c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM746.667 320c-35.413 0-64 28.587-64 64s28.587 64 64 64 64-28.587 64-64-28.587-64-64-64zM213.333 533.333l64 192h469.333l64-192h-597.333z" /> -<glyph unicode="" d="M0 320h85.333v256h-85.333v-256zM128 234.667h85.333v426.667h-85.333v-426.667zM938.667 576v-256h85.333v256h-85.333zM810.667 234.667h85.333v426.667h-85.333v-426.667zM704 832h-384c-35.413 0-64-28.587-64-64v-640c0-35.413 28.587-64 64-64h384c35.413 0 64 28.587 64 64v640c0 35.413-28.587 64-64 64zM682.667 149.333h-341.333v597.333h341.333v-597.333z" /> -<glyph unicode="" d="M853.333 874.667h-682.667c-47.147 0-84.907-38.187-84.907-85.333l-0.427-768 170.667 170.667h597.333c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM768 362.667l-170.667 136.533v-136.533h-341.333v341.333h341.333v-136.533l170.667 136.533v-341.333z" /> -<glyph unicode="" d="M938.667 789.333v21.333c0 58.88-47.787 106.667-106.667 106.667s-106.667-47.787-106.667-106.667v-21.333c-23.68 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 18.987-42.667 42.667-42.667h213.333c23.68 0 42.667 19.2 42.667 42.667v170.667c0 23.467-18.987 42.667-42.667 42.667zM904.533 789.333h-145.067v21.333c0 40.107 32.427 72.533 72.533 72.533s72.533-32.427 72.533-72.533v-21.333zM807.467 448c1.707-14.080 3.2-28.16 3.2-42.667 0-88.747-34.133-169.387-89.813-230.187-10.88 34.56-42.88 59.52-80.853 59.52h-42.667v128c0 23.467-19.2 42.667-42.667 42.667h-256v85.333h85.333c23.467 0 42.667 19.2 42.667 42.667v85.333h85.333c47.147 0 85.333 38.187 85.333 85.333v108.373c-40.32 12.8-83.413 19.627-128 19.627-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667c0 14.507-0.853 28.587-2.133 42.667h-86.4zM426.667 66.987c-168.32 20.907-298.667 164.267-298.667 338.347 0 26.24 3.2 51.84 8.96 76.373l204.373-204.373v-42.667c0-47.147 38.187-85.333 85.333-85.333v-82.347z" /> -<glyph unicode="" d="M512 661.333c47.147 0 85.333 38.187 85.333 85.333 0 16-4.48 31.147-12.16 43.947l-73.173 126.72-73.173-126.72c-7.68-12.8-12.16-27.947-12.16-43.947 0-47.147 38.187-85.333 85.333-85.333zM896 64v170.667c0 47.147-38.187 85.333-85.333 85.333h-42.667v128c0 47.147-38.187 85.333-85.333 85.333h-128v85.333h-85.333v-85.333h-128c-47.147 0-85.333-38.187-85.333-85.333v-128h-42.667c-47.147 0-85.333-38.187-85.333-85.333v-170.667h-85.333v-85.333h938.667v85.333h-85.333z" /> -<glyph unicode="" d="M512 661.333v170.667h-426.667v-768h853.333v597.333h-426.667zM256 149.333h-85.333v85.333h85.333v-85.333zM256 320h-85.333v85.333h85.333v-85.333zM256 490.667h-85.333v85.333h85.333v-85.333zM256 661.333h-85.333v85.333h85.333v-85.333zM426.667 149.333h-85.333v85.333h85.333v-85.333zM426.667 320h-85.333v85.333h85.333v-85.333zM426.667 490.667h-85.333v85.333h85.333v-85.333zM426.667 661.333h-85.333v85.333h85.333v-85.333zM853.333 149.333h-341.333v85.333h85.333v85.333h-85.333v85.333h85.333v85.333h-85.333v85.333h341.333v-426.667zM768 490.667h-85.333v-85.333h85.333v85.333zM768 320h-85.333v-85.333h85.333v85.333z" /> -<glyph unicode="" d="M682.667 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-70.613 0-128-57.387-128-128s57.387-128 128-128zM341.333 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-70.613 0-128-57.387-128-128s57.387-128 128-128zM341.333 405.333c-99.627 0-298.667-49.92-298.667-149.333v-106.667h597.333v106.667c0 99.413-199.040 149.333-298.667 149.333zM682.667 405.333c-12.373 0-26.24-0.853-41.173-2.347 49.493-35.627 83.84-83.627 83.84-146.987v-106.667h256v106.667c0 99.413-199.040 149.333-298.667 149.333z" /> -<glyph unicode="" d="M341.333 533.333h-128v128h-85.333v-128h-128v-85.333h128v-128h85.333v128h128v85.333zM768 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-13.653 0-26.667-2.133-39.040-6.187 24.107-34.56 38.613-76.587 38.613-121.813s-14.507-87.253-38.613-121.813c12.373-4.053 25.387-6.187 39.040-6.187zM554.667 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-70.613 0-128-57.387-128-128s57.387-128 128-128zM837.12 398.507c35.413-30.933 58.88-70.827 58.88-121.173v-85.333h128v85.333c0 65.707-101.333 106.027-186.88 121.173zM554.667 405.333c-85.333 0-256-42.667-256-128v-85.333h512v85.333c0 85.333-170.667 128-256 128z" /> -<glyph unicode="" d="M640 490.667v256l-128 128-128-128v-85.333h-256v-597.333h768v426.667h-256zM298.667 149.333h-85.333v85.333h85.333v-85.333zM298.667 320h-85.333v85.333h85.333v-85.333zM298.667 490.667h-85.333v85.333h85.333v-85.333zM554.667 149.333h-85.333v85.333h85.333v-85.333zM554.667 320h-85.333v85.333h85.333v-85.333zM554.667 490.667h-85.333v85.333h85.333v-85.333zM554.667 661.333h-85.333v85.333h85.333v-85.333zM810.667 149.333h-85.333v85.333h85.333v-85.333zM810.667 320h-85.333v85.333h85.333v-85.333z" /> -<glyph unicode="" d="M511.787 874.667c-235.733 0-426.453-190.933-426.453-426.667s190.72-426.667 426.453-426.667c235.733 0 426.88 190.933 426.88 426.667s-191.147 426.667-426.88 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333zM661.333 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM362.667 490.667c35.413 0 64 28.587 64 64s-28.587 64-64 64-64-28.587-64-64 28.587-64 64-64zM512 213.333c99.413 0 183.68 62.080 217.813 149.333h-435.627c34.133-87.253 118.4-149.333 217.813-149.333z" /> -<glyph unicode="" d="M490.667 21.333c47.147 0 85.333 38.187 85.333 85.333h-170.667c0-47.147 38.187-85.333 85.333-85.333zM768 277.333v234.667c0 131.2-91.093 240.64-213.333 269.653v29.013c0 35.413-28.587 64-64 64s-64-28.587-64-64v-29.013c-122.24-29.013-213.333-138.453-213.333-269.653v-234.667l-85.333-85.333v-42.667h725.333v42.667l-85.333 85.333z" /> -<glyph unicode="" d="M490.667 21.333c47.147 0 85.333 38.187 85.333 85.333h-170.667c0-47.147 38.187-85.333 85.333-85.333zM768 277.333v234.667c0 131.2-91.093 240.64-213.333 269.653v29.013c0 35.413-28.587 64-64 64s-64-28.587-64-64v-29.013c-122.24-29.013-213.333-138.453-213.333-269.653v-234.667l-85.333-85.333v-42.667h725.333v42.667l-85.333 85.333zM682.667 234.667h-384v277.333c0 106.027 85.973 192 192 192s192-85.973 192-192v-277.333z" /> -<glyph unicode="" d="M490.667 21.333c47.147 0 85.333 38.187 85.333 85.333h-170.667c0-47.147 38.187-85.333 85.333-85.333zM768 512c0 131.2-91.093 240.64-213.333 269.653v29.013c0 35.413-28.587 64-64 64s-64-28.587-64-64v-29.013c-21.76-5.12-42.24-13.653-61.653-23.68l402.987-402.987v157.013zM756.48 149.333l85.333-85.333 54.187 54.4-713.6 713.6-54.4-54.4 124.587-124.587c-24.747-41.173-39.253-89.387-39.253-141.013v-234.667l-85.333-85.333v-42.667h628.48z" /> -<glyph unicode="" d="M280.747 807.253l-61.013 61.013c-102.187-77.867-169.6-198.187-176-334.933h85.333c6.613 113.067 64.853 212.053 151.68 273.92zM852.267 533.333h85.333c-6.4 136.747-73.813 257.067-176 334.933l-60.8-60.8c86.613-62.080 144.853-161.067 151.467-274.133zM768 512c0 131.2-91.093 240.64-213.333 269.653v29.013c0 35.413-28.587 64-64 64s-64-28.587-64-64v-29.013c-122.24-29.013-213.333-138.453-213.333-269.653v-234.667l-85.333-85.333v-42.667h725.333v42.667l-85.333 85.333v234.667zM490.667 21.333c5.973 0 11.733 0.64 17.28 1.707 27.733 5.76 50.56 24.96 61.44 50.347 4.267 10.24 6.613 21.333 6.613 33.28h-170.667c0-47.147 38.187-85.333 85.333-85.333z" /> -<glyph unicode="" d="M490.667 21.333c47.147 0 85.333 38.187 85.333 85.333h-170.667c0-47.147 38.187-85.333 85.333-85.333zM768 277.333v234.667c0 131.2-91.093 240.64-213.333 269.653v29.013c0 35.413-28.587 64-64 64s-64-28.587-64-64v-29.013c-122.24-29.013-213.333-138.453-213.333-269.653v-234.667l-85.333-85.333v-42.667h725.333v42.667l-85.333 85.333zM597.333 541.867l-119.467-145.067h119.467v-76.8h-213.333v76.8l119.467 145.067h-119.467v76.8h213.333v-76.8z" /> -<glyph unicode="" d="M128 746.667v-256h213.333l-42.667 170.667 170.667-42.667v213.333h-256c-47.147 0-85.333-38.187-85.333-85.333zM341.333 405.333h-213.333v-256c0-47.147 38.187-85.333 85.333-85.333h256v213.333l-170.667-42.667 42.667 170.667zM725.333 234.667l-170.667 42.667v-213.333h256c47.147 0 85.333 38.187 85.333 85.333v256h-213.333l42.667-170.667zM810.667 832h-256v-213.333l170.667 42.667-42.667-170.667h213.333v256c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M853.333 789.333h-135.253l-78.080 85.333h-256l-78.080-85.333h-135.253c-47.147 0-85.333-38.187-85.333-85.333v-512c0-47.147 38.187-85.333 85.333-85.333h682.667c47.147 0 85.333 38.187 85.333 85.333v512c0 47.147-38.187 85.333-85.333 85.333zM512 661.333c69.547 0 130.773-33.92 169.813-85.333h-169.813c-70.613 0-128-57.387-128-128 0-15.147 2.987-29.227 7.893-42.667h-88.96c-2.773 13.867-4.267 27.947-4.267 42.667 0 117.76 95.573 213.333 213.333 213.333zM512 234.667c-69.547 0-130.773 33.707-169.6 85.333h169.6c70.613 0 128 57.387 128 128 0 14.933-2.987 29.227-7.893 42.667h88.96c2.773-13.867 4.267-27.947 4.267-42.667 0-117.76-95.573-213.333-213.333-213.333z" /> -<glyph unicode="" d="M682.667 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-70.613 0-128-57.387-128-128s57.387-128 128-128zM341.333 490.667c70.613 0 127.573 57.387 127.573 128s-56.96 128-127.573 128c-70.613 0-128-57.387-128-128s57.387-128 128-128zM341.333 405.333c-99.627 0-298.667-49.92-298.667-149.333v-106.667h597.333v106.667c0 99.413-199.040 149.333-298.667 149.333zM682.667 405.333c-12.373 0-26.24-0.853-41.173-2.347 49.493-35.627 83.84-83.627 83.84-146.987v-106.667h256v106.667c0 99.413-199.040 149.333-298.667 149.333z" /> -<glyph unicode="" d="M704 405.333c-51.413 0-131.2-14.293-192-42.88-60.8 28.587-140.587 42.88-192 42.88-92.373 0-277.333-46.293-277.333-138.667v-117.333h938.667v117.333c0 92.373-184.96 138.667-277.333 138.667zM533.333 213.333h-426.667v53.333c0 22.827 109.227 74.667 213.333 74.667s213.333-51.84 213.333-74.667v-53.333zM917.333 213.333h-320v53.333c0 19.413-8.533 36.693-22.187 52.053 37.76 12.8 83.84 22.613 128.853 22.613 104.107 0 213.333-51.84 213.333-74.667v-53.333zM320 448c82.56 0 149.333 66.987 149.333 149.333s-66.773 149.333-149.333 149.333c-82.347 0-149.333-66.987-149.333-149.333s66.987-149.333 149.333-149.333zM320 682.667c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333 38.187 85.333 85.333 85.333zM704 448c82.56 0 149.333 66.987 149.333 149.333s-66.773 149.333-149.333 149.333c-82.347 0-149.333-66.987-149.333-149.333s66.987-149.333 149.333-149.333zM704 682.667c47.147 0 85.333-38.187 85.333-85.333s-38.187-85.333-85.333-85.333-85.333 38.187-85.333 85.333 38.187 85.333 85.333 85.333z" /> -<glyph unicode="" d="M512 448c94.293 0 170.667 76.587 170.667 170.667 0 94.293-76.373 170.667-170.667 170.667s-170.667-76.373-170.667-170.667c0-94.080 76.373-170.667 170.667-170.667zM512 362.667c-113.707 0-341.333-56.96-341.333-170.667v-85.333h682.667v85.333c0 113.707-227.627 170.667-341.333 170.667z" /> -<glyph unicode="" d="M640 448c94.293 0 170.667 76.587 170.667 170.667 0 94.293-76.373 170.667-170.667 170.667s-170.667-76.373-170.667-170.667c0-94.080 76.373-170.667 170.667-170.667zM256 533.333v128h-85.333v-128h-128v-85.333h128v-128h85.333v128h128v85.333h-128zM640 362.667c-113.707 0-341.333-56.96-341.333-170.667v-85.333h682.667v85.333c0 113.707-227.627 170.667-341.333 170.667z" /> -<glyph unicode="" d="M512 708.267c49.493 0 89.6-40.107 89.6-89.6s-40.107-89.6-89.6-89.6-89.6 40.107-89.6 89.6 40.107 89.6 89.6 89.6zM512 324.267c126.933 0 260.267-62.080 260.267-89.6v-46.933h-520.533v46.933c0 27.52 133.333 89.6 260.267 89.6zM512 789.333c-94.293 0-170.667-76.373-170.667-170.667 0-94.080 76.373-170.667 170.667-170.667s170.667 76.587 170.667 170.667c0 94.293-76.373 170.667-170.667 170.667zM512 405.333c-113.707 0-341.333-56.96-341.333-170.667v-128h682.667v128c0 113.707-227.627 170.667-341.333 170.667z" /> -<glyph unicode="" d="M426.667 618.667h-85.333v-170.667h-170.667v-85.333h170.667v-170.667h85.333v170.667h170.667v85.333h-170.667zM618.667 700.587v-77.653l106.667 21.333v-452.267h85.333v554.667z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM384 234.667h-85.333v298.667h85.333v-298.667zM554.667 234.667h-85.333v426.667h85.333v-426.667zM725.333 234.667h-85.333v170.667h85.333v-170.667z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM469.333 109.653c-168.32 20.907-298.667 164.267-298.667 338.347 0 26.24 3.2 51.84 8.96 76.373l204.373-204.373v-42.667c0-47.147 38.187-85.333 85.333-85.333v-82.347zM763.52 217.813c-10.88 34.56-42.88 59.52-80.853 59.52h-42.667v128c0 23.467-19.2 42.667-42.667 42.667h-256v85.333h85.333c23.467 0 42.667 19.2 42.667 42.667v85.333h85.333c47.147 0 85.333 38.187 85.333 85.333v17.707c125.013-50.56 213.333-173.013 213.333-316.373 0-88.747-34.133-169.387-89.813-230.187z" /> -<glyph unicode="" d="M213.333 397.653v-170.667l298.667-162.987 298.667 162.987v170.667l-298.667-162.987-298.667 162.987zM512 832l-469.333-256 469.333-256 384 209.493v-294.827h85.333v341.333l-469.333 256z" /> -<glyph unicode="" d="M768 273.707c-32.427 0-61.653-12.587-83.84-32.853l-304 177.28c2.347 9.6 3.84 19.627 3.84 29.867s-1.493 20.267-3.84 29.867l300.8 175.573c22.827-21.333 53.333-34.56 87.040-34.56 70.613 0 128 57.387 128 128s-57.387 128-128 128-128-57.387-128-128c0-10.24 1.493-20.267 3.84-29.867l-300.8-175.573c-22.827 21.333-53.333 34.56-87.040 34.56-70.613 0-128-57.387-128-128s57.387-128 128-128c33.707 0 64.213 13.227 87.040 34.56l304-177.28c-2.133-8.96-3.413-18.347-3.413-27.947 0-68.693 55.68-124.373 124.373-124.373s124.373 55.68 124.373 124.373-55.68 124.373-124.373 124.373z" /> -<glyph unicode="" d="M576 931.413s31.573-113.067 31.573-204.8c0-87.893-57.6-159.36-145.707-159.36s-154.667 71.253-154.667 159.36l1.067 15.36c-85.76-102.613-137.6-234.88-137.6-379.307 0-188.587 152.747-341.333 341.333-341.333s341.333 152.747 341.333 341.333c0 230.187-110.72 435.413-277.333 568.747zM499.627 149.333c-75.947 0-137.6 59.947-137.6 133.973 0 69.333 44.587 117.973 120.107 133.12s153.6 51.413 196.907 109.867c16.64-55.040 25.387-113.067 25.387-172.16 0-112.853-91.733-204.8-204.8-204.8z" /> -<glyph unicode="" d="M810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333zM426.667 234.667l-213.333 213.333 60.373 60.373 152.96-152.96 323.627 323.627 60.373-60.373-384-384z" /> -<glyph unicode="" d="M810.667 746.667v-597.333h-597.333v597.333h597.333zM810.667 832h-597.333c-47.147 0-85.333-38.187-85.333-85.333v-597.333c0-47.147 38.187-85.333 85.333-85.333h597.333c47.147 0 85.333 38.187 85.333 85.333v597.333c0 47.147-38.187 85.333-85.333 85.333z" /> -<glyph unicode="" d="M512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333z" /> -<glyph unicode="" d="M512 661.333c-117.76 0-213.333-95.573-213.333-213.333s95.573-213.333 213.333-213.333 213.333 95.573 213.333 213.333-95.573 213.333-213.333 213.333zM512 874.667c-235.733 0-426.667-190.933-426.667-426.667s190.933-426.667 426.667-426.667 426.667 190.933 426.667 426.667-190.933 426.667-426.667 426.667zM512 106.667c-188.587 0-341.333 152.747-341.333 341.333s152.747 341.333 341.333 341.333 341.333-152.747 341.333-341.333-152.747-341.333-341.333-341.333z" /> -</font></defs></svg> diff --git a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.ttf b/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.ttf Binary files differdeleted file mode 100644 index f0c07f7a..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.ttf +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.woff b/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.woff Binary files differdeleted file mode 100644 index e06f547c..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.woff +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.woff2 b/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.woff2 Binary files differdeleted file mode 100644 index ccf4eff7..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/material-design-icons/Material-Design-Icons.woff2 +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.ttf b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.ttf Binary files differdeleted file mode 100644 index 68822caf..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.ttf +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.woff b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.woff Binary files differdeleted file mode 100644 index 1f75afdc..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.woff +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.woff2 b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.woff2 Binary files differdeleted file mode 100644 index 350d1c3a..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Bold.woff2 +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.ttf b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.ttf Binary files differdeleted file mode 100644 index aa453407..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.ttf +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.woff b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.woff Binary files differdeleted file mode 100644 index 3480c6c8..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.woff +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.woff2 b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.woff2 Binary files differdeleted file mode 100644 index 9a4d98c4..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Light.woff2 +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.ttf b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.ttf Binary files differdeleted file mode 100644 index a3c1a1f1..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.ttf +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.woff b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.woff Binary files differdeleted file mode 100644 index 1186773f..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.woff +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.woff2 b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.woff2 Binary files differdeleted file mode 100644 index d10a5926..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Medium.woff2 +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.ttf b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.ttf Binary files differdeleted file mode 100644 index 0e58508a..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.ttf +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.woff b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.woff Binary files differdeleted file mode 100644 index f823258a..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.woff +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.woff2 b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.woff2 Binary files differdeleted file mode 100644 index b7082ef3..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Regular.woff2 +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.ttf b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.ttf Binary files differdeleted file mode 100644 index 8779333b..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.ttf +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.woff b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.woff Binary files differdeleted file mode 100644 index 2a98c1e4..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.woff +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.woff2 b/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.woff2 Binary files differdeleted file mode 100644 index a38025a1..00000000 --- a/plugins/phonegap-plugin-push/example/www/font/roboto/Roboto-Thin.woff2 +++ /dev/null diff --git a/plugins/phonegap-plugin-push/example/www/index.html b/plugins/phonegap-plugin-push/example/www/index.html deleted file mode 100644 index d2a72cb6..00000000 --- a/plugins/phonegap-plugin-push/example/www/index.html +++ /dev/null @@ -1,56 +0,0 @@ -<!DOCTYPE html> -<!-- - 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. ---> -<html> - <head> - <meta charset="utf-8" /> - <meta name="format-detection" content="telephone=no" /> - <meta name="msapplication-tap-highlight" content="no" /> - <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 --> - <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> - <!-- link rel="stylesheet" type="text/css" href="css/index.css" / --> - <link type="text/css" rel="stylesheet" href="css/materialize.min.css" media="screen,projection"/> - <title>Hello World</title> - </head> - <body> - <nav> - <div class="nav-wrapper"> - <a href="#" class="brand-logo">Push Demo</a> - </div> - </nav> - - <div class="row"> - <div class="col s12 m6"> - <div class="card darken-1"> - <div class="card-content black-text"> - <span class="card-title black-text">Registration ID</span> - <p id="regId">Requested</p> - </div> - </div> - </div> - </div> - - <div id="cards"></div> - - <script type="text/javascript" src="cordova.js"></script> - <script type="text/javascript" src="js/jquery-2.1.1.min.js"></script> - <script type="text/javascript" src="js/materialize.min.js"></script> - <script type="text/javascript" src="js/index.js"></script> - </body> -</html> diff --git a/plugins/phonegap-plugin-push/example/www/js/index.js b/plugins/phonegap-plugin-push/example/www/js/index.js deleted file mode 100644 index e8b9ff9b..00000000 --- a/plugins/phonegap-plugin-push/example/www/js/index.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 app = { - // Application Constructor - initialize: function() { - this.bindEvents(); - }, - // Bind Event Listeners - // - // Bind any events that are required on startup. Common events are: - // 'load', 'deviceready', 'offline', and 'online'. - bindEvents: function() { - document.addEventListener('deviceready', this.onDeviceReady, false); - }, - // deviceready Event Handler - // - // The scope of 'this' is the event. In order to call the 'receivedEvent' - // function, we must explicitly call 'app.receivedEvent(...);' - onDeviceReady: function() { - var push = PushNotification.init({ - "android": { - "senderID": "741175631277" - }, - "ios": {"alert": "true", "badge": "true", "sound": "true"}, - "windows": {} - }); - - push.on('registration', function(data) { - console.log("registration event"); - document.getElementById("regId").innerHTML = data.registrationId; - console.log(JSON.stringify(data)); - }); - - push.on('notification', function(data) { - console.log("notification event"); - console.log(JSON.stringify(data)); - var cards = document.getElementById("cards"); - var push = '<div class="row">' + - '<div class="col s12 m6">' + - ' <div class="card darken-1">' + - ' <div class="card-content black-text">' + - ' <span class="card-title black-text">' + data.title + '</span>' + - ' <p>' + data.message + '</p>' + - ' </div>' + - ' </div>' + - ' </div>' + - '</div>'; - cards.innerHTML += push; - }); - - push.on('error', function(e) { - console.log("push error"); - }); - } -}; - -app.initialize();
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/example/www/js/jquery-2.1.1.min.js b/plugins/phonegap-plugin-push/example/www/js/jquery-2.1.1.min.js deleted file mode 100644 index e5ace116..00000000 --- a/plugins/phonegap-plugin-push/example/www/js/jquery-2.1.1.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) -},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b)) -},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=l.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,n.ajaxSettings),b):tc(n.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Dc)Dc[a]()}),k.cors=!!Fc&&"withCredentials"in Fc,k.ajax=Fc=!!Fc,n.ajaxTransport(function(a){var b;return k.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||n.expando+"_"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Ic=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Jc})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Lc=a.jQuery,Mc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Mc),b&&a.jQuery===n&&(a.jQuery=Lc),n},typeof b===U&&(a.jQuery=a.$=n),n}); diff --git a/plugins/phonegap-plugin-push/example/www/js/materialize.min.js b/plugins/phonegap-plugin-push/example/www/js/materialize.min.js deleted file mode 100644 index ed30cdaa..00000000 --- a/plugins/phonegap-plugin-push/example/www/js/materialize.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * Materialize v0.96.1 (http://materializecss.com) - * Copyright 2014-2015 Materialize - * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) - */ -jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(a,b,c,d,e){return jQuery.easing[jQuery.easing.def](a,b,c,d,e)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:(b/=e/2)<1?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){return(b/=e/2)<1?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin(2*(b*e-f)*Math.PI/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(1==(b/=e))return c+d;if(g||(g=.3*e),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin(2*(b*e-f)*Math.PI/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(0==b)return c;if(2==(b/=e/2))return c+d;if(g||(g=.3*e*1.5),h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return 1>b?-.5*h*Math.pow(2,10*(b-=1))*Math.sin(2*(b*e-f)*Math.PI/g)+c:h*Math.pow(2,-10*(b-=1))*Math.sin(2*(b*e-f)*Math.PI/g)*.5+d+c},easeInBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*(b/=e)*b*((f+1)*b-f)+c},easeOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),d*((b=b/e-1)*b*((f+1)*b+f)+1)+c},easeInOutBack:function(a,b,c,d,e,f){return void 0==f&&(f=1.70158),(b/=e/2)<1?d/2*b*b*(((f*=1.525)+1)*b-f)+c:d/2*((b-=2)*b*(((f*=1.525)+1)*b+f)+2)+c},easeInBounce:function(a,b,c,d,e){return d-jQuery.easing.easeOutBounce(a,e-b,0,d,e)+c},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?7.5625*d*b*b+c:2/2.75>b?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:2.5/2.75>b?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(a,b,c,d,e){return e/2>b?.5*jQuery.easing.easeInBounce(a,2*b,0,d,e)+c:.5*jQuery.easing.easeOutBounce(a,2*b-e,0,d,e)+.5*d+c}}),jQuery.extend(jQuery.easing,{easeInOutMaterial:function(a,b,c,d,e){return(b/=e/2)<1?d/2*b*b+c:d/4*((b-=2)*b*b+2)+c}}),!function(a){function b(a){var b=a.length,d=c.type(a);return"function"===d||c.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===d||0===b||"number"==typeof b&&b>0&&b-1 in a}if(!a.jQuery){var c=function(a,b){return new c.fn.init(a,b)};c.isWindow=function(a){return null!=a&&a==a.window},c.type=function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?e[g.call(a)]||"object":typeof a},c.isArray=Array.isArray||function(a){return"array"===c.type(a)},c.isPlainObject=function(a){var b;if(!a||"object"!==c.type(a)||a.nodeType||c.isWindow(a))return!1;try{if(a.constructor&&!f.call(a,"constructor")&&!f.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(d){return!1}for(b in a);return void 0===b||f.call(a,b)},c.each=function(a,c,d){var e,f=0,g=a.length,h=b(a);if(d){if(h)for(;g>f&&(e=c.apply(a[f],d),e!==!1);f++);else for(f in a)if(e=c.apply(a[f],d),e===!1)break}else if(h)for(;g>f&&(e=c.call(a[f],f,a[f]),e!==!1);f++);else for(f in a)if(e=c.call(a[f],f,a[f]),e===!1)break;return a},c.data=function(a,b,e){if(void 0===e){var f=a[c.expando],g=f&&d[f];if(void 0===b)return g;if(g&&b in g)return g[b]}else if(void 0!==b){var f=a[c.expando]||(a[c.expando]=++c.uuid);return d[f]=d[f]||{},d[f][b]=e,e}},c.removeData=function(a,b){var e=a[c.expando],f=e&&d[e];f&&c.each(b,function(a,b){delete f[b]})},c.extend=function(){var a,b,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[i]||{},i++),"object"!=typeof h&&"function"!==c.type(h)&&(h={}),i===j&&(h=this,i--);j>i;i++)if(null!=(f=arguments[i]))for(e in f)a=h[e],d=f[e],h!==d&&(k&&d&&(c.isPlainObject(d)||(b=c.isArray(d)))?(b?(b=!1,g=a&&c.isArray(a)?a:[]):g=a&&c.isPlainObject(a)?a:{},h[e]=c.extend(k,g,d)):void 0!==d&&(h[e]=d));return h},c.queue=function(a,d,e){function f(a,c){var d=c||[];return null!=a&&(b(Object(a))?!function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;)a[e++]=b[d++];if(c!==c)for(;void 0!==b[d];)a[e++]=b[d++];return a.length=e,a}(d,"string"==typeof a?[a]:a):[].push.call(d,a)),d}if(a){d=(d||"fx")+"queue";var g=c.data(a,d);return e?(!g||c.isArray(e)?g=c.data(a,d,f(e)):g.push(e),g):g||[]}},c.dequeue=function(a,b){c.each(a.nodeType?[a]:a,function(a,d){b=b||"fx";var e=c.queue(d,b),f=e.shift();"inprogress"===f&&(f=e.shift()),f&&("fx"===b&&e.unshift("inprogress"),f.call(d,function(){c.dequeue(d,b)}))})},c.fn=c.prototype={init:function(a){if(a.nodeType)return this[0]=a,this;throw new Error("Not a DOM node.")},offset:function(){var b=this[0].getBoundingClientRect?this[0].getBoundingClientRect():{top:0,left:0};return{top:b.top+(a.pageYOffset||document.scrollTop||0)-(document.clientTop||0),left:b.left+(a.pageXOffset||document.scrollLeft||0)-(document.clientLeft||0)}},position:function(){function a(){for(var a=this.offsetParent||document;a&&"html"===!a.nodeType.toLowerCase&&"static"===a.style.position;)a=a.offsetParent;return a||document}var b=this[0],a=a.apply(b),d=this.offset(),e=/^(?:body|html)$/i.test(a.nodeName)?{top:0,left:0}:c(a).offset();return d.top-=parseFloat(b.style.marginTop)||0,d.left-=parseFloat(b.style.marginLeft)||0,a.style&&(e.top+=parseFloat(a.style.borderTopWidth)||0,e.left+=parseFloat(a.style.borderLeftWidth)||0),{top:d.top-e.top,left:d.left-e.left}}};var d={};c.expando="velocity"+(new Date).getTime(),c.uuid=0;for(var e={},f=e.hasOwnProperty,g=e.toString,h="Boolean Number String Function Array Date RegExp Object Error".split(" "),i=0;i<h.length;i++)e["[object "+h[i]+"]"]=h[i].toLowerCase();c.fn.init.prototype=c.fn,a.Velocity={Utilities:c}}}(window),function(a){"object"==typeof module&&"object"==typeof module.exports?module.exports=a():"function"==typeof define&&define.amd?define(a):a()}(function(){return function(a,b,c,d){function e(a){for(var b=-1,c=a?a.length:0,d=[];++b<c;){var e=a[b];e&&d.push(e)}return d}function f(a){return p.isWrapped(a)?a=[].slice.call(a):p.isNode(a)&&(a=[a]),a}function g(a){var b=m.data(a,"velocity");return null===b?d:b}function h(a){return function(b){return Math.round(b*a)*(1/a)}}function i(a,c,d,e){function f(a,b){return 1-3*b+3*a}function g(a,b){return 3*b-6*a}function h(a){return 3*a}function i(a,b,c){return((f(b,c)*a+g(b,c))*a+h(b))*a}function j(a,b,c){return 3*f(b,c)*a*a+2*g(b,c)*a+h(b)}function k(b,c){for(var e=0;p>e;++e){var f=j(c,a,d);if(0===f)return c;var g=i(c,a,d)-b;c-=g/f}return c}function l(){for(var b=0;t>b;++b)x[b]=i(b*u,a,d)}function m(b,c,e){var f,g,h=0;do g=c+(e-c)/2,f=i(g,a,d)-b,f>0?e=g:c=g;while(Math.abs(f)>r&&++h<s);return g}function n(b){for(var c=0,e=1,f=t-1;e!=f&&x[e]<=b;++e)c+=u;--e;var g=(b-x[e])/(x[e+1]-x[e]),h=c+g*u,i=j(h,a,d);return i>=q?k(b,h):0==i?h:m(b,c,c+u)}function o(){y=!0,(a!=c||d!=e)&&l()}var p=4,q=.001,r=1e-7,s=10,t=11,u=1/(t-1),v="Float32Array"in b;if(4!==arguments.length)return!1;for(var w=0;4>w;++w)if("number"!=typeof arguments[w]||isNaN(arguments[w])||!isFinite(arguments[w]))return!1;a=Math.min(a,1),d=Math.min(d,1),a=Math.max(a,0),d=Math.max(d,0);var x=v?new Float32Array(t):new Array(t),y=!1,z=function(b){return y||o(),a===c&&d===e?b:0===b?0:1===b?1:i(n(b),c,e)};z.getControlPoints=function(){return[{x:a,y:c},{x:d,y:e}]};var A="generateBezier("+[a,c,d,e]+")";return z.toString=function(){return A},z}function j(a,b){var c=a;return p.isString(a)?t.Easings[a]||(c=!1):c=p.isArray(a)&&1===a.length?h.apply(null,a):p.isArray(a)&&2===a.length?u.apply(null,a.concat([b])):p.isArray(a)&&4===a.length?i.apply(null,a):!1,c===!1&&(c=t.Easings[t.defaults.easing]?t.defaults.easing:s),c}function k(a){if(a){var b=(new Date).getTime(),c=t.State.calls.length;c>1e4&&(t.State.calls=e(t.State.calls));for(var f=0;c>f;f++)if(t.State.calls[f]){var h=t.State.calls[f],i=h[0],j=h[2],n=h[3],o=!!n,q=null;n||(n=t.State.calls[f][3]=b-16);for(var r=Math.min((b-n)/j.duration,1),s=0,u=i.length;u>s;s++){var w=i[s],y=w.element;if(g(y)){var z=!1;if(j.display!==d&&null!==j.display&&"none"!==j.display){if("flex"===j.display){var A=["-webkit-box","-moz-box","-ms-flexbox","-webkit-flex"];m.each(A,function(a,b){v.setPropertyValue(y,"display",b)})}v.setPropertyValue(y,"display",j.display)}j.visibility!==d&&"hidden"!==j.visibility&&v.setPropertyValue(y,"visibility",j.visibility);for(var B in w)if("element"!==B){var C,D=w[B],E=p.isString(D.easing)?t.Easings[D.easing]:D.easing;if(1===r)C=D.endValue;else{var F=D.endValue-D.startValue;if(C=D.startValue+F*E(r,j,F),!o&&C===D.currentValue)continue}if(D.currentValue=C,"tween"===B)q=C;else{if(v.Hooks.registered[B]){var G=v.Hooks.getRoot(B),H=g(y).rootPropertyValueCache[G];H&&(D.rootPropertyValue=H)}var I=v.setPropertyValue(y,B,D.currentValue+(0===parseFloat(C)?"":D.unitType),D.rootPropertyValue,D.scrollData);v.Hooks.registered[B]&&(g(y).rootPropertyValueCache[G]=v.Normalizations.registered[G]?v.Normalizations.registered[G]("extract",null,I[1]):I[1]),"transform"===I[0]&&(z=!0)}}j.mobileHA&&g(y).transformCache.translate3d===d&&(g(y).transformCache.translate3d="(0px, 0px, 0px)",z=!0),z&&v.flushTransformCache(y)}}j.display!==d&&"none"!==j.display&&(t.State.calls[f][2].display=!1),j.visibility!==d&&"hidden"!==j.visibility&&(t.State.calls[f][2].visibility=!1),j.progress&&j.progress.call(h[1],h[1],r,Math.max(0,n+j.duration-b),n,q),1===r&&l(f)}}t.State.isTicking&&x(k)}function l(a,b){if(!t.State.calls[a])return!1;for(var c=t.State.calls[a][0],e=t.State.calls[a][1],f=t.State.calls[a][2],h=t.State.calls[a][4],i=!1,j=0,k=c.length;k>j;j++){var l=c[j].element;if(b||f.loop||("none"===f.display&&v.setPropertyValue(l,"display",f.display),"hidden"===f.visibility&&v.setPropertyValue(l,"visibility",f.visibility)),f.loop!==!0&&(m.queue(l)[1]===d||!/\.velocityQueueEntryFlag/i.test(m.queue(l)[1]))&&g(l)){g(l).isAnimating=!1,g(l).rootPropertyValueCache={};var n=!1;m.each(v.Lists.transforms3D,function(a,b){var c=/^scale/.test(b)?1:0,e=g(l).transformCache[b];g(l).transformCache[b]!==d&&new RegExp("^\\("+c+"[^.]").test(e)&&(n=!0,delete g(l).transformCache[b])}),f.mobileHA&&(n=!0,delete g(l).transformCache.translate3d),n&&v.flushTransformCache(l),v.Values.removeClass(l,"velocity-animating")}if(!b&&f.complete&&!f.loop&&j===k-1)try{f.complete.call(e,e)}catch(o){setTimeout(function(){throw o},1)}h&&f.loop!==!0&&h(e),g(l)&&f.loop===!0&&!b&&(m.each(g(l).tweensContainer,function(a,b){/^rotate/.test(a)&&360===parseFloat(b.endValue)&&(b.endValue=0,b.startValue=360),/^backgroundPosition/.test(a)&&100===parseFloat(b.endValue)&&"%"===b.unitType&&(b.endValue=0,b.startValue=100)}),t(l,"reverse",{loop:!0,delay:f.delay})),f.queue!==!1&&m.dequeue(l,f.queue)}t.State.calls[a]=!1;for(var p=0,q=t.State.calls.length;q>p;p++)if(t.State.calls[p]!==!1){i=!0;break}i===!1&&(t.State.isTicking=!1,delete t.State.calls,t.State.calls=[])}var m,n=function(){if(c.documentMode)return c.documentMode;for(var a=7;a>4;a--){var b=c.createElement("div");if(b.innerHTML="<!--[if IE "+a+"]><span></span><![endif]-->",b.getElementsByTagName("span").length)return b=null,a}return d}(),o=function(){var a=0;return b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||function(b){var c,d=(new Date).getTime();return c=Math.max(0,16-(d-a)),a=d+c,setTimeout(function(){b(d+c)},c)}}(),p={isString:function(a){return"string"==typeof a},isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},isFunction:function(a){return"[object Function]"===Object.prototype.toString.call(a)},isNode:function(a){return a&&a.nodeType},isNodeList:function(a){return"object"==typeof a&&/^\[object (HTMLCollection|NodeList|Object)\]$/.test(Object.prototype.toString.call(a))&&a.length!==d&&(0===a.length||"object"==typeof a[0]&&a[0].nodeType>0)},isWrapped:function(a){return a&&(a.jquery||b.Zepto&&b.Zepto.zepto.isZ(a))},isSVG:function(a){return b.SVGElement&&a instanceof b.SVGElement},isEmptyObject:function(a){for(var b in a)return!1;return!0}},q=!1;if(a.fn&&a.fn.jquery?(m=a,q=!0):m=b.Velocity.Utilities,8>=n&&!q)throw new Error("Velocity: IE8 and below require jQuery to be loaded before Velocity.");if(7>=n)return void(jQuery.fn.velocity=jQuery.fn.animate);var r=400,s="swing",t={State:{isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),isAndroid:/Android/i.test(navigator.userAgent),isGingerbread:/Android 2\.3\.[3-7]/i.test(navigator.userAgent),isChrome:b.chrome,isFirefox:/Firefox/i.test(navigator.userAgent),prefixElement:c.createElement("div"),prefixMatches:{},scrollAnchor:null,scrollPropertyLeft:null,scrollPropertyTop:null,isTicking:!1,calls:[]},CSS:{},Utilities:m,Redirects:{},Easings:{},Promise:b.Promise,defaults:{queue:"",duration:r,easing:s,begin:d,complete:d,progress:d,display:d,visibility:d,loop:!1,delay:!1,mobileHA:!0,_cacheValues:!0},init:function(a){m.data(a,"velocity",{isSVG:p.isSVG(a),isAnimating:!1,computedStyle:null,tweensContainer:null,rootPropertyValueCache:{},transformCache:{}})},hook:null,mock:!1,version:{major:1,minor:2,patch:2},debug:!1};b.pageYOffset!==d?(t.State.scrollAnchor=b,t.State.scrollPropertyLeft="pageXOffset",t.State.scrollPropertyTop="pageYOffset"):(t.State.scrollAnchor=c.documentElement||c.body.parentNode||c.body,t.State.scrollPropertyLeft="scrollLeft",t.State.scrollPropertyTop="scrollTop");var u=function(){function a(a){return-a.tension*a.x-a.friction*a.v}function b(b,c,d){var e={x:b.x+d.dx*c,v:b.v+d.dv*c,tension:b.tension,friction:b.friction};return{dx:e.v,dv:a(e)}}function c(c,d){var e={dx:c.v,dv:a(c)},f=b(c,.5*d,e),g=b(c,.5*d,f),h=b(c,d,g),i=1/6*(e.dx+2*(f.dx+g.dx)+h.dx),j=1/6*(e.dv+2*(f.dv+g.dv)+h.dv);return c.x=c.x+i*d,c.v=c.v+j*d,c}return function d(a,b,e){var f,g,h,i={x:-1,v:0,tension:null,friction:null},j=[0],k=0,l=1e-4,m=.016;for(a=parseFloat(a)||500,b=parseFloat(b)||20,e=e||null,i.tension=a,i.friction=b,f=null!==e,f?(k=d(a,b),g=k/e*m):g=m;h=c(h||i,g),j.push(1+h.x),k+=16,Math.abs(h.x)>l&&Math.abs(h.v)>l;);return f?function(a){return j[a*(j.length-1)|0]}:k}}();t.Easings={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},spring:function(a){return 1-Math.cos(4.5*a*Math.PI)*Math.exp(6*-a)}},m.each([["ease",[.25,.1,.25,1]],["ease-in",[.42,0,1,1]],["ease-out",[0,0,.58,1]],["ease-in-out",[.42,0,.58,1]],["easeInSine",[.47,0,.745,.715]],["easeOutSine",[.39,.575,.565,1]],["easeInOutSine",[.445,.05,.55,.95]],["easeInQuad",[.55,.085,.68,.53]],["easeOutQuad",[.25,.46,.45,.94]],["easeInOutQuad",[.455,.03,.515,.955]],["easeInCubic",[.55,.055,.675,.19]],["easeOutCubic",[.215,.61,.355,1]],["easeInOutCubic",[.645,.045,.355,1]],["easeInQuart",[.895,.03,.685,.22]],["easeOutQuart",[.165,.84,.44,1]],["easeInOutQuart",[.77,0,.175,1]],["easeInQuint",[.755,.05,.855,.06]],["easeOutQuint",[.23,1,.32,1]],["easeInOutQuint",[.86,0,.07,1]],["easeInExpo",[.95,.05,.795,.035]],["easeOutExpo",[.19,1,.22,1]],["easeInOutExpo",[1,0,0,1]],["easeInCirc",[.6,.04,.98,.335]],["easeOutCirc",[.075,.82,.165,1]],["easeInOutCirc",[.785,.135,.15,.86]]],function(a,b){t.Easings[b[0]]=i.apply(null,b[1])});var v=t.CSS={RegEx:{isHex:/^#([A-f\d]{3}){1,2}$/i,valueUnwrap:/^[A-z]+\((.*)\)$/i,wrappedValueAlreadyExtracted:/[0-9.]+ [0-9.]+ [0-9.]+( [0-9.]+)?/,valueSplit:/([A-z]+\(.+\))|(([A-z0-9#-.]+?)(?=\s|$))/gi},Lists:{colors:["fill","stroke","stopColor","color","backgroundColor","borderColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","outlineColor"],transformsBase:["translateX","translateY","scale","scaleX","scaleY","skewX","skewY","rotateZ"],transforms3D:["transformPerspective","translateZ","scaleZ","rotateX","rotateY"]},Hooks:{templates:{textShadow:["Color X Y Blur","black 0px 0px 0px"],boxShadow:["Color X Y Blur Spread","black 0px 0px 0px 0px"],clip:["Top Right Bottom Left","0px 0px 0px 0px"],backgroundPosition:["X Y","0% 0%"],transformOrigin:["X Y Z","50% 50% 0px"],perspectiveOrigin:["X Y","50% 50%"]},registered:{},register:function(){for(var a=0;a<v.Lists.colors.length;a++){var b="color"===v.Lists.colors[a]?"0 0 0 1":"255 255 255 1";v.Hooks.templates[v.Lists.colors[a]]=["Red Green Blue Alpha",b]}var c,d,e;if(n)for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");var f=d[1].match(v.RegEx.valueSplit);"Color"===e[0]&&(e.push(e.shift()),f.push(f.shift()),v.Hooks.templates[c]=[e.join(" "),f.join(" ")])}for(c in v.Hooks.templates){d=v.Hooks.templates[c],e=d[0].split(" ");for(var a in e){var g=c+e[a],h=a;v.Hooks.registered[g]=[c,h]}}},getRoot:function(a){var b=v.Hooks.registered[a];return b?b[0]:a},cleanRootPropertyValue:function(a,b){return v.RegEx.valueUnwrap.test(b)&&(b=b.match(v.RegEx.valueUnwrap)[1]),v.Values.isCSSNullValue(b)&&(b=v.Hooks.templates[a][1]),b},extractValue:function(a,b){var c=v.Hooks.registered[a];if(c){var d=c[0],e=c[1];return b=v.Hooks.cleanRootPropertyValue(d,b),b.toString().match(v.RegEx.valueSplit)[e]}return b},injectValue:function(a,b,c){var d=v.Hooks.registered[a];if(d){var e,f,g=d[0],h=d[1];return c=v.Hooks.cleanRootPropertyValue(g,c),e=c.toString().match(v.RegEx.valueSplit),e[h]=b,f=e.join(" ")}return c}},Normalizations:{registered:{clip:function(a,b,c){switch(a){case"name":return"clip";case"extract":var d;return v.RegEx.wrappedValueAlreadyExtracted.test(c)?d=c:(d=c.toString().match(v.RegEx.valueUnwrap),d=d?d[1].replace(/,(\s+)?/g," "):c),d;case"inject":return"rect("+c+")"}},blur:function(a,b,c){switch(a){case"name":return t.State.isFirefox?"filter":"-webkit-filter";case"extract":var d=parseFloat(c);if(!d&&0!==d){var e=c.toString().match(/blur\(([0-9]+[A-z]+)\)/i);d=e?e[1]:0}return d;case"inject":return parseFloat(c)?"blur("+c+")":"none"}},opacity:function(a,b,c){if(8>=n)switch(a){case"name":return"filter";case"extract":var d=c.toString().match(/alpha\(opacity=(.*)\)/i);return c=d?d[1]/100:1;case"inject":return b.style.zoom=1,parseFloat(c)>=1?"":"alpha(opacity="+parseInt(100*parseFloat(c),10)+")"}else switch(a){case"name":return"opacity";case"extract":return c;case"inject":return c}}},register:function(){9>=n||t.State.isGingerbread||(v.Lists.transformsBase=v.Lists.transformsBase.concat(v.Lists.transforms3D));for(var a=0;a<v.Lists.transformsBase.length;a++)!function(){var b=v.Lists.transformsBase[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return"transform";case"extract":return g(c)===d||g(c).transformCache[b]===d?/^scale/i.test(b)?1:0:g(c).transformCache[b].replace(/[()]/g,"");case"inject":var f=!1;switch(b.substr(0,b.length-1)){case"translate":f=!/(%|px|em|rem|vw|vh|\d)$/i.test(e);break;case"scal":case"scale":t.State.isAndroid&&g(c).transformCache[b]===d&&1>e&&(e=1),f=!/(\d)$/i.test(e);break;case"skew":f=!/(deg|\d)$/i.test(e);break;case"rotate":f=!/(deg|\d)$/i.test(e)}return f||(g(c).transformCache[b]="("+e+")"),g(c).transformCache[b]}}}();for(var a=0;a<v.Lists.colors.length;a++)!function(){var b=v.Lists.colors[a];v.Normalizations.registered[b]=function(a,c,e){switch(a){case"name":return b;case"extract":var f;if(v.RegEx.wrappedValueAlreadyExtracted.test(e))f=e;else{var g,h={black:"rgb(0, 0, 0)",blue:"rgb(0, 0, 255)",gray:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",red:"rgb(255, 0, 0)",white:"rgb(255, 255, 255)"};/^[A-z]+$/i.test(e)?g=h[e]!==d?h[e]:h.black:v.RegEx.isHex.test(e)?g="rgb("+v.Values.hexToRgb(e).join(" ")+")":/^rgba?\(/i.test(e)||(g=h.black),f=(g||e).toString().match(v.RegEx.valueUnwrap)[1].replace(/,(\s+)?/g," ")}return 8>=n||3!==f.split(" ").length||(f+=" 1"),f;case"inject":return 8>=n?4===e.split(" ").length&&(e=e.split(/\s+/).slice(0,3).join(" ")):3===e.split(" ").length&&(e+=" 1"),(8>=n?"rgb":"rgba")+"("+e.replace(/\s+/g,",").replace(/\.(\d)+(?=,)/g,"")+")"}}}()}},Names:{camelCase:function(a){return a.replace(/-(\w)/g,function(a,b){return b.toUpperCase()})},SVGAttribute:function(a){var b="width|height|x|y|cx|cy|r|rx|ry|x1|x2|y1|y2";return(n||t.State.isAndroid&&!t.State.isChrome)&&(b+="|transform"),new RegExp("^("+b+")$","i").test(a)},prefixCheck:function(a){if(t.State.prefixMatches[a])return[t.State.prefixMatches[a],!0];for(var b=["","Webkit","Moz","ms","O"],c=0,d=b.length;d>c;c++){var e;if(e=0===c?a:b[c]+a.replace(/^\w/,function(a){return a.toUpperCase()}),p.isString(t.State.prefixElement.style[e]))return t.State.prefixMatches[a]=e,[e,!0]}return[a,!1]}},Values:{hexToRgb:function(a){var b,c=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,d=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;return a=a.replace(c,function(a,b,c,d){return b+b+c+c+d+d}),b=d.exec(a),b?[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]:[0,0,0]},isCSSNullValue:function(a){return 0==a||/^(none|auto|transparent|(rgba\(0, ?0, ?0, ?0\)))$/i.test(a)},getUnitType:function(a){return/^(rotate|skew)/i.test(a)?"deg":/(^(scale|scaleX|scaleY|scaleZ|alpha|flexGrow|flexHeight|zIndex|fontWeight)$)|((opacity|red|green|blue|alpha)$)/i.test(a)?"":"px"},getDisplayType:function(a){var b=a&&a.tagName.toString().toLowerCase();return/^(b|big|i|small|tt|abbr|acronym|cite|code|dfn|em|kbd|strong|samp|var|a|bdo|br|img|map|object|q|script|span|sub|sup|button|input|label|select|textarea)$/i.test(b)?"inline":/^(li)$/i.test(b)?"list-item":/^(tr)$/i.test(b)?"table-row":/^(table)$/i.test(b)?"table":/^(tbody)$/i.test(b)?"table-row-group":"block"},addClass:function(a,b){a.classList?a.classList.add(b):a.className+=(a.className.length?" ":"")+b},removeClass:function(a,b){a.classList?a.classList.remove(b):a.className=a.className.toString().replace(new RegExp("(^|\\s)"+b.split(" ").join("|")+"(\\s|$)","gi")," ")}},getPropertyValue:function(a,c,e,f){function h(a,c){function e(){j&&v.setPropertyValue(a,"display","none")}var i=0;if(8>=n)i=m.css(a,c);else{var j=!1;if(/^(width|height)$/.test(c)&&0===v.getPropertyValue(a,"display")&&(j=!0,v.setPropertyValue(a,"display",v.Values.getDisplayType(a))),!f){if("height"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var k=a.offsetHeight-(parseFloat(v.getPropertyValue(a,"borderTopWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderBottomWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingTop"))||0)-(parseFloat(v.getPropertyValue(a,"paddingBottom"))||0);return e(),k}if("width"===c&&"border-box"!==v.getPropertyValue(a,"boxSizing").toString().toLowerCase()){var l=a.offsetWidth-(parseFloat(v.getPropertyValue(a,"borderLeftWidth"))||0)-(parseFloat(v.getPropertyValue(a,"borderRightWidth"))||0)-(parseFloat(v.getPropertyValue(a,"paddingLeft"))||0)-(parseFloat(v.getPropertyValue(a,"paddingRight"))||0);return e(),l}}var o;o=g(a)===d?b.getComputedStyle(a,null):g(a).computedStyle?g(a).computedStyle:g(a).computedStyle=b.getComputedStyle(a,null),"borderColor"===c&&(c="borderTopColor"),i=9===n&&"filter"===c?o.getPropertyValue(c):o[c],(""===i||null===i)&&(i=a.style[c]),e()}if("auto"===i&&/^(top|right|bottom|left)$/i.test(c)){var p=h(a,"position");("fixed"===p||"absolute"===p&&/top|left/i.test(c))&&(i=m(a).position()[c]+"px")}return i}var i;if(v.Hooks.registered[c]){var j=c,k=v.Hooks.getRoot(j);e===d&&(e=v.getPropertyValue(a,v.Names.prefixCheck(k)[0])),v.Normalizations.registered[k]&&(e=v.Normalizations.registered[k]("extract",a,e)),i=v.Hooks.extractValue(j,e)}else if(v.Normalizations.registered[c]){var l,o;l=v.Normalizations.registered[c]("name",a),"transform"!==l&&(o=h(a,v.Names.prefixCheck(l)[0]),v.Values.isCSSNullValue(o)&&v.Hooks.templates[c]&&(o=v.Hooks.templates[c][1])),i=v.Normalizations.registered[c]("extract",a,o)}if(!/^[\d-]/.test(i))if(g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c))if(/^(height|width)$/i.test(c))try{i=a.getBBox()[c]}catch(p){i=0}else i=a.getAttribute(c);else i=h(a,v.Names.prefixCheck(c)[0]);return v.Values.isCSSNullValue(i)&&(i=0),t.debug>=2&&console.log("Get "+c+": "+i),i},setPropertyValue:function(a,c,d,e,f){var h=c;if("scroll"===c)f.container?f.container["scroll"+f.direction]=d:"Left"===f.direction?b.scrollTo(d,f.alternateValue):b.scrollTo(f.alternateValue,d);else if(v.Normalizations.registered[c]&&"transform"===v.Normalizations.registered[c]("name",a))v.Normalizations.registered[c]("inject",a,d),h="transform",d=g(a).transformCache[c];else{if(v.Hooks.registered[c]){var i=c,j=v.Hooks.getRoot(c);e=e||v.getPropertyValue(a,j),d=v.Hooks.injectValue(i,d,e),c=j}if(v.Normalizations.registered[c]&&(d=v.Normalizations.registered[c]("inject",a,d),c=v.Normalizations.registered[c]("name",a)),h=v.Names.prefixCheck(c)[0],8>=n)try{a.style[h]=d}catch(k){t.debug&&console.log("Browser does not support ["+d+"] for ["+h+"]")}else g(a)&&g(a).isSVG&&v.Names.SVGAttribute(c)?a.setAttribute(c,d):a.style[h]=d;t.debug>=2&&console.log("Set "+c+" ("+h+"): "+d)}return[h,d]},flushTransformCache:function(a){function b(b){return parseFloat(v.getPropertyValue(a,b))}var c="";if((n||t.State.isAndroid&&!t.State.isChrome)&&g(a).isSVG){var d={translate:[b("translateX"),b("translateY")],skewX:[b("skewX")],skewY:[b("skewY")],scale:1!==b("scale")?[b("scale"),b("scale")]:[b("scaleX"),b("scaleY")],rotate:[b("rotateZ"),0,0]};m.each(g(a).transformCache,function(a){/^translate/i.test(a)?a="translate":/^scale/i.test(a)?a="scale":/^rotate/i.test(a)&&(a="rotate"),d[a]&&(c+=a+"("+d[a].join(" ")+") ",delete d[a])})}else{var e,f;m.each(g(a).transformCache,function(b){return e=g(a).transformCache[b],"transformPerspective"===b?(f=e,!0):(9===n&&"rotateZ"===b&&(b="rotate"),void(c+=b+e+" "))}),f&&(c="perspective"+f+" "+c)}v.setPropertyValue(a,"transform",c)}};v.Hooks.register(),v.Normalizations.register(),t.hook=function(a,b,c){var e=d;return a=f(a),m.each(a,function(a,f){if(g(f)===d&&t.init(f),c===d)e===d&&(e=t.CSS.getPropertyValue(f,b));else{var h=t.CSS.setPropertyValue(f,b,c);"transform"===h[0]&&t.CSS.flushTransformCache(f),e=h}}),e};var w=function(){function a(){return h?B.promise||null:i}function e(){function a(){function a(a,b){var c=d,e=d,g=d;return p.isArray(a)?(c=a[0],!p.isArray(a[1])&&/^[\d-]/.test(a[1])||p.isFunction(a[1])||v.RegEx.isHex.test(a[1])?g=a[1]:(p.isString(a[1])&&!v.RegEx.isHex.test(a[1])||p.isArray(a[1]))&&(e=b?a[1]:j(a[1],h.duration),a[2]!==d&&(g=a[2]))):c=a,b||(e=e||h.easing),p.isFunction(c)&&(c=c.call(f,y,x)),p.isFunction(g)&&(g=g.call(f,y,x)),[c||0,e,g]}function l(a,b){var c,d;return d=(b||"0").toString().toLowerCase().replace(/[%A-z]+$/,function(a){return c=a,""}),c||(c=v.Values.getUnitType(a)),[d,c]}function n(){var a={myParent:f.parentNode||c.body,position:v.getPropertyValue(f,"position"),fontSize:v.getPropertyValue(f,"fontSize")},d=a.position===I.lastPosition&&a.myParent===I.lastParent,e=a.fontSize===I.lastFontSize;I.lastParent=a.myParent,I.lastPosition=a.position,I.lastFontSize=a.fontSize;var h=100,i={};if(e&&d)i.emToPx=I.lastEmToPx,i.percentToPxWidth=I.lastPercentToPxWidth,i.percentToPxHeight=I.lastPercentToPxHeight;else{var j=g(f).isSVG?c.createElementNS("http://www.w3.org/2000/svg","rect"):c.createElement("div");t.init(j),a.myParent.appendChild(j),m.each(["overflow","overflowX","overflowY"],function(a,b){t.CSS.setPropertyValue(j,b,"hidden")}),t.CSS.setPropertyValue(j,"position",a.position),t.CSS.setPropertyValue(j,"fontSize",a.fontSize),t.CSS.setPropertyValue(j,"boxSizing","content-box"),m.each(["minWidth","maxWidth","width","minHeight","maxHeight","height"],function(a,b){t.CSS.setPropertyValue(j,b,h+"%")}),t.CSS.setPropertyValue(j,"paddingLeft",h+"em"),i.percentToPxWidth=I.lastPercentToPxWidth=(parseFloat(v.getPropertyValue(j,"width",null,!0))||1)/h,i.percentToPxHeight=I.lastPercentToPxHeight=(parseFloat(v.getPropertyValue(j,"height",null,!0))||1)/h,i.emToPx=I.lastEmToPx=(parseFloat(v.getPropertyValue(j,"paddingLeft"))||1)/h,a.myParent.removeChild(j)}return null===I.remToPx&&(I.remToPx=parseFloat(v.getPropertyValue(c.body,"fontSize"))||16),null===I.vwToPx&&(I.vwToPx=parseFloat(b.innerWidth)/100,I.vhToPx=parseFloat(b.innerHeight)/100),i.remToPx=I.remToPx,i.vwToPx=I.vwToPx,i.vhToPx=I.vhToPx,t.debug>=1&&console.log("Unit ratios: "+JSON.stringify(i),f),i}if(h.begin&&0===y)try{h.begin.call(o,o)}catch(r){setTimeout(function(){throw r},1)}if("scroll"===C){var u,w,z,A=/^x$/i.test(h.axis)?"Left":"Top",D=parseFloat(h.offset)||0;h.container?p.isWrapped(h.container)||p.isNode(h.container)?(h.container=h.container[0]||h.container,u=h.container["scroll"+A],z=u+m(f).position()[A.toLowerCase()]+D):h.container=null:(u=t.State.scrollAnchor[t.State["scrollProperty"+A]],w=t.State.scrollAnchor[t.State["scrollProperty"+("Left"===A?"Top":"Left")]],z=m(f).offset()[A.toLowerCase()]+D),i={scroll:{rootPropertyValue:!1,startValue:u,currentValue:u,endValue:z,unitType:"",easing:h.easing,scrollData:{container:h.container,direction:A,alternateValue:w}},element:f},t.debug&&console.log("tweensContainer (scroll): ",i.scroll,f)}else if("reverse"===C){if(!g(f).tweensContainer)return void m.dequeue(f,h.queue);"none"===g(f).opts.display&&(g(f).opts.display="auto"),"hidden"===g(f).opts.visibility&&(g(f).opts.visibility="visible"),g(f).opts.loop=!1,g(f).opts.begin=null,g(f).opts.complete=null,s.easing||delete h.easing,s.duration||delete h.duration,h=m.extend({},g(f).opts,h);var E=m.extend(!0,{},g(f).tweensContainer);for(var F in E)if("element"!==F){var G=E[F].startValue;E[F].startValue=E[F].currentValue=E[F].endValue,E[F].endValue=G,p.isEmptyObject(s)||(E[F].easing=h.easing),t.debug&&console.log("reverse tweensContainer ("+F+"): "+JSON.stringify(E[F]),f)}i=E}else if("start"===C){var E;g(f).tweensContainer&&g(f).isAnimating===!0&&(E=g(f).tweensContainer),m.each(q,function(b,c){if(RegExp("^"+v.Lists.colors.join("$|^")+"$").test(b)){var e=a(c,!0),f=e[0],g=e[1],h=e[2];if(v.RegEx.isHex.test(f)){for(var i=["Red","Green","Blue"],j=v.Values.hexToRgb(f),k=h?v.Values.hexToRgb(h):d,l=0;l<i.length;l++){var m=[j[l]];g&&m.push(g),k!==d&&m.push(k[l]),q[b+i[l]]=m}delete q[b]}}});for(var H in q){var K=a(q[H]),L=K[0],M=K[1],N=K[2];H=v.Names.camelCase(H);var O=v.Hooks.getRoot(H),P=!1;if(g(f).isSVG||"tween"===O||v.Names.prefixCheck(O)[1]!==!1||v.Normalizations.registered[O]!==d){(h.display!==d&&null!==h.display&&"none"!==h.display||h.visibility!==d&&"hidden"!==h.visibility)&&/opacity|filter/.test(H)&&!N&&0!==L&&(N=0),h._cacheValues&&E&&E[H]?(N===d&&(N=E[H].endValue+E[H].unitType),P=g(f).rootPropertyValueCache[O]):v.Hooks.registered[H]?N===d?(P=v.getPropertyValue(f,O),N=v.getPropertyValue(f,H,P)):P=v.Hooks.templates[O][1]:N===d&&(N=v.getPropertyValue(f,H));var Q,R,S,T=!1;if(Q=l(H,N),N=Q[0],S=Q[1],Q=l(H,L),L=Q[0].replace(/^([+-\/*])=/,function(a,b){return T=b,""}),R=Q[1],N=parseFloat(N)||0,L=parseFloat(L)||0,"%"===R&&(/^(fontSize|lineHeight)$/.test(H)?(L/=100,R="em"):/^scale/.test(H)?(L/=100,R=""):/(Red|Green|Blue)$/i.test(H)&&(L=L/100*255,R="")),/[\/*]/.test(T))R=S;else if(S!==R&&0!==N)if(0===L)R=S;else{e=e||n();var U=/margin|padding|left|right|width|text|word|letter/i.test(H)||/X$/.test(H)||"x"===H?"x":"y";switch(S){case"%":N*="x"===U?e.percentToPxWidth:e.percentToPxHeight;break;case"px":break;default:N*=e[S+"ToPx"]}switch(R){case"%":N*=1/("x"===U?e.percentToPxWidth:e.percentToPxHeight);break;case"px":break;default: -N*=1/e[R+"ToPx"]}}switch(T){case"+":L=N+L;break;case"-":L=N-L;break;case"*":L=N*L;break;case"/":L=N/L}i[H]={rootPropertyValue:P,startValue:N,currentValue:N,endValue:L,unitType:R,easing:M},t.debug&&console.log("tweensContainer ("+H+"): "+JSON.stringify(i[H]),f)}else t.debug&&console.log("Skipping ["+O+"] due to a lack of browser support.")}i.element=f}i.element&&(v.Values.addClass(f,"velocity-animating"),J.push(i),""===h.queue&&(g(f).tweensContainer=i,g(f).opts=h),g(f).isAnimating=!0,y===x-1?(t.State.calls.push([J,o,h,null,B.resolver]),t.State.isTicking===!1&&(t.State.isTicking=!0,k())):y++)}var e,f=this,h=m.extend({},t.defaults,s),i={};switch(g(f)===d&&t.init(f),parseFloat(h.delay)&&h.queue!==!1&&m.queue(f,h.queue,function(a){t.velocityQueueEntryFlag=!0,g(f).delayTimer={setTimeout:setTimeout(a,parseFloat(h.delay)),next:a}}),h.duration.toString().toLowerCase()){case"fast":h.duration=200;break;case"normal":h.duration=r;break;case"slow":h.duration=600;break;default:h.duration=parseFloat(h.duration)||1}t.mock!==!1&&(t.mock===!0?h.duration=h.delay=1:(h.duration*=parseFloat(t.mock)||1,h.delay*=parseFloat(t.mock)||1)),h.easing=j(h.easing,h.duration),h.begin&&!p.isFunction(h.begin)&&(h.begin=null),h.progress&&!p.isFunction(h.progress)&&(h.progress=null),h.complete&&!p.isFunction(h.complete)&&(h.complete=null),h.display!==d&&null!==h.display&&(h.display=h.display.toString().toLowerCase(),"auto"===h.display&&(h.display=t.CSS.Values.getDisplayType(f))),h.visibility!==d&&null!==h.visibility&&(h.visibility=h.visibility.toString().toLowerCase()),h.mobileHA=h.mobileHA&&t.State.isMobile&&!t.State.isGingerbread,h.queue===!1?h.delay?setTimeout(a,h.delay):a():m.queue(f,h.queue,function(b,c){return c===!0?(B.promise&&B.resolver(o),!0):(t.velocityQueueEntryFlag=!0,void a(b))}),""!==h.queue&&"fx"!==h.queue||"inprogress"===m.queue(f)[0]||m.dequeue(f)}var h,i,n,o,q,s,u=arguments[0]&&(arguments[0].p||m.isPlainObject(arguments[0].properties)&&!arguments[0].properties.names||p.isString(arguments[0].properties));if(p.isWrapped(this)?(h=!1,n=0,o=this,i=this):(h=!0,n=1,o=u?arguments[0].elements||arguments[0].e:arguments[0]),o=f(o)){u?(q=arguments[0].properties||arguments[0].p,s=arguments[0].options||arguments[0].o):(q=arguments[n],s=arguments[n+1]);var x=o.length,y=0;if(!/^(stop|finish)$/i.test(q)&&!m.isPlainObject(s)){var z=n+1;s={};for(var A=z;A<arguments.length;A++)p.isArray(arguments[A])||!/^(fast|normal|slow)$/i.test(arguments[A])&&!/^\d/.test(arguments[A])?p.isString(arguments[A])||p.isArray(arguments[A])?s.easing=arguments[A]:p.isFunction(arguments[A])&&(s.complete=arguments[A]):s.duration=arguments[A]}var B={promise:null,resolver:null,rejecter:null};h&&t.Promise&&(B.promise=new t.Promise(function(a,b){B.resolver=a,B.rejecter=b}));var C;switch(q){case"scroll":C="scroll";break;case"reverse":C="reverse";break;case"finish":case"stop":m.each(o,function(a,b){g(b)&&g(b).delayTimer&&(clearTimeout(g(b).delayTimer.setTimeout),g(b).delayTimer.next&&g(b).delayTimer.next(),delete g(b).delayTimer)});var D=[];return m.each(t.State.calls,function(a,b){b&&m.each(b[1],function(c,e){var f=s===d?"":s;return f===!0||b[2].queue===f||s===d&&b[2].queue===!1?void m.each(o,function(c,d){d===e&&((s===!0||p.isString(s))&&(m.each(m.queue(d,p.isString(s)?s:""),function(a,b){p.isFunction(b)&&b(null,!0)}),m.queue(d,p.isString(s)?s:"",[])),"stop"===q?(g(d)&&g(d).tweensContainer&&f!==!1&&m.each(g(d).tweensContainer,function(a,b){b.endValue=b.currentValue}),D.push(a)):"finish"===q&&(b[2].duration=1))}):!0})}),"stop"===q&&(m.each(D,function(a,b){l(b,!0)}),B.promise&&B.resolver(o)),a();default:if(!m.isPlainObject(q)||p.isEmptyObject(q)){if(p.isString(q)&&t.Redirects[q]){var E=m.extend({},s),F=E.duration,G=E.delay||0;return E.backwards===!0&&(o=m.extend(!0,[],o).reverse()),m.each(o,function(a,b){parseFloat(E.stagger)?E.delay=G+parseFloat(E.stagger)*a:p.isFunction(E.stagger)&&(E.delay=G+E.stagger.call(b,a,x)),E.drag&&(E.duration=parseFloat(F)||(/^(callout|transition)/.test(q)?1e3:r),E.duration=Math.max(E.duration*(E.backwards?1-a/x:(a+1)/x),.75*E.duration,200)),t.Redirects[q].call(b,b,E||{},a,x,o,B.promise?B:d)}),a()}var H="Velocity: First argument ("+q+") was not a property map, a known action, or a registered redirect. Aborting.";return B.promise?B.rejecter(new Error(H)):console.log(H),a()}C="start"}var I={lastParent:null,lastPosition:null,lastFontSize:null,lastPercentToPxWidth:null,lastPercentToPxHeight:null,lastEmToPx:null,remToPx:null,vwToPx:null,vhToPx:null},J=[];m.each(o,function(a,b){p.isNode(b)&&e.call(b)});var K,E=m.extend({},t.defaults,s);if(E.loop=parseInt(E.loop),K=2*E.loop-1,E.loop)for(var L=0;K>L;L++){var M={delay:E.delay,progress:E.progress};L===K-1&&(M.display=E.display,M.visibility=E.visibility,M.complete=E.complete),w(o,"reverse",M)}return a()}};t=m.extend(w,t),t.animate=w;var x=b.requestAnimationFrame||o;return t.State.isMobile||c.hidden===d||c.addEventListener("visibilitychange",function(){c.hidden?(x=function(a){return setTimeout(function(){a(!0)},16)},k()):x=b.requestAnimationFrame||o}),a.Velocity=t,a!==b&&(a.fn.velocity=w,a.fn.velocity.defaults=t.defaults),m.each(["Down","Up"],function(a,b){t.Redirects["slide"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j=i.begin,k=i.complete,l={height:"",marginTop:"",marginBottom:"",paddingTop:"",paddingBottom:""},n={};i.display===d&&(i.display="Down"===b?"inline"===t.CSS.Values.getDisplayType(a)?"inline-block":"block":"none"),i.begin=function(){j&&j.call(g,g);for(var c in l){n[c]=a.style[c];var d=t.CSS.getPropertyValue(a,c);l[c]="Down"===b?[d,0]:[0,d]}n.overflow=a.style.overflow,a.style.overflow="hidden"},i.complete=function(){for(var b in n)a.style[b]=n[b];k&&k.call(g,g),h&&h.resolver(g)},t(a,l,i)}}),m.each(["In","Out"],function(a,b){t.Redirects["fade"+b]=function(a,c,e,f,g,h){var i=m.extend({},c),j={opacity:"In"===b?1:0},k=i.complete;i.complete=e!==f-1?i.begin=null:function(){k&&k.call(g,g),h&&h.resolver(g)},i.display===d&&(i.display="In"===b?"auto":"none"),t(this,j,i)}}),t}(window.jQuery||window.Zepto||window,window,document)}),!function(a,b,c,d){"use strict";function e(a,b,c){return setTimeout(k(a,c),b)}function f(a,b,c){return Array.isArray(a)?(g(a,c[b],c),!0):!1}function g(a,b,c){var e;if(a)if(a.forEach)a.forEach(b,c);else if(a.length!==d)for(e=0;e<a.length;)b.call(c,a[e],e,a),e++;else for(e in a)a.hasOwnProperty(e)&&b.call(c,a[e],e,a)}function h(a,b,c){for(var e=Object.keys(b),f=0;f<e.length;)(!c||c&&a[e[f]]===d)&&(a[e[f]]=b[e[f]]),f++;return a}function i(a,b){return h(a,b,!0)}function j(a,b,c){var d,e=b.prototype;d=a.prototype=Object.create(e),d.constructor=a,d._super=e,c&&h(d,c)}function k(a,b){return function(){return a.apply(b,arguments)}}function l(a,b){return typeof a==ka?a.apply(b?b[0]||d:d,b):a}function m(a,b){return a===d?b:a}function n(a,b,c){g(r(b),function(b){a.addEventListener(b,c,!1)})}function o(a,b,c){g(r(b),function(b){a.removeEventListener(b,c,!1)})}function p(a,b){for(;a;){if(a==b)return!0;a=a.parentNode}return!1}function q(a,b){return a.indexOf(b)>-1}function r(a){return a.trim().split(/\s+/g)}function s(a,b,c){if(a.indexOf&&!c)return a.indexOf(b);for(var d=0;d<a.length;){if(c&&a[d][c]==b||!c&&a[d]===b)return d;d++}return-1}function t(a){return Array.prototype.slice.call(a,0)}function u(a,b,c){for(var d=[],e=[],f=0;f<a.length;){var g=b?a[f][b]:a[f];s(e,g)<0&&d.push(a[f]),e[f]=g,f++}return c&&(d=b?d.sort(function(a,c){return a[b]>c[b]}):d.sort()),d}function v(a,b){for(var c,e,f=b[0].toUpperCase()+b.slice(1),g=0;g<ia.length;){if(c=ia[g],e=c?c+f:b,e in a)return e;g++}return d}function w(){return oa++}function x(a){var b=a.ownerDocument;return b.defaultView||b.parentWindow}function y(a,b){var c=this;this.manager=a,this.callback=b,this.element=a.element,this.target=a.options.inputTarget,this.domHandler=function(b){l(a.options.enable,[a])&&c.handler(b)},this.init()}function z(a){var b,c=a.options.inputClass;return new(b=c?c:ra?N:sa?Q:qa?S:M)(a,A)}function A(a,b,c){var d=c.pointers.length,e=c.changedPointers.length,f=b&ya&&0===d-e,g=b&(Aa|Ba)&&0===d-e;c.isFirst=!!f,c.isFinal=!!g,f&&(a.session={}),c.eventType=b,B(a,c),a.emit("hammer.input",c),a.recognize(c),a.session.prevInput=c}function B(a,b){var c=a.session,d=b.pointers,e=d.length;c.firstInput||(c.firstInput=E(b)),e>1&&!c.firstMultiple?c.firstMultiple=E(b):1===e&&(c.firstMultiple=!1);var f=c.firstInput,g=c.firstMultiple,h=g?g.center:f.center,i=b.center=F(d);b.timeStamp=na(),b.deltaTime=b.timeStamp-f.timeStamp,b.angle=J(h,i),b.distance=I(h,i),C(c,b),b.offsetDirection=H(b.deltaX,b.deltaY),b.scale=g?L(g.pointers,d):1,b.rotation=g?K(g.pointers,d):0,D(c,b);var j=a.element;p(b.srcEvent.target,j)&&(j=b.srcEvent.target),b.target=j}function C(a,b){var c=b.center,d=a.offsetDelta||{},e=a.prevDelta||{},f=a.prevInput||{};(b.eventType===ya||f.eventType===Aa)&&(e=a.prevDelta={x:f.deltaX||0,y:f.deltaY||0},d=a.offsetDelta={x:c.x,y:c.y}),b.deltaX=e.x+(c.x-d.x),b.deltaY=e.y+(c.y-d.y)}function D(a,b){var c,e,f,g,h=a.lastInterval||b,i=b.timeStamp-h.timeStamp;if(b.eventType!=Ba&&(i>xa||h.velocity===d)){var j=h.deltaX-b.deltaX,k=h.deltaY-b.deltaY,l=G(i,j,k);e=l.x,f=l.y,c=ma(l.x)>ma(l.y)?l.x:l.y,g=H(j,k),a.lastInterval=b}else c=h.velocity,e=h.velocityX,f=h.velocityY,g=h.direction;b.velocity=c,b.velocityX=e,b.velocityY=f,b.direction=g}function E(a){for(var b=[],c=0;c<a.pointers.length;)b[c]={clientX:la(a.pointers[c].clientX),clientY:la(a.pointers[c].clientY)},c++;return{timeStamp:na(),pointers:b,center:F(b),deltaX:a.deltaX,deltaY:a.deltaY}}function F(a){var b=a.length;if(1===b)return{x:la(a[0].clientX),y:la(a[0].clientY)};for(var c=0,d=0,e=0;b>e;)c+=a[e].clientX,d+=a[e].clientY,e++;return{x:la(c/b),y:la(d/b)}}function G(a,b,c){return{x:b/a||0,y:c/a||0}}function H(a,b){return a===b?Ca:ma(a)>=ma(b)?a>0?Da:Ea:b>0?Fa:Ga}function I(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return Math.sqrt(d*d+e*e)}function J(a,b,c){c||(c=Ka);var d=b[c[0]]-a[c[0]],e=b[c[1]]-a[c[1]];return 180*Math.atan2(e,d)/Math.PI}function K(a,b){return J(b[1],b[0],La)-J(a[1],a[0],La)}function L(a,b){return I(b[0],b[1],La)/I(a[0],a[1],La)}function M(){this.evEl=Na,this.evWin=Oa,this.allow=!0,this.pressed=!1,y.apply(this,arguments)}function N(){this.evEl=Ra,this.evWin=Sa,y.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function O(){this.evTarget=Ua,this.evWin=Va,this.started=!1,y.apply(this,arguments)}function P(a,b){var c=t(a.touches),d=t(a.changedTouches);return b&(Aa|Ba)&&(c=u(c.concat(d),"identifier",!0)),[c,d]}function Q(){this.evTarget=Xa,this.targetIds={},y.apply(this,arguments)}function R(a,b){var c=t(a.touches),d=this.targetIds;if(b&(ya|za)&&1===c.length)return d[c[0].identifier]=!0,[c,c];var e,f,g=t(a.changedTouches),h=[],i=this.target;if(f=c.filter(function(a){return p(a.target,i)}),b===ya)for(e=0;e<f.length;)d[f[e].identifier]=!0,e++;for(e=0;e<g.length;)d[g[e].identifier]&&h.push(g[e]),b&(Aa|Ba)&&delete d[g[e].identifier],e++;return h.length?[u(f.concat(h),"identifier",!0),h]:void 0}function S(){y.apply(this,arguments);var a=k(this.handler,this);this.touch=new Q(this.manager,a),this.mouse=new M(this.manager,a)}function T(a,b){this.manager=a,this.set(b)}function U(a){if(q(a,bb))return bb;var b=q(a,cb),c=q(a,db);return b&&c?cb+" "+db:b||c?b?cb:db:q(a,ab)?ab:_a}function V(a){this.id=w(),this.manager=null,this.options=i(a||{},this.defaults),this.options.enable=m(this.options.enable,!0),this.state=eb,this.simultaneous={},this.requireFail=[]}function W(a){return a&jb?"cancel":a&hb?"end":a&gb?"move":a&fb?"start":""}function X(a){return a==Ga?"down":a==Fa?"up":a==Da?"left":a==Ea?"right":""}function Y(a,b){var c=b.manager;return c?c.get(a):a}function Z(){V.apply(this,arguments)}function $(){Z.apply(this,arguments),this.pX=null,this.pY=null}function _(){Z.apply(this,arguments)}function aa(){V.apply(this,arguments),this._timer=null,this._input=null}function ba(){Z.apply(this,arguments)}function ca(){Z.apply(this,arguments)}function da(){V.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function ea(a,b){return b=b||{},b.recognizers=m(b.recognizers,ea.defaults.preset),new fa(a,b)}function fa(a,b){b=b||{},this.options=i(b,ea.defaults),this.options.inputTarget=this.options.inputTarget||a,this.handlers={},this.session={},this.recognizers=[],this.element=a,this.input=z(this),this.touchAction=new T(this,this.options.touchAction),ga(this,!0),g(b.recognizers,function(a){var b=this.add(new a[0](a[1]));a[2]&&b.recognizeWith(a[2]),a[3]&&b.requireFailure(a[3])},this)}function ga(a,b){var c=a.element;g(a.options.cssProps,function(a,d){c.style[v(c.style,d)]=b?a:""})}function ha(a,c){var d=b.createEvent("Event");d.initEvent(a,!0,!0),d.gesture=c,c.target.dispatchEvent(d)}var ia=["","webkit","moz","MS","ms","o"],ja=b.createElement("div"),ka="function",la=Math.round,ma=Math.abs,na=Date.now,oa=1,pa=/mobile|tablet|ip(ad|hone|od)|android/i,qa="ontouchstart"in a,ra=v(a,"PointerEvent")!==d,sa=qa&&pa.test(navigator.userAgent),ta="touch",ua="pen",va="mouse",wa="kinect",xa=25,ya=1,za=2,Aa=4,Ba=8,Ca=1,Da=2,Ea=4,Fa=8,Ga=16,Ha=Da|Ea,Ia=Fa|Ga,Ja=Ha|Ia,Ka=["x","y"],La=["clientX","clientY"];y.prototype={handler:function(){},init:function(){this.evEl&&n(this.element,this.evEl,this.domHandler),this.evTarget&&n(this.target,this.evTarget,this.domHandler),this.evWin&&n(x(this.element),this.evWin,this.domHandler)},destroy:function(){this.evEl&&o(this.element,this.evEl,this.domHandler),this.evTarget&&o(this.target,this.evTarget,this.domHandler),this.evWin&&o(x(this.element),this.evWin,this.domHandler)}};var Ma={mousedown:ya,mousemove:za,mouseup:Aa},Na="mousedown",Oa="mousemove mouseup";j(M,y,{handler:function(a){var b=Ma[a.type];b&ya&&0===a.button&&(this.pressed=!0),b&za&&1!==a.which&&(b=Aa),this.pressed&&this.allow&&(b&Aa&&(this.pressed=!1),this.callback(this.manager,b,{pointers:[a],changedPointers:[a],pointerType:va,srcEvent:a}))}});var Pa={pointerdown:ya,pointermove:za,pointerup:Aa,pointercancel:Ba,pointerout:Ba},Qa={2:ta,3:ua,4:va,5:wa},Ra="pointerdown",Sa="pointermove pointerup pointercancel";a.MSPointerEvent&&(Ra="MSPointerDown",Sa="MSPointerMove MSPointerUp MSPointerCancel"),j(N,y,{handler:function(a){var b=this.store,c=!1,d=a.type.toLowerCase().replace("ms",""),e=Pa[d],f=Qa[a.pointerType]||a.pointerType,g=f==ta,h=s(b,a.pointerId,"pointerId");e&ya&&(0===a.button||g)?0>h&&(b.push(a),h=b.length-1):e&(Aa|Ba)&&(c=!0),0>h||(b[h]=a,this.callback(this.manager,e,{pointers:b,changedPointers:[a],pointerType:f,srcEvent:a}),c&&b.splice(h,1))}});var Ta={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Ua="touchstart",Va="touchstart touchmove touchend touchcancel";j(O,y,{handler:function(a){var b=Ta[a.type];if(b===ya&&(this.started=!0),this.started){var c=P.call(this,a,b);b&(Aa|Ba)&&0===c[0].length-c[1].length&&(this.started=!1),this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}});var Wa={touchstart:ya,touchmove:za,touchend:Aa,touchcancel:Ba},Xa="touchstart touchmove touchend touchcancel";j(Q,y,{handler:function(a){var b=Wa[a.type],c=R.call(this,a,b);c&&this.callback(this.manager,b,{pointers:c[0],changedPointers:c[1],pointerType:ta,srcEvent:a})}}),j(S,y,{handler:function(a,b,c){var d=c.pointerType==ta,e=c.pointerType==va;if(d)this.mouse.allow=!1;else if(e&&!this.mouse.allow)return;b&(Aa|Ba)&&(this.mouse.allow=!0),this.callback(a,b,c)},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var Ya=v(ja.style,"touchAction"),Za=Ya!==d,$a="compute",_a="auto",ab="manipulation",bb="none",cb="pan-x",db="pan-y";T.prototype={set:function(a){a==$a&&(a=this.compute()),Za&&(this.manager.element.style[Ya]=a),this.actions=a.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var a=[];return g(this.manager.recognizers,function(b){l(b.options.enable,[b])&&(a=a.concat(b.getTouchAction()))}),U(a.join(" "))},preventDefaults:function(a){if(!Za){var b=a.srcEvent,c=a.offsetDirection;if(this.manager.session.prevented)return void b.preventDefault();var d=this.actions,e=q(d,bb),f=q(d,db),g=q(d,cb);return e||f&&c&Ha||g&&c&Ia?this.preventSrc(b):void 0}},preventSrc:function(a){this.manager.session.prevented=!0,a.preventDefault()}};var eb=1,fb=2,gb=4,hb=8,ib=hb,jb=16,kb=32;V.prototype={defaults:{},set:function(a){return h(this.options,a),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(a){if(f(a,"recognizeWith",this))return this;var b=this.simultaneous;return a=Y(a,this),b[a.id]||(b[a.id]=a,a.recognizeWith(this)),this},dropRecognizeWith:function(a){return f(a,"dropRecognizeWith",this)?this:(a=Y(a,this),delete this.simultaneous[a.id],this)},requireFailure:function(a){if(f(a,"requireFailure",this))return this;var b=this.requireFail;return a=Y(a,this),-1===s(b,a)&&(b.push(a),a.requireFailure(this)),this},dropRequireFailure:function(a){if(f(a,"dropRequireFailure",this))return this;a=Y(a,this);var b=s(this.requireFail,a);return b>-1&&this.requireFail.splice(b,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(a){return!!this.simultaneous[a.id]},emit:function(a){function b(b){c.manager.emit(c.options.event+(b?W(d):""),a)}var c=this,d=this.state;hb>d&&b(!0),b(),d>=hb&&b(!0)},tryEmit:function(a){return this.canEmit()?this.emit(a):void(this.state=kb)},canEmit:function(){for(var a=0;a<this.requireFail.length;){if(!(this.requireFail[a].state&(kb|eb)))return!1;a++}return!0},recognize:function(a){var b=h({},a);return l(this.options.enable,[this,b])?(this.state&(ib|jb|kb)&&(this.state=eb),this.state=this.process(b),void(this.state&(fb|gb|hb|jb)&&this.tryEmit(b))):(this.reset(),void(this.state=kb))},process:function(){},getTouchAction:function(){},reset:function(){}},j(Z,V,{defaults:{pointers:1},attrTest:function(a){var b=this.options.pointers;return 0===b||a.pointers.length===b},process:function(a){var b=this.state,c=a.eventType,d=b&(fb|gb),e=this.attrTest(a);return d&&(c&Ba||!e)?b|jb:d||e?c&Aa?b|hb:b&fb?b|gb:fb:kb}}),j($,Z,{defaults:{event:"pan",threshold:10,pointers:1,direction:Ja},getTouchAction:function(){var a=this.options.direction,b=[];return a&Ha&&b.push(db),a&Ia&&b.push(cb),b},directionTest:function(a){var b=this.options,c=!0,d=a.distance,e=a.direction,f=a.deltaX,g=a.deltaY;return e&b.direction||(b.direction&Ha?(e=0===f?Ca:0>f?Da:Ea,c=f!=this.pX,d=Math.abs(a.deltaX)):(e=0===g?Ca:0>g?Fa:Ga,c=g!=this.pY,d=Math.abs(a.deltaY))),a.direction=e,c&&d>b.threshold&&e&b.direction},attrTest:function(a){return Z.prototype.attrTest.call(this,a)&&(this.state&fb||!(this.state&fb)&&this.directionTest(a))},emit:function(a){this.pX=a.deltaX,this.pY=a.deltaY;var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this._super.emit.call(this,a)}}),j(_,Z,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.scale-1)>this.options.threshold||this.state&fb)},emit:function(a){if(this._super.emit.call(this,a),1!==a.scale){var b=a.scale<1?"in":"out";this.manager.emit(this.options.event+b,a)}}}),j(aa,V,{defaults:{event:"press",pointers:1,time:500,threshold:5},getTouchAction:function(){return[_a]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime>b.time;if(this._input=a,!d||!c||a.eventType&(Aa|Ba)&&!f)this.reset();else if(a.eventType&ya)this.reset(),this._timer=e(function(){this.state=ib,this.tryEmit()},b.time,this);else if(a.eventType&Aa)return ib;return kb},reset:function(){clearTimeout(this._timer)},emit:function(a){this.state===ib&&(a&&a.eventType&Aa?this.manager.emit(this.options.event+"up",a):(this._input.timeStamp=na(),this.manager.emit(this.options.event,this._input)))}}),j(ba,Z,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[bb]},attrTest:function(a){return this._super.attrTest.call(this,a)&&(Math.abs(a.rotation)>this.options.threshold||this.state&fb)}}),j(ca,Z,{defaults:{event:"swipe",threshold:10,velocity:.65,direction:Ha|Ia,pointers:1},getTouchAction:function(){return $.prototype.getTouchAction.call(this)},attrTest:function(a){var b,c=this.options.direction;return c&(Ha|Ia)?b=a.velocity:c&Ha?b=a.velocityX:c&Ia&&(b=a.velocityY),this._super.attrTest.call(this,a)&&c&a.direction&&a.distance>this.options.threshold&&ma(b)>this.options.velocity&&a.eventType&Aa},emit:function(a){var b=X(a.direction);b&&this.manager.emit(this.options.event+b,a),this.manager.emit(this.options.event,a)}}),j(da,V,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:2,posThreshold:10},getTouchAction:function(){return[ab]},process:function(a){var b=this.options,c=a.pointers.length===b.pointers,d=a.distance<b.threshold,f=a.deltaTime<b.time;if(this.reset(),a.eventType&ya&&0===this.count)return this.failTimeout();if(d&&f&&c){if(a.eventType!=Aa)return this.failTimeout();var g=this.pTime?a.timeStamp-this.pTime<b.interval:!0,h=!this.pCenter||I(this.pCenter,a.center)<b.posThreshold;this.pTime=a.timeStamp,this.pCenter=a.center,h&&g?this.count+=1:this.count=1,this._input=a;var i=this.count%b.taps;if(0===i)return this.hasRequireFailures()?(this._timer=e(function(){this.state=ib,this.tryEmit()},b.interval,this),fb):ib}return kb},failTimeout:function(){return this._timer=e(function(){this.state=kb},this.options.interval,this),kb},reset:function(){clearTimeout(this._timer)},emit:function(){this.state==ib&&(this._input.tapCount=this.count,this.manager.emit(this.options.event,this._input))}}),ea.VERSION="2.0.4",ea.defaults={domEvents:!1,touchAction:$a,enable:!0,inputTarget:null,inputClass:null,preset:[[ba,{enable:!1}],[_,{enable:!1},["rotate"]],[ca,{direction:Ha}],[$,{direction:Ha},["swipe"]],[da],[da,{event:"doubletap",taps:2},["tap"]],[aa]],cssProps:{userSelect:"default",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}};var lb=1,mb=2;fa.prototype={set:function(a){return h(this.options,a),a.touchAction&&this.touchAction.update(),a.inputTarget&&(this.input.destroy(),this.input.target=a.inputTarget,this.input.init()),this},stop:function(a){this.session.stopped=a?mb:lb},recognize:function(a){var b=this.session;if(!b.stopped){this.touchAction.preventDefaults(a);var c,d=this.recognizers,e=b.curRecognizer;(!e||e&&e.state&ib)&&(e=b.curRecognizer=null);for(var f=0;f<d.length;)c=d[f],b.stopped===mb||e&&c!=e&&!c.canRecognizeWith(e)?c.reset():c.recognize(a),!e&&c.state&(fb|gb|hb)&&(e=b.curRecognizer=c),f++}},get:function(a){if(a instanceof V)return a;for(var b=this.recognizers,c=0;c<b.length;c++)if(b[c].options.event==a)return b[c];return null},add:function(a){if(f(a,"add",this))return this;var b=this.get(a.options.event);return b&&this.remove(b),this.recognizers.push(a),a.manager=this,this.touchAction.update(),a},remove:function(a){if(f(a,"remove",this))return this;var b=this.recognizers;return a=this.get(a),b.splice(s(b,a),1),this.touchAction.update(),this},on:function(a,b){var c=this.handlers;return g(r(a),function(a){c[a]=c[a]||[],c[a].push(b)}),this},off:function(a,b){var c=this.handlers;return g(r(a),function(a){b?c[a].splice(s(c[a],b),1):delete c[a]}),this},emit:function(a,b){this.options.domEvents&&ha(a,b);var c=this.handlers[a]&&this.handlers[a].slice();if(c&&c.length){b.type=a,b.preventDefault=function(){b.srcEvent.preventDefault()};for(var d=0;d<c.length;)c[d](b),d++}},destroy:function(){this.element&&ga(this,!1),this.handlers={},this.session={},this.input.destroy(),this.element=null}},h(ea,{INPUT_START:ya,INPUT_MOVE:za,INPUT_END:Aa,INPUT_CANCEL:Ba,STATE_POSSIBLE:eb,STATE_BEGAN:fb,STATE_CHANGED:gb,STATE_ENDED:hb,STATE_RECOGNIZED:ib,STATE_CANCELLED:jb,STATE_FAILED:kb,DIRECTION_NONE:Ca,DIRECTION_LEFT:Da,DIRECTION_RIGHT:Ea,DIRECTION_UP:Fa,DIRECTION_DOWN:Ga,DIRECTION_HORIZONTAL:Ha,DIRECTION_VERTICAL:Ia,DIRECTION_ALL:Ja,Manager:fa,Input:y,TouchAction:T,TouchInput:Q,MouseInput:M,PointerEventInput:N,TouchMouseInput:S,SingleTouchInput:O,Recognizer:V,AttrRecognizer:Z,Tap:da,Pan:$,Swipe:ca,Pinch:_,Rotate:ba,Press:aa,on:n,off:o,each:g,merge:i,extend:h,inherit:j,bindFn:k,prefixed:v}),typeof define==ka&&define.amd?define(function(){return ea}):"undefined"!=typeof module&&module.exports?module.exports=ea:a[c]=ea}(window,document,"Hammer"),function(a){"function"==typeof define&&define.amd?define(["jquery","hammerjs"],a):"object"==typeof exports?a(require("jquery"),require("hammerjs")):a(jQuery,Hammer)}(function(a,b){function c(c,d){var e=a(c);e.data("hammer")||e.data("hammer",new b(e[0],d))}a.fn.hammer=function(a){return this.each(function(){c(this,a)})},b.Manager.prototype.emit=function(b){return function(c,d){b.call(this,c,d),a(this.element).trigger({type:c,gesture:d})}}(b.Manager.prototype.emit)}),Materialize={},Materialize.guid=function(){function a(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return function(){return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()}}(),Materialize.elementOrParentIsFixed=function(a){var b=$(a),c=b.add(b.parents()),d=!1;return c.each(function(){return"fixed"===$(this).css("position")?(d=!0,!1):void 0}),d};var Vel;Vel=$?$.Velocity:Velocity,function(a){a.fn.collapsible=function(b){var c={accordion:void 0};return b=a.extend(c,b),this.each(function(){function c(b){h=g.find("> li > .collapsible-header"),b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}),h.not(b).removeClass("active").parent().removeClass("active"),h.not(b).parent().children(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}})}function d(b){b.hasClass("active")?b.parent().addClass("active"):b.parent().removeClass("active"),b.parent().hasClass("active")?b.siblings(".collapsible-body").stop(!0,!1).slideDown({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}}):b.siblings(".collapsible-body").stop(!0,!1).slideUp({duration:350,easing:"easeOutQuart",queue:!1,complete:function(){a(this).css("height","")}})}function e(a){var b=f(a);return b.length>0}function f(a){return a.closest("li > .collapsible-header")}var g=a(this),h=a(this).find("> li > .collapsible-header"),i=g.data("collapsible");g.off("click.collapse",".collapsible-header"),h.off("click.collapse"),b.accordion||"accordion"==i||void 0==i?(h=g.find("> li > .collapsible-header"),h.on("click.collapse",function(b){var d=a(b.target);e(d)&&(d=f(d)),d.toggleClass("active"),c(d)}),c(h.filter(".active").first())):h.each(function(){a(this).on("click.collapse",function(b){var c=a(b.target);e(c)&&(c=f(c)),c.toggleClass("active"),d(c)}),a(this).hasClass("active")&&d(a(this))})})},a(document).ready(function(){a(".collapsible").collapsible()})}(jQuery),function(a){a.fn.scrollTo=function(b){return a(this).scrollTop(a(this).scrollTop()-a(this).offset().top+a(b).offset().top),this},a.fn.dropdown=function(b){var c={inDuration:300,outDuration:225,constrain_width:!0,hover:!1,gutter:0,belowOrigin:!1};this.each(function(){function d(){void 0!=g.data("induration")&&(h.inDuration=g.data("inDuration")),void 0!=g.data("outduration")&&(h.outDuration=g.data("outDuration")),void 0!=g.data("constrainwidth")&&(h.constrain_width=g.data("constrainwidth")),void 0!=g.data("hover")&&(h.hover=g.data("hover")),void 0!=g.data("gutter")&&(h.gutter=g.data("gutter")),void 0!=g.data("beloworigin")&&(h.belowOrigin=g.data("beloworigin"))}function e(){d(),i.addClass("active"),1==h.constrain_width&&i.css("width",g.outerWidth());var b=0;1==h.belowOrigin&&(b=g.height());var c=g.offset().left,e=0,f=h.gutter;c+i.innerWidth()>a(window).width()&&(e=g.innerWidth()-i.innerWidth(),f=-1*f),i.css({position:"absolute",top:g.position().top+b,left:g.position().left+e+f}),i.stop(!0,!0).css("opacity",0).slideDown({queue:!1,duration:h.inDuration,easing:"easeOutCubic",complete:function(){a(this).css("height","")}}).animate({opacity:1},{queue:!1,duration:h.inDuration,easing:"easeOutSine"})}function f(){i.fadeOut(h.outDuration),i.removeClass("active")}var g=a(this),h=a.extend({},c,b),i=a("#"+g.attr("data-activates"));if(d(),g.after(i),h.hover){var j=!1;g.unbind("click."+g.attr("id")),g.on("mouseenter",function(){j===!1&&(e(),j=!0)}),g.on("mouseleave",function(b){a(b.toElement).closest(".dropdown-content").is(i)||(i.stop(!0,!0),f(),j=!1)}),i.on("mouseleave",function(b){a(b.toElement).closest(".dropdown-button").is(g)||(i.stop(!0,!0),f(),j=!1)})}else g.unbind("click."+g.attr("id")),g.bind("click."+g.attr("id"),function(b){g[0]==b.currentTarget&&0===a(b.target).closest(".dropdown-content").length?(b.preventDefault(),e()):g.hasClass("active")&&(f(),a(document).unbind("click."+i.attr("id"))),i.hasClass("active")&&a(document).bind("click."+i.attr("id"),function(b){!i.is(b.target)&&!g.is(b.target)&&!g.find(b.target).length>0&&(f(),a(document).unbind("click."+i.attr("id")))})});g.on("open",e),g.on("close",f)})},a(document).ready(function(){a(".dropdown-button").dropdown()})}(jQuery),function(a){a.fn.extend({openModal:function(b){var c=this,d=a('<div id="lean-overlay"></div>');a("body").append(d);var e={opacity:.5,in_duration:350,out_duration:250,ready:void 0,complete:void 0,dismissible:!0};b=a.extend(e,b),b.dismissible&&(a("#lean-overlay").click(function(){a(c).closeModal(b)}),a(document).on("keyup.leanModal",function(d){27===d.keyCode&&a(c).closeModal(b)})),a(c).find(".modal-close").click(function(){a(c).closeModal(b)}),a("#lean-overlay").css({display:"block",opacity:0}),a(c).css({display:"block",opacity:0}),a("#lean-overlay").velocity({opacity:b.opacity},{duration:b.in_duration,queue:!1,ease:"easeOutCubic"}),a(c).hasClass("bottom-sheet")?a(c).velocity({bottom:"0",opacity:1},{duration:b.in_duration,queue:!1,ease:"easeOutCubic",complete:function(){"function"==typeof b.ready&&b.ready()}}):(a(c).css({top:"4%"}),a(c).velocity({top:"10%",opacity:1},{duration:b.in_duration,queue:!1,ease:"easeOutCubic",complete:function(){"function"==typeof b.ready&&b.ready()}}))}}),a.fn.extend({closeModal:function(b){var c={out_duration:250,complete:void 0},b=a.extend(c,b);a(".modal-close").off(),a(document).off("keyup.leanModal"),a("#lean-overlay").velocity({opacity:0},{duration:b.out_duration,queue:!1,ease:"easeOutQuart"}),a(this).hasClass("bottom-sheet")?a(this).velocity({bottom:"-100%",opacity:0},{duration:b.out_duration,queue:!1,ease:"easeOutCubic",complete:function(){a("#lean-overlay").css({display:"none"}),"function"==typeof b.complete&&b.complete(),a("#lean-overlay").remove()}}):a(this).fadeOut(b.out_duration,function(){a(this).css({top:0}),a("#lean-overlay").css({display:"none"}),"function"==typeof b.complete&&b.complete(),a("#lean-overlay").remove()})}}),a.fn.extend({leanModal:function(b){return this.each(function(){a(this).click(function(c){var d=a(this).attr("href")||"#"+a(this).data("target");a(d).openModal(b),c.preventDefault()})})}})}(jQuery),function(a){a.fn.materialbox=function(){return this.each(function(){function b(){d=!1;var b=g.parent(".material-placeholder"),e=(window.innerWidth,window.innerHeight,g.data("width")),h=g.data("height");g.velocity("stop",!0),a("#materialbox-overlay").velocity("stop",!0),a(".materialbox-caption").velocity("stop",!0),a("#materialbox-overlay").velocity({opacity:0},{duration:f,queue:!1,easing:"easeOutQuad",complete:function(){c=!1,a(this).remove()}}),g.velocity({width:e,height:h,left:0,top:0},{duration:f,queue:!1,easing:"easeOutQuad"}),a(".materialbox-caption").velocity({opacity:0},{duration:f,queue:!1,easing:"easeOutQuad",complete:function(){b.css({height:"",width:"",position:"",top:"",left:""}),g.css({height:"",top:"",left:"",width:"","max-width":"",position:"","z-index":""}),g.removeClass("active"),d=!0,a(this).remove()}})}if(!a(this).hasClass("intialized")){a(this).addClass("intialized"); - -var c=!1,d=!0,e=275,f=200,g=a(this),h=a("<div></div>").addClass("material-placeholder");g.wrap(h),g.on("click",function(){var f=g.parent(".material-placeholder"),h=window.innerWidth,i=window.innerHeight,j=g.width(),k=g.height();if(d===!1)return b(),!1;if(c&&d===!0)return b(),!1;d=!1,g.addClass("active"),c=!0,f.css({width:f[0].getBoundingClientRect().width,height:f[0].getBoundingClientRect().height,position:"relative",top:0,left:0}),g.css({position:"absolute","z-index":1e3}).data("width",j).data("height",k);var l=a('<div id="materialbox-overlay"></div>').css({opacity:0}).click(function(){d===!0&&b()});if(a("body").append(l),l.velocity({opacity:1},{duration:e,queue:!1,easing:"easeOutQuad"}),""!==g.data("caption")){var m=a('<div class="materialbox-caption"></div>');m.text(g.data("caption")),a("body").append(m),m.css({display:"inline"}),m.velocity({opacity:1},{duration:e,queue:!1,easing:"easeOutQuad"})}var n=0,o=j/h,p=k/i,q=0,r=0;o>p?(n=k/j,q=.9*h,r=.9*h*n):(n=j/k,q=.9*i*n,r=.9*i),g.hasClass("responsive-img")?g.velocity({"max-width":q,width:j},{duration:0,queue:!1,complete:function(){g.css({left:0,top:0}).velocity({height:r,width:q,left:a(document).scrollLeft()+h/2-g.parent(".material-placeholder").offset().left-q/2,top:a(document).scrollTop()+i/2-g.parent(".material-placeholder").offset().top-r/2},{duration:e,queue:!1,easing:"easeOutQuad",complete:function(){d=!0}})}}):g.css("left",0).css("top",0).velocity({height:r,width:q,left:a(document).scrollLeft()+h/2-g.parent(".material-placeholder").offset().left-q/2,top:a(document).scrollTop()+i/2-g.parent(".material-placeholder").offset().top-r/2},{duration:e,queue:!1,easing:"easeOutQuad",complete:function(){d=!0}})}),a(window).scroll(function(){c&&b()}),a(document).keyup(function(a){27===a.keyCode&&d===!0&&c&&b()})}})},a(document).ready(function(){a(".materialboxed").materialbox()})}(jQuery),function(a){a.fn.parallax=function(){var b=a(window).width();return this.each(function(){function c(c){var e;e=601>b?d.height()>0?d.height():d.children("img").height():d.height()>0?d.height():500;var f=d.children("img").first(),g=f.height(),h=g-e,i=d.offset().top+e,j=d.offset().top,k=a(window).scrollTop(),l=window.innerHeight,m=k+l,n=(m-j)/(e+l),o=Math.round(h*n);c&&f.css("display","block"),i>k&&k+l>j&&f.css("transform","translate3D(-50%,"+o+"px, 0)")}var d=a(this);d.addClass("parallax"),d.children("img").one("load",function(){c(!0)}).each(function(){this.complete&&a(this).load()}),a(window).scroll(function(){b=a(window).width(),c(!1)}),a(window).resize(function(){b=a(window).width(),c(!1)})})}}(jQuery),function(a){var b={init:function(){return this.each(function(){{var b=a(this);a(window).width()}b.width("100%");var c=a(this).children("li").length;b.children("li").each(function(){a(this).width(100/c+"%")});var d,e,f=b.find("li.tab a"),g=b.width(),h=b.find("li").first().outerWidth(),i=0;d=a(f.filter('[href="'+location.hash+'"]')),0===d.length&&(d=a(this).find("li.tab a.active").first()),0===d.length&&(d=a(this).find("li.tab a").first()),d.addClass("active"),i=f.index(d),0>i&&(i=0),e=a(d[0].hash),b.append('<div class="indicator"></div>');var j=b.find(".indicator");b.is(":visible")&&(j.css({right:g-(i+1)*h}),j.css({left:i*h})),a(window).resize(function(){g=b.width(),h=b.find("li").first().outerWidth(),0>i&&(i=0),0!==h&&0!==g&&(j.css({right:g-(i+1)*h}),j.css({left:i*h}))}),f.not(d).each(function(){a(this.hash).hide()}),b.on("click","a",function(c){g=b.width(),h=b.find("li").first().outerWidth(),d.removeClass("active"),e.hide(),d=a(this),e=a(this.hash),f=b.find("li.tab a"),d.addClass("active");var k=i;i=f.index(a(this)),0>i&&(i=0),e.show(),i-k>=0?(j.velocity({right:g-(i+1)*h},{duration:300,queue:!1,easing:"easeOutQuad"}),j.velocity({left:i*h},{duration:300,queue:!1,easing:"easeOutQuad",delay:90})):(j.velocity({left:i*h},{duration:300,queue:!1,easing:"easeOutQuad"}),j.velocity({right:g-(i+1)*h},{duration:300,queue:!1,easing:"easeOutQuad",delay:90})),c.preventDefault()})})},select_tab:function(a){this.find('a[href="#'+a+'"]').trigger("click")}};a.fn.tabs=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tooltip"):b.init.apply(this,arguments)},a(document).ready(function(){a("ul.tabs").tabs()})}(jQuery),function(a){a.fn.tooltip=function(b){var c=null,d=!1,e=null,f=5,g={delay:350};return b=a.extend(g,b),a(".material-tooltip").remove(),this.each(function(){var g=a(this),h=a("<span></span>").text(g.attr("data-tooltip")),i=a("<div></div>");i.addClass("material-tooltip").append(h),i.appendTo(a("body"));var j=a("<div></div>").addClass("backdrop");j.appendTo(i),j.css({top:0,left:0}),a(this).off("mouseenter mouseleave"),a(this).on({mouseenter:function(){var a=g.data("delay");a=void 0==a||""==a?b.delay:a,c=0,e=setInterval(function(){if(c+=10,c>=a&&0==d){d=!0,i.css({display:"block",left:"0px",top:"0px"}),i.children("span").text(g.attr("data-tooltip"));var b=g.outerWidth(),e=g.outerHeight(),h=g.attr("data-position"),k=i.outerHeight(),l=i.outerWidth(),m="0px",n="0px",o=8;"top"===h?(i.css({top:g.offset().top-k-f,left:g.offset().left+b/2-l/2}),m="-10px",j.css({borderRadius:"14px 14px 0 0",transformOrigin:"50% 90%",marginTop:k,marginLeft:l/2-j.width()/2})):"left"===h?(i.css({top:g.offset().top+e/2-k/2,left:g.offset().left-l-f}),n="-10px",j.css({width:"14px",height:"14px",borderRadius:"14px 0 0 14px",transformOrigin:"95% 50%",marginTop:k/2,marginLeft:l})):"right"===h?(i.css({top:g.offset().top+e/2-k/2,left:g.offset().left+b+f}),n="+10px",j.css({width:"14px",height:"14px",borderRadius:"0 14px 14px 0",transformOrigin:"5% 50%",marginTop:k/2,marginLeft:"0px"})):(i.css({top:g.offset().top+g.outerHeight()+f,left:g.offset().left+b/2-l/2}),m="+10px",j.css({marginLeft:l/2-j.width()/2})),o=l/8,8>o&&(o=8),("right"===h||"left"===h)&&(o=l/10,6>o&&(o=6)),i.velocity({opacity:1,marginTop:m,marginLeft:n},{duration:350,queue:!1}),j.css({display:"block"}).velocity({opacity:1},{duration:55,delay:0,queue:!1}).velocity({scale:o},{duration:300,delay:0,queue:!1,easing:"easeInOutQuad"})}},10)},mouseleave:function(){clearInterval(e),c=0,i.velocity({opacity:0,marginTop:0,marginLeft:0},{duration:225,queue:!1,delay:275}),j.velocity({opacity:0,scale:1},{duration:225,delay:275,queue:!1,complete:function(){j.css("display","none"),i.css("display","none"),d=!1}})}})})},a(document).ready(function(){a(".tooltipped").tooltip()})}(jQuery),function(a){"use strict";function b(a){return null!==a&&a===a.window}function c(a){return b(a)?a:9===a.nodeType&&a.defaultView}function d(a){var b,d,e={top:0,left:0},f=a&&a.ownerDocument;return b=f.documentElement,"undefined"!=typeof a.getBoundingClientRect&&(e=a.getBoundingClientRect()),d=c(f),{top:e.top+d.pageYOffset-b.clientTop,left:e.left+d.pageXOffset-b.clientLeft}}function e(a){var b="";for(var c in a)a.hasOwnProperty(c)&&(b+=c+":"+a[c]+";");return b}function f(a){if(k.allowEvent(a)===!1)return null;for(var b=null,c=a.target||a.srcElement;null!==c.parentElement;){if(!(c instanceof SVGElement||-1===c.className.indexOf("waves-effect"))){b=c;break}if(c.classList.contains("waves-effect")){b=c;break}c=c.parentElement}return b}function g(b){var c=f(b);null!==c&&(j.show(b,c),"ontouchstart"in a&&(c.addEventListener("touchend",j.hide,!1),c.addEventListener("touchcancel",j.hide,!1)),c.addEventListener("mouseup",j.hide,!1),c.addEventListener("mouseleave",j.hide,!1))}var h=h||{},i=document.querySelectorAll.bind(document),j={duration:750,show:function(a,b){if(2===a.button)return!1;var c=b||this,f=document.createElement("div");f.className="waves-ripple",c.appendChild(f);var g=d(c),h=a.pageY-g.top,i=a.pageX-g.left,k="scale("+c.clientWidth/100*10+")";"touches"in a&&(h=a.touches[0].pageY-g.top,i=a.touches[0].pageX-g.left),f.setAttribute("data-hold",Date.now()),f.setAttribute("data-scale",k),f.setAttribute("data-x",i),f.setAttribute("data-y",h);var l={top:h+"px",left:i+"px"};f.className=f.className+" waves-notransition",f.setAttribute("style",e(l)),f.className=f.className.replace("waves-notransition",""),l["-webkit-transform"]=k,l["-moz-transform"]=k,l["-ms-transform"]=k,l["-o-transform"]=k,l.transform=k,l.opacity="1",l["-webkit-transition-duration"]=j.duration+"ms",l["-moz-transition-duration"]=j.duration+"ms",l["-o-transition-duration"]=j.duration+"ms",l["transition-duration"]=j.duration+"ms",l["-webkit-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-moz-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["-o-transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",l["transition-timing-function"]="cubic-bezier(0.250, 0.460, 0.450, 0.940)",f.setAttribute("style",e(l))},hide:function(a){k.touchup(a);var b=this,c=(1.4*b.clientWidth,null),d=b.getElementsByClassName("waves-ripple");if(!(d.length>0))return!1;c=d[d.length-1];var f=c.getAttribute("data-x"),g=c.getAttribute("data-y"),h=c.getAttribute("data-scale"),i=Date.now()-Number(c.getAttribute("data-hold")),l=350-i;0>l&&(l=0),setTimeout(function(){var a={top:g+"px",left:f+"px",opacity:"0","-webkit-transition-duration":j.duration+"ms","-moz-transition-duration":j.duration+"ms","-o-transition-duration":j.duration+"ms","transition-duration":j.duration+"ms","-webkit-transform":h,"-moz-transform":h,"-ms-transform":h,"-o-transform":h,transform:h};c.setAttribute("style",e(a)),setTimeout(function(){try{b.removeChild(c)}catch(a){return!1}},j.duration)},l)},wrapInput:function(a){for(var b=0;b<a.length;b++){var c=a[b];if("input"===c.tagName.toLowerCase()){var d=c.parentNode;if("i"===d.tagName.toLowerCase()&&-1!==d.className.indexOf("waves-effect"))continue;var e=document.createElement("i");e.className=c.className+" waves-input-wrapper";var f=c.getAttribute("style");f||(f=""),e.setAttribute("style",f),c.className="waves-button-input",c.removeAttribute("style"),d.replaceChild(e,c),e.appendChild(c)}}}},k={touches:0,allowEvent:function(a){var b=!0;return"touchstart"===a.type?k.touches+=1:"touchend"===a.type||"touchcancel"===a.type?setTimeout(function(){k.touches>0&&(k.touches-=1)},500):"mousedown"===a.type&&k.touches>0&&(b=!1),b},touchup:function(a){k.allowEvent(a)}};h.displayEffect=function(b){b=b||{},"duration"in b&&(j.duration=b.duration),j.wrapInput(i(".waves-effect")),"ontouchstart"in a&&document.body.addEventListener("touchstart",g,!1),document.body.addEventListener("mousedown",g,!1)},h.attach=function(b){"input"===b.tagName.toLowerCase()&&(j.wrapInput([b]),b=b.parentElement),"ontouchstart"in a&&b.addEventListener("touchstart",g,!1),b.addEventListener("mousedown",g,!1)},a.Waves=h,document.addEventListener("DOMContentLoaded",function(){h.displayEffect()},!1)}(window),Materialize.toast=function(a,b,c,d){function e(a){var b=document.createElement("div");if(b.classList.add("toast"),c)for(var e=c.split(" "),f=0,g=e.length;g>f;f++)b.classList.add(e[f]);b.innerHTML=a;var h=new Hammer(b,{prevent_default:!1});return h.on("pan",function(a){var c=a.deltaX,d=80;b.classList.contains("panning")||b.classList.add("panning");var e=1-Math.abs(c/d);0>e&&(e=0),Vel(b,{left:c,opacity:e},{duration:50,queue:!1,easing:"easeOutQuad"})}),h.on("panend",function(a){var c=a.deltaX,e=80;Math.abs(c)>e?Vel(b,{marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),b.parentNode.removeChild(b)}}):(b.classList.remove("panning"),Vel(b,{left:0,opacity:1},{duration:300,easing:"easeOutExpo",queue:!1}))}),b}c=c||"";var f=document.getElementById("toast-container");if(null===f){var f=document.createElement("div");f.id="toast-container",document.body.appendChild(f)}var g=e(a);f.appendChild(g),g.style.top="35px",g.style.opacity=0,Vel(g,{top:"0px",opacity:1},{duration:300,easing:"easeOutCubic",queue:!1});var h=b,i=setInterval(function(){null===g.parentNode&&window.clearInterval(i),g.classList.contains("panning")||(h-=20),0>=h&&(Vel(g,{opacity:0,marginTop:"-40px"},{duration:375,easing:"easeOutExpo",queue:!1,complete:function(){"function"==typeof d&&d(),this[0].parentNode.removeChild(this[0])}}),window.clearInterval(i))},20)},function(a){var b={init:function(b){var c={menuWidth:240,edge:"left",closeOnClick:!1};b=a.extend(c,b),a(this).each(function(){function c(c){f=!1,g=!1,a("#sidenav-overlay").velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),"left"===b.edge?(a(".drag-target").css({width:"",right:"",left:"0"}),e.velocity({left:-1*(b.menuWidth+10)},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){1==c&&(e.removeAttr("style"),e.css("width",b.menuWidth))}})):(a(".drag-target").css({width:"",right:"0",left:""}),e.velocity({right:-1*(b.menuWidth+10)},{duration:200,queue:!1,easing:"easeOutCubic",complete:function(){1==c&&(e.removeAttr("style"),e.css("width",b.menuWidth))}}))}var d=a(this),e=a("#"+d.attr("data-activates"));240!=b.menuWidth&&e.css("width",b.menuWidth),a("body").append(a('<div class="drag-target"></div>')),"left"==b.edge?(e.css("left",-1*(b.menuWidth+10)),a(".drag-target").css({left:0})):(e.addClass("right-aligned").css("right",-1*(b.menuWidth+10)).css("left",""),a(".drag-target").css({right:0})),e.hasClass("fixed")&&a(window).width()>992&&e.css("left",0),e.hasClass("fixed")&&a(window).resize(function(){window.innerWidth>992?0!=a("#sidenav-overlay").css("opacity")&&g?c(!0):(e.removeAttr("style"),e.css("width",b.menuWidth)):g===!1&&("left"===b.edge?e.css("left",-1*(b.menuWidth+10)):e.css("right",-1*(b.menuWidth+10)))}),1==b.closeOnClick&&e.on("click.itemclick","a:not(.collapsible-header)",function(){c()});var f=!1,g=!1;a(".drag-target").on("click",function(){c()}),a(".drag-target").hammer({prevent_default:!1}).bind("pan",function(d){if("touch"==d.gesture.pointerType){{var f=(d.gesture.direction,d.gesture.center.x);d.gesture.center.y,d.gesture.velocityX}if(0===a("#sidenav-overlay").length){var h=a('<div id="sidenav-overlay"></div>');h.css("opacity",0).click(function(){c()}),a("body").append(h)}if("left"===b.edge&&(f>b.menuWidth?f=b.menuWidth:0>f&&(f=0)),"left"===b.edge)f<b.menuWidth/2?g=!1:f>=b.menuWidth/2&&(g=!0),e.css("left",f-b.menuWidth);else{f<a(window).width()-b.menuWidth/2?g=!0:f>=a(window).width()-b.menuWidth/2&&(g=!1);var i=-1*(f-b.menuWidth/2);i>0&&(i=0),e.css("right",i)}if("left"===b.edge){var j=f/b.menuWidth;a("#sidenav-overlay").velocity({opacity:j},{duration:50,queue:!1,easing:"easeOutQuad"})}else{var j=Math.abs((f-a(window).width())/b.menuWidth);a("#sidenav-overlay").velocity({opacity:j},{duration:50,queue:!1,easing:"easeOutQuad"})}}}).bind("panend",function(c){if("touch"==c.gesture.pointerType){var d=c.gesture.velocityX;f=!1,"left"===b.edge?g&&.3>=d||-.5>d?(e.velocity({left:0},{duration:300,queue:!1,easing:"easeOutQuad"}),a("#sidenav-overlay").velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),a(".drag-target").css({width:"50%",right:0,left:""})):(!g||d>.3)&&(e.velocity({left:-1*(b.menuWidth+10)},{duration:200,queue:!1,easing:"easeOutQuad"}),a("#sidenav-overlay").velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),a(".drag-target").css({width:"10px",right:"",left:0})):g&&d>=-.3||d>.5?(e.velocity({right:0},{duration:300,queue:!1,easing:"easeOutQuad"}),a("#sidenav-overlay").velocity({opacity:1},{duration:50,queue:!1,easing:"easeOutQuad"}),a(".drag-target").css({width:"50%",right:"",left:0})):(!g||-.3>d)&&(e.velocity({right:-1*(b.menuWidth+10)},{duration:200,queue:!1,easing:"easeOutQuad"}),a("#sidenav-overlay").velocity({opacity:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}}),a(".drag-target").css({width:"10px",right:0,left:""}))}}),d.click(function(){if(1==g)g=!1,f=!1,c();else{"left"===b.edge?(a(".drag-target").css({width:"50%",right:0,left:""}),e.velocity({left:0},{duration:300,queue:!1,easing:"easeOutQuad"})):(a(".drag-target").css({width:"50%",right:"",left:0}),e.velocity({right:0},{duration:300,queue:!1,easing:"easeOutQuad"}),e.css("left",""));var d=a('<div id="sidenav-overlay"></div>');d.css("opacity",0).click(function(){g=!1,f=!1,c(),d.velocity({opacity:0},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){a(this).remove()}})}),a("body").append(d),d.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){g=!0,f=!1}})}return!1})})},show:function(){this.trigger("click")},hide:function(){a("#sidenav-overlay").trigger("click")}};a.fn.sideNav=function(c){return b[c]?b[c].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof c&&c?void a.error("Method "+c+" does not exist on jQuery.tooltip"):b.init.apply(this,arguments)}}(jQuery),function(a){function b(b,c,d,e){var f=a();return a.each(g,function(a,g){if(g.height()>0){var h=g.offset().top,i=g.offset().left,j=i+g.width(),k=h+g.height(),l=!(i>c||e>j||h>d||b>k);l&&f.push(g)}}),f}function c(){++j;var c=f.scrollTop(),d=f.scrollLeft(),e=d+f.width(),g=c+f.height(),i=b(c+k.top+200,e+k.right,g+k.bottom,d+k.left);a.each(i,function(a,b){var c=b.data("scrollSpy:ticks");"number"!=typeof c&&b.triggerHandler("scrollSpy:enter"),b.data("scrollSpy:ticks",j)}),a.each(h,function(a,b){var c=b.data("scrollSpy:ticks");"number"==typeof c&&c!==j&&(b.triggerHandler("scrollSpy:exit"),b.data("scrollSpy:ticks",null))}),h=i}function d(){f.trigger("scrollSpy:winSize")}function e(a,b,c){var d,e,f,g=null,h=0;c||(c={});var i=function(){h=c.leading===!1?0:l(),g=null,f=a.apply(d,e),d=e=null};return function(){var j=l();h||c.leading!==!1||(h=j);var k=b-(j-h);return d=this,e=arguments,0>=k?(clearTimeout(g),g=null,h=j,f=a.apply(d,e),d=e=null):g||c.trailing===!1||(g=setTimeout(i,k)),f}}var f=a(window),g=[],h=[],i=!1,j=0,k={top:0,right:0,bottom:0,left:0},l=Date.now||function(){return(new Date).getTime()};a.scrollSpy=function(b,d){var h=[];b=a(b),b.each(function(b,c){g.push(a(c)),a(c).data("scrollSpy:id",b),a("a[href=#"+a(c).attr("id")+"]").click(function(b){b.preventDefault();var c=a(this.hash).offset().top+1;a("html, body").animate({scrollTop:c-200},{duration:400,queue:!1,easing:"easeOutCubic"})})}),d=d||{throttle:100},k.top=d.offsetTop||0,k.right=d.offsetRight||0,k.bottom=d.offsetBottom||0,k.left=d.offsetLeft||0;var j=e(c,d.throttle||100),l=function(){a(document).ready(j)};return i||(f.on("scroll",l),f.on("resize",l),i=!0),setTimeout(l,0),b.on("scrollSpy:enter",function(){h=a.grep(h,function(a){return 0!=a.height()});var b=a(this);h[0]?(a("a[href=#"+h[0].attr("id")+"]").removeClass("active"),b.data("scrollSpy:id")<h[0].data("scrollSpy:id")?h.unshift(a(this)):h.push(a(this))):h.push(a(this)),a("a[href=#"+h[0].attr("id")+"]").addClass("active")}),b.on("scrollSpy:exit",function(){if(h=a.grep(h,function(a){return 0!=a.height()}),h[0]){a("a[href=#"+h[0].attr("id")+"]").removeClass("active");var b=a(this);h=a.grep(h,function(a){return a.attr("id")!=b.attr("id")}),h[0]&&a("a[href=#"+h[0].attr("id")+"]").addClass("active")}}),b},a.winSizeSpy=function(b){return a.winSizeSpy=function(){return f},b=b||{throttle:100},f.on("resize",e(d,b.throttle||100))},a.fn.scrollSpy=function(b){return a.scrollSpy(a(this),b)}}(jQuery),function(a){a(document).ready(function(){function b(b){d.text(b.val()+"\n");var c=d.html().replace(/\n/g,"<br>");d.html(c),b.is(":visible")?d.css("width",b.width()):d.css("width",a(window).width()/2),b.css("height",d.height())}Materialize.updateTextFields=function(){var b="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a(b).each(function(b,c){a(c).val().length>0||void 0!==a(this).attr("placeholder")?a(this).siblings("label, i").addClass("active"):a(this).siblings("label, i").removeClass("active")})};var c="input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea";a("input[autofocus]").siblings("label, i").addClass("active"),a(document).on("change",c,function(){(0!==a(this).val().length||void 0!==a(this).attr("placeholder"))&&a(this).siblings("label, i").addClass("active"),validate_field(a(this))}),a(document).ready(function(){Materialize.updateTextFields()}),a(document).on("reset",function(b){a(b.target).is("form")&&(a(this).find(c).removeClass("valid").removeClass("invalid"),a(this).find(c).siblings("label, i").removeClass("active"),a(this).find("select.initialized").each(function(){var b=a(this).find("option[selected]").text();a(this).siblings("input.select-dropdown").val(b)}))}),a(document).on("focus",c,function(){a(this).siblings("label, i").addClass("active")}),a(document).on("blur",c,function(){0===a(this).val().length&&void 0===a(this).attr("placeholder")&&a(this).siblings("label, i").removeClass("active"),validate_field(a(this))}),validate_field=function(a){0===a.val().length?a.hasClass("validate")&&(a.removeClass("valid"),a.removeClass("invalid")):a.hasClass("validate")&&(a.is(":valid")?(a.removeClass("invalid"),a.addClass("valid")):(a.removeClass("valid"),a.addClass("invalid")))};var d=a(".hiddendiv").first();d.length||(d=a('<div class="hiddendiv common"></div>'),a("body").append(d));var e=".materialize-textarea";a(e).each(function(){var c=a(this);c.val().length&&b(c)}),a("body").on("keyup keydown",e,function(){b(a(this))}),a(".file-field").each(function(){var b=a(this).find("input.file-path");a(this).find('input[type="file"]').change(function(){b.val(a(this)[0].files[0].name),b.trigger("change")})});var f="input[type=range]",g=!1;a(f).each(function(){var b=a('<span class="thumb"><span class="value"></span></span>');a(this).after(b)});var h=".range-field";a(document).on("mousedown",h,function(b){var c=a(this).children(".thumb");c.length<=0&&(c=a('<span class="thumb"><span class="value"></span></span>'),a(this).append(c)),g=!0,a(this).addClass("active"),c.hasClass("active")||c.velocity({height:"30px",width:"30px",top:"-20px",marginLeft:"-15px"},{duration:300,easing:"easeOutExpo"});var d=b.pageX-a(this).offset().left,e=a(this).outerWidth();0>d?d=0:d>e&&(d=e),c.addClass("active").css("left",d),c.find(".value").html(a(this).children("input[type=range]").val())}),a(document).on("mouseup",h,function(){g=!1,a(this).removeClass("active")}),a(document).on("mousemove",h,function(b){var c=a(this).children(".thumb");if(g){c.hasClass("active")||c.velocity({height:"30px",width:"30px",top:"-20px",marginLeft:"-15px"},{duration:300,easing:"easeOutExpo"});var d=b.pageX-a(this).offset().left,e=a(this).outerWidth();0>d?d=0:d>e&&(d=e),c.addClass("active").css("left",d),c.find(".value").html(a(this).children("input[type=range]").val())}}),a(document).on("mouseout",h,function(){if(!g){var b=a(this).children(".thumb");b.hasClass("active")&&b.velocity({height:"0",width:"0",top:"10px",marginLeft:"-6px"},{duration:100}),b.removeClass("active")}})}),a.fn.material_select=function(b){a(this).each(function(){if($select=a(this),!$select.hasClass("browser-default")){var c=$select.data("select-id");if(c&&($select.parent().find("i").remove(),$select.parent().find("input").remove(),$select.unwrap(),a("ul#select-options-"+c).remove()),"destroy"===b)return void $select.data("select-id",null).removeClass("initialized");var d=Materialize.guid();$select.data("select-id",d);var e=a('<div class="select-wrapper"></div>');e.addClass($select.attr("class"));var f=a('<ul id="select-options-'+d+'" class="dropdown-content select-dropdown"></ul>'),g=$select.children("option");if(void 0!==$select.find("option:selected"))var h=$select.find("option:selected");else var h=f.first();g.each(function(){f.append(a('<li class="'+(a(this).is(":disabled")?"disabled":"")+'"><span>'+a(this).html()+"</span></li>"))}),f.find("li").each(function(c){var d=$select;a(this).click(function(){a(this).hasClass("disabled")||(d.find("option").eq(c).prop("selected",!0),d.trigger("change"),d.siblings("input.select-dropdown").val(a(this).text()),"undefined"!=typeof b&&b())})}),$select.wrap(e);var i=a('<i class="mdi-navigation-arrow-drop-down"></i>');$select.is(":disabled")&&i.addClass("disabled");var j=a('<input type="text" class="select-dropdown" readonly="true" '+($select.is(":disabled")?"disabled":"")+' data-activates="select-options-'+d+'" value="'+h.html()+'"/>');$select.before(j),j.before(i),a("body").append(f),$select.is(":disabled")||j.dropdown({hover:!1}),$select.attr("tabindex")&&a(j[0]).attr("tabindex",$select.attr("tabindex")),$select.addClass("initialized"),j.on("focus",function(){a(this).trigger("open"),h=a(this).val(),selectedOption=f.find("li").filter(function(){return a(this).text().toLowerCase()===h.toLowerCase()})[0],activateOption(f,selectedOption)}),j.on("blur",function(){a(this).trigger("close")}),activateOption=function(b,c){b.find("li.active").removeClass("active"),a(c).addClass("active"),b.scrollTo(c)},filterQuery=[],onKeyDown=function(b){return 9==b.which?void j.trigger("close"):40!=b.which||f.is(":visible")?void((13!=b.which||f.is(":visible"))&&(b.preventDefault(),letter=String.fromCharCode(b.which).toLowerCase(),letter&&(filterQuery.push(letter),string=filterQuery.join(""),newOption=f.find("li").filter(function(){return 0===a(this).text().toLowerCase().indexOf(string)})[0],newOption&&activateOption(f,newOption)),13==b.which&&(activeOption=f.find("li.active:not(.disabled)")[0],activeOption&&(a(activeOption).trigger("click"),j.trigger("close"))),40==b.which&&(newOption=f.find("li.active").next("li:not(.disabled)")[0],newOption&&activateOption(f,newOption)),27==b.which&&j.trigger("close"),38==b.which&&(newOption=f.find("li.active").prev("li:not(.disabled)")[0],newOption&&activateOption(f,newOption)),setTimeout(function(){filterQuery=[]},1e3))):void j.trigger("open")},j.on("keydown",onKeyDown)}})}}(jQuery),function(a){a.fn.slider=function(b){var c={indicators:!0,height:400,transition:500,interval:6e3};return b=a.extend(c,b),this.each(function(){function c(a,b){a.hasClass("center-align")?a.velocity({opacity:0,translateY:-100},{duration:b,queue:!1}):a.hasClass("right-align")?a.velocity({opacity:0,translateX:100},{duration:b,queue:!1}):a.hasClass("left-align")&&a.velocity({opacity:0,translateX:-100},{duration:b,queue:!1})}function d(a){a>=h.length?a=0:0>a&&(a=h.length-1),i=g.find(".active").index(),i!=a&&(e=h.eq(i),$caption=e.find(".caption"),e.removeClass("active"),e.velocity({opacity:0},{duration:b.transition,queue:!1,easing:"easeOutQuad",complete:function(){h.not(".active").velocity({opacity:0,translateX:0,translateY:0},{duration:0,queue:!1})}}),c($caption,b.transition),b.indicators&&j.eq(i).removeClass("active"),h.eq(a).velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),h.eq(a).find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,delay:b.transition,queue:!1,easing:"easeOutQuad"}),h.eq(a).addClass("active"),b.indicators&&j.eq(a).addClass("active"))}var e,f=a(this),g=f.find("ul.slides").first(),h=g.find("li"),i=g.find(".active").index();if(-1!=i&&(e=h.eq(i)),400!=b.height&&(f.height(b.height+40),g.height(b.height)),h.find(".caption").each(function(){c(a(this),0)}),h.find("img").each(function(){a(this).css("background-image","url("+a(this).attr("src")+")"),a(this).attr("src","data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==")}),b.indicators){var j=a('<ul class="indicators"></ul>');h.each(function(){var c=a('<li class="indicator-item"></li>');c.click(function(){var c=g.parent(),e=c.find(a(this)).index();d(e),clearInterval($interval),$interval=setInterval(function(){i=g.find(".active").index(),h.length==i+1?i=0:i+=1,d(i)},b.transition+b.interval)}),j.append(c)}),f.append(j),j=f.find("ul.indicators").find("li.indicator-item")}e?e.show():(h.first().addClass("active").velocity({opacity:1},{duration:b.transition,queue:!1,easing:"easeOutQuad"}),i=0,e=h.eq(i),b.indicators&&j.eq(i).addClass("active")),e.find("img").each(function(){e.find(".caption").velocity({opacity:1,translateX:0,translateY:0},{duration:b.transition,queue:!1,easing:"easeOutQuad"})}),$interval=setInterval(function(){i=g.find(".active").index(),d(i+1)},b.transition+b.interval);var k=!1,l=!1,m=!1;f.hammer({prevent_default:!1}).bind("pan",function(a){if("touch"===a.gesture.pointerType){clearInterval($interval);var b=a.gesture.direction,c=a.gesture.deltaX,d=a.gesture.velocityX;$curr_slide=g.find(".active"),$curr_slide.velocity({translateX:c},{duration:50,queue:!1,easing:"easeOutQuad"}),4===b&&(c>f.innerWidth()/2||-.65>d)?m=!0:2===b&&(c<-1*f.innerWidth()/2||d>.65)&&(l=!0);var e;l&&(e=$curr_slide.next(),0===e.length&&(e=h.first()),e.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"})),m&&(e=$curr_slide.prev(),0===e.length&&(e=h.last()),e.velocity({opacity:1},{duration:300,queue:!1,easing:"easeOutQuad"}))}}).bind("panend",function(a){"touch"===a.gesture.pointerType&&($curr_slide=g.find(".active"),k=!1,curr_index=g.find(".active").index(),m||l?l?(d(curr_index+1),$curr_slide.velocity({translateX:-1*f.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})):m&&(d(curr_index-1),$curr_slide.velocity({translateX:f.innerWidth()},{duration:300,queue:!1,easing:"easeOutQuad",complete:function(){$curr_slide.velocity({opacity:0,translateX:0},{duration:0,queue:!1})}})):$curr_slide.velocity({translateX:0},{duration:300,queue:!1,easing:"easeOutQuad"}),l=!1,m=!1,clearInterval($interval),$interval=setInterval(function(){i=g.find(".active").index(),h.length==i+1?i=0:i+=1,d(i)},b.transition+b.interval))})})}}(jQuery),function(a){a(document).ready(function(){a(document).on("click.card",".card",function(b){a(this).find(".card-reveal").length&&(a(b.target).is(a(".card-reveal .card-title"))||a(b.target).is(a(".card-reveal .card-title i"))?a(this).find(".card-reveal").velocity({translateY:0},{duration:225,queue:!1,easing:"easeInOutQuad",complete:function(){a(this).css({display:"none"})}}):(a(b.target).is(a(".card .activator"))||a(b.target).is(a(".card .activator i")))&&a(this).find(".card-reveal").css({display:"block"}).velocity("stop",!1).velocity({translateY:"-100%"},{duration:300,queue:!1,easing:"easeInOutQuad"}))})})}(jQuery),function(a){a(document).ready(function(){a.fn.pushpin=function(b){var c={top:0,bottom:1/0,offset:0};return b=a.extend(c,b),$index=0,this.each(function(){function c(a){a.removeClass("pin-top"),a.removeClass("pinned"),a.removeClass("pin-bottom")}function d(d,e){d.each(function(){b.top<=e&&b.bottom>=e&&!a(this).hasClass("pinned")&&(c(a(this)),a(this).css("top",b.offset),a(this).addClass("pinned")),e<b.top&&!a(this).hasClass("pin-top")&&(c(a(this)),a(this).css("top",0),a(this).addClass("pin-top")),e>b.bottom&&!a(this).hasClass("pin-bottom")&&(c(a(this)),a(this).addClass("pin-bottom"),a(this).css("top",b.bottom-g))})}var e=Materialize.guid(),f=a(this),g=a(this).offset().top;d(f,a(window).scrollTop()),a(window).on("scroll."+e,function(){var c=a(window).scrollTop()+b.offset;d(f,c)})})}})}(jQuery),function(a){a(document).ready(function(){a.fn.reverse=[].reverse,a(document).on("mouseenter.fixedActionBtn",".fixed-action-btn",function(){var b=a(this);b.find("ul .btn-floating").velocity({scaleY:".4",scaleX:".4",translateY:"40px"},{duration:0});var c=0;b.find("ul .btn-floating").reverse().each(function(){a(this).velocity({opacity:"1",scaleX:"1",scaleY:"1",translateY:"0"},{duration:80,delay:c}),c+=40})}),a(document).on("mouseleave.fixedActionBtn",".fixed-action-btn",function(){var b=a(this);b.find("ul .btn-floating").velocity("stop",!0),b.find("ul .btn-floating").velocity({opacity:"0",scaleX:".4",scaleY:".4",translateY:"40px"},{duration:80})})})}(jQuery),function(a){Materialize.fadeInImage=function(b){var c=a(b);c.css({opacity:0}),a(c).velocity({opacity:1},{duration:650,queue:!1,easing:"easeOutSine"}),a(c).velocity({opacity:1},{duration:1300,queue:!1,easing:"swing",step:function(b,c){c.start=100;var d=b/100,e=150-(100-b)/1.75;100>e&&(e=100),b>=0&&a(this).css({"-webkit-filter":"grayscale("+d+")brightness("+e+"%)",filter:"grayscale("+d+")brightness("+e+"%)"})}})},Materialize.showStaggeredList=function(b){var c=0;a(b).find("li").velocity({translateX:"-100px" -},{duration:0}),a(b).find("li").each(function(){a(this).velocity({opacity:"1",translateX:"0"},{duration:800,delay:c,easing:[60,10]}),c+=120})},a(document).ready(function(){var b=!1,c=!1;a(".dismissable").each(function(){a(this).hammer({prevent_default:!1}).bind("pan",function(d){if("touch"===d.gesture.pointerType){var e=a(this),f=d.gesture.direction,g=d.gesture.deltaX,h=d.gesture.velocityX;e.velocity({translateX:g},{duration:50,queue:!1,easing:"easeOutQuad"}),4===f&&(g>e.innerWidth()/2||-.75>h)?b=!0:2===f&&(g<-1*e.innerWidth()/2||h>.75)&&(c=!0)}}).bind("panend",function(d){if("touch"===d.gesture.pointerType){var e=a(this);if(b||c){var f;f=b?e.innerWidth():-1*e.innerWidth(),e.velocity({translateX:f},{duration:100,queue:!1,easing:"easeOutQuad",complete:function(){e.css("border","none"),e.velocity({height:0,padding:0},{duration:200,queue:!1,easing:"easeOutQuad",complete:function(){e.remove()}})}})}else e.velocity({translateX:0},{duration:100,queue:!1,easing:"easeOutQuad"});b=!1,c=!1}})})})}(jQuery),function(){Materialize.scrollFire=function(a){var b=!1;window.addEventListener("scroll",function(){b=!0}),setInterval(function(){if(b){b=!1;for(var c=window.pageYOffset+window.innerHeight,d=0;d<a.length;d++){var e=a[d],f=e.selector,g=e.offset,h=e.callback,i=document.querySelector(f);if(null!==i){var j=i.getBoundingClientRect().top+document.body.scrollTop;if(c>j+g&&1!=e.done){var k=new Function(h);k(),e.done=!0}}}}},100)}}(jQuery),function(a){"function"==typeof define&&define.amd?define("picker",["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):this.Picker=a(jQuery)}(function(a){function b(f,g,i,l){function m(){return b._.node("div",b._.node("div",b._.node("div",b._.node("div",y.component.nodes(t.open),v.box),v.wrap),v.frame),v.holder)}function n(){w.data(g,y).addClass(v.input).attr("tabindex",-1).val(w.data("value")?y.get("select",u.format):f.value),u.editable||w.on("focus."+t.id+" click."+t.id,function(a){a.preventDefault(),y.$root[0].focus()}).on("keydown."+t.id,q),e(f,{haspopup:!0,expanded:!1,readonly:!1,owns:f.id+"_root"})}function o(){y.$root.on({keydown:q,focusin:function(a){y.$root.removeClass(v.focused),a.stopPropagation()},"mousedown click":function(b){var c=b.target;c!=y.$root.children()[0]&&(b.stopPropagation(),"mousedown"!=b.type||a(c).is("input, select, textarea, button, option")||(b.preventDefault(),y.$root[0].focus()))}}).on({focus:function(){w.addClass(v.target)},blur:function(){w.removeClass(v.target)}}).on("focus.toOpen",r).on("click","[data-pick], [data-nav], [data-clear], [data-close]",function(){var b=a(this),c=b.data(),d=b.hasClass(v.navDisabled)||b.hasClass(v.disabled),e=h();e=e&&(e.type||e.href),(d||e&&!a.contains(y.$root[0],e))&&y.$root[0].focus(),!d&&c.nav?y.set("highlight",y.component.item.highlight,{nav:c.nav}):!d&&"pick"in c?y.set("select",c.pick):c.clear?y.clear().close(!0):c.close&&y.close(!0)}),e(y.$root[0],"hidden",!0)}function p(){var b;u.hiddenName===!0?(b=f.name,f.name=""):(b=["string"==typeof u.hiddenPrefix?u.hiddenPrefix:"","string"==typeof u.hiddenSuffix?u.hiddenSuffix:"_submit"],b=b[0]+f.name+b[1]),y._hidden=a('<input type=hidden name="'+b+'"'+(w.data("value")||f.value?' value="'+y.get("select",u.formatSubmit)+'"':"")+">")[0],w.on("change."+t.id,function(){y._hidden.value=f.value?y.get("select",u.formatSubmit):""}),u.container?a(u.container).append(y._hidden):w.after(y._hidden)}function q(a){var b=a.keyCode,c=/^(8|46)$/.test(b);return 27==b?(y.close(),!1):void((32==b||c||!t.open&&y.component.key[b])&&(a.preventDefault(),a.stopPropagation(),c?y.clear().close():y.open()))}function r(a){a.stopPropagation(),"focus"==a.type&&y.$root.addClass(v.focused),y.open()}if(!f)return b;var s=!1,t={id:f.id||"P"+Math.abs(~~(Math.random()*new Date))},u=i?a.extend(!0,{},i.defaults,l):l||{},v=a.extend({},b.klasses(),u.klass),w=a(f),x=function(){return this.start()},y=x.prototype={constructor:x,$node:w,start:function(){return t&&t.start?y:(t.methods={},t.start=!0,t.open=!1,t.type=f.type,f.autofocus=f==h(),f.readOnly=!u.editable,f.id=f.id||t.id,"text"!=f.type&&(f.type="text"),y.component=new i(y,u),y.$root=a(b._.node("div",m(),v.picker,'id="'+f.id+'_root" tabindex="0"')),o(),u.formatSubmit&&p(),n(),u.container?a(u.container).append(y.$root):w.after(y.$root),y.on({start:y.component.onStart,render:y.component.onRender,stop:y.component.onStop,open:y.component.onOpen,close:y.component.onClose,set:y.component.onSet}).on({start:u.onStart,render:u.onRender,stop:u.onStop,open:u.onOpen,close:u.onClose,set:u.onSet}),s=c(y.$root.children()[0]),f.autofocus&&y.open(),y.trigger("start").trigger("render"))},render:function(a){return a?y.$root.html(m()):y.$root.find("."+v.box).html(y.component.nodes(t.open)),y.trigger("render")},stop:function(){return t.start?(y.close(),y._hidden&&y._hidden.parentNode.removeChild(y._hidden),y.$root.remove(),w.removeClass(v.input).removeData(g),setTimeout(function(){w.off("."+t.id)},0),f.type=t.type,f.readOnly=!1,y.trigger("stop"),t.methods={},t.start=!1,y):y},open:function(c){return t.open?y:(w.addClass(v.active),e(f,"expanded",!0),setTimeout(function(){y.$root.addClass(v.opened),e(y.$root[0],"hidden",!1)},0),c!==!1&&(t.open=!0,s&&k.css("overflow","hidden").css("padding-right","+="+d()),y.$root[0].focus(),j.on("click."+t.id+" focusin."+t.id,function(a){var b=a.target;b!=f&&b!=document&&3!=a.which&&y.close(b===y.$root.children()[0])}).on("keydown."+t.id,function(c){var d=c.keyCode,e=y.component.key[d],f=c.target;27==d?y.close(!0):f!=y.$root[0]||!e&&13!=d?a.contains(y.$root[0],f)&&13==d&&(c.preventDefault(),f.click()):(c.preventDefault(),e?b._.trigger(y.component.key.go,y,[b._.trigger(e)]):y.$root.find("."+v.highlighted).hasClass(v.disabled)||y.set("select",y.component.item.highlight).close())})),y.trigger("open"))},close:function(a){return a&&(y.$root.off("focus.toOpen")[0].focus(),setTimeout(function(){y.$root.on("focus.toOpen",r)},0)),w.removeClass(v.active),e(f,"expanded",!1),setTimeout(function(){y.$root.removeClass(v.opened+" "+v.focused),e(y.$root[0],"hidden",!0)},0),t.open?(t.open=!1,s&&k.css("overflow","").css("padding-right","-="+d()),j.off("."+t.id),y.trigger("close")):y},clear:function(a){return y.set("clear",null,a)},set:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(d=g&&a.isPlainObject(c)?c:d||{},b){g||(h[b]=c);for(e in h)f=h[e],e in y.component.item&&(void 0===f&&(f=null),y.component.set(e,f,d)),("select"==e||"clear"==e)&&w.val("clear"==e?"":y.get(e,u.format)).trigger("change");y.render()}return d.muted?y:y.trigger("set",h)},get:function(a,c){if(a=a||"value",null!=t[a])return t[a];if("valueSubmit"==a){if(y._hidden)return y._hidden.value;a="value"}if("value"==a)return f.value;if(a in y.component.item){if("string"==typeof c){var d=y.component.get(a);return d?b._.trigger(y.component.formats.toString,y.component,[c,d]):""}return y.component.get(a)}},on:function(b,c,d){var e,f,g=a.isPlainObject(b),h=g?b:{};if(b){g||(h[b]=c);for(e in h)f=h[e],d&&(e="_"+e),t.methods[e]=t.methods[e]||[],t.methods[e].push(f)}return y},off:function(){var a,b,c=arguments;for(a=0,namesCount=c.length;a<namesCount;a+=1)b=c[a],b in t.methods&&delete t.methods[b];return y},trigger:function(a,c){var d=function(a){var d=t.methods[a];d&&d.map(function(a){b._.trigger(a,y,[c])})};return d("_"+a),d(a),y}};return new x}function c(a){var b,c="position";return a.currentStyle?b=a.currentStyle[c]:window.getComputedStyle&&(b=getComputedStyle(a)[c]),"fixed"==b}function d(){if(k.height()<=i.height())return 0;var b=a('<div style="visibility:hidden;width:100px" />').appendTo("body"),c=b[0].offsetWidth;b.css("overflow","scroll");var d=a('<div style="width:100%" />').appendTo(b),e=d[0].offsetWidth;return b.remove(),c-e}function e(b,c,d){if(a.isPlainObject(c))for(var e in c)f(b,e,c[e]);else f(b,c,d)}function f(a,b,c){a.setAttribute(("role"==b?"":"aria-")+b,c)}function g(b,c){a.isPlainObject(b)||(b={attribute:c}),c="";for(var d in b){var e=("role"==d?"":"aria-")+d,f=b[d];c+=null==f?"":e+'="'+b[d]+'"'}return c}function h(){try{return document.activeElement}catch(a){}}var i=a(window),j=a(document),k=a(document.documentElement);return b.klasses=function(a){return a=a||"picker",{picker:a,opened:a+"--opened",focused:a+"--focused",input:a+"__input",active:a+"__input--active",target:a+"__input--target",holder:a+"__holder",frame:a+"__frame",wrap:a+"__wrap",box:a+"__box"}},b._={group:function(a){for(var c,d="",e=b._.trigger(a.min,a);e<=b._.trigger(a.max,a,[e]);e+=a.i)c=b._.trigger(a.item,a,[e]),d+=b._.node(a.node,c[0],c[1],c[2]);return d},node:function(b,c,d,e){return c?(c=a.isArray(c)?c.join(""):c,d=d?' class="'+d+'"':"",e=e?" "+e:"","<"+b+d+e+">"+c+"</"+b+">"):""},lead:function(a){return(10>a?"0":"")+a},trigger:function(a,b,c){return"function"==typeof a?a.apply(b,c||[]):a},digits:function(a){return/\d/.test(a[1])?2:1},isDate:function(a){return{}.toString.call(a).indexOf("Date")>-1&&this.isInteger(a.getDate())},isInteger:function(a){return{}.toString.call(a).indexOf("Number")>-1&&a%1===0},ariaAttr:g},b.extend=function(c,d){a.fn[c]=function(e,f){var g=this.data(c);return"picker"==e?g:g&&"string"==typeof e?b._.trigger(g[e],g,[f]):this.each(function(){var f=a(this);f.data(c)||new b(this,c,d,e)})},a.fn[c].defaults=d.defaults},b}),function(a){"function"==typeof define&&define.amd?define(["picker","jquery"],a):"object"==typeof exports?module.exports=a(require("./picker.js"),require("jquery")):a(Picker,jQuery)}(function(a,b){function c(a,b){var c=this,d=a.$node[0],e=d.value,f=a.$node.data("value"),g=f||e,h=f?b.formatSubmit:b.format,i=function(){return d.currentStyle?"rtl"==d.currentStyle.direction:"rtl"==getComputedStyle(a.$root[0]).direction};c.settings=b,c.$node=a.$node,c.queue={min:"measure create",max:"measure create",now:"now create",select:"parse create validate",highlight:"parse navigate create validate",view:"parse create validate viewset",disable:"deactivate",enable:"activate"},c.item={},c.item.clear=null,c.item.disable=(b.disable||[]).slice(0),c.item.enable=-function(a){return a[0]===!0?a.shift():-1}(c.item.disable),c.set("min",b.min).set("max",b.max).set("now"),g?c.set("select",g,{format:h}):c.set("select",null).set("highlight",c.item.now),c.key={40:7,38:-7,39:function(){return i()?-1:1},37:function(){return i()?1:-1},go:function(a){var b=c.item.highlight,d=new Date(b.year,b.month,b.date+a);c.set("highlight",d,{interval:a}),this.render()}},a.on("render",function(){a.$root.find("."+b.klass.selectMonth).on("change",function(){var c=this.value;c&&(a.set("highlight",[a.get("view").year,c,a.get("highlight").date]),a.$root.find("."+b.klass.selectMonth).trigger("focus"))}),a.$root.find("."+b.klass.selectYear).on("change",function(){var c=this.value;c&&(a.set("highlight",[c,a.get("view").month,a.get("highlight").date]),a.$root.find("."+b.klass.selectYear).trigger("focus"))})},1).on("open",function(){var d="";c.disabled(c.get("now"))&&(d=":not(."+b.klass.buttonToday+")"),a.$root.find("button"+d+", select").attr("disabled",!1)},1).on("close",function(){a.$root.find("button, select").attr("disabled",!0)},1)}var d=7,e=6,f=a._;c.prototype.set=function(a,b,c){var d=this,e=d.item;return null===b?("clear"==a&&(a="select"),e[a]=b,d):(e["enable"==a?"disable":"flip"==a?"enable":a]=d.queue[a].split(" ").map(function(e){return b=d[e](a,b,c)}).pop(),"select"==a?d.set("highlight",e.select,c):"highlight"==a?d.set("view",e.highlight,c):a.match(/^(flip|min|max|disable|enable)$/)&&(e.select&&d.disabled(e.select)&&d.set("select",e.select,c),e.highlight&&d.disabled(e.highlight)&&d.set("highlight",e.highlight,c)),d)},c.prototype.get=function(a){return this.item[a]},c.prototype.create=function(a,c,d){var e,g=this;return c=void 0===c?a:c,c==-(1/0)||c==1/0?e=c:b.isPlainObject(c)&&f.isInteger(c.pick)?c=c.obj:b.isArray(c)?(c=new Date(c[0],c[1],c[2]),c=f.isDate(c)?c:g.create().obj):c=f.isInteger(c)||f.isDate(c)?g.normalize(new Date(c),d):g.now(a,c,d),{year:e||c.getFullYear(),month:e||c.getMonth(),date:e||c.getDate(),day:e||c.getDay(),obj:e||c,pick:e||c.getTime()}},c.prototype.createRange=function(a,c){var d=this,e=function(a){return a===!0||b.isArray(a)||f.isDate(a)?d.create(a):a};return f.isInteger(a)||(a=e(a)),f.isInteger(c)||(c=e(c)),f.isInteger(a)&&b.isPlainObject(c)?a=[c.year,c.month,c.date+a]:f.isInteger(c)&&b.isPlainObject(a)&&(c=[a.year,a.month,a.date+c]),{from:e(a),to:e(c)}},c.prototype.withinRange=function(a,b){return a=this.createRange(a.from,a.to),b.pick>=a.from.pick&&b.pick<=a.to.pick},c.prototype.overlapRanges=function(a,b){var c=this;return a=c.createRange(a.from,a.to),b=c.createRange(b.from,b.to),c.withinRange(a,b.from)||c.withinRange(a,b.to)||c.withinRange(b,a.from)||c.withinRange(b,a.to)},c.prototype.now=function(a,b,c){return b=new Date,c&&c.rel&&b.setDate(b.getDate()+c.rel),this.normalize(b,c)},c.prototype.navigate=function(a,c,d){var e,f,g,h,i=b.isArray(c),j=b.isPlainObject(c),k=this.item.view;if(i||j){for(j?(f=c.year,g=c.month,h=c.date):(f=+c[0],g=+c[1],h=+c[2]),d&&d.nav&&k&&k.month!==g&&(f=k.year,g=k.month),e=new Date(f,g+(d&&d.nav?d.nav:0),1),f=e.getFullYear(),g=e.getMonth();new Date(f,g,h).getMonth()!==g;)h-=1;c=[f,g,h]}return c},c.prototype.normalize=function(a){return a.setHours(0,0,0,0),a},c.prototype.measure=function(a,b){var c=this;return b?"string"==typeof b?b=c.parse(a,b):f.isInteger(b)&&(b=c.now(a,b,{rel:b})):b="min"==a?-(1/0):1/0,b},c.prototype.viewset=function(a,b){return this.create([b.year,b.month,1])},c.prototype.validate=function(a,c,d){var e,g,h,i,j=this,k=c,l=d&&d.interval?d.interval:1,m=-1===j.item.enable,n=j.item.min,o=j.item.max,p=m&&j.item.disable.filter(function(a){if(b.isArray(a)){var d=j.create(a).pick;d<c.pick?e=!0:d>c.pick&&(g=!0)}return f.isInteger(a)}).length;if((!d||!d.nav)&&(!m&&j.disabled(c)||m&&j.disabled(c)&&(p||e||g)||!m&&(c.pick<=n.pick||c.pick>=o.pick)))for(m&&!p&&(!g&&l>0||!e&&0>l)&&(l*=-1);j.disabled(c)&&(Math.abs(l)>1&&(c.month<k.month||c.month>k.month)&&(c=k,l=l>0?1:-1),c.pick<=n.pick?(h=!0,l=1,c=j.create([n.year,n.month,n.date+(c.pick===n.pick?0:-1)])):c.pick>=o.pick&&(i=!0,l=-1,c=j.create([o.year,o.month,o.date+(c.pick===o.pick?0:1)])),!h||!i);)c=j.create([c.year,c.month,c.date+l]);return c},c.prototype.disabled=function(a){var c=this,d=c.item.disable.filter(function(d){return f.isInteger(d)?a.day===(c.settings.firstDay?d:d-1)%7:b.isArray(d)||f.isDate(d)?a.pick===c.create(d).pick:b.isPlainObject(d)?c.withinRange(d,a):void 0});return d=d.length&&!d.filter(function(a){return b.isArray(a)&&"inverted"==a[3]||b.isPlainObject(a)&&a.inverted}).length,-1===c.item.enable?!d:d||a.pick<c.item.min.pick||a.pick>c.item.max.pick},c.prototype.parse=function(a,b,c){var d=this,e={};return b&&"string"==typeof b?(c&&c.format||(c=c||{},c.format=d.settings.format),d.formats.toArray(c.format).map(function(a){var c=d.formats[a],g=c?f.trigger(c,d,[b,e]):a.replace(/^!/,"").length;c&&(e[a]=b.substr(0,g)),b=b.substr(g)}),[e.yyyy||e.yy,+(e.mm||e.m)-1,e.dd||e.d]):b},c.prototype.formats=function(){function a(a,b,c){var d=a.match(/\w+/)[0];return c.mm||c.m||(c.m=b.indexOf(d)+1),d.length}function b(a){return a.match(/\w+/)[0].length}return{d:function(a,b){return a?f.digits(a):b.date},dd:function(a,b){return a?2:f.lead(b.date)},ddd:function(a,c){return a?b(a):this.settings.weekdaysShort[c.day]},dddd:function(a,c){return a?b(a):this.settings.weekdaysFull[c.day]},m:function(a,b){return a?f.digits(a):b.month+1},mm:function(a,b){return a?2:f.lead(b.month+1)},mmm:function(b,c){var d=this.settings.monthsShort;return b?a(b,d,c):d[c.month]},mmmm:function(b,c){var d=this.settings.monthsFull;return b?a(b,d,c):d[c.month]},yy:function(a,b){return a?2:(""+b.year).slice(2)},yyyy:function(a,b){return a?4:b.year},toArray:function(a){return a.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g)},toString:function(a,b){var c=this;return c.formats.toArray(a).map(function(a){return f.trigger(c.formats[a],c,[0,b])||a.replace(/^!/,"")}).join("")}}}(),c.prototype.isDateExact=function(a,c){var d=this;return f.isInteger(a)&&f.isInteger(c)||"boolean"==typeof a&&"boolean"==typeof c?a===c:(f.isDate(a)||b.isArray(a))&&(f.isDate(c)||b.isArray(c))?d.create(a).pick===d.create(c).pick:b.isPlainObject(a)&&b.isPlainObject(c)?d.isDateExact(a.from,c.from)&&d.isDateExact(a.to,c.to):!1},c.prototype.isDateOverlap=function(a,c){var d=this,e=d.settings.firstDay?1:0;return f.isInteger(a)&&(f.isDate(c)||b.isArray(c))?(a=a%7+e,a===d.create(c).day+1):f.isInteger(c)&&(f.isDate(a)||b.isArray(a))?(c=c%7+e,c===d.create(a).day+1):b.isPlainObject(a)&&b.isPlainObject(c)?d.overlapRanges(a,c):!1},c.prototype.flipEnable=function(a){var b=this.item;b.enable=a||(-1==b.enable?1:-1)},c.prototype.deactivate=function(a,c){var d=this,e=d.item.disable.slice(0);return"flip"==c?d.flipEnable():c===!1?(d.flipEnable(1),e=[]):c===!0?(d.flipEnable(-1),e=[]):c.map(function(a){for(var c,g=0;g<e.length;g+=1)if(d.isDateExact(a,e[g])){c=!0;break}c||(f.isInteger(a)||f.isDate(a)||b.isArray(a)||b.isPlainObject(a)&&a.from&&a.to)&&e.push(a)}),e},c.prototype.activate=function(a,c){var d=this,e=d.item.disable,g=e.length;return"flip"==c?d.flipEnable():c===!0?(d.flipEnable(1),e=[]):c===!1?(d.flipEnable(-1),e=[]):c.map(function(a){var c,h,i,j;for(i=0;g>i;i+=1){if(h=e[i],d.isDateExact(h,a)){c=e[i]=null,j=!0;break}if(d.isDateOverlap(h,a)){b.isPlainObject(a)?(a.inverted=!0,c=a):b.isArray(a)?(c=a,c[3]||c.push("inverted")):f.isDate(a)&&(c=[a.getFullYear(),a.getMonth(),a.getDate(),"inverted"]);break}}if(c)for(i=0;g>i;i+=1)if(d.isDateExact(e[i],a)){e[i]=null;break}if(j)for(i=0;g>i;i+=1)if(d.isDateOverlap(e[i],a)){e[i]=null;break}c&&e.push(c)}),e.filter(function(a){return null!=a})},c.prototype.nodes=function(a){var b=this,c=b.settings,g=b.item,h=g.now,i=g.select,j=g.highlight,k=g.view,l=g.disable,m=g.min,n=g.max,o=function(a,b){return c.firstDay&&(a.push(a.shift()),b.push(b.shift())),f.node("thead",f.node("tr",f.group({min:0,max:d-1,i:1,node:"th",item:function(d){return[a[d],c.klass.weekdays,'scope=col title="'+b[d]+'"']}})))}((c.showWeekdaysFull?c.weekdaysFull:c.weekdaysLetter).slice(0),c.weekdaysFull.slice(0)),p=function(a){return f.node("div"," ",c.klass["nav"+(a?"Next":"Prev")]+(a&&k.year>=n.year&&k.month>=n.month||!a&&k.year<=m.year&&k.month<=m.month?" "+c.klass.navDisabled:""),"data-nav="+(a||-1)+" "+f.ariaAttr({role:"button",controls:b.$node[0].id+"_table"})+' title="'+(a?c.labelMonthNext:c.labelMonthPrev)+'"')},q=function(d){var e=c.showMonthsShort?c.monthsShort:c.monthsFull;return"short_months"==d&&(e=c.monthsShort),c.selectMonths&&void 0==d?f.node("select",f.group({min:0,max:11,i:1,node:"option",item:function(a){return[e[a],0,"value="+a+(k.month==a?" selected":"")+(k.year==m.year&&a<m.month||k.year==n.year&&a>n.month?" disabled":"")]}}),c.klass.selectMonth+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelMonthSelect+'"'):"short_months"==d?null!=i?f.node("div",e[i.month]):f.node("div",e[k.month]):f.node("div",e[k.month],c.klass.month)},r=function(d){var e=k.year,g=c.selectYears===!0?5:~~(c.selectYears/2);if(g){var h=m.year,i=n.year,j=e-g,l=e+g;if(h>j&&(l+=h-j,j=h),l>i){var o=j-h,p=l-i;j-=o>p?p:o,l=i}if(c.selectYears&&void 0==d)return f.node("select",f.group({min:j,max:l,i:1,node:"option",item:function(a){return[a,0,"value="+a+(e==a?" selected":"")]}}),c.klass.selectYear+" browser-default",(a?"":"disabled")+" "+f.ariaAttr({controls:b.$node[0].id+"_table"})+' title="'+c.labelYearSelect+'"')}return"raw"==d?f.node("div",e):f.node("div",e,c.klass.year)};return createDayLabel=function(){return null!=i?f.node("div",i.date):f.node("div",h.date)},createWeekdayLabel=function(){var a;a=null!=i?i.day:h.day;var b=c.weekdaysFull[a];return b},f.node("div",f.node("div",createWeekdayLabel(),"picker__weekday-display")+f.node("div",q("short_months"),c.klass.month_display)+f.node("div",createDayLabel(),c.klass.day_display)+f.node("div",r("raw"),c.klass.year_display),c.klass.date_display)+f.node("div",f.node("div",(c.selectYears?q()+r():q()+r())+p()+p(1),c.klass.header)+f.node("table",o+f.node("tbody",f.group({min:0,max:e-1,i:1,node:"tr",item:function(a){var e=c.firstDay&&0===b.create([k.year,k.month,1]).day?-7:0;return[f.group({min:d*a-k.day+e+1,max:function(){return this.min+d-1},i:1,node:"td",item:function(a){a=b.create([k.year,k.month,a+(c.firstDay?1:0)]);var d=i&&i.pick==a.pick,e=j&&j.pick==a.pick,g=l&&b.disabled(a)||a.pick<m.pick||a.pick>n.pick,o=f.trigger(b.formats.toString,b,[c.format,a]);return[f.node("div",a.date,function(b){return b.push(k.month==a.month?c.klass.infocus:c.klass.outfocus),h.pick==a.pick&&b.push(c.klass.now),d&&b.push(c.klass.selected),e&&b.push(c.klass.highlighted),g&&b.push(c.klass.disabled),b.join(" ")}([c.klass.day]),"data-pick="+a.pick+" "+f.ariaAttr({role:"gridcell",label:o,selected:d&&b.$node.val()===o?!0:null,activedescendant:e?!0:null,disabled:g?!0:null})),"",f.ariaAttr({role:"presentation"})]}})]}})),c.klass.table,'id="'+b.$node[0].id+'_table" '+f.ariaAttr({role:"grid",controls:b.$node[0].id,readonly:!0})),c.klass.calendar_container)+f.node("div",f.node("button",c.today,"btn-flat picker__today","type=button data-pick="+h.pick+(a&&!b.disabled(h)?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.clear,"btn-flat picker__clear","type=button data-clear=1"+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id}))+f.node("button",c.close,"btn-flat picker__close","type=button data-close=true "+(a?"":" disabled")+" "+f.ariaAttr({controls:b.$node[0].id})),c.klass.footer)},c.defaults=function(a){return{labelMonthNext:"Next month",labelMonthPrev:"Previous month",labelMonthSelect:"Select a month",labelYearSelect:"Select a year",monthsFull:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdaysFull:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekdaysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],weekdaysLetter:["S","M","T","W","T","F","S"],today:"Today",clear:"Clear",close:"Close",format:"d mmmm, yyyy",klass:{table:a+"table",header:a+"header",date_display:a+"date-display",day_display:a+"day-display",month_display:a+"month-display",year_display:a+"year-display",calendar_container:a+"calendar-container",navPrev:a+"nav--prev",navNext:a+"nav--next",navDisabled:a+"nav--disabled",month:a+"month",year:a+"year",selectMonth:a+"select--month",selectYear:a+"select--year",weekdays:a+"weekday",day:a+"day",disabled:a+"day--disabled",selected:a+"day--selected",highlighted:a+"day--highlighted",now:a+"day--today",infocus:a+"day--infocus",outfocus:a+"day--outfocus",footer:a+"footer",buttonClear:a+"button--clear",buttonToday:a+"button--today",buttonClose:a+"button--close"}}}(a.klasses().picker+"__"),a.extend("pickadate",c)}),function(a){function b(){var b=+a(this).attr("length"),c=+a(this).val().length,d=b>=c;a(this).parent().find('span[class="character-counter"]').html(c+"/"+b),e(d,a(this))}function c(b){$counterElement=a("<span/>").addClass("character-counter").css("float","right").css("font-size","12px").css("height",1),b.parent().append($counterElement)}function d(){a(this).parent().find('span[class="character-counter"]').html("")}function e(a,b){inputHasInvalidClass=b.hasClass("invalid"),a&&inputHasInvalidClass?b.removeClass("invalid"):a||inputHasInvalidClass||(b.removeClass("valid"),b.addClass("invalid"))}a.fn.characterCounter=function(){return this.each(function(){itHasLengthAttribute=void 0!=a(this).attr("length"),itHasLengthAttribute&&(a(this).on("input",b),a(this).on("focus",b),a(this).on("blur",d),c(a(this)))})},a(document).ready(function(){a("input, textarea").characterCounter()})}(jQuery);
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/package.json b/plugins/phonegap-plugin-push/package.json deleted file mode 100644 index a8bcf391..00000000 --- a/plugins/phonegap-plugin-push/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "phonegap-plugin-push", - "description": "Register and receive push notifications.", - "version": "1.3.0", - "homepage": "http://github.com/phonegap/phonegap-plugin-push#readme", - "repository": { - "type": "git", - "url": "git://github.com/phonegap/phonegap-plugin-push.git" - }, - "bugs": { - "url": "https://github.com/phonegap/phonegap-plugin-push/issues" - }, - "cordova": { - "id": "phonegap-plugin-push", - "platforms": [ - "ios", - "android", - "windows8", - "windows", - "wp8", - "browser" - ] - }, - "keywords": [ - "ecosystem:cordova", - "ecosystem:phonegap", - "cordova-ios", - "cordova-android", - "cordova-windows8", - "cordova-windows", - "cordova-wp8", - "cordova-browser" - ], - "engines": [ - { - "name": "cordova", - "version": ">=3.0.0" - } - ], - "author": "Adobe PhoneGap Team", - "license": "APL", - "scripts": { - "test": "jasmine-node --color spec" - }, - "devDependencies": { - "jasmine-node": "1.14.5" - } -} diff --git a/plugins/phonegap-plugin-push/plugin.xml b/plugins/phonegap-plugin-push/plugin.xml deleted file mode 100755 index b3f786db..00000000 --- a/plugins/phonegap-plugin-push/plugin.xml +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:amazon="http://schemas.android.com/apk/lib/com.amazon.device.ads" - xmlns:rim="http://www.blackberry.com/ns/widgets" - id="phonegap-plugin-push" - version="1.3.0"> - - <name>PushPlugin</name> - <author>Bob Easterday</author> - - <description> - This plugin allows your application to receive push notifications on Android, iOS, WP8 and Windows8 devices. - Android uses Google Cloud Messaging. - iOS uses Apple APNS Notifications. - WP8 uses Microsoft MPNS Notifications. - Windows8 uses Microsoft WNS Notifications. - </description> - - <license>MIT</license> - - <js-module src="www/push.js" name="PushNotification"> - <clobbers target="PushNotification" /> - </js-module> - - <engines> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <!-- android --> - <platform name="android"> - - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="PushNotification" > - <param name="android-package" value="com.adobe.phonegap.push.PushPlugin"/> - </feature> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/manifest"> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.WAKE_LOCK" /> - <uses-permission android:name="android.permission.VIBRATE"/> - <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> - <permission android:name="$PACKAGE_NAME.permission.C2D_MESSAGE" android:protectionLevel="signature" /> - <uses-permission android:name="$PACKAGE_NAME.permission.C2D_MESSAGE" /> - </config-file> - - <config-file target="AndroidManifest.xml" parent="/manifest/application"> - <activity android:name="com.adobe.phonegap.push.PushHandlerActivity" android:exported="true"/> - <receiver android:name="com.adobe.phonegap.push.CordovaGCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" > - <intent-filter> - <action android:name="com.google.android.c2dm.intent.RECEIVE" /> - <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> - <category android:name="$PACKAGE_NAME" /> - </intent-filter> - </receiver> - <service android:name="com.adobe.phonegap.push.GCMIntentService" /> - </config-file> - - <framework src="com.android.support:support-v13:23+" /> - - <source-file src="src/android/libs/gcm.jar" target-dir="libs/" /> - <source-file src="src/android/com/adobe/phonegap/push/CordovaGCMBroadcastReceiver.java" target-dir="src/com/adobe/phonegap/push/" /> - <source-file src="src/android/com/adobe/phonegap/push/GCMIntentService.java" target-dir="src/com/adobe/phonegap/push/" /> - <source-file src="src/android/com/adobe/phonegap/push/PushConstants.java" target-dir="src/com/adobe/phonegap/push/" /> - <source-file src="src/android/com/adobe/phonegap/push/PushHandlerActivity.java" target-dir="src/com/adobe/phonegap/push/" /> - <source-file src="src/android/com/adobe/phonegap/push/PushPlugin.java" target-dir="src/com/adobe/phonegap/push/" /> - - </platform> - - <!-- ios --> - <platform name="ios"> - - <config-file target="config.xml" parent="/*"> - <feature name="PushNotification"> - <param name="ios-package" value="PushPlugin"/> - </feature> - </config-file> - - <source-file src="src/ios/AppDelegate+notification.m" /> - <source-file src="src/ios/PushPlugin.m" /> - - <header-file src="src/ios/AppDelegate+notification.h" /> - <header-file src="src/ios/PushPlugin.h" /> - - </platform> - - <!-- windows --> - <platform name="windows"> - <js-module src="src/windows/PushPluginProxy.js" name="PushPlugin"> - <merges target="" /> - </js-module> - <config-file target="config.xml" parent="/*"> - <preference name="WindowsToastCapable" value="true" /> - </config-file> - </platform> - -</plugin> diff --git a/plugins/phonegap-plugin-push/spec/helper/cordova.js b/plugins/phonegap-plugin-push/spec/helper/cordova.js deleted file mode 100644 index 02bdee5f..00000000 --- a/plugins/phonegap-plugin-push/spec/helper/cordova.js +++ /dev/null @@ -1,83 +0,0 @@ -/* global cordova:true */ - -/*! - * Module dependencies. - */ - -/** - * cordova.js for node. - * - * Think of this as cordova-node, which would be simliar to cordova-android - * or cordova-browser. The purpose of this module is to enable testing - * of a plugin's JavaScript interface. - * - * When this module is first required, it will insert a global cordova - * instance, which can hijack cordova-specific commands within the pluin's - * implementation. - * - * Remember to require this module before the plugin that you want to test. - * - * Example: - * - * var cordova = require('./helper/cordova'), - * myPlugin = require('../www/myPlugin'); - */ - -module.exports = global.cordova = cordova = { - - /** - * cordova.require Mock. - * - * Hijacks all cordova.requires. By default, it returns an empty function. - * You can define your own implementation of each required module before - * or after it has been required. - * - * See `cordova.required` to learn how to add your own module implemtnation. - */ - - require: function(moduleId) { - // define a default function if it doesn't exist - if (!cordova.required[moduleId]) { - cordova.required[moduleId] = function() {}; - } - // create a new module mapping between the module Id and cordova.required. - return new ModuleMap(moduleId); - }, - - /** - * Cordova module implementations. - * - * A key-value hash, where the key is the module such as 'cordova/exec' - * and the value is the function or object returned. - * - * For example: - * - * var exec = require('cordova/exec'); - * - * Will map to: - * - * cordova.required['cordova/exec']; - */ - - required: { - // populated at runtime - } -}; - -/** - * Module Mapper. - * - * Returns a function that when executed will lookup the implementation - * in cordova.required[id]. - * - * @param {String} moduleId is the module name/path, such as 'cordova/exec' - * @return {Function}. - */ - -function ModuleMap(moduleId) { - return function() { - // lookup and execute the module's mock implementation, passing - // in any parameters that were provided. - return cordova.required[moduleId].apply(this, arguments); - }; -} diff --git a/plugins/phonegap-plugin-push/spec/index.spec.js b/plugins/phonegap-plugin-push/spec/index.spec.js deleted file mode 100644 index f794fae5..00000000 --- a/plugins/phonegap-plugin-push/spec/index.spec.js +++ /dev/null @@ -1,160 +0,0 @@ -/*! - * Module dependencies. - */ - -var cordova = require('./helper/cordova'), - PushNotification = require('../www/push'), - execSpy, - execWin, - options; - -/*! - * Specification. - */ - -describe('phonegap-plugin-push', function() { - beforeEach(function() { - options = { android: {}, ios: {}, windows: {} }; - execWin = jasmine.createSpy(); - execSpy = spyOn(cordova.required, 'cordova/exec').andCallFake(execWin); - }); - - describe('PushNotification', function() { - it("should exist", function() { - expect(PushNotification).toBeDefined(); - expect(typeof PushNotification == 'object').toBe(true); - }); - - it("should contain a init function", function() { - expect(PushNotification.init).toBeDefined(); - expect(typeof PushNotification.init == 'function').toBe(true); - }); - - it("should contain a unregister function", function() { - var push = PushNotification.init({}); - expect(push.unregister).toBeDefined(); - expect(typeof push.unregister == 'function').toBe(true); - }); - - it("should contain a setApplicationIconBadgeNumber function", function() { - var push = PushNotification.init({}); - expect(push.setApplicationIconBadgeNumber).toBeDefined(); - expect(typeof push.setApplicationIconBadgeNumber == 'function').toBe(true); - }); - }); - - describe('PushNotification instance', function() { - describe('cordova.exec', function() { - it('should call cordova.exec on next process tick', function(done) { - PushNotification.init(options); - setTimeout(function() { - expect(execSpy).toHaveBeenCalledWith( - jasmine.any(Function), - jasmine.any(Function), - 'PushNotification', - 'init', - jasmine.any(Object) - ); - done(); - }, 100); - }); - }); - - describe('on "registration" event', function() { - it('should be emitted with an argument', function(done) { - execSpy.andCallFake(function(win, fail, service, id, args) { - win({ 'registrationId': 1 }); - }); - var push = PushNotification.init(options); - push.on('registration', function(data) { - expect(data.registrationId).toEqual(1); - done(); - }); - }); - }); - - describe('on "notification" event', function() { - beforeEach(function() { - execSpy.andCallFake(function(win, fail, service, id, args) { - win({ - message: 'Message', - title: 'Title', - count: 1, - sound: 'beep', - image: 'Image', - additionalData: {} - }); - }); - }); - - it('should be emitted on success', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - done(); - }); - }); - - it('should provide the data.message argument', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - expect(data.message).toEqual('Message'); - done(); - }); - }); - - it('should provide the data.title argument', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - expect(data.title).toEqual('Title'); - done(); - }); - }); - - it('should provide the data.count argument', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - expect(data.count).toEqual(1); - done(); - }); - }); - - it('should provide the data.sound argument', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - expect(data.sound).toEqual('beep'); - done(); - }); - }); - - it('should provide the data.image argument', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - expect(data.image).toEqual('Image'); - done(); - }); - }); - - it('should provide the data.additionalData argument', function(done) { - var push = PushNotification.init(options); - push.on('notification', function(data) { - expect(data.additionalData).toEqual({}); - done(); - }); - }); - }); - - describe('on "error" event', function() { - it('should be emitted with an Error', function(done) { - execSpy.andCallFake(function(win, fail, service, id, args) { - fail('something went wrong'); - }); - var push = PushNotification.init(options); - push.on('error', function(e) { - expect(e).toEqual(jasmine.any(Error)); - expect(e.message).toEqual('something went wrong'); - done(); - }); - }); - }); - }); -}); diff --git a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/CordovaGCMBroadcastReceiver.java b/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/CordovaGCMBroadcastReceiver.java deleted file mode 100644 index 8bae76d9..00000000 --- a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/CordovaGCMBroadcastReceiver.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.adobe.phonegap.push; - -import android.content.Context; - -import com.google.android.gcm.GCMBroadcastReceiver; -import static com.google.android.gcm.GCMConstants.DEFAULT_INTENT_SERVICE_CLASS_NAME; - -/* - * Implementation of GCMBroadcastReceiver that hard-wires the intent service to be - * com.plugin.gcm.GCMIntentService, instead of your_package.GCMIntentService - */ -public class CordovaGCMBroadcastReceiver extends GCMBroadcastReceiver implements PushConstants { - - @Override - protected String getGCMIntentServiceClassName(Context context) { - return COM_ADOBE_PHONEGAP_PUSH + DEFAULT_INTENT_SERVICE_CLASS_NAME; - } - -}
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/GCMIntentService.java b/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/GCMIntentService.java deleted file mode 100644 index 67230c22..00000000 --- a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/GCMIntentService.java +++ /dev/null @@ -1,542 +0,0 @@ -package com.adobe.phonegap.push; - -import android.annotation.SuppressLint; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.AssetManager; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.net.Uri; -import android.os.Bundle; -import android.support.v4.app.NotificationCompat; -import android.text.Html; -import android.util.Log; - -import com.google.android.gcm.GCMBaseIntentService; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; - -@SuppressLint("NewApi") -public class GCMIntentService extends GCMBaseIntentService implements PushConstants { - - private static final String LOG_TAG = "PushPlugin_GCMIntentService"; - private static HashMap<Integer, ArrayList<String>> messageMap = new HashMap<Integer, ArrayList<String>>(); - - public void setNotification(int notId, String message){ - ArrayList<String> messageList = messageMap.get(notId); - if(messageList == null) { - messageList = new ArrayList<String>(); - messageMap.put(notId, messageList); - } - - if(message.isEmpty()){ - messageList.clear(); - }else{ - messageList.add(message); - } - } - - public GCMIntentService() { - super("GCMIntentService"); - } - - @Override - public void onRegistered(Context context, String regId) { - - Log.v(LOG_TAG, "onRegistered: " + regId); - - try { - JSONObject json = new JSONObject().put(REGISTRATION_ID, regId); - - Log.v(LOG_TAG, "onRegistered: " + json.toString()); - - PushPlugin.sendEvent( json ); - } - catch(JSONException e) { - // No message to the user is sent, JSON failed - Log.e(LOG_TAG, "onRegistered: JSON exception"); - } - } - - @Override - public void onUnregistered(Context context, String regId) { - Log.d(LOG_TAG, "onUnregistered - regId: " + regId); - } - - @Override - protected void onMessage(Context context, Intent intent) { - Log.d(LOG_TAG, "onMessage - context: " + context); - - // Extract the payload from the message - Bundle extras = intent.getExtras(); - if (extras != null) { - // if we are in the foreground, just surface the payload, else post it to the statusbar - if (PushPlugin.isInForeground()) { - extras.putBoolean(FOREGROUND, true); - PushPlugin.sendExtras(extras); - } - else { - extras.putBoolean(FOREGROUND, false); - - // Send a notification if there is a message - String message = this.getMessageText(extras); - String title = getString(extras, TITLE, ""); - if ((message != null && message.length() != 0) || - (title != null && title.length() != 0)) { - createNotification(context, extras); - } - } - } - } - - public void createNotification(Context context, Bundle extras) { - NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - String appName = getAppName(this); - String packageName = context.getPackageName(); - Resources resources = context.getResources(); - - int notId = parseInt(NOT_ID, extras); - Intent notificationIntent = new Intent(this, PushHandlerActivity.class); - notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); - notificationIntent.putExtra(PUSH_BUNDLE, extras); - notificationIntent.putExtra(NOT_ID, notId); - - int requestCode = new Random().nextInt(); - PendingIntent contentIntent = PendingIntent.getActivity(this, requestCode, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - NotificationCompat.Builder mBuilder = - new NotificationCompat.Builder(context) - .setWhen(System.currentTimeMillis()) - .setContentTitle(getString(extras, TITLE)) - .setTicker(getString(extras, TITLE)) - .setContentIntent(contentIntent) - .setAutoCancel(true); - - SharedPreferences prefs = context.getSharedPreferences(PushPlugin.COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); - String localIcon = prefs.getString(ICON, null); - String localIconColor = prefs.getString(ICON_COLOR, null); - boolean soundOption = prefs.getBoolean(SOUND, true); - //PP - make vibrate false - //boolean vibrateOption = prefs.getBoolean(VIBRATE, true); - boolean vibrateOption = false; - Log.d(LOG_TAG, "stored icon=" + localIcon); - Log.d(LOG_TAG, "stored iconColor=" + localIconColor); - Log.d(LOG_TAG, "stored sound=" + soundOption); - Log.d(LOG_TAG, "stored vibrate=" + vibrateOption); - - /* - * Notification Vibration - */ - - setNotificationVibration(extras, vibrateOption, mBuilder); - - /* - * Notification Icon Color - * - * Sets the small-icon background color of the notification. - * To use, add the `iconColor` key to plugin android options - * - */ - setNotificationIconColor(getString(extras,"color"), mBuilder, localIconColor); - - /* - * Notification Icon - * - * Sets the small-icon of the notification. - * - * - checks the plugin options for `icon` key - * - if none, uses the application icon - * - * The icon value must be a string that maps to a drawable resource. - * If no resource is found, falls - * - */ - setNotificationSmallIcon(context, extras, packageName, resources, mBuilder, localIcon); - - /* - * Notification Large-Icon - * - * Sets the large-icon of the notification - * - * - checks the gcm data for the `image` key - * - checks to see if remote image, loads it. - * - checks to see if assets image, Loads It. - * - checks to see if resource image, LOADS IT! - * - if none, we don't set the large icon - * - */ - setNotificationLargeIcon(extras, packageName, resources, mBuilder); - - /* - * Notification Sound - */ - if (soundOption) { - // setNotificationSound(context, extras, mBuilder); - } - - /* - * LED Notification - */ - setNotificationLedColor(extras, mBuilder); - - /* - * Priority Notification - */ - setNotificationPriority(extras, mBuilder); - - /* - * Notification message - */ - setNotificationMessage(notId, extras, mBuilder); - - /* - * Notification count - */ - setNotificationCount(extras, mBuilder); - - /* - * Notication add actions - */ - createActions(extras, mBuilder, resources, packageName); - - // PP add lights - mBuilder.setLights(0xFFFF0000, 500, 500); - - //PP - http://stackoverflow.com/questions/29343974/custom-sound-in-android-push-notifications-gcm - // mNotificationManager.notify(appName, notId, mBuilder.build()); - Notification notification = mBuilder.build(); - //notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "/"+ R.raw.blop); - //PP http://stackoverflow.com/questions/15449945/notification-sound-from-uri-parse-does-not-work - notification.sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName() + "/raw/blop"); - //notification.defaults |= Notification.DEFAULT_VIBRATE; - mNotificationManager.notify((String) appName, notId, notification); - } - - private void createActions(Bundle extras, NotificationCompat.Builder mBuilder, Resources resources, String packageName) { - Log.d(LOG_TAG, "create actions"); - String actions = getString(extras, ACTIONS); - if (actions != null) { - try { - JSONArray actionsArray = new JSONArray(actions); - for (int i=0; i < actionsArray.length(); i++) { - Log.d(LOG_TAG, "adding action"); - JSONObject action = actionsArray.getJSONObject(i); - Log.d(LOG_TAG, "adding callback = " + action.getString(CALLBACK)); - Intent intent = new Intent(this, PushHandlerActivity.class); - intent.putExtra(CALLBACK, action.getString(CALLBACK)); - intent.putExtra(PUSH_BUNDLE, extras); - PendingIntent pIntent = PendingIntent.getActivity(this, i, intent, PendingIntent.FLAG_UPDATE_CURRENT); - - mBuilder.addAction(resources.getIdentifier(action.getString(ICON), DRAWABLE, packageName), - action.getString(TITLE), pIntent); - } - } catch(JSONException e) { - // nope - } - } - } - - private void setNotificationCount(Bundle extras, NotificationCompat.Builder mBuilder) { - String msgcnt = getString(extras, MSGCNT); - if (msgcnt == null) { - msgcnt = getString(extras, BADGE); - } - if (msgcnt != null) { - mBuilder.setNumber(Integer.parseInt(msgcnt)); - } - } - - private void setNotificationVibration(Bundle extras, Boolean vibrateOption, NotificationCompat.Builder mBuilder) { - String vibrationPattern = getString(extras, VIBRATION_PATTERN); - if (vibrationPattern != null) { - String[] items = vibrationPattern.replaceAll("\\[", "").replaceAll("\\]", "").split(","); - long[] results = new long[items.length]; - for (int i = 0; i < items.length; i++) { - try { - results[i] = Long.parseLong(items[i]); - } catch (NumberFormatException nfe) {} - } - mBuilder.setVibrate(results); - } else { - if (vibrateOption) { - mBuilder.setDefaults(Notification.DEFAULT_VIBRATE); - } - } - } - - private void setNotificationMessage(int notId, Bundle extras, NotificationCompat.Builder mBuilder) { - String message = getMessageText(extras); - - String style = getString(extras, STYLE, STYLE_TEXT); - if(STYLE_INBOX.equals(style)) { - setNotification(notId, message); - - mBuilder.setContentText(message); - - ArrayList<String> messageList = messageMap.get(notId); - Integer sizeList = messageList.size(); - if (sizeList > 1) { - String sizeListMessage = sizeList.toString(); - String stacking = sizeList + " more"; - if (getString(extras, SUMMARY_TEXT) != null) { - stacking = getString(extras, SUMMARY_TEXT); - stacking = stacking.replace("%n%", sizeListMessage); - } - NotificationCompat.InboxStyle notificationInbox = new NotificationCompat.InboxStyle() - .setBigContentTitle(getString(extras, TITLE)) - .setSummaryText(stacking); - - for (int i = messageList.size() - 1; i >= 0; i--) { - notificationInbox.addLine(Html.fromHtml(messageList.get(i))); - } - - mBuilder.setStyle(notificationInbox); - } else { - NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle(); - if (message != null) { - bigText.bigText(message); - bigText.setBigContentTitle(getString(extras, TITLE)); - mBuilder.setStyle(bigText); - } - } - } else if (STYLE_PICTURE.equals(style)) { - setNotification(notId, ""); - - NotificationCompat.BigPictureStyle bigPicture = new NotificationCompat.BigPictureStyle(); - bigPicture.bigPicture(getBitmapFromURL(getString(extras, PICTURE))); - bigPicture.setBigContentTitle(getString(extras, TITLE)); - bigPicture.setSummaryText(getString(extras, SUMMARY_TEXT)); - - mBuilder.setContentTitle(getString(extras, TITLE)); - mBuilder.setContentText(message); - - mBuilder.setStyle(bigPicture); - } else { - setNotification(notId, ""); - - NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle(); - - if (message != null) { - mBuilder.setContentText(Html.fromHtml(message)); - - bigText.bigText(message); - bigText.setBigContentTitle(getString(extras, TITLE)); - - String summaryText = getString(extras, SUMMARY_TEXT); - if (summaryText != null) { - bigText.setSummaryText(summaryText); - } - - mBuilder.setStyle(bigText); - } - /* - else { - mBuilder.setContentText("<missing message content>"); - } - */ - } - } - - private String getString(Bundle extras,String key) { - String message = extras.getString(key); - if (message == null) { - message = extras.getString(GCM_NOTIFICATION+"."+key); - } - return message; - } - - private String getString(Bundle extras,String key, String defaultString) { - String message = extras.getString(key); - if (message == null) { - message = extras.getString(GCM_NOTIFICATION+"."+key, defaultString); - } - return message; - } - - private String getMessageText(Bundle extras) { - String message = getString(extras, MESSAGE); - if (message == null) { - message = getString(extras, BODY); - } - return message; - } - - private void setNotificationSound(Context context, Bundle extras, NotificationCompat.Builder mBuilder) { - String soundname = getString(extras, SOUNDNAME); - if (soundname == null) { - soundname = getString(extras, SOUND); - } - if (soundname != null) { - Uri sound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE - + "://" + context.getPackageName() + "/raw/" + soundname); - Log.d(LOG_TAG, sound.toString()); - mBuilder.setSound(sound); - } else { - mBuilder.setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI); - } - } - - private void setNotificationLedColor(Bundle extras, NotificationCompat.Builder mBuilder) { - String ledColor = getString(extras, LED_COLOR); - if (ledColor != null) { - // Converts parse Int Array from ledColor - String[] items = ledColor.replaceAll("\\[", "").replaceAll("\\]", "").split(","); - int[] results = new int[items.length]; - for (int i = 0; i < items.length; i++) { - try { - results[i] = Integer.parseInt(items[i]); - } catch (NumberFormatException nfe) {} - } - if (results.length == 4) { - mBuilder.setLights(Color.argb(results[0], results[1], results[2], results[3]), 500, 500); - } else { - Log.e(LOG_TAG, "ledColor parameter must be an array of length == 4 (ARGB)"); - } - } - } - - private void setNotificationPriority(Bundle extras, NotificationCompat.Builder mBuilder) { - String priorityStr = getString(extras, PRIORITY); - if (priorityStr != null) { - try { - Integer priority = Integer.parseInt(priorityStr); - if (priority >= NotificationCompat.PRIORITY_MIN && priority <= NotificationCompat.PRIORITY_MAX) { - mBuilder.setPriority(priority); - } else { - Log.e(LOG_TAG, "Priority parameter must be between -2 and 2"); - } - } catch (NumberFormatException e) { - e.printStackTrace(); - } - } - } - - private void setNotificationLargeIcon(Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder) { - String gcmLargeIcon = getString(extras, IMAGE); // from gcm - if (gcmLargeIcon != null) { - if (gcmLargeIcon.startsWith("http://") || gcmLargeIcon.startsWith("https://")) { - mBuilder.setLargeIcon(getBitmapFromURL(gcmLargeIcon)); - Log.d(LOG_TAG, "using remote large-icon from gcm"); - } else { - AssetManager assetManager = getAssets(); - InputStream istr; - try { - istr = assetManager.open(gcmLargeIcon); - Bitmap bitmap = BitmapFactory.decodeStream(istr); - mBuilder.setLargeIcon(bitmap); - Log.d(LOG_TAG, "using assets large-icon from gcm"); - } catch (IOException e) { - int largeIconId = 0; - largeIconId = resources.getIdentifier(gcmLargeIcon, DRAWABLE, packageName); - if (largeIconId != 0) { - Bitmap largeIconBitmap = BitmapFactory.decodeResource(resources, largeIconId); - mBuilder.setLargeIcon(largeIconBitmap); - Log.d(LOG_TAG, "using resources large-icon from gcm"); - } else { - Log.d(LOG_TAG, "Not setting large icon"); - } - } - } - } - } - - private void setNotificationSmallIcon(Context context, Bundle extras, String packageName, Resources resources, NotificationCompat.Builder mBuilder, String localIcon) { - int iconId = 0; - String icon = getString(extras, ICON); - if (icon != null) { - iconId = resources.getIdentifier(icon, DRAWABLE, packageName); - Log.d(LOG_TAG, "using icon from plugin options"); - } - else if (localIcon != null) { - iconId = resources.getIdentifier(localIcon, DRAWABLE, packageName); - Log.d(LOG_TAG, "using icon from plugin options"); - } - if (iconId == 0) { - Log.d(LOG_TAG, "no icon resource found - using application icon"); - iconId = context.getApplicationInfo().icon; - } - mBuilder.setSmallIcon(iconId); - } - - private void setNotificationIconColor(String color, NotificationCompat.Builder mBuilder, String localIconColor) { - int iconColor = 0; - if (color != null) { - try { - iconColor = Color.parseColor(color); - } catch (IllegalArgumentException e) { - Log.e(LOG_TAG, "couldn't parse color from android options"); - } - } - else if (localIconColor != null) { - try { - iconColor = Color.parseColor(localIconColor); - } catch (IllegalArgumentException e) { - Log.e(LOG_TAG, "couldn't parse color from android options"); - } - } - if (iconColor != 0) { - mBuilder.setColor(iconColor); - } - } - - public Bitmap getBitmapFromURL(String strURL) { - try { - URL url = new URL(strURL); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setDoInput(true); - connection.connect(); - InputStream input = connection.getInputStream(); - return BitmapFactory.decodeStream(input); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - private static String getAppName(Context context) { - CharSequence appName = context.getPackageManager().getApplicationLabel(context.getApplicationInfo()); - return (String)appName; - } - - @Override - public void onError(Context context, String errorId) { - Log.e(LOG_TAG, "onError - errorId: " + errorId); - // if we are in the foreground, just send the error - if (PushPlugin.isInForeground()) { - PushPlugin.sendError(errorId); - } - } - - private int parseInt(String value, Bundle extras) { - int retval = 0; - - try { - retval = Integer.parseInt(getString(extras, value)); - } - catch(NumberFormatException e) { - Log.e(LOG_TAG, "Number format exception - Error parsing " + value + ": " + e.getMessage()); - } - catch(Exception e) { - Log.e(LOG_TAG, "Number format exception - Error parsing " + value + ": " + e.getMessage()); - } - - return retval; - } -} diff --git a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java b/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java deleted file mode 100644 index 09d7d4b9..00000000 --- a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushConstants.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.adobe.phonegap.push; - -public interface PushConstants { - public static final String COM_ADOBE_PHONEGAP_PUSH = "com.adobe.phonegap.push"; - public static final String REGISTRATION_ID = "registrationId"; - public static final String FOREGROUND = "foreground"; - public static final String TITLE = "title"; - public static final String NOT_ID = "notId"; - public static final String PUSH_BUNDLE = "pushBundle"; - public static final String ICON = "icon"; - public static final String ICON_COLOR = "iconColor"; - public static final String SOUND = "sound"; - public static final String VIBRATE = "vibrate"; - public static final String ACTIONS = "actions"; - public static final String CALLBACK = "callback"; - public static final String DRAWABLE = "drawable"; - public static final String MSGCNT = "msgcnt"; - public static final String VIBRATION_PATTERN = "vibrationPattern"; - public static final String STYLE = "style"; - public static final String SUMMARY_TEXT = "summaryText"; - public static final String PICTURE = "picture"; - public static final String GCM_NOTIFICATION = "gcm.notification"; - public static final String MESSAGE = "message"; - public static final String BODY = "body"; - public static final String SOUNDNAME = "soundname"; - public static final String LED_COLOR = "ledColor"; - public static final String PRIORITY = "priority"; - public static final String IMAGE = "image"; - public static final String STYLE_INBOX = "inbox"; - public static final String STYLE_PICTURE = "picture"; - public static final String STYLE_TEXT = "text"; - public static final String BADGE = "badge"; - public static final String INITIALIZE = "init"; - public static final String UNREGISTER = "unregister"; - public static final String EXIT = "exit"; - public static final String ANDROID = "android"; - public static final String SENDER_ID = "senderID"; - public static final String CLEAR_NOTIFICATIONS = "clearNotifications"; - public static final String COLDSTART = "coldstart"; - public static final String ADDITIONAL_DATA = "additionalData"; - public static final String COUNT = "count"; - public static final String FROM = "from"; - public static final String COLLAPSE_KEY = "collapse_key"; -} diff --git a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java b/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java deleted file mode 100644 index 57d2be84..00000000 --- a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushHandlerActivity.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.adobe.phonegap.push; - -import android.app.Activity; -import android.app.NotificationManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; -import android.util.Log; - -public class PushHandlerActivity extends Activity implements PushConstants { - private static String LOG_TAG = "PushPlugin_PushHandlerActivity"; - - /* - * this activity will be started if the user touches a notification that we own. - * We send it's data off to the push plugin for processing. - * If needed, we boot up the main activity to kickstart the application. - * @see android.app.Activity#onCreate(android.os.Bundle) - */ - @Override - public void onCreate(Bundle savedInstanceState) { - GCMIntentService gcm = new GCMIntentService(); - gcm.setNotification(getIntent().getIntExtra(NOT_ID, 0), ""); - super.onCreate(savedInstanceState); - Log.v(LOG_TAG, "onCreate"); - - boolean isPushPluginActive = PushPlugin.isActive(); - processPushBundle(isPushPluginActive); - - finish(); - - if (!isPushPluginActive) { - forceMainActivityReload(); - } - } - - /** - * Takes the pushBundle extras from the intent, - * and sends it through to the PushPlugin for processing. - */ - private void processPushBundle(boolean isPushPluginActive) { - Bundle extras = getIntent().getExtras(); - - if (extras != null) { - Bundle originalExtras = extras.getBundle(PUSH_BUNDLE); - - originalExtras.putBoolean(FOREGROUND, false); - originalExtras.putBoolean(COLDSTART, !isPushPluginActive); - originalExtras.putString(CALLBACK, getIntent().getExtras().getString("callback")); - - PushPlugin.sendExtras(originalExtras); - } - } - - /** - * Forces the main activity to re-launch if it's unloaded. - */ - private void forceMainActivityReload() { - PackageManager pm = getPackageManager(); - Intent launchIntent = pm.getLaunchIntentForPackage(getApplicationContext().getPackageName()); - startActivity(launchIntent); - } - - @Override - protected void onResume() { - super.onResume(); - final NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancelAll(); - } -}
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java b/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java deleted file mode 100644 index 781ed2d1..00000000 --- a/plugins/phonegap-plugin-push/src/android/com/adobe/phonegap/push/PushPlugin.java +++ /dev/null @@ -1,250 +0,0 @@ -package com.adobe.phonegap.push; - -import android.app.NotificationManager; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.util.Log; - -import com.google.android.gcm.GCMRegistrar; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.PluginResult; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Iterator; - -public class PushPlugin extends CordovaPlugin implements PushConstants { - - public static final String LOG_TAG = "PushPlugin"; - - private static CallbackContext pushContext; - private static CordovaWebView gWebView; - private static Bundle gCachedExtras = null; - private static boolean gForeground = false; - - /** - * Gets the application context from cordova's main activity. - * @return the application context - */ - private Context getApplicationContext() { - return this.cordova.getActivity().getApplicationContext(); - } - - @Override - public boolean execute(String action, JSONArray data, CallbackContext callbackContext) { - - boolean result = false; - - Log.v(LOG_TAG, "execute: action=" + action); - - if (INITIALIZE.equals(action)) { - pushContext = callbackContext; - JSONObject jo = null; - - Log.v(LOG_TAG, "execute: data=" + data.toString()); - - try { - jo = data.getJSONObject(0).getJSONObject(ANDROID); - - gWebView = this.webView; - Log.v(LOG_TAG, "execute: jo=" + jo.toString()); - - String senderID = jo.getString(SENDER_ID); - - Log.v(LOG_TAG, "execute: senderID=" + senderID); - - GCMRegistrar.register(getApplicationContext(), senderID); - result = true; - } catch (JSONException e) { - Log.e(LOG_TAG, "execute: Got JSON Exception " + e.getMessage()); - result = false; - callbackContext.error(e.getMessage()); - } - - if (jo != null) { - SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = sharedPref.edit(); - try { - editor.putString(ICON, jo.getString(ICON)); - } catch (JSONException e) { - Log.d(LOG_TAG, "no icon option"); - } - try { - editor.putString(ICON_COLOR, jo.getString(ICON_COLOR)); - } catch (JSONException e) { - Log.d(LOG_TAG, "no iconColor option"); - } - editor.putBoolean(SOUND, jo.optBoolean(SOUND, true)); - editor.putBoolean(VIBRATE, jo.optBoolean(VIBRATE, true)); - editor.putBoolean(CLEAR_NOTIFICATIONS, jo.optBoolean(CLEAR_NOTIFICATIONS, true)); - editor.commit(); - } - - if ( gCachedExtras != null) { - Log.v(LOG_TAG, "sending cached extras"); - sendExtras(gCachedExtras); - gCachedExtras = null; - } - - } else if (UNREGISTER.equals(action)) { - - GCMRegistrar.unregister(getApplicationContext()); - - Log.v(LOG_TAG, "UNREGISTER"); - result = true; - callbackContext.success(); - } else { - result = false; - Log.e(LOG_TAG, "Invalid action : " + action); - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.INVALID_ACTION)); - } - - return result; - } - - public static void sendEvent(JSONObject _json) { - PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, _json); - pluginResult.setKeepCallback(true); - if (pushContext != null) { - pushContext.sendPluginResult(pluginResult); - } - } - - public static void sendError(String message) { - PluginResult pluginResult = new PluginResult(PluginResult.Status.ERROR, message); - pluginResult.setKeepCallback(true); - if (pushContext != null) { - pushContext.sendPluginResult(pluginResult); - } - } - - /* - * Sends the pushbundle extras to the client application. - * If the client application isn't currently active, it is cached for later processing. - */ - public static void sendExtras(Bundle extras) { - if (extras != null) { - if (gWebView != null) { - sendEvent(convertBundleToJson(extras)); - } else { - Log.v(LOG_TAG, "sendExtras: caching extras to send at a later time."); - gCachedExtras = extras; - } - } - } - - @Override - public void initialize(CordovaInterface cordova, CordovaWebView webView) { - super.initialize(cordova, webView); - gForeground = true; - } - - @Override - public void onPause(boolean multitasking) { - super.onPause(multitasking); - gForeground = false; - - SharedPreferences prefs = getApplicationContext().getSharedPreferences(COM_ADOBE_PHONEGAP_PUSH, Context.MODE_PRIVATE); - if (prefs.getBoolean(CLEAR_NOTIFICATIONS, true)) { - final NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE); - notificationManager.cancelAll(); - } - } - - @Override - public void onResume(boolean multitasking) { - super.onResume(multitasking); - gForeground = true; - } - - @Override - public void onDestroy() { - super.onDestroy(); - gForeground = false; - gWebView = null; - } - - /* - * serializes a bundle to JSON. - */ - private static JSONObject convertBundleToJson(Bundle extras) { - try { - JSONObject json = new JSONObject(); - JSONObject additionalData = new JSONObject(); - Iterator<String> it = extras.keySet().iterator(); - while (it.hasNext()) { - String key = it.next(); - Object value = extras.get(key); - - Log.d(LOG_TAG, "key = " + key); - if (key.startsWith(GCM_NOTIFICATION)) { - key = key.substring(GCM_NOTIFICATION.length()+1, key.length()); - } - - // System data from Android - if (key.equals(FROM) || key.equals(COLLAPSE_KEY)) { - additionalData.put(key, value); - } - else if (key.equals(FOREGROUND)) { - additionalData.put(key, extras.getBoolean(FOREGROUND)); - } - else if (key.equals(COLDSTART)){ - additionalData.put(key, extras.getBoolean(COLDSTART)); - } else if (key.equals(MESSAGE) || key.equals(BODY)) { - json.put(MESSAGE, value); - } else if (key.equals(TITLE)) { - json.put(TITLE, value); - } else if (key.equals(MSGCNT) || key.equals(BADGE)) { - json.put(COUNT, value); - } else if (key.equals(SOUNDNAME) || key.equals(SOUND)) { - json.put(SOUND, value); - } else if (key.equals(IMAGE)) { - json.put(IMAGE, value); - } else if (key.equals(CALLBACK)) { - json.put(CALLBACK, value); - } - else if ( value instanceof String ) { - String strValue = (String)value; - try { - // Try to figure out if the value is another JSON object - if (strValue.startsWith("{")) { - additionalData.put(key, new JSONObject(strValue)); - } - // Try to figure out if the value is another JSON array - else if (strValue.startsWith("[")) { - additionalData.put(key, new JSONArray(strValue)); - } - else { - additionalData.put(key, value); - } - } catch (Exception e) { - additionalData.put(key, value); - } - } - } // while - - json.put(ADDITIONAL_DATA, additionalData); - Log.v(LOG_TAG, "extrasToJSON: " + json.toString()); - - return json; - } - catch( JSONException e) { - Log.e(LOG_TAG, "extrasToJSON: JSON exception"); - } - return null; - } - - public static boolean isInForeground() { - return gForeground; - } - - public static boolean isActive() { - return gWebView != null; - } -}
\ No newline at end of file diff --git a/plugins/phonegap-plugin-push/src/android/libs/gcm.jar b/plugins/phonegap-plugin-push/src/android/libs/gcm.jar Binary files differdeleted file mode 100644 index ac109a83..00000000 --- a/plugins/phonegap-plugin-push/src/android/libs/gcm.jar +++ /dev/null diff --git a/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.h b/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.h deleted file mode 100644 index 695e9384..00000000 --- a/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// AppDelegate+notification.h -// pushtest -// -// Created by Robert Easterday on 10/26/12. -// -// - -#import "AppDelegate.h" - -@interface AppDelegate (notification) -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo; -- (void)applicationDidBecomeActive:(UIApplication *)application; -- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings; -- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler; -- (id) getCommandInstance:(NSString*)className; - -@property (nonatomic, retain) NSDictionary *launchNotification; - -@end diff --git a/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.m b/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.m deleted file mode 100644 index 37241269..00000000 --- a/plugins/phonegap-plugin-push/src/ios/AppDelegate+notification.m +++ /dev/null @@ -1,135 +0,0 @@ -// -// AppDelegate+notification.m -// pushtest -// -// Created by Robert Easterday on 10/26/12. -// -// - -#import "AppDelegate+notification.h" -#import "PushPlugin.h" -#import <objc/runtime.h> - -static char launchNotificationKey; - -@implementation AppDelegate (notification) - -- (id) getCommandInstance:(NSString*)className -{ - return [self.viewController getCommandInstance:className]; -} - -// its dangerous to override a method from within a category. -// Instead we will use method swizzling. we set this up in the load call. -+ (void)load -{ - Method original, swizzled; - - original = class_getInstanceMethod(self, @selector(init)); - swizzled = class_getInstanceMethod(self, @selector(swizzled_init)); - method_exchangeImplementations(original, swizzled); -} - -- (AppDelegate *)swizzled_init -{ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createNotificationChecker:) - name:@"UIApplicationDidFinishLaunchingNotification" object:nil]; - - // This actually calls the original init method over in AppDelegate. Equivilent to calling super - // on an overrided method, this is not recursive, although it appears that way. neat huh? - return [self swizzled_init]; -} - -// This code will be called immediately after application:didFinishLaunchingWithOptions:. We need -// to process notifications in cold-start situations -- (void)createNotificationChecker:(NSNotification *)notification -{ - if (notification) - { - NSDictionary *launchOptions = [notification userInfo]; - if (launchOptions) - self.launchNotification = [launchOptions objectForKey: @"UIApplicationLaunchOptionsRemoteNotificationKey"]; - } -} - -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; - [pushHandler didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; -} - -- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { - PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; - [pushHandler didFailToRegisterForRemoteNotificationsWithError:error]; -} - -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { - NSLog(@"didReceiveNotification"); - - // Get application state for iOS4.x+ devices, otherwise assume active - UIApplicationState appState = UIApplicationStateActive; - if ([application respondsToSelector:@selector(applicationState)]) { - appState = application.applicationState; - } - - if (appState == UIApplicationStateActive) { - PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; - pushHandler.notificationMessage = userInfo; - pushHandler.isInline = YES; - [pushHandler notificationReceived]; - } else { - //save it for later - self.launchNotification = userInfo; - } -} - -- (void)applicationDidBecomeActive:(UIApplication *)application { - - NSLog(@"active"); - - //zero badge - application.applicationIconBadgeNumber = 0; - - if (self.launchNotification) { - PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; - pushHandler.isInline = NO; - pushHandler.notificationMessage = self.launchNotification; - self.launchNotification = nil; - [pushHandler performSelectorOnMainThread:@selector(notificationReceived) withObject:pushHandler waitUntilDone:NO]; - } -} - -- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings -{ - //register to receive notifications - [application registerForRemoteNotifications]; -} - -//For interactive notification only -- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler -{ - //handle the actions - if ([identifier isEqualToString:@"declineAction"]){ - } - else if ([identifier isEqualToString:@"answerAction"]){ - } -} - - -// The accessors use an Associative Reference since you can't define a iVar in a category -// http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocAssociativeReferences.html -- (NSMutableArray *)launchNotification -{ - return objc_getAssociatedObject(self, &launchNotificationKey); -} - -- (void)setLaunchNotification:(NSDictionary *)aDictionary -{ - objc_setAssociatedObject(self, &launchNotificationKey, aDictionary, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (void)dealloc -{ - self.launchNotification = nil; // clear the association and release the object -} - -@end diff --git a/plugins/phonegap-plugin-push/src/ios/PushPlugin.h b/plugins/phonegap-plugin-push/src/ios/PushPlugin.h deleted file mode 100644 index e363e2e5..00000000 --- a/plugins/phonegap-plugin-push/src/ios/PushPlugin.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright 2009-2011 Urban Airship Inc. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - 2. Redistributions in binaryform must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided withthe distribution. - - THIS SOFTWARE IS PROVIDED BY THE URBAN AIRSHIP INC``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - EVENT SHALL URBAN AIRSHIP INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import <Foundation/Foundation.h> -#import <Cordova/CDV.h> -#import <Cordova/CDVPlugin.h> - -@interface PushPlugin : CDVPlugin -{ - NSDictionary *notificationMessage; - BOOL isInline; - NSString *notificationCallbackId; - NSString *callback; - - BOOL ready; -} - -@property (nonatomic, copy) NSString *callbackId; -@property (nonatomic, copy) NSString *notificationCallbackId; -@property (nonatomic, copy) NSString *callback; - -@property (nonatomic, strong) NSDictionary *notificationMessage; -@property BOOL isInline; - -- (void)init:(CDVInvokedUrlCommand*)command; -- (void)unregister:(CDVInvokedUrlCommand*)command; - -- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; -- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; - -- (void)setNotificationMessage:(NSDictionary *)notification; -- (void)notificationReceived; - -@end diff --git a/plugins/phonegap-plugin-push/src/ios/PushPlugin.m b/plugins/phonegap-plugin-push/src/ios/PushPlugin.m deleted file mode 100644 index fc5b8c2e..00000000 --- a/plugins/phonegap-plugin-push/src/ios/PushPlugin.m +++ /dev/null @@ -1,279 +0,0 @@ -/* - Copyright 2009-2011 Urban Airship Inc. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - 2. Redistributions in binaryform must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided withthe distribution. - - THIS SOFTWARE IS PROVIDED BY THE URBAN AIRSHIP INC``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - EVENT SHALL URBAN AIRSHIP INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "PushPlugin.h" - -@implementation PushPlugin - -@synthesize notificationMessage; -@synthesize isInline; - -@synthesize callbackId; -@synthesize notificationCallbackId; -@synthesize callback; - - -- (void)unregister:(CDVInvokedUrlCommand*)command; -{ - self.callbackId = command.callbackId; - - [[UIApplication sharedApplication] unregisterForRemoteNotifications]; - [self successWithMessage:@"unregistered"]; -} - -- (void)init:(CDVInvokedUrlCommand*)command; -{ - NSLog(@"Push Plugin register called"); - self.callbackId = command.callbackId; - - NSMutableDictionary* options = [command.arguments objectAtIndex:0]; - NSMutableDictionary* iosOptions = [options objectForKey:@"ios"]; - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - UIUserNotificationType UserNotificationTypes = UIUserNotificationTypeNone; -#endif - UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeNone; - - id badgeArg = [iosOptions objectForKey:@"badge"]; - id soundArg = [iosOptions objectForKey:@"sound"]; - id alertArg = [iosOptions objectForKey:@"alert"]; - - if (([badgeArg isKindOfClass:[NSString class]] && [badgeArg isEqualToString:@"true"]) || [badgeArg boolValue]) - { - notificationTypes |= UIRemoteNotificationTypeBadge; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - UserNotificationTypes |= UIUserNotificationTypeBadge; -#endif - } - - if (([soundArg isKindOfClass:[NSString class]] && [soundArg isEqualToString:@"true"]) || [soundArg boolValue]) - { - notificationTypes |= UIRemoteNotificationTypeSound; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - UserNotificationTypes |= UIUserNotificationTypeSound; -#endif - } - - if (([alertArg isKindOfClass:[NSString class]] && [alertArg isEqualToString:@"true"]) || [alertArg boolValue]) - { - notificationTypes |= UIRemoteNotificationTypeAlert; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - UserNotificationTypes |= UIUserNotificationTypeAlert; -#endif - } - - notificationTypes |= UIRemoteNotificationTypeNewsstandContentAvailability; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - UserNotificationTypes |= UIUserNotificationActivationModeBackground; -#endif - - if (notificationTypes == UIRemoteNotificationTypeNone) - NSLog(@"PushPlugin.register: Push notification type is set to none"); - - isInline = NO; - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 - if ([[UIApplication sharedApplication]respondsToSelector:@selector(registerUserNotificationSettings:)]) { - UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UserNotificationTypes categories:nil]; - [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; - [[UIApplication sharedApplication] registerForRemoteNotifications]; - } else { - [[UIApplication sharedApplication] registerForRemoteNotificationTypes: - (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; - } -#else - [[UIApplication sharedApplication] registerForRemoteNotificationTypes: - (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; -#endif - - if (notificationMessage) // if there is a pending startup notification - [self notificationReceived]; // go ahead and process it -} - -- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - NSLog(@"Push Plugin register success: %@", deviceToken); - - NSMutableDictionary *results = [NSMutableDictionary dictionary]; - NSString *token = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""] - stringByReplacingOccurrencesOfString:@">" withString:@""] - stringByReplacingOccurrencesOfString: @" " withString: @""]; - [results setValue:token forKey:@"deviceToken"]; - -#if !TARGET_IPHONE_SIMULATOR - // Get Bundle Info for Remote Registration (handy if you have more than one app) - [results setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"] forKey:@"appName"]; - [results setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] forKey:@"appVersion"]; - - // Check what Notifications the user has turned on. We registered for all three, but they may have manually disabled some or all of them. -#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) - - NSUInteger rntypes; - if (!SYSTEM_VERSION_LESS_THAN(@"8.0")) { - rntypes = [[[UIApplication sharedApplication] currentUserNotificationSettings] types]; - } else { - rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes]; - } - - // Set the defaults to disabled unless we find otherwise... - NSString *pushBadge = @"disabled"; - NSString *pushAlert = @"disabled"; - NSString *pushSound = @"disabled"; - - // Check what Registered Types are turned on. This is a bit tricky since if two are enabled, and one is off, it will return a number 2... not telling you which - // one is actually disabled. So we are literally checking to see if rnTypes matches what is turned on, instead of by number. The "tricky" part is that the - // single notification types will only match if they are the ONLY one enabled. Likewise, when we are checking for a pair of notifications, it will only be - // true if those two notifications are on. This is why the code is written this way - if(rntypes & UIRemoteNotificationTypeBadge){ - pushBadge = @"enabled"; - } - if(rntypes & UIRemoteNotificationTypeAlert) { - pushAlert = @"enabled"; - } - if(rntypes & UIRemoteNotificationTypeSound) { - pushSound = @"enabled"; - } - - [results setValue:pushBadge forKey:@"pushBadge"]; - [results setValue:pushAlert forKey:@"pushAlert"]; - [results setValue:pushSound forKey:@"pushSound"]; - - // Get the users Device Model, Display Name, Token & Version Number - UIDevice *dev = [UIDevice currentDevice]; - [results setValue:dev.name forKey:@"deviceName"]; - [results setValue:dev.model forKey:@"deviceModel"]; - [results setValue:dev.systemVersion forKey:@"deviceSystemVersion"]; - - // Send result to trigger 'registration' event but keep callback - NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:1]; - [message setObject:token forKey:@"registrationId"]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; - [pluginResult setKeepCallbackAsBool:YES]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; -#endif -} - -- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error -{ - NSLog(@"Push Plugin register failed"); - [self failWithMessage:@"" withError:error]; -} - -- (void)notificationReceived { - NSLog(@"Notification received"); - - if (notificationMessage && self.callbackId != nil) - { - NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:4]; - NSMutableDictionary* additionalData = [NSMutableDictionary dictionaryWithCapacity:4]; - - - for (id key in notificationMessage) { - if ([key isEqualToString:@"aps"]) { - id aps = [notificationMessage objectForKey:@"aps"]; - - for(id key in aps) { - NSLog(@"Push Plugin key: %@", key); - id value = [aps objectForKey:key]; - - if ([key isEqualToString:@"alert"]) { - if ([value isKindOfClass:[NSDictionary class]]) { - for (id messageKey in value) { - id messageValue = [value objectForKey:messageKey]; - if ([messageKey isEqualToString:@"body"]) { - [message setObject:messageValue forKey:@"message"]; - } else if ([messageKey isEqualToString:@"title"]) { - [message setObject:messageValue forKey:@"title"]; - } else { - [additionalData setObject:messageValue forKey:messageKey]; - } - } - } - else { - [message setObject:value forKey:@"message"]; - } - } else if ([key isEqualToString:@"title"]) { - [message setObject:value forKey:@"title"]; - } else if ([key isEqualToString:@"badge"]) { - [message setObject:value forKey:@"count"]; - } else if ([key isEqualToString:@"sound"]) { - [message setObject:value forKey:@"sound"]; - } else if ([key isEqualToString:@"image"]) { - [message setObject:value forKey:@"image"]; - } else { - [additionalData setObject:value forKey:key]; - } - } - } else { - [additionalData setObject:[notificationMessage objectForKey:key] forKey:key]; - } - } - - if (isInline) { - [additionalData setObject:[NSNumber numberWithBool:YES] forKey:@"foreground"]; - } else { - [additionalData setObject:[NSNumber numberWithBool:NO] forKey:@"foreground"]; - } - - [message setObject:additionalData forKey:@"additionalData"]; - - // send notification message - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message]; - [pluginResult setKeepCallbackAsBool:YES]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; - - self.notificationMessage = nil; - } -} - -- (void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command -{ - NSMutableDictionary* options = [command.arguments objectAtIndex:0]; - int badge = [[options objectForKey:@"badge"] intValue] ?: 0; - - [[UIApplication sharedApplication] setApplicationIconBadgeNumber:badge]; - - NSString* message = [NSString stringWithFormat:@"app badge count set to %d", badge]; - CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; - [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; -} - --(void)successWithMessage:(NSString *)message -{ - if (self.callbackId != nil) - { - CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; - [self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId]; - } -} - --(void)failWithMessage:(NSString *)message withError:(NSError *)error -{ - NSString *errorMessage = (error) ? [NSString stringWithFormat:@"%@ - %@", message, [error localizedDescription]] : message; - CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage]; - - [self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId]; -} - -@end diff --git a/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js b/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js deleted file mode 100644 index ca8087b2..00000000 --- a/plugins/phonegap-plugin-push/src/windows/PushPluginProxy.js +++ /dev/null @@ -1,86 +0,0 @@ -var myApp = {}; -var pushNotifications = Windows.Networking.PushNotifications; - -var createNotificationJSON = function (e) { - var result = { message: '' }; //Added to identify callback as notification type in the API in case where notification has no message - var notificationPayload; - - switch (e.notificationType) { - case pushNotifications.PushNotificationType.toast: - case pushNotifications.PushNotificationType.tile: - if (e.notificationType === pushNotifications.PushNotificationType.toast) { - notificationPayload = e.toastNotification.content; - } - else { - notificationPayload = e.tileNotification.content; - } - var texts = notificationPayload.getElementsByTagName("text"); - if (texts.length > 1) { - result.title = texts[0].innerText; - result.message = texts[1].innerText; - } - else if(texts.length === 1) { - result.message = texts[0].innerText; - } - var images = notificationPayload.getElementsByTagName("image"); - if (images.length > 0) { - result.image = images[0].getAttribute("src"); - } - var soundFile = notificationPayload.getElementsByTagName("audio"); - if (soundFile.length > 0) { - result.sound = soundFile[0].getAttribute("src"); - } - break; - - case pushNotifications.PushNotificationType.badge: - notificationPayload = e.badgeNotification.content; - result.count = notificationPayload.getElementsByTagName("badge")[0].getAttribute("value"); - break; - - case pushNotifications.PushNotificationType.raw: - result.message = e.rawNotification.content; - break; - } - - result.additionalData = {}; - result.additionalData.pushNotificationReceivedEventArgs = e; - return result; -} - -module.exports = { - init: function (onSuccess, onFail, args) { - - var onNotificationReceived = function (e) { - var result = createNotificationJSON(e); - onSuccess(result, { keepCallback: true }); - } - - try { - pushNotifications.PushNotificationChannelManager.createPushNotificationChannelForApplicationAsync().done( - function (channel) { - var result = {}; - result.registrationId = channel.uri; - myApp.channel = channel; - channel.addEventListener("pushnotificationreceived", onNotificationReceived); - myApp.notificationEvent = onNotificationReceived; - onSuccess(result, { keepCallback: true }); - }, function (error) { - onFail(error); - }); - } catch (ex) { - onFail(ex); - } - }, - unregister: function (onSuccess, onFail, args) { - try { - myApp.channel.removeEventListener("pushnotificationreceived", myApp.notificationEvent); - myApp.channel.close(); - onSuccess(); - } catch(ex) { - onFail(ex); - } - } -}; -require("cordova/exec/proxy").add("PushNotification", module.exports); - - diff --git a/plugins/phonegap-plugin-push/www/push.js b/plugins/phonegap-plugin-push/www/push.js deleted file mode 100644 index d03ea593..00000000 --- a/plugins/phonegap-plugin-push/www/push.js +++ /dev/null @@ -1,178 +0,0 @@ -/* global cordova:false */ - -/*! - * Module dependencies. - */ - -var exec = cordova.require('cordova/exec'); - -/** - * PushNotification constructor. - * - * @param {Object} options to initiate Push Notifications. - * @return {PushNotification} instance that can be monitored and cancelled. - */ - -var PushNotification = function(options) { - this._handlers = { - 'registration': [], - 'notification': [], - 'error': [] - }; - - // require options parameter - if (typeof options === 'undefined') { - throw new Error('The options argument is required.'); - } - - // store the options to this object instance - this.options = options; - - // triggered on registration and notification - var that = this; - var success = function(result) { - if (result && typeof result.registrationId !== 'undefined') { - that.emit('registration', result); - } else if (result && typeof result.callback !== 'undefined') { - var executeFunctionByName = function(functionName, context /*, args */) { - var args = Array.prototype.slice.call(arguments, 2); - var namespaces = functionName.split("."); - var func = namespaces.pop(); - for (var i = 0; i < namespaces.length; i++) { - context = context[namespaces[i]]; - } - return context[func].apply(context, args); - } - - executeFunctionByName(result.callback, window, result); - } else if (result) { - that.emit('notification', result); - } - }; - - // triggered on error - var fail = function(msg) { - var e = (typeof msg === 'string') ? new Error(msg) : msg; - that.emit('error', e); - }; - - // wait at least one process tick to allow event subscriptions - setTimeout(function() { - exec(success, fail, 'PushNotification', 'init', [options]); - }, 10); -}; - -/** - * Unregister from push notifications - */ - -PushNotification.prototype.unregister = function(successCallback, errorCallback, options) { - if (errorCallback == null) { errorCallback = function() {}} - - if (typeof errorCallback != "function") { - console.log("PushNotification.unregister failure: failure parameter not a function"); - return - } - - if (typeof successCallback != "function") { - console.log("PushNotification.unregister failure: success callback parameter must be a function"); - return - } - - exec(successCallback, errorCallback, "PushNotification", "unregister", [options]); -}; - -/** - * Call this to set the application icon badge - */ - -PushNotification.prototype.setApplicationIconBadgeNumber = function(successCallback, errorCallback, badge) { - if (errorCallback == null) { errorCallback = function() {}} - - if (typeof errorCallback != "function") { - console.log("PushNotification.setApplicationIconBadgeNumber failure: failure parameter not a function"); - return - } - - if (typeof successCallback != "function") { - console.log("PushNotification.setApplicationIconBadgeNumber failure: success callback parameter must be a function"); - return - } - - exec(successCallback, errorCallback, "PushNotification", "setApplicationIconBadgeNumber", [{badge: badge}]); -}; - -/** - * Listen for an event. - * - * The following events are supported: - * - * - registration - * - notification - * - error - * - * @param {String} eventName to subscribe to. - * @param {Function} callback triggered on the event. - */ - -PushNotification.prototype.on = function(eventName, callback) { - if (this._handlers.hasOwnProperty(eventName)) { - this._handlers[eventName].push(callback); - } -}; - -/** - * Emit an event. - * - * This is intended for internal use only. - * - * @param {String} eventName is the event to trigger. - * @param {*} all arguments are passed to the event listeners. - * - * @return {Boolean} is true when the event is triggered otherwise false. - */ - -PushNotification.prototype.emit = function() { - var args = Array.prototype.slice.call(arguments); - var eventName = args.shift(); - - if (!this._handlers.hasOwnProperty(eventName)) { - return false; - } - - for (var i = 0, length = this._handlers[eventName].length; i < length; i++) { - this._handlers[eventName][i].apply(undefined,args); - } - - return true; -}; - -/*! - * Push Notification Plugin. - */ - -module.exports = { - /** - * Register for Push Notifications. - * - * This method will instantiate a new copy of the PushNotification object - * and start the registration process. - * - * @param {Object} options - * @return {PushNotification} instance - */ - - init: function(options) { - return new PushNotification(options); - }, - - /** - * PushNotification Object. - * - * Expose the PushNotification object for direct use - * and testing. Typically, you should use the - * .init helper method. - */ - - PushNotification: PushNotification -};
\ No newline at end of file diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/CHANGELOG.md b/plugins/uk.co.whiteoctober.cordova.appversion/CHANGELOG.md deleted file mode 100644 index dcc0129a..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/CHANGELOG.md +++ /dev/null @@ -1,39 +0,0 @@ -### 0.1.7 - -* Add getPackageName feature (thanks to @gprasanth) -* Add getAppName feature (thanks to @mirko77) -* Fix for windows 8 (thanks to @deliriousrhino) -* Fix version number in plugin.xml file - -### 0.1.6 - -* Split into two functions getAppVersion.getVersionNumber() and getAppVersion.getVersionCode() to return build number -* Fix a deprecation warning in iOS version - -### 0.1.5 - -* iOS: Return version number but log and fall back to build number if it is nil (thanks to [Eddy Verbruggen](https://github.com/EddyVerbruggen)) - -### 0.1.4 - -* Return version number, not build number on iOS (thanks to http://www.humancopy.net) -* Support for Windows phone 8 (thanks to Cristi Badila / Gediminas Šaltenis) -* Support for AngularJS as well as jQuery (thanks to Matias Singers, [Red Ape Solutions](http://www.redapesolutions.com/)) - -### 0.1.3 - -* Fixes to Android for Corova 3 and above (thanks to AxoInsanit) - -### 0.1.2 - -* Updated for Cordova 3 and above (thanks to Russell Keith-Magee [freakboy3742](https://github.com/freakboy3742) - -### 0.1.1 - -* Improved README -* Bug fix for non-jQuery use -* Tidy plugin.xml - -### 0.1.0 - -* First release diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/LICENSE b/plugins/uk.co.whiteoctober.cordova.appversion/LICENSE deleted file mode 100644 index 484859fd..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2013 White October - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/README.md b/plugins/uk.co.whiteoctober.cordova.appversion/README.md deleted file mode 100644 index 2afff928..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# Cordova AppVersion plugin - -Reads the version of your app from the target build settings. - -## Installation - -### With cordova-cli - -If you are using [cordova-cli](https://github.com/apache/cordova-cli), install -with: - - cordova plugin add https://github.com/whiteoctober/cordova-plugin-app-version.git - -### With plugman - -With a plain [plugman](https://github.com/apache/cordova-plugman), you should be -able to install with something like: - - plugman --platform <ios|android> --project <directory> --plugin https://github.com/whiteoctober/cordova-plugin-app-version.git - -### Manually in iOS - -TODO: Write these instructions - -### Manually in Android - -TODO: Write these instructions - -## Use from Javascript - -If you are using jQuery or AngularJS, promise style is supported. Use something like: - - cordova.getAppVersion.getVersionNumber().then(function (version) { - $('.version').text(version); - }); - -If not, pass a callback function: - - cordova.getAppVersion.getVersionNumber(function (version) { - alert(version); - }); - -In addition to the version number you can also retrieve other details about your application: - -### getAppName - -Returns the name of the app. E.g. "My Awesome App" - -### getPackageName - -Returns the package name of the app - the reversed domain name app identifier like com.example.myawesomeapp - -### getVersionCode - -Returns the build identifier of the app - -### getVersionNumber - -Returns the version number of the app - -## Credits - -Written by [Robert (Jamie) Munro](http://twitter.com/rjmunro) at -[White October](http://whiteoctober.co.uk/) - -Various others have contributed fixes and new features. See the CHANGELOG.md for details. - -Original code based on the following Stack Overflow posts: - -* [iOS](http://stackoverflow.com/a/14713364/3408) -* [Android](http://stackoverflow.com/a/3637686/3408) diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/VERSION b/plugins/uk.co.whiteoctober.cordova.appversion/VERSION deleted file mode 100644 index 11808190..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1.7 diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/plugin.xml b/plugins/uk.co.whiteoctober.cordova.appversion/plugin.xml deleted file mode 100644 index 8ff4c5eb..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/plugin.xml +++ /dev/null @@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0" - xmlns:android="http://schemas.android.com/apk/res/android" - id="uk.co.whiteoctober.cordova.appversion" - version="0.1.7"> - - <name>AppVersion</name> - <description> - This plugin will return the version of your App that you have set in - packaging it. I.e. it will always match the version in the app store. - </description> - <license>MIT</license> - - <engines> - <!-- - Cordova 2.8.0 is all I have tested on - it should work fine with earlier versions. - Please modify the below line, test, and submit a PR if it works for you. - --> - <engine name="cordova" version=">=3.0.0" /> - </engines> - - <js-module src="www/AppVersionPlugin.js"> - <clobbers target="cordova.getAppVersion" /> - </js-module> - - <!-- android --> - <platform name="android"> - <config-file target="res/xml/config.xml" parent="/*"> - <feature name="AppVersion"> - <param name="android-package" value="uk.co.whiteoctober.cordova.AppVersion"/> - </feature> - </config-file> - <source-file src="src/android/AppVersion.java" target-dir="src/uk/co/whiteoctober/cordova" /> - </platform> - - <!-- blackberry10 --> - <platform name="blackberry10"> - <dependency id="com.blackberry.app" /> - - <config-file target="www/config.xml" parent="/widget"> - <feature name="AppVersion" value="AppVersion" /> - </config-file> - <js-module src="www/blackberry10/AppVersionProxy.js" name="AppVersionProxy.js" > - <runs /> - </js-module> - </platform> - - <!-- ios --> - <platform name="ios"> - <plugins-plist key="AppVersion" string="AppVersion" /> - - <config-file target="config.xml" parent="/*"> - <feature name="AppVersion"> - <param name="ios-package" value="AppVersion" /> - </feature> - </config-file> - - <header-file src="src/ios/AppVersion.h" /> - <source-file src="src/ios/AppVersion.m" /> - </platform> - - <!-- windows8 --> - <platform name="windows8"> - <js-module src="src/windows8/AppVersionProxy.js" name="AppVersionProxy"> - <merges target=""/> - </js-module> - </platform> - - <!-- wp8 --> - <platform name="wp8"> - <config-file target="config.xml" parent="/*"> - <feature name="AppVersion"> - <param name="wp-package" value="AppVersion"/> - </feature> - </config-file> - - <source-file src="src/wp8/AppVersion.cs" /> - </platform> -</plugin> diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/src/android/AppVersion.java b/plugins/uk.co.whiteoctober.cordova.appversion/src/android/AppVersion.java deleted file mode 100644 index 204ed7e8..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/src/android/AppVersion.java +++ /dev/null @@ -1,45 +0,0 @@ -package uk.co.whiteoctober.cordova; - -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CallbackContext; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.PackageManager; - -public class AppVersion extends CordovaPlugin { - @Override - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - - try { - if (action.equals("getAppName")) { - PackageManager packageManager = this.cordova.getActivity().getPackageManager(); - ApplicationInfo app = packageManager.getApplicationInfo(this.cordova.getActivity().getPackageName(), 0); - callbackContext.success((String)packageManager.getApplicationLabel(app)); - return true; - } - if (action.equals("getPackageName")) { - callbackContext.success(this.cordova.getActivity().getPackageName()); - return true; - } - if (action.equals("getVersionNumber")) { - PackageManager packageManager = this.cordova.getActivity().getPackageManager(); - callbackContext.success(packageManager.getPackageInfo(this.cordova.getActivity().getPackageName(), 0).versionName); - return true; - } - if (action.equals("getVersionCode")) { - PackageManager packageManager = this.cordova.getActivity().getPackageManager(); - callbackContext.success(packageManager.getPackageInfo(this.cordova.getActivity().getPackageName(), 0).versionCode); - return true; - } - return false; - } catch (NameNotFoundException e) { - callbackContext.success("N/A"); - return true; - } - } - -} diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/src/ios/AppVersion.h b/plugins/uk.co.whiteoctober.cordova.appversion/src/ios/AppVersion.h deleted file mode 100644 index 87c0330b..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/src/ios/AppVersion.h +++ /dev/null @@ -1,13 +0,0 @@ -#import <Cordova/CDVPlugin.h> - -@interface AppVersion : CDVPlugin - -- (void)getAppName:(CDVInvokedUrlCommand*)command; - -- (void)getPackageName:(CDVInvokedUrlCommand*)command; - -- (void)getVersionNumber:(CDVInvokedUrlCommand*)command; - -- (void)getVersionCode:(CDVInvokedUrlCommand*)command; - -@end diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/src/ios/AppVersion.m b/plugins/uk.co.whiteoctober.cordova.appversion/src/ios/AppVersion.m deleted file mode 100644 index a73c78f9..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/src/ios/AppVersion.m +++ /dev/null @@ -1,47 +0,0 @@ -#import "AppVersion.h" -#import <Cordova/CDVPluginResult.h> - -@implementation AppVersion - -- (void)getAppName : (CDVInvokedUrlCommand *)command -{ - NSString * callbackId = command.callbackId; - NSString * version =[[[NSBundle mainBundle]infoDictionary]objectForKey :@"CFBundleDisplayName"]; - CDVPluginResult * pluginResult =[CDVPluginResult resultWithStatus : CDVCommandStatus_OK messageAsString : version]; - [self.commandDelegate sendPluginResult : pluginResult callbackId : callbackId]; -} - -- (void)getPackageName:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - NSString* packageName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:packageName]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; -} - -- (void)getVersionNumber:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - NSString* version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; - if (version == nil) { - NSLog(@"CFBundleShortVersionString was nil, attempting CFBundleVersion"); - version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; - if (version == nil) { - NSLog(@"CFBundleVersion was also nil, giving up"); - // not calling error callback here to maintain backward compatibility - } - } - - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:version]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; -} - -- (void)getVersionCode:(CDVInvokedUrlCommand*)command -{ - NSString* callbackId = command.callbackId; - NSString* version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]; - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:version]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:callbackId]; -} - -@end diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/src/windows8/AppVersionProxy.js b/plugins/uk.co.whiteoctober.cordova.appversion/src/windows8/AppVersionProxy.js deleted file mode 100644 index 3b4c50ee..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/src/windows8/AppVersionProxy.js +++ /dev/null @@ -1,7 +0,0 @@ -AppVersionProxy = { - getVersionNumber: function (successCallback, failCallback, args) { - var version = Windows.ApplicationModel.Package.current.id.version; - successCallback([version.major, version.minor, version.build, version.revision].join('.')); - } -}; -cordova.commandProxy.add("AppVersion", AppVersionProxy); diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/src/wp8/AppVersion.cs b/plugins/uk.co.whiteoctober.cordova.appversion/src/wp8/AppVersion.cs deleted file mode 100644 index 2f3d2c95..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/src/wp8/AppVersion.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Navigation; -using Microsoft.Phone.Controls; -using WPCordovaClassLib.Cordova; -using WPCordovaClassLib.Cordova.Commands; -using WPCordovaClassLib.Cordova.JSON; -using Windows.ApplicationModel; -using System.Xml.Linq; - -namespace Cordova.Extension.Commands -{ - public class AppVersion : BaseCommand - { - public void getVersionNumber(string empty) - { - //Windows.ApplicationModel.Package.current.id.version is NOT working in Windows Phone 8 - //Workaround based on http://stackoverflow.com/questions/14371275/how-can-i-get-my-windows-store-apps-title-and-version-info - String version= XDocument.Load("WMAppManifest.xml").Root.Element("App").Attribute("Version").Value; - - this.DispatchCommandResult(new PluginResult(PluginResult.Status.OK, version)); - } - } -} diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/www/AppVersionPlugin.js b/plugins/uk.co.whiteoctober.cordova.appversion/www/AppVersionPlugin.js deleted file mode 100644 index 3e395260..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/www/AppVersionPlugin.js +++ /dev/null @@ -1,48 +0,0 @@ -/*jslint indent: 2 */ -/*global window, jQuery, angular, cordova */ -"use strict"; - -// Returns a jQuery or AngularJS deferred object, or pass a success and fail callbacks if you don't want to use jQuery or AngularJS -var getPromisedCordovaExec = function (command, success, fail) { - var toReturn, deferred, injector, $q; - if (success === undefined) { - if (window.jQuery) { - deferred = jQuery.Deferred(); - toReturn = deferred; - } else if (window.angular) { - injector = angular.injector(["ng"]); - $q = injector.get("$q"); - deferred = $q.defer(); - toReturn = deferred.promise; - } else { - return console.error('AppVersion either needs a success callback, or jQuery/AngularJS defined for using promises'); - } - success = deferred.resolve; - fail = deferred.reject; - } - // 5th param is NOT optional. must be at least empty array - cordova.exec(success, fail, "AppVersion", command, []); - return toReturn; -}; - -var getAppVersion = function (success, fail) { - return getPromisedCordovaExec('getVersionNumber', success, fail); -}; - -getAppVersion.getAppName = function (success, fail) { - return getPromisedCordovaExec('getAppName', success, fail); -}; - -getAppVersion.getPackageName = function (success, fail) { - return getPromisedCordovaExec('getPackageName', success, fail); -}; - -getAppVersion.getVersionNumber = function (success, fail) { - return getPromisedCordovaExec('getVersionNumber', success, fail); -}; - -getAppVersion.getVersionCode = function (success, fail) { - return getPromisedCordovaExec('getVersionCode', success, fail); -}; - -module.exports = getAppVersion; diff --git a/plugins/uk.co.whiteoctober.cordova.appversion/www/blackberry10/AppVersionProxy.js b/plugins/uk.co.whiteoctober.cordova.appversion/www/blackberry10/AppVersionProxy.js deleted file mode 100644 index 82dc82aa..00000000 --- a/plugins/uk.co.whiteoctober.cordova.appversion/www/blackberry10/AppVersionProxy.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - getVersionNumber: function( success, fail ) { - if( !blackberry || !blackberry.app || !blackberry.app.version ) { - if( fail ) { - return fail(); - } else { - return ""; - } - } - - if( success ) { - return success( blackberry.app.version ); - } - return blackberry.app.version; - } -}; - -require("cordova/exec/proxy").add("AppVersion", module.exports); |
