Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

implementation for Windows8

  • Loading branch information...
commit fcba9c443bc96b5ca58ca308dca968e0ec6b52d3 1 parent 462d649
@sgrebnov authored
View
29 plugin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
+xmlns:android="http://schemas.android.com/apk/res/android"
+ id="msopentech.azure.NotificationHub"
+ version="0.0.1">
+ <name>Azure Notification Hub</name>
+
+ <description>Cordova Azure Notification Hub Plugin</description>
+ <license>Apache 2.0</license>
+ <keywords>cordova, azure, push, notifications, hub</keywords>
+ <repo>TODO</repo>
+ <issue>TODO</issue>
+
+ <js-module src="www/Promise.js" name="Promise"/>
+
+ <js-module src="www/NotificationHub.js" name="NotificationHub">
+ <clobbers target="WindowsAzure.Messaging.NotificationHub" />
+ </js-module>
+
+ <!-- windows8 -->
+ <platform name="windows8">
+ <framework src="src/windows8/Microsoft.WindowsAzure.Messaging.Managed.dll" custom="true"/>
+ <framework src="src/windows8/NotificationHubRuntimeProxy.winmd" custom="true"/>
+ <js-module src="src/windows8/NotificationHubProxy.js" name="NotificationHubProxy" >
+ <clobbers target="" />
+ </js-module>
+ </platform>
+</plugin>
View
BIN  src/windows8/Microsoft.WindowsAzure.Messaging.Managed.dll
Binary file not shown
View
63 src/windows8/NotificationHubProxy.js
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 = {
+ registerApplication: function (success, fail, args) {
+ try {
+ var notificationHubPath = args[0];
+ var connectionString = args[1];
+ var pushNotificationCallback = window[args[2]];
+
+ var notificationChannel = null;
+
+ Windows.Networking.PushNotifications.PushNotificationChannelManager.createPushNotificationChannelForApplicationAsync().then(function (channel) {
+ notificationChannel = channel;
+ return (new NotificationHubRuntimeProxy.HubApi()).registerNativeAsync(notificationHubPath, connectionString, channel.uri);
+ }).done(function (result) {
+ var registration = {};
+ registration.registrationId = result;
+ registration.channelUri = notificationChannel.uri;
+ registration.notificationHubPath = notificationHubPath;
+
+ success(registration);
+ }, fail);
+
+ } catch (ex) {
+ fail(ex);
+ }
+ },
+
+ unregisterApplication: function (success, fail, args) {
+ try {
+ var notificationHubPath = args[0];
+ var connectionString = args[1];
+
+ (new NotificationHubRuntimeProxy.HubApi()).unregisterNativeAsync(notificationHubPath, connectionString);
+
+ success();
+
+ } catch (ex) {
+ fail(ex);
+ }
+ }
+
+}
+
+require("cordova/windows8/commandProxy").add("NotificationHub", module.exports);
View
BIN  src/windows8/NotificationHubRuntimeProxy.winmd
Binary file not shown
View
46 src/windows8/NotificationHubRuntimeProxy/HubApi.cs
@@ -0,0 +1,46 @@
+/*
+* Licensed under the Apache License, Version 2.0 (the "License")
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Copyright © Microsoft Open Technologies, Inc.
+* All Rights Reserved
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.WindowsAzure;
+using Windows.Networking.PushNotifications;
+using Windows.Foundation;
+using System.Diagnostics;
+
+namespace NotificationHubRuntimeProxy
+{
+ public sealed class HubApi
+ {
+ public IAsyncOperation<string> RegisterNativeAsync(string notificationHubPath, string connectionString, string channelUri)
+ {
+ return this.RegisterNativeAsyncInternal(notificationHubPath, connectionString, channelUri).AsAsyncOperation();
+ }
+
+ public async void UnregisterNativeAsync(string notificationHubPath, string connectionString)
+ {
+ var hub = new Microsoft.WindowsAzure.Messaging.NotificationHub(notificationHubPath, connectionString);
+
+ await hub.UnregisterNativeAsync();
+ }
+
+ private async Task<string> RegisterNativeAsyncInternal(string notificationHubPath, string connectionString, string channelUri)
+ {
+ // Create the notification hub
+ var hub = new Microsoft.WindowsAzure.Messaging.NotificationHub(notificationHubPath, connectionString);
+
+ // Register with the Notification Hub, passing the push channel uri and the string array of tags
+ var registration = await hub.RegisterNativeAsync(channelUri);
+
+ return registration.RegistrationId;
+ }
+ }
+}
View
129 src/windows8/NotificationHubRuntimeProxy/NotificationHubRuntimeProxy.csproj
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{34833D61-CFE8-4B23-A408-96269C644202}</ProjectGuid>
+ <OutputType>winmdobj</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>NotificationHubRuntimeProxy</RootNamespace>
+ <AssemblyName>NotificationHubRuntimeProxy</AssemblyName>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <TargetPlatformVersion>8.1</TargetPlatformVersion>
+ <MinimumVisualStudioVersion>12</MinimumVisualStudioVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\windows8\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\ARM\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>full</DebugType>
+ <PlatformTarget>ARM</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
+ <OutputPath>bin\ARM\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <Optimize>true</Optimize>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>ARM</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x64\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ <OutputPath>bin\x64\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <Optimize>true</Optimize>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x64</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\x86\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>full</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+ <OutputPath>bin\x86\Release\</OutputPath>
+ <DefineConstants>TRACE;NETFX_CORE</DefineConstants>
+ <Optimize>true</Optimize>
+ <NoWarn>;2008</NoWarn>
+ <DebugType>pdbonly</DebugType>
+ <PlatformTarget>x86</PlatformTarget>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ <ErrorReport>prompt</ErrorReport>
+ <Prefer32Bit>true</Prefer32Bit>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="HubApi.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.WindowsAzure.Messaging.Managed">
+ <HintPath>..\windows8\packages\WindowsAzure.Messaging.Managed.0.1.7.6\lib\netcore45\Microsoft.WindowsAzure.Messaging.Managed.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '12.0' ">
+ <VisualStudioVersion>12.0</VisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
+ <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
29 src/windows8/NotificationHubRuntimeProxy/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NotificationHubRuntimeProxy")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NotificationHubRuntimeProxy")]
+[assembly: AssemblyCopyright("Copyright © 2014")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
View
4 src/windows8/NotificationHubRuntimeProxy/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="WindowsAzure.Messaging.Managed" version="0.1.7.6" targetFramework="win81" />
+</packages>
View
115 test/css/index.css
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+* {
+ -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
+}
+
+body {
+ -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
+ -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
+ -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
+ background-color:#E4E4E4;
+ background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
+ background-image:-webkit-gradient(
+ linear,
+ left top,
+ left bottom,
+ color-stop(0, #A7A7A7),
+ color-stop(0.51, #E4E4E4)
+ );
+ background-attachment:fixed;
+ font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
+ font-size:12px;
+ height:100%;
+ margin:0px;
+ padding:0px;
+ text-transform:uppercase;
+ width:100%;
+}
+
+/* Portrait layout (default) */
+.app {
+ background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
+ position:absolute; /* position in the center of the screen */
+ left:50%;
+ top:50%;
+ height:50px; /* text area height */
+ width:225px; /* text area width */
+ text-align:center;
+ padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
+ margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
+ /* offset horizontal: half of text area width */
+}
+
+/* Landscape layout (with min-width) */
+@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
+ .app {
+ background-position:left center;
+ padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
+ margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
+ /* offset horizontal: half of image width and text area width */
+ }
+}
+
+h1 {
+ font-size:24px;
+ font-weight:normal;
+ margin:0px;
+ overflow:visible;
+ padding:0px;
+ text-align:center;
+}
+
+.event {
+ border-radius:4px;
+ -webkit-border-radius:4px;
+ color:#FFFFFF;
+ font-size:12px;
+ margin:0px 30px;
+ padding:2px 0px;
+}
+
+.event.listening {
+ background-color:#333333;
+ display:block;
+}
+
+.event.received {
+ background-color:#4B946A;
+ display:none;
+}
+
+@keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+@-webkit-keyframes fade {
+ from { opacity: 1.0; }
+ 50% { opacity: 0.4; }
+ to { opacity: 1.0; }
+}
+
+.blink {
+ animation:fade 3000ms infinite;
+ -webkit-animation:fade 3000ms infinite;
+}
View
BIN  test/img/logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
43 test/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <meta name="format-detection" content="telephone=no" />
+ <!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
+ <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
+ <link rel="stylesheet" type="text/css" href="css/index.css" />
+ <title>Hello World</title>
+ </head>
+ <body>
+ <div class="app">
+ <h1>Apache Cordova</h1>
+ <div id="deviceready" class="blink">
+ <p class="event listening">Connecting to Device</p>
+ <p class="event received">Device is Ready</p>
+ </div>
+ </div>
+ <script type="text/javascript" src="cordova.js"></script>
+ <script type="text/javascript" src="js/index.js"></script>
+ <script type="text/javascript">
+ app.initialize();
+ </script>
+ </body>
+</html>
View
70 test/js/index.js
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+var app = {
+ // Application Constructor
+ initialize: function() {
+ this.bindEvents();
+ },
+ // Bind Event Listeners
+ //
+ // Bind any events that are required on startup. Common events are:
+ // 'load', 'deviceready', 'offline', and 'online'.
+ bindEvents: function() {
+ document.addEventListener('deviceready', this.onDeviceReady, false);
+ },
+ // deviceready Event Handler
+ //
+ // The scope of 'this' is the event. In order to call the 'receivedEvent'
+ // function, we must explicity call 'app.receivedEvent(...);'
+ onDeviceReady: function() {
+ app.receivedEvent('deviceready');
+
+ var connectionString = "Endpoint=sb://[service bus name space].servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=[notification hub full key]",
+ notificationHubPath = "[notification hub name]";
+
+ // TODO: remove
+ connectionString = "Endpoint=sb://msopentech.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=vWgSeiB5WI3lT6ymUsQh5/upLZa0PHUYB+Hmya/RT3k=";
+ notificationHubPath = "test";
+
+ var hub = new WindowsAzure.Messaging.NotificationHub(notificationHubPath, connectionString);
+
+ hub.registerApplicationAsync().then(
+ function (result) {
+ console.log("Registration successful: " + result.registrationId);
+ },
+ function (error) {
+ console.log("Registration failed: " + error);
+ });
+
+ hub.onPushNotificationReceived = function (msg) {
+ console.log("onPushNotificationReceived: " + msg);
+ };
+ },
+ // Update DOM on a Received Event
+ receivedEvent: function(id) {
+ var parentElement = document.getElementById(id);
+ var listeningElement = parentElement.querySelector('.listening');
+ var receivedElement = parentElement.querySelector('.received');
+
+ listeningElement.setAttribute('style', 'display:none;');
+ receivedElement.setAttribute('style', 'display:block;');
+
+ console.log('Received Event: ' + id);
+ }
+};
View
85 www/NotificationHub.js
@@ -0,0 +1,85 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var exec = require('cordova/exec');
+var Promise = require('./Promise');
+
+// http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.messaging.notificationhub.notificationhub.aspx
+var NotificationHub = function (notificationHubPath, connectionString) {
+ if (typeof notificationHubPath == 'undefined') {
+ throw new Error('Please specify notificationHubPath');
+ }
+
+ if (typeof connectionString == 'undefined') {
+ throw new Error('Please specify connectionString');
+ }
+ this.notificationHubPath = notificationHubPath;
+ this.connectionString = connectionString;
+
+ this.onPushNotificationReceived = null;
+};
+
+// tags - optional
+// http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.messaging.notificationhub.registerasync.aspx
+NotificationHub.prototype.registerApplicationAsync = function (tags) {
+ var deferral = new Promise.Deferral(),
+
+ successCallback = function (result) {
+ deferral.resolve(result);
+ },
+
+ errorCallback = function (err) {
+ deferral.reject(err);
+ };
+
+ var me = this,
+ globalNotificationHandlerName = 'NotificationHub_onNotificationReceivedGlobal';
+ // global handler that will be called every time new notification is received
+ window[globalNotificationHandlerName] = function (msg) {
+ // if handler attached
+ if (me.onPushNotificationReceived != null) {
+ me.onPushNotificationReceived(msg)
+ }
+ }
+
+ exec(successCallback, errorCallback, 'NotificationHub', 'registerApplication', [this.notificationHubPath, this.connectionString, globalNotificationHandlerName, tags]);
+
+ return deferral.promise;
+}
+
+NotificationHub.prototype.unregisterApplicationAsync = function ()
+{
+ var deferral = new Promise.Deferral(),
+
+ successCallback = function (result) {
+ deferral.resolve(result);
+ },
+
+ errorCallback = function (err) {
+ deferral.reject(err);
+ };
+
+ exec(successCallback, errorCallback, 'NotificationHub', 'unregisterApplication', [this.notificationHubPath, this.connectionString]);
+
+ return deferral.promise;
+}
+
+module.exports = NotificationHub;
View
205 www/Promise.js
@@ -0,0 +1,205 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT 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 (global) {
+ /**
+ * Provides a mechanism for managing interactions with asynchronous APIs based on Promises.
+ * See 'Asynchronous programming in JavaScript' for more details
+ * http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
+ * http://msdn.microsoft.com/en-us/library/windows/apps/br211867.aspx
+ * Note. Functionality is limited, support of .then and .cancel methods only, other methods are in progress.
+ */
+ function Promise() {
+ this._completeCallbacks = [];
+ this._errorCallbacks = [];
+ this._progressCallbacks = [];
+ this._chainedDefer = null;
+ this._state = 'pending'; // -> 'resolved' or 'rejected' or 'cancelled'
+ this.result = null; // represents error or result depending on _state
+ };
+
+ function Deferral() {
+ this.promise = new Promise();
+ };
+
+ Promise.Deferral = Deferral;
+
+ Promise.prototype.then = function (onComplete, onError, onProgress) {
+
+ if (onComplete) { this._completeCallbacks.push(onComplete); }
+ if (onError) { this._errorCallbacks.push(onError); }
+ if (onProgress) { this._progressCallbacks.push(onProgress); }
+
+ // TODO: add support of several chained defers - pass defer object along with callback to _successCallbacks/_errorCallbacks etc..
+ // Example: var a = new Promise(); var b = a.then(..); var c = a.then(..).
+ // both b and c promises should work
+
+ // deferred object for chained promise
+ this._chainedDefer = new Promise.Deferral();
+ this._chainedDefer.promise.parent = this;
+
+ // if operation already completed/failed
+ if (this._state === 'resolved') {
+ this.executeCallback(onComplete, this.result);
+ } else if (this._state === 'rejected') {
+ this.executeCallback(onError, this.result);
+ }
+
+ return this._chainedDefer.promise;
+ };
+
+ // Attempts to cancel the fulfillment of a promised value. If the promise hasn't already been fulfilled and
+ // cancellation is supported, the promise enters the error state with a value of Error("Canceled").
+ // http://msdn.microsoft.com/en-us/library/windows/apps/br211667.aspx
+ Promise.prototype.cancel = function (flag) {
+ // start cancellation from the root promise and then go down the way
+ // TODO find official/correct implementation way
+ if (this.parent != null && !flag) {
+ var root = this;
+ while (root.parent) {
+ root = root.parent;
+ }
+ window.setTimeout(function () {
+ root.cancel(true);
+ });
+ return;
+ }
+
+ // we can cancel only pending promise
+ if (this._state !== 'pending') {
+ return;
+ }
+
+ this._state = 'cancelled';
+
+ var me = this,
+ error = new Error('Cancelled');
+
+ this.result = error;
+
+ // trigger cancellation error
+ this._errorCallbacks.forEach(function (callback) {
+ me.executeCallback(callback, error);
+ });
+
+ // special way to implement any custom logic when user requested async operation cancel
+ if (this.onCancelled) {
+ this.onCancelled();
+ }
+
+ if (this._chainedDefer) {
+ this._chainedDefer.promise.cancel(true);
+ }
+
+ };
+
+ Promise.prototype.executeCallback = function (callback, args) {
+ var chainedDefer = this._chainedDefer;
+ state = this._state;
+
+ window.setTimeout(function () {
+
+ var fnResult;
+ try {
+ fnResult = callback(args);
+ } catch (ex) {
+ // pass error to chained promise
+ chainedDefer && chainedDefer.reject(ex);
+ return;
+ }
+
+ // if there is chained promise we should resolve it after callback function is completed
+ // for promise cancellation there is different propagation mechanism
+ if (chainedDefer == null || state === 'cancelled') return;
+
+ if (fnResult instanceof Promise) {
+ chainedDefer.bind(fnResult);
+ } else {
+ // TODO promise is rejected when it's resolved with an instance of error; add check for fnResult instance of Error
+ chainedDefer.resolve(fnResult);
+ }
+ }, 0);
+ };
+
+
+ Deferral.prototype.resolve = function (data) {
+
+ if (this.promise._state !== 'pending') {
+ return;
+ }
+
+ var promise = this.promise;
+ promise._state = 'resolved';
+ promise.result = data;
+
+ promise._completeCallbacks.forEach(function (callback) {
+ promise.executeCallback(callback, data);
+ });
+ };
+
+ Deferral.prototype.reject = function (error) {
+
+ if (this.promise._state !== 'pending') {
+ return;
+ }
+
+ var promise = this.promise;
+ promise._state = 'rejected';
+ promise.result = error;
+
+ promise._errorCallbacks.forEach(function (callback) {
+ promise.executeCallback(callback, error);
+ });
+ };
+
+ Deferral.prototype.notify = function (value) {
+
+ if (this.promise._state === 'cancelled') {
+ return;
+ }
+
+ this.promise._progressCallbacks.forEach(function (callback) {
+ window.setTimeout(function () {
+ callback(value);
+ });
+ });
+ };
+
+ Deferral.prototype.bind = function (promise) {
+ var that = this;
+ promise.then(function (res) {
+ that.resolve(res);
+ }, function (err) {
+ that.reject(err);
+ });
+ };
+
+ if (typeof exports == 'object') {
+ module.exports = Promise;
+ } else if (typeof define === 'function' && define.amd) {
+ /* AMD support */
+ define(function () {
+ return Promise;
+ });
+ } else {
+ global.Promise = Promise;
+ }
+
+})(this);

0 comments on commit fcba9c4

Please sign in to comment.
Something went wrong with that request. Please try again.