Commit 59e85018 by Sebastián Katzer

Update project

parent 8cd74e5b
/out /out
/gen /gen
/platforms/android/CordovaLib/build /platforms/android/CordovaLib/build
/platforms/windows/build
...@@ -9,4 +9,5 @@ ...@@ -9,4 +9,5 @@
</author> </author>
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<preference name="windows-target-version" value="10.0" />
</widget> </widget>
...@@ -7,25 +7,17 @@ ...@@ -7,25 +7,17 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="09590114-0710-4ca6-8105-bfe16b486a0c" name="Default" comment=""> <list default="true" id="09590114-0710-4ca6-8105-bfe16b486a0c" name="Default" comment="">
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/cordova-web.png" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/../ios/NotificationExample.xcodeproj/project.xcworkspace/xcuserdata/sebastian.xcuserdatad/UserInterfaceState.xcuserstate" afterPath="$PROJECT_DIR$/../ios/NotificationExample.xcodeproj/project.xcworkspace/xcuserdata/sebastian.xcuserdatad/UserInterfaceState.xcuserstate" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-hdpi/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-hdpi-v11/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-hdpi-v9/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-mdpi/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-mdpi-v11/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-mdpi-v9/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-xhdpi/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-xhdpi-v11/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-xhdpi-v9/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-xxhdpi/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-xxhdpi-v11/cordova.png" />
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/res/drawable-xxhdpi-v9/cordova.png" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/cache.properties.lock" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/cache.properties.lock" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/cache.properties.lock" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/cache.properties.lock" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileHashes.bin" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileHashes.bin" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileHashes.bin" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileHashes.bin" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin" afterPath="$PROJECT_DIR$/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/../ios/NotificationExample/NotificationExample-Info.plist" afterPath="$PROJECT_DIR$/../ios/NotificationExample/NotificationExample-Info.plist" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/assets/www/index.html" afterPath="$PROJECT_DIR$/assets/www/index.html" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/assets/www/index.html" afterPath="$PROJECT_DIR$/assets/www/index.html" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/../../www/index.html" afterPath="$PROJECT_DIR$/../../www/index.html" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js" afterPath="$PROJECT_DIR$/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js" afterPath="$PROJECT_DIR$/assets/www/plugins/de.appplant.cordova.plugin.local-notification/www/local-notification-util.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/../ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj" afterPath="$PROJECT_DIR$/../ios/CordovaLib/CordovaLib.xcodeproj/project.pbxproj" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/../ios/NotificationExample.xcodeproj/project.pbxproj" afterPath="$PROJECT_DIR$/../ios/NotificationExample.xcodeproj/project.pbxproj" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
</list> </list>
<ignored path="android.iws" /> <ignored path="android.iws" />
...@@ -47,37 +39,44 @@ ...@@ -47,37 +39,44 @@
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf> <leaf>
<file leaf-file-name="Builder.java" pinned="false" current-in-tab="false"> <file leaf-file-name="Builder.java" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.36746988">
<caret line="25" column="7" selection-start-line="25" selection-start-column="7" selection-end-line="25" selection-end-column="7" /> <caret line="126" column="45" selection-start-line="126" selection-start-column="45" selection-end-line="126" selection-end-column="45" />
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="Options.java" pinned="false" current-in-tab="false"> <file leaf-file-name="Manager.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Manager.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.0">
<caret line="48" column="19" selection-start-line="48" selection-start-column="19" selection-end-line="48" selection-end-column="19" /> <caret line="120" column="0" selection-start-line="120" selection-start-column="0" selection-end-line="120" selection-end-column="0" />
<folding> <folding />
<element signature="e#4141#4142#0" expanded="true" />
<element signature="e#4171#4172#0" expanded="true" />
<element signature="e#5111#5112#0" expanded="true" />
<element signature="e#5157#5158#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="AssetUtil.java" pinned="false" current-in-tab="true"> <file leaf-file-name="Options.java" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.55479455"> <state vertical-scroll-proportion="0.0">
<caret line="347" column="43" selection-start-line="347" selection-start-column="43" selection-end-line="347" selection-end-column="43" /> <caret line="126" column="7" selection-start-line="126" selection-start-column="7" selection-end-line="126" selection-end-column="7" />
<folding /> <folding>
<element signature="imports" expanded="true" />
<element signature="e#4736#4737#0" expanded="true" />
<element signature="e#4785#4786#0" expanded="true" />
<element signature="e#4880#4881#0" expanded="true" />
<element signature="e#4939#4940#0" expanded="true" />
<element signature="e#5339#5340#0" expanded="true" />
<element signature="e#5380#5381#0" expanded="true" />
<element signature="e#5453#5454#0" expanded="true" />
<element signature="e#5502#5503#0" expanded="true" />
<element signature="e#5591#5592#0" expanded="true" />
<element signature="e#5645#5646#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
...@@ -1014,7 +1013,7 @@ ...@@ -1014,7 +1013,7 @@
<option name="modificationStamps"> <option name="modificationStamps">
<map> <map>
<entry key="$PROJECT_DIR$/../../../../appPlant/it-projects/workshop/droidshop" value="5724663350000" /> <entry key="$PROJECT_DIR$/../../../../appPlant/it-projects/workshop/droidshop" value="5724663350000" />
<entry key="$PROJECT_DIR$" value="5798728858000" /> <entry key="$PROJECT_DIR$" value="5801142720000" />
</map> </map>
</option> </option>
<option name="projectBuildClasspath"> <option name="projectBuildClasspath">
...@@ -1307,10 +1306,10 @@ ...@@ -1307,10 +1306,10 @@
<option value="$PROJECT_DIR$/assets/www/index.html" /> <option value="$PROJECT_DIR$/assets/www/index.html" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AbstractClickActivity.java" /> <option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AbstractClickActivity.java" />
<option value="$PROJECT_DIR$/build.gradle" /> <option value="$PROJECT_DIR$/build.gradle" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Manager.java" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java" /> <option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Notification.java" /> <option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Notification.java" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java" /> <option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Manager.java" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java" /> <option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java" />
<option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java" /> <option value="$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java" />
</list> </list>
...@@ -1365,14 +1364,6 @@ ...@@ -1365,14 +1364,6 @@
<option name="myItemId" value="android" /> <option name="myItemId" value="android" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="assets" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidSourceTypeNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="www" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidPsiDirectoryNode" />
</PATH_ELEMENT>
</PATH> </PATH>
<PATH> <PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
...@@ -1384,17 +1375,9 @@ ...@@ -1384,17 +1375,9 @@
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="assets" /> <option name="myItemId" value="java" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidSourceTypeNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidSourceTypeNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="www" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidPsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="img" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH> </PATH>
<PATH> <PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
...@@ -1406,8 +1389,12 @@ ...@@ -1406,8 +1389,12 @@
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="res" /> <option name="myItemId" value="java" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidResFolderNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidSourceTypeNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="appplant" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidPsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
<PATH> <PATH>
...@@ -1420,12 +1407,16 @@ ...@@ -1420,12 +1407,16 @@
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="res" /> <option name="myItemId" value="java" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidResFolderNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidSourceTypeNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="drawable" /> <option name="myItemId" value="appplant" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidResFolderTypeNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidPsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="plugin" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
<PATH> <PATH>
...@@ -1437,30 +1428,21 @@ ...@@ -1437,30 +1428,21 @@
<option name="myItemId" value="android" /> <option name="myItemId" value="android" />
<option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidModuleNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH>
</subPane>
</pane>
<pane id="Scope" />
<pane id="PackagesPane">
<subPane>
<PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="android" /> <option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidSourceTypeNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="CordovaLib" /> <option name="myItemId" value="appplant" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" /> <option name="myItemType" value="com.android.tools.idea.navigator.nodes.AndroidPsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="android" /> <option name="myItemId" value="plugin" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="android" /> <option name="myItemId" value="localnotification" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
</subPane> </subPane>
...@@ -1499,6 +1481,31 @@ ...@@ -1499,6 +1481,31 @@
</PATH> </PATH>
</subPane> </subPane>
</pane> </pane>
<pane id="Scope" />
<pane id="PackagesPane">
<subPane>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="CordovaLib" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="android" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
...@@ -1519,7 +1526,7 @@ ...@@ -1519,7 +1526,7 @@
<property name="settings.editor.splitter.proportion" value="0.2" /> <property name="settings.editor.splitter.proportion" value="0.2" />
<property name="android.sdk.path" value="$USER_HOME$/.android/sdk" /> <property name="android.sdk.path" value="$USER_HOME$/.android/sdk" />
<property name="com.android.studio.selected.modules.on.import" value="CordovaLib&#10;android" /> <property name="com.android.studio.selected.modules.on.import" value="CordovaLib&#10;android" />
<property name="ANDROID_EXTENDED_DEVICE_CHOOSER_SERIALS" value="63aed4b4" /> <property name="ANDROID_EXTENDED_DEVICE_CHOOSER_SERIALS" value="" />
<property name="ANDROID_EXTENDED_DEVICE_CHOOSER_AVD" value="Galaxy_Nexus_API_23" /> <property name="ANDROID_EXTENDED_DEVICE_CHOOSER_AVD" value="Galaxy_Nexus_API_23" />
<property name="FullScreen" value="false" /> <property name="FullScreen" value="false" />
</component> </component>
...@@ -1655,10 +1662,10 @@ ...@@ -1655,10 +1662,10 @@
<window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" /> <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Android Monitor" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.32658958" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Android Monitor" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32658958" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32658958" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32658958" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Captures" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Captures" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3297568" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Gradle Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" /> <window_info id="Gradle Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
...@@ -1690,7 +1697,7 @@ ...@@ -1690,7 +1697,7 @@
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
<option name="time" value="26" /> <option name="time" value="32" />
</breakpoint-manager> </breakpoint-manager>
<watches-manager /> <watches-manager />
</component> </component>
...@@ -1698,6 +1705,78 @@ ...@@ -1698,6 +1705,78 @@
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.0">
<caret line="25" column="7" selection-start-line="25" selection-start-column="7" selection-end-line="25" selection-end-column="7" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="48" column="19" selection-start-line="48" selection-start-column="19" selection-end-line="48" selection-end-column="19" />
<folding>
<element signature="imports" expanded="true" />
<element signature="e#4736#4737#0" expanded="true" />
<element signature="e#4785#4786#0" expanded="true" />
<element signature="e#4880#4881#0" expanded="true" />
<element signature="e#4939#4940#0" expanded="true" />
<element signature="e#5339#5340#0" expanded="true" />
<element signature="e#5380#5381#0" expanded="true" />
<element signature="e#5453#5454#0" expanded="true" />
<element signature="e#5502#5503#0" expanded="true" />
<element signature="e#5591#5592#0" expanded="true" />
<element signature="e#5645#5646#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="25" column="7" selection-start-line="25" selection-start-column="7" selection-end-line="25" selection-end-column="7" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="48" column="19" selection-start-line="48" selection-start-column="19" selection-end-line="48" selection-end-column="19" />
<folding>
<element signature="imports" expanded="true" />
<element signature="e#4736#4737#0" expanded="true" />
<element signature="e#4785#4786#0" expanded="true" />
<element signature="e#4880#4881#0" expanded="true" />
<element signature="e#4939#4940#0" expanded="true" />
<element signature="e#5339#5340#0" expanded="true" />
<element signature="e#5380#5381#0" expanded="true" />
<element signature="e#5453#5454#0" expanded="true" />
<element signature="e#5502#5503#0" expanded="true" />
<element signature="e#5591#5592#0" expanded="true" />
<element signature="e#5645#5646#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="0" column="0" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="124" column="27" selection-start-line="124" selection-start-column="27" selection-end-line="124" selection-end-column="27" /> <caret line="124" column="27" selection-start-line="124" selection-start-column="27" selection-end-line="124" selection-end-column="27" />
<folding /> <folding />
</state> </state>
...@@ -1708,10 +1787,17 @@ ...@@ -1708,10 +1787,17 @@
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.0">
<caret line="153" column="0" selection-start-line="153" selection-start-column="0" selection-end-line="153" selection-end-column="0" /> <caret line="153" column="0" selection-start-line="153" selection-start-column="0" selection-end-line="153" selection-end-column="0" />
<folding> <folding>
<element signature="e#4141#4142#0" expanded="true" /> <element signature="imports" expanded="true" />
<element signature="e#4171#4172#0" expanded="true" /> <element signature="e#4736#4737#0" expanded="true" />
<element signature="e#5111#5112#0" expanded="true" /> <element signature="e#4785#4786#0" expanded="true" />
<element signature="e#5157#5158#0" expanded="true" /> <element signature="e#4880#4881#0" expanded="true" />
<element signature="e#4939#4940#0" expanded="true" />
<element signature="e#5339#5340#0" expanded="true" />
<element signature="e#5380#5381#0" expanded="true" />
<element signature="e#5453#5454#0" expanded="true" />
<element signature="e#5502#5503#0" expanded="true" />
<element signature="e#5591#5592#0" expanded="true" />
<element signature="e#5645#5646#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
...@@ -1753,10 +1839,17 @@ ...@@ -1753,10 +1839,17 @@
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.0">
<caret line="282" column="0" selection-start-line="282" selection-start-column="0" selection-end-line="282" selection-end-column="0" /> <caret line="282" column="0" selection-start-line="282" selection-start-column="0" selection-end-line="282" selection-end-column="0" />
<folding> <folding>
<element signature="e#4141#4142#0" expanded="true" /> <element signature="imports" expanded="true" />
<element signature="e#4171#4172#0" expanded="true" /> <element signature="e#4736#4737#0" expanded="true" />
<element signature="e#5111#5112#0" expanded="true" /> <element signature="e#4785#4786#0" expanded="true" />
<element signature="e#5157#5158#0" expanded="true" /> <element signature="e#4880#4881#0" expanded="true" />
<element signature="e#4939#4940#0" expanded="true" />
<element signature="e#5339#5340#0" expanded="true" />
<element signature="e#5380#5381#0" expanded="true" />
<element signature="e#5453#5454#0" expanded="true" />
<element signature="e#5502#5503#0" expanded="true" />
<element signature="e#5591#5592#0" expanded="true" />
<element signature="e#5645#5646#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
...@@ -1916,60 +2009,75 @@ ...@@ -1916,60 +2009,75 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Manager.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Notification.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.23195876"> <state vertical-scroll-proportion="0.4804217">
<caret line="96" column="25" selection-start-line="96" selection-start-column="21" selection-end-line="96" selection-end-column="29" /> <caret line="163" column="7" selection-start-line="163" selection-start-column="7" selection-end-line="163" selection-end-column="7" />
<folding>
<element signature="imports" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/localnotification/TriggerReceiver.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="-0.06849315"> <state vertical-scroll-proportion="-0.62371135">
<caret line="138" column="0" selection-start-line="138" selection-start-column="0" selection-end-line="138" selection-end-column="0" /> <caret line="34" column="13" selection-start-line="34" selection-start-column="13" selection-end-line="34" selection-end-column="13" />
<folding> <folding />
<element signature="e#2351#2359#0" expanded="false" />
<element signature="e#4550#7103#0" expanded="false" />
<element signature="e#7102#7103#0" expanded="false" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Notification.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.4804217"> <state vertical-scroll-proportion="-1.6849315">
<caret line="163" column="7" selection-start-line="163" selection-start-column="7" selection-end-line="163" selection-end-column="7" /> <caret line="139" column="29" selection-start-line="139" selection-start-column="29" selection-end-line="139" selection-end-column="29" />
<folding> <folding>
<element signature="imports" expanded="true" /> <element signature="e#11766#11767#0" expanded="true" />
<element signature="e#11813#11814#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/localnotification/LocalNotification.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.0">
<caret line="48" column="19" selection-start-line="48" selection-start-column="19" selection-end-line="48" selection-end-column="19" /> <caret line="231" column="15" selection-start-line="231" selection-start-column="15" selection-end-line="231" selection-end-column="15" />
<folding> <folding />
<element signature="e#4141#4142#0" expanded="true" />
<element signature="e#4171#4172#0" expanded="true" />
<element signature="e#5111#5112#0" expanded="true" />
<element signature="e#5157#5158#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Manager.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0"> <state vertical-scroll-proportion="0.0">
<caret line="25" column="7" selection-start-line="25" selection-start-column="7" selection-end-line="25" selection-end-column="7" /> <caret line="120" column="0" selection-start-line="120" selection-start-column="0" selection-end-line="120" selection-end-column="0" />
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/AssetUtil.java"> <entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Options.java">
<provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.0">
<caret line="126" column="7" selection-start-line="126" selection-start-column="7" selection-end-line="126" selection-end-column="7" />
<folding>
<element signature="imports" expanded="true" />
<element signature="e#4736#4737#0" expanded="true" />
<element signature="e#4785#4786#0" expanded="true" />
<element signature="e#4880#4881#0" expanded="true" />
<element signature="e#4939#4940#0" expanded="true" />
<element signature="e#5339#5340#0" expanded="true" />
<element signature="e#5380#5381#0" expanded="true" />
<element signature="e#5453#5454#0" expanded="true" />
<element signature="e#5502#5503#0" expanded="true" />
<element signature="e#5591#5592#0" expanded="true" />
<element signature="e#5645#5646#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/de/appplant/cordova/plugin/notification/Builder.java">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state vertical-scroll-proportion="0.55479455"> <state vertical-scroll-proportion="0.36746988">
<caret line="347" column="43" selection-start-line="347" selection-start-column="43" selection-end-line="347" selection-end-column="43" /> <caret line="126" column="45" selection-start-line="126" selection-start-column="45" selection-end-line="126" selection-end-column="45" />
<folding /> <folding />
</state> </state>
</provider> </provider>
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
<!-- update --> <!-- update -->
<h2 class="section">Update</h2> <h2 class="section">Update</h2>
<div class="container"> <div class="container">
<div onclick="update()">Title<br /><span>update(1)</span></div> <div onclick="update()">Text<br /><span>update(1)</span></div>
<div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div> <div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div>
</div> </div>
...@@ -249,6 +249,8 @@ ...@@ -249,6 +249,8 @@
cordova.plugins.notification.local.update({ cordova.plugins.notification.local.update({
id: 1, id: 1,
text: 'Updated Message 1', text: 'Updated Message 1',
icon: 'res://icon',
color: 'FF0000',
json: { updated: true } json: { updated: true }
}); });
}; };
......
...@@ -442,6 +442,9 @@ exports.registerPermission = function (callback, scope) { ...@@ -442,6 +442,9 @@ exports.registerPermission = function (callback, scope) {
*/ */
exports.on = function (event, callback, scope) { exports.on = function (event, callback, scope) {
if (typeof callback !== "function")
return;
if (!this._listener[event]) { if (!this._listener[event]) {
this._listener[event] = []; this._listener[event] = [];
} }
......
...@@ -65,7 +65,8 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -65,7 +65,8 @@ exports.applyPlatformSpecificOptions = function () {
defaults.smallIcon = undefined; defaults.smallIcon = undefined;
defaults.ongoing = false; defaults.ongoing = false;
defaults.autoClear = true; defaults.autoClear = true;
defaults.led = 'FFFFFF'; defaults.led = 'FF0000';
defaults.color = undefined;
break; break;
} }
......
...@@ -442,6 +442,9 @@ exports.registerPermission = function (callback, scope) { ...@@ -442,6 +442,9 @@ exports.registerPermission = function (callback, scope) {
*/ */
exports.on = function (event, callback, scope) { exports.on = function (event, callback, scope) {
if (typeof callback !== "function")
return;
if (!this._listener[event]) { if (!this._listener[event]) {
this._listener[event] = []; this._listener[event] = [];
} }
......
...@@ -61,11 +61,12 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -61,11 +61,12 @@ exports.applyPlatformSpecificOptions = function () {
switch (device.platform) { switch (device.platform) {
case 'Android': case 'Android':
defaults.icon = 'res://icon'; defaults.icon = 'res://ic_popup_reminder';
defaults.smallIcon = 'res://ic_popup_reminder'; defaults.smallIcon = undefined;
defaults.ongoing = false; defaults.ongoing = false;
defaults.autoClear = true; defaults.autoClear = true;
defaults.led = 'FFFFFF'; defaults.led = 'FF0000';
defaults.color = undefined;
break; break;
} }
......
...@@ -19,4 +19,5 @@ ...@@ -19,4 +19,5 @@
</author> </author>
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<preference name="windows-target-version" value="10.0" />
</widget> </widget>
...@@ -325,7 +325,7 @@ ...@@ -325,7 +325,7 @@
0867D690FE84028FC02AAC07 /* Project object */ = { 0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 0510; LastUpgradeCheck = 0720;
}; };
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "CordovaLib" */; buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "CordovaLib" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
...@@ -432,6 +432,7 @@ ...@@ -432,6 +432,7 @@
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = c99; GCC_C_LANGUAGE_STANDARD = c99;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = ""; GCC_PREPROCESSOR_DEFINITIONS = "";
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
objectVersion = 46; objectVersion = 46;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
0D62F8E153E44EF28A7721FA /* Toast+UIView.m in Sources */ = {isa = PBXBuildFile; fileRef = C6AD7DC485A4443E929A7620 /* Toast+UIView.m */; };
197FB026841240789EACC5D0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF785F79A8B7472E92024450 /* QuartzCore.framework */; };
1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; };
1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; };
288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; };
...@@ -38,16 +40,14 @@ ...@@ -38,16 +40,14 @@
7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; }; 7E7966E51810823500FA85AD /* icon-76@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DB1810823500FA85AD /* icon-76@2x.png */; };
7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; }; 7E7966E61810823500FA85AD /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DC1810823500FA85AD /* icon-small.png */; };
7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; }; 7E7966E71810823500FA85AD /* icon-small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7E7966DD1810823500FA85AD /* icon-small@2x.png */; };
D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; };
CC42D1F09F714070882869AF /* CDVDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CE7DBE8F25C94EE78486BF2D /* CDVDevice.m */; };
0D62F8E153E44EF28A7721FA /* Toast+UIView.m in Sources */ = {isa = PBXBuildFile; fileRef = C6AD7DC485A4443E929A7620 /* Toast+UIView.m */; };
C0912AD10EF243F1953F9047 /* Toast.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C291FF26573452996FB3E0E /* Toast.m */; }; C0912AD10EF243F1953F9047 /* Toast.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C291FF26573452996FB3E0E /* Toast.m */; };
197FB026841240789EACC5D0 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF785F79A8B7472E92024450 /* QuartzCore.framework */; }; CC42D1F09F714070882869AF /* CDVDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CE7DBE8F25C94EE78486BF2D /* CDVDevice.m */; };
50697973345046E7B998064B /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 065D89C4F7314325A06E2AAC /* AppDelegate+APPRegisterUserNotificationSettings.m */; }; D4A0D8761607E02300AEF8BB /* Default-568h@2x~iphone.png in Resources */ = {isa = PBXBuildFile; fileRef = D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */; };
C88A28C5C7E7446D87A4CBED /* APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D7E8D71BF1D4B9987CA02BA /* APPLocalNotification.m */; }; BCDF7572D156489CA23538B0 /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 83BEC131F711411088C92EDA /* AppDelegate+APPRegisterUserNotificationSettings.m */; };
20521DA5E2574D0B8FD0A38B /* APPLocalNotificationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = AD28D9A6884A43538F937328 /* APPLocalNotificationOptions.m */; }; 9E367FA486424D39BA150ECD /* APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E97D790684542B885DA3CF7 /* APPLocalNotification.m */; };
035BE69C08814B2FB4BE26EF /* UIApplication+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 709EAD43C5B44F83A8C8B8B7 /* UIApplication+APPLocalNotification.m */; }; AFC7D470F50A47519DF04184 /* APPLocalNotificationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CC79B3EDF31424E97DD9C43 /* APPLocalNotificationOptions.m */; };
DA9ACED970BF4ED59B28C696 /* UILocalNotification+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 97014C1256FB4CCDBCE4B0A9 /* UILocalNotification+APPLocalNotification.m */; }; 704F898AC24049919D2CFDFF /* UIApplication+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA61515A5B64BA686E32943 /* UIApplication+APPLocalNotification.m */; };
C87EB797F6994CD084F57E41 /* UILocalNotification+APPLocalNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 31E97140586C4586969A25F4 /* UILocalNotification+APPLocalNotification.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
...@@ -68,11 +68,11 @@ ...@@ -68,11 +68,11 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
038EB824BC264EB38A1CC2B4 /* Toast+UIView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Toast+UIView.h"; path = "cordova-plugin-x-toast/Toast+UIView.h"; sourceTree = "<group>"; };
0C291FF26573452996FB3E0E /* Toast.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Toast.m; path = "cordova-plugin-x-toast/Toast.m"; sourceTree = "<group>"; };
1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
1D6058910D05DD3D006BFB54 /* NotificationExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NotificationExample.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 1D6058910D05DD3D006BFB54 /* NotificationExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NotificationExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
1F766FDD13BBADB100FB74C0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = Localizable.strings; sourceTree = "<group>"; };
1F766FE013BBADB100FB74C0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Localizable.strings; sourceTree = "<group>"; };
288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; }; 301BF52D109A57CC0062928A /* CordovaLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = CordovaLib.xcodeproj; path = CordovaLib/CordovaLib.xcodeproj; sourceTree = "<group>"; };
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = "<group>"; }; 30C1856519D5FC0A00212699 /* icon-60@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-60@3x.png"; sourceTree = "<group>"; };
30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = "<group>"; }; 30FC414816E50CA1004E6F35 /* icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72@2x.png"; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* NotificationExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NotificationExample-Prefix.pch"; sourceTree = "<group>"; }; 32CA4F630368D1EE00C91783 /* NotificationExample-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NotificationExample-Prefix.pch"; sourceTree = "<group>"; };
528A07C507BD4FE3AD9EA09F /* CDVDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVDevice.h; path = "cordova-plugin-device/CDVDevice.h"; sourceTree = "<group>"; };
5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; 5B1594DC16A7569C00FEF299 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = "<group>"; }; 7E7966D41810823500FA85AD /* icon-40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40.png"; sourceTree = "<group>"; };
7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = "<group>"; }; 7E7966D51810823500FA85AD /* icon-40@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-40@2x.png"; sourceTree = "<group>"; };
...@@ -108,28 +109,25 @@ ...@@ -108,28 +109,25 @@
7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; }; 7E7966DC1810823500FA85AD /* icon-small.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small.png"; sourceTree = "<group>"; };
7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = "<group>"; }; 7E7966DD1810823500FA85AD /* icon-small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-small@2x.png"; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* NotificationExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NotificationExample-Info.plist"; path = "../NotificationExample-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; }; 8D1107310486CEB800E47090 /* NotificationExample-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "NotificationExample-Info.plist"; path = "../NotificationExample-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
C6AD7DC485A4443E929A7620 /* Toast+UIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "Toast+UIView.m"; path = "cordova-plugin-x-toast/Toast+UIView.m"; sourceTree = "<group>"; };
CE7DBE8F25C94EE78486BF2D /* CDVDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVDevice.m; path = "cordova-plugin-device/CDVDevice.m"; sourceTree = "<group>"; };
D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; }; D4A0D8751607E02300AEF8BB /* Default-568h@2x~iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x~iphone.png"; sourceTree = "<group>"; };
E754277EEB384C66B1431A9F /* Toast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Toast.h; path = "cordova-plugin-x-toast/Toast.h"; sourceTree = "<group>"; };
EB87FDF21871DA7A0020F90C /* merges */ = {isa = PBXFileReference; lastKnownFileType = folder; name = merges; path = ../../merges; sourceTree = "<group>"; }; EB87FDF21871DA7A0020F90C /* merges */ = {isa = PBXFileReference; lastKnownFileType = folder; name = merges; path = ../../merges; sourceTree = "<group>"; };
EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = "<group>"; }; EB87FDF31871DA8E0020F90C /* www */ = {isa = PBXFileReference; lastKnownFileType = folder; name = www; path = ../../www; sourceTree = "<group>"; };
EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = "<group>"; }; EB87FDF41871DAF40020F90C /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = ../../config.xml; sourceTree = "<group>"; };
F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = "NotificationExample/config.xml"; sourceTree = "<group>"; }; EF785F79A8B7472E92024450 /* QuartzCore.framework */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
CE7DBE8F25C94EE78486BF2D /* CDVDevice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "CDVDevice.m"; path = "cordova-plugin-device/CDVDevice.m"; sourceTree = "<group>"; fileEncoding = 4; }; F840E1F0165FE0F500CFE078 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = config.xml; path = NotificationExample/config.xml; sourceTree = "<group>"; };
528A07C507BD4FE3AD9EA09F /* CDVDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "CDVDevice.h"; path = "cordova-plugin-device/CDVDevice.h"; sourceTree = "<group>"; fileEncoding = 4; }; 83BEC131F711411088C92EDA /* AppDelegate+APPRegisterUserNotificationSettings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "AppDelegate+APPRegisterUserNotificationSettings.m"; path = "../../../../plugins/cordova-plugin-registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.m"; sourceTree = "<group>"; fileEncoding = 4; };
C6AD7DC485A4443E929A7620 /* Toast+UIView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "Toast+UIView.m"; path = "cordova-plugin-x-toast/Toast+UIView.m"; sourceTree = "<group>"; fileEncoding = 4; }; A5FA75D5042F413EA3791296 /* AppDelegate+APPRegisterUserNotificationSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "AppDelegate+APPRegisterUserNotificationSettings.h"; path = "../../../../plugins/cordova-plugin-registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.h"; sourceTree = "<group>"; fileEncoding = 4; };
0C291FF26573452996FB3E0E /* Toast.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "Toast.m"; path = "cordova-plugin-x-toast/Toast.m"; sourceTree = "<group>"; fileEncoding = 4; }; 1E97D790684542B885DA3CF7 /* APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "APPLocalNotification.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
038EB824BC264EB38A1CC2B4 /* Toast+UIView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Toast+UIView.h"; path = "cordova-plugin-x-toast/Toast+UIView.h"; sourceTree = "<group>"; fileEncoding = 4; }; 7CC79B3EDF31424E97DD9C43 /* APPLocalNotificationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "APPLocalNotificationOptions.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotificationOptions.m"; sourceTree = "<group>"; fileEncoding = 4; };
E754277EEB384C66B1431A9F /* Toast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Toast.h"; path = "cordova-plugin-x-toast/Toast.h"; sourceTree = "<group>"; fileEncoding = 4; }; DCA61515A5B64BA686E32943 /* UIApplication+APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UIApplication+APPLocalNotification.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UIApplication+APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
EF785F79A8B7472E92024450 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "QuartzCore.framework"; path = "System/Library/Frameworks/QuartzCore.framework"; sourceTree = SDKROOT; fileEncoding = 4; }; 31E97140586C4586969A25F4 /* UILocalNotification+APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UILocalNotification+APPLocalNotification.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UILocalNotification+APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
065D89C4F7314325A06E2AAC /* AppDelegate+APPRegisterUserNotificationSettings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "AppDelegate+APPRegisterUserNotificationSettings.m"; path = "../../../../plugins/cordova-plugin-registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.m"; sourceTree = "<group>"; fileEncoding = 4; }; A36117D2BDF54F4FB9655726 /* APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "APPLocalNotification.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
D71248FC8BE4448BAD70BE9B /* AppDelegate+APPRegisterUserNotificationSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "AppDelegate+APPRegisterUserNotificationSettings.h"; path = "../../../../plugins/cordova-plugin-registerusernotificationsettings/src/ios/AppDelegate+APPRegisterUserNotificationSettings.h"; sourceTree = "<group>"; fileEncoding = 4; }; A1794ABC64CB4F149CE892B8 /* APPLocalNotificationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "APPLocalNotificationOptions.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotificationOptions.h"; sourceTree = "<group>"; fileEncoding = 4; };
1D7E8D71BF1D4B9987CA02BA /* APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "APPLocalNotification.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; }; 7EA4BEA5695D48A19AEC8E54 /* UIApplication+APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UIApplication+APPLocalNotification.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UIApplication+APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
AD28D9A6884A43538F937328 /* APPLocalNotificationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "APPLocalNotificationOptions.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotificationOptions.m"; sourceTree = "<group>"; fileEncoding = 4; }; 3ECEAA4923104469833E2888 /* UILocalNotification+APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UILocalNotification+APPLocalNotification.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UILocalNotification+APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
709EAD43C5B44F83A8C8B8B7 /* UIApplication+APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UIApplication+APPLocalNotification.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UIApplication+APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
97014C1256FB4CCDBCE4B0A9 /* UILocalNotification+APPLocalNotification.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UILocalNotification+APPLocalNotification.m"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UILocalNotification+APPLocalNotification.m"; sourceTree = "<group>"; fileEncoding = 4; };
DCE39BDF75A34F38B69075FA /* APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "APPLocalNotification.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
C9A607D964B84F5B8BBC9949 /* APPLocalNotificationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "APPLocalNotificationOptions.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/APPLocalNotificationOptions.h"; sourceTree = "<group>"; fileEncoding = 4; };
C37E099FE5C54C959123995C /* UIApplication+APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UIApplication+APPLocalNotification.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UIApplication+APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
0D47D14375804D0187F4E4DB /* UILocalNotification+APPLocalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "UILocalNotification+APPLocalNotification.h"; path = "../../../../../cordova-plugin-local-notifications/src/ios/UILocalNotification+APPLocalNotification.h"; sourceTree = "<group>"; fileEncoding = 4; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -158,7 +156,7 @@ ...@@ -158,7 +156,7 @@
1D3623250D0F684500981E51 /* AppDelegate.m */, 1D3623250D0F684500981E51 /* AppDelegate.m */,
); );
name = Classes; name = Classes;
path = "NotificationExample/Classes"; path = NotificationExample/Classes;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
19C28FACFE9D520D11CA2CBB /* Products */ = { 19C28FACFE9D520D11CA2CBB /* Products */ = {
...@@ -194,7 +192,7 @@ ...@@ -194,7 +192,7 @@
29B97316FDCFA39411CA2CEA /* main.m */, 29B97316FDCFA39411CA2CEA /* main.m */,
); );
name = "Other Sources"; name = "Other Sources";
path = "NotificationExample"; path = NotificationExample;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
29B97317FDCFA39411CA2CEA /* Resources */ = { 29B97317FDCFA39411CA2CEA /* Resources */ = {
...@@ -205,7 +203,7 @@ ...@@ -205,7 +203,7 @@
8D1107310486CEB800E47090 /* NotificationExample-Info.plist */, 8D1107310486CEB800E47090 /* NotificationExample-Info.plist */,
); );
name = Resources; name = Resources;
path = "NotificationExample/Resources"; path = NotificationExample/Resources;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
29B97323FDCFA39411CA2CEA /* Frameworks */ = { 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
...@@ -236,19 +234,19 @@ ...@@ -236,19 +234,19 @@
0C291FF26573452996FB3E0E /* Toast.m */, 0C291FF26573452996FB3E0E /* Toast.m */,
038EB824BC264EB38A1CC2B4 /* Toast+UIView.h */, 038EB824BC264EB38A1CC2B4 /* Toast+UIView.h */,
E754277EEB384C66B1431A9F /* Toast.h */, E754277EEB384C66B1431A9F /* Toast.h */,
065D89C4F7314325A06E2AAC /* AppDelegate+APPRegisterUserNotificationSettings.m */, 83BEC131F711411088C92EDA /* AppDelegate+APPRegisterUserNotificationSettings.m */,
D71248FC8BE4448BAD70BE9B /* AppDelegate+APPRegisterUserNotificationSettings.h */, A5FA75D5042F413EA3791296 /* AppDelegate+APPRegisterUserNotificationSettings.h */,
1D7E8D71BF1D4B9987CA02BA /* APPLocalNotification.m */, 1E97D790684542B885DA3CF7 /* APPLocalNotification.m */,
AD28D9A6884A43538F937328 /* APPLocalNotificationOptions.m */, 7CC79B3EDF31424E97DD9C43 /* APPLocalNotificationOptions.m */,
709EAD43C5B44F83A8C8B8B7 /* UIApplication+APPLocalNotification.m */, DCA61515A5B64BA686E32943 /* UIApplication+APPLocalNotification.m */,
97014C1256FB4CCDBCE4B0A9 /* UILocalNotification+APPLocalNotification.m */, 31E97140586C4586969A25F4 /* UILocalNotification+APPLocalNotification.m */,
DCE39BDF75A34F38B69075FA /* APPLocalNotification.h */, A36117D2BDF54F4FB9655726 /* APPLocalNotification.h */,
C9A607D964B84F5B8BBC9949 /* APPLocalNotificationOptions.h */, A1794ABC64CB4F149CE892B8 /* APPLocalNotificationOptions.h */,
C37E099FE5C54C959123995C /* UIApplication+APPLocalNotification.h */, 7EA4BEA5695D48A19AEC8E54 /* UIApplication+APPLocalNotification.h */,
0D47D14375804D0187F4E4DB /* UILocalNotification+APPLocalNotification.h */, 3ECEAA4923104469833E2888 /* UILocalNotification+APPLocalNotification.h */,
); );
name = Plugins; name = Plugins;
path = "NotificationExample/Plugins"; path = NotificationExample/Plugins;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
308D052D1370CCF300D202BF /* icons */ = { 308D052D1370CCF300D202BF /* icons */ = {
...@@ -316,8 +314,8 @@ ...@@ -316,8 +314,8 @@
dependencies = ( dependencies = (
301BF551109A68C00062928A /* PBXTargetDependency */, 301BF551109A68C00062928A /* PBXTargetDependency */,
); );
name = "NotificationExample"; name = NotificationExample;
productName = "NotificationExample"; productName = NotificationExample;
productReference = 1D6058910D05DD3D006BFB54 /* NotificationExample.app */; productReference = 1D6058910D05DD3D006BFB54 /* NotificationExample.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
...@@ -327,9 +325,9 @@ ...@@ -327,9 +325,9 @@
29B97313FDCFA39411CA2CEA /* Project object */ = { 29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 510; LastUpgradeCheck = 720;
}; };
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "NotificationExample" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
developmentRegion = English; developmentRegion = English;
hasScannedForEncodings = 1; hasScannedForEncodings = 1;
...@@ -433,11 +431,11 @@ ...@@ -433,11 +431,11 @@
CC42D1F09F714070882869AF /* CDVDevice.m in Sources */, CC42D1F09F714070882869AF /* CDVDevice.m in Sources */,
0D62F8E153E44EF28A7721FA /* Toast+UIView.m in Sources */, 0D62F8E153E44EF28A7721FA /* Toast+UIView.m in Sources */,
C0912AD10EF243F1953F9047 /* Toast.m in Sources */, C0912AD10EF243F1953F9047 /* Toast.m in Sources */,
50697973345046E7B998064B /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */, BCDF7572D156489CA23538B0 /* AppDelegate+APPRegisterUserNotificationSettings.m in Sources */,
C88A28C5C7E7446D87A4CBED /* APPLocalNotification.m in Sources */, 9E367FA486424D39BA150ECD /* APPLocalNotification.m in Sources */,
20521DA5E2574D0B8FD0A38B /* APPLocalNotificationOptions.m in Sources */, AFC7D470F50A47519DF04184 /* APPLocalNotificationOptions.m in Sources */,
035BE69C08814B2FB4BE26EF /* UIApplication+APPLocalNotification.m in Sources */, 704F898AC24049919D2CFDFF /* UIApplication+APPLocalNotification.m in Sources */,
DA9ACED970BF4ED59B28C696 /* UILocalNotification+APPLocalNotification.m in Sources */, C87EB797F6994CD084F57E41 /* UILocalNotification+APPLocalNotification.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
...@@ -478,7 +476,8 @@ ...@@ -478,7 +476,8 @@
"-weak-lSystem", "-weak-lSystem",
"-ObjC", "-ObjC",
); );
PRODUCT_NAME = "NotificationExample"; PRODUCT_BUNDLE_IDENTIFIER = de.appplant.localnotification.example;
PRODUCT_NAME = NotificationExample;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
...@@ -507,7 +506,8 @@ ...@@ -507,7 +506,8 @@
"-weak-lSystem", "-weak-lSystem",
"-ObjC", "-ObjC",
); );
PRODUCT_NAME = "NotificationExample"; PRODUCT_BUNDLE_IDENTIFIER = de.appplant.localnotification.example;
PRODUCT_NAME = NotificationExample;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;
...@@ -523,6 +523,7 @@ ...@@ -523,6 +523,7 @@
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = c99; GCC_C_LANGUAGE_STANDARD = c99;
GCC_THUMB_SUPPORT = NO; GCC_THUMB_SUPPORT = NO;
GCC_VERSION = ""; GCC_VERSION = "";
...@@ -612,7 +613,7 @@ ...@@ -612,7 +613,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "__CLI__" */ = { C01FCF4E08A954540054247B /* Build configuration list for PBXProject "NotificationExample" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */, C01FCF4F08A954540054247B /* Debug */,
......
...@@ -2,11 +2,6 @@ ...@@ -2,11 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
...@@ -61,20 +56,23 @@ ...@@ -61,20 +56,23 @@
<string>${PRODUCT_NAME}</string> <string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.0.1</string> <string>0.0.1</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string/> <string/>
<key>NSMainNibFile~ipad</key> <key>NSMainNibFile~ipad</key>
<string/> <string/>
<key>UIRequiresFullScreen</key>
<true/>
<key>UILaunchImages</key> <key>UILaunchImages</key>
<array> <array>
<dict> <dict>
...@@ -178,5 +176,7 @@ ...@@ -178,5 +176,7 @@
<string>{768, 1024}</string> <string>{768, 1024}</string>
</dict> </dict>
</array> </array>
<key>UIRequiresFullScreen</key>
<true/>
</dict> </dict>
</plist> </plist>
\ No newline at end of file
...@@ -33,4 +33,5 @@ ...@@ -33,4 +33,5 @@
</author> </author>
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<preference name="windows-target-version" value="10.0" />
</widget> </widget>
...@@ -441,6 +441,9 @@ exports.registerPermission = function (callback, scope) { ...@@ -441,6 +441,9 @@ exports.registerPermission = function (callback, scope) {
*/ */
exports.on = function (event, callback, scope) { exports.on = function (event, callback, scope) {
if (typeof callback !== "function")
return;
if (!this._listener[event]) { if (!this._listener[event]) {
this._listener[event] = []; this._listener[event] = [];
} }
......
...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () {
switch (device.platform) { switch (device.platform) {
case 'Android': case 'Android':
defaults.icon = 'res://icon'; defaults.icon = 'res://ic_popup_reminder';
defaults.smallIcon = 'res://ic_popup_reminder'; defaults.smallIcon = undefined;
defaults.ongoing = false; defaults.ongoing = false;
defaults.autoClear = true; defaults.autoClear = true;
defaults.led = 'FFFFFF'; defaults.led = 'FF0000';
defaults.color = undefined;
break; break;
} }
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
<!-- update --> <!-- update -->
<h2 class="section">Update</h2> <h2 class="section">Update</h2>
<div class="container"> <div class="container">
<div onclick="update()">Title<br /><span>update(1)</span></div> <div onclick="update()">Text<br /><span>update(1)</span></div>
<div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div> <div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div>
</div> </div>
...@@ -188,7 +188,8 @@ ...@@ -188,7 +188,8 @@
cordova.plugins.notification.local.schedule({ cordova.plugins.notification.local.schedule({
id: 1, id: 1,
text: 'Test Message 1', text: 'Test Message 1',
icon: 'http://www.optimizeordie.de/wp-content/plugins/social-media-widget/images/default/64/googleplus.png', icon: 'http://3.bp.blogspot.com/-Qdsy-GpempY/UU_BN9LTqSI/AAAAAAAAAMA/LkwLW2yNBJ4/s1600/supersu.png',
smallIcon: 'res://cordova',
sound: null, sound: null,
data: { test: id } data: { test: id }
}); });
...@@ -197,13 +198,18 @@ ...@@ -197,13 +198,18 @@
scheduleMultiple = function () { scheduleMultiple = function () {
cordova.plugins.notification.local.schedule([{ cordova.plugins.notification.local.schedule([{
id: 1, id: 1,
text: 'Multi Message 1' text: 'Multi Message 1',
icon: 'res://cordova'
}, { }, {
id: 2, id: 2,
text: 'Multi Message 2' text: 'Multi Message 2',
icon: 'res://icon',
smallIcon: 'ic_media_play'
}, { }, {
id: 3, id: 3,
text: 'Multi Message 3' text: 'Multi Message 3',
icon: 'res://icon',
smallIcon: 'ic_media_pause'
}]); }]);
}; };
...@@ -230,7 +236,9 @@ ...@@ -230,7 +236,9 @@
id: 1, id: 1,
text: 'Scheduled every minute', text: 'Scheduled every minute',
every: 'minute', every: 'minute',
sound: sound sound: sound,
icon: 'res://icon',
smallIcon: 'res://ic_popup_sync'
}); });
}; };
</script> </script>
...@@ -241,6 +249,8 @@ ...@@ -241,6 +249,8 @@
cordova.plugins.notification.local.update({ cordova.plugins.notification.local.update({
id: 1, id: 1,
text: 'Updated Message 1', text: 'Updated Message 1',
icon: 'res://icon',
color: 'FF0000',
json: { updated: true } json: { updated: true }
}); });
}; };
......
...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () {
switch (device.platform) { switch (device.platform) {
case 'Android': case 'Android':
defaults.icon = 'res://icon'; defaults.icon = 'res://ic_popup_reminder';
defaults.smallIcon = 'res://ic_popup_reminder'; defaults.smallIcon = undefined;
defaults.ongoing = false; defaults.ongoing = false;
defaults.autoClear = true; defaults.autoClear = true;
defaults.led = 'FFFFFF'; defaults.led = 'FF0000';
defaults.color = undefined;
break; break;
} }
......
<?xml version='1.0' encoding='utf-8'?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<OutputPath>build\phone\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>build\phone\$(Configuration)\$(Platform)\</OutputPath>
<IntermediateOutputPath>build\phone\bld\</IntermediateOutputPath> <IntermediateOutputPath>build\phone\bld\</IntermediateOutputPath>
...@@ -41,7 +59,11 @@ ...@@ -41,7 +59,11 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>31b67a35-9503-4213-857e-f44eb42ae549</ProjectGuid> <ProjectGuid>31b67a35-9503-4213-857e-f44eb42ae549</ProjectGuid>
</PropertyGroup> </PropertyGroup>
<Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> <PropertyGroup Label="CordovaBuildParameters" Condition="'$(CordovaBundlePlatforms)' != ''">
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>$(CordovaBundlePlatforms)</AppxBundlePlatforms>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'"> <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'">
<VisualStudioVersion>12.0</VisualStudioVersion> <VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
...@@ -53,18 +75,26 @@ ...@@ -53,18 +75,26 @@
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<AppxManifest Include="package.phone.appxmanifest"> <AppxManifest Include="package.phone.appxmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AppxManifest> </AppxManifest>
<Content Exclude="images\*.scale-180.*" Include="images\*.png" /> <Content Include="images\*.png" Exclude="images\*.scale-180.*" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.Phone.WinJS.2.1, Version=1.0" /> <SDKReference Include="Microsoft.Phone.WinJS.2.1, Version=1.0" />
</ItemGroup> </ItemGroup>
<Import Label="Shared" Project="CordovaApp.projitems" /> <Import Project="CordovaApp.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project> </Project>
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<OutputPath>build\windows\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>build\windows\$(Configuration)\$(Platform)\win8.1\</OutputPath>
<IntermediateOutputPath>build\windows\bld\</IntermediateOutputPath> <IntermediateOutputPath>build\windows\bld\</IntermediateOutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
...@@ -41,7 +59,11 @@ ...@@ -41,7 +59,11 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>58950fb6-2f93-4963-b9cd-637f83f3efbf</ProjectGuid> <ProjectGuid>58950fb6-2f93-4963-b9cd-637f83f3efbf</ProjectGuid>
</PropertyGroup> </PropertyGroup>
<Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> <PropertyGroup Label="CordovaBuildParameters" Condition="'$(CordovaBundlePlatforms)' != ''">
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>$(CordovaBundlePlatforms)</AppxBundlePlatforms>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'"> <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0'">
<VisualStudioVersion>12.0</VisualStudioVersion> <VisualStudioVersion>12.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
...@@ -52,19 +74,27 @@ ...@@ -52,19 +74,27 @@
<TargetPlatformVersion>8.1</TargetPlatformVersion> <TargetPlatformVersion>8.1</TargetPlatformVersion>
<RequiredPlatformVersion>8.1</RequiredPlatformVersion> <RequiredPlatformVersion>8.1</RequiredPlatformVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<PackageCertificateKeyFile>CordovaApp_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<AppxManifest Include="package.windows.appxmanifest"> <AppxManifest Include="package.windows.appxmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AppxManifest> </AppxManifest>
<Content Exclude="images\*.scale-240.*" Include="images\*.png" /> <Content Include="images\*.png" Exclude="images\*.scale-240.*" />
<None Include="CordovaApp_TemporaryKey.pfx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.WinJS.2.0, Version=1.0" /> <SDKReference Include="Microsoft.WinJS.2.0, Version=1.0" />
</ItemGroup> </ItemGroup>
<Import Label="Shared" Project="CordovaApp.projitems" /> <Import Project="CordovaApp.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<!-- To modify your build process, add your task inside one of the targets below then uncomment
that target and the DisableFastUpToDateCheck PropertyGroup.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
<PropertyGroup>
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
</PropertyGroup>
-->
</Project> </Project>
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputPath>build\windows\$(Configuration)\$(Platform)\win10\</OutputPath>
<IntermediateOutputPath>build\windows\bld\</IntermediateOutputPath>
<AppxPackageSigningEnabled>true</AppxPackageSigningEnabled>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>f9b0ae20-c91c-42b9-9c6e-d3bc28b4509e</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(CordovaBundlePlatforms)' != ''" Label="CordovaBuildParameters">
<AppxBundle>Always</AppxBundle>
<AppxBundlePlatforms>$(CordovaBundlePlatforms)</AppxBundlePlatforms>
</PropertyGroup>
<Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0'">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<UapDefaultAssetScale>100</UapDefaultAssetScale>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' &lt; '14.0'">
<TargetPlatformVersion>10.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="package.windows10.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<Content Exclude="images\*.scale-240.*" Include="images\*.png" />
</ItemGroup>
<Import Label="Shared" Project="CordovaApp.projitems" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
</Project>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>WindowsPhoneEmulatorDebugger</DebuggerFlavor>
<WindowsPhoneEmulatorID>2DDADD82-5910-40E6-894F-17EB5CD463EF;Mobile Emulator 10.0.10240.0 720p 5 inch 1GB</WindowsPhoneEmulatorID>
</PropertyGroup>
<PropertyGroup>
<ReferenceCachePath>C:\Users\katze\AppData\Local\Temp\luyvizjb_CordovaApp.Windows10_refcache</ReferenceCachePath>
</PropertyGroup>
</Project>
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<OutputPath>build\windows80\$(Configuration)\$(Platform)\</OutputPath> <OutputPath>build\windows80\$(Configuration)\$(Platform)\</OutputPath>
<IntermediateOutputPath>build\windows80\bld\</IntermediateOutputPath> <IntermediateOutputPath>build\windows80\bld\</IntermediateOutputPath>
...@@ -44,32 +62,22 @@ ...@@ -44,32 +62,22 @@
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0'"> <PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0'">
<VisualStudioVersion>11.0</VisualStudioVersion> <VisualStudioVersion>11.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
<Import Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).props" />
<PropertyGroup> <PropertyGroup>
<TargetPlatformIdentifier>Windows</TargetPlatformIdentifier> <TargetPlatformIdentifier>Windows</TargetPlatformIdentifier>
<TargetPlatformVersion>8.0</TargetPlatformVersion> <TargetPlatformVersion>8.0</TargetPlatformVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<PackageCertificateKeyFile>CordovaApp_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<AppxManifest Include="package.windows80.appxmanifest"> <AppxManifest Include="package.windows80.appxmanifest">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</AppxManifest> </AppxManifest>
<Content Exclude="images\*.scale-240.*" Include="images\*.png" /> <Content Include="images\*.png" Exclude="images\*.scale-240.*" />
<None Include="CordovaApp_TemporaryKey.pfx" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<SDKReference Include="Microsoft.WinJS.1.0, Version=1.0" /> <SDKReference Include="Microsoft.WinJS.1.0, Version=1.0" />
</ItemGroup> </ItemGroup>
<Import Label="Shared" Project="CordovaApp.projitems" /> <Import Project="CordovaApp.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\$(WMSJSProjectDirectory)\Microsoft.VisualStudio.$(WMSJSProject).targets" />
<PropertyGroup>
<BuildFromCordovaTooling>false</BuildFromCordovaTooling>
<PreBuildEvent Condition="$(BuildFromCordovaTooling) != true">
cd /d $(MSBuildThisFileDirectory)
node -e "require('./cordova/lib/prepare.js').applyPlatformConfig()"
</PreBuildEvent>
</PropertyGroup>
</Project> </Project>
...@@ -11,4 +11,6 @@ ...@@ -11,4 +11,6 @@
<ItemGroup> <ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)config.xml" /> <Content Include="$(MSBuildThisFileDirectory)config.xml" />
</ItemGroup> </ItemGroup>
<Import Condition="Exists('$(MSBuildThisFileDirectory)CordovaAppDebug.projitems') And '$(Configuration)'=='Debug'" Project="CordovaAppDebug.projitems" />
<Import Condition="Exists('$(MSBuildThisFileDirectory)CordovaAppRelease.projitems') And '$(Configuration)'!='Debug'" Project="CordovaAppRelease.projitems" />
</Project> </Project>
...@@ -21,6 +21,40 @@ ...@@ -21,6 +21,40 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{9ebdb27f-d75b-4d8c-b53f-7be4a1fe89f9}</ProjectGuid> <ProjectGuid>{9ebdb27f-d75b-4d8c-b53f-7be4a1fe89f9}</ProjectGuid>
</PropertyGroup> </PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
......
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
# #
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
...@@ -19,24 +21,22 @@ Microsoft Visual Studio Solution File, Format Version 12.00 ...@@ -19,24 +21,22 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
VisualStudioVersion = 12.0.30324.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CordovaApp", "CordovaApp", "{3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CordovaApp", "CordovaApp", "{3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}"
EndProject EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CordovaApp", "CordovaApp.shproj", "{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}" Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CordovaApp", "CordovaApp.shproj", "{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}"
EndProject EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Windows8.0", "CordovaApp.Windows80.jsproj", "{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}"
EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Windows", "CordovaApp.Windows.jsproj", "{58950FB6-2F93-4963-B9CD-637F83F3EFBF}" Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Windows", "CordovaApp.Windows.jsproj", "{58950FB6-2F93-4963-B9CD-637F83F3EFBF}"
EndProject EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Phone", "CordovaApp.Phone.jsproj", "{31B67A35-9503-4213-857E-F44EB42AE549}" Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Phone", "CordovaApp.Phone.jsproj", "{31B67A35-9503-4213-857E-F44EB42AE549}"
EndProject EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Windows10", "CordovaApp.Windows10.jsproj", "{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}"
EndProject
Global Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution GlobalSection(SharedMSBuildProjectFiles) = preSolution
CordovaApp.projitems*{58950fb6-2f93-4963-b9cd-637f83f3efbf}*SharedItemsImports = 5 CordovaApp.projitems*{58950fb6-2f93-4963-b9cd-637f83f3efbf}*SharedItemsImports = 5
CordovaApp.projitems*{efffab2f-bfc5-4eda-b545-45ef4995f55a}*SharedItemsImports = 5 CordovaApp.projitems*{9ebdb27f-d75b-4d8c-b53f-7be4a1fe89f9}*SharedItemsImports = 14
CordovaApp.projitems*{9ebdb27f-d75b-4d8c-b53f-7be4a1fe89f9}*SharedItemsImports = 13
CordovaApp.projitems*{31b67a35-9503-4213-857e-f44eb42ae549}*SharedItemsImports = 5 CordovaApp.projitems*{31b67a35-9503-4213-857e-f44eb42ae549}*SharedItemsImports = 5
CordovaApp.projitems*{f9B0ae20-c91c-42b9-9c6e-d3bc28b4509e}*SharedItemsImports = 5
EndGlobalSection EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
...@@ -97,30 +97,30 @@ Global ...@@ -97,30 +97,30 @@ Global
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.ActiveCfg = Release|x86 {31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.ActiveCfg = Release|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.Build.0 = Release|x86 {31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.Build.0 = Release|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.Deploy.0 = Release|x86 {31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.Deploy.0 = Release|x86
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|Any CPU.Build.0 = Debug|Any CPU {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|ARM.ActiveCfg = Debug|ARM {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|ARM.ActiveCfg = Debug|ARM
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|ARM.Build.0 = Debug|ARM {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|ARM.Build.0 = Debug|ARM
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|ARM.Deploy.0 = Debug|ARM {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|ARM.Deploy.0 = Debug|ARM
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|x64.ActiveCfg = Debug|x64 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x64.ActiveCfg = Debug|x64
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|x64.Build.0 = Debug|x64 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x64.Build.0 = Debug|x64
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|x64.Deploy.0 = Debug|x64 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x64.Deploy.0 = Debug|x64
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|x86.ActiveCfg = Debug|x86 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x86.ActiveCfg = Debug|x86
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|x86.Build.0 = Debug|x86 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x86.Build.0 = Debug|x86
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Debug|x86.Deploy.0 = Debug|x86 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x86.Deploy.0 = Debug|x86
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|Any CPU.ActiveCfg = Release|Any CPU {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|Any CPU.Build.0 = Release|Any CPU {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|Any CPU.Build.0 = Release|Any CPU
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|Any CPU.Deploy.0 = Release|Any CPU {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|Any CPU.Deploy.0 = Release|Any CPU
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|ARM.ActiveCfg = Release|ARM {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|ARM.ActiveCfg = Release|ARM
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|ARM.Build.0 = Release|ARM {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|ARM.Build.0 = Release|ARM
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|ARM.Deploy.0 = Release|ARM {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|ARM.Deploy.0 = Release|ARM
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|x64.ActiveCfg = Release|x64 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x64.ActiveCfg = Release|x64
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|x64.Build.0 = Release|x64 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x64.Build.0 = Release|x64
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|x64.Deploy.0 = Release|x64 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x64.Deploy.0 = Release|x64
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|x86.ActiveCfg = Release|x86 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x86.ActiveCfg = Release|x86
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|x86.Build.0 = Release|x86 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x86.Build.0 = Release|x86
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A}.Release|x86.Deploy.0 = Release|x86 {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
...@@ -129,6 +129,6 @@ Global ...@@ -129,6 +129,6 @@ Global
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944} {9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
{58950FB6-2F93-4963-B9CD-637F83F3EFBF} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944} {58950FB6-2F93-4963-B9CD-637F83F3EFBF} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
{31B67A35-9503-4213-857E-F44EB42AE549} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944} {31B67A35-9503-4213-857E-F44EB42AE549} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
{EFFFAB2F-BFC5-4EDA-B545-45EF4995F55A} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944} {F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 14 for Windows
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CordovaApp", "CordovaApp", "{3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CordovaApp", "CordovaApp.shproj", "{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}"
EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Windows", "CordovaApp.Windows.jsproj", "{58950FB6-2F93-4963-B9CD-637F83F3EFBF}"
EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Phone", "CordovaApp.Phone.jsproj", "{31B67A35-9503-4213-857E-F44EB42AE549}"
EndProject
Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "CordovaApp.Windows10", "CordovaApp.Windows10.jsproj", "{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
CordovaApp.projitems*{f9b0ae20-c91c-42b9-9c6e-d3bc28b4509e}*SharedItemsImports = 5
CordovaApp.projitems*{58950fb6-2f93-4963-b9cd-637f83f3efbf}*SharedItemsImports = 5
CordovaApp.projitems*{9ebdb27f-d75b-4d8c-b53f-7be4a1fe89f9}*SharedItemsImports = 13
CordovaApp.projitems*{31b67a35-9503-4213-857e-f44eb42ae549}*SharedItemsImports = 5
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Debug|ARM.ActiveCfg = Debug|ARM
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Debug|x64.ActiveCfg = Debug|x64
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Debug|x86.ActiveCfg = Debug|x86
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Release|ARM.ActiveCfg = Release|ARM
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Release|x64.ActiveCfg = Release|x64
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9}.Release|x86.ActiveCfg = Release|x86
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|ARM.ActiveCfg = Debug|ARM
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|ARM.Build.0 = Debug|ARM
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|ARM.Deploy.0 = Debug|ARM
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|x64.ActiveCfg = Debug|x64
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|x64.Build.0 = Debug|x64
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|x64.Deploy.0 = Debug|x64
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|x86.ActiveCfg = Debug|x86
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|x86.Build.0 = Debug|x86
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Debug|x86.Deploy.0 = Debug|x86
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|Any CPU.Build.0 = Release|Any CPU
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|Any CPU.Deploy.0 = Release|Any CPU
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|ARM.ActiveCfg = Release|ARM
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|ARM.Build.0 = Release|ARM
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|ARM.Deploy.0 = Release|ARM
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|x64.ActiveCfg = Release|x64
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|x64.Build.0 = Release|x64
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|x64.Deploy.0 = Release|x64
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|x86.ActiveCfg = Release|x86
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|x86.Build.0 = Release|x86
{58950FB6-2F93-4963-B9CD-637F83F3EFBF}.Release|x86.Deploy.0 = Release|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|ARM.ActiveCfg = Debug|ARM
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|ARM.Build.0 = Debug|ARM
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|ARM.Deploy.0 = Debug|ARM
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|x64.ActiveCfg = Debug|x64
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|x64.Build.0 = Debug|x64
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|x64.Deploy.0 = Debug|x64
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|x86.ActiveCfg = Debug|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|x86.Build.0 = Debug|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Debug|x86.Deploy.0 = Debug|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|Any CPU.Build.0 = Release|Any CPU
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|Any CPU.Deploy.0 = Release|Any CPU
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|ARM.ActiveCfg = Release|ARM
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|ARM.Build.0 = Release|ARM
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|ARM.Deploy.0 = Release|ARM
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x64.ActiveCfg = Release|x64
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x64.Build.0 = Release|x64
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x64.Deploy.0 = Release|x64
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.ActiveCfg = Release|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.Build.0 = Release|x86
{31B67A35-9503-4213-857E-F44EB42AE549}.Release|x86.Deploy.0 = Release|x86
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|ARM.ActiveCfg = Debug|ARM
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|ARM.Build.0 = Debug|ARM
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|ARM.Deploy.0 = Debug|ARM
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x64.ActiveCfg = Debug|x64
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x64.Build.0 = Debug|x64
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x64.Deploy.0 = Debug|x64
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x86.ActiveCfg = Debug|x86
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x86.Build.0 = Debug|x86
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Debug|x86.Deploy.0 = Debug|x86
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|Any CPU.Build.0 = Release|Any CPU
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|Any CPU.Deploy.0 = Release|Any CPU
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|ARM.ActiveCfg = Release|ARM
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|ARM.Build.0 = Release|ARM
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|ARM.Deploy.0 = Release|ARM
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x64.ActiveCfg = Release|x64
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x64.Build.0 = Release|x64
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x64.Deploy.0 = Release|x64
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x86.ActiveCfg = Release|x86
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x86.Build.0 = Release|x86
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{9EBDB27F-D75B-4D8C-B53F-7BE4A1FE89F9} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
{58950FB6-2F93-4963-B9CD-637F83F3EFBF} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
{31B67A35-9503-4213-857E-F44EB42AE549} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
{F9B0AE20-C91C-42B9-9C6E-D3BC28B4509E} = {3A47E08D-7EA5-4F3F-AA6D-1D4A41F26944}
EndGlobalSection
EndGlobal
<?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.
-->
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:build="http://schemas.microsoft.com/developer/appx/2012/build" IgnorableNamespaces="build">
<!--
DIESE PAKETMANIFESTDATEI WIRD DURCH DEN BUILDVORGANG GENERIERT.
Änderungen an dieser Datei gehen verloren, wenn sie erneut erstellt wird. Um Fehler in dieser Datei zu beheben, bearbeiten Sie die '.appxmanifest'-Quelldatei.
Weitere Informationen zu Paketmanifestdateien finden Sie unter http://go.microsoft.com/fwlink/?LinkID=241727
-->
<Identity Name="1482d0c0-f943-11e4-ad39-81ab0f14e62c" Version="1.0.0.0" Publisher="CN=$username$" ProcessorArchitecture="neutral" />
<mp:PhoneIdentity PhoneProductId="1482d0c0-f943-11e4-ad39-81ab0f14e62c" PhonePublisherId="db093ed5-53b1-45f7-af72-751e8f36ab80" />
<Properties>
<DisplayName>NotificationExample</DisplayName>
<PublisherDisplayName>$username$</PublisherDisplayName>
<Logo>images\StoreLogo.png</Logo>
</Properties>
<Prerequisites>
<OSMinVersion>6.3.1</OSMinVersion>
<OSMaxVersionTested>6.3.1</OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="EN-US" />
</Resources>
<Applications>
<Application Id="de.appplant.localnotification.example" StartPage="www/index.html">
<m3:VisualElements ToastCapable="true" DisplayName="NotificationExample" Square150x150Logo="images\Square150x150Logo.png" Square44x44Logo="images\Square44x44Logo.png" Description="CordovaApp" ForegroundText="light" BackgroundColor="transparent">
<m3:DefaultTile Wide310x150Logo="images\Wide310x150Logo.png" Square71x71Logo="images\Square71x71Logo.png">
<m3:ShowNameOnTiles>
<m3:ShowOn Tile="square150x150Logo" />
<m3:ShowOn Tile="wide310x150Logo" />
</m3:ShowNameOnTiles>
</m3:DefaultTile>
<m3:SplashScreen Image="images\SplashScreenPhone.png" />
</m3:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClientServer" />
</Capabilities>
<Dependencies>
<PackageDependency Name="Microsoft.Phone.WinJS.2.1" MinVersion="1.0.9651.0" />
</Dependencies>
<build:Metadata>
<build:Item Name="SharedGUID" Value="9ebdb27f-d75b-4d8c-b53f-7be4a1fe89f9" />
<build:Item Name="CodeSharingProject" Value="248F659F-DAC5-46E8-AC09-60EC9FC95053" />
<build:Item Name="VisualStudio" Version="12.0" />
<build:Item Name="VisualStudioEdition" Value="Microsoft Visual Studio Express 2013 für Windows" />
<build:Item Name="OperatingSystem" Version="6.3.9600.16384 (winblue_rtm.130821-1623)" />
<build:Item Name="Microsoft.Build.AppxPackage.dll" Version="12.0.31101.0" />
<build:Item Name="ProjectGUID" Value="31b67a35-9503-4213-857e-f44eb42ae549" />
<build:Item Name="MakePri.exe" Version="6.3.9600.17298 (winblue.141024-1500)" />
</build:Metadata>
</Package>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Machine>SEBASTINKATE177</Machine>
<WindowsUser>sebastian</WindowsUser>
<TargetPlatformIdentifier>WindowsPhoneApp</TargetPlatformIdentifier>
<SolutionConfiguration>Debug|AnyCPU</SolutionConfiguration>
<PackageArchitecture>neutral</PackageArchitecture>
<PackageIdentityName>1482d0c0-f943-11e4-ad39-81ab0f14e62c</PackageIdentityName>
<IntermediateOutputPath>Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<AppXManifest Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\Debug\AnyCPU\AppxManifest.xml">
<PackagePath>AppxManifest.xml</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppXManifest>
</ItemGroup>
<ItemGroup>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\SplashScreen.scale-100.png">
<PackagePath>images\SplashScreen.scale-100.png</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\SplashScreenPhone.scale-240.png">
<PackagePath>images\SplashScreenPhone.scale-240.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square150x150Logo.scale-100.png">
<PackagePath>images\Square150x150Logo.scale-100.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square150x150Logo.scale-240.png">
<PackagePath>images\Square150x150Logo.scale-240.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square30x30Logo.scale-100.png">
<PackagePath>images\Square30x30Logo.scale-100.png</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square310x310Logo.scale-100.png">
<PackagePath>images\Square310x310Logo.scale-100.png</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square44x44Logo.scale-240.png">
<PackagePath>images\Square44x44Logo.scale-240.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square70x70Logo.scale-100.png">
<PackagePath>images\Square70x70Logo.scale-100.png</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Square71x71Logo.scale-240.png">
<PackagePath>images\Square71x71Logo.scale-240.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\StoreLogo.scale-100.png">
<PackagePath>images\StoreLogo.scale-100.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\StoreLogo.scale-240.png">
<PackagePath>images\StoreLogo.scale-240.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Wide310x150Logo.scale-100.png">
<PackagePath>images\Wide310x150Logo.scale-100.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\images\Wide310x150Logo.scale-240.png">
<PackagePath>images\Wide310x150Logo.scale-240.png</PackagePath>
<ReRegisterAppIfChanged>true</ReRegisterAppIfChanged>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\img\logo.png">
<PackagePath>www\img\logo.png</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\beep.caf">
<PackagePath>www\beep.caf</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\cordova.js">
<PackagePath>www\cordova.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\cordova_plugins.js">
<PackagePath>www\cordova_plugins.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\js\index.js">
<PackagePath>www\js\index.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationCore.js">
<PackagePath>www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationCore.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationProxy.js">
<PackagePath>www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationProxy.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationUtil.js">
<PackagePath>www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationUtil.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-core.js">
<PackagePath>www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-core.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-util.js">
<PackagePath>www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-util.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification.js">
<PackagePath>www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\nl.x-services.plugins.toast\test\tests.js">
<PackagePath>www\plugins\nl.x-services.plugins.toast\test\tests.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\nl.x-services.plugins.toast\www\Toast.js">
<PackagePath>www\plugins\nl.x-services.plugins.toast\www\Toast.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\org.apache.cordova.device\src\windows\DeviceProxy.js">
<PackagePath>www\plugins\org.apache.cordova.device\src\windows\DeviceProxy.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\plugins\org.apache.cordova.device\www\device.js">
<PackagePath>www\plugins\org.apache.cordova.device\www\device.js</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\css\index.css">
<PackagePath>www\css\index.css</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\index.html">
<PackagePath>www\index.html</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\www\sound.mp3">
<PackagePath>www\sound.mp3</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\config.xml">
<PackagePath>config.xml</PackagePath>
</AppxPackagedFile>
<AppxPackagedFile Include="Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\Debug\AnyCPU\ReverseMap\resources.pri">
<PackagePath>resources.pri</PackagePath>
</AppxPackagedFile>
</ItemGroup>
<ItemGroup>
<ResolvedSDKReference Include="C:\Program Files %28x86%29\Microsoft SDKs\WindowsPhoneApp\v8.1\ExtensionSDKs\Microsoft.Phone.WinJS.2.1\1.0\">
<Name>Microsoft.Phone.WinJS.2.1</Name>
<Version>1.0.9651.0</Version>
<Architecture>Neutral</Architecture>
<FrameworkIdentity>Name=Microsoft.Phone.WinJS.2.1, MinVersion=1.0.9651.0</FrameworkIdentity>
<AppxLocation>C:\Program Files %28x86%29\Microsoft SDKs\WindowsPhoneApp\v8.1\ExtensionSDKs\Microsoft.Phone.WinJS.2.1\1.0\Microsoft.Phone.WinJS.2.1.appx</AppxLocation>
<MoreInfo>http://go.microsoft.com/fwlink/%3fLinkId=260891</MoreInfo>
</ResolvedSDKReference>
</ItemGroup>
</Project>
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\Debug\AnyCPU\ReverseMap\resources.pri
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\Debug\AnyCPU\AppxManifest.xml
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\Debug\AnyCPU\CordovaApp.Phone.build.appxrecipe
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\priconfig.xml
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\priconfig.xml.intermediate
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\layout.resfiles
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\layout.resfiles.intermediate
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\resources.resfiles
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\resources.resfiles.intermediate
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\pri.resfiles
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\pri.resfiles.intermediate
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\qualifiers.txt
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\qualifiers.txt.intermediate
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\MultipleQualifiersPerDimensionFound.txt
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\build\phone\bld\ProjectArchitectures.txt
Y:\Documents\github\cordova-example-local-notifications\platforms\windows\CordovaApp.Phone.jsproj;neutral
config.xml
images\SplashScreen.scale-100.png
images\SplashScreenPhone.scale-240.png
images\Square150x150Logo.scale-100.png
images\Square150x150Logo.scale-240.png
images\Square30x30Logo.scale-100.png
images\Square310x310Logo.scale-100.png
images\Square44x44Logo.scale-240.png
images\Square70x70Logo.scale-100.png
images\Square71x71Logo.scale-240.png
images\StoreLogo.scale-100.png
images\StoreLogo.scale-240.png
images\Wide310x150Logo.scale-100.png
images\Wide310x150Logo.scale-240.png
www\beep.caf
www\cordova.js
www\cordova_plugins.js
www\css\index.css
www\img\logo.png
www\index.html
www\js\index.js
www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationCore.js
www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationProxy.js
www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationUtil.js
www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification.js
www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-core.js
www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-util.js
www\plugins\nl.x-services.plugins.toast\test\tests.js
www\plugins\nl.x-services.plugins.toast\www\Toast.js
www\plugins\org.apache.cordova.device\src\windows\DeviceProxy.js
www\plugins\org.apache.cordova.device\www\device.js
www\sound.mp3
config.xml
images\SplashScreen.scale-100.png
images\SplashScreenPhone.scale-240.png
images\Square150x150Logo.scale-100.png
images\Square150x150Logo.scale-240.png
images\Square30x30Logo.scale-100.png
images\Square310x310Logo.scale-100.png
images\Square44x44Logo.scale-240.png
images\Square70x70Logo.scale-100.png
images\Square71x71Logo.scale-240.png
images\StoreLogo.scale-100.png
images\StoreLogo.scale-240.png
images\Wide310x150Logo.scale-100.png
images\Wide310x150Logo.scale-240.png
www\beep.caf
www\cordova.js
www\cordova_plugins.js
www\css\index.css
www\img\logo.png
www\index.html
www\js\index.js
www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationCore.js
www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationProxy.js
www\plugins\de.appplant.cordova.plugin.local-notification\src\windows\LocalNotificationUtil.js
www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification.js
www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-core.js
www\plugins\de.appplant.cordova.plugin.local-notification\www\local-notification-util.js
www\plugins\nl.x-services.plugins.toast\test\tests.js
www\plugins\nl.x-services.plugins.toast\www\Toast.js
www\plugins\org.apache.cordova.device\src\windows\DeviceProxy.js
www\plugins\org.apache.cordova.device\www\device.js
www\sound.mp3
<?xml version="1.0" encoding="utf-8"?>
<resources targetOsVersion="6.3.1" targetPlatform="WindowsPhone" majorVersion="1">
<index root="\" startIndexAt="build\phone\bld\layout.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="240" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Theme" value="Dark" />
<qualifier name="AlternateForm" value="" />
</default>
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="build\phone\bld\resources.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="240" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Theme" value="Dark" />
<qualifier name="AlternateForm" value="" />
</default>
<indexer-config type="RESW" convertDotsToSlashes="true" />
<indexer-config type="RESJSON" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="build\phone\bld\pri.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="240" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Theme" value="Dark" />
<qualifier name="AlternateForm" value="" />
</default>
<indexer-config type="PRI" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources targetOsVersion="6.3.1" targetPlatform="WindowsPhone" majorVersion="1">
<index root="\" startIndexAt="build\phone\bld\layout.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="240" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Theme" value="Dark" />
<qualifier name="AlternateForm" value="" />
</default>
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="build\phone\bld\resources.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="240" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Theme" value="Dark" />
<qualifier name="AlternateForm" value="" />
</default>
<indexer-config type="RESW" convertDotsToSlashes="true" />
<indexer-config type="RESJSON" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
<index root="\" startIndexAt="build\phone\bld\pri.resfiles">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="240" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Theme" value="Dark" />
<qualifier name="AlternateForm" value="" />
</default>
<indexer-config type="PRI" />
<indexer-config type="RESFILES" qualifierDelimiter="." />
</index>
</resources>
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<widget id="de.appplant.localnotification.example" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <widget id="de.appplant.localnotification.example" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<preference name="windows-target-version" value="8.0" /> <preference name="WindowsToastCapable" value="true" />
<preference name="windows-phone-target-version" value="8.1" />
<name>NotificationExample</name> <name>NotificationExample</name>
<description> <description>
A sample Apache Cordova application that responds to the deviceready event. A sample Apache Cordova application that responds to the deviceready event.
...@@ -11,4 +10,5 @@ ...@@ -11,4 +10,5 @@
</author> </author>
<content src="index.html" /> <content src="index.html" />
<access origin="*" /> <access origin="*" />
<preference name="windows-target-version" value="10.0" />
</widget> </widget>
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var check_reqs = require('./lib/check_reqs');
// check for help flag
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) > -1) {
check_reqs.help();
} else {
check_reqs.run().done(function success(msbuild) {
console.log('Environment is supported; found MSBuild Tools version ' + msbuild.version + ' at ' + msbuild.path);
}, function (err) {
console.error('Environment is not supported: ' + err);
process.exit(2);
});
}
:: Licensed to the Apache Software Foundation (ASF) under one
:: or more contributor license agreements. See the NOTICE file
:: distributed with this work for additional information
:: regarding copyright ownership. The ASF licenses this file
:: to you under the Apache License, Version 2.0 (the
:: "License"); you may not use this file except in compliance
:: with the License. You may obtain a copy of the License at
::
:: http://www.apache.org/licenses/LICENSE-2.0
::
:: Unless required by applicable law or agreed to in writing,
:: software distributed under the License is distributed on an
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations
:: under the License
@ECHO OFF
SET script_path="%~dp0check_reqs"
IF EXIST %script_path% (
node "%script_path%" %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
EXIT /B 1
)
\ No newline at end of file
...@@ -20,6 +20,5 @@ ...@@ -20,6 +20,5 @@
# #
--> -->
<widget xmlns="http://www.w3.org/ns/widgets"> <widget xmlns="http://www.w3.org/ns/widgets">
<preference name="windows-target-version" value="8.0" />
<preference name="windows-phone-target-version" value="8.1" />
</widget> </widget>
...@@ -90,6 +90,9 @@ ConfigParser.prototype = { ...@@ -90,6 +90,9 @@ ConfigParser.prototype = {
version: function() { version: function() {
return this.doc.getroot().attrib['version']; return this.doc.getroot().attrib['version'];
}, },
windows_packageVersion: function() {
return this.doc.getroot().attrib['windows-packageVersion'];
},
android_versionCode: function() { android_versionCode: function() {
return this.doc.getroot().attrib['android-versionCode']; return this.doc.getroot().attrib['android-versionCode'];
}, },
...@@ -113,6 +116,17 @@ ConfigParser.prototype = { ...@@ -113,6 +116,17 @@ ConfigParser.prototype = {
}); });
return ret; return ret;
}, },
getMatchingPreferences: function(regexp) {
var preferences = this.doc.findall('preference');
var result = [];
preferences.forEach(function(preference) {
if (regexp.test(preference.attrib.name)) {
result.push({ name: preference.attrib.name, value: preference.attrib.value });
}
});
return result;
},
/** /**
* Returns all resources. * Returns all resources.
* @param {string} resourceName Type of static resources to return. * @param {string} resourceName Type of static resources to return.
...@@ -164,6 +178,48 @@ ConfigParser.prototype = { ...@@ -164,6 +178,48 @@ ConfigParser.prototype = {
return ret; return ret;
}, },
/**
* Returns all <allow-navigation> rules.
* @return {string[]} Array of allow-navigation rules.
*/
getNavigationWhitelistRules: function() {
var rules = this.doc.getroot().findall('allow-navigation');
var result = [];
rules.forEach(function(rule) {
if (rule.attrib.href) {
result.push(rule.attrib.href);
}
});
return result;
},
getWindowsTargetVersion: function() {
var preference = this.getPreference('windows-target-version');
if (!preference)
preference = '8.1'; // default is 8.1.
return preference;
},
getWindowsPhoneTargetVersion: function() {
// This is a little more complicated than the previous one.
// 1. Check for an explicit preference. If the preference is set explicitly, return that, irrespective of whether it is valid
// 2. Get the Windows baseline version. If it's equivalent to 8.0, bump it to 8.1.
// 3. Return the Windows baseline version.
var explicitPreference = this.getPreference('windows-phone-target-version');
if (explicitPreference)
return explicitPreference;
var windowsTargetVersion = this.getWindowsTargetVersion();
if (windowsTargetVersion === '8' || windowsTargetVersion === '8.0')
windowsTargetVersion = '8.1';
return windowsTargetVersion;
},
// Returns the widget defaultLocale // Returns the widget defaultLocale
defaultLocale: function() { defaultLocale: function() {
return this.doc.getroot().attrib['defaultlocale']; return this.doc.getroot().attrib['defaultlocale'];
......
...@@ -17,25 +17,33 @@ ...@@ -17,25 +17,33 @@
under the License. under the License.
*/ */
var Q = require('Q'), var Q = require('q'),
path = require('path'), path = require('path'),
exec = require('./exec'), exec = require('./exec'),
spawn = require('./spawn'); shell = require('shelljs'),
spawn = require('./spawn'),
Version = require('./Version');
function MSBuildTools (version, path) { function MSBuildTools (version, path) {
this.version = version; this.version = version;
this.path = path; this.path = path;
} }
MSBuildTools.prototype.buildProject = function(projFile, buildType, buildarch) { MSBuildTools.prototype.buildProject = function(projFile, buildType, buildarch, otherConfigProperties) {
console.log('Building project: ' + projFile); console.log('Building project: ' + projFile);
console.log('\tConfiguration : ' + buildType); console.log('\tConfiguration : ' + buildType);
console.log('\tPlatform : ' + buildarch); console.log('\tPlatform : ' + buildarch);
var args = ['/clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal', '/nologo', var args = ['/clp:NoSummary;NoItemAndPropertyList;Verbosity=minimal', '/nologo',
'/p:Configuration=' + buildType, '/p:Configuration=' + buildType,
'/p:Platform=' + buildarch, '/p:Platform=' + buildarch];
'/p:BuildFromCordovaTooling=' + true];
if (otherConfigProperties) {
var keys = Object.keys(otherConfigProperties);
keys.forEach(function(key) {
args.push('/p:' + key + '=' + otherConfigProperties[key]);
});
}
return spawn(path.join(this.path, 'msbuild'), [projFile].concat(args)); return spawn(path.join(this.path, 'msbuild'), [projFile].concat(args));
}; };
...@@ -52,6 +60,16 @@ module.exports.findAvailableVersion = function () { ...@@ -52,6 +60,16 @@ module.exports.findAvailableVersion = function () {
}); });
}; };
module.exports.findAllAvailableVersions = function () {
var versions = ['14.0', '12.0', '4.0'];
return Q.all(versions.map(checkMSBuildVersion)).then(function(unprocessedResults) {
return unprocessedResults.filter(function(item) {
return !!item;
});
});
};
function checkMSBuildVersion(version) { function checkMSBuildVersion(version) {
var deferred = Q.defer(); var deferred = Q.defer();
exec('reg query HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\' + version + ' /v MSBuildToolsPath') exec('reg query HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\' + version + ' /v MSBuildToolsPath')
...@@ -59,7 +77,13 @@ function checkMSBuildVersion(version) { ...@@ -59,7 +77,13 @@ function checkMSBuildVersion(version) {
// fetch msbuild path from 'reg' output // fetch msbuild path from 'reg' output
var path = /MSBuildToolsPath\s+REG_SZ\s+(.*)/i.exec(output); var path = /MSBuildToolsPath\s+REG_SZ\s+(.*)/i.exec(output);
if (path) { if (path) {
deferred.resolve(new MSBuildTools(version, path[1])); path = path[1];
// CB-9565: Windows 10 invokes .NET Native compiler, which only runs on x86 arch,
// so if we're running an x64 Node, make sure to use x86 tools.
if (version === '14.0' && path.indexOf('amd64') > -1) {
path = require('path').join(path, '..');
}
deferred.resolve(new MSBuildTools(version, path));
return; return;
} }
deferred.resolve(null); // not found deferred.resolve(null); // not found
...@@ -69,3 +93,30 @@ function checkMSBuildVersion(version) { ...@@ -69,3 +93,30 @@ function checkMSBuildVersion(version) {
}); });
return deferred.promise; return deferred.promise;
} }
/// returns an array of available UAP Versions
function getAvailableUAPVersions() {
/*jshint -W069 */
var programFilesFolder = process.env['ProgramFiles(x86)'] || process.env['ProgramFiles'];
// No Program Files folder found, so we won't be able to find UAP SDK
if (!programFilesFolder) return [];
var uapFolderPath = path.join(programFilesFolder, 'Windows Kits', '10', 'Platforms', 'UAP');
if (!shell.test('-e', uapFolderPath)) {
return []; // No UAP SDK exists on this machine
}
var result = [];
shell.ls(uapFolderPath).filter(function(uapDir) {
return shell.test('-d', path.join(uapFolderPath, uapDir));
}).map(function(folder) {
return Version.tryParse(folder);
}).forEach(function(version, index) {
if (version) {
result.push(version);
}
});
return result;
}
module.exports.getAvailableUAPVersions = getAvailableUAPVersions;
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT 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 Version(major, minor, build, qfe) {
this.major = major;
this.minor = zeroIfUndefined(minor);
this.build = zeroIfUndefined(build);
this.qfe = zeroIfUndefined(qfe);
}
function zeroIfUndefined(val) {
if (typeof val === 'undefined')
return 0;
return val;
}
Version.Expression = /^\d{1,8}(\.\d{1,8}){0,3}$/;
Version.fromString = function(str) {
var result = Version.tryParse(str);
if (!result)
throw new RangeError('Could not parse a version from the provided value "' + str + '".');
return result;
};
Version.tryParse = function(str) {
if (Version.Expression.test(str)) {
var parts = str.split('.').map(function(part) {
return parseInt(part, 10);
});
var result = new Version(parts[0], parts[1], parts[2], parts[3]);
return result;
}
return false;
};
Version.comparer = function(a, b) {
if (a.constructor !== Version || b.constructor !== Version)
throw new TypeError('Must compare only Versions');
if (a.gt(b))
return 1;
else if (a.eq(b))
return 0;
return -1;
};
Version.prototype.gt = function(other) {
if (other.constructor !== Version)
throw new TypeError('other is not a Version.');
if (this.major > other.major) return true;
if (this.major < other.major) return false;
if (this.minor > other.minor) return true;
if (this.minor < other.minor) return false;
if (this.build > other.build) return true;
if (this.build < other.build) return false;
if (this.qfe > other.qfe) return true;
if (this.qfe < other.qfe) return false;
return false;
};
Version.prototype.gte = function(other) {
if (other.constructor !== Version)
throw new TypeError('other is not a Version.');
if (this.major > other.major) return true;
if (this.major < other.major) return false;
if (this.minor > other.minor) return true;
if (this.minor < other.minor) return false;
if (this.build > other.build) return true;
if (this.build < other.build) return false;
if (this.qfe > other.qfe) return true;
if (this.qfe < other.qfe) return false;
return true;
};
Version.prototype.eq = function(other) {
if (other.constructor !== Version)
throw new TypeError('other is not a Version.');
if (this.major === other.major && this.minor === other.minor && this.build === other.build && this.qfe === other.qfe)
return true;
return false;
};
Version.prototype.toString = function() {
return this.major + '.' + this.minor + '.' + this.build + '.' + this.qfe;
};
module.exports = Version;
...@@ -129,6 +129,24 @@ function Install-App { ...@@ -129,6 +129,24 @@ function Install-App {
} }
} }
function Install-AppFromDirectory {
param(
[Parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[string] $Path <# Full path to actual AppxManifest.xml #>
)
Add-AppxPackage -Path $Path -Register -ForceApplicationShutdown
}
function Install-AppFromAppx {
param(
[Parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[string] $Path <# Full path to actual .appx #>
)
Add-AppxPackage -Path $Path -ForceApplicationShutdown
}
function Start-Locally { function Start-Locally {
param( param(
[Parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)] [Parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
......
...@@ -17,108 +17,352 @@ ...@@ -17,108 +17,352 @@
under the License. under the License.
*/ */
var Q = require('Q'), var Q = require('q'),
path = require('path'), path = require('path'),
nopt = require('nopt'), nopt = require('nopt'),
shell = require('shelljs'),
utils = require('./utils'), utils = require('./utils'),
et = require('elementtree'),
prepare = require('./prepare'), prepare = require('./prepare'),
package = require('./package'),
MSBuildTools = require('./MSBuildTools'), MSBuildTools = require('./MSBuildTools'),
ConfigParser = require('./ConfigParser'); ConfigParser = require('./ConfigParser'),
fs = require('fs');
// Platform project root folder // Platform project root folder
var ROOT = path.join(__dirname, '..', '..'); var ROOT = path.join(__dirname, '..', '..');
var projFiles = { var projFiles = {
phone: 'CordovaApp.Phone.jsproj', phone: 'CordovaApp.Phone.jsproj',
win: 'CordovaApp.Windows.jsproj', win: 'CordovaApp.Windows.jsproj',
win80: 'CordovaApp.Windows80.jsproj' win80: 'CordovaApp.Windows80.jsproj',
win10: 'CordovaApp.Windows10.jsproj'
};
var projFilesToManifests = {
'CordovaApp.Phone.jsproj': 'package.phone.appxmanifest',
'CordovaApp.Windows.jsproj': 'package.windows.appxmanifest',
'CordovaApp.Windows80.jsproj': 'package.windows80.appxmanifest',
'CordovaApp.Windows10.jsproj': 'package.windows10.appxmanifest'
}; };
// parsed nopt arguments
var args;
// build type (Release vs Debug)
var buildType;
// target chip architectures to build for
var buildArchs;
// MSBuild Tools available on this development machine
var msbuild;
// builds cordova-windows application with parameters provided. // builds cordova-windows application with parameters provided.
// See 'help' function for args list // See 'help' function for args list
module.exports.run = function run (argv) { module.exports.run = function run (argv) {
if (!utils.isCordovaProject(ROOT)){ if (!utils.isCordovaProject(ROOT)){
return Q.reject('Could not find project at ' + ROOT); return Q.reject('Could not find project at ' + ROOT);
} }
try { return Q.all([parseAndValidateArgs(argv), MSBuildTools.findAllAvailableVersions()])
// thows exception if something goes wrong .spread(function(buildConfig, msbuildTools) {
parseAndValidateArgs(argv); // Apply build related configs
} catch (error) { prepare.updateBuildConfig(buildConfig);
return Q.reject(error); if (buildConfig.publisherId) {
updateManifestWithPublisher(msbuildTools, buildConfig);
} }
// bug: Windows 8 build fails on a system with MSBuild 14 on it.
// update platform as per configuration settings // Don't regress, make sure MSBuild 4 is selected for a Windows 8 build.
prepare.applyPlatformConfig(); cleanIntermediates();
return buildTargets(msbuildTools, buildConfig).then(function(pkg) {
return MSBuildTools.findAvailableVersion().then( console.log(' BUILD OUTPUT: ' + pkg.appx);
function(msbuildTools) { return pkg;
msbuild = msbuildTools; });
console.log('MSBuildToolsPath: ' + msbuild.path); }, function(error) {
return buildTargets(); return Q.reject(error);
}); });
}; };
// help/usage function // help/usage function
module.exports.help = function help() { module.exports.help = function help() {
console.log(''); console.log('');
console.log('Usage: build [ --debug | --release ] [--archs=\"<list of architectures...>\"] [--phone | --win]'); console.log('Usage: build [--debug | --release] [--phone | --win] [--bundle]');
console.log(' [--archs="<list of architectures...>"');
console.log(' [--packageCertificateKeyFile="key path"]');
console.log(' [--packageThumbprint="thumbprint"] [--publisherId]');
console.log(' [--buildConfig="file path"]');
console.log(' --help : Displays this dialog.'); console.log(' --help : Displays this dialog.');
console.log(' --debug : Builds project in debug mode. (Default)'); console.log(' --debug : Builds project in debug mode. (Default).');
console.log(' --release : Builds project in release mode.'); console.log(' --release (-r) : Builds project in release mode.');
console.log(' -r : Shortcut :: builds project in release mode.'); console.log(' --phone, --win : Specifies, what type of project to build.');
console.log(' --archs : Builds project binaries for specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).'); console.log(' --bundle : Tells the compiler to create a .appxbundle.');
console.log(' --phone, --win'); console.log(' Bundling is disabled when `anycpu` is built.');
console.log(' : Specifies, what type of project to build'); console.log(' --archs : Builds project binaries for specific chip');
console.log(' architectures (`anycpu`, `arm`, `x86`, `x64`).');
console.log(' Separate multiple choices with spaces and if');
console.log(' passing multiple choices, enclose with " ".');
console.log(' --appx=<8.1-win|8.1-phone|uap>');
console.log(' : Overrides windows-target-version to build');
console.log(' Windows 8.1, Windows Phone 8.1, or');
console.log(' Windows 10 Universal.');
console.log(' --packageCertificateKeyFile : Builds the project using provided certificate.');
console.log(' --packageThumbprint : Thumbprint associated with the certificate.');
console.log(' --publisherId : Sets publisher id field in manifest.');
console.log(' --buildConfig : Sets build settings from configuration file.');
console.log('');
console.log('examples:'); console.log('examples:');
console.log(' build '); console.log(' build ');
console.log(' build --debug'); console.log(' build --debug');
console.log(' build --release'); console.log(' build --release');
console.log(' build --release --archs="arm x86"'); console.log(' build --release --archs="arm x86" --bundle');
console.log(' build --appx=8.1-phone -r');
console.log(' build --packageCertificateKeyFile="CordovaApp_TemporaryKey.pfx"');
console.log(' build --publisherId="CN=FakeCorp, C=US"');
console.log(' build --buildConfig="build.json"');
console.log(''); console.log('');
process.exit(0); process.exit(0);
}; };
// returns list of projects to be built based on config.xml and additional parameters (-appx)
module.exports.getBuildTargets = function(isWinSwitch, isPhoneSwitch, projOverride) {
// apply build target override if one was specified
if (projOverride) {
switch (projOverride.toLowerCase()) {
case '8.1-phone':
return [projFiles.phone];
case '8.1-win':
return [projFiles.win];
case 'uap':
return [projFiles.win10];
default:
console.warn('Unrecognized --appx parameter passed to build: "' + projOverride + '", ignoring.');
break;
}
}
var configXML = new ConfigParser(path.join(ROOT, 'config.xml'));
var targets = [];
var noSwitches = !(isPhoneSwitch || isWinSwitch);
// Windows
if (isWinSwitch || noSwitches) { // if --win or no arg
var windowsTargetVersion = configXML.getWindowsTargetVersion();
switch(windowsTargetVersion.toLowerCase()) {
case '8':
case '8.0':
targets.push(projFiles.win80);
break;
case '8.1':
targets.push(projFiles.win);
break;
case '10.0':
case 'uap':
targets.push(projFiles.win10);
break;
default:
throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion);
}
}
// Windows Phone
if (isPhoneSwitch || noSwitches) { // if --phone or no arg
var windowsPhoneTargetVersion = configXML.getWindowsPhoneTargetVersion();
switch(windowsPhoneTargetVersion.toLowerCase()) {
case '8.1':
targets.push(projFiles.phone);
break;
case '10.0':
case 'uap':
if (targets.indexOf(projFiles.win10) < 0) {
// Already built due to --win or no switches
// and since the same thing can be run on Phone as Windows,
// we can skip this one.
targets.push(projFiles.win10);
}
break;
default:
throw new Error('Unsupported windows-phone-target-version value: ' + windowsPhoneTargetVersion);
}
}
return targets;
};
function parseAndValidateArgs(argv) { function parseAndValidateArgs(argv) {
return Q.promise(function(resolve, reject) {
// parse and validate args // parse and validate args
args = nopt({'debug': Boolean, 'release': Boolean, 'archs': [String], var args = nopt({
'phone': Boolean, 'win': Boolean}, {'-r': '--release'}, argv); 'debug': Boolean,
'release': Boolean,
'archs': [String],
'appx': String,
'phone': Boolean,
'win': Boolean,
'bundle': Boolean,
'packageCertificateKeyFile': String,
'packageThumbprint': String,
'publisherId': String,
'buildConfig': String
}, {'-r': '--release'}, argv);
var config = {};
var buildConfig = {};
// Validate args // Validate args
if (args.debug && args.release) { if (args.debug && args.release) {
throw 'Only one of "debug"/"release" options should be specified'; reject('Only one of "debug"/"release" options should be specified');
return;
} }
if (args.phone && args.win) { if (args.phone && args.win) {
throw 'Only one of "phone"/"win" options should be specified'; reject('Only one of "phone"/"win" options should be specified');
return;
} }
// get build options/defaults // get build options/defaults
buildType = args.release ? 'release' : 'debug'; config.buildType = args.release ? 'release' : 'debug';
buildArchs = args.archs ? args.archs.split(' ') : ['anycpu']; config.buildArchs = args.archs ? args.archs.split(' ') : ['anycpu'];
config.phone = args.phone ? true : false;
config.win = args.win ? true : false;
config.projVerOverride = args.appx;
// only set config.bundle if architecture is not anycpu
if (args.bundle) {
if ((config.buildArchs.indexOf('anycpu') > -1 || config.buildArchs.indexOf('any cpu') > -1) && config.buildArchs.length > 1) {
// Not valid to bundle anycpu with cpu-specific architectures. warn, then don't bundle
console.warn('Warning: anycpu and CPU-specific architectures were selected. This is not valid');
console.warn(' when enabling bundling with --bundle. Disabling bundling for this build.');
} else {
config.bundle = true;
}
}
// if build.json is provided, parse it
var buildConfigPath = args.buildConfig;
if (buildConfigPath) {
buildConfig = parseBuildConfig(buildConfigPath, config);
for (var prop in buildConfig) { config[prop] = buildConfig[prop]; }
}
// CLI arguments override build.json config
if (args.packageCertificateKeyFile) {
args.packageCertificateKeyFile = path.resolve(process.cwd(), args.packageCertificateKeyFile);
config.packageCertificateKeyFile = args.packageCertificateKeyFile;
}
config.packageThumbprint = config.packageThumbprint || args.packageThumbprint;
config.publisherId = config.publisherId || args.publisherId;
resolve(config);
});
}
function parseBuildConfig(buildConfigPath, config) {
var buildConfig, result = {};
console.log('Reading build config file: '+ buildConfigPath);
try {
var contents = fs.readFileSync(buildConfigPath, 'utf8');
buildConfig = JSON.parse(contents);
} catch (e) {
if (e.code === 'ENOENT') {
throw Error('Specified build config file does not exist: ' + buildConfigPath);
} else {
throw e;
}
}
if (buildConfig.windows && buildConfig.windows[config.buildType]) {
var windowsInfo = buildConfig.windows[config.buildType];
// If provided assume it's a relative path
if(windowsInfo.packageCertificateKeyFile) {
var buildPath = path.dirname(fs.realpathSync(buildConfigPath));
result.packageCertificateKeyFile = path.resolve(buildPath, windowsInfo.packageCertificateKeyFile);
}
if(windowsInfo.packageThumbprint) {
result.packageThumbprint = windowsInfo.packageThumbprint;
}
if(windowsInfo.publisherId) {
// Quickly validate publisherId
var publisherRegexStr = '(CN|L|O|OU|E|C|S|STREET|T|G|I|SN|DC|SERIALNUMBER|(OID\\.(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*))+))=' +
'(([^,+="<>#;])+|".*")(, (' +
'(CN|L|O|OU|E|C|S|STREET|T|G|I|SN|DC|SERIALNUMBER|(OID\\.(0|[1-9][0-9]*)(\\.(0|[1-9][0-9]*))+))=' +
'(([^,+="<>#;])+|".*")))*';
var publisherRegex = new RegExp(publisherRegexStr);
if (!publisherRegex.test(windowsInfo.publisherId)) {
throw Error('Invalid publisher id: ' + windowsInfo.publisherId);
}
result.publisherId = windowsInfo.publisherId;
}
}
return result;
} }
function buildTargets() { // Note: This function is very narrow and only writes to the app manifest if an update is done. See CB-9450 for the
// reasoning of why this is the case.
function updateManifestWithPublisher(allMsBuildVersions, config) {
var selectedBuildTargets = getBuildTargets(config);
var msbuild = getMsBuildForTargets(selectedBuildTargets, config, allMsBuildVersions);
var myBuildTargets = filterSupportedTargets(selectedBuildTargets, msbuild);
var manifestFiles = myBuildTargets.map(function(proj) {
return projFilesToManifests[proj];
});
manifestFiles.forEach(function(file) {
var manifestPath = path.join(ROOT, file);
var contents = fs.readFileSync(manifestPath, 'utf-8');
if (!contents) {
return;
}
// Skip BOM
contents = contents.substring(contents.indexOf('<'));
var manifest = new et.ElementTree(et.XML(contents));
var identityNode = manifest.find('.//Identity');
if (config.publisherId && config.publisherId !== identityNode.attrib.Publisher) {
identityNode.attrib.Publisher = config.publisherId;
fs.writeFileSync(manifestPath, manifest.write({indent: 4}), 'utf-8');
}
});
}
function buildTargets(allMsBuildVersions, config) {
// filter targets to make sure they are supported on this development machine // filter targets to make sure they are supported on this development machine
var myBuildTargets = filterSupportedTargets(getBuildTargets(), msbuild); var selectedBuildTargets = getBuildTargets(config);
var msbuild = getMsBuildForTargets(selectedBuildTargets, config, allMsBuildVersions);
if (!msbuild) {
return Q.reject('No valid MSBuild was detected for the selected target.');
}
console.log('MSBuildToolsPath: ' + msbuild.path);
var myBuildTargets = filterSupportedTargets(selectedBuildTargets, msbuild);
var buildConfigs = []; var buildConfigs = [];
var bundleTerms = '';
var hasAnyCpu = false;
var shouldBundle = !!config.bundle;
if (myBuildTargets.indexOf(projFiles.win80) > -1) {
if (shouldBundle) {
console.warn('Warning: Bundling is disabled because a Windows 8 project was detected.');
}
shouldBundle = false;
}
// collect all build configurations (pairs of project to build and target architecture) // collect all build configurations (pairs of project to build and target architecture)
myBuildTargets.forEach(function(buildTarget) { myBuildTargets.forEach(function(buildTarget) {
buildArchs.forEach(function(buildArch) { config.buildArchs.forEach(function(buildArch) {
buildConfigs.push({target:buildTarget, arch: buildArch}); buildConfigs.push({
target:buildTarget,
arch: buildArch
});
if (buildArch === 'anycpu' || buildArch === 'any cpu') {
hasAnyCpu = true;
bundleTerms = 'neutral';
}
if (!hasAnyCpu) {
if (bundleTerms.length > 0) {
bundleTerms += '|';
}
bundleTerms += buildArch;
}
}); });
}); });
// run builds serially // run builds serially
return buildConfigs.reduce(function (promise, build) { var buildsCompleted = buildConfigs.reduce(function (promise, build, index, configsArray) {
return promise.then(function () { return promise.then(function () {
// support for "any cpu" specified with or without space // support for "any cpu" specified with or without space
if (build.arch == 'any cpu') { if (build.arch == 'any cpu') {
...@@ -128,18 +372,81 @@ function buildTargets() { ...@@ -128,18 +372,81 @@ function buildTargets() {
if (msbuild.version == '4.0' && build.target == projFiles.win80) { if (msbuild.version == '4.0' && build.target == projFiles.win80) {
build.target = 'CordovaApp.vs2012.sln'; build.target = 'CordovaApp.vs2012.sln';
} }
return msbuild.buildProject(path.join(ROOT, build.target), buildType, build.arch);
var otherProperties = { };
// Only add the CordovaBundlePlatforms argument when on the last build step
if (shouldBundle && index === configsArray.length - 1) {
otherProperties.CordovaBundlePlatforms = bundleTerms;
} else if (shouldBundle) {
otherProperties.CordovaBundlePlatforms = build.arch;
}
return msbuild.buildProject(path.join(ROOT, build.target), config.buildType, build.arch, otherProperties);
}); });
}, Q()); }, Q());
if (shouldBundle) {
return buildsCompleted.then(function() {
return clearIntermediatesAndGetPackage(bundleTerms, config, hasAnyCpu);
});
} else {
return buildsCompleted.then(function() {
return package.getPackage(config.targetProject, config.buildType, config.buildArchs[0]);
});
}
} }
function getBuildTargets() { function clearIntermediatesAndGetPackage(bundleTerms, config, hasAnyCpu) {
var config = new ConfigParser(path.join(ROOT, 'config.xml')); // msbuild isn't capable of generating bundles unless you enable bundling for each individual arch
// However, that generates intermediate bundles, like "CordovaApp.Windows10_0.0.1.0_x64.appxbundle"
// We need to clear the intermediate bundles, or else "cordova run" will fail because of too
// many .appxbundle files.
console.log('Clearing intermediates...');
var appPackagesPath = path.join(ROOT, 'AppPackages');
var childDirectories = shell.ls(path.join(appPackagesPath, '*')).map(function(pathName) {
return { path: pathName, stats: fs.statSync(pathName) };
}).filter(function(fileInfo) {
return fileInfo.stats.isDirectory();
});
if (childDirectories.length === 0) {
throw new Error('Could not find a completed app package directory.');
}
// find the most-recently-modified directory
childDirectories.sort(function(a, b) { return b.stats.mtime - a.stats.mtime; });
var outputDirectory = childDirectories[0];
var finalFile = '';
var archSearchString = bundleTerms.replace(/\|/g, '_') + (config.buildType === 'debug' ? '_debug' : '') + '.appxbundle';
if (hasAnyCpu) {
archSearchString = 'AnyCPU' + (config.buildType === 'debug' ? '_debug' : '') + '.appxbundle';
}
var filesToDelete = shell.ls(path.join(outputDirectory.path, '*.appx*')).filter(function(appxbundle) {
var isMatch = appxbundle.indexOf(archSearchString) === -1;
if (!isMatch) {
finalFile = appxbundle;
}
return isMatch;
});
filesToDelete.forEach(function(file) {
shell.rm(file);
});
return package.getPackageFileInfo(finalFile);
}
// Can update buildConfig in the following ways:
// * Sets targetProject property, the project to launch when complete
function getBuildTargets(buildConfig) {
var configXML = new ConfigParser(path.join(ROOT, 'config.xml'));
var targets = []; var targets = [];
var noSwitches = !(args.phone || args.win); var noSwitches = !(buildConfig.phone || buildConfig.win);
// Windows // Windows
if (args.win || noSwitches) { // if --win or no arg if (buildConfig.win || noSwitches) { // if --win or no arg
var windowsTargetVersion = config.getPreference('windows-target-version'); var windowsTargetVersion = configXML.getWindowsTargetVersion();
switch(windowsTargetVersion) { switch(windowsTargetVersion) {
case '8': case '8':
case '8.0': case '8.0':
...@@ -148,43 +455,144 @@ function getBuildTargets() { ...@@ -148,43 +455,144 @@ function getBuildTargets() {
case '8.1': case '8.1':
targets.push(projFiles.win); targets.push(projFiles.win);
break; break;
case '10.0':
case 'UAP':
targets.push(projFiles.win10);
break;
default: default:
throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion); throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion);
} }
} }
// Windows Phone // Windows Phone
if (args.phone || noSwitches) { // if --phone or no arg if (buildConfig.phone || noSwitches) { // if --phone or no arg
var windowsPhoneTargetVersion = config.getPreference('windows-phone-target-version'); var windowsPhoneTargetVersion = configXML.getWindowsPhoneTargetVersion();
switch(windowsPhoneTargetVersion) { switch(windowsPhoneTargetVersion) {
case '8.1': case '8.1':
targets.push(projFiles.phone); targets.push(projFiles.phone);
break; break;
case '10.0':
case 'UAP':
if (!buildConfig.win && !noSwitches) {
// Already built due to --win or no switches
// and since the same thing can be run on Phone as Windows,
// we can skip this one.
targets.push(projFiles.win10);
}
break;
default: default:
throw new Error('Unsupported windows-phone-target-version value: ' + windowsPhoneTargetVersion); throw new Error('Unsupported windows-phone-target-version value: ' + windowsPhoneTargetVersion);
} }
} }
// apply build target override if one was specified
if (buildConfig.projVerOverride) {
switch (buildConfig.projVerOverride) {
case '8.1-phone':
targets = [projFiles.phone];
break;
case '8.1-win':
targets = [projFiles.win];
break;
case 'uap':
targets = [projFiles.win10];
break;
default:
console.warn('Unrecognized --appx parameter passed to build: "' + buildConfig.projVerOverride + '", ignoring.');
break;
}
}
// As part of reworking how build and package determine the winning project, set the 'target type' project
// as part of build configuration. This will be used for determining the binary to 'run' after build is done.
if (targets.length > 0) {
switch (targets[0]) {
case projFiles.win80:
buildConfig.targetProject = 'windows80';
break;
case projFiles.phone:
buildConfig.targetProject = 'phone';
break;
case projFiles.win10:
buildConfig.targetProject = 'windows10';
break;
case projFiles.win:
/* falls through */
default:
buildConfig.targetProject = 'windows';
break;
}
}
return targets; return targets;
} }
function filterSupportedTargets (targets) { function getMsBuildForTargets(selectedTargets, buildConfig, allMsBuildVersions) {
var availableVersions = allMsBuildVersions.reduce(function(obj, msbuildVersion) {
obj[msbuildVersion.version] = msbuildVersion;
return obj;
}, {});
var result = null;
if (selectedTargets.indexOf(projFiles.win80) > -1) {
// building Windows 8; prefer 4.0, unless phone is also present, in which case prefer 12
// prefer 12. If not present, can't build this; error in the filterSupportedTargets function
result = availableVersions['12.0'] || availableVersions['4.0'];
} else {
// 14 can build Windows 10, Windows 8.1, and Windows Phone 8.1, so resolve to 14 if available, else 12
result = (availableVersions['14.0'] || availableVersions['12.0']);
}
return result;
}
// TODO: Fix this so that it outlines supported versions based on version criteria:
// - v14: Windows 8.1, Windows 10
// - v12: Windows 8.1, Windows 8.0
// - v4: Windows 8.0
function msBuild4TargetsFilter(target) {
return target === projFiles.win80;
}
function msBuild12TargetsFilter(target) {
return target === projFiles.win80 || target === projFiles.win || target === projFiles.phone;
}
function msBuild14TargetsFilter(target) {
return target === projFiles.win || target === projFiles.phone || target === projFiles.win10;
}
function filterSupportedTargets (targets, msbuild) {
if (!targets || targets.length === 0) { if (!targets || targets.length === 0) {
console.warn('\r\nNo build targets are specified.'); console.warn('\r\nNo build targets are specified.');
return []; return [];
} }
if (msbuild.version != '4.0') { var targetFilters = {
return targets; '4.0': msBuild4TargetsFilter,
} '12.0': msBuild12TargetsFilter,
'14.0': msBuild14TargetsFilter
};
// MSBuild 4.0 does not support Windows 8.1 and Windows Phone 8.1 var filter = targetFilters[msbuild.version];
var supportedTargets = targets.filter(function(target) { if (!filter) {
return target != projFiles.win && target != projFiles.phone; console.warn('Unsupported msbuild version "' + msbuild.version + '", aborting.');
}); return [];
}
var supportedTargets = targets.filter(filter);
// unsupported targets have been detected // unsupported targets have been detected
if (supportedTargets.length != targets.length) { if (supportedTargets.length !== targets.length) {
console.warn('\r\nWarning. Windows 8.1 and Windows Phone 8.1 target platforms are not supported on this development machine and will be skipped.'); console.warn('Warning: Not all desired build targets are compatible with the current build environment.');
console.warn('Please install OS Windows 8.1 and Visual Studio 2013 Update2 in order to build for Windows 8.1 and Windows Phone 8.1.\r\n'); console.warn('Please install Visual Studio 2015 for Windows 8.1 and Windows 10, or Visual Studio 2013 Update 2 for Windows 8 and 8.1.');
} }
return supportedTargets; return supportedTargets;
} }
function cleanIntermediates() {
var buildPath = path.join(ROOT, 'build');
if (shell.test('-e', buildPath)) {
shell.rm('-rf', buildPath);
}
}
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
/*jshint node:true*/
var Q = require('q');
var os = require('os');
var path = require('path');
var shell = require('shelljs');
var ConfigParser, MSBuildTools, Version, exec;
try {
ConfigParser = require('../../template/cordova/lib/ConfigParser');
MSBuildTools = require('../../template/cordova/lib/MSBuildTools');
exec = require('../../template/cordova/lib/exec');
Version = require('../../template/cordova/lib/Version');
} catch (ex) {
// If previous import fails, we're probably running this script
// from installed platform and the module location is different.
ConfigParser = require('./ConfigParser');
MSBuildTools = require('./MSBuildTools');
exec = require('./exec');
Version = require('./Version');
}
// The constant for VS2013 Upd2 PackageVersion. See MSDN for
// reference: https://msdn.microsoft.com/en-us/library/bb164659(v=vs.120).aspx
var VS2013_UPDATE2_RC = new Version(12, 0, 30324);
var REQUIRED_VERSIONS = {
'8.0': {
os: '6.2',
msbuild: '11.0',
visualstudio: '11.0',
windowssdk: '8.0'
},
'8.1': {
os: '6.3',
msbuild: '12.0',
visualstudio: '12.0',
windowssdk: '8.1',
phonesdk: '8.1'
},
'10.0': {
// Note that Windows 10 target is also supported on Windows 7, so this should look
// like '6.1 || >=6.3', but due to Version module restricted functionality we handle
// this case separately in checkOS function below.
os: '6.3',
msbuild: '14.0',
visualstudio: '14.0',
windowssdk: '10.0',
phonesdk: '10.0'
}
};
function getConfig() {
try {
return new ConfigParser(path.join(__dirname, '..', '..', 'config.xml'));
} catch (e) {
throw new Error('Can\'t find config.xml file or it is malformed.');
}
}
function getMinimalRequiredVersionFor (requirement) {
var config = getConfig();
var windowsTargetVersion = config.getWindowsTargetVersion();
var windowsPhoneTargetVersion = config.getWindowsPhoneTargetVersion();
var windowsReqVersion = Version.tryParse(REQUIRED_VERSIONS[windowsTargetVersion][requirement]);
var phoneReqVersion = Version.tryParse(REQUIRED_VERSIONS[windowsPhoneTargetVersion][requirement]);
// If we're searching for Windows SDK, we're not
// interested in Phone's version and and vice versa.
if (requirement === 'windowssdk') return windowsReqVersion;
if (requirement === 'phonesdk') return phoneReqVersion;
// If both windowsReqVersion and phoneReqVersion is valid Versions, choose the max one
if (windowsReqVersion && phoneReqVersion) {
return windowsReqVersion.gt(phoneReqVersion) ?
windowsReqVersion :
phoneReqVersion;
}
// Otherwise return that one which is defined and valid
return windowsReqVersion || phoneReqVersion;
}
function getHighestAppropriateVersion (versions, requiredVersion) {
return versions.map(function (version) {
return Version.tryParse(version);
})
.sort(Version.comparer)
.filter(function (toolVersion) {
return toolVersion.gte(requiredVersion);
})[0];
}
/**
* Return Version object for current Windows version. User 'ver' binary or
* os.release() in case of errors.
*
* @return {Version} Version information for current OS.
*/
function getWindowsVersion() {
return exec('ver').then(function (output) {
var match = /\[Version (.*)\]\s*$/.exec(output);
return Version.fromString(match[1]);
}).fail(function () {
return Version.fromString(os.release());
});
}
/**
* Lists all Visual Studio versions insalled. For VS 2013 if it present, alao
* checks if Update 2 is installed.
*
* @return {String[]} List of installed Visual Studio versions.
*/
function getInstalledVSVersions() {
// Query all keys with Install value equal to 1, then filter out
// those, which are not related to VS itself
return exec('reg query HKLM\\SOFTWARE\\Microsoft\\DevDiv\\vs\\Servicing /s /v Install /f 1 /d /e /reg:32')
.fail(function () { return ''; })
.then(function (output) {
return output.split('\n')
.reduce(function (installedVersions, line) {
var match = /(\d+\.\d+)\\(ultimate|professional|premium|community)/.exec(line);
if (match && match[1] && installedVersions.indexOf(match[1]) === -1)
installedVersions.push(match[1]);
return installedVersions;
}, []);
})
.then(function (installedVersions) {
// If there is no VS2013 installed, the we have nothing to do
if (installedVersions.indexOf('12.0') === -1) return installedVersions;
// special case for VS 2013. We need to check if VS2013 update 2 is installed
return exec('reg query "HKLM\\SOFTWARE\\Microsoft\\Updates\\Microsoft Visual Studio' +
' 2013\\vsupdate_KB2829760" /v PackageVersion /reg:32')
.then(function (output) {
var updateVer = Version.fromString(/PackageVersion\s+REG_SZ\s+(.*)/i.exec(output)[1]);
// if update version is lover than Update2, reject the promise
if (VS2013_UPDATE2_RC.gte(updateVer)) return Q.reject();
return installedVersions;
})
.fail(function () {
// if we got any errors on previous steps, we're assuming that
// required VS update is not installed.
installedVersions.splice(installedVersions.indexOf('12.0'));
return installedVersions;
});
});
}
/**
* Gets list of installed Windows SDKs
*
* @return {Version[]} List of installed SDKs' versions
*/
function getInstalledWindowsSdks () {
var installedSdks = [];
return exec('reg query "HKLM\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows" /s /v InstallationFolder /reg:32')
.fail(function () { return ''; })
.then(function (output) {
var re = /\\Microsoft SDKs\\Windows\\v(\d+\.\d+)\s*InstallationFolder\s+REG_SZ\s+(.*)/gim;
var match;
while ((match = re.exec(output))){
var sdkPath = match[2];
// Verify that SDKs is really installed by checking SDKManifest file at SDK root
if (shell.test('-e', path.join(sdkPath, 'SDKManifest.xml'))) {
installedSdks.push(Version.tryParse(match[1]));
}
}
})
.thenResolve(installedSdks);
}
/**
* Gets list of installed Windows Phone SDKs. Separately searches for 8.1 Phone
* SDK and Windows 10 SDK, because the latter is needed for both Windows and
* Windows Phone applications.
*
* @return {Version[]} List of installed Phone SDKs' versions.
*/
function getInstalledPhoneSdks () {
var installedSdks = [];
return exec('reg query "HKLM\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows Phone\\v8.1" /v InstallationFolder /reg:32')
.fail(function () { return ''; })
.then(function (output) {
var match = /\\Microsoft SDKs\\Windows Phone\\v(\d+\.\d+)\s*InstallationFolder\s+REG_SZ\s+(.*)/gim.exec(output);
if (match && shell.test('-e', path.join(match[2], 'SDKManifest.xml'))) {
installedSdks.push(Version.tryParse(match[1]));
}
})
.then(function () {
return exec('reg query "HKLM\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v10.0" /v InstallationFolder /reg:32');
})
.fail(function () { return ''; })
.then(function (output) {
var match = /\\Microsoft SDKs\\Windows\\v(\d+\.\d+)\s*InstallationFolder\s+REG_SZ\s+(.*)/gim.exec(output);
if (match && shell.test('-e', path.join(match[2], 'SDKManifest.xml'))) {
installedSdks.push(Version.tryParse(match[1]));
}
})
.thenResolve(installedSdks);
}
/**
* Shortens version string or Version object by leaving only first two segments
* (major and minor).
* @param {String|Version} version The version identifier. Either Version
* object or string that looks like "12.5.6"
* @return {String} Shortened version, or undefined if provided
* parameter is not a valid version
*/
function shortenVersion (version) {
return /^(\d+(?:\.\d+)?)/.exec(version.toString())[1];
}
function mapWindowsVersionToName(version) {
var map = {
'6.2': 'Windows 8',
'6.3': 'Windows 8.1',
'10.0': 'Windows 10'
};
var majorMinor = shortenVersion(version);
return map[majorMinor];
}
function mapVSVersionToName(version) {
var map = {
'11.0': '2012 Express for Windows',
'12.0': '2013 Express for Windows Update2',
'14.0': '2015 Community'
};
var majorMinor = shortenVersion(version);
return map[majorMinor];
}
/**
* Check if current OS is supports building windows platform
* @return {Promise} Promise either fullfilled or rejected with error message.
*/
var checkOS = function () {
if (process.platform !== 'win32') {
// Build Universal windows apps available for windows platform only, so we reject on others platforms
return Q.reject('Cordova tooling for Windows requires Windows OS to build project');
}
return getWindowsVersion().then(function (actualVersion) {
var requiredOsVersion = getMinimalRequiredVersionFor('os');
if (actualVersion.gte(requiredOsVersion) ||
// Special case for Windows 10/Phone 10 targets which can be built on Windows 7 (version 6.1)
actualVersion.major === 6 && actualVersion.minor === 1 && getConfig.getWindowsTargetVersion() === '10.0') {
return mapWindowsVersionToName(actualVersion);
}
return Q.reject('Current Windows version doesn\'t support building this project. ' +
'Consider upgrading your OS to ' + mapWindowsVersionToName(requiredOsVersion));
});
};
/**
* Checks if MSBuild tools is available.
* @return {Promise} Promise either fullfilled with MSBuild version
* or rejected with error message.
*/
var checkMSBuild = function () {
return MSBuildTools.findAllAvailableVersions()
.then(function (msbuildToolsVersions) {
var msbuildRequiredVersion = getMinimalRequiredVersionFor('msbuild');
msbuildToolsVersions = msbuildToolsVersions.map(function (msbuildToolsVersion) {
return msbuildToolsVersion.version;
});
var appropriateVersion = getHighestAppropriateVersion(msbuildToolsVersions, msbuildRequiredVersion);
return appropriateVersion ?
shortenVersion(appropriateVersion) :
Q.reject('MSBuild tools v.' + shortenVersion(msbuildRequiredVersion) + ' not found. ' +
'Please install Visual Studio ' + mapVSVersionToName(getMinimalRequiredVersionFor('visualstudio')) +
' from https://www.visualstudio.com/downloads/download-visual-studio-vs');
});
};
var checkVS = function () {
var vsRequiredVersion = getMinimalRequiredVersionFor('visualstudio');
return getInstalledVSVersions()
.then(function (installedVersions) {
var appropriateVersion = getHighestAppropriateVersion(installedVersions, vsRequiredVersion);
return appropriateVersion ?
shortenVersion(appropriateVersion) :
Q.reject('Required version of Visual Studio not found. Please install Visual Studio ' +
mapVSVersionToName(vsRequiredVersion) +
' from https://www.visualstudio.com/downloads/download-visual-studio-vs');
});
};
var checkWinSdk = function () {
return getInstalledWindowsSdks()
.then(function (installedSdks) {
var requiredVersion = getMinimalRequiredVersionFor('windowssdk');
var hasSdkInstalled = installedSdks.some(function (installedSdk) {
return installedSdk.eq(requiredVersion);
});
if (!hasSdkInstalled) {
return Q.reject('Windows SDK not found. Please ensure that you have installed ' +
'Windows ' + shortenVersion(requiredVersion) + ' SDK along with Visual Studio or install ' +
'Windows ' + shortenVersion(requiredVersion) + ' SDK separately from ' +
'https://dev.windows.com/en-us/downloads');
}
return shortenVersion(requiredVersion);
});
};
var checkPhoneSdk = function () {
var requiredVersion = getMinimalRequiredVersionFor('phonesdk');
return getInstalledPhoneSdks()
.then(function (installedSdks) {
var requiredVersion = getMinimalRequiredVersionFor('phonesdk');
var hasSdkInstalled = installedSdks.some(function (installedSdk) {
return installedSdk.eq(requiredVersion);
});
return hasSdkInstalled ?
shortenVersion(requiredVersion) :
Q.reject();
})
.fail(function () {
return Q.reject('Windows Phone SDK not found. Please ensure that you have installed ' +
'Windows Phone ' + shortenVersion(requiredVersion) + ' SDK along with Visual Studio or install ' +
'Windows Phone ' + shortenVersion(requiredVersion) + ' SDK separately from ' +
'https://dev.windows.com/develop/download-phone-sdk');
});
};
module.exports.run = function () {
return checkOS().then(function () {
return MSBuildTools.findAvailableVersion();
});
};
/**
* Object that represents one of requirements for current platform.
* @param {String} id The unique identifier for this requirements.
* @param {String} name The name of requirements. Human-readable field.
* @param {Boolean} isFatal Marks the requirement as fatal. If such requirement will fail
* next requirements' checks will be skipped.
*/
var Requirement = function (id, name, isFatal) {
this.id = id;
this.name = name;
this.installed = false;
this.metadata = {};
this.isFatal = isFatal || false;
};
var requirements = [
new Requirement('os', 'Windows OS', true),
new Requirement('msbuild', 'MSBuild Tools'),
new Requirement('visualstudio', 'Visual Studio'),
new Requirement('windowssdk', 'Windows SDK'),
new Requirement('phonesdk', 'Windows Phone SDK')
];
// Define list of checks needs to be performed
var checkFns = [checkOS, checkMSBuild, checkVS, checkWinSdk, checkPhoneSdk];
/**
* Methods that runs all checks one by one and returns a result of checks
* as an array of Requirement objects. This method intended to be used by cordova-lib check_reqs method.
* @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
*/
module.exports.check_all = function() {
var result = [];
var fatalIsHit = false;
// Then execute requirement checks one-by-one
return checkFns.reduce(function (promise, checkFn, idx) {
return promise.then(function () {
// If fatal requirement is failed,
// we don't need to check others
if (fatalIsHit) return Q();
var requirement = requirements[idx];
return checkFn()
.then(function (version) {
requirement.installed = true;
requirement.metadata.version = version;
result.push(requirement);
}, function (err) {
if (requirement.isFatal) fatalIsHit = true;
requirement.metadata.reason = err;
result.push(requirement);
});
});
}, Q())
.then(function () {
// When chain is completed, return requirements array to upstream API
return result;
});
};
module.exports.help = function () {
console.log('Usage: check_reqs or node check_reqs');
};
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT 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 Q = require('q'),
fs = require('fs'),
/* jshint ignore:start */ // 'path' only used in ignored blocks
path = require('path'),
/* jshint ignore:end */
proc = require('child_process');
var E_INVALIDARG = 2147942487;
// neither 'exec' nor 'spawn' was sufficient because we need to pass arguments via spawn
// but also need to be able to capture stdout / stderr
function run(cmd, args, opt_cwd) {
var d = Q.defer();
try {
var child = proc.spawn(cmd, args, {cwd: opt_cwd, maxBuffer: 1024000});
var stdout = '', stderr = '';
child.stdout.on('data', function(s) { stdout += s; });
child.stderr.on('data', function(s) { stderr += s; });
child.on('exit', function(code) {
if (code) {
d.reject({ message: stderr, code: code, toString: function() { return stderr; }});
} else {
d.resolve(stdout);
}
});
} catch(e) {
console.error('error caught: ' + e);
d.reject(e);
}
return d.promise;
}
function DeploymentTool() {
}
/**
* Determines whether the requested version of the deployment tool is available.
* @returns True if the deployment tool can function; false if not.
*/
DeploymentTool.prototype.isAvailable = function() {
return fs.existsSync(this.path);
};
/**
* Enumerates devices attached to the development machine.
* @returns A Promise for an array of objects, which should be passed into other functions to represent the device.
* @remarks The returned objects contain 'index', 'name', and 'type' properties indicating basic information about them,
* which is limited to the information provided by the system. Other properties may also be included, but they are
* specific to the deployment tool which created them and are likely used internally.
*/
DeploymentTool.prototype.enumerateDevices = function() {
return Q.reject('May not use DeploymentTool directly, instead get an instance from DeploymentTool.getDeploymentTool()');
};
/**
* Installs an app package to the target device.
* @returns A Promise which will be fulfilled on success or rejected on failure.
* @param pathToAppxPackage The path to the .appx package to install.
* @param targetDevice An object returned from a successful call to enumerateDevices.
* @shouldLaunch Indicates whether to launch the app after installing it.
* @shouldUpdate Indicates whether to explicitly update the app, or install clean.
* @pin Optionally provided if the device requires pairing for deployment.
*/
DeploymentTool.prototype.installAppPackage = function(pathToAppxPackage, targetDevice, shouldLaunch, shouldUpdate, pin) {
return Q.reject('May not use DeploymentTool directly, instead get an instance from DeploymentTool.getDeploymentTool()');
};
/**
* Uninstalls an app package from the target device.
* @returns A Promise which will be fulfilled on success or rejected on failure.
* @param packageInfo The app package name or Phone GUID representing the app.
* @param targetDevice An object returned from a successful call to enumerateDevices.
*/
DeploymentTool.prototype.uninstallAppPackage = function(packageInfo, targetDevice) {
return Q.reject('Unable to uninstall any app packages because that feature is not supported.');
};
/**
* Gets a list of installed apps on the target device. This function is not supported for
* Windows Phone 8.1.
* @param targetDevice {Object} An object returned from a successful call to enumerateDevices.
* @returns A Promise for an array of app names.
*/
DeploymentTool.prototype.getInstalledApps = function(targetDevice) {
return Q.reject('Unable to get installed apps because that feature is not supported.');
};
/**
* Launches an app on the target device. This function is not supported for Windows 10.
* @param packageInfo {String} The app package name or Phone GUID representing the app.
* @param targetDevice {Object} An object returned from a successful call to enumerateDevices.
* @returns A Promise for when the app is launched.
*/
DeploymentTool.prototype.launchApp = function(packageInfo, targetDevice) {
return Q.reject('Unable to launch an app because that feature is not supported.');
};
/**
* Gets a DeploymentTool to deploy to devices or emulators.
* @param targetOsVersion {String} The version of the
*/
DeploymentTool.getDeploymentTool = function(targetOsVersion) {
if (targetOsVersion === '8.1') {
return new AppDeployCmdTool(targetOsVersion);
}
else {
return new WinAppDeployCmdTool(targetOsVersion);
}
};
// DeviceInfo is an opaque object passed to install/uninstall.
// Implementations of DeploymentTool can populate it with any additional
// information required for accessing them.
function DeviceInfo(deviceIndex, deviceName, deviceType) {
this.index = deviceIndex;
this.name = deviceName;
this.type = deviceType;
}
DeviceInfo.prototype.toString = function() {
return this.index + '. ' + this.name + ' (' + this.type + ')';
};
function AppDeployCmdTool(targetOsVersion) {
if (!(this instanceof AppDeployCmdTool))
throw new ReferenceError('Only create an AppDeployCmdTool as an instance object.');
DeploymentTool.call(this);
this.targetOsVersion = targetOsVersion;
/* jshint ignore:start */ /* Ignore jshint to use dot notation for 2nd process.env access for consistency */
var programFilesPath = process.env['ProgramFiles(x86)'] || process.env['ProgramFiles'];
this.path = path.join(programFilesPath, 'Microsoft SDKs', 'Windows Phone', 'v' + this.targetOsVersion, 'Tools', 'AppDeploy', 'AppDeployCmd.exe');
/* jshint ignore:end */
}
AppDeployCmdTool.prototype = Object.create(DeploymentTool.prototype);
AppDeployCmdTool.prototype.constructor = AppDeployCmdTool;
AppDeployCmdTool.prototype.enumerateDevices = function() {
var that = this;
// 9 Emulator 8.1 720P 4.7 inch\r\n
// maps to
// [(line), 9, 'Emulator 8.1 720P 4.7 inch']
// Expansion is: space, index, spaces, name
var LINE_TEST = /^\s(\d+?)\s+(.+?)$/m;
return run(that.path, ['/EnumerateDevices']).then(function(result) {
var lines = result.split('\n');
var matchedLines = lines.filter(function(line) {
return LINE_TEST.test(line);
});
var devices = matchedLines.map(function(line, arrayIndex) {
var match = line.match(LINE_TEST);
var index = parseInt(match[1], 10);
var name = match[2];
var shorthand = '';
var type = 'emulator';
if (name === 'Device') {
shorthand = 'de';
type = 'device';
} else if (arrayIndex === 1) {
shorthand = 'xd';
} else {
shorthand = index;
}
var deviceInfo = new DeviceInfo(index, name, type);
deviceInfo.__sourceLine = line;
deviceInfo.__shorthand = shorthand;
return deviceInfo;
});
return devices;
});
};
// Note: To account for CB-9482, we pass an extra parameter when retrying the call. Be forwarned to check for that
// if additional parameters are added in the future.
AppDeployCmdTool.prototype.installAppPackage = function(pathToAppxPackage, targetDevice, shouldLaunch, shouldUpdate, pin) {
var command = shouldUpdate ? '/update' : '/install';
if (shouldLaunch) {
command += 'launch';
}
var that = this;
var result = run(this.path, [command, pathToAppxPackage, '/targetdevice:' + targetDevice.__shorthand]);
if (targetDevice.type === 'emulator') {
result = result.then(null, function(e) {
// CB-9482: AppDeployCmd also reports E_INVALIDARG during this process. If so, try to repeat.
if (e.code === E_INVALIDARG) {
return run(that.path, [command, pathToAppxPackage, '/targetdevice:' + targetDevice.__shorthand]);
}
throw e;
});
}
return result;
};
AppDeployCmdTool.prototype.uninstallAppPackage = function(packageInfo, targetDevice) {
// CB-9482: AppDeployCmd reports failure when targeting an emulator, but actually succeeds
// Further calls in the promise chain then are not executed (such as installAppPackage) because
// of the failure reported here. By ensuring that this function always reports a success
// state, it allows install to proceed. (Install will fail if there is a legitimate
// uninstall failure such as due to no device).
var assureSuccess = function() {};
return run(this.path, ['/uninstall', packageInfo, '/targetdevice:' + targetDevice.__shorthand]).then(assureSuccess, assureSuccess);
};
AppDeployCmdTool.prototype.launchApp = function(packageInfo, targetDevice) {
return run(this.path, ['/launch', packageInfo, '/targetdevice:' + targetDevice.__shorthand]);
};
function WinAppDeployCmdTool(targetOsVersion) {
if (!(this instanceof WinAppDeployCmdTool))
throw new ReferenceError('Only create a WinAppDeployCmdTool as an instance object.');
DeploymentTool.call(this);
this.targetOsVersion = targetOsVersion;
/* jshint ignore:start */ /* Ignore jshint to use dot notation for 2nd process.env access for consistency */
var programFilesPath = process.env['ProgramFiles(x86)'] || process.env['ProgramFiles'];
this.path = path.join(programFilesPath, 'Windows Kits', '10', 'bin', 'x86', 'WinAppDeployCmd.exe');
/* jshint ignore:end */
}
WinAppDeployCmdTool.prototype = Object.create(DeploymentTool.prototype);
WinAppDeployCmdTool.prototype.constructor = WinAppDeployCmdTool;
WinAppDeployCmdTool.prototype.enumerateDevices = function() {
var that = this;
// 127.0.0.1 00000015-b21e-0da9-0000-000000000000 Lumia 1520 (RM-940)\r
// maps to
// [(line), '127.0.0.1', '00000015-b21e-0da9-0000-000000000000', 'Lumia 1520 (RM-940)']
// The expansion is: IP address, spaces, GUID, spaces, text name
var LINE_TEST = /^([\d\.]+?)\s+([\da-fA-F\-]+?)\s+(.+)$/m;
return run(that.path, ['devices']).then(function(result) {
var lines = result.split('\n');
var matchedLines = lines.filter(function(line) {
return LINE_TEST.test(line);
});
var devices = matchedLines.map(function(line, arrayIndex) {
var match = line.match(LINE_TEST);
var ip = match[1];
var guid = match[2];
var name = match[3];
var type = 'device';
var deviceInfo = new DeviceInfo(arrayIndex, name, type);
deviceInfo.__ip = ip;
deviceInfo.__guid = guid;
return deviceInfo;
});
return devices;
});
};
WinAppDeployCmdTool.prototype.installAppPackage = function(pathToAppxPackage, targetDevice, shouldLaunch, shouldUpdate, pin) {
if (shouldLaunch) {
console.warn('Warning: Cannot launch app with current version of Windows 10 SDK tools.');
console.warn(' You will have to launch the app after installation is completed.');
}
var args = [shouldUpdate ? 'update' : 'install', '-file', pathToAppxPackage, '-ip', targetDevice.__ip];
if (pin) {
args.push('-pin');
args.push(pin);
}
return run(this.path, args).then(function() {
console.log('Deployment completed successfully.');
});
};
WinAppDeployCmdTool.prototype.uninstallAppPackage = function(packageInfo, targetDevice) {
return run(this.path, ['uninstall', '-package', packageInfo, '-ip', targetDevice.__ip]);
};
// usage: require('deployment').getDeploymentTool('8.1');
module.exports = DeploymentTool;
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
// requires
var path = require('path'),
et = require('elementtree'),
Q = require('q'),
cp = require('child_process'),
ConfigParser = require('./ConfigParser.js'),
nopt = require('nopt');
// paths
var platformRoot = path.join(__dirname, '..', '..'),
projectRoot = path.join(platformRoot, '..', '..'),
configPath = path.join(projectRoot, 'config.xml');
//constants
var APP_TRACING_LOG = 'Microsoft-Windows-AppHost/ApplicationTracing',
ADMIN_LOG = 'Microsoft-Windows-AppHost/Admin';
// variables
var appTracingInitialState = null,
appTracingCurrentState = null,
adminInitialState = null,
adminCurrentState = null,
timers = [],
appName;
/*
* Gets windows AppHost/ApplicationTracing and AppHost/Admin logs
* and prints them to console
*/
module.exports.run = function(args) {
var startTime = new Date(new Date().getTime() - 10 * 60 * 1000).toISOString(), // show last 10 minutes by default
knownOpts = { 'minutes' : Number, 'dump' : Boolean, 'help' : Boolean },
shortHands = { 'mins' : ['--minutes'], 'h' : ['--help'] },
parsedOpts = nopt(knownOpts, shortHands, args, 0);
if (parsedOpts.help) {
module.exports.help();
return;
}
if (parsedOpts.dump) {
if (parsedOpts.minutes) {
startTime = new Date(new Date().getTime() - parsedOpts.minutes * 60 * 1000).toISOString();
}
dumpLogs(startTime);
return;
}
getLogState(ADMIN_LOG).then(function (state) {
adminInitialState = adminCurrentState = state;
return getLogState(APP_TRACING_LOG);
}).then(function (state) {
appTracingInitialState = appTracingCurrentState = state;
if (!adminCurrentState) {
return enableChannel(ADMIN_LOG).then(function () {
return getLogState(ADMIN_LOG);
}).then(function (state) {
adminCurrentState = state;
});
}
}).then(function () {
if (!appTracingCurrentState) {
return enableChannel(APP_TRACING_LOG).then(function () {
return getLogState(APP_TRACING_LOG);
}).then(function (state) {
appTracingCurrentState = state;
});
}
}).then(function () {
if (!adminCurrentState && !appTracingCurrentState) {
throw 'No log channels enabled. Exiting...';
}
}).then(function () {
try {
var config = new ConfigParser(configPath);
appName = config.name();
} catch (err) {
console.warn('Unable to read app name from config, showing logs for all applications.');
}
}).then(function () {
console.log('Now printing logs. To stop, please press Ctrl+C once.');
startLogging(ADMIN_LOG);
startLogging(APP_TRACING_LOG);
}).catch(function (error) {
console.error(error);
});
// Catch Ctrl+C message and exit gracefully
process.once('SIGINT', function () {
exitGracefully(0);
});
// Catch SIGTERM message and exit gracefully
process.once('SIGTERM', function () {
exitGracefully(0);
});
// Catch uncaught exceptions, print trace, then exit gracefully
process.once('uncaughtException', function(e) {
console.log(e.stack);
exitGracefully(1);
});
};
module.exports.help = function() {
console.log();
console.log('Usage: ' + path.relative(process.cwd(), path.join(platformRoot, 'cordova', 'log [options]')));
console.log('Continuously prints your app logs to the command line.');
console.log();
console.log('Options:');
console.log(' --dump: Dumps logs to console instead of continuous output.');
console.log(' --mins <minutes>: Used only with --dump. Dumps logs starting from this much minutes back.');
console.log();
console.log(' Example: ' + path.relative(process.cwd(), path.join(platformRoot, 'cordova', 'log --dump --mins 5')));
process.exit(0);
};
function exitGracefully(exitCode) {
if (appTracingInitialState === false && appTracingCurrentState === true) {
disableChannel(APP_TRACING_LOG);
}
if (adminInitialState === false && adminCurrentState === true) {
disableChannel(ADMIN_LOG);
}
timers.forEach(function (timer) {
clearInterval(timer);
});
// give async call some time to execute
console.log('Exiting in 2 seconds. Please don\'t interrupt the process.');
setTimeout(function() {
process.exit(exitCode);
}, 2000);
}
function startLogging(channel) {
var startTime = new Date().toISOString();
timers.push(setInterval(function() {
getEvents(channel, startTime).then(function(events) {
events.forEach(function (evt) {
startTime = evt.timeCreated;
console.log(stringifyEvent(evt));
});
});
}, 1000));
}
function dumpLogs(startTime) {
console.log('Dumping logs starting from ' + startTime);
var appTracingEvents, adminEvents;
getEvents(APP_TRACING_LOG, startTime).then(function (evts) {
appTracingEvents = evts;
return getEvents(ADMIN_LOG, startTime);
}).then(function(evts) {
adminEvents = evts;
appTracingEvents.concat(adminEvents)
.sort(function(evt1, evt2) {
if (evt1.timeCreated < evt2.timeCreated) {
return -1;
} else if (evt1.timeCreated > evt2.timeCreated) {
return 1;
}
return 0;
})
.forEach(function(evt) {
console.log(stringifyEvent(evt));
});
});
}
function getEvents(channel, startTime) {
var d = Q.defer();
var command = 'wevtutil qe ' + channel + ' /q:"*[System [(TimeCreated [@SystemTime>\'' + startTime + '\'])]]" /e:root';
cp.exec(command, function (error, stdout, stderr) {
if (error) {
d.reject('Failed to run wevtutil command. ' + error);
} else {
d.resolve(parseEvents(stdout));
}
});
return d.promise;
}
function getElementValue(et, element, attribute) {
var result;
var found = et.findall(element);
if (found.length > 0) {
if (!!attribute) {
result = found[0].get(attribute);
} else {
result = found[0].text;
}
}
return result;
}
function parseEvents(output) {
var etree = et.parse(output);
var events = etree.getroot().findall('./Event');
var results = [];
events.forEach(function (event) {
// Get only informative logs
if ((getElementValue(event, './System/Channel') === ADMIN_LOG) &&
(typeof getElementValue(event, './UserData/WWAUnhandledApplicationException') === 'undefined') &&
(typeof getElementValue(event, './UserData/WWATerminateApplication') === 'undefined')) {
return;
}
if ((getElementValue(event, './System/Channel') === APP_TRACING_LOG) &&
(typeof getElementValue(event, './UserData/WWADevToolBarLog') === 'undefined')) {
return;
}
var result = {
channel: getElementValue(event, './System/Channel'),
timeCreated: getElementValue(event, './System/TimeCreated', 'SystemTime'),
pid: getElementValue(event, './System/Execution', 'ProcessID'),
source: getElementValue(event, './UserData/WWADevToolBarLog/Source'),
documentFile: getElementValue(event, './UserData/WWADevToolBarLog/DocumentFile') ||
getElementValue(event, './UserData/WWAUnhandledApplicationException/DocumentFile') ||
getElementValue(event, './UserData/WWATerminateApplication/DocumentFile'),
displayName: getElementValue(event, './UserData/WWADevToolBarLog/DisplayName') ||
getElementValue(event, './UserData/WWAUnhandledApplicationException/DisplayName') ||
getElementValue(event, './UserData/WWATerminateApplication/DisplayName'),
line: getElementValue(event, './UserData/WWADevToolBarLog/Line'),
column: getElementValue(event, './UserData/WWADevToolBarLog/Column'),
sourceFile: getElementValue(event, './UserData/WWAUnhandledApplicationException/SourceFile'),
sourceLine: getElementValue(event, './UserData/WWAUnhandledApplicationException/SourceLine'),
sourceColumn: getElementValue(event, './UserData/WWAUnhandledApplicationException/SourceColumn'),
message: getElementValue(event, './UserData/WWADevToolBarLog/Message'),
appName: getElementValue(event, './UserData/WWAUnhandledApplicationException/ApplicationName'),
errorType: getElementValue(event, './UserData/WWAUnhandledApplicationException/ErrorType'),
errorDescription: getElementValue(event, './UserData/WWAUnhandledApplicationException/ErrorDescription') ||
getElementValue(event, './UserData/WWATerminateApplication/ErrorDescription'),
stackTrace: getElementValue(event, './UserData/WWAUnhandledApplicationException/StackTrace') ||
getElementValue(event, './UserData/WWATerminateApplication/StackTrace'),
};
// filter out events from other applications
if (typeof result.displayName !== 'undefined' && typeof appName !== 'undefined' && result.displayName !== appName) {
return;
}
// do not show Process ID, App Name and Display Name for filtered events
if (typeof appName !== 'undefined') {
result.pid = undefined;
result.appName = undefined;
result.displayName = undefined;
}
// cut out uninformative fields
if ((result.line === '0') && (result.column === '0')) {
result.line = undefined;
result.column = undefined;
}
// trim whitespace
if (typeof result.errorDescription !== 'undefined') {
result.errorDescription = result.errorDescription.trim();
}
if (typeof result.message !== 'undefined') {
result.message = result.message.trim();
}
results.push(result);
});
return results;
}
function formatField(event, fieldName, fieldShownName, offset) {
var whitespace = '', // to align all field values
multiLineWhitespace = ' '; // to align multiline fields (i.e. Stack Trace) correctly
for (var i = 0; i < offset; i++) {
if (i >= fieldShownName.length) {
whitespace += ' ';
}
multiLineWhitespace += ' ';
}
if (event.hasOwnProperty(fieldName) && (typeof event[fieldName] !== 'undefined')) {
event[fieldName] = event[fieldName].replace(/\n\s*/g, '\n' + multiLineWhitespace);
return ('\n' + fieldShownName + ':' + whitespace + event[fieldName]).replace(/\n$/m, '');
}
return '';
}
function stringifyEvent(event) {
if (typeof event === 'undefined') {
return;
}
var result = '',
offset = 18;
result += formatField(event, 'channel', 'Channel', offset);
result += formatField(event, 'timeCreated', 'Time Created', offset);
result += formatField(event, 'pid', 'Process ID', offset);
result += formatField(event, 'source', 'Source', offset);
result += formatField(event, 'documentFile', 'Document File', offset);
result += formatField(event, 'displayName', 'Display Name', offset);
result += formatField(event, 'line', 'Line', offset);
result += formatField(event, 'column', 'Column', offset);
result += formatField(event, 'message', 'Message', offset);
result += formatField(event, 'appName', 'App Name', offset);
result += formatField(event, 'errorType', 'Error Type', offset);
result += formatField(event, 'errorDescription', 'Error Description', offset);
result += formatField(event, 'sourceFile', 'Source File', offset);
result += formatField(event, 'sourceLine', 'Source Line', offset);
result += formatField(event, 'sourceColumn', 'Source Column', offset);
result += formatField(event, 'stackTrace', 'Stack Trace', offset);
return result;
}
function getLogState(channel) {
return exec('wevtutil get-log "' + channel + '"').then(function(output) {
return output.indexOf('enabled: true') != -1;
});
}
function enableChannel(channel) {
return exec('wevtutil set-log "' + channel + '" /e:false /q:true').then(function() {
return exec('wevtutil set-log "' + channel + '" /e:true /rt:true /ms:4194304 /q:true');
}, function() {
console.warn('Cannot enable log channel: ' + channel);
console.warn('Try running the script with administrator privileges.');
});
}
function disableChannel(channel) {
console.log('Disabling channel ' + channel);
exec('wevtutil set-log "' + channel + '" /e:false /q:true');
}
function exec(command) {
var d = Q.defer();
cp.exec(command, function (error, stdout) {
if (error) {
d.reject('An error occured while executing following command:\n' + command + '\n' + error);
}
d.resolve(stdout);
});
return d.promise;
}
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
var Q = require('q'), var Q = require('q'),
fs = require('fs'), fs = require('fs'),
path = require('path'), path = require('path'),
exec = require('./exec'),
spawn = require('./spawn'), spawn = require('./spawn'),
utils = require('./utils'); utils = require('./utils');
...@@ -41,13 +40,16 @@ module.exports.getPackage = function (projectType, buildtype, buildArch) { ...@@ -41,13 +40,16 @@ module.exports.getPackage = function (projectType, buildtype, buildArch) {
return fs.statSync(pkgDir).isDirectory(); return fs.statSync(pkgDir).isDirectory();
}); });
for (var dir in pkgDirs) { for (var dirIndex = 0; dirIndex < pkgDirs.length; dirIndex++) {
var packageFiles = fs.readdirSync(pkgDirs[dir]).filter(function(e) { var dir = pkgDirs[dirIndex];
var packageFiles = fs.readdirSync(dir).filter(function(e) {
return e.match('.*.(appx|appxbundle)$'); return e.match('.*.(appx|appxbundle)$');
}); });
for (var pkgFile in packageFiles) { for (var pkgIndex = 0; pkgIndex < packageFiles.length; pkgIndex++) {
var packageFile = path.join(pkgDirs[dir], packageFiles[pkgFile]); var pkgFile = packageFiles[pkgIndex];
var packageFile = path.join(dir, pkgFile);
var pkgInfo = module.exports.getPackageFileInfo(packageFile); var pkgInfo = module.exports.getPackageFileInfo(packageFile);
if (pkgInfo && pkgInfo.type == projectType && if (pkgInfo && pkgInfo.type == projectType &&
...@@ -58,23 +60,34 @@ module.exports.getPackage = function (projectType, buildtype, buildArch) { ...@@ -58,23 +60,34 @@ module.exports.getPackage = function (projectType, buildtype, buildArch) {
} }
} }
} }
// reject because seems that no corresponding packages found // reject because seems that no corresponding packages found
return Q.reject('Package with specified parameters not found in AppPackages folder'); return Q.reject('Package with specified parameters not found in AppPackages folder');
}; };
function getPackagePhoneProductId(packageFile) {
var windowsPlatformPath = path.join(packageFile, '..', '..', '..');
return module.exports.getAppId(windowsPlatformPath);
}
// returns package info object or null if it is not valid package // returns package info object or null if it is not valid package
module.exports.getPackageFileInfo = function (packageFile) { module.exports.getPackageFileInfo = function (packageFile) {
var pkgName = path.basename(packageFile); var pkgName = path.basename(packageFile);
// CordovaApp.Windows_0.0.1.0_anycpu_debug.appx // CordovaApp.Windows_0.0.1.0_anycpu_debug.appx
// CordovaApp.Phone_0.0.1.0_x86_debug.appxbundle // CordovaApp.Phone_0.0.1.0_x86_debug.appxbundle
var props = /.*\.(Phone|Windows|Windows80)_((?:\d*\.)*\d*)_(AnyCPU|x64|x86|ARM)(?:_(Debug))?.(appx|appxbundle)$/i.exec(pkgName); // CordovaApp.Windows10_0.0.1.0_x64_x86_arm.appxbundle
var props = /.*\.(Phone|Windows|Windows80|Windows10)_((?:\d*\.)*\d*)*((?:_(AnyCPU|x86|x64|ARM)){1,4})(?:(_Debug))?.(appx|appxbundle)$/i.exec(pkgName);
if (props) { if (props) {
return {type : props[1].toLowerCase(), return {
arch : props[3].toLowerCase(), type : props[1].toLowerCase(),
buildtype : props[4] ? props[4].toLowerCase() : 'release', arch : props[3].toLowerCase().substring(1),
file : props[1].toLowerCase() != 'phone' ? archs : props[3].toLowerCase().substring(1).split('_'),
path.join(packageFile, '..', 'Add-AppDevPackage.ps1') : buildtype : props[5] ? props[5].substring(1).toLowerCase() : 'release',
packageFile appx : packageFile,
script : path.join(packageFile, '..', 'Add-AppDevPackage.ps1'),
phoneId : getPackagePhoneProductId(packageFile)
}; };
} }
return null; return null;
...@@ -85,35 +98,54 @@ module.exports.getPackageFileInfo = function (packageFile) { ...@@ -85,35 +98,54 @@ module.exports.getPackageFileInfo = function (packageFile) {
module.exports.getAppId = function (platformPath) { module.exports.getAppId = function (platformPath) {
var manifest = path.join(platformPath, 'package.phone.appxmanifest'); var manifest = path.join(platformPath, 'package.phone.appxmanifest');
try { try {
return Q.resolve(/PhoneProductId="(.*?)"/gi.exec(fs.readFileSync(manifest, 'utf8'))[1]); return /PhoneProductId="(.*?)"/gi.exec(fs.readFileSync(manifest, 'utf8'))[1];
} catch (e) { } catch (e) {
return Q.reject('Can\'t read appId from phone manifest' + e); throw new Error('Can\'t read appId from phone manifest', e);
} }
}; };
// return package name fetched from appxmanifest // return package name fetched from appxmanifest
// return rejected promise if appxmanifest not valid // return rejected promise if appxmanifest not valid
module.exports.getPackageName = function (platformPath) { function getPackageName(platformPath) {
// Can reliably read from package.windows.appxmanifest even if targeting Windows 10
// because the function is only used for desktop deployment, which always has the same
// package name when uninstalling / reinstalling
var manifest = path.join(platformPath, 'package.windows.appxmanifest'); var manifest = path.join(platformPath, 'package.windows.appxmanifest');
try { try {
return Q.resolve(/Application Id="(.*?)"/gi.exec(fs.readFileSync(manifest, 'utf8'))[1]); return Q.resolve(/Identity Name="(.*?)"/gi.exec(fs.readFileSync(manifest, 'utf8'))[1]);
} catch (e) { } catch (e) {
return Q.reject('Can\'t read package name from manifest ' + e); return Q.reject('Can\'t read package name from manifest ' + e);
} }
}; }
// returns one of available devices which name match with provided string // returns one of available devices which name match with provided string
// return rejected promise if device with name specified not found // return rejected promise if device with name specified not found
module.exports.findDevice = function (target) { module.exports.findDevice = function (deploymentTool, target) {
target = target.toLowerCase(); target = target.toLowerCase();
return module.exports.listDevices().then(function(deviceList) { return deploymentTool.enumerateDevices().then(function(deviceList) {
// CB-7617 since we use partial match shorter names should go first, // CB-7617 since we use partial match shorter names should go first,
// example case is ['Emulator 8.1 WVGA 4 inch 512MB', 'Emulator 8.1 WVGA 4 inch'] // example case is ['Emulator 8.1 WVGA 4 inch 512MB', 'Emulator 8.1 WVGA 4 inch']
var sortedList = deviceList.concat().sort(function (l, r) { return l.length > r.length; }); // In CB-9283, we need to differentiate between emulator, device, and target.
// So, for emulators to honor the above CB-7617, we preserve the original behavior.
// Else, we choose either the target by ID (DeviceInfo.index) or if it's just device,
// we choose the default (aka first) device.
if (target === 'emulator') {
var sortedList = deviceList.concat().sort(function (l, r) { return l.toString().length > r.toString().length; });
for (var idx in sortedList){ for (var idx in sortedList){
if (sortedList[idx].toLowerCase().indexOf(target) > -1) { if (sortedList[idx].toString().toLowerCase().indexOf(target) > -1) {
// we should return index based on original list // we should return index based on original list
return Q.resolve(deviceList.indexOf(sortedList[idx])); return Q.resolve(sortedList[idx]);
}
}
} else if (target === 'device') {
return Q.resolve(deviceList[0]);
} else {
var candidateList = deviceList.filter(function(device) {
return device.index === parseInt(target, 10);
});
if (candidateList.length > 0) {
return candidateList[0];
} }
} }
return Q.reject('Specified device not found'); return Q.reject('Specified device not found');
...@@ -121,57 +153,88 @@ module.exports.findDevice = function (target) { ...@@ -121,57 +153,88 @@ module.exports.findDevice = function (target) {
}; };
// returns array of available devices names // returns array of available devices names
module.exports.listDevices = function () { module.exports.listDevices = function (deploymentTool) {
return utils.getAppDeployUtils().then(function(appDeployUtils) {
return exec('"' + appDeployUtils + '" /enumeratedevices').then(function(output) { return deploymentTool.enumerateDevices().then(function(deviceList) {
return Q.resolve(output.split('\n').map(function(line) { return deviceList.map(function(device) {
var match = /\s*(\d)+\s+(.*)/.exec(line); return device.toString();
return match && match[2];
}).filter(function (line) {
return line;
}));
}); });
}, function(e) {
console.warn('Failed to enumerate devices');
console.warn(e);
throw e;
}); });
}; };
// deploys specified phone package to device/emulator
module.exports.deployToPhone = function (appxPath, deployTarget) { function uninstallAppFromPhone(appDeployUtils, package, target) {
var getTarget = deployTarget == 'device' ? Q('de') : console.log('Attempting to remove previously installed application...');
deployTarget == 'emulator' ? Q('xd') : module.exports.findDevice(deployTarget); return appDeployUtils.uninstallAppPackage(package.phoneId, target);
}
// /installlaunch option sometimes fails with 'Error: The parameter is incorrect.'
// so we use separate steps to /install and then /launch // deploys specified phone package to device/emulator and launches it
return getTarget.then(function(target) { module.exports.deployToPhone = function (package, deployTarget, targetWindows10, deploymentTool) {
return utils.getAppDeployUtils().then(function(appDeployUtils) { var deployment;
console.log('Installing application'); if (deploymentTool) {
return spawn(appDeployUtils, ['/install', appxPath, '/targetdevice:' + target]).then(function() { deployment = Q(deploymentTool);
// TODO: resolve AppId without specifying project root; }
return module.exports.getAppId(path.join(__dirname, '..', '..')); else {
}).then(function(appId) { deployment = utils.getAppDeployUtils(targetWindows10);
console.log('Running application'); }
return spawn(appDeployUtils, ['/launch', appId, '/targetdevice:' + target]);
return deployment.then(function(deploymentTool) {
return module.exports.findDevice(deploymentTool, deployTarget).then(function(target) {
return uninstallAppFromPhone(deploymentTool, package, target).then(
function() {}, function() {}).then(function() {
// shouldUpdate = false because we've already uninstalled
console.log('Deploying app package...');
return deploymentTool.installAppPackage(package.appx, target, /*shouldLaunch*/ true, /*shouldUpdate*/ false);
}).then(function() { }, function(error) {
if (error.message.indexOf('Error code 2148734208 for command') === 0) {
return deploymentTool.installAppPackage(package.appx, target, /*shouldLaunch*/ true, /*shouldUpdate*/ true);
} else if (error.message.indexOf('Error code -2146233088') === 0) {
throw new Error('No Windows Phone device was detected.');
} else {
console.warn('Unexpected error from installation:');
console.warn(error.message);
console.warn('You may have previously installed the app with an earlier version of cordova-windows.');
console.warn('Ensure the app is uninstalled from the phone and then try to run again.');
throw error;
}
}); });
}); });
}); });
}; };
// deploys specified package to desktop // deploys specified package to desktop
module.exports.deployToDesktop = function (appxScript, deployTarget) { module.exports.deployToDesktop = function (package, deployTarget) {
if (deployTarget != 'device' && deployTarget != 'emulator') { if (deployTarget != 'device' && deployTarget != 'emulator') {
return Q.reject('Deploying desktop apps to specific target not supported'); return Q.reject('Deploying desktop apps to specific target not supported');
} }
return utils.getAppStoreUtils().then(function(appStoreUtils) { return utils.getAppStoreUtils().then(function(appStoreUtils) {
return module.exports.getPackageName(path.join(__dirname, '..', '..')).then(function(pkgname) { return getPackageName(path.join(__dirname, '..', '..')).then(function(pkgname) {
var oldArch;
// uninstalls previous application instance (if exists) // uninstalls previous application instance (if exists)
console.log('Attempt to uninstall previous application version...'); console.log('Attempt to uninstall previous application version...');
return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Uninstall-App ' + pkgname]) return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Uninstall-App ' + pkgname])
.then(function() { .then(function() {
console.log('Attempt to install application...'); console.log('Attempt to install application...');
return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Install-App', utils.quote(appxScript)]); oldArch = process.env.PROCESSOR_ARCHITECTURE;
if (package.arch === 'x64') {
process.env.PROCESSOR_ARCHITECTURE = 'AMD64';
}
return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Install-App', utils.quote(package.script)]);
}).then(function() { }).then(function() {
process.env.PROCESSOR_ARCHITECTURE = oldArch;
console.log('Starting application...'); console.log('Starting application...');
return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Start-Locally', pkgname]); return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Start-Locally', pkgname]);
}, function (error) {
process.env.PROCESSOR_ARCHITECTURE = oldArch;
throw error;
}); });
}); });
}); });
......
...@@ -20,57 +20,113 @@ ...@@ -20,57 +20,113 @@
var path = require('path'), var path = require('path'),
fs = require('fs'), fs = require('fs'),
et = require('elementtree'), et = require('elementtree'),
subElement = et.SubElement,
shell = require('shelljs'), shell = require('shelljs'),
MSBuildTools = require('./MSBuildTools'),
Version = require('./Version'),
ConfigParser = require('./ConfigParser'); ConfigParser = require('./ConfigParser');
var ROOT = path.join(__dirname, '..', '..'), var ROOT = path.join(__dirname, '..', '..'),
accessRules; PROJECT_WINDOWS10 = 'CordovaApp.Windows10.jsproj',
MANIFEST_WINDOWS8 = 'package.windows80.appxmanifest',
module.exports.applyPlatformConfig = function () { MANIFEST_WINDOWS = 'package.windows.appxmanifest',
console.log('Applying Platform Config...'); MANIFEST_PHONE = 'package.phone.appxmanifest',
MANIFEST_WINDOWS10 = 'package.windows10.appxmanifest',
BASE_UAP_VERSION = new Version(10, 0, 10240, 0),
UAP_RESTRICTED_CAPS = ['enterpriseAuthentication', 'sharedUserCertificates',
'documentsLibrary', 'musicLibrary', 'picturesLibrary',
'videosLibrary', 'removableStorage', 'internetClientServer',
'privateNetworkClientServer'],
// UAP namespace capabilities come from the XSD type ST_Capability_Uap from AppxManifestTypes.xsd
CAPS_NEEDING_UAPNS = ['documentsLibrary', 'picturesLibrary', 'videosLibrary',
'musicLibrary', 'enterpriseAuthentication', 'sharedUserCertificates',
'removableStorage', 'appointments', 'contacts', 'userAccountInformation',
'phoneCall', 'blockedChatMessages', 'objects3D'];
var TEMPLATE =
'<?xml version="1.0" encoding="utf-8"?>\n' +
'<!--\n This file is automatically generated.\n' +
' Do not modify this file - YOUR CHANGES WILL BE ERASED!\n-->\n';
module.exports.applyPlatformConfig = function() {
var config = new ConfigParser(path.join(ROOT, 'config.xml')); var config = new ConfigParser(path.join(ROOT, 'config.xml'));
accessRules = config.getAccessRules().filter(function(rule) {
if (rule.indexOf('https://') === 0 || rule == '*') {
return true;
} else {
console.log('Access rules must begin with "https://", the following rule will be ignored: ' + rule);
}
return false;
});
// Apply appxmanifest changes // Apply appxmanifest changes
['package.windows.appxmanifest', 'package.windows80.appxmanifest', 'package.phone.appxmanifest'].forEach( [{ fileName: MANIFEST_WINDOWS, namespacePrefix: 'm2:' },
{ fileName: MANIFEST_WINDOWS8, namespacePrefix: '' },
{ fileName: MANIFEST_WINDOWS10, namespacePrefix: 'uap:' },
{ fileName: MANIFEST_PHONE, namespacePrefix: 'm3:' }].forEach(
function(manifestFile) { function(manifestFile) {
updateManifestFile(config, path.join(ROOT, manifestFile)); // Break out Windows 10-specific functionality because we also need to
// apply UAP versioning to Windows 10 appx-manifests.
var isTargetingWin10 = (manifestFile.fileName === MANIFEST_WINDOWS10);
updateManifestFile(config, path.join(ROOT, manifestFile.fileName), manifestFile.namespacePrefix, isTargetingWin10);
}); });
// Apply jsproj changes if (process.platform === 'win32') {
['CordovaApp.Phone.jsproj', 'CordovaApp.Windows.jsproj', 'CordovaApp.Windows80.jsproj'].forEach( applyUAPVersionToProject(path.join(ROOT, PROJECT_WINDOWS10), getUAPVersions());
function(jsprojFile) { }
updatejsprojFile(config, path.join(ROOT, jsprojFile));
});
copyImages(config); copyImages(config);
}; };
function updatejsprojFile(config, jsProjFilePath) { module.exports.updateBuildConfig = function(buildConfig) {
var defaultLocale = config.defaultLocale() || 'en-US'; var config = new ConfigParser(path.join(ROOT, 'config.xml'));
// if no buildConfig is provided dont do anything
buildConfig = buildConfig || {};
var contents = fs.readFileSync(jsProjFilePath, 'utf-8'); // Merge buildConfig with config
// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) for (var attr in buildConfig) {
if (contents.charCodeAt(0) === 0xFEFF) { config[attr] = buildConfig[attr];
contents = contents.slice(1);
} }
var jsProjXML = new et.ElementTree(et.XML(contents));
var jsProjDefaultLocale = jsProjXML.find('./PropertyGroup/DefaultLanguage');
jsProjDefaultLocale.text = defaultLocale;
fs.writeFileSync(jsProjFilePath, jsProjXML.write({indent: 2}), 'utf-8');
}
function updateManifestFile (config, manifestPath) { var root = new et.Element('Project');
root.set('xmlns', 'http://schemas.microsoft.com/developer/msbuild/2003');
var buildConfigXML = new et.ElementTree(root);
var propertyGroup = new et.Element('PropertyGroup');
var itemGroup = new et.Element('ItemGroup');
// Append PropertyGroup and ItemGroup
buildConfigXML.getroot().append(propertyGroup);
buildConfigXML.getroot().append(itemGroup);
// packageCertificateKeyFile - defaults to 'CordovaApp_TemporaryKey.pfx'
var packageCertificateKeyFile = config.packageCertificateKeyFile || 'CordovaApp_TemporaryKey.pfx';
if (config.packageCertificateKeyFile) {
// Convert packageCertificateKeyFile from absolute to relative path
packageCertificateKeyFile = path.relative(ROOT, packageCertificateKeyFile);
}
var certificatePropertyElement = new et.Element('PackageCertificateKeyFile');
certificatePropertyElement.text = packageCertificateKeyFile;
propertyGroup.append(certificatePropertyElement);
var certificateItemElement = new et.Element('None', { 'Include': packageCertificateKeyFile });
itemGroup.append(certificateItemElement);
// packageThumbprint
if (config.packageThumbprint) {
var thumbprintElement = new et.Element('PackageCertificateThumbprint');
thumbprintElement.text = config.packageThumbprint;
propertyGroup.append(thumbprintElement);
}
// DefaultLanguage - defaults to 'en-US'
var defaultLocale = config.defaultLocale() || 'en-US';
var defaultLocaleElement = new et.Element('DefaultLanguage');
defaultLocaleElement.text = defaultLocale;
propertyGroup.append(defaultLocaleElement);
var buildConfigFileName = buildConfig.buildType === 'release' ?
path.join(ROOT, 'CordovaAppRelease.projitems') :
path.join(ROOT, 'CordovaAppDebug.projitems');
fs.writeFileSync(buildConfigFileName, TEMPLATE + buildConfigXML.write({indent: 2, xml_declaration: false}), 'utf-8');
};
function updateManifestFile (config, manifestPath, namespacePrefix, isTargetingWin10) {
var contents = fs.readFileSync(manifestPath, 'utf-8'); var contents = fs.readFileSync(manifestPath, 'utf-8');
if(contents) { if(contents) {
//Windows is the BOM. Skip the Byte Order Mark. //Windows is the BOM. Skip the Byte Order Mark.
...@@ -79,28 +135,31 @@ function updateManifestFile (config, manifestPath) { ...@@ -79,28 +135,31 @@ function updateManifestFile (config, manifestPath) {
var manifest = new et.ElementTree(et.XML(contents)); var manifest = new et.ElementTree(et.XML(contents));
applyCoreProperties(config, manifest, manifestPath); applyCoreProperties(config, manifest, manifestPath, namespacePrefix, isTargetingWin10);
// sort Capability elements as per CB-5350 Windows8 build fails due to invalid 'Capabilities' definition // sort Capability elements as per CB-5350 Windows8 build fails due to invalid 'Capabilities' definition
sortCapabilities(manifest); sortCapabilities(manifest);
applyAccessRules(config, manifest); applyAccessRules(config, manifest, isTargetingWin10);
applyBackgroundColor(config, manifest); applyBackgroundColor(config, manifest, namespacePrefix);
applyToastCapability(config, manifest, namespacePrefix);
if (isTargetingWin10) {
applyTargetPlatformVersion(config, manifest);
checkForRestrictedCapabilities(config, manifest);
ensureUapPrefixedCapabilities(manifest.find('.//Capabilities'));
}
//Write out manifest //Write out manifest
fs.writeFileSync(manifestPath, manifest.write({indent: 4}), 'utf-8'); fs.writeFileSync(manifestPath, manifest.write({indent: 4}), 'utf-8');
} }
function applyCoreProperties(config, manifest, manifestPath) { function applyCoreProperties(config, manifest, manifestPath, xmlnsPrefix, targetWin10) {
var version = fixConfigVersion(config.version()); var version = fixConfigVersion(config.windows_packageVersion() || config.version());
var name = config.name(); var name = config.name();
var pkgName = config.packageName(); // CB-9450: iOS/Android and Windows Store have an incompatibility here; Windows Store assigns the
// package name that should be used for upload to the store. However, this can't be set for typical
// Cordova apps. So, we have to create a Windows-specific preference here.
var pkgName = config.getPreference('WindowsStoreIdentityName') || config.packageName();
var author = config.author(); var author = config.author();
var startPage = config.startPage();
if (!startPage) {
// If not specified, set default value
// http://cordova.apache.org/docs/en/edge/config_ref_index.md.html#The%20config.xml%20File
startPage = 'index.html';
}
var identityNode = manifest.find('.//Identity'); var identityNode = manifest.find('.//Identity');
if(!identityNode) { if(!identityNode) {
...@@ -114,61 +173,61 @@ function applyCoreProperties(config, manifest, manifestPath) { ...@@ -114,61 +173,61 @@ function applyCoreProperties(config, manifest, manifestPath) {
(identityNode.attrib.Version = version); (identityNode.attrib.Version = version);
} }
// Update publisher id (identity)
if (config.publisherId && identityNode.attrib.Publisher !== config.publisherId) {
identityNode.attrib.Publisher = config.publisherId;
}
// Update name (windows8 has it in the Application[@Id] and Application.VisualElements[@DisplayName]) // Update name (windows8 has it in the Application[@Id] and Application.VisualElements[@DisplayName])
var app = manifest.find('.//Application'); var app = manifest.find('.//Application');
if(!app) { if(!app) {
throw new Error('Invalid manifest file (no <Application> node): ' + manifestPath); throw new Error('Invalid manifest file (no <Application> node): ' + manifestPath);
} }
if (pkgName) {
var baselinePackageName = config.packageName();
if (baselinePackageName) {
// 64 symbols restriction goes from manifest schema definition // 64 symbols restriction goes from manifest schema definition
// http://msdn.microsoft.com/en-us/library/windows/apps/br211415.aspx // http://msdn.microsoft.com/en-us/library/windows/apps/br211415.aspx
var appId = pkgName.length <= 64 ? pkgName : pkgName.substr(0, 64); var appId = baselinePackageName.length <= 64 ? baselinePackageName : baselinePackageName.substr(0, 64);
app.attrib.Id = appId; app.attrib.Id = appId;
} }
app.attrib.StartPage = 'www/' + startPage;
var visualElems = manifest.find('.//VisualElements') || // windows 8.0 applyStartPage(app, config, targetWin10);
manifest.find('.//m2:VisualElements') || // windows 8.1
manifest.find('.//m3:VisualElements'); // windows phone 8.1 var visualElementsName = './/' + xmlnsPrefix + 'VisualElements';
var visualElems = manifest.find(visualElementsName);
if(!visualElems) { if(!visualElems) {
throw new Error('Invalid manifest file (no <VisualElements> node): ' + manifestPath); throw new Error('Invalid manifest file (no <' + xmlnsPrefix + 'VisualElements> node): ' + manifestPath);
} }
if (name) { if (name) {
(visualElems.attrib.DisplayName = name); (visualElems.attrib.DisplayName = name);
} }
// CB-9410: Get a display name and publisher display name. In the Windows Store, certain
// strings which are typically used in Cordova aren't valid for Store ingestion.
// Here, we check for Windows-specific preferences, and if we find it, prefer that over
// the Cordova <widget> areas.
var displayName = config.getPreference('WindowsStoreDisplayName') || name;
var publisherName = config.getPreference('WindowsStorePublisherName') || author;
// Update properties // Update properties
var properties = manifest.find('.//Properties'); var properties = manifest.find('.//Properties');
if (properties && properties.find) { if (properties && properties.find) {
var displayNameElement = properties.find('.//DisplayName'); var displayNameElement = properties.find('.//DisplayName');
if (displayNameElement && name) { if (displayNameElement && displayName) {
displayNameElement.text = name; displayNameElement.text = displayName;
} }
var publisherNameElement = properties.find('.//PublisherDisplayName'); var publisherNameElement = properties.find('.//PublisherDisplayName');
if (publisherNameElement && author) { if (publisherNameElement && publisherName) {
publisherNameElement.text = author; publisherNameElement.text = publisherName;
} }
} }
// Supported orientations // Supported orientations
var isWin80 = manifest.find('.//VisualElements') !== null; var rotationPreferenceName = xmlnsPrefix + 'Rotation';
var isWin81 = manifest.find('.//m2:VisualElements') !== null; var rotationPreferenceRootName = xmlnsPrefix + 'InitialRotationPreference';
var isWP81 = manifest.find('.//m3:VisualElements') !== null;
var rotationPreferenceName, rotationPreferenceRootName;
if(isWin80) {
rotationPreferenceName = 'Rotation';
rotationPreferenceRootName = 'InitialRotationPreference';
} else if(isWin81) {
rotationPreferenceName = 'm2:Rotation';
rotationPreferenceRootName = 'm2:InitialRotationPreference';
} else if(isWP81) {
rotationPreferenceName = 'm3:Rotation';
rotationPreferenceRootName = 'm3:InitialRotationPreference';
}
var orientation = config.getPreference('Orientation'); var orientation = config.getPreference('Orientation');
var rotationPreferenceRoot; var rotationPreferenceRoot;
...@@ -212,6 +271,46 @@ function applyCoreProperties(config, manifest, manifestPath) { ...@@ -212,6 +271,46 @@ function applyCoreProperties(config, manifest, manifestPath) {
} }
} }
function applyStartPage(appNode, config, targetingWin10) {
var startPage = config.startPage();
if (!startPage) {
// If not specified, set default value
// http://cordova.apache.org/docs/en/edge/config_ref_index.md.html#The%20config.xml%20File
startPage = 'index.html';
}
var uriPrefix = '';
if (targetingWin10) {
// for Win10, we respect config options such as WindowsDefaultUriPrefix and default to
// ms-appx-web:// as the homepage. Set those here.
// Only add a URI prefix if the start page doesn't specify a URI scheme
if (!(/^[\w-]+?\:\/\//i).test(startPage)) {
uriPrefix = config.getPreference('WindowsDefaultUriPrefix');
if (!uriPrefix) {
uriPrefix = 'ms-appx-web://';
}
else if (/^ms\-appx\:\/\/$/i.test(uriPrefix)) {
// Explicitly ignore the ms-appx:// scheme because it doesn't validate
// in the Windows 10 build schema (treat it as the root).
uriPrefix = '';
}
}
}
var startPagePrefix = 'www/';
if ((uriPrefix && uriPrefix.toLowerCase().substring(0, 4) === 'http') ||
startPage.toLowerCase().substring(0, 4) === 'http') {
startPagePrefix = '';
}
else if (uriPrefix.toLowerCase().substring(0, 7) === 'ms-appx') {
uriPrefix += '/'; // add a 3rd trailing forward slash for correct area resolution
}
appNode.attrib.StartPage = uriPrefix + startPagePrefix + startPage;
}
// Adjust version number as per CB-5337 Windows8 build fails due to invalid app version // Adjust version number as per CB-5337 Windows8 build fails due to invalid app version
function fixConfigVersion (version) { function fixConfigVersion (version) {
if(version && version.match(/\.\d/g)) { if(version && version.match(/\.\d/g)) {
...@@ -223,29 +322,104 @@ function fixConfigVersion (version) { ...@@ -223,29 +322,104 @@ function fixConfigVersion (version) {
return version; return version;
} }
function applyAccessRules (config, manifest) { function applyAccessRules (config, manifest, isTargetingWin10) {
// Updates WhiteListing rules // Updates WhiteListing rules
//<ApplicationContentUriRules> //<ApplicationContentUriRules>
// <Rule Match="https://www.example.com" Type="include"/> // <Rule Match="https://www.example.com" Type="include"/>
//</ApplicationContentUriRules> //</ApplicationContentUriRules>
var AppContentUriRulesElementName = 'ApplicationContentUriRules',
RuleElementName = 'Rule';
if (isTargetingWin10) {
return applyNavigationWhitelist(config, manifest);
}
var accessRules = config.getAccessRules().filter(function(rule) {
// https:// rules are always good, * rules are always good
if (rule.indexOf('https://') === 0 || rule === '*') {
return true;
} else {
console.warn('Access rules must begin with "https://", the following rule will be ignored: ' + rule);
}
return false;
});
// If * is specified, emit no access rules.
if (accessRules.indexOf('*') > -1) {
accessRules = [];
}
createApplicationContentUriRules(manifest, AppContentUriRulesElementName, RuleElementName, accessRules, { Type: 'include' });
}
/**
* Windows 10-based whitelist-plugin-compatible support for the enhanced navigation whitelist.
* Allows WinRT access to origins specified by <allow-navigation href="origin" /> elements.
*/
function applyNavigationWhitelist(config, manifest) {
var AppContentUriRulesElementName = 'uap:ApplicationContentUriRules';
var RuleElementName = 'uap:Rule';
var UriSchemeTest = /^(?:https?|ms-appx-web):\/\//i;
var whitelistRules = config.getNavigationWhitelistRules().filter(function(rule) {
if (UriSchemeTest.test(rule)) {
return true;
} else {
console.warn('The following navigation rule had an invalid URI scheme and is ignored: "' + rule + '".');
}
return false;
});
var defaultPrefix = config.getPreference('WindowsDefaultUriPrefix');
if ('ms-appx://' !== defaultPrefix) {
var hasMsAppxWeb = whitelistRules.some(function(rule) {
return /^ms-appx-web:\/\/\/$/i.test(rule);
});
if (!hasMsAppxWeb) {
whitelistRules.push('ms-appx-web:///');
}
}
createApplicationContentUriRules(manifest, AppContentUriRulesElementName, RuleElementName, whitelistRules, {
Type: 'include',
WindowsRuntimeAccess: 'all'
});
}
/**
* Private function used by applyNavigationWhitelist and applyAccessRules
* which creates the corresponding section in the app manifest.
* @param manifest {et.ElementTree} The manifest document.
* @param acurElementName {string} The name of the AccessContentUriRules element, including prefix if applicable.
* @param ruleElementName {string} The name of the Rule element, including prefix if applicable.
* @param rulesOrigins {string[]} The origins that will be permitted.
* @param commonAttributes {Object} Property bag of additional attributes that should be applied to every rule.
*/
function createApplicationContentUriRules(manifest, acurElementName, ruleElementName, rulesOrigins, commonAttributes) {
var appUriRulesRoot = manifest.find('.//Application'), var appUriRulesRoot = manifest.find('.//Application'),
appUriRules = appUriRulesRoot.find('.//ApplicationContentUriRules'); appUriRules = appUriRulesRoot.find(acurElementName);
if (appUriRules !== null) { if (appUriRules !== null) {
appUriRulesRoot.remove(null, appUriRules); appUriRulesRoot.remove(null, appUriRules);
} }
// rules are not defined or allow any
if (accessRules.length === 0 || accessRules.indexOf('*') > -1) { // No rules defined
if (rulesOrigins.length === 0) {
return; return;
} }
appUriRules = et.Element('ApplicationContentUriRules'); appUriRules = et.Element(acurElementName);
appUriRulesRoot.append(appUriRules); appUriRulesRoot.append(appUriRules);
accessRules.forEach(function(rule) { rulesOrigins.forEach(function(rule) {
var el = et.Element('Rule'); var el = et.Element(ruleElementName);
el.attrib.Match = rule; el.attrib.Match = rule;
el.attrib.Type = 'include';
var attributes = Object.keys(commonAttributes);
attributes.forEach(function(attributeName) {
el.attrib[attributeName] = commonAttributes[attributeName];
});
appUriRules.append(el); appUriRules.append(el);
}); });
} }
...@@ -274,6 +448,20 @@ function sortCapabilities(manifest) { ...@@ -274,6 +448,20 @@ function sortCapabilities(manifest) {
}); });
} }
function checkForRestrictedCapabilities(config, manifest) {
var hasRemoteUris = checkForRemoteModeUris(config);
if (hasRemoteUris) {
var capabilitiesRoot = manifest.find('.//Capabilities');
var badCaps = checkForRestrictedRemoteCapabilityDeclarations(capabilitiesRoot);
if (badCaps) {
console.warn('The following Capabilities were declared and are restricted:');
console.warn(' ' + badCaps.join(','));
console.warn('You will be unable to on-board your app to the public Windows Store with');
console.warn(' these capabilities and access rules permitting access to remote URIs.');
}
}
}
function copyImages(config) { function copyImages(config) {
var platformRoot = ROOT; var platformRoot = ROOT;
// TODO find the way to detect whether command was triggered by CLI or not // TODO find the way to detect whether command was triggered by CLI or not
...@@ -311,7 +499,6 @@ function copyImages(config) { ...@@ -311,7 +499,6 @@ function copyImages(config) {
} }
copyImage(path.join(srcDir, img), destFileName+scale+destExt); copyImage(path.join(srcDir, img), destFileName+scale+destExt);
}); });
} }
// Platform default images // Platform default images
...@@ -322,9 +509,11 @@ function copyImages(config) { ...@@ -322,9 +509,11 @@ function copyImages(config) {
{dest: 'SplashScreen.scale-100.png', width: 620, height: 300}, {dest: 'SplashScreen.scale-100.png', width: 620, height: 300},
// scaled images are specified here for backward compatibility only so we can find them by size // scaled images are specified here for backward compatibility only so we can find them by size
{dest: 'StoreLogo.scale-240.png', width: 120, height: 120}, {dest: 'StoreLogo.scale-240.png', width: 120, height: 120},
{dest: 'Square44x44Logo.scale-100.png', width: 44, height: 44},
{dest: 'Square44x44Logo.scale-240.png', width: 106, height: 106}, {dest: 'Square44x44Logo.scale-240.png', width: 106, height: 106},
{dest: 'Square71x71Logo.scale-240.png', width: 170, height: 170},
{dest: 'Square70x70Logo.scale-100.png', width: 70, height: 70}, {dest: 'Square70x70Logo.scale-100.png', width: 70, height: 70},
{dest: 'Square71x71Logo.scale-100.png', width: 71, height: 71},
{dest: 'Square71x71Logo.scale-240.png', width: 170, height: 170},
{dest: 'Square150x150Logo.scale-240.png', width: 360, height: 360}, {dest: 'Square150x150Logo.scale-240.png', width: 360, height: 360},
{dest: 'Square310x310Logo.scale-100.png', width: 310, height: 310}, {dest: 'Square310x310Logo.scale-100.png', width: 310, height: 310},
{dest: 'Wide310x150Logo.scale-100.png', width: 310, height: 150}, {dest: 'Wide310x150Logo.scale-100.png', width: 310, height: 150},
...@@ -367,7 +556,7 @@ function copyImages(config) { ...@@ -367,7 +556,7 @@ function copyImages(config) {
}); });
} }
function applyBackgroundColor (config, manifest) { function applyBackgroundColor (config, manifest, xmlnsPrefix) {
var visualElems =null; var visualElems =null;
function refineColor(color) { function refineColor(color) {
...@@ -385,18 +574,212 @@ function applyBackgroundColor (config, manifest) { ...@@ -385,18 +574,212 @@ function applyBackgroundColor (config, manifest) {
// background color // background color
var bgColor = config.getPreference('BackgroundColor'); var bgColor = config.getPreference('BackgroundColor');
if (bgColor) { if (bgColor) {
visualElems = manifest.find('.//VisualElements') || // windows 8.0 var visualElementsName = './/' + xmlnsPrefix + 'VisualElements';
manifest.find('.//m2:VisualElements') || // windows 8.1 visualElems = manifest.find(visualElementsName);
manifest.find('.//m3:VisualElements'); // windows phone 8.1
visualElems.attrib.BackgroundColor = refineColor(bgColor); visualElems.attrib.BackgroundColor = refineColor(bgColor);
} }
// Splash Screen background color // Splash Screen background color
bgColor = config.getPreference('SplashScreenBackgroundColor'); bgColor = config.getPreference('SplashScreenBackgroundColor');
if (bgColor) { if (bgColor) {
visualElems = manifest.find('.//SplashScreen') || // windows 8.0 var splashScreenElementsName = './/' + xmlnsPrefix + 'SplashScreen';
manifest.find('.//m2:SplashScreen') || // windows 8.1 visualElems = manifest.find(splashScreenElementsName);
manifest.find('.//m3:SplashScreen'); // windows phone 8.1
visualElems.attrib.BackgroundColor = refineColor(bgColor); visualElems.attrib.BackgroundColor = refineColor(bgColor);
} }
} }
function applyUAPVersionToProject(projectFilePath, uapVersionInfo) {
// No uapVersionInfo means that there is no UAP SDKs installed and there is nothing to do for us
if (!uapVersionInfo) return;
var fileContents = fs.readFileSync(projectFilePath).toString().trim();
var xml = et.parse(fileContents);
var tpv = xml.find('./PropertyGroup/TargetPlatformVersion');
var tpmv = xml.find('./PropertyGroup/TargetPlatformMinVersion');
tpv.text = uapVersionInfo.targetUAPVersion.toString();
tpmv.text = uapVersionInfo.minUAPVersion.toString();
fs.writeFileSync(projectFilePath, xml.write({ indent: 4 }), {});
}
function applyTargetPlatformVersion(config, manifest) {
var dependencies = manifest.find('./Dependencies');
while (dependencies.len() > 0) {
dependencies.delItem(0);
}
var uapVersionSet = getAllMinMaxUAPVersions(config);
var platformNames = Object.keys(uapVersionSet);
for (var i = 0; i < platformNames.length; i++) {
var curTargetPlatformName = platformNames[i];
var curTargetPlatformInfo = uapVersionSet[curTargetPlatformName];
var elem = subElement(dependencies, 'TargetDeviceFamily');
elem.set('Name', curTargetPlatformName);
elem.set('MinVersion', curTargetPlatformInfo.MinVersion.toString());
elem.set('MaxVersionTested', curTargetPlatformInfo.MaxVersionTested.toString());
}
}
// returns {minUAPVersion: Version, targetUAPVersion: Version} | false
function getUAPVersions() {
var baselineVersions = MSBuildTools.getAvailableUAPVersions();
if (!baselineVersions || baselineVersions.length === 0) {
return false;
}
baselineVersions.sort(Version.comparer);
return {
minUAPVersion: baselineVersions[0],
targetUAPVersion: baselineVersions[baselineVersions.length - 1]
};
}
/**
* Gets min/max UAP versions from the configuration. If no version preferences are
* in the configuration file, this will provide Windows.Universal at BASE_UAP_VERSION for both min and max.
* This will always return a rational object or will fail; for example, if a platform expects
* a higher min-version than max-version, it will raise the max version to the min version.
*
* @param config {ConfigParser} The configuration parser
* @return An object in the shape of: { 'Windows.Mobile': {'MinVersion': Version, 'MaxVersion': Version } } (where Version is a Version object)
* @exception {RangeError} Thrown if a Version string is badly formed.
*/
function getAllMinMaxUAPVersions(config) {
var uapVersionPreferenceTest = /(Microsoft.+?|Windows.+?)\-(MinVersion|MaxVersionTested)/i;
var platformBag = Object.create(null);
var preferenceList = config.getMatchingPreferences(uapVersionPreferenceTest);
preferenceList.forEach(function(verPref) {
var matches = uapVersionPreferenceTest.exec(verPref.name);
// 'matches' should look like: ['Windows.Universal-MinVersion', 'Windows.Universal', 'MinVersion']
var platformName = matches[1];
var versionPropertyName = matches[2];
var platformVersionSet = platformBag[platformName];
if (typeof platformVersionSet === 'undefined') {
platformVersionSet = { };
platformBag[platformName] = platformVersionSet;
}
var versionTest = Version.tryParse(verPref.value);
if (!versionTest) {
throw new RangeError('Could not comprehend a valid version from the string "' + verPref.value + '" of platform-boundary "' + verPref.name + '".');
}
platformVersionSet[versionPropertyName] = versionTest;
});
for (var platformName in platformBag) {
// Go through each and make sure there are min/max set
var versionPref = platformBag[platformName];
if (!versionPref.MaxVersionTested && !!versionPref.MinVersion) { // min is set, but max is not
versionPref.MaxVersionTested = versionPref.MinVersion;
}
else if (!versionPref.MinVersion && !!versionPref.MaxVersionTested) { // max is set, min is not
versionPref.MinVersion = versionPref.MaxVersionTested;
}
else if (!versionPref.MinVersion && !versionPref.MaxVersionTested) { // neither are set
versionPref.MinVersion = BASE_UAP_VERSION;
versionPref.MaxVersionTested = BASE_UAP_VERSION;
}
else { // both are set
if (versionPref.MinVersion.gt(versionPref.MaxVersionTested)) {
versionPref.MaxVersionTested = versionPref.MinVersion;
}
}
}
if (Object.keys(platformBag).length === 0) {
platformBag['Windows.Universal'] = { MinVersion: BASE_UAP_VERSION, MaxVersionTested: BASE_UAP_VERSION };
}
return platformBag;
}
/**
* Checks to see whether access rules or
* @param config {ConfigParser} The configuration parser
* @return {boolean} True if the config specifies remote URIs for access or start; false otherwise.
*/
function checkForRemoteModeUris(config) {
var accessRules = config.getNavigationWhitelistRules();
var startPage = config.startPage();
var test = /(https?|ms-appx-web):\/\//i;
var hasRemoteUri = test.test(startPage);
hasRemoteUri = hasRemoteUri || accessRules.some(function(rule) {
return test.test(rule);
});
return hasRemoteUri;
}
/**
* Checks for capabilities which are Restricted in Windows 10 UAP.
* @param appxManifestCapabilitiesElement {ElementTree.Element} The appx manifest element for <capabilities>
* @return {string[]|false} An array of restricted capability names, or false.
*/
function checkForRestrictedRemoteCapabilityDeclarations(appxManifestCapabilitiesElement) {
if (!appxManifestCapabilitiesElement)
return false;
var hasRestrictedCapabilities = false;
var foundRestrictedCapabilities = [];
var children = appxManifestCapabilitiesElement.getchildren();
var declaredCapabilities = children.map(function(el) {
return el.attrib.Name;
});
UAP_RESTRICTED_CAPS.forEach(function(cap) {
if (declaredCapabilities.indexOf(cap) > -1) {
hasRestrictedCapabilities = true;
foundRestrictedCapabilities.push(cap);
}
});
return hasRestrictedCapabilities ? foundRestrictedCapabilities : hasRestrictedCapabilities;
}
/**
* Checks for capabilities which require the uap: prefix in Windows 10.
* @param appxManifestCapabilitiesElement {ElementTree.Element} The appx manifest element for <capabilities>
*/
function ensureUapPrefixedCapabilities(appxManifestCapabilitiesElement) {
var children = appxManifestCapabilitiesElement.getchildren();
var declaredCapabilities = children.map(function(el) {
return { name: el.attrib.Name, element: el, elementName: el.tag };
});
declaredCapabilities.forEach(function(cap) {
if (CAPS_NEEDING_UAPNS.indexOf(cap.name) > -1) {
if (cap.elementName.indexOf('uap:') === -1) {
cap.elementName = 'uap:' + cap.elementName;
cap.element.tag = cap.elementName;
}
}
});
}
/**
* Applies the ToastCapable attribute to the VisualElements tag
* @param config {ConfigParser} The configuration reader
* @param manifest {et.ElementTree} The manifest file
* @namespacePrefix {String} The XML namespace for the VisualElements tag, in the form 'm2:'
*/
function applyToastCapability(config, manifest, namespacePrefix) {
var isToastCapable = config.getPreference('WindowsToastCapable');
isToastCapable = (isToastCapable && isToastCapable.toString().toLowerCase() === 'true');
var visualElementsName = './/' + namespacePrefix + 'VisualElements';
var visualElems = manifest.find(visualElementsName);
if (isToastCapable) {
visualElems.attrib.ToastCapable = 'true';
}
else {
delete visualElems.attrib.ToastCapable;
}
}
...@@ -22,8 +22,8 @@ var Q = require('q'), ...@@ -22,8 +22,8 @@ var Q = require('q'),
path = require('path'), path = require('path'),
build = require('./build'), build = require('./build'),
utils = require('./utils'), utils = require('./utils'),
ConfigParser = require('./ConfigParser'), packages = require('./package'),
packages = require('./package'); execSync = require('child_process').execSync;
var ROOT = path.join(__dirname, '..', '..'); var ROOT = path.join(__dirname, '..', '..');
...@@ -32,10 +32,15 @@ module.exports.run = function (argv) { ...@@ -32,10 +32,15 @@ module.exports.run = function (argv) {
return Q.reject('Could not find project at ' + ROOT); return Q.reject('Could not find project at ' + ROOT);
} }
// parse args // Check if ran from admin prompt and fail quickly if CLI has administrative permissions
// http://stackoverflow.com/a/11995662/64949
if (ranWithElevatedPermissions())
return Q.reject('Can not run this platform with administrative permissions. Please run from a non-admin prompt.');
// parse arg
var args = nopt({'debug': Boolean, 'release': Boolean, 'nobuild': Boolean, var args = nopt({'debug': Boolean, 'release': Boolean, 'nobuild': Boolean,
'device': Boolean, 'emulator': Boolean, 'target': String, 'archs': String, 'device': Boolean, 'emulator': Boolean, 'target': String, 'archs': String,
'phone': Boolean, 'win': Boolean}, {'r' : '--release'}, argv); 'phone': Boolean, 'win': Boolean, 'appx': String, 'win10tools': Boolean }, {'r' : '--release'}, argv);
// Validate args // Validate args
if (args.debug && args.release) { if (args.debug && args.release) {
...@@ -51,30 +56,62 @@ module.exports.run = function (argv) { ...@@ -51,30 +56,62 @@ module.exports.run = function (argv) {
// Get build/deploy options // Get build/deploy options
var buildType = args.release ? 'release' : 'debug', var buildType = args.release ? 'release' : 'debug',
buildArchs = args.archs ? args.archs.split(' ') : ['anycpu'], buildArchs = args.archs ? args.archs.split(' ') : ['anycpu'],
projectType = args.phone ? 'phone' : 'windows', deployTarget = args.target ? args.target : (args.emulator ? 'emulator' : 'device');
deployTarget = args.target ? args.target : args.device ? 'device' : 'emulator';
var buildTargets = build.getBuildTargets(args.win, args.phone, args.appx);
if (!buildTargets || buildTargets.lenght <= 0) {
return Q.reject('Unable to determine deploy target.');
}
// for win switch we should correctly handle 8.0 and 8.1 version as per configuration // we deploy the first build target so we use buildTargets[0] to determine
if (projectType == 'windows' && getWindowsTargetVersion() == '8.0') { // what project type we should deploy
projectType = 'windows80'; var projectType = projFileToType(buildTargets[0]);
if (projectType === 'windows80' && argv.indexOf('--bundle') > -1) {
// Don't enable bundling for Windows 8.
// Assumes the commander only enters the --bundle param once
argv.splice(argv.indexOf('--bundle'), 1);
} }
// if --nobuild isn't specified then build app first // if --nobuild isn't specified then build app first
var buildPackages = args.nobuild ? Q() : build.run(argv); var buildPackages = args.nobuild ? packages.getPackage(projectType, buildType, buildArchs) : build.run(argv);
return buildPackages.then(function () { // buildPackages also deploys bundles
return packages.getPackage(projectType, buildType, buildArchs[0]); return buildPackages.then(function(pkg) {
}).then(function(pkg) { console.log('\nDeploying ' + pkg.type + ' package to ' + deployTarget + ':\n' + pkg.appx);
console.log('\nDeploying ' + pkg.type + ' package to ' + deployTarget + ':\n' + pkg.file); switch (pkg.type) {
return pkg.type == 'phone' ? case 'phone':
packages.deployToPhone(pkg.file, deployTarget) : return packages.deployToPhone(pkg, deployTarget, args.win10tools).catch(function(e) {
packages.deployToDesktop(pkg.file, deployTarget); if (args.target || args.emulator || args.device) {
throw e; // Explicit target, carry on
}
// 'device' was inferred initially, because no target was specified
return packages.deployToPhone(pkg, 'emulator', args.win10tools);
});
case 'windows10':
if (args.phone) {
// Win10 emulator launch is not currently supported, always force device
if (args.emulator || args.target === 'emulator') {
console.warn('Windows 10 Phone emulator is currently not supported.');
console.warn('If you want to deploy to emulator, please use Visual Studio instead.');
console.warn('Attempting to deploy to device...');
}
return packages.deployToPhone(pkg, deployTarget, true);
}
else {
return packages.deployToDesktop(pkg, deployTarget, projectType);
}
break;
default: // 'windows'
return packages.deployToDesktop(pkg, deployTarget, projectType);
}
}); });
}; };
module.exports.help = function () { module.exports.help = function () {
console.log('\nUsage: run [ --device | --emulator | --target=<id> ] [ --debug | --release | --nobuild ]'); console.log('\nUsage: run [ --device | --emulator | --target=<id> ] [ --debug | --release | --nobuild ]');
console.log(' [ --x86 | --x64 | --arm ] [--phone | --win]'); console.log(' [ --x86 | --x64 | --arm | --archs="list" ] [--bundle] [--phone | --win]');
console.log(' --device : Deploys and runs the project on the connected device.'); console.log(' --device : Deploys and runs the project on the connected device.');
console.log(' --emulator : Deploys and runs the project on an emulator.'); console.log(' --emulator : Deploys and runs the project on an emulator.');
console.log(' --target=<id> : Deploys and runs the project on the specified target.'); console.log(' --target=<id> : Deploys and runs the project on the specified target.');
...@@ -82,9 +119,17 @@ module.exports.help = function () { ...@@ -82,9 +119,17 @@ module.exports.help = function () {
console.log(' --release : Builds project in release mode.'); console.log(' --release : Builds project in release mode.');
console.log(' --nobuild : Uses pre-built package, or errors if project is not built.'); console.log(' --nobuild : Uses pre-built package, or errors if project is not built.');
console.log(' --archs : Specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).'); console.log(' --archs : Specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).');
console.log(' Separate multiple choices with a space and, if choosing');
console.log(' multiple choices, enclose in quotes (").');
console.log(' --bundle : Generates an .appxbundle. Not valid if anycpu AND chip-specific');
console.log(' architectures are used.');
console.log(' --phone, --win'); console.log(' --phone, --win');
console.log(' : Specifies project type to deploy'); console.log(' : Specifies project type to deploy');
console.log(''); console.log(' --appx=<8.1-win|8.1-phone|uap>');
console.log(' : Overrides windows-target-version to build Windows 8.1, ');
console.log(' Windows Phone 8.1, or Windows 10.');
console.log(' --win10tools : Uses Windows 10 deployment tools (used for a Windows 8.1 app when');
console.log(' being deployed to a Windows 10 device)');
console.log('Examples:'); console.log('Examples:');
console.log(' run'); console.log(' run');
console.log(' run --emulator'); console.log(' run --emulator');
...@@ -92,21 +137,35 @@ module.exports.help = function () { ...@@ -92,21 +137,35 @@ module.exports.help = function () {
console.log(' run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710'); console.log(' run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710');
console.log(' run --device --release'); console.log(' run --device --release');
console.log(' run --emulator --debug'); console.log(' run --emulator --debug');
console.log(' run --archs="x64 x86 arm" --no-bundle');
console.log(' run --device --appx=phone-8.1');
console.log(' run --device --archs="x64 x86 arm"');
console.log(''); console.log('');
process.exit(0); process.exit(0);
}; };
// Retrieves project type for the project file specified.
// @param {String} projFile Project file, for example 'CordovaApp.Windows10.jsproj'
// @returns {String} Proejct type, for example 'windows10'
function projFileToType(projFile)
{
return projFile.replace(/CordovaApp|jsproj|\./gi, '').toLowerCase();
}
function getWindowsTargetVersion() { /**
var config = new ConfigParser(path.join(ROOT, 'config.xml')); * Checks if current process is an with administrative permissions (e.g. from
var windowsTargetVersion = config.getPreference('windows-target-version'); * elevated command prompt).
switch(windowsTargetVersion) { *
case '8': * @return {Boolean} true if elevated permissions detected, otherwise false
case '8.0': */
return '8.0'; function ranWithElevatedPermissions () {
case '8.1': try {
return '8.1'; // Check if ran from admin prompt and fail quickly if CLI has administrative permissions
default: // http://stackoverflow.com/a/11995662/64949
throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion); execSync('net session', {'stdio': 'ignore'});
return true;
} catch (e) {
return false;
} }
} }
...@@ -17,20 +17,21 @@ ...@@ -17,20 +17,21 @@
under the License. under the License.
*/ */
var devices = require('./package'), var deploy = require('./deployment'),
args = process.argv.slice(2); args = process.argv.slice(2);
// help/usage function // help/usage function
function help() { function help() {
console.log(''); console.log('');
console.log('Usage: node target-list.js [ --emulators | --devices | --started_emulators | --all ]'); console.log('Usage: node target-list.js [--win10] [ --emulators | --devices | --started_emulators | --all ]');
console.log(' --win10 : Chooses to list Windows 10 devices (Windows 8.1 is default).');
console.log(' --emulators : List the possible target emulators availible.'); console.log(' --emulators : List the possible target emulators availible.');
console.log(' --devices : List the possible target devices availible. *NOT IMPLEMENTED YET*'); console.log(' --devices : List the possible target devices availible.');
console.log(' --started_emulators : List any started emulators availible. *NOT IMPLEMENTED YET*'); console.log(' --started_emulators : List any started emulators availible. *NOT IMPLEMENTED YET*');
console.log(' --all : List all available devices'); console.log(' --all : List all available devices');
console.log('examples:'); console.log('examples:');
console.log(' node target-list.js --emulators'); console.log(' node target-list.js --emulators');
console.log(' node target-list.js --devices'); console.log(' node target-list.js --win10 --devices');
console.log(' node target-list.js --started_emulators'); console.log(' node target-list.js --started_emulators');
console.log(' node target-list.js --all'); console.log(' node target-list.js --all');
console.log(''); console.log('');
...@@ -40,10 +41,42 @@ function help() { ...@@ -40,10 +41,42 @@ function help() {
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[0]) > -1) { if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[0]) > -1) {
help(); help();
} else { } else {
devices.listDevices()
.then(function (deviceList) { var version = '8.1';
if (args.indexOf('--win10') >= 0) {
version = '10.0';
}
var onlyDevices = false;
if (args.indexOf('--devices') >= 0) {
onlyDevices = true;
}
var onlyEmulators = false;
if (args.indexOf('--emulators') >= 0) {
onlyEmulators = true;
}
if (onlyDevices && onlyEmulators) {
console.warn('Error: Cannot specify both --emulators and --devices');
help();
return;
}
var deploymentTool = deploy.getDeploymentTool(version);
deploymentTool.enumerateDevices().then(function (deviceList) {
if (onlyDevices || onlyEmulators) {
deviceList = deviceList.filter(function(device) {
return (onlyDevices && device.type === 'device') || (onlyEmulators && device.type === 'emulator');
});
}
deviceList.forEach(function (device) { deviceList.forEach(function (device) {
console.log(device); console.log(device.toString());
}); });
if (deviceList.length === 0) {
console.log('No devices found matching the specified criteria.');
}
}); });
} }
\ No newline at end of file
...@@ -19,11 +19,12 @@ ...@@ -19,11 +19,12 @@
/* jshint sub:true */ /* jshint sub:true */
var Q = require('Q'), var Q = require('q'),
fs = require('fs'), fs = require('fs'),
path = require('path'), path = require('path'),
exec = require('./exec'), exec = require('./exec'),
spawn = require('./spawn'); spawn = require('./spawn'),
deploy = require('./deployment');
// returns full path to msbuild tools required to build the project and tools version // returns full path to msbuild tools required to build the project and tools version
module.exports.getMSBuildTools = function () { module.exports.getMSBuildTools = function () {
...@@ -57,7 +58,6 @@ module.exports.getAppStoreUtils = function () { ...@@ -57,7 +58,6 @@ module.exports.getAppStoreUtils = function () {
if (!fs.existsSync (appStoreUtils)) { if (!fs.existsSync (appStoreUtils)) {
return Q.reject('Can\'t unblock AppStoreUtils script'); return Q.reject('Can\'t unblock AppStoreUtils script');
} }
//console.log("Removing execution restrictions from AppStoreUtils...");
return spawn('powershell', ['Unblock-File', module.exports.quote(appStoreUtils)]).then(function () { return spawn('powershell', ['Unblock-File', module.exports.quote(appStoreUtils)]).then(function () {
return Q.resolve(appStoreUtils); return Q.resolve(appStoreUtils);
}).fail(function (err) { }).fail(function (err) {
...@@ -66,15 +66,15 @@ module.exports.getAppStoreUtils = function () { ...@@ -66,15 +66,15 @@ module.exports.getAppStoreUtils = function () {
}; };
// returns path to AppDeploy util from Windows Phone 8.1 SDK // returns path to AppDeploy util from Windows Phone 8.1 SDK
module.exports.getAppDeployUtils = function () { module.exports.getAppDeployUtils = function (targetWin10) {
var appDeployUtils = path.join((process.env['ProgramFiles(x86)'] || process.env['ProgramFiles']), var version = targetWin10 ? '10.0' : '8.1';
'Microsoft SDKs', 'Windows Phone', 'v8.1', 'Tools', 'AppDeploy', 'AppDeployCmd.exe'); var tool = deploy.getDeploymentTool(version);
// Check if AppDeployCmd is exists
if (!fs.existsSync(appDeployUtils)) { if (!tool.isAvailable()) {
console.warn('WARNING: AppDeploy tool (AppDeployCmd.exe) didn\'t found. Assume that it\'s in %PATH%'); return Q.reject('App deployment utilities: "' + tool.path + '", not found. Ensure the Windows SDK is installed.');
return Q.resolve('AppDeployCmd');
} }
return Q.resolve(appDeployUtils);
return Q.resolve(tool);
}; };
// checks to see if a .jsproj file exists in the project root // checks to see if a .jsproj file exists in the project root
......
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
var log = require('./lib/log'),
Q = require('q'),
args = process.argv;
// Usage support for when args are given
Q().then(function() {
var argsToPass = [];
if (args.length > 2) {
argsToPass = args.slice(2);
}
log.run(argsToPass);
}, function(err) {
console.error('ERROR: ' + err);
process.exit(2);
});
...@@ -13,7 +13,14 @@ ...@@ -13,7 +13,14 @@
:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY :: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
:: KIND, either express or implied. See the License for the :: KIND, either express or implied. See the License for the
:: specific language governing permissions and limitations :: specific language governing permissions and limitations
:: under the License :: under the License.
@ECHO OFF @ECHO OFF
ECHO Sorry, logging is not supported for Windows. 1>&2 SET script_path="%~dp0log"
EXIT /B 1 IF EXIST %script_path% (
\ No newline at end of file node %script_path% %*
) ELSE (
ECHO.
ECHO ERROR: Could not find 'log' script in 'cordova' folder, aborting...>&2
EXIT /B 1
)
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
var fs = require("fs"),
sys = require("sys"),
path = require("path"),
xml = fs.cat(path.join(__dirname, "test.xml")),
sax = require("../lib/sax"),
strict = sax.parser(true),
loose = sax.parser(false, {trim:true}),
inspector = function (ev) { return function (data) {
// sys.error("");
// sys.error(ev+": "+sys.inspect(data));
// for (var i in data) sys.error(i+ " "+sys.inspect(data[i]));
// sys.error(this.line+":"+this.column);
}};
xml.addCallback(function (xml) {
// strict.write(xml);
sax.EVENTS.forEach(function (ev) {
loose["on"+ev] = inspector(ev);
});
loose.onend = function () {
// sys.error("end");
// sys.error(sys.inspect(loose));
};
// do this one char at a time to verify that it works.
// (function () {
// if (xml) {
// loose.write(xml.substr(0,1000));
// xml = xml.substr(1000);
// process.nextTick(arguments.callee);
// } else loose.close();
// })();
for (var i = 0; i < 1000; i ++) {
loose.write(xml);
loose.close();
}
});
// pull out /GeneralSearchResponse/categories/category/items/product tags
// the rest we don't care about.
var sax = require("../lib/sax.js")
var fs = require("fs")
var path = require("path")
var xmlFile = path.resolve(__dirname, "shopping.xml")
var util = require("util")
var http = require("http")
fs.readFile(xmlFile, function (er, d) {
http.createServer(function (req, res) {
if (er) throw er
var xmlstr = d.toString("utf8")
var parser = sax.parser(true)
var products = []
var product = null
var currentTag = null
parser.onclosetag = function (tagName) {
if (tagName === "product") {
products.push(product)
currentTag = product = null
return
}
if (currentTag && currentTag.parent) {
var p = currentTag.parent
delete currentTag.parent
currentTag = p
}
}
parser.onopentag = function (tag) {
if (tag.name !== "product" && !product) return
if (tag.name === "product") {
product = tag
}
tag.parent = currentTag
tag.children = []
tag.parent && tag.parent.children.push(tag)
currentTag = tag
}
parser.ontext = function (text) {
if (currentTag) currentTag.children.push(text)
}
parser.onend = function () {
var out = util.inspect(products, false, 3, true)
res.writeHead(200, {"content-type":"application/json"})
res.end("{\"ok\":true}")
// res.end(JSON.stringify(products))
}
parser.write(xmlstr).end()
}).listen(1337)
})
require("http").createServer(function (req, res) {
res.writeHead(200, {"content-type":"application/json"})
res.end(JSON.stringify({ok: true}))
}).listen(1337)
<root>
something<else> blerm <slurm
attrib =
"blorg" ></else><!-- COMMENT!
--><![CDATA[processing...]]> <selfclosing tag="blr>&quot;"/> a bit down here</root>
var sax = require("../lib/sax")
, printer = sax.createStream(false, {lowercasetags:true, trim:true})
, fs = require("fs")
function entity (str) {
return str.replace('"', '&quot;')
}
printer.tabstop = 2
printer.level = 0
printer.indent = function () {
print("\n")
for (var i = this.level; i > 0; i --) {
for (var j = this.tabstop; j > 0; j --) {
print(" ")
}
}
}
printer.on("opentag", function (tag) {
this.indent()
this.level ++
print("<"+tag.name)
for (var i in tag.attributes) {
print(" "+i+"=\""+entity(tag.attributes[i])+"\"")
}
print(">")
})
printer.on("text", ontext)
printer.on("doctype", ontext)
function ontext (text) {
this.indent()
print(text)
}
printer.on("closetag", function (tag) {
this.level --
this.indent()
print("</"+tag+">")
})
printer.on("cdata", function (data) {
this.indent()
print("<![CDATA["+data+"]]>")
})
printer.on("comment", function (comment) {
this.indent()
print("<!--"+comment+"-->")
})
printer.on("error", function (error) {
console.error(error)
throw error
})
if (!process.argv[2]) {
throw new Error("Please provide an xml file to prettify\n"+
"TODO: read from stdin or take a file")
}
var xmlfile = require("path").join(process.cwd(), process.argv[2])
var fstr = fs.createReadStream(xmlfile, { encoding: "utf8" })
function print (c) {
if (!process.stdout.write(c)) {
fstr.pause()
}
}
process.stdout.on("drain", function () {
fstr.resume()
})
fstr.pipe(printer)
<GeneralSearchResponse xmlns="urn:types.partner.api.shopping.com"><serverDetail><apiEnv>sandbox</apiEnv><apiVersion>3.1 r31.Kadu4DC.phase3</apiVersion><buildNumber>5778</buildNumber><buildTimestamp>2011.10.06 15:37:23 PST</buildTimestamp><requestId>p2.a121bc2aaf029435dce6</requestId><timestamp>2011-10-21T18:38:45.982-04:00</timestamp><responseTime>P0Y0M0DT0H0M0.169S</responseTime></serverDetail><exceptions exceptionCount="1"><exception type="warning"><code>1112</code><message>You are currently using the SDC API sandbox environment! No clicks to merchant URLs from this response will be paid. Please change the host of your API requests to 'publisher.api.shopping.com' when you have finished development and testing</message></exception></exceptions><clientTracking height="19" type="logo" width="106"><sourceURL>http://statTest.dealtime.com/pixel/noscript?PV_EvnTyp=APPV&amp;APPV_APITSP=10%2F21%2F11_06%3A38%3A45_PM&amp;APPV_DSPRQSID=p2.a121bc2aaf029435dce6&amp;APPV_IMGURL=http://img.shopping.com/sc/glb/sdc_logo_106x19.gif&amp;APPV_LI_LNKINID=7000610&amp;APPV_LI_SBMKYW=nikon&amp;APPV_MTCTYP=1000&amp;APPV_PRTID=2002&amp;APPV_BrnID=14804</sourceURL><hrefURL>http://www.shopping.com/digital-cameras/products</hrefURL><titleText>Digital Cameras</titleText><altText>Digital Cameras</altText></clientTracking><searchHistory><categorySelection id="3"><name>Electronics</name><categoryURL>http://www.shopping.com/xCH-electronics-nikon~linkin_id-7000610?oq=nikon</categoryURL></categorySelection><categorySelection id="449"><name>Cameras and Photography</name><categoryURL>http://www.shopping.com/xCH-cameras_and_photography-nikon~linkin_id-7000610?oq=nikon</categoryURL></categorySelection><categorySelection id="7185"><name>Digital Cameras</name><categoryURL>http://www.shopping.com/digital-cameras/nikon/products?oq=nikon&amp;linkin_id=7000610</categoryURL></categorySelection><dynamicNavigationHistory><keywordSearch dropped="false" modified="false"><originalKeyword>nikon</originalKeyword><resultKeyword>nikon</resultKeyword></keywordSearch></dynamicNavigationHistory></searchHistory><categories matchedCategoryCount="1" returnedCategoryCount="1"><category id="7185"><name>Digital Cameras</name><categoryURL>http://www.shopping.com/digital-cameras/nikon/products?oq=nikon&amp;linkin_id=7000610</categoryURL><items matchedItemCount="322" pageNumber="1" returnedItemCount="5"><product id="101677489"><name>Nikon D3100 Digital Camera</name><shortDescription>14.2 Megapixel, SLR Camera, 3 in. LCD Screen, With High Definition Video, Weight: 1 lb.</shortDescription><fullDescription>The Nikon D3100 digital SLR camera speaks to the growing ranks of enthusiastic D-SLR users and aspiring photographers by providing an easy-to-use and affordable entrance to the world of Nikon D-SLR’s. The 14.2-megapixel D3100 has powerful features, such as the enhanced Guide Mode that makes it easy to unleash creative potential and capture memories with still images and full HD video. Like having a personal photo tutor at your fingertips, this unique feature provides a simple graphical interface on the camera’s LCD that guides users by suggesting and/or adjusting camera settings to achieve the desired end result images. The D3100 is also the world’s first D-SLR to introduce full time auto focus (AF) in Live View and D-Movie mode to effortlessly achieve the critical focus needed when shooting Full HD 1080p video.</fullDescription><images><image available="true" height="100" width="100"><sourceURL>http://di1.shopping.com/images/pi/93/bc/04/101677489-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di1.shopping.com/images/pi/93/bc/04/101677489-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di1.shopping.com/images/pi/93/bc/04/101677489-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di1.shopping.com/images/pi/93/bc/04/101677489-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="500" width="606"><sourceURL>http://di1.shopping.com/images/pi/93/bc/04/101677489-606x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image></images><rating><reviewCount>9</reviewCount><rating>4.56</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/pr/sdc_stars_sm_4.5.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/Nikon-D3100/reviews~linkin_id-7000610</reviewURL></rating><minPrice>429.00</minPrice><maxPrice>1360.00</maxPrice><productOffersURL>http://www.shopping.com/Nikon-D3100/prices~linkin_id-7000610</productOffersURL><productSpecsURL>http://www.shopping.com/Nikon-D3100/info~linkin_id-7000610</productSpecsURL><offers matchedOfferCount="64" pageNumber="1" returnedOfferCount="5"><offer featured="false" id="-ZW6BMZqz6fbS-aULwga_g==" smartBuy="false" used="false"><name>Nikon D3100 Digital SLR Camera with 18-55mm NIKKOR VR Lens</name><description>The Nikon D3100 Digital SLR Camera is an affordable compact and lightweight photographic power-house. It features the all-purpose 18-55mm VR lens a high-resolution 14.2 MP CMOS sensor along with a feature set that's comprehensive yet easy to navigate - the intuitive onboard learn-as-you grow guide mode allows the photographer to understand what the 3100 can do quickly and easily. Capture beautiful pictures and amazing Full HD 1080p movies with sound and full-time autofocus. Availabilty: In Stock!</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="350" width="350"><sourceURL>http://di102.shopping.com/images/di/2d/5a/57/36424d5a717a366662532d61554c7767615f67-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Free Shipping with Any Purchase!</storeNotes><basePrice currency="USD">529.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">799.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=475674&amp;crawler_id=475674&amp;dealId=-ZW6BMZqz6fbS-aULwga_g%3D%3D&amp;url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F343.5%2Fshopping-com%3F&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D3100+Digital+SLR+Camera+with+18-55mm+NIKKOR+VR+Lens&amp;dlprc=529.0&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=1&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=101677489&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=1&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=1&amp;SL=1&amp;FS=1&amp;code=&amp;acode=658&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="475674" trusted="true"><name>FumFie</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/475674.gif</sourceURL></logo><phoneNumber>866 666 9198</phoneNumber><ratingInfo><reviewCount>560</reviewCount><rating>4.27</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_45.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>F343C5</sku></offer><offer featured="false" id="md1e9lD8vdOu4FHQfJqKng==" smartBuy="false" used="false"><name>Nikon Nikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR, Cameras</name><description>Nikon D3100 14.2MP Digital SLR Camera with 18-55mm f/3.5-5.6 AF-S DX VR</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="352" width="385"><sourceURL>http://di109.shopping.com/images/di/6d/64/31/65396c443876644f7534464851664a714b6e67-385x352-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">549.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">549.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=779&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=305814&amp;crawler_id=305814&amp;dealId=md1e9lD8vdOu4FHQfJqKng%3D%3D&amp;url=http%3A%2F%2Fwww.electronics-expo.com%2Findex.php%3Fpage%3Ditem%26id%3DNIKD3100%26source%3DSideCar%26scpid%3D8%26scid%3Dscsho318727%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+Nikon+D3100+14.2MP+Digital+SLR+Camera+with+18-55mm+f%2F3.5-5.6+AF-S+DX+VR%2C+Cameras&amp;dlprc=549.0&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=9&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=101677489&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=9&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=771&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="305814" trusted="true"><name>Electronics Expo</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/305814.gif</sourceURL></logo><phoneNumber>1-888-707-EXPO</phoneNumber><ratingInfo><reviewCount>371</reviewCount><rating>3.90</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_4.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_electronics_expo~MRD-305814~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>NIKD3100</sku></offer><offer featured="false" id="yYuaXnDFtCY7rDUjkY2aaw==" smartBuy="false" used="false"><name>Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, Black</name><description>Split-second shutter response captures shots other cameras may have missed Helps eliminate the frustration of shutter delay! 14.2-megapixels for enlargements worth framing and hanging. Takes breathtaking 1080p HD movies. ISO sensitivity from 100-1600 for bright or dimly lit settings. 3.0in. color LCD for beautiful, wide-angle framing and viewing. In-camera image editing lets you retouch with no PC. Automatic scene modes include Child, Sports, Night Portrait and more. Accepts SDHC memory cards. Nikon D3100 14.2-Megapixel Digital SLR Camera With 18-55mm Zoom-Nikkor Lens, Black is one of many Digital SLR Cameras available through Office Depot. Made by Nikon.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="250" width="250"><sourceURL>http://di109.shopping.com/images/di/79/59/75/61586e4446744359377244556a6b5932616177-250x250-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">549.99</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">699.99</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=698&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=467671&amp;crawler_id=467671&amp;dealId=yYuaXnDFtCY7rDUjkY2aaw%3D%3D&amp;url=http%3A%2F%2Flink.mercent.com%2Fredirect.ashx%3Fmr%3AmerchantID%3DOfficeDepot%26mr%3AtrackingCode%3DCEC9669E-6ABC-E011-9F24-0019B9C043EB%26mr%3AtargetUrl%3Dhttp%3A%2F%2Fwww.officedepot.com%2Fa%2Fproducts%2F486292%2FNikon-D3100-142-Megapixel-Digital-SLR%2F%253fcm_mmc%253dMercent-_-Shopping-_-Cameras_and_Camcorders-_-486292&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D3100+14.2-Megapixel+Digital+SLR+Camera+With+18-55mm+Zoom-Nikkor+Lens%2C+Black&amp;dlprc=549.99&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=10&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=101677489&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=10&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=1&amp;SL=1&amp;FS=1&amp;code=&amp;acode=690&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="467671" trusted="true"><name>Office Depot</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/467671.gif</sourceURL></logo><phoneNumber>1-800-GO-DEPOT</phoneNumber><ratingInfo><reviewCount>135</reviewCount><rating>2.37</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_office_depot_4158555~MRD-467671~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>486292</sku></offer><offer featured="false" id="Rl56U7CuiTYsH4MGZ02lxQ==" smartBuy="false" used="false"><name>Nikon® D3100™ 14.2MP Digital SLR with 18-55mm Lens</name><description>The Nikon D3100 DSLR will surprise you with its simplicity and impress you with superb results.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="220" width="220"><sourceURL>http://di103.shopping.com/images/di/52/6c/35/36553743756954597348344d475a30326c7851-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">549.99</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.05</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">549.99</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=332477&amp;crawler_id=332477&amp;dealId=Rl56U7CuiTYsH4MGZ02lxQ%3D%3D&amp;url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D903483107%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon%C2%AE+D3100%E2%84%A2+14.2MP+Digital+SLR+with+18-55mm+Lens&amp;dlprc=549.99&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=11&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=101677489&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=11&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=0&amp;code=&amp;acode=496&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="332477" trusted="false"><name>RadioShack</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/332477.gif</sourceURL></logo><ratingInfo><reviewCount>24</reviewCount><rating>2.25</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>9614867</sku></offer><offer featured="false" id="huS6xZKDKaKMTMP71eI6DA==" smartBuy="false" used="false"><name>Nikon D3100 SLR w/Nikon 18-55mm VR &amp; 55-200mm VR Lenses</name><description>14.2 Megapixels3" LCDLive ViewHD 1080p Video w/ Sound &amp; Autofocus11-point Autofocus3 Frames per Second ShootingISO 100 to 3200 (Expand to 12800-Hi2)Self Cleaning SensorEXPEED 2, Image Processing EngineScene Recognition System</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="345" width="345"><sourceURL>http://di105.shopping.com/images/di/68/75/53/36785a4b444b614b4d544d5037316549364441-345x345-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">695.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">695.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=487342&amp;crawler_id=487342&amp;dealId=huS6xZKDKaKMTMP71eI6DA%3D%3D&amp;url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D32983%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D3100+SLR+w%2FNikon+18-55mm+VR+%26+55-200mm+VR+Lenses&amp;dlprc=695.0&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=15&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=101677489&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=15&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=379&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="487342" trusted="false"><name>RytherCamera.com</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/487342.gif</sourceURL></logo><phoneNumber>1-877-644-7593</phoneNumber><ratingInfo><reviewCount>0</reviewCount></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>32983</sku></offer></offers></product><product id="95397883"><name>Nikon COOLPIX S203 Digital Camera</name><shortDescription>10 Megapixel, Ultra-Compact Camera, 2.5 in. LCD Screen, 3x Optical Zoom, With Video Capability, Weight: 0.23 lb.</shortDescription><fullDescription>With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.</fullDescription><images><image available="true" height="100" width="100"><sourceURL>http://di1.shopping.com/images/pi/c4/ef/1b/95397883-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di1.shopping.com/images/pi/c4/ef/1b/95397883-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di1.shopping.com/images/pi/c4/ef/1b/95397883-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di1.shopping.com/images/pi/c4/ef/1b/95397883-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="499" width="500"><sourceURL>http://di1.shopping.com/images/pi/c4/ef/1b/95397883-500x499-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image></images><rating><reviewCount>0</reviewCount></rating><minPrice>139.00</minPrice><maxPrice>139.00</maxPrice><productOffersURL>http://www.shopping.com/Nikon-Coolpix-S203/prices~linkin_id-7000610</productOffersURL><productSpecsURL>http://www.shopping.com/Nikon-Coolpix-S203/info~linkin_id-7000610</productSpecsURL><offers matchedOfferCount="1" pageNumber="1" returnedOfferCount="1"><offer featured="false" id="sBd2JnIEPM-A_lBAM1RZgQ==" smartBuy="false" used="false"><name>Nikon Coolpix S203 Digital Camera (Red)</name><description>With 10.34 mega pixel, electronic VR vibration reduction, 5-level brightness adjustment, 3x optical zoom, and TFT LCD, Nikon Coolpix s203 fulfills all the demands of any photographer. The digital camera has an inbuilt memory of 44MB and an external memory slot made for all kinds of SD (Secure Digital) cards.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="500" width="500"><sourceURL>http://di108.shopping.com/images/di/73/42/64/324a6e4945504d2d415f6c42414d31525a6751-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Fantastic prices with ease &amp; comfort of Amazon.com!</storeNotes><basePrice currency="USD">139.00</basePrice><shippingCost currency="USD">9.50</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">139.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=301531&amp;crawler_id=1903313&amp;dealId=sBd2JnIEPM-A_lBAM1RZgQ%3D%3D&amp;url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB002T964IM%2Fref%3Dasc_df_B002T964IM1751618%3Fsmid%3DA22UHVNXG98FAT%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB002T964IM&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+Coolpix+S203+Digital+Camera+%28Red%29&amp;dlprc=139.0&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=63&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=95397883&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=63&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=0&amp;code=&amp;acode=518&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="301531" trusted="false"><name>Amazon Marketplace</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/301531.gif</sourceURL></logo><ratingInfo><reviewCount>213</reviewCount><rating>2.73</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>B002T964IM</sku></offer></offers></product><product id="106834268"><name>Nikon S3100 Digital Camera</name><shortDescription>14.5 Megapixel, Compact Camera, 2.7 in. LCD Screen, 5x Optical Zoom, With High Definition Video, Weight: 0.23 lb.</shortDescription><fullDescription>This digital camera features a wide-angle optical Zoom-NIKKOR glass lens that allows you to capture anything from landscapes to portraits to action shots. The high-definition movie mode with one-touch recording makes it easy to capture video clips.</fullDescription><images><image available="true" height="100" width="100"><sourceURL>http://di1.shopping.com/images/pi/66/2d/33/106834268-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di1.shopping.com/images/pi/66/2d/33/106834268-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di1.shopping.com/images/pi/66/2d/33/106834268-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di1.shopping.com/images/pi/66/2d/33/106834268-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="387" width="507"><sourceURL>http://di1.shopping.com/images/pi/66/2d/33/106834268-507x387-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image></images><rating><reviewCount>1</reviewCount><rating>2.00</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/pr/sdc_stars_sm_2.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/nikon-s3100/reviews~linkin_id-7000610</reviewURL></rating><minPrice>99.95</minPrice><maxPrice>134.95</maxPrice><productOffersURL>http://www.shopping.com/nikon-s3100/prices~linkin_id-7000610</productOffersURL><productSpecsURL>http://www.shopping.com/nikon-s3100/info~linkin_id-7000610</productSpecsURL><offers matchedOfferCount="67" pageNumber="1" returnedOfferCount="5"><offer featured="false" id="UUyGoqV8r0-xrkn-rnGNbg==" smartBuy="false" used="false"><name>CoolPix S3100 14 Megapixel Compact Digital Camera- Red</name><description>Nikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - red</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di111.shopping.com/images/di/55/55/79/476f71563872302d78726b6e2d726e474e6267-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Get 30 days FREE SHIPPING w/ ShipVantage</storeNotes><basePrice currency="USD">119.95</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.95</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">139.95</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=485615&amp;crawler_id=485615&amp;dealId=UUyGoqV8r0-xrkn-rnGNbg%3D%3D&amp;url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJ3Yx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmDAJeU1oyGG0GcBdhGwUGCAVqYF9SO0xSN1sZdmA7dmMdBQAJB24qX1NbQxI6AjA2ME5dVFULPDsGPFcQTTdaLTA6SR0OFlQvPAwMDxYcYlxIVkcoLTcCDA%3D%3D%26nAID%3D13736960%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=CoolPix+S3100+14+Megapixel+Compact+Digital+Camera-+Red&amp;dlprc=119.95&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=28&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=106834268&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=28&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=1&amp;FS=0&amp;code=&amp;acode=583&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="485615" trusted="true"><name>Sears</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/485615.gif</sourceURL></logo><phoneNumber>1-800-349-4358</phoneNumber><ratingInfo><reviewCount>888</reviewCount><rating>2.85</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_3.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>00337013000</sku></offer><offer featured="false" id="X87AwXlW1dXoMXk4QQDToQ==" smartBuy="false" used="false"><name>COOLPIX S3100 Pink</name><description>Nikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - pink</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di111.shopping.com/images/di/58/38/37/4177586c573164586f4d586b34515144546f51-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Get 30 days FREE SHIPPING w/ ShipVantage</storeNotes><basePrice currency="USD">119.95</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.95</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">139.95</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=485615&amp;crawler_id=485615&amp;dealId=X87AwXlW1dXoMXk4QQDToQ%3D%3D&amp;url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJxYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGsPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=COOLPIX+S3100+Pink&amp;dlprc=119.95&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=31&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=106834268&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=31&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=1&amp;FS=0&amp;code=&amp;acode=583&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="485615" trusted="true"><name>Sears</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/485615.gif</sourceURL></logo><phoneNumber>1-800-349-4358</phoneNumber><ratingInfo><reviewCount>888</reviewCount><rating>2.85</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_3.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>00337015000</sku></offer><offer featured="false" id="nvFwnpfA4rlA1Dbksdsa0w==" smartBuy="false" used="false"><name>Nikon Coolpix S3100 14.0 MP Digital Camera - Silver</name><description>Nikon Coolpix S3100 14.0 MP Digital Camera - Silver</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="270" width="270"><sourceURL>http://di109.shopping.com/images/di/6e/76/46/776e70664134726c413144626b736473613077-270x270-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">109.97</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">109.97</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=803&amp;BEFID=7185&amp;aon=%5E&amp;MerchantID=475774&amp;crawler_id=475774&amp;dealId=nvFwnpfA4rlA1Dbksdsa0w%3D%3D&amp;url=http%3A%2F%2Fwww.thewiz.com%2Fcatalog%2Fproduct.jsp%3FmodelNo%3DS3100SILVER%26gdftrk%3DgdfV2677_a_7c996_a_7c4049_a_7c26262&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+Coolpix+S3100+14.0+MP+Digital+Camera+-+Silver&amp;dlprc=109.97&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=33&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=106834268&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=33&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=797&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="475774" trusted="false"><name>TheWiz.com</name><logo available="false" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/475774.gif</sourceURL></logo><phoneNumber>877-542-6988</phoneNumber><ratingInfo><reviewCount>0</reviewCount></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>26262</sku></offer><offer featured="false" id="5GtaN2NeryKwps-Se2l-4g==" smartBuy="false" used="false"><name>Nikon� COOLPIX� S3100 14MP Digital Camera (Silver)</name><description>The Nikon COOLPIX S3100 is the easy way to share your life and stay connected.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="220" width="220"><sourceURL>http://di102.shopping.com/images/di/35/47/74/614e324e6572794b7770732d5365326c2d3467-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">119.99</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.05</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">119.99</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=332477&amp;crawler_id=332477&amp;dealId=5GtaN2NeryKwps-Se2l-4g%3D%3D&amp;url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D848064082%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon%C3%AF%C2%BF%C2%BD+COOLPIX%C3%AF%C2%BF%C2%BD+S3100+14MP+Digital+Camera+%28Silver%29&amp;dlprc=119.99&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=37&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=106834268&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=37&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=0&amp;code=&amp;acode=509&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="332477" trusted="false"><name>RadioShack</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/332477.gif</sourceURL></logo><ratingInfo><reviewCount>24</reviewCount><rating>2.25</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>10101095</sku></offer><offer featured="false" id="a43m0RXulX38zCnQjU59jw==" smartBuy="false" used="false"><name>COOLPIX S3100 Yellow</name><description>Nikon Coolpix S3100 - Digital camera - compact - 14.0 Mpix - optical zoom: 5 x - supported memory: SD, SDXC, SDHC - yellow</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di107.shopping.com/images/di/61/34/33/6d305258756c5833387a436e516a5535396a77-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Get 30 days FREE SHIPPING w/ ShipVantage</storeNotes><basePrice currency="USD">119.95</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.95</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">139.95</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=485615&amp;crawler_id=485615&amp;dealId=a43m0RXulX38zCnQjU59jw%3D%3D&amp;url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBJpFHJwYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcUFxDEGoPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=COOLPIX+S3100+Yellow&amp;dlprc=119.95&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=38&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=106834268&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=38&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=1&amp;FS=0&amp;code=&amp;acode=583&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="485615" trusted="true"><name>Sears</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/485615.gif</sourceURL></logo><phoneNumber>1-800-349-4358</phoneNumber><ratingInfo><reviewCount>888</reviewCount><rating>2.85</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_3.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>00337014000</sku></offer></offers></product><product id="99671132"><name>Nikon D90 Digital Camera</name><shortDescription>12.3 Megapixel, Point and Shoot Camera, 3 in. LCD Screen, With Video Capability, Weight: 1.36 lb.</shortDescription><fullDescription>Untitled Document Nikon D90 SLR Digital Camera With 28-80mm 75-300mm Lens Kit The Nikon D90 SLR Digital Camera, with its 12.3-megapixel DX-format CMOS, 3" High resolution LCD display, Scene Recognition System, Picture Control, Active D-Lighting, and one-button Live View, provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera.</fullDescription><images><image available="true" height="100" width="100"><sourceURL>http://di1.shopping.com/images/pi/52/fb/d3/99671132-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di1.shopping.com/images/pi/52/fb/d3/99671132-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di1.shopping.com/images/pi/52/fb/d3/99671132-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di1.shopping.com/images/pi/52/fb/d3/99671132-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="255" width="499"><sourceURL>http://di1.shopping.com/images/pi/52/fb/d3/99671132-499x255-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image></images><rating><reviewCount>7</reviewCount><rating>5.00</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/pr/sdc_stars_sm_5.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/reviews~linkin_id-7000610</reviewURL></rating><minPrice>689.00</minPrice><maxPrice>2299.00</maxPrice><productOffersURL>http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/prices~linkin_id-7000610</productOffersURL><productSpecsURL>http://www.shopping.com/Nikon-D90-with-18-270mm-Lens/info~linkin_id-7000610</productSpecsURL><offers matchedOfferCount="43" pageNumber="1" returnedOfferCount="5"><offer featured="false" id="GU5JJkpUAxe5HujB7fkwAA==" smartBuy="false" used="false"><name>Nikon® D90 12.3MP Digital SLR Camera (Body Only)</name><description>The Nikon D90 will make you rethink what a digital SLR camera can achieve.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="220" width="220"><sourceURL>http://di106.shopping.com/images/di/47/55/35/4a4a6b70554178653548756a4237666b774141-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">1015.99</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.05</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">1015.99</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=332477&amp;crawler_id=332477&amp;dealId=GU5JJkpUAxe5HujB7fkwAA%3D%3D&amp;url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D851830266%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&amp;dlprc=1015.99&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=14&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=99671132&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=14&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=0&amp;code=&amp;acode=496&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="332477" trusted="false"><name>RadioShack</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/332477.gif</sourceURL></logo><ratingInfo><reviewCount>24</reviewCount><rating>2.25</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>10148659</sku></offer><offer featured="false" id="XhURuSC-spBbTIDfo4qfzQ==" smartBuy="false" used="false"><name>Nikon D90 SLR Digital Camera (Camera Body)</name><description>The Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CCD 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View provides photo enthusiasts with the image quality and performance they need to pursue their own vision while still being intuitive enough for use as an everyday camera. In addition the D90 introduces the D-Movie mode allowing for the first time an interchangeable lens SLR camera that is capable of recording 720p HD movie clips. Availabilty: In Stock</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="350" width="350"><sourceURL>http://di109.shopping.com/images/di/58/68/55/527553432d73704262544944666f3471667a51-350x350-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Free Shipping with Any Purchase!</storeNotes><basePrice currency="USD">689.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">900.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=647&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=475674&amp;crawler_id=475674&amp;dealId=XhURuSC-spBbTIDfo4qfzQ%3D%3D&amp;url=http%3A%2F%2Fwww.fumfie.com%2Fproduct%2F169.5%2Fshopping-com%3F&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+SLR+Digital+Camera+%28Camera+Body%29&amp;dlprc=689.0&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=16&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=99671132&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=16&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=1&amp;SL=1&amp;FS=1&amp;code=&amp;acode=658&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="475674" trusted="true"><name>FumFie</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/475674.gif</sourceURL></logo><phoneNumber>866 666 9198</phoneNumber><ratingInfo><reviewCount>560</reviewCount><rating>4.27</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_45.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_fumfie~MRD-475674~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>F169C5</sku></offer><offer featured="false" id="o0Px_XLWDbrxAYRy3rCmyQ==" smartBuy="false" used="false"><name>Nikon D90 SLR w/Nikon 18-105mm VR &amp; 55-200mm VR Lenses</name><description>12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="500" width="500"><sourceURL>http://di101.shopping.com/images/di/6f/30/50/785f584c5744627278415952793372436d7951-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">1189.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">1189.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=487342&amp;crawler_id=487342&amp;dealId=o0Px_XLWDbrxAYRy3rCmyQ%3D%3D&amp;url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30619%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+%26+55-200mm+VR+Lenses&amp;dlprc=1189.0&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=20&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=99671132&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=20&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=379&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="487342" trusted="false"><name>RytherCamera.com</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/487342.gif</sourceURL></logo><phoneNumber>1-877-644-7593</phoneNumber><ratingInfo><reviewCount>0</reviewCount></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>30619</sku></offer><offer featured="false" id="4HgbWJSJ8ssgIf8B0MXIwA==" smartBuy="false" used="false"><name>Nikon D90 12.3 Megapixel Digital SLR Camera (Body Only)</name><description>Fusing 12.3 megapixel image quality and a cinematic 24fps D-Movie Mode, the Nikon D90 exceeds the demands of passionate photographers. Coupled with Nikon's EXPEED image processing technologies and NIKKOR optics, breathtaking image fidelity is assured. Combined with fast 0.15ms power-up and split-second 65ms shooting lag, dramatic action and decisive moments are captured easily. Effective 4-frequency, ultrasonic sensor cleaning frees image degrading dust particles from the sensor's optical low pass filter.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di110.shopping.com/images/di/34/48/67/62574a534a3873736749663842304d58497741-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>FREE FEDEX 2-3 DAY DELIVERY</storeNotes><basePrice currency="USD">899.95</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">899.95</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=269&amp;BEFID=7185&amp;aon=%5E&amp;MerchantID=9296&amp;crawler_id=811558&amp;dealId=4HgbWJSJ8ssgIf8B0MXIwA%3D%3D&amp;url=http%3A%2F%2Fwww.pcnation.com%2Foptics-gallery%2Fdetails.asp%3Faffid%3D305%26item%3D2N145P&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+12.3+Megapixel+Digital+SLR+Camera+%28Body+Only%29&amp;dlprc=899.95&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=21&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=99671132&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=21&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=257&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="9296" trusted="true"><name>PCNation</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/9296.gif</sourceURL></logo><phoneNumber>800-470-7079</phoneNumber><ratingInfo><reviewCount>1622</reviewCount><rating>4.43</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_45.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_pcnation_9689~MRD-9296~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>2N145P</sku></offer><offer featured="false" id="UNDa3uMDZXOnvD_7sTILYg==" smartBuy="false" used="false"><name>Nikon D90 12.3MP Digital SLR Camera (Body Only)</name><description>Fusing 12.3-megapixel image quality inherited from the award-winning D300 with groundbreaking features, the D90's breathtaking, low-noise image quality is further advanced with EXPEED image processing. Split-second shutter response and continuous shooting at up to 4.5 frames-per-second provide the power to capture fast action and precise moments perfectly, while Nikon's exclusive Scene Recognition System contributes to faster 11-area autofocus performance, finer white balance detection and more. The D90 delivers the control passionate photographers demand, utilizing comprehensive exposure functions and the intelligence of 3D Color Matrix Metering II. Stunning results come to life on a 3-inch 920,000-dot color LCD monitor, providing accurate image review, Live View composition and brilliant playback of the D90's cinematic-quality 24-fps HD D-Movie mode.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="500" width="500"><sourceURL>http://di102.shopping.com/images/di/55/4e/44/6133754d445a584f6e76445f377354494c5967-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Fantastic prices with ease &amp; comfort of Amazon.com!</storeNotes><basePrice currency="USD">780.00</basePrice><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">780.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=566&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=301531&amp;crawler_id=1903313&amp;dealId=UNDa3uMDZXOnvD_7sTILYg%3D%3D&amp;url=http%3A%2F%2Fwww.amazon.com%2Fdp%2FB001ET5U92%2Fref%3Dasc_df_B001ET5U921751618%3Fsmid%3DAHF4SYKP09WBH%26tag%3Ddealtime-ce-mp01feed-20%26linkCode%3Dasn%26creative%3D395105%26creativeASIN%3DB001ET5U92&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+12.3MP+Digital+SLR+Camera+%28Body+Only%29&amp;dlprc=780.0&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=29&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=99671132&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=29&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=520&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="301531" trusted="false"><name>Amazon Marketplace</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/301531.gif</sourceURL></logo><ratingInfo><reviewCount>213</reviewCount><rating>2.73</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_amazon_marketplace_9689~MRD-301531~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>B001ET5U92</sku></offer></offers></product><product id="70621646"><name>Nikon D90 Digital Camera with 18-105mm lens</name><shortDescription>12.9 Megapixel, SLR Camera, 3 in. LCD Screen, 5.8x Optical Zoom, With Video Capability, Weight: 2.3 lb.</shortDescription><fullDescription>Its 12.3 megapixel DX-format CMOS image sensor and EXPEED image processing system offer outstanding image quality across a wide ISO light sensitivity range. Live View mode lets you compose and shoot via the high-resolution 3-inch LCD monitor, and an advanced Scene Recognition System and autofocus performance help capture images with astounding accuracy. Movies can be shot in Motion JPEG format using the D-Movie function. The camera’s large image sensor ensures exceptional movie image quality and you can create dramatic effects by shooting with a wide range of interchangeable NIKKOR lenses, from wide-angle to macro to fisheye, or by adjusting the lens aperture and experimenting with depth-of-field. The D90 – designed to fuel your passion for photography.</fullDescription><images><image available="true" height="100" width="100"><sourceURL>http://di1.shopping.com/images/pi/57/6a/4f/70621646-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di1.shopping.com/images/pi/57/6a/4f/70621646-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di1.shopping.com/images/pi/57/6a/4f/70621646-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di1.shopping.com/images/pi/57/6a/4f/70621646-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="489" width="490"><sourceURL>http://di1.shopping.com/images/pi/57/6a/4f/70621646-490x489-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=2&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image></images><rating><reviewCount>32</reviewCount><rating>4.81</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/pr/sdc_stars_sm_5.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/Nikon-D90-with-18-105mm-lens/reviews~linkin_id-7000610</reviewURL></rating><minPrice>849.95</minPrice><maxPrice>1599.95</maxPrice><productOffersURL>http://www.shopping.com/Nikon-D90-with-18-105mm-lens/prices~linkin_id-7000610</productOffersURL><productSpecsURL>http://www.shopping.com/Nikon-D90-with-18-105mm-lens/info~linkin_id-7000610</productSpecsURL><offers matchedOfferCount="25" pageNumber="1" returnedOfferCount="5"><offer featured="false" id="3o5e1VghgJPfhLvT1JFKTA==" smartBuy="false" used="false"><name>Nikon D90 18-105mm VR Lens</name><description>The Nikon D90 SLR Digital Camera with its 12.3-megapixel DX-format CMOS 3" High resolution LCD display Scene Recognition System Picture Control Active D-Lighting and one-button Live View prov</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image><image available="true" height="260" width="260"><sourceURL>http://di111.shopping.com/images/di/33/6f/35/6531566768674a5066684c7654314a464b5441-260x260-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=1</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">849.95</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">849.95</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=419&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=9390&amp;crawler_id=1905054&amp;dealId=3o5e1VghgJPfhLvT1JFKTA%3D%3D&amp;url=http%3A%2F%2Fwww.ajrichard.com%2FNikon-D90-18-105mm-VR-Lens%2Fp-292%3Frefid%3DShopping%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+18-105mm+VR+Lens&amp;dlprc=849.95&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=2&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=70621646&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=2&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=425&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="9390" trusted="false"><name>AJRichard</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/9390.gif</sourceURL></logo><phoneNumber>1-888-871-1256</phoneNumber><ratingInfo><reviewCount>3124</reviewCount><rating>4.48</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_45.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_ajrichard~MRD-9390~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>292</sku></offer><offer featured="false" id="_lYWj_jbwfsSkfcwUcDuww==" smartBuy="false" used="false"><name>Nikon D90 SLR w/Nikon 18-105mm VR Lens</name><description>12.3 MegapixelDX Format CMOS Sensor3" VGA LCD DisplayLive ViewSelf Cleaning SensorD-Movie ModeHigh Sensitivity (ISO 3200)4.5 fps BurstIn-Camera Image Editing</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image><image available="true" height="500" width="500"><sourceURL>http://di108.shopping.com/images/di/5f/6c/59/576a5f6a62776673536b666377556344757777-500x500-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=2</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">909.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">909.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=371&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=487342&amp;crawler_id=487342&amp;dealId=_lYWj_jbwfsSkfcwUcDuww%3D%3D&amp;url=http%3A%2F%2Fwww.rythercamera.com%2Fcatalog%2Fproduct_info.php%3Fcsv%3Dsh%26products_id%3D30971%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+SLR+w%2FNikon+18-105mm+VR+Lens&amp;dlprc=909.0&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=3&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=70621646&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=3&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=1&amp;code=&amp;acode=379&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="487342" trusted="false"><name>RytherCamera.com</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/487342.gif</sourceURL></logo><phoneNumber>1-877-644-7593</phoneNumber><ratingInfo><reviewCount>0</reviewCount></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>30971</sku></offer><offer featured="false" id="1KCclCGuWvty2XKU9skadg==" smartBuy="false" used="false"><name>25448/D90 12.3 Megapixel Digital Camera 18-105mm Zoom Lens w/ 3" Screen - Black</name><description>Nikon D90 - Digital camera - SLR - 12.3 Mpix - Nikon AF-S DX 18-105mm lens - optical zoom: 5.8 x - supported memory: SD, SDHC</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image><image available="true" height="400" width="400"><sourceURL>http://di110.shopping.com/images/di/31/4b/43/636c4347755776747932584b5539736b616467-400x400-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=3</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Get 30 days FREE SHIPPING w/ ShipVantage</storeNotes><basePrice currency="USD">1199.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">8.20</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">1199.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=578&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=485615&amp;crawler_id=485615&amp;dealId=1KCclCGuWvty2XKU9skadg%3D%3D&amp;url=http%3A%2F%2Fsears.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1NbQBRtFXpzYx0CTAICI2BbH1lEFmgKP3QvUVpEREdlfUAUHAQPLVpFTVdtJzxAHUNYW3AhQBM0QhFvEXAbYh8EAAVmb2JcVlhCGGkPc3QDEkFZVQ0WFhdRW0MWbgYWDlxzdGMdAVQWRi0xDAwPFhw9TSobb05eWVVYKzsLTFVVQi5RICs3SA8MU1s2MQQKD1wf%26nAID%3D13736960%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=25448%2FD90+12.3+Megapixel+Digital+Camera+18-105mm+Zoom+Lens+w%2F+3%22+Screen+-+Black&amp;dlprc=1199.0&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=4&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=70621646&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=4&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=0&amp;code=&amp;acode=586&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="485615" trusted="true"><name>Sears</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/485615.gif</sourceURL></logo><phoneNumber>1-800-349-4358</phoneNumber><ratingInfo><reviewCount>888</reviewCount><rating>2.85</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_3.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_sears_4189479~MRD-485615~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>00353197000</sku></offer><offer featured="false" id="3-VOSfVV5Jo7HlA4kJtanA==" smartBuy="false" used="false"><name>Nikon® D90 12.3MP Digital SLR with 18-105mm Lens</name><description>The Nikon D90 will make you rethink what a digital SLR camera can achieve.</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="false" height="300" width="300"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image><image available="true" height="220" width="220"><sourceURL>http://di101.shopping.com/images/di/33/2d/56/4f53665656354a6f37486c41346b4a74616e41-220x220-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=4</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><basePrice currency="USD">1350.99</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">6.05</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">1350.99</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=504&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=332477&amp;crawler_id=332477&amp;dealId=3-VOSfVV5Jo7HlA4kJtanA%3D%3D&amp;url=http%3A%2F%2Ftracking.searchmarketing.com%2Fgsic.asp%3Faid%3D982673361%26&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon%C2%AE+D90+12.3MP+Digital+SLR+with+18-105mm+Lens&amp;dlprc=1350.99&amp;crn=&amp;istrsmrc=0&amp;isathrsl=0&amp;AR=5&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=70621646&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=5&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=0&amp;FS=0&amp;code=&amp;acode=496&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="332477" trusted="false"><name>RadioShack</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/332477.gif</sourceURL></logo><ratingInfo><reviewCount>24</reviewCount><rating>2.25</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_25.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_radioshack_9689~MRD-332477~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>11148905</sku></offer><offer featured="false" id="kQnB6rS4AjN5dx5h2_631g==" smartBuy="false" used="false"><name>Nikon D90 Kit 12.3-megapixel Digital SLR with 18-105mm VR Lens</name><description>Photographers, take your passion further!Now is the time for new creativity, and to rethink what a digital SLR camera can achieve. It's time for the D90, a camera with everything you would expect from Nikon's next-generation D-SLRs, and some unexpected surprises, as well. The stunning image quality is inherited from the D300, Nikon's DX-format flagship. The D90 also has Nikon's unmatched ergonomics and high performance, and now takes high-quality movies with beautifully cinematic results. The world of photography has changed, and with the D90 in your hands, it's time to make your own rules.AF-S DX NIKKOR 18-105mm f/3.5-5.6G ED VR LensWide-ratio 5.8x zoom Compact, versatile and ideal for a broad range of shooting situations, ranging from interiors and landscapes to beautiful portraits� a perfect everyday zoom. Nikon VR (Vibration Reduction) image stabilization Vibration Reduction is engineered specifically for each VR NIKKOR lens and enables handheld shooting at up to 3 shutter speeds slower than would</description><categoryId>7185</categoryId><manufacturer>Nikon</manufacturer><imageList><image available="true" height="100" width="100"><sourceURL>http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-100x100-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="200" width="200"><sourceURL>http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-200x200-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="300" width="300"><sourceURL>http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x300-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="false" height="400" width="400"><sourceURL>http://img.shopping.com/sc/ds/no_image_100X100.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image><image available="true" height="232" width="300"><sourceURL>http://di110.shopping.com/images/di/6b/51/6e/4236725334416a4e3564783568325f36333167-300x232-0-0.jpg?p=p2.a121bc2aaf029435dce6&amp;a=1&amp;c=1&amp;l=7000610&amp;t=111021183845&amp;r=5</sourceURL></image></imageList><stockStatus>in-stock</stockStatus><storeNotes>Shipping Included!</storeNotes><basePrice currency="USD">1050.00</basePrice><tax checkSite="true"></tax><shippingCost currency="USD">0.00</shippingCost><totalPrice checkSite="true"></totalPrice><originalPrice currency="USD">1199.00</originalPrice><offerURL>http://statTest.dealtime.com/DealFrame/DealFrame.cmp?bm=135&amp;BEFID=7185&amp;aon=%5E1&amp;MerchantID=313162&amp;crawler_id=313162&amp;dealId=kQnB6rS4AjN5dx5h2_631g%3D%3D&amp;url=http%3A%2F%2Fonecall.rdr.channelintelligence.com%2Fgo.asp%3FfVhzOGNRAAQIASNiE1pZSxNoWHFwLx8GTAICa2ZeH1sPXTZLNzRpAh1HR0BxPQEGCBJNMhFHUElsFCFCVkVTTHAcBggEHQ4aHXNpGERGH3RQODsbAgdechJtbBt8fx8JAwhtZFAzJj1oGgIWCxRlNyFOUV9UUGIxBgo0T0IyTSYqJ0RWHw4QPCIBAAQXRGMDICg6TllZVBhh%26nAID%3D13736960&amp;linkin_id=7000610&amp;Issdt=111021183845&amp;searchID=p2.a121bc2aaf029435dce6&amp;DealName=Nikon+D90+Kit+12.3-megapixel+Digital+SLR+with+18-105mm+VR+Lens&amp;dlprc=1050.0&amp;crn=&amp;istrsmrc=1&amp;isathrsl=0&amp;AR=6&amp;NG=20&amp;NDP=200&amp;PN=1&amp;ST=7&amp;DB=sdcprod&amp;MT=phx-pkadudc2&amp;FPT=DSP&amp;NDS=&amp;NMS=&amp;MRS=&amp;PD=70621646&amp;brnId=14804&amp;IsFtr=0&amp;IsSmart=0&amp;DMT=&amp;op=&amp;CM=&amp;DlLng=1&amp;RR=6&amp;cid=&amp;semid1=&amp;semid2=&amp;IsLps=0&amp;CC=0&amp;SL=1&amp;FS=1&amp;code=&amp;acode=143&amp;category=&amp;HasLink=&amp;frameId=&amp;ND=&amp;MN=&amp;PT=&amp;prjID=&amp;GR=&amp;lnkId=&amp;VK=</offerURL><store authorizedReseller="false" id="313162" trusted="true"><name>OneCall</name><logo available="true" height="31" width="88"><sourceURL>http://img.shopping.com/cctool/merch_logos/313162.gif</sourceURL></logo><phoneNumber>1.800.398.0766</phoneNumber><ratingInfo><reviewCount>180</reviewCount><rating>4.44</rating><ratingImage height="18" width="91"><sourceURL>http://img.shopping.com/sc/mr/sdc_checks_45.gif</sourceURL></ratingImage><reviewURL>http://www.shopping.com/xMR-store_onecall_9689~MRD-313162~S-1~linkin_id-7000610</reviewURL></ratingInfo><countryFlag height="11" width="18"><sourceURL>http://img.shopping.com/sc/glb/flag/US.gif</sourceURL><countryCode>US</countryCode></countryFlag></store><sku>92826</sku></offer></offers></product></items><attributes matchedAttributeCount="5" returnedAttributeCount="5"><attribute id="Dynamic_Price_Range"><name>Price range</name><attributeURL>http://www.shopping.com/digital-cameras/nikon/products?oq=nikon&amp;linkin_id=7000610</attributeURL><attributeValues matchedValueCount="2" returnedValueCount="2"><attributeValue id="price_range_24_4012" matchingItemsCount="1"><name>$24 - $4012</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon/products?minPrice=24&amp;maxPrice=4012&amp;linkin_id=7000610</attributeValueURL></attributeValue><attributeValue id="price_range_4012_7999" matchingItemsCount="1"><name>$4012 - $7999</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon/products?minPrice=4012&amp;maxPrice=7999&amp;linkin_id=7000610</attributeValueURL></attributeValue></attributeValues></attribute><attribute id="9688_brand"><name>Brand</name><attributeURL>http://www.shopping.com/digital-cameras/nikon/products~all-9688-brand~MS-1?oq=nikon&amp;linkin_id=7000610</attributeURL><attributeValues matchedValueCount="7" returnedValueCount="5"><attributeValue id="brand_nikon" matchingItemsCount="2261"><name>Nikon</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+brand-nikon/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="9688_brand_crane" matchingItemsCount="17"><name>Crane</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+9688-brand-crane/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="ikelite" matchingItemsCount="2"><name>Ikelite</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+ikelite/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="bower" matchingItemsCount="1"><name>Bower</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+bower/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="brand_fuji" matchingItemsCount="2"><name>FUJIFILM</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+brand-fuji/products~linkin_id-7000610</attributeValueURL></attributeValue></attributeValues></attribute><attribute id="store"><name>Store</name><attributeURL>http://www.shopping.com/digital-cameras/nikon/products~all-store~MS-1?oq=nikon&amp;linkin_id=7000610</attributeURL><attributeValues matchedValueCount="35" returnedValueCount="5"><attributeValue id="store_amazon_marketplace_9689" matchingItemsCount="808"><name>Amazon Marketplace</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+store-amazon-marketplace-9689/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="store_amazon" matchingItemsCount="83"><name>Amazon</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+store-amazon/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="store_adorama" matchingItemsCount="81"><name>Adorama</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+store-adorama/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="store_j_r_music_and_computer_world" matchingItemsCount="78"><name>J&amp;R Music and Computer World</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+store-j-r-music-and-computer-world/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="store_rythercamera_com" matchingItemsCount="78"><name>RytherCamera.com</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+store-rythercamera-com/products~linkin_id-7000610</attributeValueURL></attributeValue></attributeValues></attribute><attribute id="21885_resolution"><name>Resolution</name><attributeURL>http://www.shopping.com/digital-cameras/nikon/products~all-21885-resolution~MS-1?oq=nikon&amp;linkin_id=7000610</attributeURL><attributeValues matchedValueCount="13" returnedValueCount="5"><attributeValue id="under_4_megapixel" matchingItemsCount="3"><name>Under 4 Megapixel</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+under-4-megapixel/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="5_megapixel_digital_cameras" matchingItemsCount="1085"><name>At least 5 Megapixel</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+5-megapixel-digital-cameras/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="6_megapixel_digital_cameras" matchingItemsCount="1080"><name>At least 6 Megapixel</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+6-megapixel-digital-cameras/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="7_megapixel_digital_cameras" matchingItemsCount="1066"><name>At least 7 Megapixel</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+7-megapixel-digital-cameras/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="8_megapixel_digital_cameras" matchingItemsCount="1056"><name>At least 8 Megapixel</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+8-megapixel-digital-cameras/products~linkin_id-7000610</attributeValueURL></attributeValue></attributeValues></attribute><attribute id="32804-features"><name>Features</name><attributeURL>http://www.shopping.com/digital-cameras/nikon/products~all-32804-features~MS-1?oq=nikon&amp;linkin_id=7000610</attributeURL><attributeValues matchedValueCount="12" returnedValueCount="5"><attributeValue id="32804_features_shockproof" matchingItemsCount="7"><name>Shockproof</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+32804-features-shockproof/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="32804_features_waterproof" matchingItemsCount="32"><name>Waterproof</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+32804-features-waterproof/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="32804_features_freezeproof" matchingItemsCount="7"><name>Freezeproof</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+32804-features-freezeproof/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="32804_features_dust_proof" matchingItemsCount="23"><name>Dust proof</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+32804-features-dust-proof/products~linkin_id-7000610</attributeValueURL></attributeValue><attributeValue id="32804_features_image_stabilization" matchingItemsCount="797"><name>Image Stabilization</name><attributeValueURL>http://www.shopping.com/digital-cameras/nikon+32804-features-image-stabilization/products~linkin_id-7000610</attributeValueURL></attributeValue></attributeValues></attribute></attributes><contentType>hybrid</contentType></category></categories><relatedTerms><term>digital camera</term><term>g1</term><term>sony</term><term>camera</term><term>canon</term><term>nikon</term><term>kodak digital camera</term><term>kodak</term><term>sony cybershot</term><term>kodak easyshare digital camera</term><term>nikon coolpix</term><term>olympus</term><term>pink digital camera</term><term>canon powershot</term></relatedTerms></GeneralSearchResponse>
\ No newline at end of file
<!--
This is HTML 4.01 Strict DTD, which excludes the presentation
attributes and elements that W3C expects to phase out as
support for style sheets matures. Authors should use the Strict
DTD when possible, but may use the Transitional DTD when support
for presentation attribute and elements is required.
HTML 4 includes mechanisms for style sheets, scripting,
embedding objects, improved support for right to left and mixed
direction text, and enhancements to forms for improved
accessibility for people with disabilities.
Draft: $Date: 1999/12/24 23:37:48 $
Authors:
Dave Raggett <dsr@w3.org>
Arnaud Le Hors <lehors@w3.org>
Ian Jacobs <ij@w3.org>
Further information about HTML 4.01 is available at:
http://www.w3.org/TR/1999/REC-html401-19991224
The HTML 4.01 specification includes additional
syntactic constraints that cannot be expressed within
the DTDs.
-->
<!--
Typical usage:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
...
</head>
<body>
...
</body>
</html>
The URI used as a system identifier with the public identifier allows
the user agent to download the DTD and entity sets as needed.
The FPI for the Transitional HTML 4.01 DTD is:
"-//W3C//DTD HTML 4.01 Transitional//EN"
This version of the transitional DTD is:
http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd
If you are writing a document that includes frames, use
the following FPI:
"-//W3C//DTD HTML 4.01 Frameset//EN"
This version of the frameset DTD is:
http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd
Use the following (relative) URIs to refer to
the DTDs and entity definitions of this specification:
"strict.dtd"
"loose.dtd"
"frameset.dtd"
"HTMLlat1.ent"
"HTMLsymbol.ent"
"HTMLspecial.ent"
-->
<!--================== Imported Names ====================================-->
<!-- Feature Switch for frameset documents -->
<!ENTITY % HTML.Frameset "IGNORE">
<!ENTITY % ContentType "CDATA"
-- media type, as per [RFC2045]
-->
<!ENTITY % ContentTypes "CDATA"
-- comma-separated list of media types, as per [RFC2045]
-->
<!ENTITY % Charset "CDATA"
-- a character encoding, as per [RFC2045]
-->
<!ENTITY % Charsets "CDATA"
-- a space-separated list of character encodings, as per [RFC2045]
-->
<!ENTITY % LanguageCode "NAME"
-- a language code, as per [RFC1766]
-->
<!ENTITY % Character "CDATA"
-- a single character from [ISO10646]
-->
<!ENTITY % LinkTypes "CDATA"
-- space-separated list of link types
-->
<!ENTITY % MediaDesc "CDATA"
-- single or comma-separated list of media descriptors
-->
<!ENTITY % URI "CDATA"
-- a Uniform Resource Identifier,
see [URI]
-->
<!ENTITY % Datetime "CDATA" -- date and time information. ISO date format -->
<!ENTITY % Script "CDATA" -- script expression -->
<!ENTITY % StyleSheet "CDATA" -- style sheet data -->
<!ENTITY % Text "CDATA">
<!-- Parameter Entities -->
<!ENTITY % head.misc "SCRIPT|STYLE|META|LINK|OBJECT" -- repeatable head elements -->
<!ENTITY % heading "H1|H2|H3|H4|H5|H6">
<!ENTITY % list "UL | OL">
<!ENTITY % preformatted "PRE">
<!--================ Character mnemonic entities =========================-->
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin1//EN//HTML"
"HTMLlat1.ent">
%HTMLlat1;
<!ENTITY % HTMLsymbol PUBLIC
"-//W3C//ENTITIES Symbols//EN//HTML"
"HTMLsymbol.ent">
%HTMLsymbol;
<!ENTITY % HTMLspecial PUBLIC
"-//W3C//ENTITIES Special//EN//HTML"
"HTMLspecial.ent">
%HTMLspecial;
<!--=================== Generic Attributes ===============================-->
<!ENTITY % coreattrs
"id ID #IMPLIED -- document-wide unique id --
class CDATA #IMPLIED -- space-separated list of classes --
style %StyleSheet; #IMPLIED -- associated style info --
title %Text; #IMPLIED -- advisory title --"
>
<!ENTITY % i18n
"lang %LanguageCode; #IMPLIED -- language code --
dir (ltr|rtl) #IMPLIED -- direction for weak/neutral text --"
>
<!ENTITY % events
"onclick %Script; #IMPLIED -- a pointer button was clicked --
ondblclick %Script; #IMPLIED -- a pointer button was double clicked--
onmousedown %Script; #IMPLIED -- a pointer button was pressed down --
onmouseup %Script; #IMPLIED -- a pointer button was released --
onmouseover %Script; #IMPLIED -- a pointer was moved onto --
onmousemove %Script; #IMPLIED -- a pointer was moved within --
onmouseout %Script; #IMPLIED -- a pointer was moved away --
onkeypress %Script; #IMPLIED -- a key was pressed and released --
onkeydown %Script; #IMPLIED -- a key was pressed down --
onkeyup %Script; #IMPLIED -- a key was released --"
>
<!-- Reserved Feature Switch -->
<!ENTITY % HTML.Reserved "IGNORE">
<!-- The following attributes are reserved for possible future use -->
<![ %HTML.Reserved; [
<!ENTITY % reserved
"datasrc %URI; #IMPLIED -- a single or tabular Data Source --
datafld CDATA #IMPLIED -- the property or column name --
dataformatas (plaintext|html) plaintext -- text or html --"
>
]]>
<!ENTITY % reserved "">
<!ENTITY % attrs "%coreattrs; %i18n; %events;">
<!--=================== Text Markup ======================================-->
<!ENTITY % fontstyle
"TT | I | B | BIG | SMALL">
<!ENTITY % phrase "EM | STRONG | DFN | CODE |
SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >
<!ENTITY % special
"A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">
<!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">
<!-- %inline; covers inline or "text-level" elements -->
<!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">
<!ELEMENT (%fontstyle;|%phrase;) - - (%inline;)*>
<!ATTLIST (%fontstyle;|%phrase;)
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT (SUB|SUP) - - (%inline;)* -- subscript, superscript -->
<!ATTLIST (SUB|SUP)
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT SPAN - - (%inline;)* -- generic language/style container -->
<!ATTLIST SPAN
%attrs; -- %coreattrs, %i18n, %events --
%reserved; -- reserved for possible future use --
>
<!ELEMENT BDO - - (%inline;)* -- I18N BiDi over-ride -->
<!ATTLIST BDO
%coreattrs; -- id, class, style, title --
lang %LanguageCode; #IMPLIED -- language code --
dir (ltr|rtl) #REQUIRED -- directionality --
>
<!ELEMENT BR - O EMPTY -- forced line break -->
<!ATTLIST BR
%coreattrs; -- id, class, style, title --
>
<!--================== HTML content models ===============================-->
<!--
HTML has two basic content models:
%inline; character level elements and text strings
%block; block-like elements e.g. paragraphs and lists
-->
<!ENTITY % block
"P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT |
BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS">
<!ENTITY % flow "%block; | %inline;">
<!--=================== Document Body ====================================-->
<!ELEMENT BODY O O (%block;|SCRIPT)+ +(INS|DEL) -- document body -->
<!ATTLIST BODY
%attrs; -- %coreattrs, %i18n, %events --
onload %Script; #IMPLIED -- the document has been loaded --
onunload %Script; #IMPLIED -- the document has been removed --
>
<!ELEMENT ADDRESS - - (%inline;)* -- information on author -->
<!ATTLIST ADDRESS
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT DIV - - (%flow;)* -- generic language/style container -->
<!ATTLIST DIV
%attrs; -- %coreattrs, %i18n, %events --
%reserved; -- reserved for possible future use --
>
<!--================== The Anchor Element ================================-->
<!ENTITY % Shape "(rect|circle|poly|default)">
<!ENTITY % Coords "CDATA" -- comma-separated list of lengths -->
<!ELEMENT A - - (%inline;)* -(A) -- anchor -->
<!ATTLIST A
%attrs; -- %coreattrs, %i18n, %events --
charset %Charset; #IMPLIED -- char encoding of linked resource --
type %ContentType; #IMPLIED -- advisory content type --
name CDATA #IMPLIED -- named link end --
href %URI; #IMPLIED -- URI for linked resource --
hreflang %LanguageCode; #IMPLIED -- language code --
rel %LinkTypes; #IMPLIED -- forward link types --
rev %LinkTypes; #IMPLIED -- reverse link types --
accesskey %Character; #IMPLIED -- accessibility key character --
shape %Shape; rect -- for use with client-side image maps --
coords %Coords; #IMPLIED -- for use with client-side image maps --
tabindex NUMBER #IMPLIED -- position in tabbing order --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>
<!--================== Client-side image maps ============================-->
<!-- These can be placed in the same document or grouped in a
separate document although this isn't yet widely supported -->
<!ELEMENT MAP - - ((%block;) | AREA)+ -- client-side image map -->
<!ATTLIST MAP
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #REQUIRED -- for reference by usemap --
>
<!ELEMENT AREA - O EMPTY -- client-side image map area -->
<!ATTLIST AREA
%attrs; -- %coreattrs, %i18n, %events --
shape %Shape; rect -- controls interpretation of coords --
coords %Coords; #IMPLIED -- comma-separated list of lengths --
href %URI; #IMPLIED -- URI for linked resource --
nohref (nohref) #IMPLIED -- this region has no action --
alt %Text; #REQUIRED -- short description --
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>
<!--================== The LINK Element ==================================-->
<!--
Relationship values can be used in principle:
a) for document specific toolbars/menus when used
with the LINK element in document head e.g.
start, contents, previous, next, index, end, help
b) to link to a separate style sheet (rel=stylesheet)
c) to make a link to a script (rel=script)
d) by stylesheets to control how collections of
html nodes are rendered into printed documents
e) to make a link to a printable version of this document
e.g. a postscript or pdf version (rel=alternate media=print)
-->
<!ELEMENT LINK - O EMPTY -- a media-independent link -->
<!ATTLIST LINK
%attrs; -- %coreattrs, %i18n, %events --
charset %Charset; #IMPLIED -- char encoding of linked resource --
href %URI; #IMPLIED -- URI for linked resource --
hreflang %LanguageCode; #IMPLIED -- language code --
type %ContentType; #IMPLIED -- advisory content type --
rel %LinkTypes; #IMPLIED -- forward link types --
rev %LinkTypes; #IMPLIED -- reverse link types --
media %MediaDesc; #IMPLIED -- for rendering on these media --
>
<!--=================== Images ===========================================-->
<!-- Length defined in strict DTD for cellpadding/cellspacing -->
<!ENTITY % Length "CDATA" -- nn for pixels or nn% for percentage length -->
<!ENTITY % MultiLength "CDATA" -- pixel, percentage, or relative -->
<![ %HTML.Frameset; [
<!ENTITY % MultiLengths "CDATA" -- comma-separated list of MultiLength -->
]]>
<!ENTITY % Pixels "CDATA" -- integer representing length in pixels -->
<!-- To avoid problems with text-only UAs as well as
to make image content understandable and navigable
to users of non-visual UAs, you need to provide
a description with ALT, and avoid server-side image maps -->
<!ELEMENT IMG - O EMPTY -- Embedded image -->
<!ATTLIST IMG
%attrs; -- %coreattrs, %i18n, %events --
src %URI; #REQUIRED -- URI of image to embed --
alt %Text; #REQUIRED -- short description --
longdesc %URI; #IMPLIED -- link to long description
(complements alt) --
name CDATA #IMPLIED -- name of image for scripting --
height %Length; #IMPLIED -- override height --
width %Length; #IMPLIED -- override width --
usemap %URI; #IMPLIED -- use client-side image map --
ismap (ismap) #IMPLIED -- use server-side image map --
>
<!-- USEMAP points to a MAP element which may be in this document
or an external document, although the latter is not widely supported -->
<!--==================== OBJECT ======================================-->
<!--
OBJECT is used to embed objects as part of HTML pages
PARAM elements should precede other content. SGML mixed content
model technicality precludes specifying this formally ...
-->
<!ELEMENT OBJECT - - (PARAM | %flow;)*
-- generic embedded object -->
<!ATTLIST OBJECT
%attrs; -- %coreattrs, %i18n, %events --
declare (declare) #IMPLIED -- declare but don't instantiate flag --
classid %URI; #IMPLIED -- identifies an implementation --
codebase %URI; #IMPLIED -- base URI for classid, data, archive--
data %URI; #IMPLIED -- reference to object's data --
type %ContentType; #IMPLIED -- content type for data --
codetype %ContentType; #IMPLIED -- content type for code --
archive CDATA #IMPLIED -- space-separated list of URIs --
standby %Text; #IMPLIED -- message to show while loading --
height %Length; #IMPLIED -- override height --
width %Length; #IMPLIED -- override width --
usemap %URI; #IMPLIED -- use client-side image map --
name CDATA #IMPLIED -- submit as part of form --
tabindex NUMBER #IMPLIED -- position in tabbing order --
%reserved; -- reserved for possible future use --
>
<!ELEMENT PARAM - O EMPTY -- named property value -->
<!ATTLIST PARAM
id ID #IMPLIED -- document-wide unique id --
name CDATA #REQUIRED -- property name --
value CDATA #IMPLIED -- property value --
valuetype (DATA|REF|OBJECT) DATA -- How to interpret value --
type %ContentType; #IMPLIED -- content type for value
when valuetype=ref --
>
<!--=================== Horizontal Rule ==================================-->
<!ELEMENT HR - O EMPTY -- horizontal rule -->
<!ATTLIST HR
%attrs; -- %coreattrs, %i18n, %events --
>
<!--=================== Paragraphs =======================================-->
<!ELEMENT P - O (%inline;)* -- paragraph -->
<!ATTLIST P
%attrs; -- %coreattrs, %i18n, %events --
>
<!--=================== Headings =========================================-->
<!--
There are six levels of headings from H1 (the most important)
to H6 (the least important).
-->
<!ELEMENT (%heading;) - - (%inline;)* -- heading -->
<!ATTLIST (%heading;)
%attrs; -- %coreattrs, %i18n, %events --
>
<!--=================== Preformatted Text ================================-->
<!-- excludes markup for images and changes in font size -->
<!ENTITY % pre.exclusion "IMG|OBJECT|BIG|SMALL|SUB|SUP">
<!ELEMENT PRE - - (%inline;)* -(%pre.exclusion;) -- preformatted text -->
<!ATTLIST PRE
%attrs; -- %coreattrs, %i18n, %events --
>
<!--===================== Inline Quotes ==================================-->
<!ELEMENT Q - - (%inline;)* -- short inline quotation -->
<!ATTLIST Q
%attrs; -- %coreattrs, %i18n, %events --
cite %URI; #IMPLIED -- URI for source document or msg --
>
<!--=================== Block-like Quotes ================================-->
<!ELEMENT BLOCKQUOTE - - (%block;|SCRIPT)+ -- long quotation -->
<!ATTLIST BLOCKQUOTE
%attrs; -- %coreattrs, %i18n, %events --
cite %URI; #IMPLIED -- URI for source document or msg --
>
<!--=================== Inserted/Deleted Text ============================-->
<!-- INS/DEL are handled by inclusion on BODY -->
<!ELEMENT (INS|DEL) - - (%flow;)* -- inserted text, deleted text -->
<!ATTLIST (INS|DEL)
%attrs; -- %coreattrs, %i18n, %events --
cite %URI; #IMPLIED -- info on reason for change --
datetime %Datetime; #IMPLIED -- date and time of change --
>
<!--=================== Lists ============================================-->
<!-- definition lists - DT for term, DD for its definition -->
<!ELEMENT DL - - (DT|DD)+ -- definition list -->
<!ATTLIST DL
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT DT - O (%inline;)* -- definition term -->
<!ELEMENT DD - O (%flow;)* -- definition description -->
<!ATTLIST (DT|DD)
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT OL - - (LI)+ -- ordered list -->
<!ATTLIST OL
%attrs; -- %coreattrs, %i18n, %events --
>
<!-- Unordered Lists (UL) bullet styles -->
<!ELEMENT UL - - (LI)+ -- unordered list -->
<!ATTLIST UL
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT LI - O (%flow;)* -- list item -->
<!ATTLIST LI
%attrs; -- %coreattrs, %i18n, %events --
>
<!--================ Forms ===============================================-->
<!ELEMENT FORM - - (%block;|SCRIPT)+ -(FORM) -- interactive form -->
<!ATTLIST FORM
%attrs; -- %coreattrs, %i18n, %events --
action %URI; #REQUIRED -- server-side form handler --
method (GET|POST) GET -- HTTP method used to submit the form--
enctype %ContentType; "application/x-www-form-urlencoded"
accept %ContentTypes; #IMPLIED -- list of MIME types for file upload --
name CDATA #IMPLIED -- name of form for scripting --
onsubmit %Script; #IMPLIED -- the form was submitted --
onreset %Script; #IMPLIED -- the form was reset --
accept-charset %Charsets; #IMPLIED -- list of supported charsets --
>
<!-- Each label must not contain more than ONE field -->
<!ELEMENT LABEL - - (%inline;)* -(LABEL) -- form field label text -->
<!ATTLIST LABEL
%attrs; -- %coreattrs, %i18n, %events --
for IDREF #IMPLIED -- matches field ID value --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
>
<!ENTITY % InputType
"(TEXT | PASSWORD | CHECKBOX |
RADIO | SUBMIT | RESET |
FILE | HIDDEN | IMAGE | BUTTON)"
>
<!-- attribute name required for all but submit and reset -->
<!ELEMENT INPUT - O EMPTY -- form control -->
<!ATTLIST INPUT
%attrs; -- %coreattrs, %i18n, %events --
type %InputType; TEXT -- what kind of widget is needed --
name CDATA #IMPLIED -- submit as part of form --
value CDATA #IMPLIED -- Specify for radio buttons and checkboxes --
checked (checked) #IMPLIED -- for radio buttons and check boxes --
disabled (disabled) #IMPLIED -- unavailable in this context --
readonly (readonly) #IMPLIED -- for text and passwd --
size CDATA #IMPLIED -- specific to each type of field --
maxlength NUMBER #IMPLIED -- max chars for text fields --
src %URI; #IMPLIED -- for fields with images --
alt CDATA #IMPLIED -- short description --
usemap %URI; #IMPLIED -- use client-side image map --
ismap (ismap) #IMPLIED -- use server-side image map --
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
onselect %Script; #IMPLIED -- some text was selected --
onchange %Script; #IMPLIED -- the element value was changed --
accept %ContentTypes; #IMPLIED -- list of MIME types for file upload --
%reserved; -- reserved for possible future use --
>
<!ELEMENT SELECT - - (OPTGROUP|OPTION)+ -- option selector -->
<!ATTLIST SELECT
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #IMPLIED -- field name --
size NUMBER #IMPLIED -- rows visible --
multiple (multiple) #IMPLIED -- default is single selection --
disabled (disabled) #IMPLIED -- unavailable in this context --
tabindex NUMBER #IMPLIED -- position in tabbing order --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
onchange %Script; #IMPLIED -- the element value was changed --
%reserved; -- reserved for possible future use --
>
<!ELEMENT OPTGROUP - - (OPTION)+ -- option group -->
<!ATTLIST OPTGROUP
%attrs; -- %coreattrs, %i18n, %events --
disabled (disabled) #IMPLIED -- unavailable in this context --
label %Text; #REQUIRED -- for use in hierarchical menus --
>
<!ELEMENT OPTION - O (#PCDATA) -- selectable choice -->
<!ATTLIST OPTION
%attrs; -- %coreattrs, %i18n, %events --
selected (selected) #IMPLIED
disabled (disabled) #IMPLIED -- unavailable in this context --
label %Text; #IMPLIED -- for use in hierarchical menus --
value CDATA #IMPLIED -- defaults to element content --
>
<!ELEMENT TEXTAREA - - (#PCDATA) -- multi-line text field -->
<!ATTLIST TEXTAREA
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #IMPLIED
rows NUMBER #REQUIRED
cols NUMBER #REQUIRED
disabled (disabled) #IMPLIED -- unavailable in this context --
readonly (readonly) #IMPLIED
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
onselect %Script; #IMPLIED -- some text was selected --
onchange %Script; #IMPLIED -- the element value was changed --
%reserved; -- reserved for possible future use --
>
<!--
#PCDATA is to solve the mixed content problem,
per specification only whitespace is allowed there!
-->
<!ELEMENT FIELDSET - - (#PCDATA,LEGEND,(%flow;)*) -- form control group -->
<!ATTLIST FIELDSET
%attrs; -- %coreattrs, %i18n, %events --
>
<!ELEMENT LEGEND - - (%inline;)* -- fieldset legend -->
<!ATTLIST LEGEND
%attrs; -- %coreattrs, %i18n, %events --
accesskey %Character; #IMPLIED -- accessibility key character --
>
<!ELEMENT BUTTON - -
(%flow;)* -(A|%formctrl;|FORM|FIELDSET)
-- push button -->
<!ATTLIST BUTTON
%attrs; -- %coreattrs, %i18n, %events --
name CDATA #IMPLIED
value CDATA #IMPLIED -- sent to server when submitted --
type (button|submit|reset) submit -- for use as form button --
disabled (disabled) #IMPLIED -- unavailable in this context --
tabindex NUMBER #IMPLIED -- position in tabbing order --
accesskey %Character; #IMPLIED -- accessibility key character --
onfocus %Script; #IMPLIED -- the element got the focus --
onblur %Script; #IMPLIED -- the element lost the focus --
%reserved; -- reserved for possible future use --
>
<!--======================= Tables =======================================-->
<!-- IETF HTML table standard, see [RFC1942] -->
<!--
The BORDER attribute sets the thickness of the frame around the
table. The default units are screen pixels.
The FRAME attribute specifies which parts of the frame around
the table should be rendered. The values are not the same as
CALS to avoid a name clash with the VALIGN attribute.
The value "border" is included for backwards compatibility with
<TABLE BORDER> which yields frame=border and border=implied
For <TABLE BORDER=1> you get border=1 and frame=implied. In this
case, it is appropriate to treat this as frame=border for backwards
compatibility with deployed browsers.
-->
<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)">
<!--
The RULES attribute defines which rules to draw between cells:
If RULES is absent then assume:
"none" if BORDER is absent or BORDER=0 otherwise "all"
-->
<!ENTITY % TRules "(none | groups | rows | cols | all)">
<!-- horizontal placement of table relative to document -->
<!ENTITY % TAlign "(left|center|right)">
<!-- horizontal alignment attributes for cell contents -->
<!ENTITY % cellhalign
"align (left|center|right|justify|char) #IMPLIED
char %Character; #IMPLIED -- alignment char, e.g. char=':' --
charoff %Length; #IMPLIED -- offset for alignment char --"
>
<!-- vertical alignment attributes for cell contents -->
<!ENTITY % cellvalign
"valign (top|middle|bottom|baseline) #IMPLIED"
>
<!ELEMENT TABLE - -
(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
<!ELEMENT CAPTION - - (%inline;)* -- table caption -->
<!ELEMENT THEAD - O (TR)+ -- table header -->
<!ELEMENT TFOOT - O (TR)+ -- table footer -->
<!ELEMENT TBODY O O (TR)+ -- table body -->
<!ELEMENT COLGROUP - O (COL)* -- table column group -->
<!ELEMENT COL - O EMPTY -- table column -->
<!ELEMENT TR - O (TH|TD)+ -- table row -->
<!ELEMENT (TH|TD) - O (%flow;)* -- table header cell, table data cell-->
<!ATTLIST TABLE -- table element --
%attrs; -- %coreattrs, %i18n, %events --
summary %Text; #IMPLIED -- purpose/structure for speech output--
width %Length; #IMPLIED -- table width --
border %Pixels; #IMPLIED -- controls frame width around table --
frame %TFrame; #IMPLIED -- which parts of frame to render --
rules %TRules; #IMPLIED -- rulings between rows and cols --
cellspacing %Length; #IMPLIED -- spacing between cells --
cellpadding %Length; #IMPLIED -- spacing within cells --
%reserved; -- reserved for possible future use --
datapagesize CDATA #IMPLIED -- reserved for possible future use --
>
<!ATTLIST CAPTION
%attrs; -- %coreattrs, %i18n, %events --
>
<!--
COLGROUP groups a set of COL elements. It allows you to group
several semantically related columns together.
-->
<!ATTLIST COLGROUP
%attrs; -- %coreattrs, %i18n, %events --
span NUMBER 1 -- default number of columns in group --
width %MultiLength; #IMPLIED -- default width for enclosed COLs --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>
<!--
COL elements define the alignment properties for cells in
one or more columns.
The WIDTH attribute specifies the width of the columns, e.g.
width=64 width in screen pixels
width=0.5* relative width of 0.5
The SPAN attribute causes the attributes of one
COL element to apply to more than one column.
-->
<!ATTLIST COL -- column groups and properties --
%attrs; -- %coreattrs, %i18n, %events --
span NUMBER 1 -- COL attributes affect N columns --
width %MultiLength; #IMPLIED -- column width specification --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>
<!--
Use THEAD to duplicate headers when breaking table
across page boundaries, or for static headers when
TBODY sections are rendered in scrolling panel.
Use TFOOT to duplicate footers when breaking table
across page boundaries, or for static footers when
TBODY sections are rendered in scrolling panel.
Use multiple TBODY sections when rules are needed
between groups of table rows.
-->
<!ATTLIST (THEAD|TBODY|TFOOT) -- table section --
%attrs; -- %coreattrs, %i18n, %events --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>
<!ATTLIST TR -- table row --
%attrs; -- %coreattrs, %i18n, %events --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>
<!-- Scope is simpler than headers attribute for common tables -->
<!ENTITY % Scope "(row|col|rowgroup|colgroup)">
<!-- TH is for headers, TD for data, but for cells acting as both use TD -->
<!ATTLIST (TH|TD) -- header or data cell --
%attrs; -- %coreattrs, %i18n, %events --
abbr %Text; #IMPLIED -- abbreviation for header cell --
axis CDATA #IMPLIED -- comma-separated list of related headers--
headers IDREFS #IMPLIED -- list of id's for header cells --
scope %Scope; #IMPLIED -- scope covered by header cells --
rowspan NUMBER 1 -- number of rows spanned by cell --
colspan NUMBER 1 -- number of cols spanned by cell --
%cellhalign; -- horizontal alignment in cells --
%cellvalign; -- vertical alignment in cells --
>
<!--================ Document Head =======================================-->
<!-- %head.misc; defined earlier on as "SCRIPT|STYLE|META|LINK|OBJECT" -->
<!ENTITY % head.content "TITLE & BASE?">
<!ELEMENT HEAD O O (%head.content;) +(%head.misc;) -- document head -->
<!ATTLIST HEAD
%i18n; -- lang, dir --
profile %URI; #IMPLIED -- named dictionary of meta info --
>
<!-- The TITLE element is not considered part of the flow of text.
It should be displayed, for example as the page header or
window title. Exactly one title is required per document.
-->
<!ELEMENT TITLE - - (#PCDATA) -(%head.misc;) -- document title -->
<!ATTLIST TITLE %i18n>
<!ELEMENT BASE - O EMPTY -- document base URI -->
<!ATTLIST BASE
href %URI; #REQUIRED -- URI that acts as base URI --
>
<!ELEMENT META - O EMPTY -- generic metainformation -->
<!ATTLIST META
%i18n; -- lang, dir, for use with content --
http-equiv NAME #IMPLIED -- HTTP response header name --
name NAME #IMPLIED -- metainformation name --
content CDATA #REQUIRED -- associated information --
scheme CDATA #IMPLIED -- select form of content --
>
<!ELEMENT STYLE - - %StyleSheet -- style info -->
<!ATTLIST STYLE
%i18n; -- lang, dir, for use with title --
type %ContentType; #REQUIRED -- content type of style language --
media %MediaDesc; #IMPLIED -- designed for use with these media --
title %Text; #IMPLIED -- advisory title --
>
<!ELEMENT SCRIPT - - %Script; -- script statements -->
<!ATTLIST SCRIPT
charset %Charset; #IMPLIED -- char encoding of linked resource --
type %ContentType; #REQUIRED -- content type of script language --
src %URI; #IMPLIED -- URI for an external script --
defer (defer) #IMPLIED -- UA may defer execution of script --
event CDATA #IMPLIED -- reserved for possible future use --
for %URI; #IMPLIED -- reserved for possible future use --
>
<!ELEMENT NOSCRIPT - - (%block;)+
-- alternate content container for non script-based rendering -->
<!ATTLIST NOSCRIPT
%attrs; -- %coreattrs, %i18n, %events --
>
<!--================ Document Structure ==================================-->
<!ENTITY % html.content "HEAD, BODY">
<!ELEMENT HTML O O (%html.content;) -- document root element -->
<!ATTLIST HTML
%i18n; -- lang, dir --
>
#!/usr/local/bin/node-bench
var Promise = require("events").Promise;
var xml = require("posix").cat("test.xml").wait(),
path = require("path"),
sax = require("../lib/sax"),
saxT = require("../lib/sax-trampoline"),
parser = sax.parser(false, {trim:true}),
parserT = saxT.parser(false, {trim:true}),
sys = require("sys");
var count = exports.stepsPerLap = 500,
l = xml.length,
runs = 0;
exports.countPerLap = 1000;
exports.compare = {
"switch" : function () {
// sys.debug("switch runs: "+runs++);
// for (var x = 0; x < l; x += 1000) {
// parser.write(xml.substr(x, 1000))
// }
// for (var i = 0; i < count; i ++) {
parser.write(xml);
parser.close();
// }
// done();
},
trampoline : function () {
// sys.debug("trampoline runs: "+runs++);
// for (var x = 0; x < l; x += 1000) {
// parserT.write(xml.substr(x, 1000))
// }
// for (var i = 0; i < count; i ++) {
parserT.write(xml);
parserT.close();
// }
// done();
},
};
sys.debug("rock and roll...");
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<title>testing the parser</title>
</head>
<body>
<p>hello
<script>
</script>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE RootElement [
<!ENTITY e SYSTEM "001.ent">
]>
<RootElement param="value">
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
<FirstElement>
Some Text
</FirstElement>
<?some_pi some_attr="some_value"?>
<!-- this is a comment -- but this isnt part of the comment -->
<!-- this is a comment == and this is a part of the comment -->
<!-- this is a comment > and this is also part of the thing -->
<!invalid comment>
<![CDATA[ this is random stuff. & and < and > are ok in here. ]]>
<SecondElement param2="something">
Pre-Text &amp; <Inline>Inlined text</Inline> Post-text.
&#xF8FF;
</SecondElement>
</RootElement>
\ No newline at end of file
// set this really low so that I don't have to put 64 MB of xml in here.
var sax = require("../lib/sax")
var bl = sax.MAX_BUFFER_LENGTH
sax.MAX_BUFFER_LENGTH = 5;
require(__dirname).test({
expect : [
["error", "Max buffer length exceeded: tagName\nLine: 0\nColumn: 15\nChar: "],
["error", "Max buffer length exceeded: tagName\nLine: 0\nColumn: 30\nChar: "],
["error", "Max buffer length exceeded: tagName\nLine: 0\nColumn: 45\nChar: "],
["opentag", {
"name": "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ",
"attributes": {}
}],
["text", "yo"],
["closetag", "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"]
]
}).write("<abcdefghijklmn")
.write("opqrstuvwxyzABC")
.write("DEFGHIJKLMNOPQR")
.write("STUVWXYZ>")
.write("yo")
.write("</abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ>")
.close();
sax.MAX_BUFFER_LENGTH = bl
require(__dirname).test({
expect : [
["opentag", {"name": "R","attributes": {}}],
["opencdata", undefined],
["cdata", " this is character data  "],
["closecdata", undefined],
["closetag", "R"]
]
}).write("<r><![CDATA[ this is ").write("character data  ").write("]]></r>").close();
require(__dirname).test({
expect : [
["opentag", {"name": "R","attributes": {}}],
["opencdata", undefined],
["cdata", " this is "],
["closecdata", undefined],
["closetag", "R"]
]
})
.write("<r><![CDATA[ this is ]")
.write("]>")
.write("</r>")
.close();
var p = require(__dirname).test({
expect : [
["opentag", {"name": "R","attributes": {}}],
["opencdata", undefined],
["cdata", "[[[[[[[[]]]]]]]]"],
["closecdata", undefined],
["closetag", "R"]
]
})
var x = "<r><![CDATA[[[[[[[[[]]]]]]]]]]></r>"
for (var i = 0; i < x.length ; i ++) {
p.write(x.charAt(i))
}
p.close();
var p2 = require(__dirname).test({
expect : [
["opentag", {"name": "R","attributes": {}}],
["opencdata", undefined],
["cdata", "[[[[[[[[]]]]]]]]"],
["closecdata", undefined],
["closetag", "R"]
]
})
var x = "<r><![CDATA[[[[[[[[[]]]]]]]]]]></r>"
p2.write(x).close();
require(__dirname).test({
expect : [
["opentag", {"name": "R","attributes": {}}],
["opencdata", undefined],
["cdata", " this is "],
["closecdata", undefined],
["opencdata", undefined],
["cdata", "character data  "],
["closecdata", undefined],
["closetag", "R"]
]
}).write("<r><![CDATA[ this is ]]>").write("<![CDA").write("T").write("A[")
.write("character data  ").write("]]></r>").close();
require(__dirname).test({
xml : "<r><![CDATA[ this is character data  ]]></r>",
expect : [
["opentag", {"name": "R","attributes": {}}],
["opencdata", undefined],
["cdata", " this is character data  "],
["closecdata", undefined],
["closetag", "R"]
]
});
var globalsBefore = JSON.stringify(Object.keys(global))
, util = require("util")
, assert = require("assert")
, fs = require("fs")
, path = require("path")
, sax = require("../lib/sax")
exports.sax = sax
// handy way to do simple unit tests
// if the options contains an xml string, it'll be written and the parser closed.
// otherwise, it's assumed that the test will write and close.
exports.test = function test (options) {
var xml = options.xml
, parser = sax.parser(options.strict, options.opt)
, expect = options.expect
, e = 0
sax.EVENTS.forEach(function (ev) {
parser["on" + ev] = function (n) {
if (process.env.DEBUG) {
console.error({ expect: expect[e]
, actual: [ev, n] })
}
if (e >= expect.length && (ev === "end" || ev === "ready")) return
assert.ok( e < expect.length,
"expectation #"+e+" "+util.inspect(expect[e])+"\n"+
"Unexpected event: "+ev+" "+(n ? util.inspect(n) : ""))
var inspected = n instanceof Error ? "\n"+ n.message : util.inspect(n)
assert.equal(ev, expect[e][0],
"expectation #"+e+"\n"+
"Didn't get expected event\n"+
"expect: "+expect[e][0] + " " +util.inspect(expect[e][1])+"\n"+
"actual: "+ev+" "+inspected+"\n")
if (ev === "error") assert.equal(n.message, expect[e][1])
else assert.deepEqual(n, expect[e][1],
"expectation #"+e+"\n"+
"Didn't get expected argument\n"+
"expect: "+expect[e][0] + " " +util.inspect(expect[e][1])+"\n"+
"actual: "+ev+" "+inspected+"\n")
e++
if (ev === "error") parser.resume()
}
})
if (xml) parser.write(xml).close()
return parser
}
if (module === require.main) {
var running = true
, failures = 0
function fail (file, er) {
util.error("Failed: "+file)
util.error(er.stack || er.message)
failures ++
}
fs.readdir(__dirname, function (error, files) {
files = files.filter(function (file) {
return (/\.js$/.exec(file) && file !== 'index.js')
})
var n = files.length
, i = 0
console.log("0.." + n)
files.forEach(function (file) {
// run this test.
try {
require(path.resolve(__dirname, file))
var globalsAfter = JSON.stringify(Object.keys(global))
if (globalsAfter !== globalsBefore) {
var er = new Error("new globals introduced\n"+
"expected: "+globalsBefore+"\n"+
"actual: "+globalsAfter)
globalsBefore = globalsAfter
throw er
}
console.log("ok " + (++i) + " - " + file)
} catch (er) {
console.log("not ok "+ (++i) + " - " + file)
fail(file, er)
}
})
if (!failures) return console.log("#all pass")
else return console.error(failures + " failure" + (failures > 1 ? "s" : ""))
})
}
require(__dirname).test
( { xml :
"<compileClassesResponse>"+
"<result>"+
"<bodyCrc>653724009</bodyCrc>"+
"<column>-1</column>"+
"<id>01pG0000002KoSUIA0</id>"+
"<line>-1</line>"+
"<name>CalendarController</name>"+
"<success>true</success>"+
"</result>"+
"</compileClassesResponse>"
, expect :
[ [ "opentag", { name: "COMPILECLASSESRESPONSE", attributes: {} } ]
, [ "opentag", { name : "RESULT", attributes: {} } ]
, [ "opentag", { name: "BODYCRC", attributes: {} } ]
, [ "text", "653724009" ]
, [ "closetag", "BODYCRC" ]
, [ "opentag", { name: "COLUMN", attributes: {} } ]
, [ "text", "-1" ]
, [ "closetag", "COLUMN" ]
, [ "opentag", { name: "ID", attributes: {} } ]
, [ "text", "01pG0000002KoSUIA0" ]
, [ "closetag", "ID" ]
, [ "opentag", {name: "LINE", attributes: {} } ]
, [ "text", "-1" ]
, [ "closetag", "LINE" ]
, [ "opentag", {name: "NAME", attributes: {} } ]
, [ "text", "CalendarController" ]
, [ "closetag", "NAME" ]
, [ "opentag", {name: "SUCCESS", attributes: {} } ]
, [ "text", "true" ]
, [ "closetag", "SUCCESS" ]
, [ "closetag", "RESULT" ]
, [ "closetag", "COMPILECLASSESRESPONSE" ]
]
, strict : false
, opt : {}
}
)
// https://github.com/isaacs/sax-js/issues/33
require(__dirname).test
( { xml : "<xml>\n"+
"<!-- \n"+
" comment with a single dash- in it\n"+
"-->\n"+
"<data/>\n"+
"</xml>"
, expect :
[ [ "opentag", { name: "xml", attributes: {} } ]
, [ "text", "\n" ]
, [ "comment", " \n comment with a single dash- in it\n" ]
, [ "text", "\n" ]
, [ "opentag", { name: "data", attributes: {} } ]
, [ "closetag", "data" ]
, [ "text", "\n" ]
, [ "closetag", "xml" ]
]
, strict : true
, opt : {}
}
)
// https://github.com/isaacs/sax-js/issues/35
require(__dirname).test
( { xml : "<xml>&#Xd;&#X0d;\n"+
"</xml>"
, expect :
[ [ "opentag", { name: "xml", attributes: {} } ]
, [ "text", "\r\r\n" ]
, [ "closetag", "xml" ]
]
, strict : true
, opt : {}
}
)
// https://github.com/isaacs/sax-js/issues/47
require(__dirname).test
( { xml : '<a href="query.svc?x=1&y=2&z=3"/>'
, expect : [
[ "attribute", { name:'href', value:"query.svc?x=1&y=2&z=3"} ],
[ "opentag", { name: "a", attributes: { href:"query.svc?x=1&y=2&z=3"} } ],
[ "closetag", "a" ]
]
, strict : true
, opt : {}
}
)
// https://github.com/isaacs/sax-js/issues/49
require(__dirname).test
( { xml : "<xml><script>hello world</script></xml>"
, expect :
[ [ "opentag", { name: "xml", attributes: {} } ]
, [ "opentag", { name: "script", attributes: {} } ]
, [ "text", "hello world" ]
, [ "closetag", "script" ]
, [ "closetag", "xml" ]
]
, strict : false
, opt : { lowercasetags: true, noscript: true }
}
)
require(__dirname).test
( { xml : "<xml><script><![CDATA[hello world]]></script></xml>"
, expect :
[ [ "opentag", { name: "xml", attributes: {} } ]
, [ "opentag", { name: "script", attributes: {} } ]
, [ "opencdata", undefined ]
, [ "cdata", "hello world" ]
, [ "closecdata", undefined ]
, [ "closetag", "script" ]
, [ "closetag", "xml" ]
]
, strict : false
, opt : { lowercasetags: true, noscript: true }
}
)
var sax = require("../lib/sax"),
assert = require("assert")
function testPosition(chunks, expectedEvents) {
var parser = sax.parser();
expectedEvents.forEach(function(expectation) {
parser['on' + expectation[0]] = function() {
for (var prop in expectation[1]) {
assert.equal(parser[prop], expectation[1][prop]);
}
}
});
chunks.forEach(function(chunk) {
parser.write(chunk);
});
};
testPosition(['<div>abcdefgh</div>'],
[ ['opentag', { position: 5, startTagPosition: 1 }]
, ['text', { position: 19, startTagPosition: 14 }]
, ['closetag', { position: 19, startTagPosition: 14 }]
]);
testPosition(['<div>abcde','fgh</div>'],
[ ['opentag', { position: 5, startTagPosition: 1 }]
, ['text', { position: 19, startTagPosition: 14 }]
, ['closetag', { position: 19, startTagPosition: 14 }]
]);
require(__dirname).test({
xml : "<html><head><script>if (1 < 0) { console.log('elo there'); }</script></head></html>",
expect : [
["opentag", {"name": "HTML","attributes": {}}],
["opentag", {"name": "HEAD","attributes": {}}],
["opentag", {"name": "SCRIPT","attributes": {}}],
["script", "if (1 < 0) { console.log('elo there'); }"],
["closetag", "SCRIPT"],
["closetag", "HEAD"],
["closetag", "HTML"]
]
});
require(__dirname).test({
xml :
"<root>"+
"<child>" +
"<haha />" +
"</child>" +
"<monkey>" +
"=(|)" +
"</monkey>" +
"</root>",
expect : [
["opentag", {
"name": "root",
"attributes": {}
}],
["opentag", {
"name": "child",
"attributes": {}
}],
["opentag", {
"name": "haha",
"attributes": {}
}],
["closetag", "haha"],
["closetag", "child"],
["opentag", {
"name": "monkey",
"attributes": {}
}],
["text", "=(|)"],
["closetag", "monkey"],
["closetag", "root"],
["end"],
["ready"]
],
strict : true,
opt : {}
});
require(__dirname).test({
xml :
"<root>"+
"<child>" +
"<haha />" +
"</child>" +
"<monkey>" +
"=(|)" +
"</monkey>" +
"</root>",
expect : [
["opentag", {
"name": "ROOT",
"attributes": {}
}],
["opentag", {
"name": "CHILD",
"attributes": {}
}],
["opentag", {
"name": "HAHA",
"attributes": {}
}],
["closetag", "HAHA"],
["closetag", "CHILD"],
["opentag", {
"name": "MONKEY",
"attributes": {}
}],
["text", "=(|)"],
["closetag", "MONKEY"],
["closetag", "ROOT"],
["end"],
["ready"]
],
strict : false,
opt : {}
});
require(__dirname).test({
xml :
"<root> "+
"<haha /> "+
"<haha/> "+
"<monkey> "+
"=(|) "+
"</monkey>"+
"</root> ",
expect : [
["opentag", {name:"ROOT", attributes:{}}],
["opentag", {name:"HAHA", attributes:{}}],
["closetag", "HAHA"],
["opentag", {name:"HAHA", attributes:{}}],
["closetag", "HAHA"],
// ["opentag", {name:"HAHA", attributes:{}}],
// ["closetag", "HAHA"],
["opentag", {name:"MONKEY", attributes:{}}],
["text", "=(|)"],
["closetag", "MONKEY"],
["closetag", "ROOT"]
],
opt : { trim : true }
});
\ No newline at end of file
// stray ending tags should just be ignored in non-strict mode.
// https://github.com/isaacs/sax-js/issues/32
require(__dirname).test
( { xml :
"<a><b></c></b></a>"
, expect :
[ [ "opentag", { name: "A", attributes: {} } ]
, [ "opentag", { name: "B", attributes: {} } ]
, [ "text", "</c>" ]
, [ "closetag", "B" ]
, [ "closetag", "A" ]
]
, strict : false
, opt : {}
}
)
require(__dirname).test({
xml : "<span>Welcome,</span> to monkey land",
expect : [
["opentag", {
"name": "SPAN",
"attributes": {}
}],
["text", "Welcome,"],
["closetag", "SPAN"],
["text", " to monkey land"],
["end"],
["ready"]
],
strict : false,
opt : {}
});
// unquoted attributes should be ok in non-strict mode
// https://github.com/isaacs/sax-js/issues/31
require(__dirname).test
( { xml :
"<span class=test hello=world></span>"
, expect :
[ [ "attribute", { name: "class", value: "test" } ]
, [ "attribute", { name: "hello", value: "world" } ]
, [ "opentag", { name: "SPAN",
attributes: { class: "test", hello: "world" } } ]
, [ "closetag", "SPAN" ]
]
, strict : false
, opt : {}
}
)
var t = require(__dirname)
, xmls = // should be the same both ways.
[ "<parent xmlns:a='http://ATTRIBUTE' a:attr='value' />"
, "<parent a:attr='value' xmlns:a='http://ATTRIBUTE' />" ]
, ex1 =
[ [ "opennamespace"
, { prefix: "a"
, uri: "http://ATTRIBUTE"
}
]
, [ "attribute"
, { name: "xmlns:a"
, value: "http://ATTRIBUTE"
, prefix: "xmlns"
, local: "a"
, uri: "http://www.w3.org/2000/xmlns/"
}
]
, [ "attribute"
, { name: "a:attr"
, local: "attr"
, prefix: "a"
, uri: "http://ATTRIBUTE"
, value: "value"
}
]
, [ "opentag"
, { name: "parent"
, uri: ""
, prefix: ""
, local: "parent"
, attributes:
{ "a:attr":
{ name: "a:attr"
, local: "attr"
, prefix: "a"
, uri: "http://ATTRIBUTE"
, value: "value"
}
, "xmlns:a":
{ name: "xmlns:a"
, local: "a"
, prefix: "xmlns"
, uri: "http://www.w3.org/2000/xmlns/"
, value: "http://ATTRIBUTE"
}
}
, ns: {"a": "http://ATTRIBUTE"}
}
]
, ["closetag", "parent"]
, ["closenamespace", { prefix: "a", uri: "http://ATTRIBUTE" }]
]
// swap the order of elements 2 and 1
, ex2 = [ex1[0], ex1[2], ex1[1]].concat(ex1.slice(3))
, expected = [ex1, ex2]
xmls.forEach(function (x, i) {
t.test({ xml: x
, expect: expected[i]
, strict: true
, opt: { xmlns: true }
})
})
require(__dirname).test
( { xml :
"<root xmlns:x='x1' xmlns:y='y1' x:a='x1' y:a='y1'>"+
"<rebind xmlns:x='x2'>"+
"<check x:a='x2' y:a='y1'/>"+
"</rebind>"+
"<check x:a='x1' y:a='y1'/>"+
"</root>"
, expect :
[ [ "opennamespace", { prefix: "x", uri: "x1" } ]
, [ "opennamespace", { prefix: "y", uri: "y1" } ]
, [ "attribute", { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ]
, [ "attribute", { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" } ]
, [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ]
, [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ]
, [ "opentag", { name: "root", uri: "", prefix: "", local: "root",
attributes: { "xmlns:x": { name: "xmlns:x", value: "x1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" }
, "xmlns:y": { name: "xmlns:y", value: "y1", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "y" }
, "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" }
, "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } },
ns: { x: 'x1', y: 'y1' } } ]
, [ "opennamespace", { prefix: "x", uri: "x2" } ]
, [ "attribute", { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } ]
, [ "opentag", { name: "rebind", uri: "", prefix: "", local: "rebind",
attributes: { "xmlns:x": { name: "xmlns:x", value: "x2", uri: "http://www.w3.org/2000/xmlns/", prefix: "xmlns", local: "x" } },
ns: { x: 'x2' } } ]
, [ "attribute", { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" } ]
, [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ]
, [ "opentag", { name: "check", uri: "", prefix: "", local: "check",
attributes: { "x:a": { name: "x:a", value: "x2", uri: "x2", prefix: "x", local: "a" }
, "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } },
ns: { x: 'x2' } } ]
, [ "closetag", "check" ]
, [ "closetag", "rebind" ]
, [ "closenamespace", { prefix: "x", uri: "x2" } ]
, [ "attribute", { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" } ]
, [ "attribute", { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } ]
, [ "opentag", { name: "check", uri: "", prefix: "", local: "check",
attributes: { "x:a": { name: "x:a", value: "x1", uri: "x1", prefix: "x", local: "a" }
, "y:a": { name: "y:a", value: "y1", uri: "y1", prefix: "y", local: "a" } },
ns: { x: 'x1', y: 'y1' } } ]
, [ "closetag", "check" ]
, [ "closetag", "root" ]
, [ "closenamespace", { prefix: "x", uri: "x1" } ]
, [ "closenamespace", { prefix: "y", uri: "y1" } ]
]
, strict : true
, opt : { xmlns: true }
}
)
require(__dirname).test
( { xml :
"<root>"+
"<plain attr='normal'/>"+
"<ns1 xmlns='uri:default'>"+
"<plain attr='normal'/>"+
"</ns1>"+
"<ns2 xmlns:a='uri:nsa'>"+
"<plain attr='normal'/>"+
"<a:ns a:attr='namespaced'/>"+
"</ns2>"+
"</root>"
, expect :
[ [ "opentag", { name: "root", prefix: "", local: "root", uri: "",
attributes: {}, ns: {} } ]
, [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ]
, [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "",
attributes: { "attr": { name: "attr", value: "normal", uri: "", prefix: "", local: "attr", uri: "" } },
ns: {} } ]
, [ "closetag", "plain" ]
, [ "opennamespace", { prefix: "", uri: "uri:default" } ]
, [ "attribute", { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } ]
, [ "opentag", { name: "ns1", prefix: "", local: "ns1", uri: "uri:default",
attributes: { "xmlns": { name: "xmlns", value: "uri:default", prefix: "xmlns", local: "", uri: "http://www.w3.org/2000/xmlns/" } },
ns: { "": "uri:default" } } ]
, [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "uri:default" } ]
, [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "uri:default", ns: { '': 'uri:default' },
attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "uri:default" } } } ]
, [ "closetag", "plain" ]
, [ "closetag", "ns1" ]
, [ "closenamespace", { prefix: "", uri: "uri:default" } ]
, [ "opennamespace", { prefix: "a", uri: "uri:nsa" } ]
, [ "attribute", { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } ]
, [ "opentag", { name: "ns2", prefix: "", local: "ns2", uri: "",
attributes: { "xmlns:a": { name: "xmlns:a", value: "uri:nsa", prefix: "xmlns", local: "a", uri: "http://www.w3.org/2000/xmlns/" } },
ns: { a: "uri:nsa" } } ]
, [ "attribute", { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } ]
, [ "opentag", { name: "plain", prefix: "", local: "plain", uri: "",
attributes: { "attr": { name: "attr", value: "normal", prefix: "", local: "attr", uri: "" } },
ns: { a: 'uri:nsa' } } ]
, [ "closetag", "plain" ]
, [ "attribute", { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } ]
, [ "opentag", { name: "a:ns", prefix: "a", local: "ns", uri: "uri:nsa",
attributes: { "a:attr": { name: "a:attr", value: "namespaced", prefix: "a", local: "attr", uri: "uri:nsa" } },
ns: { a: 'uri:nsa' } } ]
, [ "closetag", "a:ns" ]
, [ "closetag", "ns2" ]
, [ "closenamespace", { prefix: "a", uri: "uri:nsa" } ]
, [ "closetag", "root" ]
]
, strict : true
, opt : { xmlns: true }
}
)
require(__dirname).test(
{ strict : true
, opt : { xmlns: true }
, expect :
[ ["error", "Unbound namespace prefix: \"unbound\"\nLine: 0\nColumn: 28\nChar: >"]
, [ "attribute", { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } ]
, [ "opentag", { name: "root", uri: "", prefix: "", local: "root",
attributes: { "unbound:attr": { name: "unbound:attr", value: "value", uri: "unbound", prefix: "unbound", local: "attr" } },
ns: {} } ]
, [ "closetag", "root" ]
]
}
).write("<root unbound:attr='value'/>")
require(__dirname).test(
{ xml : "<root xml:lang='en'/>"
, expect :
[ [ "attribute"
, { name: "xml:lang"
, local: "lang"
, prefix: "xml"
, uri: "http://www.w3.org/XML/1998/namespace"
, value: "en"
}
]
, [ "opentag"
, { name: "root"
, uri: ""
, prefix: ""
, local: "root"
, attributes:
{ "xml:lang":
{ name: "xml:lang"
, local: "lang"
, prefix: "xml"
, uri: "http://www.w3.org/XML/1998/namespace"
, value: "en"
}
}
, ns: {}
}
]
, ["closetag", "root"]
]
, strict : true
, opt : { xmlns: true }
}
)
require(__dirname).test(
{ xml : "<xml:root/>"
, expect :
[
[ "opentag"
, { name: "xml:root"
, uri: "http://www.w3.org/XML/1998/namespace"
, prefix: "xml"
, local: "root"
, attributes: {}
, ns: {}
}
]
, ["closetag", "xml:root"]
]
, strict : true
, opt : { xmlns: true }
}
)
require(__dirname).test(
{ xml : "<xml:root xmlns:xml='ERROR'/>"
, expect :
[ ["error"
, "xml: prefix must be bound to http://www.w3.org/XML/1998/namespace\n"
+ "Actual: ERROR\n"
+ "Line: 0\nColumn: 27\nChar: '"
]
, [ "attribute"
, { name: "xmlns:xml"
, local: "xml"
, prefix: "xmlns"
, uri: "http://www.w3.org/2000/xmlns/"
, value: "ERROR"
}
]
, [ "opentag"
, { name: "xml:root"
, uri: "http://www.w3.org/XML/1998/namespace"
, prefix: "xml"
, local: "root"
, attributes:
{ "xmlns:xml":
{ name: "xmlns:xml"
, local: "xml"
, prefix: "xmlns"
, uri: "http://www.w3.org/2000/xmlns/"
, value: "ERROR"
}
}
, ns: {}
}
]
, ["closetag", "xml:root"]
]
, strict : true
, opt : { xmlns: true }
}
)
<?xml version="1.0"?>
<container name="test_container_1" xmlns:android="http://schemas.android.com/apk/res/android">
<object>dd
<name>test_object_1</name>
<hash>4281c348eaf83e70ddce0e07221c3d28</hash>
<bytes android:type="cool">14</bytes>
<content_type>application/octetstream</content_type>
<last_modified>2009-02-03T05:26:32.612278</last_modified>
</object>
<object>
<name>test_object_2</name>
<hash>b039efe731ad111bc1b0ef221c3849d0</hash>
<bytes android:type="lame">64</bytes>
<content_type>application/octetstream</content_type>
<last_modified>2009-02-03T05:26:32.612278</last_modified>
</object>
</container>
<?xml version="1.0"?>
<object>
<title>
Hello World
</title>
<children>
<object id="obj1" />
<object id="obj2" />
<object id="obj3" />
</children>
<text><![CDATA[
Test & Test & Test
]]></text>
</object>
/**
* Copyright 2011 Rackspace
*
* 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.
*
*/
var fs = require('fs');
var path = require('path');
var sprintf = require('./../lib/sprintf').sprintf;
var et = require('elementtree');
var XML = et.XML;
var ElementTree = et.ElementTree;
var Element = et.Element;
var SubElement = et.SubElement;
var SyntaxError = require('./../lib/errors').SyntaxError;
function readFile(name) {
return fs.readFileSync(path.join(__dirname, '/data/', name), 'utf8');
}
exports['test_simplest'] = function(test, assert) {
/* Ported from <https://github.com/lxml/lxml/blob/master/src/lxml/tests/test_elementtree.py> */
var Element = et.Element;
var root = Element('root');
root.append(Element('one'));
root.append(Element('two'));
root.append(Element('three'));
assert.equal(3, root.len());
assert.equal('one', root.getItem(0).tag);
assert.equal('two', root.getItem(1).tag);
assert.equal('three', root.getItem(2).tag);
test.finish();
};
exports['test_attribute_values'] = function(test, assert) {
var XML = et.XML;
var root = XML('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>');
assert.equal('Alpha', root.attrib['alpha']);
assert.equal('Beta', root.attrib['beta']);
assert.equal('Gamma', root.attrib['gamma']);
test.finish();
};
exports['test_findall'] = function(test, assert) {
var XML = et.XML;
var root = XML('<a><b><c/></b><b/><c><b/></c></a>');
assert.equal(root.findall("c").length, 1);
assert.equal(root.findall(".//c").length, 2);
assert.equal(root.findall(".//b").length, 3);
assert.equal(root.findall(".//b")[0]._children.length, 1);
assert.equal(root.findall(".//b")[1]._children.length, 0);
assert.equal(root.findall(".//b")[2]._children.length, 0);
assert.deepEqual(root.findall('.//b')[0], root.getchildren()[0]);
test.finish();
};
exports['test_find'] = function(test, assert) {
var a = Element('a');
var b = SubElement(a, 'b');
var c = SubElement(a, 'c');
assert.deepEqual(a.find('./b/..'), a);
test.finish();
};
exports['test_elementtree_find_qname'] = function(test, assert) {
var tree = new et.ElementTree(XML('<a><b><c/></b><b/><c><b/></c></a>'));
assert.deepEqual(tree.find(new et.QName('c')), tree.getroot()._children[2]);
test.finish();
};
exports['test_attrib_ns_clear'] = function(test, assert) {
var attribNS = '{http://foo/bar}x';
var par = Element('par');
par.set(attribNS, 'a');
var child = SubElement(par, 'child');
child.set(attribNS, 'b');
assert.equal('a', par.get(attribNS));
assert.equal('b', child.get(attribNS));
par.clear();
assert.equal(null, par.get(attribNS));
assert.equal('b', child.get(attribNS));
test.finish();
};
exports['test_create_tree_and_parse_simple'] = function(test, assert) {
var i = 0;
var e = new Element('bar', {});
var expected = "<?xml version='1.0' encoding='utf-8'?>\n" +
'<bar><blah a="11" /><blah a="12" /><gag a="13" b="abc">ponies</gag></bar>';
SubElement(e, "blah", {a: 11});
SubElement(e, "blah", {a: 12});
var se = et.SubElement(e, "gag", {a: '13', b: 'abc'});
se.text = 'ponies';
se.itertext(function(text) {
assert.equal(text, 'ponies');
i++;
});
assert.equal(i, 1);
var etree = new ElementTree(e);
var xml = etree.write();
assert.equal(xml, expected);
test.finish();
};
exports['test_write_with_options'] = function(test, assert) {
var i = 0;
var e = new Element('bar', {});
var expected1 = "<?xml version='1.0' encoding='utf-8'?>\n" +
'<bar>\n' +
' <blah a="11">\n' +
' <baz d="11">test</baz>\n' +
' </blah>\n' +
' <blah a="12" />\n' +
' <gag a="13" b="abc">ponies</gag>\n' +
'</bar>\n';
var expected2 = "<?xml version='1.0' encoding='utf-8'?>\n" +
'<bar>\n' +
' <blah a="11">\n' +
' <baz d="11">test</baz>\n' +
' </blah>\n' +
' <blah a="12" />\n' +
' <gag a="13" b="abc">ponies</gag>\n' +
'</bar>\n';
var expected3 = "<?xml version='1.0' encoding='utf-8'?>\n" +
'<object>\n' +
' <title>\n' +
' Hello World\n' +
' </title>\n' +
' <children>\n' +
' <object id="obj1" />\n' +
' <object id="obj2" />\n' +
' <object id="obj3" />\n' +
' </children>\n' +
' <text>\n' +
' Test &amp; Test &amp; Test\n' +
' </text>\n' +
'</object>\n';
var se1 = SubElement(e, "blah", {a: 11});
var se2 = SubElement(se1, "baz", {d: 11});
se2.text = 'test';
SubElement(e, "blah", {a: 12});
var se = et.SubElement(e, "gag", {a: '13', b: 'abc'});
se.text = 'ponies';
se.itertext(function(text) {
assert.equal(text, 'ponies');
i++;
});
assert.equal(i, 1);
var etree = new ElementTree(e);
var xml1 = etree.write({'indent': 4});
var xml2 = etree.write({'indent': 2});
assert.equal(xml1, expected1);
assert.equal(xml2, expected2);
var file = readFile('xml2.xml');
var etree2 = et.parse(file);
var xml3 = etree2.write({'indent': 4});
assert.equal(xml3, expected3);
test.finish();
};
exports['test_parse_and_find_2'] = function(test, assert) {
var data = readFile('xml1.xml');
var etree = et.parse(data);
assert.equal(etree.findall('./object').length, 2);
assert.equal(etree.findall('[@name]').length, 1);
assert.equal(etree.findall('[@name="test_container_1"]').length, 1);
assert.equal(etree.findall('[@name=\'test_container_1\']').length, 1);
assert.equal(etree.findall('./object')[0].findtext('name'), 'test_object_1');
assert.equal(etree.findtext('./object/name'), 'test_object_1');
assert.equal(etree.findall('.//bytes').length, 2);
assert.equal(etree.findall('*/bytes').length, 2);
assert.equal(etree.findall('*/foobar').length, 0);
test.finish();
};
exports['test_namespaced_attribute'] = function(test, assert) {
var data = readFile('xml1.xml');
var etree = et.parse(data);
assert.equal(etree.findall('*/bytes[@android:type="cool"]').length, 1);
test.finish();
}
exports['test_syntax_errors'] = function(test, assert) {
var expressions = [ './/@bar', '[@bar', '[@foo=bar]', '[@', '/bar' ];
var errCount = 0;
var data = readFile('xml1.xml');
var etree = et.parse(data);
expressions.forEach(function(expression) {
try {
etree.findall(expression);
}
catch (err) {
errCount++;
}
});
assert.equal(errCount, expressions.length);
test.finish();
};
exports['test_register_namespace'] = function(test, assert){
var prefix = 'TESTPREFIX';
var namespace = 'http://seriously.unknown/namespace/URI';
var errCount = 0;
var etree = Element(sprintf('{%s}test', namespace));
assert.equal(et.tostring(etree, { 'xml_declaration': false}),
sprintf('<ns0:test xmlns:ns0="%s" />', namespace));
et.register_namespace(prefix, namespace);
var etree = Element(sprintf('{%s}test', namespace));
assert.equal(et.tostring(etree, { 'xml_declaration': false}),
sprintf('<%s:test xmlns:%s="%s" />', prefix, prefix, namespace));
try {
et.register_namespace('ns25', namespace);
}
catch (err) {
errCount++;
}
assert.equal(errCount, 1, 'Reserved prefix used, but exception was not thrown');
test.finish();
};
exports['test_tostring'] = function(test, assert) {
var a = Element('a');
var b = SubElement(a, 'b');
var c = SubElement(a, 'c');
c.text = 543;
assert.equal(et.tostring(a, { 'xml_declaration': false }), '<a><b /><c>543</c></a>');
assert.equal(et.tostring(c, { 'xml_declaration': false }), '<c>543</c>');
test.finish();
};
exports['test_escape'] = function(test, assert) {
var a = Element('a');
var b = SubElement(a, 'b');
b.text = '&&&&<>"\n\r';
assert.equal(et.tostring(a, { 'xml_declaration': false }), '<a><b>&amp;&amp;&amp;&amp;&lt;&gt;\"\n\r</b></a>');
test.finish();
};
exports['test_find_null'] = function(test, assert) {
var root = Element('root');
var node = SubElement(root, 'node');
var leaf = SubElement(node, 'leaf');
leaf.text = 'ipsum';
assert.equal(root.find('node/leaf'), leaf);
assert.equal(root.find('no-such-node/leaf'), null);
test.finish();
};
exports['test_findtext_null'] = function(test, assert) {
var root = Element('root');
var node = SubElement(root, 'node');
var leaf = SubElement(node, 'leaf');
leaf.text = 'ipsum';
assert.equal(root.findtext('node/leaf'), 'ipsum');
assert.equal(root.findtext('no-such-node/leaf'), null);
test.finish();
};
exports['test_remove'] = function(test, assert) {
var root = Element('root');
var node1 = SubElement(root, 'node1');
var node2 = SubElement(root, 'node2');
var node3 = SubElement(root, 'node3');
assert.equal(root.len(), 3);
root.remove(node2);
assert.equal(root.len(), 2);
assert.equal(root.getItem(0).tag, 'node1')
assert.equal(root.getItem(1).tag, 'node3')
test.finish();
};
exports['test_cdata_write'] = function(test, assert) {
var root, etree, xml, values, value, i;
values = [
'if(0>1) then true;',
'<test1>ponies hello</test1>',
''
];
for (i = 0; i < values.length; i++) {
value = values[i];
root = Element('root');
root.append(et.CData(value));
etree = new ElementTree(root);
xml = etree.write({'xml_declaration': false});
assert.equal(xml, sprintf('<root><![CDATA[%s]]></root>', value));
}
test.finish();
};
# node-uuid Benchmarks
### Results
To see the results of our benchmarks visit https://github.com/broofa/node-uuid/wiki/Benchmark
### Run them yourself
node-uuid comes with some benchmarks to measure performance of generating UUIDs. These can be run using node.js. node-uuid is being benchmarked against some other uuid modules, that are available through npm namely `uuid` and `uuid-js`.
To prepare and run the benchmark issue;
```
npm install uuid uuid-js
node benchmark/benchmark.js
```
You'll see an output like this one:
```
# v4
nodeuuid.v4(): 854700 uuids/second
nodeuuid.v4('binary'): 788643 uuids/second
nodeuuid.v4('binary', buffer): 1336898 uuids/second
uuid(): 479386 uuids/second
uuid('binary'): 582072 uuids/second
uuidjs.create(4): 312304 uuids/second
# v1
nodeuuid.v1(): 938086 uuids/second
nodeuuid.v1('binary'): 683060 uuids/second
nodeuuid.v1('binary', buffer): 1644736 uuids/second
uuidjs.create(1): 190621 uuids/second
```
* The `uuid()` entries are for Nikhil Marathe's [uuid module](https://bitbucket.org/nikhilm/uuidjs) which is a wrapper around the native libuuid library.
* The `uuidjs()` entries are for Patrick Negri's [uuid-js module](https://github.com/pnegri/uuid-js) which is a pure javascript implementation based on [UUID.js](https://github.com/LiosK/UUID.js) by LiosK.
If you want to get more reliable results you can run the benchmark multiple times and write the output into a log file:
```
for i in {0..9}; do node benchmark/benchmark.js >> benchmark/bench_0.4.12.log; done;
```
If you're interested in how performance varies between different node versions, you can issue the above command multiple times.
You can then use the shell script `bench.sh` provided in this directory to calculate the averages over all benchmark runs and draw a nice plot:
```
(cd benchmark/ && ./bench.sh)
```
This assumes you have [gnuplot](http://www.gnuplot.info/) and [ImageMagick](http://www.imagemagick.org/) installed. You'll find a nice `bench.png` graph in the `benchmark/` directory then.
#!/opt/local/bin/gnuplot -persist
#
#
# G N U P L O T
# Version 4.4 patchlevel 3
# last modified March 2011
# System: Darwin 10.8.0
#
# Copyright (C) 1986-1993, 1998, 2004, 2007-2010
# Thomas Williams, Colin Kelley and many others
#
# gnuplot home: http://www.gnuplot.info
# faq, bugs, etc: type "help seeking-assistance"
# immediate help: type "help"
# plot window: hit 'h'
set terminal postscript eps noenhanced defaultplex \
leveldefault color colortext \
solid linewidth 1.2 butt noclip \
palfuncparam 2000,0.003 \
"Helvetica" 14
set output 'bench.eps'
unset clip points
set clip one
unset clip two
set bar 1.000000 front
set border 31 front linetype -1 linewidth 1.000
set xdata
set ydata
set zdata
set x2data
set y2data
set timefmt x "%d/%m/%y,%H:%M"
set timefmt y "%d/%m/%y,%H:%M"
set timefmt z "%d/%m/%y,%H:%M"
set timefmt x2 "%d/%m/%y,%H:%M"
set timefmt y2 "%d/%m/%y,%H:%M"
set timefmt cb "%d/%m/%y,%H:%M"
set boxwidth
set style fill empty border
set style rectangle back fc lt -3 fillstyle solid 1.00 border lt -1
set style circle radius graph 0.02, first 0, 0
set dummy x,y
set format x "% g"
set format y "% g"
set format x2 "% g"
set format y2 "% g"
set format z "% g"
set format cb "% g"
set angles radians
unset grid
set key title ""
set key outside left top horizontal Right noreverse enhanced autotitles columnhead nobox
set key noinvert samplen 4 spacing 1 width 0 height 0
set key maxcolumns 2 maxrows 0
unset label
unset arrow
set style increment default
unset style line
set style line 1 linetype 1 linewidth 2.000 pointtype 1 pointsize default pointinterval 0
unset style arrow
set style histogram clustered gap 2 title offset character 0, 0, 0
unset logscale
set offsets graph 0.05, 0.15, 0, 0
set pointsize 1.5
set pointintervalbox 1
set encoding default
unset polar
unset parametric
unset decimalsign
set view 60, 30, 1, 1
set samples 100, 100
set isosamples 10, 10
set surface
unset contour
set clabel '%8.3g'
set mapping cartesian
set datafile separator whitespace
unset hidden3d
set cntrparam order 4
set cntrparam linear
set cntrparam levels auto 5
set cntrparam points 5
set size ratio 0 1,1
set origin 0,0
set style data points
set style function lines
set xzeroaxis linetype -2 linewidth 1.000
set yzeroaxis linetype -2 linewidth 1.000
set zzeroaxis linetype -2 linewidth 1.000
set x2zeroaxis linetype -2 linewidth 1.000
set y2zeroaxis linetype -2 linewidth 1.000
set ticslevel 0.5
set mxtics default
set mytics default
set mztics default
set mx2tics default
set my2tics default
set mcbtics default
set xtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0
set xtics norangelimit
set xtics ()
set ytics border in scale 1,0.5 mirror norotate offset character 0, 0, 0
set ytics autofreq norangelimit
set ztics border in scale 1,0.5 nomirror norotate offset character 0, 0, 0
set ztics autofreq norangelimit
set nox2tics
set noy2tics
set cbtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0
set cbtics autofreq norangelimit
set title ""
set title offset character 0, 0, 0 font "" norotate
set timestamp bottom
set timestamp ""
set timestamp offset character 0, 0, 0 font "" norotate
set rrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] )
set autoscale rfixmin
set autoscale rfixmax
set trange [ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000] )
set autoscale tfixmin
set autoscale tfixmax
set urange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] )
set autoscale ufixmin
set autoscale ufixmax
set vrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] )
set autoscale vfixmin
set autoscale vfixmax
set xlabel ""
set xlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate
set x2label ""
set x2label offset character 0, 0, 0 font "" textcolor lt -1 norotate
set xrange [ * : * ] noreverse nowriteback # (currently [-0.150000:3.15000] )
set autoscale xfixmin
set autoscale xfixmax
set x2range [ * : * ] noreverse nowriteback # (currently [0.00000:3.00000] )
set autoscale x2fixmin
set autoscale x2fixmax
set ylabel ""
set ylabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270
set y2label ""
set y2label offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270
set yrange [ 0.00000 : 1.90000e+06 ] noreverse nowriteback # (currently [:] )
set autoscale yfixmin
set autoscale yfixmax
set y2range [ * : * ] noreverse nowriteback # (currently [0.00000:1.90000e+06] )
set autoscale y2fixmin
set autoscale y2fixmax
set zlabel ""
set zlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate
set zrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] )
set autoscale zfixmin
set autoscale zfixmax
set cblabel ""
set cblabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270
set cbrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] )
set autoscale cbfixmin
set autoscale cbfixmax
set zero 1e-08
set lmargin -1
set bmargin -1
set rmargin -1
set tmargin -1
set pm3d explicit at s
set pm3d scansautomatic
set pm3d interpolate 1,1 flush begin noftriangles nohidden3d corners2color mean
set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB
set palette rgbformulae 7, 5, 15
set colorbox default
set colorbox vertical origin screen 0.9, 0.2, 0 size screen 0.05, 0.6, 0 front bdefault
set loadpath
set fontpath
set fit noerrorvariables
GNUTERM = "aqua"
plot 'bench_results.txt' using 2:xticlabel(1) w lp lw 2, '' using 3:xticlabel(1) w lp lw 2, '' using 4:xticlabel(1) w lp lw 2, '' using 5:xticlabel(1) w lp lw 2, '' using 6:xticlabel(1) w lp lw 2, '' using 7:xticlabel(1) w lp lw 2, '' using 8:xticlabel(1) w lp lw 2, '' using 9:xticlabel(1) w lp lw 2
# EOF
#!/bin/bash
# for a given node version run:
# for i in {0..9}; do node benchmark.js >> bench_0.6.2.log; done;
PATTERNS=('nodeuuid.v1()' "nodeuuid.v1('binary'," 'nodeuuid.v4()' "nodeuuid.v4('binary'," "uuid()" "uuid('binary')" 'uuidjs.create(1)' 'uuidjs.create(4)' '140byte')
FILES=(node_uuid_v1_string node_uuid_v1_buf node_uuid_v4_string node_uuid_v4_buf libuuid_v4_string libuuid_v4_binary uuidjs_v1_string uuidjs_v4_string 140byte_es)
INDICES=(2 3 2 3 2 2 2 2 2)
VERSIONS=$( ls bench_*.log | sed -e 's/^bench_\([0-9\.]*\)\.log/\1/' | tr "\\n" " " )
TMPJOIN="tmp_join"
OUTPUT="bench_results.txt"
for I in ${!FILES[*]}; do
F=${FILES[$I]}
P=${PATTERNS[$I]}
INDEX=${INDICES[$I]}
echo "version $F" > $F
for V in $VERSIONS; do
(VAL=$( grep "$P" bench_$V.log | LC_ALL=en_US awk '{ sum += $'$INDEX' } END { print sum/NR }' ); echo $V $VAL) >> $F
done
if [ $I == 0 ]; then
cat $F > $TMPJOIN
else
join $TMPJOIN $F > $OUTPUT
cp $OUTPUT $TMPJOIN
fi
rm $F
done
rm $TMPJOIN
gnuplot bench.gnu
convert -density 200 -resize 800x560 -flatten bench.eps bench.png
rm bench.eps
/*
Test performance of native C UUID generation
To Compile: cc -luuid benchmark-native.c -o benchmark-native
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <uuid/uuid.h>
int main() {
uuid_t myid;
char buf[36+1];
int i;
struct timeval t;
double start, finish;
gettimeofday(&t, NULL);
start = t.tv_sec + t.tv_usec/1e6;
int n = 2e5;
for (i = 0; i < n; i++) {
uuid_generate(myid);
uuid_unparse(myid, buf);
}
gettimeofday(&t, NULL);
finish = t.tv_sec + t.tv_usec/1e6;
double dur = finish - start;
printf("%d uuids/sec", (int)(n/dur));
return 0;
}
try {
var nodeuuid = require('../uuid');
} catch (e) {
console.error('node-uuid require failed - skipping tests');
}
try {
var uuid = require('uuid');
} catch (e) {
console.error('uuid require failed - skipping tests');
}
try {
var uuidjs = require('uuid-js');
} catch (e) {
console.error('uuid-js require failed - skipping tests');
}
var N = 5e5;
function rate(msg, t) {
console.log(msg + ': ' +
(N / (Date.now() - t) * 1e3 | 0) +
' uuids/second');
}
console.log('# v4');
// node-uuid - string form
if (nodeuuid) {
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4();
rate('nodeuuid.v4() - using node.js crypto RNG', t);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4({rng: nodeuuid.mathRNG});
rate('nodeuuid.v4() - using Math.random() RNG', t);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary');
rate('nodeuuid.v4(\'binary\')', t);
var buffer = new nodeuuid.BufferClass(16);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary', buffer);
rate('nodeuuid.v4(\'binary\', buffer)', t);
}
// libuuid - string form
if (uuid) {
for (var i = 0, t = Date.now(); i < N; i++) uuid();
rate('uuid()', t);
for (var i = 0, t = Date.now(); i < N; i++) uuid('binary');
rate('uuid(\'binary\')', t);
}
// uuid-js - string form
if (uuidjs) {
for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(4);
rate('uuidjs.create(4)', t);
}
// 140byte.es
for (var i = 0, t = Date.now(); i < N; i++) 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(s,r){r=Math.random()*16|0;return (s=='x'?r:r&0x3|0x8).toString(16)});
rate('140byte.es_v4', t);
console.log('');
console.log('# v1');
// node-uuid - v1 string form
if (nodeuuid) {
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1();
rate('nodeuuid.v1()', t);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary');
rate('nodeuuid.v1(\'binary\')', t);
var buffer = new nodeuuid.BufferClass(16);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary', buffer);
rate('nodeuuid.v1(\'binary\', buffer)', t);
}
// uuid-js - v1 string form
if (uuidjs) {
for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(1);
rate('uuidjs.create(1)', t);
}
#!/usr/bin/env node
var path = require('path');
var uuid = require(path.join(__dirname, '..'));
var arg = process.argv[2];
if ('--help' === arg) {
console.log('\n USAGE: uuid [version] [options]\n\n');
console.log(' options:\n');
console.log(' --help Display this message and exit\n');
process.exit(0);
}
if (null == arg) {
console.log(uuid());
process.exit(0);
}
if ('v1' !== arg && 'v4' !== arg) {
console.error('Version must be RFC4122 version 1 or version 4, denoted as "v1" or "v4"');
process.exit(1);
}
console.log(uuid[arg]());
process.exit(0);
{
"name": "node-uuid",
"version": "1.4.3",
"homepage": "https://github.com/broofa/node-uuid",
"authors": [
"Robert Kieffer <robert@broofa.com>"
],
"description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.",
"main": "uuid.js",
"keywords": [
"uuid",
"gid",
"rfc4122"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
var assert = require('assert'),
nodeuuid = require('../uuid'),
uuidjs = require('uuid-js'),
libuuid = require('uuid').generate,
util = require('util'),
exec = require('child_process').exec,
os = require('os');
// On Mac Os X / macports there's only the ossp-uuid package that provides uuid
// On Linux there's uuid-runtime which provides uuidgen
var uuidCmd = os.type() === 'Darwin' ? 'uuid -1' : 'uuidgen -t';
function compare(ids) {
console.log(ids);
for (var i = 0; i < ids.length; i++) {
var id = ids[i].split('-');
id = [id[2], id[1], id[0]].join('');
ids[i] = id;
}
var sorted = ([].concat(ids)).sort();
if (sorted.toString() !== ids.toString()) {
console.log('Warning: sorted !== ids');
} else {
console.log('everything in order!');
}
}
// Test time order of v1 uuids
var ids = [];
while (ids.length < 10e3) ids.push(nodeuuid.v1());
var max = 10;
console.log('node-uuid:');
ids = [];
for (var i = 0; i < max; i++) ids.push(nodeuuid.v1());
compare(ids);
console.log('');
console.log('uuidjs:');
ids = [];
for (var i = 0; i < max; i++) ids.push(uuidjs.create(1).toString());
compare(ids);
console.log('');
console.log('libuuid:');
ids = [];
var count = 0;
var last = function() {
compare(ids);
}
var cb = function(err, stdout, stderr) {
ids.push(stdout.substring(0, stdout.length-1));
count++;
if (count < max) {
return next();
}
last();
};
var next = function() {
exec(uuidCmd, cb);
};
next();
<html>
<head>
<style>
div {
font-family: monospace;
font-size: 8pt;
}
div.log {color: #444;}
div.warn {color: #550;}
div.error {color: #800; font-weight: bold;}
</style>
<script src="../uuid.js"></script>
</head>
<body>
<script src="./test.js"></script>
</body>
</html>
if (!this.uuid) {
// node.js
uuid = require('../uuid');
}
//
// x-platform log/assert shims
//
function _log(msg, type) {
type = type || 'log';
if (typeof(document) != 'undefined') {
document.write('<div class="' + type + '">' + msg.replace(/\n/g, '<br />') + '</div>');
}
if (typeof(console) != 'undefined') {
var color = {
log: '\033[39m',
warn: '\033[33m',
error: '\033[31m'
};
console[type](color[type] + msg + color.log);
}
}
function log(msg) {_log(msg, 'log');}
function warn(msg) {_log(msg, 'warn');}
function error(msg) {_log(msg, 'error');}
function assert(res, msg) {
if (!res) {
error('FAIL: ' + msg);
} else {
log('Pass: ' + msg);
}
}
//
// Unit tests
//
// Verify ordering of v1 ids created with explicit times
var TIME = 1321644961388; // 2011-11-18 11:36:01.388-08:00
function compare(name, ids) {
ids = ids.map(function(id) {
return id.split('-').reverse().join('-');
}).sort();
var sorted = ([].concat(ids)).sort();
assert(sorted.toString() == ids.toString(), name + ' have expected order');
}
// Verify ordering of v1 ids created using default behavior
compare('uuids with current time', [
uuid.v1(),
uuid.v1(),
uuid.v1(),
uuid.v1(),
uuid.v1()
]);
// Verify ordering of v1 ids created with explicit times
compare('uuids with time option', [
uuid.v1({msecs: TIME - 10*3600*1000}),
uuid.v1({msecs: TIME - 1}),
uuid.v1({msecs: TIME}),
uuid.v1({msecs: TIME + 1}),
uuid.v1({msecs: TIME + 28*24*3600*1000})
]);
assert(
uuid.v1({msecs: TIME}) != uuid.v1({msecs: TIME}),
'IDs created at same msec are different'
);
// Verify throw if too many ids created
var thrown = false;
try {
uuid.v1({msecs: TIME, nsecs: 10000});
} catch (e) {
thrown = true;
}
assert(thrown, 'Exception thrown when > 10K ids created in 1 ms');
// Verify clock regression bumps clockseq
var uidt = uuid.v1({msecs: TIME});
var uidtb = uuid.v1({msecs: TIME - 1});
assert(
parseInt(uidtb.split('-')[3], 16) - parseInt(uidt.split('-')[3], 16) === 1,
'Clock regression by msec increments the clockseq'
);
// Verify clock regression bumps clockseq
var uidtn = uuid.v1({msecs: TIME, nsecs: 10});
var uidtnb = uuid.v1({msecs: TIME, nsecs: 9});
assert(
parseInt(uidtnb.split('-')[3], 16) - parseInt(uidtn.split('-')[3], 16) === 1,
'Clock regression by nsec increments the clockseq'
);
// Verify explicit options produce expected id
var id = uuid.v1({
msecs: 1321651533573,
nsecs: 5432,
clockseq: 0x385c,
node: [ 0x61, 0xcd, 0x3c, 0xbb, 0x32, 0x10 ]
});
assert(id == 'd9428888-122b-11e1-b85c-61cd3cbb3210', 'Explicit options produce expected id');
// Verify adjacent ids across a msec boundary are 1 time unit apart
var u0 = uuid.v1({msecs: TIME, nsecs: 9999});
var u1 = uuid.v1({msecs: TIME + 1, nsecs: 0});
var before = u0.split('-')[0], after = u1.split('-')[0];
var dt = parseInt(after, 16) - parseInt(before, 16);
assert(dt === 1, 'Ids spanning 1ms boundary are 100ns apart');
//
// Test parse/unparse
//
id = '00112233445566778899aabbccddeeff';
assert(uuid.unparse(uuid.parse(id.substr(0,10))) ==
'00112233-4400-0000-0000-000000000000', 'Short parse');
assert(uuid.unparse(uuid.parse('(this is the uuid -> ' + id + id)) ==
'00112233-4455-6677-8899-aabbccddeeff', 'Dirty parse');
//
// Perf tests
//
var generators = {
v1: uuid.v1,
v4: uuid.v4
};
var UUID_FORMAT = {
v1: /[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i,
v4: /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i
};
var N = 1e4;
// Get %'age an actual value differs from the ideal value
function divergence(actual, ideal) {
return Math.round(100*100*(actual - ideal)/ideal)/100;
}
function rate(msg, t) {
log(msg + ': ' + (N / (Date.now() - t) * 1e3 | 0) + ' uuids\/second');
}
for (var version in generators) {
var counts = {}, max = 0;
var generator = generators[version];
var format = UUID_FORMAT[version];
log('\nSanity check ' + N + ' ' + version + ' uuids');
for (var i = 0, ok = 0; i < N; i++) {
id = generator();
if (!format.test(id)) {
throw Error(id + ' is not a valid UUID string');
}
if (id != uuid.unparse(uuid.parse(id))) {
assert(fail, id + ' is not a valid id');
}
// Count digits for our randomness check
if (version == 'v4') {
var digits = id.replace(/-/g, '').split('');
for (var j = digits.length-1; j >= 0; j--) {
var c = digits[j];
max = Math.max(max, counts[c] = (counts[c] || 0) + 1);
}
}
}
// Check randomness for v4 UUIDs
if (version == 'v4') {
// Limit that we get worried about randomness. (Purely empirical choice, this!)
var limit = 2*100*Math.sqrt(1/N);
log('\nChecking v4 randomness. Distribution of Hex Digits (% deviation from ideal)');
for (var i = 0; i < 16; i++) {
var c = i.toString(16);
var bar = '', n = counts[c], p = Math.round(n/max*100|0);
// 1-3,5-8, and D-F: 1:16 odds over 30 digits
var ideal = N*30/16;
if (i == 4) {
// 4: 1:1 odds on 1 digit, plus 1:16 odds on 30 digits
ideal = N*(1 + 30/16);
} else if (i >= 8 && i <= 11) {
// 8-B: 1:4 odds on 1 digit, plus 1:16 odds on 30 digits
ideal = N*(1/4 + 30/16);
} else {
// Otherwise: 1:16 odds on 30 digits
ideal = N*30/16;
}
var d = divergence(n, ideal);
// Draw bar using UTF squares (just for grins)
var s = n/max*50 | 0;
while (s--) bar += '=';
assert(Math.abs(d) < limit, c + ' |' + bar + '| ' + counts[c] + ' (' + d + '% < ' + limit + '%)');
}
}
}
// Perf tests
for (var version in generators) {
log('\nPerformance testing ' + version + ' UUIDs');
var generator = generators[version];
var buf = new uuid.BufferClass(16);
for (var i = 0, t = Date.now(); i < N; i++) generator();
rate('uuid.' + version + '()', t);
for (var i = 0, t = Date.now(); i < N; i++) generator('binary');
rate('uuid.' + version + '(\'binary\')', t);
for (var i = 0, t = Date.now(); i < N; i++) generator('binary', buf);
rate('uuid.' + version + '(\'binary\', buffer)', t);
}
language: node_js
language: node_js
node_js:
- '0.8'
- '0.10'
- '0.12'
- 'iojs'
before_install:
- npm install -g npm@latest
language: node_js
node_js:
- '0.10'
- '0.12'
- 'iojs'
## 1.4.1
- Address an issue that prevented Q from being used as a `<script>` for
Firefox add-ons. Q can now be used in any environment that provides `window`
or `self` globals, favoring `window` since add-ons have an an immutable
`self` that is distinct from `window`.
## 1.4.0
- Add `noConflict` support for use in `<script>` (@jahnjw).
## 1.3.0
- Add tracking for unhandled and handled rejections in Node.js (@benjamingr).
## 1.2.1
- Fix Node.js environment detection for modern Browserify (@kahnjw).
## 1.2.0
- Added Q.any(promisesArray) method (@vergara).
Returns a promise fulfilled with the value of the first resolved promise in
promisesArray. If all promises in promisesArray are rejected, it returns
a rejected promise.
## 1.1.2
- Removed extraneous files from the npm package by using the "files"
whitelist in package.json instead of the .npmignore blacklist.
(@anton-rudeshko)
## 1.1.1
- Fix a pair of regressions in bootstrapping, one which precluded
WebWorker support, and another that precluded support in
``<script>`` usage outright. #607
## 1.1.0
- Adds support for enabling long stack traces in node.js by setting
environment variable `Q_DEBUG=1`.
- Introduces the `tap` method to promises, which will see a value
pass through without alteration.
- Use instanceof to recognize own promise instances as opposed to
thenables.
- Construct timeout errors with `code === ETIMEDOUT` (Kornel Lesiński)
- More descriminant CommonJS module environment detection.
- Dropped continuous integration for Node.js 0.6 and 0.8 because of
changes to npm that preclude the use of new `^` version predicate
operator in any transitive dependency.
- Users can now override `Q.nextTick`.
## 1.0.1
- Adds support for `Q.Promise`, which implements common usage of the
ES6 `Promise` constructor and its methods. `Promise` does not have
a valid promise constructor and a proper implementation awaits
version 2 of Q.
- Removes the console stopgap for a promise inspector. This no longer
works with any degree of reliability.
- Fixes support for content security policies that forbid eval. Now
using the `StopIteration` global to distinguish SpiderMonkey
generators from ES6 generators, assuming that they will never
coexist.
## 1.0.0
:cake: This is all but a re-release of version 0.9, which has settled
into a gentle maintenance mode and rightly deserves an official 1.0.
An ambitious 2.0 release is already around the corner, but 0.9/1.0
have been distributed far and wide and demand long term support.
- Q will now attempt to post a debug message in browsers regardless
of whether window.Touch is defined. Chrome at least now has this
property regardless of whether touch is supported by the underlying
hardware.
- Remove deprecation warning from `promise.valueOf`. The function is
called by the browser in various ways so there is no way to
distinguish usage that should be migrated from usage that cannot be
altered.
## 0.9.7
- :warning: `q.min.js` is no longer checked-in. It is however still
created by Grunt and NPM.
- Fixes a bug that inhibited `Q.async` with implementations of the new
ES6 generators.
- Fixes a bug with `nextTick` affecting Safari 6.0.5 the first time a
page loads when an `iframe` is involved.
- Introduces `passByCopy`, `join`, and `race`.
- Shows stack traces or error messages on the console, instead of
`Error` objects.
- Elimintates wrapper methods for improved performance.
- `Q.all` now propagates progress notifications of the form you might
expect of ES6 iterations, `{value, index}` where the `value` is the
progress notification from the promise at `index`.
## 0.9.6
- Fixes a bug in recognizing the difference between compatible Q
promises, and Q promises from before the implementation of "inspect".
The latter are now coerced.
- Fixes an infinite asynchronous coercion cycle introduced by former
solution, in two independently sufficient ways. 1.) All promises
returned by makePromise now implement "inspect", albeit a default
that reports that the promise has an "unknown" state. 2.) The
implementation of "then/when" is now in "then" instead of "when", so
that the responsibility to "coerce" the given promise rests solely in
the "when" method and the "then" method may assume that "this" is a
promise of the right type.
- Refactors `nextTick` to use an unrolled microtask within Q regardless
of how new ticks a requested. #316 @rkatic
## 0.9.5
- Introduces `inspect` for getting the state of a promise as
`{state: "fulfilled" | "rejected" | "pending", value | reason}`.
- Introduces `allSettled` which produces an array of promises states
for the input promises once they have all "settled". This is in
accordance with a discussion on Promises/A+ that "settled" refers to
a promise that is "fulfilled" or "rejected". "resolved" refers to a
deferred promise that has been "resolved" to another promise,
"sealing its fate" to the fate of the successor promise.
- Long stack traces are now off by default. Set `Q.longStackSupport`
to true to enable long stack traces.
- Long stack traces can now follow the entire asynchronous history of a
promise, not just a single jump.
- Introduces `spawn` for an immediately invoked asychronous generator.
@jlongster
- Support for *experimental* synonyms `mapply`, `mcall`, `nmapply`,
`nmcall` for method invocation.
## 0.9.4
- `isPromise` and `isPromiseAlike` now always returns a boolean
(even for falsy values). #284 @lfac-pt
- Support for ES6 Generators in `async` #288 @andywingo
- Clear duplicate promise rejections from dispatch methods #238 @SLaks
- Unhandled rejection API #296 @domenic
`stopUnhandledRejectionTracking`, `getUnhandledReasons`,
`resetUnhandledRejections`.
## 0.9.3
- Add the ability to give `Q.timeout`'s errors a custom error message. #270
@jgrenon
- Fix Q's call-stack busting behavior in Node.js 0.10, by switching from
`process.nextTick` to `setImmediate`. #254 #259
- Fix Q's behavior when used with the Mocha test runner in the browser, since
Mocha introduces a fake `process` global without a `nextTick` property. #267
- Fix some, but not all, cases wherein Q would give false positives in its
unhandled rejection detection (#252). A fix for other cases (#238) is
hopefully coming soon.
- Made `Q.promise` throw early if given a non-function.
## 0.9.2
- Pass through progress notifications when using `timeout`. #229 @omares
- Pass through progress notifications when using `delay`.
- Fix `nbind` to actually bind the `thisArg`. #232 @davidpadbury
## 0.9.1
- Made the AMD detection compatible with the RequireJS optimizer's `namespace`
option. #225 @terinjokes
- Fix side effects from `valueOf`, and thus from `isFulfilled`, `isRejected`,
and `isPending`. #226 @benjamn
## 0.9.0
This release removes many layers of deprecated methods and brings Q closer to
alignment with Mark Miller’s TC39 [strawman][] for concurrency. At the same
time, it fixes many bugs and adds a few features around error handling. Finally,
it comes with an updated and comprehensive [API Reference][].
[strawman]: http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
[API Reference]: https://github.com/kriskowal/q/wiki/API-Reference
### API Cleanup
The following deprecated or undocumented methods have been removed.
Their replacements are listed here:
<table>
<thead>
<tr>
<th>0.8.x method</th>
<th>0.9 replacement</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Q.ref</code></td>
<td><code>Q</code></td>
</tr>
<tr>
<td><code>call</code>, <code>apply</code>, <code>bind</code> (*)</td>
<td><code>fcall</code>/<code>invoke</code>, <code>fapply</code>/<code>post</code>, <code>fbind</code></td>
</tr>
<tr>
<td><code>ncall</code>, <code>napply</code> (*)</td>
<td><code>nfcall</code>/<code>ninvoke</code>, <code>nfapply</code>/<code>npost</code></td>
</tr>
<tr>
<td><code>end</code></td>
<td><code>done</code></td>
</tr>
<tr>
<td><code>put</code></td>
<td><code>set</code></td>
</tr>
<tr>
<td><code>node</code></td>
<td><code>nbind</code></td>
</tr>
<tr>
<td><code>nend</code></td>
<td><code>nodeify</code></td>
</tr>
<tr>
<td><code>isResolved</code></td>
<td><code>isPending</code></td>
</tr>
<tr>
<td><code>deferred.node</code></td>
<td><code>deferred.makeNodeResolver</code></td>
</tr>
<tr>
<td><code>Method</code>, <code>sender</code></td>
<td><code>dispatcher</code></td>
</tr>
<tr>
<td><code>send</code></td>
<td><code>dispatch</code></td>
</tr>
<tr>
<td><code>view</code>, <code>viewInfo</code></td>
<td>(none)</td>
</tr>
</tbody>
</table>
(*) Use of ``thisp`` is discouraged. For calling methods, use ``post`` or
``invoke``.
### Alignment with the Concurrency Strawman
- Q now exports a `Q(value)` function, an alias for `resolve`.
`Q.call`, `Q.apply`, and `Q.bind` were removed to make room for the
same methods on the function prototype.
- `invoke` has been aliased to `send` in all its forms.
- `post` with no method name acts like `fapply`.
### Error Handling
- Long stack traces can be turned off by setting `Q.stackJumpLimit` to zero.
In the future, this property will be used to fine tune how many stack jumps
are retained in long stack traces; for now, anything nonzero is treated as
one (since Q only tracks one stack jump at the moment, see #144). #168
- In Node.js, if there are unhandled rejections when the process exits, they
are output to the console. #115
### Other
- `delete` and `set` (née `put`) no longer have a fulfillment value.
- Q promises are no longer frozen, which
[helps with performance](http://code.google.com/p/v8/issues/detail?id=1858).
- `thenReject` is now included, as a counterpart to `thenResolve`.
- The included browser `nextTick` shim is now faster. #195 @rkatic.
### Bug Fixes
- Q now works in Internet Explorer 10. #186 @ForbesLindesay
- `fbind` no longer hard-binds the returned function's `this` to `undefined`.
#202
- `Q.reject` no longer leaks memory. #148
- `npost` with no arguments now works. #207
- `allResolved` now works with non-Q promises ("thenables"). #179
- `keys` behavior is now correct even in browsers without native
`Object.keys`. #192 @rkatic
- `isRejected` and the `exception` property now work correctly if the
rejection reason is falsy. #198
### Internals and Advanced
- The internal interface for a promise now uses
`dispatchPromise(resolve, op, operands)` instead of `sendPromise(op,
resolve, ...operands)`, which reduces the cases where Q needs to do
argument slicing.
- The internal protocol uses different operands. "put" is now "set".
"del" is now "delete". "view" and "viewInfo" have been removed.
- `Q.fulfill` has been added. It is distinct from `Q.resolve` in that
it does not pass promises through, nor coerces promises from other
systems. The promise becomes the fulfillment value. This is only
recommended for use when trying to fulfill a promise with an object that has
a `then` function that is at the same time not a promise.
## 0.8.12
- Treat foreign promises as unresolved in `Q.isFulfilled`; this lets `Q.all`
work on arrays containing foreign promises. #154
- Fix minor incompliances with the [Promises/A+ spec][] and [test suite][]. #157
#158
[Promises/A+ spec]: http://promises-aplus.github.com/promises-spec/
[test suite]: https://github.com/promises-aplus/promises-tests
## 0.8.11
- Added ``nfcall``, ``nfapply``, and ``nfbind`` as ``thisp``-less versions of
``ncall``, ``napply``, and ``nbind``. The latter are now deprecated. #142
- Long stack traces no longer cause linearly-growing memory usage when chaining
promises together. #111
- Inspecting ``error.stack`` in a rejection handler will now give a long stack
trace. #103
- Fixed ``Q.timeout`` to clear its timeout handle when the promise is rejected;
previously, it kept the event loop alive until the timeout period expired.
#145 @dfilatov
- Added `q/queue` module, which exports an infinite promise queue
constructor.
## 0.8.10
- Added ``done`` as a replacement for ``end``, taking the usual fulfillment,
rejection, and progress handlers. It's essentially equivalent to
``then(f, r, p).end()``.
- Added ``Q.onerror``, a settable error trap that you can use to get full stack
traces for uncaught errors. #94
- Added ``thenResolve`` as a shortcut for returning a constant value once a
promise is fulfilled. #108 @ForbesLindesay
- Various tweaks to progress notification, including propagation and
transformation of progress values and only forwarding a single progress
object.
- Renamed ``nend`` to ``nodeify``. It no longer returns an always-fulfilled
promise when a Node callback is passed.
- ``deferred.resolve`` and ``deferred.reject`` no longer (sometimes) return
``deferred.promise``.
- Fixed stack traces getting mangled if they hit ``end`` twice. #116 #121 @ef4
- Fixed ``ninvoke`` and ``npost`` to work on promises for objects with Node
methods. #134
- Fixed accidental coercion of objects with nontrivial ``valueOf`` methods,
like ``Date``s, by the promise's ``valueOf`` method. #135
- Fixed ``spread`` not calling the passed rejection handler if given a rejected
promise.
## 0.8.9
- Added ``nend``
- Added preliminary progress notification support, via
``promise.then(onFulfilled, onRejected, onProgress)``,
``promise.progress(onProgress)``, and ``deferred.notify(...progressData)``.
- Made ``put`` and ``del`` return the object acted upon for easier chaining.
#84
- Fixed coercion cycles with cooperating promises. #106
## 0.8.7
- Support [Montage Require](http://github.com/kriskowal/mr)
## 0.8.6
- Fixed ``npost`` and ``ninvoke`` to pass the correct ``thisp``. #74
- Fixed various cases involving unorthodox rejection reasons. #73 #90
@ef4
- Fixed double-resolving of misbehaved custom promises. #75
- Sped up ``Q.all`` for arrays contain already-resolved promises or scalar
values. @ForbesLindesay
- Made stack trace filtering work when concatenating assets. #93 @ef4
- Added warnings for deprecated methods. @ForbesLindesay
- Added ``.npmignore`` file so that dependent packages get a slimmer
``node_modules`` directory.
## 0.8.5
- Added preliminary support for long traces (@domenic)
- Added ``fapply``, ``fcall``, ``fbind`` for non-thisp
promised function calls.
- Added ``return`` for async generators, where generators
are implemented.
- Rejected promises now have an "exception" property. If an object
isRejected(object), then object.valueOf().exception will
be the wrapped error.
- Added Jasmine specifications
- Support Internet Explorers 7–9 (with multiple bug fixes @domenic)
- Support Firefox 12
- Support Safari 5.1.5
- Support Chrome 18
## 0.8.4
- WARNING: ``promise.timeout`` is now rejected with an ``Error`` object
and the message now includes the duration of the timeout in
miliseconds. This doesn't constitute (in my opinion) a
backward-incompatibility since it is a change of an undocumented and
unspecified public behavior, but if you happened to depend on the
exception being a string, you will need to revise your code.
- Added ``deferred.makeNodeResolver()`` to replace the more cryptic
``deferred.node()`` method.
- Added experimental ``Q.promise(maker(resolve, reject))`` to make a
promise inside a callback, such that thrown exceptions in the
callback are converted and the resolver and rejecter are arguments.
This is a shorthand for making a deferred directly and inspired by
@gozala’s stream constructor pattern and the Microsoft Windows Metro
Promise constructor interface.
- Added experimental ``Q.begin()`` that is intended to kick off chains
of ``.then`` so that each of these can be reordered without having to
edit the new and former first step.
## 0.8.3
- Added ``isFulfilled``, ``isRejected``, and ``isResolved``
to the promise prototype.
- Added ``allResolved`` for waiting for every promise to either be
fulfilled or rejected, without propagating an error. @utvara #53
- Added ``Q.bind`` as a method to transform functions that
return and throw into promise-returning functions. See
[an example](https://gist.github.com/1782808). @domenic
- Renamed ``node`` export to ``nbind``, and added ``napply`` to
complete the set. ``node`` remains as deprecated. @domenic #58
- Renamed ``Method`` export to ``sender``. ``Method``
remains as deprecated and will be removed in the next
major version since I expect it has very little usage.
- Added browser console message indicating a live list of
unhandled errors.
- Added support for ``msSetImmediate`` (IE10) or ``setImmediate``
(available via [polyfill](https://github.com/NobleJS/setImmediate))
as a browser-side ``nextTick`` implementation. #44 #50 #59
- Stopped using the event-queue dependency, which was in place for
Narwhal support: now directly using ``process.nextTick``.
- WARNING: EXPERIMENTAL: added ``finally`` alias for ``fin``, ``catch``
alias for ``fail``, ``try`` alias for ``call``, and ``delete`` alias
for ``del``. These properties are enquoted in the library for
cross-browser compatibility, but may be used as property names in
modern engines.
## 0.8.2
- Deprecated ``ref`` in favor of ``resolve`` as recommended by
@domenic.
- Update event-queue dependency.
## 0.8.1
- Fixed Opera bug. #35 @cadorn
- Fixed ``Q.all([])`` #32 @domenic
## 0.8.0
- WARNING: ``enqueue`` removed. Use ``nextTick`` instead.
This is more consistent with NodeJS and (subjectively)
more explicit and intuitive.
- WARNING: ``def`` removed. Use ``master`` instead. The
term ``def`` was too confusing to new users.
- WARNING: ``spy`` removed in favor of ``fin``.
- WARNING: ``wait`` removed. Do ``all(args).get(0)`` instead.
- WARNING: ``join`` removed. Do ``all(args).spread(callback)`` instead.
- WARNING: Removed the ``Q`` function module.exports alias
for ``Q.ref``. It conflicts with ``Q.apply`` in weird
ways, making it uncallable.
- Revised ``delay`` so that it accepts both ``(value,
timeout)`` and ``(timeout)`` variations based on
arguments length.
- Added ``ref().spread(cb(...args))``, a variant of
``then`` that spreads an array across multiple arguments.
Useful with ``all()``.
- Added ``defer().node()`` Node callback generator. The
callback accepts ``(error, value)`` or ``(error,
...values)``. For multiple value arguments, the
fulfillment value is an array, useful in conjunction with
``spread``.
- Added ``node`` and ``ncall``, both with the signature
``(fun, thisp_opt, ...args)``. The former is a decorator
and the latter calls immediately. ``node`` optional
binds and partially applies. ``ncall`` can bind and pass
arguments.
## 0.7.2
- Fixed thenable promise assimilation.
## 0.7.1
- Stopped shimming ``Array.prototype.reduce``. The
enumerable property has bad side-effects. Libraries that
depend on this (for example, QQ) will need to be revised.
## 0.7.0 - BACKWARD INCOMPATIBILITY
- WARNING: Removed ``report`` and ``asap``
- WARNING: The ``callback`` argument of the ``fin``
function no longer receives any arguments. Thus, it can
be used to call functions that should not receive
arguments on resolution. Use ``when``, ``then``, or
``fail`` if you need a value.
- IMPORTANT: Fixed a bug in the use of ``MessageChannel``
for ``nextTick``.
- Renamed ``enqueue`` to ``nextTick``.
- Added experimental ``view`` and ``viewInfo`` for creating
views of promises either when or before they're
fulfilled.
- Shims are now externally applied so subsequent scripts or
dependees can use them.
- Improved minification results.
- Improved readability.
## 0.6.0 - BACKWARD INCOMPATIBILITY
- WARNING: In practice, the implementation of ``spy`` and
the name ``fin`` were useful. I've removed the old
``fin`` implementation and renamed/aliased ``spy``.
- The "q" module now exports its ``ref`` function as a "Q"
constructor, with module systems that support exports
assignment including NodeJS, RequireJS, and when used as
a ``<script>`` tag. Notably, strictly compliant CommonJS
does not support this, but UncommonJS does.
- Added ``async`` decorator for generators that use yield
to "trampoline" promises. In engines that support
generators (SpiderMonkey), this will greatly reduce the
need for nested callbacks.
- Made ``when`` chainable.
- Made ``all`` chainable.
## 0.5.3
- Added ``all`` and refactored ``join`` and ``wait`` to use
it. All of these will now reject at the earliest
rejection.
## 0.5.2
- Minor improvement to ``spy``; now waits for resolution of
callback promise.
## 0.5.1
- Made most Q API methods chainable on promise objects, and
turned the previous promise-methods of ``join``,
``wait``, and ``report`` into Q API methods.
- Added ``apply`` and ``call`` to the Q API, and ``apply``
as a promise handler.
- Added ``fail``, ``fin``, and ``spy`` to Q and the promise
prototype for convenience when observing rejection,
fulfillment and rejection, or just observing without
affecting the resolution.
- Renamed ``def`` (although ``def`` remains shimmed until
the next major release) to ``master``.
- Switched to using ``MessageChannel`` for next tick task
enqueue in browsers that support it.
## 0.5.0 - MINOR BACKWARD INCOMPATIBILITY
- Exceptions are no longer reported when consumed.
- Removed ``error`` from the API. Since exceptions are
getting consumed, throwing them in an errback causes the
exception to silently disappear. Use ``end``.
- Added ``end`` as both an API method and a promise-chain
ending method. It causes propagated rejections to be
thrown, which allows Node to write stack traces and
emit ``uncaughtException`` events, and browsers to
likewise emit ``onerror`` and log to the console.
- Added ``join`` and ``wait`` as promise chain functions,
so you can wait for variadic promises, returning your own
promise back, or join variadic promises, resolving with a
callback that receives variadic fulfillment values.
## 0.4.4
- ``end`` no longer returns a promise. It is the end of the
promise chain.
- Stopped reporting thrown exceptions in ``when`` callbacks
and errbacks. These must be explicitly reported through
``.end()``, ``.then(null, Q.error)``, or some other
mechanism.
- Added ``report`` as an API method, which can be used as
an errback to report and propagate an error.
- Added ``report`` as a promise-chain method, so an error
can be reported if it passes such a gate.
## 0.4.3
- Fixed ``<script>`` support that regressed with 0.4.2
because of "use strict" in the module system
multi-plexer.
## 0.4.2
- Added support for RequireJS (jburke)
## 0.4.1
- Added an "end" method to the promise prototype,
as a shorthand for waiting for the promise to
be resolved gracefully, and failing to do so,
to dump an error message.
## 0.4.0 - BACKWARD INCOMPATIBLE*
- *Removed the utility modules. NPM and Node no longer
expose any module except the main module. These have
been moved and merged into the "qq" package.
- *In a non-CommonJS browser, q.js can be used as a script.
It now creates a Q global variable.
- Fixed thenable assimilation.
- Fixed some issues with asap, when it resolves to
undefined, or throws an exception.
## 0.3.0 - BACKWARD-INCOMPATIBLE
- The `post` method has been reverted to its original
signature, as provided in Tyler Close's `ref_send` API.
That is, `post` accepts two arguments, the second of
which is an arbitrary object, but usually invocation
arguments as an `Array`. To provide variadic arguments
to `post`, there is a new `invoke` function that posts
the variadic arguments to the value given in the first
argument.
- The `defined` method has been moved from `q` to `q/util`
since it gets no use in practice but is still
theoretically useful.
- The `Promise` constructor has been renamed to
`makePromise` to be consistent with the convention that
functions that do not require the `new` keyword to be
used as constructors have camelCase names.
- The `isResolved` function has been renamed to
`isFulfilled`. There is a new `isResolved` function that
indicates whether a value is not a promise or, if it is a
promise, whether it has been either fulfilled or
rejected. The code has been revised to reflect this
nuance in terminology.
## 0.2.10
- Added `join` to `"q/util"` for variadically joining
multiple promises.
## 0.2.9
- The future-compatible `invoke` method has been added,
to replace `post`, since `post` will become backward-
incompatible in the next major release.
- Exceptions thrown in the callbacks of a `when` call are
now emitted to Node's `"uncaughtException"` `process`
event in addition to being returned as a rejection reason.
## 0.2.8
- Exceptions thrown in the callbacks of a `when` call
are now consumed, warned, and transformed into
rejections of the promise returned by `when`.
## 0.2.7
- Fixed a minor bug in thenable assimilation, regressed
because of the change in the forwarding protocol.
- Fixed behavior of "q/util" `deep` method on dates and
other primitives. Github issue #11.
## 0.2.6
- Thenables (objects with a "then" method) are accepted
and provided, bringing this implementation of Q
into conformance with Promises/A, B, and D.
- Added `makePromise`, to replace the `Promise` function
eventually.
- Rejections are now also duck-typed. A rejection is a
promise with a valueOf method that returns a rejection
descriptor. A rejection descriptor has a
"promiseRejected" property equal to "true" and a
"reason" property corresponding to the rejection reason.
- Altered the `makePromise` API such that the `fallback`
method no longer receives a superfluous `resolved` method
after the `operator`. The fallback method is responsible
only for returning a resolution. This breaks an
undocumented API, so third-party API's depending on the
previous undocumented behavior may break.
## 0.2.5
- Changed promises into a duck-type such that multiple
instances of the Q module can exchange promise objects.
A promise is now defined as "an object that implements the
`promiseSend(op, resolved, ...)` method and `valueOf`".
- Exceptions in promises are now captured and returned
as rejections.
## 0.2.4
- Fixed bug in `ref` that prevented `del` messages from
being received (gozala)
- Fixed a conflict with FireFox 4; constructor property
is now read-only.
## 0.2.3
- Added `keys` message to promises and to the promise API.
## 0.2.2
- Added boilerplate to `q/queue` and `q/util`.
- Fixed missing dependency to `q/queue`.
## 0.2.1
- The `resolve` and `reject` methods of `defer` objects now
return the resolution promise for convenience.
- Added `q/util`, which provides `step`, `delay`, `shallow`,
`deep`, and three reduction orders.
- Added `q/queue` module for a promise `Queue`.
- Added `q-comm` to the list of compatible libraries.
- Deprecated `defined` from `q`, with intent to move it to
`q/util`.
## 0.2.0 - BACKWARD INCOMPATIBLE
- Changed post(ref, name, args) to variadic
post(ref, name, ...args). BACKWARD INCOMPATIBLE
- Added a def(value) method to annotate an object as being
necessarily a local value that cannot be serialized, such
that inter-process/worker/vat promise communication
libraries will send messages to it, but never send it
back.
- Added a send(value, op, ...args) method to the public API, for
forwarding messages to a value or promise in a future turn.
## 0.1.9
- Added isRejected() for testing whether a value is a rejected
promise. isResolved() retains the behavior of stating
that rejected promises are not resolved.
## 0.1.8
- Fixed isResolved(null) and isResolved(undefined) [issue #9]
- Fixed a problem with the Object.create shim
## 0.1.7
- shimmed ES5 Object.create in addition to Object.freeze
for compatibility on non-ES5 engines (gozala)
## 0.1.6
- Q.isResolved added
- promise.valueOf() now returns the value of resolved
and near values
- asap retried
- promises are frozen when possible
## 0.1.5
- fixed dependency list for Teleport (gozala)
- all unit tests now pass (gozala)
## 0.1.4
- added support for Teleport as an engine (gozala)
- simplified and updated methods for getting internal
print and enqueue functions universally (gozala)
## 0.1.3
- fixed erroneous link to the q module in package.json
## 0.1.2
- restructured for overlay style package compatibility
## 0.1.0
- removed asap because it was broken, probably down to the
philosophy.
## 0.0.3
- removed q-util
- fixed asap so it returns a value if completed
## 0.0.2
- added q-util
## 0.0.1
- initial version
WinJS
Copyright (c) Microsoft Corporation
All rights reserved.
MIT License
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
Windows Library for JavaScript (WinJS)
=====
[![Build Status](https://travis-ci.org/winjs/winjs.svg?branch=master)](https://travis-ci.org/winjs/winjs)
This project is actively developed by the WinJS developers working for Microsoft Corporation, in collaboration with the community of open source developers. Together we are dedicated to creating the best possible solution for HTML/JS/CSS application development.
WinJS is a set of JavaScript toolkits that allow developers to build applications using HTML/JS/CSS technology forged with the following principles in mind:
* Provide developers with a distinctive set of UI controls with high polish and performance with fundamental support for touch, mouse, keyboard and accessibility
* Provide developers with a cohesive set of components and utilities to build the scaffolding and infrastructure of their applications
This is a first step for the WinJS project and there is still a lot of work that needs to be done. So please check out the [roadmap](https://github.com/winjs/winjs/wiki/Roadmap) to see where the project is headed or participate by [contributing](https://github.com/winjs/winjs/wiki/Contribute) along the way.
# Contribute
There are many ways to [contribute](https://github.com/winjs/winjs/blob/master/CONTRIBUTING.md) to the project.
You can contribute by reviewing and sending feedback on code checkins, suggesting and trying out new features as they are implemented, submitting bugs and helping us verify fixes as they are checked in, as well as submitting code fixes or code contributions of your own.
Note that all code submissions will be rigorously reviewed and tested by the team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
# Roadmap
The source code on this repo is under active development that will be part of our next release. For details on our planned features and future direction, please refer to our [roadmap](https://github.com/winjs/winjs/wiki/Roadmap).
# Build WinJS
In order to build WinJS, ensure that you have [git](http://git-scm.com/downloads) and [Node.js](http://nodejs.org/download/) installed.
Clone a copy of the master WinJS git repo:
```
git clone https://github.com/winjs/winjs.git
```
Change to the `winjs` directory:
```
cd winjs
```
Install the [grunt command-line interface](https://github.com/gruntjs/grunt-cli) globally:
```
npm install -g grunt-cli
```
Grunt dependencies are installed separately in each cloned git repo. Install the dependencies with:
```
npm install
```
Run the following and the WinJS JavaScript and CSS files will be put in the `bin` directory:
```
grunt
```
> **Note:** You may need to use sudo (for OSX, *nix, BSD etc) or run your command shell as Administrator (for Windows) to install Grunt globally.
# Tests status
Refer to http://try.buildwinjs.com/#status for the current status of the unit tests and the list of known issues.
# Try WinJS
Check out our online playground http://try.buildwinjs.com
# Follow Us
Twitter https://twitter.com/BuildWinJS
Facebook https://www.facebook.com/buildwinjs
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
/* global intellisense, window */
(function () {
"use strict";
var redirect = intellisense.redirectDefinition;
var originalKeys = Object.keys;
function baseKeys(o) {
var values = Object.getOwnPropertyNames(o);
for (var i = 0, len = values.length; i < len; ++i) {
if (values[i].substr(0, 7) === "_$field") { return values; }
}
return originalKeys(o);
}
Object.keys = baseKeys;
redirect(baseKeys, originalKeys);
window._$originalAddEventListener = window.addEventListener;
function addEventListener(type, handler, useCapture) {
if (typeof (type) === "string" && (type === "pointerdown" || type === "keydown")) {
handler = function () { };
}
return window._$originalAddEventListener(type, handler, useCapture);
}
window.addEventListener = addEventListener;
redirect(addEventListener, window._$originalAddEventListener);
})();
\ No newline at end of file
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
/* global intellisense, window, document, setTimeout, WinJS */
(function () {
"use strict";
var redirect = intellisense.redirectDefinition;
function makeAllEnumerable(v) {
/// <param name="v" type="Object" />
if (v && typeof v === "object") {
Object.getOwnPropertyNames(v).forEach(function (name) {
var pd = Object.getOwnPropertyDescriptor(v, name);
if (!pd.enumerable && pd.configurable) {
pd.enumerable = true;
Object.defineProperty(v, name, pd);
}
});
}
return v;
}
function wrap(old) {
/// <param name="old" type="Function" />
var wrapper = function () {
var args = [];
for (var i = 0, len = arguments.length; i < len; i++) {
args.push(makeAllEnumerable(arguments[i]));
}
return old.apply(this, args);
};
redirect(wrapper, old);
return wrapper;
}
function wrapAllMethods(v) {
/// <param name="v" type="Object" />
if (v) {
Object.getOwnPropertyNames(v).forEach(function (name) {
var value = v[name];
if (typeof value === "function") {
v[name] = wrap(value);
}
});
}
return v;
}
if (this.WinJS) {
wrapAllMethods(WinJS.Namespace);
wrapAllMethods(WinJS.Class);
}
(function () {
var originalApplicationStart = WinJS.Application.start;
WinJS.Application.start = function () {
// Call app.stop() when execution completes to ensure that the subsequent calls to app.start() do not see the app as running.
var app = this;
setTimeout(function () {
app.stop();
}, 0);
return originalApplicationStart.apply(this, arguments);
};
redirect(WinJS.Application.start, originalApplicationStart);
var originalPagesDefine = WinJS.UI.Pages.define;
WinJS.UI.Pages.define = function (uri, members) {
var result = originalPagesDefine.apply(this, arguments);
intellisense.callerDefines(result, members);
if (typeof uri === 'string') {
intellisense.declareNavigationContainer(result, "Page (" + uri + ")");
}
// Set the call contexts for IPageControlMembers
if (members) {
var pageInstance = new result();
if (typeof members.error === 'function') {
intellisense.setCallContext(members.error, { thisArg: pageInstance, args: [new Error()] });
}
if (typeof members.init === 'function') {
intellisense.setCallContext(members.init, { thisArg: pageInstance, args: [document.createElement('element'), {}] });
}
if (typeof members.load === 'function') {
intellisense.setCallContext(members.load, { thisArg: pageInstance, args: [""] });
}
if (typeof members.processed === 'function') {
intellisense.setCallContext(members.processed, { thisArg: pageInstance, args: [document.createElement('element'), {}] });
}
if (typeof members.ready === 'function') {
intellisense.setCallContext(members.ready, { thisArg: pageInstance, args: [document.createElement('element'), {}] });
}
if (typeof members.render === 'function') {
intellisense.setCallContext(members.render, { thisArg: pageInstance, args: [document.createElement('element'), {}, WinJS.Promise.wrap()] });
}
}
return result;
};
redirect(WinJS.UI.Pages.define, originalPagesDefine);
// Simulate a call to a class' instance/static methods for WinJS.Class.define
var originalClassDefine = WinJS.Class.define;
WinJS.Class.define = function (constructor, instanceMembers, staticMembers) {
var result = originalClassDefine.call(this, constructor, instanceMembers, staticMembers);
// Go through the instance members to find methods
if (instanceMembers) {
var classInstance;
Object.getOwnPropertyNames(instanceMembers).forEach(function (name) {
var member = instanceMembers[name];
if (typeof member === 'function') {
intellisense.setCallContext(member, {
get thisArg() {
if (!classInstance) {
classInstance = new result();
}
return classInstance;
}
});
}
});
}
// Go through the static members to find methods
if (staticMembers) {
Object.getOwnPropertyNames(staticMembers).forEach(function (name) {
var member = staticMembers[name];
if (typeof member === 'function') {
intellisense.setCallContext(member, { thisArg: result });
}
});
}
return result;
};
redirect(WinJS.Class.define, originalClassDefine);
// Define the caller location property for WinJS.Namespace.define
var originalNamespaceDefine = WinJS.Namespace.define;
WinJS.Namespace.define = function (name, members) {
var result = originalNamespaceDefine.call(this, name, members);
if (typeof name === 'string' && result) {
// Get the global object
var globalObj = (function () {
return this;
})();
// Define the caller location of parent namespaces that haven't yet been defined
var path;
var namespaceParts = name.split(".");
for (var i = 0; i < namespaceParts.length - 1; i++) {
path = ((i === 0) ? namespaceParts[i] : path += "." + namespaceParts[i]);
var item = globalObj[path];
if (item) {
intellisense.callerDefines(item);
}
}
// Define the caller location of the original namespace
intellisense.callerDefines(result, members);
}
return result;
};
redirect(WinJS.Namespace.define, originalNamespaceDefine);
intellisense.setCallContext(WinJS.Promise, { thisArg: {}, args: [function () { }] });
})();
(function () {
// In the language serivce all promises are completed promises. The completed promise class is private
// to WinJS, however, we can get access to the prototype through one of the promise instances by
// getting the instance's constructor's prototype.
var promisePrototype = WinJS.Promise.as(1).constructor.prototype;
// Setting the argument calling context of the done and then methods to be an instance of Error().
// The completion callback is handled in WinJS itself through a <returns> metadata comment.
var originalDone = promisePrototype.done;
promisePrototype.done = function (c, e, p) {
intellisense.setCallContext(e, { thisArg: this, args: [new Error()] });
return originalDone.apply(this, arguments);
};
redirect(promisePrototype.done, originalDone);
var originalThen = promisePrototype.then;
promisePrototype.then = function (c, e, p) {
intellisense.setCallContext(e, { thisArg: this, args: [new Error()] });
return originalThen.apply(this, arguments);
};
redirect(promisePrototype.then, originalThen);
})();
if (window._$originalAddEventListener) {
window.addEventListener = window._$originalAddEventListener;
window._$originalAddEventListener = null;
delete window._$originalAddEventListener;
}
})();
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*!
Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
Build: 4.0.1.winjs.2015.6.10
Version: WinJS.4.0
*/
(function () {
var globalObject =
typeof window !== 'undefined' ? window :
typeof self !== 'undefined' ? self :
typeof global !== 'undefined' ? global :
{};
globalObject.strings = globalObject.strings || {};
function addStrings(keyPrefix, strings) {
Object.keys(strings).forEach(function (key) {
globalObject.strings[keyPrefix + key] = strings[key];
});
}
addStrings("ms-resource:///Microsoft.WinJS/",
{
"ui/appBarAriaLabel": "App Bar",
"ui/appBarCommandAriaLabel": "App Bar Item",
"ui/appBarOverflowButtonAriaLabel": "View more",
"ui/autoSuggestBoxAriaLabel": "Autosuggestbox",
"ui/autoSuggestBoxAriaLabelInputNoPlaceHolder": "Autosuggestbox, enter to submit query, esc to clear text",
"ui/autoSuggestBoxAriaLabelInputPlaceHolder": "Autosuggestbox, {0}, enter to submit query, esc to clear text",
"ui/autoSuggestBoxAriaLabelQuery": "Suggestion: {0}",
"_ui/autoSuggestBoxAriaLabelQuery.comment": "Suggestion: query text (example: Suggestion: contoso)",
"ui/autoSuggestBoxAriaLabelSeparator": "Separator: {0}",
"_ui/autoSuggestBoxAriaLabelSeparator.comment": "Separator: separator text (example: Separator: People or Separator: Apps)",
"ui/autoSuggestBoxAriaLabelResult": "Result: {0}, {1}",
"_ui/autoSuggestBoxAriaLabelResult.comment": "Result: text, detailed text (example: Result: contoso, www.contoso.com)",
"ui/averageRating": "Average Rating",
"ui/backbuttonarialabel": "Back",
"ui/chapterSkipBackMediaCommandDisplayText": "Chapter back",
"ui/chapterSkipForwardMediaCommandDisplayText": "Chapter forward",
"ui/clearYourRating" : "Clear your rating",
"ui/closedCaptionsLabelNone": "Off",
"ui/closedCaptionsMediaCommandDisplayText": "Closed captioning",
"ui/closeOverlay" : "Close",
"ui/commandingSurfaceAriaLabel": "CommandingSurface",
"ui/commandingSurfaceOverflowButtonAriaLabel": "View more",
"ui/datePicker": "Date Picker",
"ui/fastForwardMediaCommandDisplayText": "Fast forward",
"ui/fastForwardFeedbackDisplayText": " {0}X",
"ui/fastForwardFeedbackSlowMotionDisplayText": "0.5X",
"ui/flipViewPanningContainerAriaLabel": "Scrolling Container",
"ui/flyoutAriaLabel": "Flyout",
"ui/goToFullScreenButtonLabel": "Go full screen",
"ui/goToLiveMediaCommandDisplayText": "LIVE",
"ui/hubViewportAriaLabel": "Scrolling Container",
"ui/listViewViewportAriaLabel": "Scrolling Container",
"ui/mediaErrorAborted": "Playback was interrupted. Please try again.",
"ui/mediaErrorNetwork": "There was a network connection error.",
"ui/mediaErrorDecode": "The content could not be decoded",
"ui/mediaErrorSourceNotSupported": "This content type is not supported.",
"ui/mediaErrorUnknown": "There was an unknown error.",
"ui/mediaPlayerAudioTracksButtonLabel": "Audio tracks",
"ui/mediaPlayerCastButtonLabel": "Cast",
"ui/mediaPlayerChapterSkipBackButtonLabel": "Previous",
"ui/mediaPlayerChapterSkipForwardButtonLabel": "Next",
"ui/mediaPlayerClosedCaptionsButtonLabel": "Closed captions",
"ui/mediaPlayerFastForwardButtonLabel": "Fast forward",
"ui/mediaPlayerFullscreenButtonLabel": "Fullscreen",
"ui/mediaPlayerLiveButtonLabel": "LIVE",
"ui/mediaPlayerNextTrackButtonLabel": "Next",
"ui/mediaPlayerOverlayActiveOptionIndicator": "(On)",
"ui/mediaPlayerPauseButtonLabel": "Pause",
"ui/mediaPlayerPlayButtonLabel": "Play",
"ui/mediaPlayerPlayFromBeginningButtonLabel": "Replay",
"ui/mediaPlayerPlayRateButtonLabel": "Playback rate",
"ui/mediaPlayerPreviousTrackButtonLabel": "Previous",
"ui/mediaPlayerRewindButtonLabel": "Rewind",
"ui/mediaPlayerStopButtonLabel": "Stop",
"ui/mediaPlayerTimeSkipBackButtonLabel": "8 second replay",
"ui/mediaPlayerTimeSkipForwardButtonLabel": "30 second skip",
"ui/mediaPlayerToggleSnapButtonLabel": "Snap",
"ui/mediaPlayerVolumeButtonLabel": "Volume",
"ui/mediaPlayerZoomButtonLabel": "Zoom",
"ui/menuCommandAriaLabel": "Menu Item",
"ui/menuAriaLabel": "Menu",
"ui/navBarContainerViewportAriaLabel": "Scrolling Container",
"ui/nextTrackMediaCommandDisplayText": "Next track",
"ui/off" : "Off",
"ui/on" : "On",
"ui/pauseMediaCommandDisplayText": "Pause",
"ui/playFromBeginningMediaCommandDisplayText": "Play again",
"ui/playbackRateHalfSpeedLabel": "0.5x",
"ui/playbackRateNormalSpeedLabel": "Normal",
"ui/playbackRateOneAndHalfSpeedLabel": "1.5x",
"ui/playbackRateDoubleSpeedLabel": "2x",
"ui/playMediaCommandDisplayText": "Play",
"ui/pivotAriaLabel": "Pivot",
"ui/pivotViewportAriaLabel": "Scrolling Container",
"ui/replayMediaCommandDisplayText": "Play again",
"ui/rewindMediaCommandDisplayText": "Rewind",
"ui/rewindFeedbackDisplayText": " {0}X",
"ui/rewindFeedbackSlowMotionDisplayText": "0.5X",
"ui/searchBoxAriaLabel": "Searchbox",
"ui/searchBoxAriaLabelInputNoPlaceHolder": "Searchbox, enter to submit query, esc to clear text",
"ui/searchBoxAriaLabelInputPlaceHolder": "Searchbox, {0}, enter to submit query, esc to clear text",
"ui/searchBoxAriaLabelButton": "Click to submit query",
"ui/seeMore": "See more",
"ui/selectAMPM": "Select A.M P.M",
"ui/selectDay": "Select Day",
"ui/selectHour": "Select Hour",
"ui/selectMinute": "Select Minute",
"ui/selectMonth": "Select Month",
"ui/selectYear": "Select Year",
"ui/settingsFlyoutAriaLabel": "Settings Flyout",
"ui/stopMediaCommandDisplayText": "Stop",
"ui/tentativeRating": "Tentative Rating",
"ui/timePicker": "Time Picker",
"ui/timeSeparator": ":",
"ui/timeSkipBackMediaCommandDisplayText": "Skip back",
"ui/timeSkipForwardMediaCommandDisplayText": "Skip forward",
"ui/toolbarAriaLabel": "ToolBar",
"ui/toolbarOverflowButtonAriaLabel": "View more",
"ui/unrated": "Unrated",
"ui/userRating": "User Rating",
"ui/zoomMediaCommandDisplayText": "Zoom",
// AppBar Icons follow, the format of the ui.js and ui.resjson differ for
// the AppBarIcon namespace. The remainder of the file therefore differs.
// Code point comments are the icon glyphs in the 'Segoe UI Symbol' font.
"ui/appBarIcons/previous": "\uE100", //  group:Media
"_ui/appBarIcons/previous.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/next": "\uE101", //  group:Media
"_ui/appBarIcons/next.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/play": "\uE102", //  group:Media
"_ui/appBarIcons/play.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/pause": "\uE103", //  group:Media
"_ui/appBarIcons/pause.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/edit": "\uE104", //  group:File
"_ui/appBarIcons/edit.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/save": "\uE105", //  group:File
"_ui/appBarIcons/save.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/clear": "\uE106", //  group:File
"_ui/appBarIcons/clear.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/delete": "\uE107", //  group:File
"_ui/appBarIcons/delete.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/remove": "\uE108", //  group:File
"_ui/appBarIcons/remove.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/add": "\uE109", //  group:File
"_ui/appBarIcons/add.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/cancel": "\uE10A", //  group:Editing
"_ui/appBarIcons/cancel.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/accept": "\uE10B", //  group:General
"_ui/appBarIcons/accept.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/more": "\uE10C", //  group:General
"_ui/appBarIcons/more.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/redo": "\uE10D", //  group:Editing
"_ui/appBarIcons/redo.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/undo": "\uE10E", //  group:Editing
"_ui/appBarIcons/undo.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/home": "\uE10F", //  group:General
"_ui/appBarIcons/home.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/up": "\uE110", //  group:General
"_ui/appBarIcons/up.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/forward": "\uE111", //  group:General
"_ui/appBarIcons/forward.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/right": "\uE111", //  group:General
"_ui/appBarIcons/right.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/back": "\uE112", //  group:General
"_ui/appBarIcons/back.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/left": "\uE112", //  group:General
"_ui/appBarIcons/left.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/favorite": "\uE113", //  group:Media
"_ui/appBarIcons/favorite.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/camera": "\uE114", //  group:System
"_ui/appBarIcons/camera.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/settings": "\uE115", //  group:System
"_ui/appBarIcons/settings.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/video": "\uE116", //  group:Media
"_ui/appBarIcons/video.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/sync": "\uE117", //  group:Media
"_ui/appBarIcons/sync.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/download": "\uE118", //  group:Media
"_ui/appBarIcons/download.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mail": "\uE119", //  group:Mail and calendar
"_ui/appBarIcons/mail.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/find": "\uE11A", //  group:Data
"_ui/appBarIcons/find.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/help": "\uE11B", //  group:General
"_ui/appBarIcons/help.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/upload": "\uE11C", //  group:Media
"_ui/appBarIcons/upload.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/emoji": "\uE11D", //  group:Communications
"_ui/appBarIcons/emoji.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/twopage": "\uE11E", //  group:Layout
"_ui/appBarIcons/twopage.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/leavechat": "\uE11F", //  group:Communications
"_ui/appBarIcons/leavechat.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mailforward": "\uE120", //  group:Mail and calendar
"_ui/appBarIcons/mailforward.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/clock": "\uE121", //  group:General
"_ui/appBarIcons/clock.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/send": "\uE122", //  group:Mail and calendar
"_ui/appBarIcons/send.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/crop": "\uE123", //  group:Editing
"_ui/appBarIcons/crop.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/rotatecamera": "\uE124", //  group:System
"_ui/appBarIcons/rotatecamera.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/people": "\uE125", //  group:Communications
"_ui/appBarIcons/people.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/closepane": "\uE126", //  group:Layout
"_ui/appBarIcons/closepane.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/openpane": "\uE127", //  group:Layout
"_ui/appBarIcons/openpane.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/world": "\uE128", //  group:General
"_ui/appBarIcons/world.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/flag": "\uE129", //  group:Mail and calendar
"_ui/appBarIcons/flag.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/previewlink": "\uE12A", //  group:General
"_ui/appBarIcons/previewlink.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/globe": "\uE12B", //  group:Communications
"_ui/appBarIcons/globe.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/trim": "\uE12C", //  group:Editing
"_ui/appBarIcons/trim.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/attachcamera": "\uE12D", //  group:System
"_ui/appBarIcons/attachcamera.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/zoomin": "\uE12E", //  group:Layout
"_ui/appBarIcons/zoomin.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/bookmarks": "\uE12F", //  group:Editing
"_ui/appBarIcons/bookmarks.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/document": "\uE130", //  group:File
"_ui/appBarIcons/document.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/protecteddocument": "\uE131", //  group:File
"_ui/appBarIcons/protecteddocument.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/page": "\uE132", //  group:Layout
"_ui/appBarIcons/page.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/bullets": "\uE133", //  group:Editing
"_ui/appBarIcons/bullets.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/comment": "\uE134", //  group:Communications
"_ui/appBarIcons/comment.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mail2": "\uE135", //  group:Mail and calendar
"_ui/appBarIcons/mail2.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/contactinfo": "\uE136", //  group:Communications
"_ui/appBarIcons/contactinfo.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/hangup": "\uE137", //  group:Communications
"_ui/appBarIcons/hangup.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/viewall": "\uE138", //  group:Data
"_ui/appBarIcons/viewall.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mappin": "\uE139", //  group:General
"_ui/appBarIcons/mappin.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/phone": "\uE13A", //  group:Communications
"_ui/appBarIcons/phone.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/videochat": "\uE13B", //  group:Communications
"_ui/appBarIcons/videochat.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/switch": "\uE13C", //  group:Communications
"_ui/appBarIcons/switch.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/contact": "\uE13D", //  group:Communications
"_ui/appBarIcons/contact.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/rename": "\uE13E", //  group:File
"_ui/appBarIcons/rename.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/pin": "\uE141", //  group:System
"_ui/appBarIcons/pin.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/musicinfo": "\uE142", //  group:Media
"_ui/appBarIcons/musicinfo.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/go": "\uE143", //  group:General
"_ui/appBarIcons/go.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/keyboard": "\uE144", //  group:System
"_ui/appBarIcons/keyboard.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/dockleft": "\uE145", //  group:Layout
"_ui/appBarIcons/dockleft.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/dockright": "\uE146", //  group:Layout
"_ui/appBarIcons/dockright.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/dockbottom": "\uE147", //  group:Layout
"_ui/appBarIcons/dockbottom.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/remote": "\uE148", //  group:System
"_ui/appBarIcons/remote.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/refresh": "\uE149", //  group:Data
"_ui/appBarIcons/refresh.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/rotate": "\uE14A", //  group:Layout
"_ui/appBarIcons/rotate.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/shuffle": "\uE14B", //  group:Media
"_ui/appBarIcons/shuffle.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/list": "\uE14C", //  group:Editing
"_ui/appBarIcons/list.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/shop": "\uE14D", //  group:General
"_ui/appBarIcons/shop.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/selectall": "\uE14E", //  group:Data
"_ui/appBarIcons/selectall.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/orientation": "\uE14F", //  group:Layout
"_ui/appBarIcons/orientation.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/import": "\uE150", //  group:Data
"_ui/appBarIcons/import.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/importall": "\uE151", //  group:Data
"_ui/appBarIcons/importall.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/browsephotos": "\uE155", //  group:Media
"_ui/appBarIcons/browsephotos.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/webcam": "\uE156", //  group:System
"_ui/appBarIcons/webcam.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/pictures": "\uE158", //  group:Media
"_ui/appBarIcons/pictures.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/savelocal": "\uE159", //  group:File
"_ui/appBarIcons/savelocal.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/caption": "\uE15A", //  group:Media
"_ui/appBarIcons/caption.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/stop": "\uE15B", //  group:Media
"_ui/appBarIcons/stop.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/showresults": "\uE15C", //  group:Data
"_ui/appBarIcons/showresults.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/volume": "\uE15D", //  group:Media
"_ui/appBarIcons/volume.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/repair": "\uE15E", //  group:System
"_ui/appBarIcons/repair.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/message": "\uE15F", //  group:Communications
"_ui/appBarIcons/message.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/page2": "\uE160", //  group:Layout
"_ui/appBarIcons/page2.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/calendarday": "\uE161", //  group:Mail and calendar
"_ui/appBarIcons/calendarday.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/calendarweek": "\uE162", //  group:Mail and calendar
"_ui/appBarIcons/calendarweek.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/calendar": "\uE163", //  group:Mail and calendar
"_ui/appBarIcons/calendar.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/characters": "\uE164", //  group:Editing
"_ui/appBarIcons/characters.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mailreplyall": "\uE165", //  group:Mail and calendar
"_ui/appBarIcons/mailreplyall.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/read": "\uE166", //  group:Mail and calendar
"_ui/appBarIcons/read.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/link": "\uE167", //  group:Communications
"_ui/appBarIcons/link.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/accounts": "\uE168", //  group:Communications
"_ui/appBarIcons/accounts.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/showbcc": "\uE169", //  group:Mail and calendar
"_ui/appBarIcons/showbcc.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/hidebcc": "\uE16A", //  group:Mail and calendar
"_ui/appBarIcons/hidebcc.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/cut": "\uE16B", //  group:Editing
"_ui/appBarIcons/cut.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/attach": "\uE16C", //  group:Mail and calendar
"_ui/appBarIcons/attach.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/paste": "\uE16D", //  group:Editing
"_ui/appBarIcons/paste.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/filter": "\uE16E", //  group:Data
"_ui/appBarIcons/filter.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/copy": "\uE16F", //  group:Editing
"_ui/appBarIcons/copy.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/emoji2": "\uE170", //  group:Mail and calendar
"_ui/appBarIcons/emoji2.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/important": "\uE171", //  group:Mail and calendar
"_ui/appBarIcons/important.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mailreply": "\uE172", //  group:Mail and calendar
"_ui/appBarIcons/mailreply.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/slideshow": "\uE173", //  group:Media
"_ui/appBarIcons/slideshow.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/sort": "\uE174", //  group:Data
"_ui/appBarIcons/sort.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/manage": "\uE178", //  group:System
"_ui/appBarIcons/manage.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/allapps": "\uE179", //  group:System
"_ui/appBarIcons/allapps.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/disconnectdrive": "\uE17A", //  group:System
"_ui/appBarIcons/disconnectdrive.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mapdrive": "\uE17B", //  group:System
"_ui/appBarIcons/mapdrive.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/newwindow": "\uE17C", //  group:System
"_ui/appBarIcons/newwindow.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/openwith": "\uE17D", //  group:System
"_ui/appBarIcons/openwith.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/contactpresence": "\uE181", //  group:Communications
"_ui/appBarIcons/contactpresence.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/priority": "\uE182", //  group:Mail and calendar
"_ui/appBarIcons/priority.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/uploadskydrive": "\uE183", //  group:File
"_ui/appBarIcons/uploadskydrive.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/gototoday": "\uE184", //  group:Mail and calendar
"_ui/appBarIcons/gototoday.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/font": "\uE185", //  group:Editing
"_ui/appBarIcons/font.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/fontcolor": "\uE186", //  group:Editing
"_ui/appBarIcons/fontcolor.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/contact2": "\uE187", //  group:Communications
"_ui/appBarIcons/contact2.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/folder": "\uE188", //  group:File
"_ui/appBarIcons/folder.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/audio": "\uE189", //  group:Media
"_ui/appBarIcons/audio.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/placeholder": "\uE18A", //  group:General
"_ui/appBarIcons/placeholder.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/view": "\uE18B", //  group:Layout
"_ui/appBarIcons/view.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/setlockscreen": "\uE18C", //  group:System
"_ui/appBarIcons/setlockscreen.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/settile": "\uE18D", //  group:System
"_ui/appBarIcons/settile.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/cc": "\uE190", //  group:Media
"_ui/appBarIcons/cc.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/stopslideshow": "\uE191", //  group:Media
"_ui/appBarIcons/stopslideshow.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/permissions": "\uE192", //  group:System
"_ui/appBarIcons/permissions.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/highlight": "\uE193", //  group:Editing
"_ui/appBarIcons/highlight.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/disableupdates": "\uE194", //  group:System
"_ui/appBarIcons/disableupdates.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/unfavorite": "\uE195", //  group:Media
"_ui/appBarIcons/unfavorite.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/unpin": "\uE196", //  group:System
"_ui/appBarIcons/unpin.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/openlocal": "\uE197", //  group:File
"_ui/appBarIcons/openlocal.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/mute": "\uE198", //  group:Media
"_ui/appBarIcons/mute.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/italic": "\uE199", //  group:Editing
"_ui/appBarIcons/italic.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/underline": "\uE19A", //  group:Editing
"_ui/appBarIcons/underline.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/bold": "\uE19B", //  group:Editing
"_ui/appBarIcons/bold.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/movetofolder": "\uE19C", //  group:File
"_ui/appBarIcons/movetofolder.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/likedislike": "\uE19D", //  group:Data
"_ui/appBarIcons/likedislike.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/dislike": "\uE19E", //  group:Data
"_ui/appBarIcons/dislike.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/like": "\uE19F", //  group:Data
"_ui/appBarIcons/like.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/alignright": "\uE1A0", //  group:Editing
"_ui/appBarIcons/alignright.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/aligncenter": "\uE1A1", //  group:Editing
"_ui/appBarIcons/aligncenter.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/alignleft": "\uE1A2", //  group:Editing
"_ui/appBarIcons/alignleft.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/zoom": "\uE1A3", //  group:Layout
"_ui/appBarIcons/zoom.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/zoomout": "\uE1A4", //  group:Layout
"_ui/appBarIcons/zoomout.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/openfile": "\uE1A5", //  group:File
"_ui/appBarIcons/openfile.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/otheruser": "\uE1A6", //  group:System
"_ui/appBarIcons/otheruser.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/admin": "\uE1A7", //  group:System
"_ui/appBarIcons/admin.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/street": "\uE1C3", //  group:General
"_ui/appBarIcons/street.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/map": "\uE1C4", //  group:General
"_ui/appBarIcons/map.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/clearselection": "\uE1C5", //  group:Data
"_ui/appBarIcons/clearselection.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/fontdecrease": "\uE1C6", //  group:Editing
"_ui/appBarIcons/fontdecrease.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/fontincrease": "\uE1C7", //  group:Editing
"_ui/appBarIcons/fontincrease.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/fontsize": "\uE1C8", //  group:Editing
"_ui/appBarIcons/fontsize.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/cellphone": "\uE1C9", //  group:Communications
"_ui/appBarIcons/cellphone.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/reshare": "\uE1CA", //  group:Communications
"_ui/appBarIcons/reshare.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/tag": "\uE1CB", //  group:Data
"_ui/appBarIcons/tag.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/repeatone": "\uE1CC", //  group:Media
"_ui/appBarIcons/repeatone.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/repeatall": "\uE1CD", //  group:Media
"_ui/appBarIcons/repeatall.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/outlinestar": "\uE1CE", //  group:Data
"_ui/appBarIcons/outlinestar.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/solidstar": "\uE1CF", //  group:Data
"_ui/appBarIcons/solidstar.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/calculator": "\uE1D0", //  group:General
"_ui/appBarIcons/calculator.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/directions": "\uE1D1", //  group:General
"_ui/appBarIcons/directions.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/target": "\uE1D2", //  group:General
"_ui/appBarIcons/target.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/library": "\uE1D3", //  group:Media
"_ui/appBarIcons/library.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/phonebook": "\uE1D4", //  group:Communications
"_ui/appBarIcons/phonebook.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/memo": "\uE1D5", //  group:Communications
"_ui/appBarIcons/memo.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/microphone": "\uE1D6", //  group:System
"_ui/appBarIcons/microphone.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/postupdate": "\uE1D7", //  group:Communications
"_ui/appBarIcons/postupdate.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/backtowindow": "\uE1D8", //  group:Layout
"_ui/appBarIcons/backtowindow.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/fullscreen": "\uE1D9", //  group:Layout
"_ui/appBarIcons/fullscreen.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/newfolder": "\uE1DA", //  group:File
"_ui/appBarIcons/newfolder.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/calendarreply": "\uE1DB", //  group:Mail and calendar
"_ui/appBarIcons/calendarreply.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/unsyncfolder": "\uE1DD", //  group:File
"_ui/appBarIcons/unsyncfolder.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/reporthacked": "\uE1DE", //  group:Communications
"_ui/appBarIcons/reporthacked.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/syncfolder": "\uE1DF", //  group:File
"_ui/appBarIcons/syncfolder.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/blockcontact": "\uE1E0", //  group:Communications
"_ui/appBarIcons/blockcontact.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/switchapps": "\uE1E1", //  group:System
"_ui/appBarIcons/switchapps.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/addfriend": "\uE1E2", //  group:Communications
"_ui/appBarIcons/addfriend.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/touchpointer": "\uE1E3", //  group:System
"_ui/appBarIcons/touchpointer.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/gotostart": "\uE1E4", //  group:System
"_ui/appBarIcons/gotostart.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/zerobars": "\uE1E5", //  group:System
"_ui/appBarIcons/zerobars.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/onebar": "\uE1E6", //  group:System
"_ui/appBarIcons/onebar.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/twobars": "\uE1E7", //  group:System
"_ui/appBarIcons/twobars.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/threebars": "\uE1E8", //  group:System
"_ui/appBarIcons/threebars.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/fourbars": "\uE1E9", //  group:System
"_ui/appBarIcons/fourbars.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/scan": "\uE294", //  group:General
"_ui/appBarIcons/scan.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/preview": "\uE295", //  group:General
"_ui/appBarIcons/preview.comment": "{Locked:qps-ploc,qps-plocm}",
"ui/appBarIcons/hamburger": "\uE700", //  group:General
"_ui/appBarIcons/hamburger.comment": "{Locked:qps-ploc,qps-plocm}"
}
);
}());
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "winjs",
"title": "Windows Library for JavaScript (WinJS)",
"description": "WinJS is a set of JavaScript toolkits that allow developers to build applications using HTML/JS/CSS technology.",
"version": "4.0.1",
"main": "js/ui.js",
"homepage": "http://try.buildwinjs.com/",
"author": {
"name": "Microsoft Corporation and other contributors",
"url": "https://github.com/winjs/winjs/graphs/contributors"
},
"repository": {
"type": "git",
"url": "https://github.com/winjs/winjs"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/winjs/winjs/blob/master/License.txt"
}
],
"bugs": {
"url": "https://github.com/winjs/winjs/issues"
},
"devDependencies": {
"chalk": "~0.5.1",
"fs-extra": "^0.10.0",
"glob": "^4.0.5",
"grunt": "~0.4.5",
"grunt-contrib-clean": "~0.6.0",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-connect": "^0.8.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-cssmin": "^0.12.3",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-less": "~0.11.4",
"grunt-contrib-requirejs": "^0.4.4",
"grunt-contrib-uglify": "^0.5.1",
"grunt-jscs": "^0.6.2",
"grunt-replace": "~0.7.8",
"grunt-saucelabs": "git+https://github.com/xirzec/grunt-saucelabs.git#debug",
"grunt-shell": "~0.7.0",
"grunt-ts": "~3.0.0",
"http-post": "~0.1.1",
"less": "^1.7.4",
"load-grunt-tasks": "^0.6.0",
"minimist": "0.2.0",
"qunitjs": "~1.14.0",
"seed-random": "^2.2.0",
"text-table": "~0.2.0",
"typescript": "1.4.1",
"websocket": "^1.0.8"
},
"_id": "winjs@4.0.1",
"scripts": {},
"_shasum": "7bf65fadab719fec2bed306540e2cf69948e2e30",
"_from": "winjs@>=4.0.0",
"_npmVersion": "2.7.4",
"_nodeVersion": "0.12.2",
"_npmUser": {
"name": "rigdern",
"email": "adam.comella@outlook.com"
},
"dist": {
"shasum": "7bf65fadab719fec2bed306540e2cf69948e2e30",
"tarball": "http://registry.npmjs.org/winjs/-/winjs-4.0.1.tgz"
},
"maintainers": [
{
"name": "xirzec",
"email": "xirzec@xirzec.com"
},
{
"name": "phosphoer",
"email": "david0evans@gmail.com"
},
{
"name": "rigdern",
"email": "adam.comella@outlook.com"
}
],
"directories": {},
"_resolved": "https://registry.npmjs.org/winjs/-/winjs-4.0.1.tgz",
"readme": "ERROR: No README data found!"
}
#!/usr/bin/env node
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
// Coho updates this line:
var VERSION = "4.2.0";
console.log(VERSION);
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
:: specific language governing permissions and limitations :: specific language governing permissions and limitations
:: under the License :: under the License
@ECHO OFF @ECHO OFF
SET full_path=%~dp0 SET full_path="%~dp0"
IF EXIST "%full_path%..\VERSION" ( IF EXIST %full_path%..\VERSION (
type "%full_path%..\VERSION" type %full_path%..\VERSION
) ELSE ( ) ELSE (
ECHO. ECHO.
ECHO ERROR: Could not find file VERSION in project folder ECHO ERROR: Could not find file VERSION in project folder
......
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"> <Package xmlns="http://schemas.microsoft.com/appx/2010/manifest" xmlns:m2="http://schemas.microsoft.com/appx/2013/manifest" xmlns:m3="http://schemas.microsoft.com/appx/2014/manifest" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest">
<Identity Name="de.appplant.localnotification.example" Publisher="CN=$username$" Version="0.0.1.0" /> <Identity Name="de.appplant.localnotification.example" Publisher="CN=$username$" Version="0.0.1.0" />
<mp:PhoneIdentity PhoneProductId="1482d0c0-f943-11e4-ad39-81ab0f14e62c" PhonePublisherId="db093ed5-53b1-45f7-af72-751e8f36ab80" /> <mp:PhoneIdentity PhoneProductId="a3eae610-af16-11e5-876a-5d07037bd8ec" PhonePublisherId="db093ed5-53b1-45f7-af72-751e8f36ab80" />
<Properties> <Properties>
<DisplayName>NotificationExample</DisplayName> <DisplayName>NotificationExample</DisplayName>
<PublisherDisplayName>Apache Cordova Team</PublisherDisplayName> <PublisherDisplayName>Apache Cordova Team</PublisherDisplayName>
......
<?xml version='1.0' encoding='utf-8'?>
<Package IgnorableNamespaces="uap mp" xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10">
<Identity Name="de.appplant.localnotification.example" Publisher="CN=$username$" Version="0.0.1.0" />
<mp:PhoneIdentity PhoneProductId="a3eae610-af16-11e5-876a-5d07037bd8ec" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>NotificationExample</DisplayName>
<PublisherDisplayName>Apache Cordova Team</PublisherDisplayName>
<Logo>images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily MaxVersionTested="10.0.10240.0" MinVersion="10.0.10240.0" Name="Windows.Universal" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="de.appplant.localnotification.example" StartPage="ms-appx-web:///www/index.html">
<uap:VisualElements BackgroundColor="#464646" Description="CordovaApp" DisplayName="NotificationExample" Square150x150Logo="images\Square150x150Logo.png" Square44x44Logo="images\Square44x44Logo.png" ToastCapable="true">
<uap:SplashScreen Image="images\splashscreen.png" />
<uap:DefaultTile ShortName="NotificationExample" Square310x310Logo="images\Square310x310Logo.png" Square71x71Logo="images\Square71x71Logo.png" Wide310x150Logo="images\Wide310x150Logo.png" />
</uap:VisualElements>
<uap:ApplicationContentUriRules>
<uap:Rule Match="ms-appx-web:///" Type="include" WindowsRuntimeAccess="all" />
</uap:ApplicationContentUriRules>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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, plusplus:true*/
/*global require, module, console */
var cordova = require('cordova');
var execProxy = require('cordova/exec/proxy');
/**
* Execute a cordova command. It is up to the native side whether this action
* is synchronous or asynchronous. The native side can return:
* Synchronous: PluginResult object as a JSON string
* Asynchronous: Empty string ""
* If async, the native side will cordova.callbackSuccess or cordova.callbackError,
* depending upon the result of the action.
*
* @param {Function} success The success callback
* @param {Function} fail The fail callback
* @param {String} service The name of the service to use
* @param {String} action Action to be run in cordova
* @param {String[]} [args] Zero or more arguments to pass to the method
*/
module.exports = function (success, fail, service, action, args) {
var proxy = execProxy.get(service, action),
callbackId,
onSuccess,
onError;
args = args || [];
if (proxy) {
callbackId = service + cordova.callbackId++;
// console.log("EXEC:" + service + " : " + action);
if (typeof success === "function" || typeof fail === "function") {
cordova.callbacks[callbackId] = {success: success, fail: fail};
}
try {
// callbackOptions param represents additional optional parameters command could pass back, like keepCallback or
// custom callbackId, for example {callbackId: id, keepCallback: true, status: cordova.callbackStatus.JSON_EXCEPTION }
// CB-5806 [Windows8] Add keepCallback support to proxy
onSuccess = function (result, callbackOptions) {
callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
{
status: callbackStatus,
message: result,
keepCallback: callbackOptions.keepCallback || false
});
};
onError = function (err, callbackOptions) {
callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackError(callbackOptions.callbackId || callbackId,
{
status: callbackStatus,
message: err,
keepCallback: callbackOptions.keepCallback || false
});
};
proxy(onSuccess, onError, args);
} catch (e) {
console.log("Exception calling native with command :: " + service + " :: " + action + " ::exception=" + e);
}
} else {
if (typeof fail === "function") {
fail("Missing Command Error");
}
}
};
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 = {
// for backward compatibility we report 'windows8' when run on Windows 8.0 and
// 'windows' for Windows 8.1 and Windows Phone 8.1
id: (navigator.appVersion.indexOf("MSAppHost/1.0") !== -1) ? 'windows8' : 'windows',
bootstrap:function() {
var cordova = require('cordova'),
exec = require('cordova/exec'),
channel = cordova.require('cordova/channel'),
platform = require('cordova/platform'),
modulemapper = require('cordova/modulemapper');
modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
// we will make sure we get this channel
// TODO: remove this once other platforms catch up.
if(!channel.onActivated) {
channel.onActivated = cordova.addDocumentEventHandler('activated');
}
channel.onNativeReady.fire();
var onWinJSReady = function () {
var app = WinJS.Application;
var checkpointHandler = function checkpointHandler() {
cordova.fireDocumentEvent('pause',null,true);
};
var resumingHandler = function resumingHandler() {
cordova.fireDocumentEvent('resume',null,true);
};
// activation args are available via the activated event
// OR cordova.require('cordova/platform').activationContext
// activationContext:{type: actType, args: args};
var activationHandler = function (e) {
var args = e.detail.arguments;
var actType = e.detail.type;
platform.activationContext = { type: actType, args: args };
cordova.fireDocumentEvent('activated', platform.activationContext, true);
};
app.addEventListener("checkpoint", checkpointHandler);
app.addEventListener("activated", activationHandler, false);
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);
injectBackButtonHandler();
app.start();
};
if (!window.WinJS) {
var scriptElem = document.createElement("script");
if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) {
// Windows 10 UWP
scriptElem.src = '/www/WinJS/js/base.js';
} else if (navigator.appVersion.indexOf("Windows Phone 8.1;") !== -1) {
// windows phone 8.1 + Mobile IE 11
scriptElem.src = "//Microsoft.Phone.WinJS.2.1/js/base.js";
} else if (navigator.appVersion.indexOf("MSAppHost/2.0;") !== -1) {
// windows 8.1 + IE 11
scriptElem.src = "//Microsoft.WinJS.2.0/js/base.js";
} else {
// windows 8.0 + IE 10
scriptElem.src = "//Microsoft.WinJS.1.0/js/base.js";
}
scriptElem.addEventListener("load", onWinJSReady);
document.head.appendChild(scriptElem);
}
else {
onWinJSReady();
}
}
};
function injectBackButtonHandler() {
var app = WinJS.Application;
// create document event handler for backbutton
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
// preserve reference to original backclick implementation
// `false` as a result will trigger system default behaviour
var defaultBackButtonHandler = app.onbackclick || function () { return false; };
var backRequestedHandler = function backRequestedHandler(evt) {
// check if listeners are registered, if yes use custom backbutton event
// NOTE: On Windows Phone 8.1 backbutton handlers have to throw an exception in order to exit the app
if (backButtonChannel.numHandlers >= 1) {
try {
cordova.fireDocumentEvent('backbutton', evt, true);
evt.handled = true; // Windows Mobile requires handled to be set as well;
return true;
}
catch (e) {
return false;
}
}
// if not listeners are active, use default implementation (backwards compatibility)
else {
return defaultBackButtonHandler.apply(app, arguments);
}
};
// Only load this code if we're running on Win10 in a non-emulated app frame, otherwise crash \o/
if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) { // Windows 10 UWP (PC/Tablet/Phone)
var navigationManager = Windows.UI.Core.SystemNavigationManager.getForCurrentView();
// Inject a listener for the backbutton on the document.
backButtonChannel.onHasSubscribersChange = function () {
// If we just attached the first handler or detached the last handler,
// let native know we need to override the back button.
navigationManager.appViewBackButtonVisibility = (this.numHandlers > 0) ?
Windows.UI.Core.AppViewBackButtonVisibility.visible :
Windows.UI.Core.AppViewBackButtonVisibility.collapsed;
};
navigationManager.addEventListener("backrequested", backRequestedHandler, false);
} else { // Windows 8.1 Phone
// inject new back button handler
app.onbackclick = backRequestedHandler;
}
}
// Platform: windows // Platform: windows
// fc4db9145934bd0053161cbf9ffc0caf83b770c6 // 7703d38498920bdcfadd574e475553a26fc490e5
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
under the License. under the License.
*/ */
;(function() { ;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '3.8.0'; var PLATFORM_VERSION_BUILD_LABEL = '4.2.0';
// file: src/scripts/require.js // file: src/scripts/require.js
/*jshint -W079 */ /*jshint -W079 */
...@@ -101,10 +101,17 @@ if (typeof module === "object" && typeof require === "function") { ...@@ -101,10 +101,17 @@ if (typeof module === "object" && typeof require === "function") {
// file: src/cordova.js // file: src/cordova.js
define("cordova", function(require, exports, module) { define("cordova", function(require, exports, module) {
// Workaround for Windows 10 in hosted environment case
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
throw new Error("cordova already defined");
}
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
/** /**
* Intercept calls to addEventListener + removeEventListener and handle deviceready, * Intercept calls to addEventListener + removeEventListener and handle deviceready,
* resume, and pause events. * resume, and pause events.
...@@ -326,7 +333,6 @@ module.exports = cordova; ...@@ -326,7 +333,6 @@ module.exports = cordova;
// file: src/common/argscheck.js // file: src/common/argscheck.js
define("cordova/argscheck", function(require, exports, module) { define("cordova/argscheck", function(require, exports, module) {
var exec = require('cordova/exec');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var moduleExports = module.exports; var moduleExports = module.exports;
...@@ -811,7 +817,7 @@ module.exports = channel; ...@@ -811,7 +817,7 @@ module.exports = channel;
}); });
// file: src/windows/exec.js // file: c:/cordova/cordova-windows/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) { define("cordova/exec", function(require, exports, module) {
/*jslint sloppy:true, plusplus:true*/ /*jslint sloppy:true, plusplus:true*/
...@@ -855,18 +861,40 @@ module.exports = function (success, fail, service, action, args) { ...@@ -855,18 +861,40 @@ module.exports = function (success, fail, service, action, args) {
// CB-5806 [Windows8] Add keepCallback support to proxy // CB-5806 [Windows8] Add keepCallback support to proxy
onSuccess = function (result, callbackOptions) { onSuccess = function (result, callbackOptions) {
callbackOptions = callbackOptions || {}; callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackSuccess(callbackOptions.callbackId || callbackId, cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
{ {
status: callbackOptions.status || cordova.callbackStatus.OK, status: callbackStatus,
message: result, message: result,
keepCallback: callbackOptions.keepCallback || false keepCallback: callbackOptions.keepCallback || false
}); });
}; };
onError = function (err, callbackOptions) { onError = function (err, callbackOptions) {
callbackOptions = callbackOptions || {}; callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackError(callbackOptions.callbackId || callbackId, cordova.callbackError(callbackOptions.callbackId || callbackId,
{ {
status: callbackOptions.status || cordova.callbackStatus.ERROR, status: callbackStatus,
message: err, message: err,
keepCallback: callbackOptions.keepCallback || false keepCallback: callbackOptions.keepCallback || false
}); });
...@@ -882,6 +910,7 @@ module.exports = function (success, fail, service, action, args) { ...@@ -882,6 +910,7 @@ module.exports = function (success, fail, service, action, args) {
} }
} }
}; };
}); });
// file: src/common/exec/proxy.js // file: src/common/exec/proxy.js
...@@ -985,6 +1014,7 @@ if (!window.console.warn) { ...@@ -985,6 +1014,7 @@ if (!window.console.warn) {
// Register pause, resume and deviceready channels as events on document. // Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onActivated = cordova.addDocumentEventHandler('activated');
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
// Listen for DOMContentLoaded and notify our channel subscribers. // Listen for DOMContentLoaded and notify our channel subscribers.
...@@ -1046,10 +1076,12 @@ define("cordova/init_b", function(require, exports, module) { ...@@ -1046,10 +1076,12 @@ define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var cordova = require('cordova'); var cordova = require('cordova');
var modulemapper = require('cordova/modulemapper');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
var pluginloader = require('cordova/pluginloader');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
// setting exec // setting exec
cordova.exec = require('cordova/exec'); cordova.exec = require('cordova/exec');
...@@ -1112,6 +1144,7 @@ if (!window.console.warn) { ...@@ -1112,6 +1144,7 @@ if (!window.console.warn) {
// Register pause, resume and deviceready channels as events on document. // Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onActivated = cordova.addDocumentEventHandler('activated');
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
// Listen for DOMContentLoaded and notify our channel subscribers. // Listen for DOMContentLoaded and notify our channel subscribers.
...@@ -1133,10 +1166,19 @@ if (window._nativeReady) { ...@@ -1133,10 +1166,19 @@ if (window._nativeReady) {
// Call the platform-specific initialization. // Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap(); platform.bootstrap && platform.bootstrap();
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
// The delay allows the attached modules to be defined before the plugin loader looks for them.
setTimeout(function() {
pluginloader.load(function() {
channel.onPluginsReady.fire();
});
}, 0);
/** /**
* Create all cordova objects once native side is ready. * Create all cordova objects once native side is ready.
*/ */
channel.join(function() { channel.join(function() {
modulemapper.mapModules(window);
platform.initialize && platform.initialize(); platform.initialize && platform.initialize();
...@@ -1255,7 +1297,104 @@ exports.reset(); ...@@ -1255,7 +1297,104 @@ exports.reset();
}); });
// file: src/windows/platform.js // file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder'),
symbolList = [],
deprecationMap;
exports.reset = function() {
symbolList = [];
deprecationMap = {};
};
function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
symbolList.push(strategy, moduleName, symbolPath);
if (opt_deprecationMessage) {
deprecationMap[symbolPath] = opt_deprecationMessage;
}
}
// Note: Android 2.3 does have Function.bind().
exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
};
exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
};
exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
};
exports.runs = function(moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace(symbolPath, context) {
if (!symbolPath) {
return context;
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
cur = cur[part] = cur[part] || {};
}
return cur;
}
exports.mapModules = function(context) {
var origSymbols = {};
context.CDV_origSymbols = origSymbols;
for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i];
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
}
}
};
exports.getOriginalSymbol = function(context, symbolPath) {
var origSymbols = context.CDV_origSymbols;
if (origSymbols && (symbolPath in origSymbols)) {
return origSymbols[symbolPath];
}
var parts = symbolPath.split('.');
var obj = context;
for (var i = 0; i < parts.length; ++i) {
obj = obj && obj[parts[i]];
}
return obj;
};
exports.reset();
});
// file: c:/cordova/cordova-windows/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) { define("cordova/platform", function(require, exports, module) {
module.exports = { module.exports = {
...@@ -1266,9 +1405,16 @@ module.exports = { ...@@ -1266,9 +1405,16 @@ module.exports = {
var cordova = require('cordova'), var cordova = require('cordova'),
exec = require('cordova/exec'), exec = require('cordova/exec'),
channel = cordova.require('cordova/channel'), channel = cordova.require('cordova/channel'),
platform = require('cordova/platform'),
modulemapper = require('cordova/modulemapper'); modulemapper = require('cordova/modulemapper');
modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy'); modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
// we will make sure we get this channel
// TODO: remove this once other platforms catch up.
if(!channel.onActivated) {
channel.onActivated = cordova.addDocumentEventHandler('activated');
}
channel.onNativeReady.fire(); channel.onNativeReady.fire();
var onWinJSReady = function () { var onWinJSReady = function () {
...@@ -1281,16 +1427,32 @@ module.exports = { ...@@ -1281,16 +1427,32 @@ module.exports = {
cordova.fireDocumentEvent('resume',null,true); cordova.fireDocumentEvent('resume',null,true);
}; };
// activation args are available via the activated event
// OR cordova.require('cordova/platform').activationContext
// activationContext:{type: actType, args: args};
var activationHandler = function (e) {
var args = e.detail.arguments;
var actType = e.detail.type;
platform.activationContext = { type: actType, args: args };
cordova.fireDocumentEvent('activated', platform.activationContext, true);
};
app.addEventListener("checkpoint", checkpointHandler); app.addEventListener("checkpoint", checkpointHandler);
app.addEventListener("activated", activationHandler, false);
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false); Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);
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);
injectBackButtonHandler();
app.start(); app.start();
}; };
if (!window.WinJS) { if (!window.WinJS) {
var scriptElem = document.createElement("script"); var scriptElem = document.createElement("script");
if (navigator.appVersion.indexOf("Windows Phone 8.1;") !== -1) { if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) {
// Windows 10 UWP
scriptElem.src = '/www/WinJS/js/base.js';
} else if (navigator.appVersion.indexOf("Windows Phone 8.1;") !== -1) {
// windows phone 8.1 + Mobile IE 11 // windows phone 8.1 + Mobile IE 11
scriptElem.src = "//Microsoft.Phone.WinJS.2.1/js/base.js"; scriptElem.src = "//Microsoft.Phone.WinJS.2.1/js/base.js";
} else if (navigator.appVersion.indexOf("MSAppHost/2.0;") !== -1) { } else if (navigator.appVersion.indexOf("MSAppHost/2.0;") !== -1) {
...@@ -1309,6 +1471,55 @@ module.exports = { ...@@ -1309,6 +1471,55 @@ module.exports = {
} }
}; };
function injectBackButtonHandler() {
var app = WinJS.Application;
// create document event handler for backbutton
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
// preserve reference to original backclick implementation
// `false` as a result will trigger system default behaviour
var defaultBackButtonHandler = app.onbackclick || function () { return false; };
var backRequestedHandler = function backRequestedHandler(evt) {
// check if listeners are registered, if yes use custom backbutton event
// NOTE: On Windows Phone 8.1 backbutton handlers have to throw an exception in order to exit the app
if (backButtonChannel.numHandlers >= 1) {
try {
cordova.fireDocumentEvent('backbutton', evt, true);
evt.handled = true; // Windows Mobile requires handled to be set as well;
return true;
}
catch (e) {
return false;
}
}
// if not listeners are active, use default implementation (backwards compatibility)
else {
return defaultBackButtonHandler.apply(app, arguments);
}
};
// Only load this code if we're running on Win10 in a non-emulated app frame, otherwise crash \o/
if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) { // Windows 10 UWP (PC/Tablet/Phone)
var navigationManager = Windows.UI.Core.SystemNavigationManager.getForCurrentView();
// Inject a listener for the backbutton on the document.
backButtonChannel.onHasSubscribersChange = function () {
// If we just attached the first handler or detached the last handler,
// let native know we need to override the back button.
navigationManager.appViewBackButtonVisibility = (this.numHandlers > 0) ?
Windows.UI.Core.AppViewBackButtonVisibility.visible :
Windows.UI.Core.AppViewBackButtonVisibility.collapsed;
};
navigationManager.addEventListener("backrequested", backRequestedHandler, false);
} else { // Windows 8.1 Phone
// inject new back button handler
app.onbackclick = backRequestedHandler;
}
}
}); });
// file: src/common/pluginloader.js // file: src/common/pluginloader.js
...@@ -1423,6 +1634,54 @@ exports.load = function(callback) { ...@@ -1423,6 +1634,54 @@ exports.load = function(callback) {
}); });
// file: src/common/pluginloader_b.js
define("cordova/pluginloader_b", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
// Handler for the cordova_plugins.js content.
// See plugman's plugin_loader.js for the details of this object.
function handlePluginsObject(moduleList) {
// if moduleList is not defined or empty, we've nothing to do
if (!moduleList || !moduleList.length) {
return;
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
if (module.clobbers && module.clobbers.length) {
for (var j = 0; j < module.clobbers.length; j++) {
modulemapper.clobbers(module.id, module.clobbers[j]);
}
}
if (module.merges && module.merges.length) {
for (var k = 0; k < module.merges.length; k++) {
modulemapper.merges(module.id, module.merges[k]);
}
}
// Finally, if runs is truthy we want to simply require() the module.
if (module.runs) {
modulemapper.runs(module.id);
}
}
}
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
// but the method accepts callback to be compatible with non-browserify flow.
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
// no plugins to load, or they are all done.
exports.load = function(callback) {
var moduleList = require("cordova/plugin_list");
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js // file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) { define("cordova/urlutil", function(require, exports, module) {
...@@ -1502,15 +1761,14 @@ utils.typeName = function(val) { ...@@ -1502,15 +1761,14 @@ utils.typeName = function(val) {
/** /**
* Returns an indication of whether the argument is an array or not * Returns an indication of whether the argument is an array or not
*/ */
utils.isArray = function(a) { utils.isArray = Array.isArray ||
return utils.typeName(a) == 'Array'; function(a) {return utils.typeName(a) == 'Array';};
};
/** /**
* Returns an indication of whether the argument is a Date or not * Returns an indication of whether the argument is a Date or not
*/ */
utils.isDate = function(d) { utils.isDate = function(d) {
return utils.typeName(d) == 'Date'; return (d instanceof Date);
}; };
/** /**
...@@ -1544,17 +1802,25 @@ utils.clone = function(obj) { ...@@ -1544,17 +1802,25 @@ utils.clone = function(obj) {
* Returns a wrapped version of the function * Returns a wrapped version of the function
*/ */
utils.close = function(context, func, params) { utils.close = function(context, func, params) {
if (typeof params == 'undefined') {
return function() { return function() {
return func.apply(context, arguments); var args = params || arguments;
return func.apply(context, args);
}; };
} else {
return function() {
return func.apply(context, params);
};
}
}; };
//------------------------------------------------------------------------------
function UUIDcreatePart(length) {
var uuidpart = "";
for (var i=0; i<length; i++) {
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
if (uuidchar.length == 1) {
uuidchar = "0" + uuidchar;
}
uuidpart += uuidchar;
}
return uuidpart;
}
/** /**
* Create a UUID * Create a UUID
*/ */
...@@ -1566,6 +1832,7 @@ utils.createUUID = function() { ...@@ -1566,6 +1832,7 @@ utils.createUUID = function() {
UUIDcreatePart(6); UUIDcreatePart(6);
}; };
/** /**
* Extends a child object from a parent object using classical inheritance * Extends a child object from a parent object using classical inheritance
* pattern. * pattern.
...@@ -1575,6 +1842,7 @@ utils.extend = (function() { ...@@ -1575,6 +1842,7 @@ utils.extend = (function() {
var F = function() {}; var F = function() {};
// extend Child from Parent // extend Child from Parent
return function(Child, Parent) { return function(Child, Parent) {
F.prototype = Parent.prototype; F.prototype = Parent.prototype;
Child.prototype = new F(); Child.prototype = new F();
Child.__super__ = Parent.prototype; Child.__super__ = Parent.prototype;
...@@ -1594,18 +1862,7 @@ utils.alert = function(msg) { ...@@ -1594,18 +1862,7 @@ utils.alert = function(msg) {
}; };
//------------------------------------------------------------------------------
function UUIDcreatePart(length) {
var uuidpart = "";
for (var i=0; i<length; i++) {
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
if (uuidchar.length == 1) {
uuidchar = "0" + uuidchar;
}
uuidpart += uuidchar;
}
return uuidpart;
}
}); });
......
cordova.define('cordova/plugin_list', function(require, exports, module) { cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [ module.exports = [
{ {
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js", "file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device", "id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device", "pluginId": "cordova-plugin-device",
...@@ -30,6 +17,19 @@ module.exports = [ ...@@ -30,6 +17,19 @@ module.exports = [
] ]
}, },
{ {
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification", "pluginId": "de.appplant.cordova.plugin.local-notification",
...@@ -84,8 +84,8 @@ module.exports = [ ...@@ -84,8 +84,8 @@ module.exports = [
module.exports.metadata = module.exports.metadata =
// TOP OF METADATA // TOP OF METADATA
{ {
"cordova-plugin-x-toast": "2.3.1",
"cordova-plugin-device": "1.1.0", "cordova-plugin-device": "1.1.0",
"cordova-plugin-x-toast": "2.3.1",
"cordova-plugin-registerusernotificationsettings": "1.0.2", "cordova-plugin-registerusernotificationsettings": "1.0.2",
"de.appplant.cordova.plugin.local-notification": "0.8.3-dev" "de.appplant.cordova.plugin.local-notification": "0.8.3-dev"
} }
......
...@@ -103,9 +103,7 @@ proxy.core = { ...@@ -103,9 +103,7 @@ proxy.core = {
toast.id = options.id; toast.id = options.id;
toast.tag = 'Toast' + toast.id; toast.tag = 'Toast' + toast.id;
Notifications.ToastNotificationManager this.getToastNotifier().addToSchedule(toast);
.createToastNotifier()
.addToSchedule(toast);
}, },
/** /**
...@@ -326,9 +324,12 @@ proxy.core = { ...@@ -326,9 +324,12 @@ proxy.core = {
ids = []; ids = [];
for (var i = 0; i < toasts.length; i++) { for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i]; var toast = toasts[i],
toastId = this.getToastId(toast);
ids.push(this.getToastId(toast)); if (ids.indexOf(toastId) == -1) {
ids.push(toastId);
}
} }
return ids; return ids;
......
...@@ -412,8 +412,8 @@ channel.onCordovaReady.subscribe(function () { ...@@ -412,8 +412,8 @@ channel.onCordovaReady.subscribe(function () {
}); });
// Handle onclick event // Handle onclick event
WinJS.Application.addEventListener('activated', function (args) { document.addEventListener('activated', function (e) {
var id = args.detail.arguments, var id = e.args,
notification = exports.getAll([id])[0]; notification = exports.getAll([id])[0];
if (!notification) if (!notification)
......
...@@ -441,6 +441,9 @@ exports.registerPermission = function (callback, scope) { ...@@ -441,6 +441,9 @@ exports.registerPermission = function (callback, scope) {
*/ */
exports.on = function (event, callback, scope) { exports.on = function (event, callback, scope) {
if (typeof callback !== "function")
return;
if (!this._listener[event]) { if (!this._listener[event]) {
this._listener[event] = []; this._listener[event] = [];
} }
......
...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () {
switch (device.platform) { switch (device.platform) {
case 'Android': case 'Android':
defaults.icon = 'res://icon'; defaults.icon = 'res://ic_popup_reminder';
defaults.smallIcon = 'res://ic_popup_reminder'; defaults.smallIcon = undefined;
defaults.ongoing = false; defaults.ongoing = false;
defaults.autoClear = true; defaults.autoClear = true;
defaults.led = 'FFFFFF'; defaults.led = 'FF0000';
defaults.color = undefined;
break; break;
} }
......
...@@ -7,16 +7,21 @@ ...@@ -7,16 +7,21 @@
"files": { "files": {
"config.xml": { "config.xml": {
"parents": { "parents": {
"/widget": [] "/*": [
{
"xml": "<preference name=\"WindowsToastCapable\" value=\"true\" />",
"count": 1
}
]
} }
} }
} }
}, },
"installed_plugins": { "installed_plugins": {
"cordova-plugin-x-toast": { "cordova-plugin-device": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
}, },
"cordova-plugin-device": { "cordova-plugin-x-toast": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
}, },
"cordova-plugin-registerusernotificationsettings": { "cordova-plugin-registerusernotificationsettings": {
...@@ -29,19 +34,6 @@ ...@@ -29,19 +34,6 @@
"dependent_plugins": {}, "dependent_plugins": {},
"modules": [ "modules": [
{ {
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js", "file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device", "id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device", "pluginId": "cordova-plugin-device",
...@@ -58,6 +50,19 @@ ...@@ -58,6 +50,19 @@
] ]
}, },
{ {
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification", "pluginId": "de.appplant.cordova.plugin.local-notification",
...@@ -110,8 +115,8 @@ ...@@ -110,8 +115,8 @@
} }
], ],
"plugin_metadata": { "plugin_metadata": {
"cordova-plugin-x-toast": "2.3.1",
"cordova-plugin-device": "1.1.0", "cordova-plugin-device": "1.1.0",
"cordova-plugin-x-toast": "2.3.1",
"cordova-plugin-registerusernotificationsettings": "1.0.2", "cordova-plugin-registerusernotificationsettings": "1.0.2",
"de.appplant.cordova.plugin.local-notification": "0.8.3-dev" "de.appplant.cordova.plugin.local-notification": "0.8.3-dev"
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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, plusplus:true*/
/*global require, module, console */
var cordova = require('cordova');
var execProxy = require('cordova/exec/proxy');
/**
* Execute a cordova command. It is up to the native side whether this action
* is synchronous or asynchronous. The native side can return:
* Synchronous: PluginResult object as a JSON string
* Asynchronous: Empty string ""
* If async, the native side will cordova.callbackSuccess or cordova.callbackError,
* depending upon the result of the action.
*
* @param {Function} success The success callback
* @param {Function} fail The fail callback
* @param {String} service The name of the service to use
* @param {String} action Action to be run in cordova
* @param {String[]} [args] Zero or more arguments to pass to the method
*/
module.exports = function (success, fail, service, action, args) {
var proxy = execProxy.get(service, action),
callbackId,
onSuccess,
onError;
args = args || [];
if (proxy) {
callbackId = service + cordova.callbackId++;
// console.log("EXEC:" + service + " : " + action);
if (typeof success === "function" || typeof fail === "function") {
cordova.callbacks[callbackId] = {success: success, fail: fail};
}
try {
// callbackOptions param represents additional optional parameters command could pass back, like keepCallback or
// custom callbackId, for example {callbackId: id, keepCallback: true, status: cordova.callbackStatus.JSON_EXCEPTION }
// CB-5806 [Windows8] Add keepCallback support to proxy
onSuccess = function (result, callbackOptions) {
callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
{
status: callbackStatus,
message: result,
keepCallback: callbackOptions.keepCallback || false
});
};
onError = function (err, callbackOptions) {
callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackError(callbackOptions.callbackId || callbackId,
{
status: callbackStatus,
message: err,
keepCallback: callbackOptions.keepCallback || false
});
};
proxy(onSuccess, onError, args);
} catch (e) {
console.log("Exception calling native with command :: " + service + " :: " + action + " ::exception=" + e);
}
} else {
if (typeof fail === "function") {
fail("Missing Command Error");
}
}
};
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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 = {
// for backward compatibility we report 'windows8' when run on Windows 8.0 and
// 'windows' for Windows 8.1 and Windows Phone 8.1
id: (navigator.appVersion.indexOf("MSAppHost/1.0") !== -1) ? 'windows8' : 'windows',
bootstrap:function() {
var cordova = require('cordova'),
exec = require('cordova/exec'),
channel = cordova.require('cordova/channel'),
platform = require('cordova/platform'),
modulemapper = require('cordova/modulemapper');
modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
// we will make sure we get this channel
// TODO: remove this once other platforms catch up.
if(!channel.onActivated) {
channel.onActivated = cordova.addDocumentEventHandler('activated');
}
channel.onNativeReady.fire();
var onWinJSReady = function () {
var app = WinJS.Application;
var checkpointHandler = function checkpointHandler() {
cordova.fireDocumentEvent('pause',null,true);
};
var resumingHandler = function resumingHandler() {
cordova.fireDocumentEvent('resume',null,true);
};
// activation args are available via the activated event
// OR cordova.require('cordova/platform').activationContext
// activationContext:{type: actType, args: args};
var activationHandler = function (e) {
var args = e.detail.arguments;
var actType = e.detail.type;
platform.activationContext = { type: actType, args: args };
cordova.fireDocumentEvent('activated', platform.activationContext, true);
};
app.addEventListener("checkpoint", checkpointHandler);
app.addEventListener("activated", activationHandler, false);
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);
injectBackButtonHandler();
app.start();
};
if (!window.WinJS) {
var scriptElem = document.createElement("script");
if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) {
// Windows 10 UWP
scriptElem.src = '/www/WinJS/js/base.js';
} else if (navigator.appVersion.indexOf("Windows Phone 8.1;") !== -1) {
// windows phone 8.1 + Mobile IE 11
scriptElem.src = "//Microsoft.Phone.WinJS.2.1/js/base.js";
} else if (navigator.appVersion.indexOf("MSAppHost/2.0;") !== -1) {
// windows 8.1 + IE 11
scriptElem.src = "//Microsoft.WinJS.2.0/js/base.js";
} else {
// windows 8.0 + IE 10
scriptElem.src = "//Microsoft.WinJS.1.0/js/base.js";
}
scriptElem.addEventListener("load", onWinJSReady);
document.head.appendChild(scriptElem);
}
else {
onWinJSReady();
}
}
};
function injectBackButtonHandler() {
var app = WinJS.Application;
// create document event handler for backbutton
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
// preserve reference to original backclick implementation
// `false` as a result will trigger system default behaviour
var defaultBackButtonHandler = app.onbackclick || function () { return false; };
var backRequestedHandler = function backRequestedHandler(evt) {
// check if listeners are registered, if yes use custom backbutton event
// NOTE: On Windows Phone 8.1 backbutton handlers have to throw an exception in order to exit the app
if (backButtonChannel.numHandlers >= 1) {
try {
cordova.fireDocumentEvent('backbutton', evt, true);
evt.handled = true; // Windows Mobile requires handled to be set as well;
return true;
}
catch (e) {
return false;
}
}
// if not listeners are active, use default implementation (backwards compatibility)
else {
return defaultBackButtonHandler.apply(app, arguments);
}
};
// Only load this code if we're running on Win10 in a non-emulated app frame, otherwise crash \o/
if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) { // Windows 10 UWP (PC/Tablet/Phone)
var navigationManager = Windows.UI.Core.SystemNavigationManager.getForCurrentView();
// Inject a listener for the backbutton on the document.
backButtonChannel.onHasSubscribersChange = function () {
// If we just attached the first handler or detached the last handler,
// let native know we need to override the back button.
navigationManager.appViewBackButtonVisibility = (this.numHandlers > 0) ?
Windows.UI.Core.AppViewBackButtonVisibility.visible :
Windows.UI.Core.AppViewBackButtonVisibility.collapsed;
};
navigationManager.addEventListener("backrequested", backRequestedHandler, false);
} else { // Windows 8.1 Phone
// inject new back button handler
app.onbackclick = backRequestedHandler;
}
}
// Platform: windows // Platform: windows
// fc4db9145934bd0053161cbf9ffc0caf83b770c6 // 7703d38498920bdcfadd574e475553a26fc490e5
/* /*
Licensed to the Apache Software Foundation (ASF) under one Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file or more contributor license agreements. See the NOTICE file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
under the License. under the License.
*/ */
;(function() { ;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '3.8.0'; var PLATFORM_VERSION_BUILD_LABEL = '4.2.0';
// file: src/scripts/require.js // file: src/scripts/require.js
/*jshint -W079 */ /*jshint -W079 */
...@@ -101,10 +101,17 @@ if (typeof module === "object" && typeof require === "function") { ...@@ -101,10 +101,17 @@ if (typeof module === "object" && typeof require === "function") {
// file: src/cordova.js // file: src/cordova.js
define("cordova", function(require, exports, module) { define("cordova", function(require, exports, module) {
// Workaround for Windows 10 in hosted environment case
// http://www.w3.org/html/wg/drafts/html/master/browsers.html#named-access-on-the-window-object
if (window.cordova && !(window.cordova instanceof HTMLElement)) {
throw new Error("cordova already defined");
}
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
/** /**
* Intercept calls to addEventListener + removeEventListener and handle deviceready, * Intercept calls to addEventListener + removeEventListener and handle deviceready,
* resume, and pause events. * resume, and pause events.
...@@ -326,7 +333,6 @@ module.exports = cordova; ...@@ -326,7 +333,6 @@ module.exports = cordova;
// file: src/common/argscheck.js // file: src/common/argscheck.js
define("cordova/argscheck", function(require, exports, module) { define("cordova/argscheck", function(require, exports, module) {
var exec = require('cordova/exec');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var moduleExports = module.exports; var moduleExports = module.exports;
...@@ -811,7 +817,7 @@ module.exports = channel; ...@@ -811,7 +817,7 @@ module.exports = channel;
}); });
// file: src/windows/exec.js // file: c:/cordova/cordova-windows/cordova-js-src/exec.js
define("cordova/exec", function(require, exports, module) { define("cordova/exec", function(require, exports, module) {
/*jslint sloppy:true, plusplus:true*/ /*jslint sloppy:true, plusplus:true*/
...@@ -855,18 +861,40 @@ module.exports = function (success, fail, service, action, args) { ...@@ -855,18 +861,40 @@ module.exports = function (success, fail, service, action, args) {
// CB-5806 [Windows8] Add keepCallback support to proxy // CB-5806 [Windows8] Add keepCallback support to proxy
onSuccess = function (result, callbackOptions) { onSuccess = function (result, callbackOptions) {
callbackOptions = callbackOptions || {}; callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackSuccess(callbackOptions.callbackId || callbackId, cordova.callbackSuccess(callbackOptions.callbackId || callbackId,
{ {
status: callbackOptions.status || cordova.callbackStatus.OK, status: callbackStatus,
message: result, message: result,
keepCallback: callbackOptions.keepCallback || false keepCallback: callbackOptions.keepCallback || false
}); });
}; };
onError = function (err, callbackOptions) { onError = function (err, callbackOptions) {
callbackOptions = callbackOptions || {}; callbackOptions = callbackOptions || {};
var callbackStatus;
// covering both undefined and null.
// strict null comparison was causing callbackStatus to be undefined
// and then no callback was called because of the check in cordova.callbackFromNative
// see CB-8996 Mobilespec app hang on windows
if (callbackOptions.status !== undefined && callbackOptions.status !== null) {
callbackStatus = callbackOptions.status;
}
else {
callbackStatus = cordova.callbackStatus.OK;
}
cordova.callbackError(callbackOptions.callbackId || callbackId, cordova.callbackError(callbackOptions.callbackId || callbackId,
{ {
status: callbackOptions.status || cordova.callbackStatus.ERROR, status: callbackStatus,
message: err, message: err,
keepCallback: callbackOptions.keepCallback || false keepCallback: callbackOptions.keepCallback || false
}); });
...@@ -882,6 +910,7 @@ module.exports = function (success, fail, service, action, args) { ...@@ -882,6 +910,7 @@ module.exports = function (success, fail, service, action, args) {
} }
} }
}; };
}); });
// file: src/common/exec/proxy.js // file: src/common/exec/proxy.js
...@@ -985,6 +1014,7 @@ if (!window.console.warn) { ...@@ -985,6 +1014,7 @@ if (!window.console.warn) {
// Register pause, resume and deviceready channels as events on document. // Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onActivated = cordova.addDocumentEventHandler('activated');
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
// Listen for DOMContentLoaded and notify our channel subscribers. // Listen for DOMContentLoaded and notify our channel subscribers.
...@@ -1046,10 +1076,12 @@ define("cordova/init_b", function(require, exports, module) { ...@@ -1046,10 +1076,12 @@ define("cordova/init_b", function(require, exports, module) {
var channel = require('cordova/channel'); var channel = require('cordova/channel');
var cordova = require('cordova'); var cordova = require('cordova');
var modulemapper = require('cordova/modulemapper');
var platform = require('cordova/platform'); var platform = require('cordova/platform');
var pluginloader = require('cordova/pluginloader');
var utils = require('cordova/utils'); var utils = require('cordova/utils');
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady]; var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
// setting exec // setting exec
cordova.exec = require('cordova/exec'); cordova.exec = require('cordova/exec');
...@@ -1112,6 +1144,7 @@ if (!window.console.warn) { ...@@ -1112,6 +1144,7 @@ if (!window.console.warn) {
// Register pause, resume and deviceready channels as events on document. // Register pause, resume and deviceready channels as events on document.
channel.onPause = cordova.addDocumentEventHandler('pause'); channel.onPause = cordova.addDocumentEventHandler('pause');
channel.onResume = cordova.addDocumentEventHandler('resume'); channel.onResume = cordova.addDocumentEventHandler('resume');
channel.onActivated = cordova.addDocumentEventHandler('activated');
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready'); channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
// Listen for DOMContentLoaded and notify our channel subscribers. // Listen for DOMContentLoaded and notify our channel subscribers.
...@@ -1133,10 +1166,19 @@ if (window._nativeReady) { ...@@ -1133,10 +1166,19 @@ if (window._nativeReady) {
// Call the platform-specific initialization. // Call the platform-specific initialization.
platform.bootstrap && platform.bootstrap(); platform.bootstrap && platform.bootstrap();
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
// The delay allows the attached modules to be defined before the plugin loader looks for them.
setTimeout(function() {
pluginloader.load(function() {
channel.onPluginsReady.fire();
});
}, 0);
/** /**
* Create all cordova objects once native side is ready. * Create all cordova objects once native side is ready.
*/ */
channel.join(function() { channel.join(function() {
modulemapper.mapModules(window);
platform.initialize && platform.initialize(); platform.initialize && platform.initialize();
...@@ -1255,7 +1297,104 @@ exports.reset(); ...@@ -1255,7 +1297,104 @@ exports.reset();
}); });
// file: src/windows/platform.js // file: src/common/modulemapper_b.js
define("cordova/modulemapper_b", function(require, exports, module) {
var builder = require('cordova/builder'),
symbolList = [],
deprecationMap;
exports.reset = function() {
symbolList = [];
deprecationMap = {};
};
function addEntry(strategy, moduleName, symbolPath, opt_deprecationMessage) {
symbolList.push(strategy, moduleName, symbolPath);
if (opt_deprecationMessage) {
deprecationMap[symbolPath] = opt_deprecationMessage;
}
}
// Note: Android 2.3 does have Function.bind().
exports.clobbers = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
};
exports.merges = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
};
exports.defaults = function(moduleName, symbolPath, opt_deprecationMessage) {
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
};
exports.runs = function(moduleName) {
addEntry('r', moduleName, null);
};
function prepareNamespace(symbolPath, context) {
if (!symbolPath) {
return context;
}
var parts = symbolPath.split('.');
var cur = context;
for (var i = 0, part; part = parts[i]; ++i) {
cur = cur[part] = cur[part] || {};
}
return cur;
}
exports.mapModules = function(context) {
var origSymbols = {};
context.CDV_origSymbols = origSymbols;
for (var i = 0, len = symbolList.length; i < len; i += 3) {
var strategy = symbolList[i];
var moduleName = symbolList[i + 1];
var module = require(moduleName);
// <runs/>
if (strategy == 'r') {
continue;
}
var symbolPath = symbolList[i + 2];
var lastDot = symbolPath.lastIndexOf('.');
var namespace = symbolPath.substr(0, lastDot);
var lastName = symbolPath.substr(lastDot + 1);
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
var parentObj = prepareNamespace(namespace, context);
var target = parentObj[lastName];
if (strategy == 'm' && target) {
builder.recursiveMerge(target, module);
} else if ((strategy == 'd' && !target) || (strategy != 'd')) {
if (!(symbolPath in origSymbols)) {
origSymbols[symbolPath] = target;
}
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
}
}
};
exports.getOriginalSymbol = function(context, symbolPath) {
var origSymbols = context.CDV_origSymbols;
if (origSymbols && (symbolPath in origSymbols)) {
return origSymbols[symbolPath];
}
var parts = symbolPath.split('.');
var obj = context;
for (var i = 0; i < parts.length; ++i) {
obj = obj && obj[parts[i]];
}
return obj;
};
exports.reset();
});
// file: c:/cordova/cordova-windows/cordova-js-src/platform.js
define("cordova/platform", function(require, exports, module) { define("cordova/platform", function(require, exports, module) {
module.exports = { module.exports = {
...@@ -1266,9 +1405,16 @@ module.exports = { ...@@ -1266,9 +1405,16 @@ module.exports = {
var cordova = require('cordova'), var cordova = require('cordova'),
exec = require('cordova/exec'), exec = require('cordova/exec'),
channel = cordova.require('cordova/channel'), channel = cordova.require('cordova/channel'),
platform = require('cordova/platform'),
modulemapper = require('cordova/modulemapper'); modulemapper = require('cordova/modulemapper');
modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy'); modulemapper.clobbers('cordova/exec/proxy', 'cordova.commandProxy');
// we will make sure we get this channel
// TODO: remove this once other platforms catch up.
if(!channel.onActivated) {
channel.onActivated = cordova.addDocumentEventHandler('activated');
}
channel.onNativeReady.fire(); channel.onNativeReady.fire();
var onWinJSReady = function () { var onWinJSReady = function () {
...@@ -1281,16 +1427,32 @@ module.exports = { ...@@ -1281,16 +1427,32 @@ module.exports = {
cordova.fireDocumentEvent('resume',null,true); cordova.fireDocumentEvent('resume',null,true);
}; };
// activation args are available via the activated event
// OR cordova.require('cordova/platform').activationContext
// activationContext:{type: actType, args: args};
var activationHandler = function (e) {
var args = e.detail.arguments;
var actType = e.detail.type;
platform.activationContext = { type: actType, args: args };
cordova.fireDocumentEvent('activated', platform.activationContext, true);
};
app.addEventListener("checkpoint", checkpointHandler); app.addEventListener("checkpoint", checkpointHandler);
app.addEventListener("activated", activationHandler, false);
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false); Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);
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);
injectBackButtonHandler();
app.start(); app.start();
}; };
if (!window.WinJS) { if (!window.WinJS) {
var scriptElem = document.createElement("script"); var scriptElem = document.createElement("script");
if (navigator.appVersion.indexOf("Windows Phone 8.1;") !== -1) { if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) {
// Windows 10 UWP
scriptElem.src = '/www/WinJS/js/base.js';
} else if (navigator.appVersion.indexOf("Windows Phone 8.1;") !== -1) {
// windows phone 8.1 + Mobile IE 11 // windows phone 8.1 + Mobile IE 11
scriptElem.src = "//Microsoft.Phone.WinJS.2.1/js/base.js"; scriptElem.src = "//Microsoft.Phone.WinJS.2.1/js/base.js";
} else if (navigator.appVersion.indexOf("MSAppHost/2.0;") !== -1) { } else if (navigator.appVersion.indexOf("MSAppHost/2.0;") !== -1) {
...@@ -1309,6 +1471,55 @@ module.exports = { ...@@ -1309,6 +1471,55 @@ module.exports = {
} }
}; };
function injectBackButtonHandler() {
var app = WinJS.Application;
// create document event handler for backbutton
var backButtonChannel = cordova.addDocumentEventHandler('backbutton');
// preserve reference to original backclick implementation
// `false` as a result will trigger system default behaviour
var defaultBackButtonHandler = app.onbackclick || function () { return false; };
var backRequestedHandler = function backRequestedHandler(evt) {
// check if listeners are registered, if yes use custom backbutton event
// NOTE: On Windows Phone 8.1 backbutton handlers have to throw an exception in order to exit the app
if (backButtonChannel.numHandlers >= 1) {
try {
cordova.fireDocumentEvent('backbutton', evt, true);
evt.handled = true; // Windows Mobile requires handled to be set as well;
return true;
}
catch (e) {
return false;
}
}
// if not listeners are active, use default implementation (backwards compatibility)
else {
return defaultBackButtonHandler.apply(app, arguments);
}
};
// Only load this code if we're running on Win10 in a non-emulated app frame, otherwise crash \o/
if (navigator.appVersion.indexOf('MSAppHost/3.0') !== -1) { // Windows 10 UWP (PC/Tablet/Phone)
var navigationManager = Windows.UI.Core.SystemNavigationManager.getForCurrentView();
// Inject a listener for the backbutton on the document.
backButtonChannel.onHasSubscribersChange = function () {
// If we just attached the first handler or detached the last handler,
// let native know we need to override the back button.
navigationManager.appViewBackButtonVisibility = (this.numHandlers > 0) ?
Windows.UI.Core.AppViewBackButtonVisibility.visible :
Windows.UI.Core.AppViewBackButtonVisibility.collapsed;
};
navigationManager.addEventListener("backrequested", backRequestedHandler, false);
} else { // Windows 8.1 Phone
// inject new back button handler
app.onbackclick = backRequestedHandler;
}
}
}); });
// file: src/common/pluginloader.js // file: src/common/pluginloader.js
...@@ -1423,6 +1634,54 @@ exports.load = function(callback) { ...@@ -1423,6 +1634,54 @@ exports.load = function(callback) {
}); });
// file: src/common/pluginloader_b.js
define("cordova/pluginloader_b", function(require, exports, module) {
var modulemapper = require('cordova/modulemapper');
// Handler for the cordova_plugins.js content.
// See plugman's plugin_loader.js for the details of this object.
function handlePluginsObject(moduleList) {
// if moduleList is not defined or empty, we've nothing to do
if (!moduleList || !moduleList.length) {
return;
}
// Loop through all the modules and then through their clobbers and merges.
for (var i = 0, module; module = moduleList[i]; i++) {
if (module.clobbers && module.clobbers.length) {
for (var j = 0; j < module.clobbers.length; j++) {
modulemapper.clobbers(module.id, module.clobbers[j]);
}
}
if (module.merges && module.merges.length) {
for (var k = 0; k < module.merges.length; k++) {
modulemapper.merges(module.id, module.merges[k]);
}
}
// Finally, if runs is truthy we want to simply require() the module.
if (module.runs) {
modulemapper.runs(module.id);
}
}
}
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
// but the method accepts callback to be compatible with non-browserify flow.
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
// no plugins to load, or they are all done.
exports.load = function(callback) {
var moduleList = require("cordova/plugin_list");
handlePluginsObject(moduleList);
callback();
};
});
// file: src/common/urlutil.js // file: src/common/urlutil.js
define("cordova/urlutil", function(require, exports, module) { define("cordova/urlutil", function(require, exports, module) {
...@@ -1502,15 +1761,14 @@ utils.typeName = function(val) { ...@@ -1502,15 +1761,14 @@ utils.typeName = function(val) {
/** /**
* Returns an indication of whether the argument is an array or not * Returns an indication of whether the argument is an array or not
*/ */
utils.isArray = function(a) { utils.isArray = Array.isArray ||
return utils.typeName(a) == 'Array'; function(a) {return utils.typeName(a) == 'Array';};
};
/** /**
* Returns an indication of whether the argument is a Date or not * Returns an indication of whether the argument is a Date or not
*/ */
utils.isDate = function(d) { utils.isDate = function(d) {
return utils.typeName(d) == 'Date'; return (d instanceof Date);
}; };
/** /**
...@@ -1544,17 +1802,25 @@ utils.clone = function(obj) { ...@@ -1544,17 +1802,25 @@ utils.clone = function(obj) {
* Returns a wrapped version of the function * Returns a wrapped version of the function
*/ */
utils.close = function(context, func, params) { utils.close = function(context, func, params) {
if (typeof params == 'undefined') {
return function() { return function() {
return func.apply(context, arguments); var args = params || arguments;
return func.apply(context, args);
}; };
} else {
return function() {
return func.apply(context, params);
};
}
}; };
//------------------------------------------------------------------------------
function UUIDcreatePart(length) {
var uuidpart = "";
for (var i=0; i<length; i++) {
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
if (uuidchar.length == 1) {
uuidchar = "0" + uuidchar;
}
uuidpart += uuidchar;
}
return uuidpart;
}
/** /**
* Create a UUID * Create a UUID
*/ */
...@@ -1566,6 +1832,7 @@ utils.createUUID = function() { ...@@ -1566,6 +1832,7 @@ utils.createUUID = function() {
UUIDcreatePart(6); UUIDcreatePart(6);
}; };
/** /**
* Extends a child object from a parent object using classical inheritance * Extends a child object from a parent object using classical inheritance
* pattern. * pattern.
...@@ -1575,6 +1842,7 @@ utils.extend = (function() { ...@@ -1575,6 +1842,7 @@ utils.extend = (function() {
var F = function() {}; var F = function() {};
// extend Child from Parent // extend Child from Parent
return function(Child, Parent) { return function(Child, Parent) {
F.prototype = Parent.prototype; F.prototype = Parent.prototype;
Child.prototype = new F(); Child.prototype = new F();
Child.__super__ = Parent.prototype; Child.__super__ = Parent.prototype;
...@@ -1594,18 +1862,7 @@ utils.alert = function(msg) { ...@@ -1594,18 +1862,7 @@ utils.alert = function(msg) {
}; };
//------------------------------------------------------------------------------
function UUIDcreatePart(length) {
var uuidpart = "";
for (var i=0; i<length; i++) {
var uuidchar = parseInt((Math.random() * 256), 10).toString(16);
if (uuidchar.length == 1) {
uuidchar = "0" + uuidchar;
}
uuidpart += uuidchar;
}
return uuidpart;
}
}); });
......
cordova.define('cordova/plugin_list', function(require, exports, module) { cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [ module.exports = [
{ {
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/cordova-plugin-device/www/device.js", "file": "plugins/cordova-plugin-device/www/device.js",
"id": "cordova-plugin-device.device", "id": "cordova-plugin-device.device",
"pluginId": "cordova-plugin-device", "pluginId": "cordova-plugin-device",
...@@ -30,6 +17,19 @@ module.exports = [ ...@@ -30,6 +17,19 @@ module.exports = [
] ]
}, },
{ {
"file": "plugins/cordova-plugin-x-toast/www/Toast.js",
"id": "cordova-plugin-x-toast.Toast",
"pluginId": "cordova-plugin-x-toast",
"clobbers": [
"window.plugins.toast"
]
},
{
"file": "plugins/cordova-plugin-x-toast/test/tests.js",
"id": "cordova-plugin-x-toast.tests",
"pluginId": "cordova-plugin-x-toast"
},
{
"file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js", "file": "plugins/de.appplant.cordova.plugin.local-notification/www/local-notification.js",
"id": "de.appplant.cordova.plugin.local-notification.LocalNotification", "id": "de.appplant.cordova.plugin.local-notification.LocalNotification",
"pluginId": "de.appplant.cordova.plugin.local-notification", "pluginId": "de.appplant.cordova.plugin.local-notification",
...@@ -84,8 +84,8 @@ module.exports = [ ...@@ -84,8 +84,8 @@ module.exports = [
module.exports.metadata = module.exports.metadata =
// TOP OF METADATA // TOP OF METADATA
{ {
"cordova-plugin-x-toast": "2.3.1",
"cordova-plugin-device": "1.1.0", "cordova-plugin-device": "1.1.0",
"cordova-plugin-x-toast": "2.3.1",
"cordova-plugin-registerusernotificationsettings": "1.0.2", "cordova-plugin-registerusernotificationsettings": "1.0.2",
"de.appplant.cordova.plugin.local-notification": "0.8.3-dev" "de.appplant.cordova.plugin.local-notification": "0.8.3-dev"
} }
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
<!-- update --> <!-- update -->
<h2 class="section">Update</h2> <h2 class="section">Update</h2>
<div class="container"> <div class="container">
<div onclick="update()">Title<br /><span>update(1)</span></div> <div onclick="update()">Text<br /><span>update(1)</span></div>
<div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div> <div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div>
</div> </div>
...@@ -188,7 +188,8 @@ ...@@ -188,7 +188,8 @@
cordova.plugins.notification.local.schedule({ cordova.plugins.notification.local.schedule({
id: 1, id: 1,
text: 'Test Message 1', text: 'Test Message 1',
icon: 'http://www.optimizeordie.de/wp-content/plugins/social-media-widget/images/default/64/googleplus.png', icon: 'http://3.bp.blogspot.com/-Qdsy-GpempY/UU_BN9LTqSI/AAAAAAAAAMA/LkwLW2yNBJ4/s1600/supersu.png',
smallIcon: 'res://cordova',
sound: null, sound: null,
data: { test: id } data: { test: id }
}); });
...@@ -197,13 +198,18 @@ ...@@ -197,13 +198,18 @@
scheduleMultiple = function () { scheduleMultiple = function () {
cordova.plugins.notification.local.schedule([{ cordova.plugins.notification.local.schedule([{
id: 1, id: 1,
text: 'Multi Message 1' text: 'Multi Message 1',
icon: 'res://cordova'
}, { }, {
id: 2, id: 2,
text: 'Multi Message 2' text: 'Multi Message 2',
icon: 'res://icon',
smallIcon: 'ic_media_play'
}, { }, {
id: 3, id: 3,
text: 'Multi Message 3' text: 'Multi Message 3',
icon: 'res://icon',
smallIcon: 'ic_media_pause'
}]); }]);
}; };
...@@ -230,7 +236,9 @@ ...@@ -230,7 +236,9 @@
id: 1, id: 1,
text: 'Scheduled every minute', text: 'Scheduled every minute',
every: 'minute', every: 'minute',
sound: sound sound: sound,
icon: 'res://icon',
smallIcon: 'res://ic_popup_sync'
}); });
}; };
</script> </script>
...@@ -241,6 +249,8 @@ ...@@ -241,6 +249,8 @@
cordova.plugins.notification.local.update({ cordova.plugins.notification.local.update({
id: 1, id: 1,
text: 'Updated Message 1', text: 'Updated Message 1',
icon: 'res://icon',
color: 'FF0000',
json: { updated: true } json: { updated: true }
}); });
}; };
......
...@@ -103,9 +103,7 @@ proxy.core = { ...@@ -103,9 +103,7 @@ proxy.core = {
toast.id = options.id; toast.id = options.id;
toast.tag = 'Toast' + toast.id; toast.tag = 'Toast' + toast.id;
Notifications.ToastNotificationManager this.getToastNotifier().addToSchedule(toast);
.createToastNotifier()
.addToSchedule(toast);
}, },
/** /**
...@@ -326,9 +324,12 @@ proxy.core = { ...@@ -326,9 +324,12 @@ proxy.core = {
ids = []; ids = [];
for (var i = 0; i < toasts.length; i++) { for (var i = 0; i < toasts.length; i++) {
var toast = toasts[i]; var toast = toasts[i],
toastId = this.getToastId(toast);
ids.push(this.getToastId(toast)); if (ids.indexOf(toastId) == -1) {
ids.push(toastId);
}
} }
return ids; return ids;
......
...@@ -412,8 +412,8 @@ channel.onCordovaReady.subscribe(function () { ...@@ -412,8 +412,8 @@ channel.onCordovaReady.subscribe(function () {
}); });
// Handle onclick event // Handle onclick event
WinJS.Application.addEventListener('activated', function (args) { document.addEventListener('activated', function (e) {
var id = args.detail.arguments, var id = e.args,
notification = exports.getAll([id])[0]; notification = exports.getAll([id])[0];
if (!notification) if (!notification)
......
...@@ -441,6 +441,9 @@ exports.registerPermission = function (callback, scope) { ...@@ -441,6 +441,9 @@ exports.registerPermission = function (callback, scope) {
*/ */
exports.on = function (event, callback, scope) { exports.on = function (event, callback, scope) {
if (typeof callback !== "function")
return;
if (!this._listener[event]) { if (!this._listener[event]) {
this._listener[event] = []; this._listener[event] = [];
} }
......
...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () { ...@@ -60,11 +60,12 @@ exports.applyPlatformSpecificOptions = function () {
switch (device.platform) { switch (device.platform) {
case 'Android': case 'Android':
defaults.icon = 'res://icon'; defaults.icon = 'res://ic_popup_reminder';
defaults.smallIcon = 'res://ic_popup_reminder'; defaults.smallIcon = undefined;
defaults.ongoing = false; defaults.ongoing = false;
defaults.autoClear = true; defaults.autoClear = true;
defaults.led = 'FFFFFF'; defaults.led = 'FF0000';
defaults.color = undefined;
break; break;
} }
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
"files": {} "files": {}
}, },
"installed_plugins": { "installed_plugins": {
"cordova-plugin-device": {
"PACKAGE_NAME": "NotificationExample"
},
"cordova-plugin-x-toast": { "cordova-plugin-x-toast": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
}, },
...@@ -15,9 +18,6 @@ ...@@ -15,9 +18,6 @@
} }
}, },
"dependent_plugins": { "dependent_plugins": {
"cordova-plugin-device": {
"PACKAGE_NAME": "NotificationExample"
},
"cordova-plugin-registerusernotificationsettings": { "cordova-plugin-registerusernotificationsettings": {
"PACKAGE_NAME": "NotificationExample" "PACKAGE_NAME": "NotificationExample"
} }
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
<!-- update --> <!-- update -->
<h2 class="section">Update</h2> <h2 class="section">Update</h2>
<div class="container"> <div class="container">
<div onclick="update()">Title<br /><span>update(1)</span></div> <div onclick="update()">Text<br /><span>update(1)</span></div>
<div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div> <div onclick="updateInterval()">Interval<br /><span>update(1, every:minute)</span></div>
</div> </div>
...@@ -249,6 +249,8 @@ ...@@ -249,6 +249,8 @@
cordova.plugins.notification.local.update({ cordova.plugins.notification.local.update({
id: 1, id: 1,
text: 'Updated Message 1', text: 'Updated Message 1',
icon: 'res://icon',
color: 'FF0000',
json: { updated: true } json: { updated: true }
}); });
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment