diff --git a/merges/android/scripts/android2.3-jscompat.js b/merges/android/scripts/android2.3-jscompat.js new file mode 100644 index 0000000..c77f98e --- /dev/null +++ b/merges/android/scripts/android2.3-jscompat.js @@ -0,0 +1,30 @@ +// Polyfill pour la prise en charge de Function.prototype.bind() sur Android 2.3 +(function () { + if (!Function.prototype.bind) { + Function.prototype.bind = function (thisValue) { + if (typeof this !== "function") { + throw new TypeError(this + " cannot be bound as it is not a function"); + } + + // bind() permet également d'ajouter des arguments au début de l'appel + var preArgs = Array.prototype.slice.call(arguments, 1); + + // Fonction réelle à laquelle lier la valeur et les arguments "this" + var functionToBind = this; + var noOpFunction = function () { }; + + // Argument "this" à utiliser + var thisArg = this instanceof noOpFunction && thisValue ? this : thisValue; + + // Fonction liée résultante + var boundFunction = function () { + return functionToBind.apply(thisArg, preArgs.concat(Array.prototype.slice.call(arguments))); + }; + + noOpFunction.prototype = this.prototype; + boundFunction.prototype = new noOpFunction(); + + return boundFunction; + }; + } +}()); diff --git a/merges/android/scripts/platformOverrides.js b/merges/android/scripts/platformOverrides.js new file mode 100644 index 0000000..15f8a12 --- /dev/null +++ b/merges/android/scripts/platformOverrides.js @@ -0,0 +1,10 @@ +(function () { + // Ajouter le polyfill bind() + var scriptElem = document.createElement('script'); + scriptElem.setAttribute('src', 'scripts/android2.3-jscompat.js'); + if (document.body) { + document.body.appendChild(scriptElem); + } else { + document.head.appendChild(scriptElem); + } +}()); \ No newline at end of file diff --git a/merges/windows/scripts/platformOverrides.js b/merges/windows/scripts/platformOverrides.js new file mode 100644 index 0000000..b1bd926 --- /dev/null +++ b/merges/windows/scripts/platformOverrides.js @@ -0,0 +1,10 @@ +(function () { + // Ajouter le polyfill safeHTML + var scriptElem = document.createElement('script'); + scriptElem.setAttribute('src', 'scripts/winstore-jscompat.js'); + if (document.body) { + document.body.appendChild(scriptElem); + } else { + document.head.appendChild(scriptElem); + } +}()); \ No newline at end of file diff --git a/merges/windows/scripts/winstore-jscompat.js b/merges/windows/scripts/winstore-jscompat.js new file mode 100644 index 0000000..1d2c67b --- /dev/null +++ b/merges/windows/scripts/winstore-jscompat.js @@ -0,0 +1,176 @@ +// Copyright (c) Microsoft Open Technologies, Inc. Tous droits réservés. +// Sous licence Apache, version 2.0. +// Consultez http://www.apache.org/licenses/LICENSE-2.0.html. +// Shim de contenu dynamique JavaScript pour applications du Windows Store +(function () { + + if (window.MSApp && MSApp.execUnsafeLocalFunction) { + + // Certains nœuds ont une propriété "attributes" qui masque la propriété Node.prototype.attributes + // ce qui signifie que nous ne voyons pas réellement les attributs de Node (curieusement, la console de débogage VS + // semble affectée par le même problème). + // + var Element_setAttribute = Object.getOwnPropertyDescriptor(Element.prototype, "setAttribute").value; + var Element_removeAttribute = Object.getOwnPropertyDescriptor(Element.prototype, "removeAttribute").value; + var HTMLElement_insertAdjacentHTMLPropertyDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "insertAdjacentHTML"); + var Node_get_attributes = Object.getOwnPropertyDescriptor(Node.prototype, "attributes").get; + var Node_get_childNodes = Object.getOwnPropertyDescriptor(Node.prototype, "childNodes").get; + var detectionDiv = document.createElement("div"); + + function getAttributes(element) { + return Node_get_attributes.call(element); + } + + function setAttribute(element, attribute, value) { + try { + Element_setAttribute.call(element, attribute, value); + } catch (e) { + // ignorer + } + } + + function removeAttribute(element, attribute) { + Element_removeAttribute.call(element, attribute); + } + + function childNodes(element) { + return Node_get_childNodes.call(element); + } + + function empty(element) { + while (element.childNodes.length) { + element.removeChild(element.lastChild); + } + } + + function insertAdjacentHTML(element, position, html) { + HTMLElement_insertAdjacentHTMLPropertyDescriptor.value.call(element, position, html); + } + + function inUnsafeMode() { + var isUnsafe = true; + try { + detectionDiv.innerHTML = ""; + } + catch (ex) { + isUnsafe = false; + } + + return isUnsafe; + } + + function cleanse(html, targetElement) { + var cleaner = document.implementation.createHTMLDocument("cleaner"); + empty(cleaner.documentElement); + MSApp.execUnsafeLocalFunction(function () { + insertAdjacentHTML(cleaner.documentElement, "afterbegin", html); + }); + + var scripts = cleaner.documentElement.querySelectorAll("script"); + Array.prototype.forEach.call(scripts, function (script) { + switch (script.type.toLowerCase()) { + case "": + script.type = "text/inert"; + break; + case "text/javascript": + case "text/ecmascript": + case "text/x-javascript": + case "text/jscript": + case "text/livescript": + case "text/javascript1.1": + case "text/javascript1.2": + case "text/javascript1.3": + script.type = "text/inert-" + script.type.slice("text/".length); + break; + case "application/javascript": + case "application/ecmascript": + case "application/x-javascript": + script.type = "application/inert-" + script.type.slice("application/".length); + break; + + default: + break; + } + }); + + function cleanseAttributes(element) { + var attributes = getAttributes(element); + if (attributes && attributes.length) { + // comme la collection d'attributs est dynamique, il est plus simple de mettre en file d'attente les changements de noms + var events; + for (var i = 0, len = attributes.length; i < len; i++) { + var attribute = attributes[i]; + var name = attribute.name; + if ((name[0] === "o" || name[0] === "O") && + (name[1] === "n" || name[1] === "N")) { + events = events || []; + events.push({ name: attribute.name, value: attribute.value }); + } + } + if (events) { + for (var i = 0, len = events.length; i < len; i++) { + var attribute = events[i]; + removeAttribute(element, attribute.name); + setAttribute(element, "x-" + attribute.name, attribute.value); + } + } + } + var children = childNodes(element); + for (var i = 0, len = children.length; i < len; i++) { + cleanseAttributes(children[i]); + } + } + cleanseAttributes(cleaner.documentElement); + + var cleanedNodes = []; + + if (targetElement.tagName === 'HTML') { + cleanedNodes = Array.prototype.slice.call(document.adoptNode(cleaner.documentElement).childNodes); + } else { + if (cleaner.head) { + cleanedNodes = cleanedNodes.concat(Array.prototype.slice.call(document.adoptNode(cleaner.head).childNodes)); + } + if (cleaner.body) { + cleanedNodes = cleanedNodes.concat(Array.prototype.slice.call(document.adoptNode(cleaner.body).childNodes)); + } + } + + return cleanedNodes; + } + + function cleansePropertySetter(property, setter) { + var propertyDescriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, property); + var originalSetter = propertyDescriptor.set; + Object.defineProperty(HTMLElement.prototype, property, { + get: propertyDescriptor.get, + set: function (value) { + if (window.WinJS && window.WinJS._execUnsafe && inUnsafeMode()) { + originalSetter.call(this, value); + } else { + var that = this; + var nodes = cleanse(value, that); + MSApp.execUnsafeLocalFunction(function () { + setter(propertyDescriptor, that, nodes); + }); + } + }, + enumerable: propertyDescriptor.enumerable, + configurable: propertyDescriptor.configurable, + }); + } + cleansePropertySetter("innerHTML", function (propertyDescriptor, target, elements) { + empty(target); + for (var i = 0, len = elements.length; i < len; i++) { + target.appendChild(elements[i]); + } + }); + cleansePropertySetter("outerHTML", function (propertyDescriptor, target, elements) { + for (var i = 0, len = elements.length; i < len; i++) { + target.insertAdjacentElement("afterend", elements[i]); + } + target.parentNode.removeChild(target); + }); + + } + +}()); diff --git a/scripts/index.ts b/scripts/index.ts new file mode 100644 index 0000000..34b4832 --- /dev/null +++ b/scripts/index.ts @@ -0,0 +1,39 @@ +// Pour obtenir une présentation du modèle Vide, consultez la documentation suivante : +// http://go.microsoft.com/fwlink/?LinkID=397705 +// Pour déboguer du code durant le chargement d'une page dans Ripple ou sur les appareils/émulateurs Android, lancez votre application, définissez des points d'arrêt, +// puis exécutez "window.location.reload()" dans la console JavaScript. +module BlankCordovaApp1 { + "use strict"; + + export module Application { + export function initialize() { + document.addEventListener('deviceready', onDeviceReady, false); + } + + function onDeviceReady() { + // Gérer les événements de suspension et de reprise Cordova + document.addEventListener('pause', onPause, false); + document.addEventListener('resume', onResume, false); + + // TODO: Cordova a été chargé. Effectuez l'initialisation qui nécessite Cordova ici. + var parentElement = document.getElementById('deviceready'); + var listeningElement = parentElement.querySelector('.listening'); + var receivedElement = parentElement.querySelector('.received'); + listeningElement.setAttribute('style', 'display:none;'); + receivedElement.setAttribute('style', 'display:block;'); + } + + function onPause() { + // TODO: cette application a été suspendue. Enregistrez l'état de l'application ici. + } + + function onResume() { + // TODO: cette application a été réactivée. Restaurez l'état de l'application ici. + } + + } + + window.onload = function () { + Application.initialize(); + } +} diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 0000000..8308bc3 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "noEmitOnError": true, + "removeComments": false, + "sourceMap": true, + "inlineSources": true, + "out": "www/scripts/appBundle.js", + "target": "es5" + } +} diff --git a/scripts/typings/cordova/cordova.d.ts b/scripts/typings/cordova/cordova.d.ts new file mode 100644 index 0000000..75b77eb --- /dev/null +++ b/scripts/typings/cordova/cordova.d.ts @@ -0,0 +1,92 @@ +// Type definitions for Apache Cordova +// Project: http://cordova.apache.org +// Definitions by: Microsoft Open Technologies Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +interface Cordova { + /** Invokes native functionality by specifying corresponding service name, action and optional parameters. + * @param success A success callback function. + * @param fail An error callback function. + * @param service The service name to call on the native side (corresponds to a native class). + * @param action The action name to call on the native side (generally corresponds to the native class method). + * @param args An array of arguments to pass into the native environment. + */ + exec(success: () => any, fail: () => any, service: string, action: string, args?: string[]): void; + /** Gets the operating system name. */ + platformId: string; + /** Gets Cordova framework version */ + version: string; + /** Defines custom logic as a Cordova module. Other modules can later access it using module name provided. */ + define(moduleName: string, factory: (require: any, exports: any, module: any) => any): void; + /** Access a Cordova module by name. */ + require(moduleName: string): any; +} + +interface Document { + addEventListener(type: "deviceready", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "resume", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "backbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "menubutton", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "searchbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "startcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "endcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "volumedownbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + addEventListener(type: "volumeupbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + + removeEventListener(type: "deviceready", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "pause", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "resume", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "backbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "menubutton", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "searchbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "startcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "endcallbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "volumedownbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: "volumeupbutton", listener: (ev: Event) => any, useCapture?: boolean): void; + + addEventListener(type: string, listener: (ev: Event) => any, useCapture?: boolean): void; + removeEventListener(type: string, listener: (ev: Event) => any, useCapture?: boolean): void; +} + +interface Window { + cordova:Cordova; +} + +// cordova/argscheck module +interface ArgsCheck { + checkArgs(argsSpec: string, functionName: string, args: any[], callee?: any): void; + getValue(value?: any, defaultValue?: any): any; + enableChecks: boolean; +} + +// cordova/urlutil module +interface UrlUtil { + makeAbsolute(url: string): string +} + +/** Apache Cordova instance */ +declare var cordova: Cordova; diff --git a/scripts/typings/cordova/plugins/BatteryStatus.d.ts b/scripts/typings/cordova/plugins/BatteryStatus.d.ts new file mode 100644 index 0000000..7343fab --- /dev/null +++ b/scripts/typings/cordova/plugins/BatteryStatus.d.ts @@ -0,0 +1,125 @@ +// Type definitions for Apache Cordova BatteryStatus plugin. +// Project: https://github.com/apache/cordova-plugin-battery-status +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Window { + onbatterystatus: (type: BatteryStatusEvent) => void; + onbatterycritical: (type: BatteryStatusEvent) => void; + onbatterylow: (type: BatteryStatusEvent) => void; + /** + * Adds a listener for an event from the BatteryStatus plugin. + * @param type the event to listen for + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param listener the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + addEventListener(type: "batterystatus", listener: (ev: BatteryStatusEvent) => any, useCapture?: boolean): void; + /** + * Adds a listener for an event from the BatteryStatus plugin. + * @param type the event to listen for + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param listener the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + addEventListener(type: "batterycritical", listener: (ev: BatteryStatusEvent) => any, useCapture?: boolean): void; + /** + * Adds a listener for an event from the BatteryStatus plugin. + * @param type the event to listen for + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param listener the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + addEventListener(type: "batterylow", listener: (ev: BatteryStatusEvent) => any, useCapture?: boolean): void; + /** + * Adds a listener for an event from the BatteryStatus plugin. + * @param type the event to listen for + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param listener the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + addEventListener(type: string, listener: (ev: Event) => any, useCapture?: boolean): void; + /** + * Removes a listener for an event from the BatteryStatus plugin. + * @param type The event to stop listening for. + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param callback the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + removeEventListener(type: "batterystatus", listener: (ev: BatteryStatusEvent) => any, useCapture?: boolean): void; + /** + * Removes a listener for an event from the BatteryStatus plugin. + * @param type The event to stop listening for. + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param callback the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + removeEventListener(type: "batterycritical", listener: (ev: BatteryStatusEvent) => any, useCapture?: boolean): void; + /** + * Removes a listener for an event from the BatteryStatus plugin. + * @param type The event to stop listening for. + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param callback the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + removeEventListener(type: "batterylow", listener: (ev: BatteryStatusEvent) => any, useCapture?: boolean): void; + /** + * Removes a listener for an event from the BatteryStatus plugin. + * @param type The event to stop listening for. + * batterystatus: event fires when the percentage of battery charge + * changes by at least 1 percent, or if the device is plugged in or unplugged. + * batterycritical: event fires when the percentage of battery charge has reached + * the critical battery threshold. The value is device-specific. + * batterylow: event fires when the percentage of battery charge has + * reached the low battery threshold, device-specific value. + * @param callback the function that executes when the event fires. The function is + * passed an BatteryStatusEvent object as a parameter. + */ + removeEventListener(type: string, listener: (ev: Event) => any, useCapture?: boolean): void; +} + +/** Object, that passed into battery event listener */ +interface BatteryStatusEvent extends Event { + /* The percentage of battery charge (0-100). */ + level: number; + /* A boolean that indicates whether the device is plugged in. */ + isPlugged: boolean; +} \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/Camera.d.ts b/scripts/typings/cordova/plugins/Camera.d.ts new file mode 100644 index 0000000..126b329 --- /dev/null +++ b/scripts/typings/cordova/plugins/Camera.d.ts @@ -0,0 +1,174 @@ +// Type definitions for Apache Cordova Camera plugin. +// Project: https://github.com/apache/cordova-plugin-camera +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Navigator { + /** + * This plugin provides an API for taking pictures and for choosing images from the system's image library. + */ + camera: Camera; +} + +/** + * This plugin provides an API for taking pictures and for choosing images from the system's image library. + */ +interface Camera { + /** + * Removes intermediate photos taken by the camera from temporary storage. + * @param onSuccess Success callback, that called when cleanup succeeds. + * @param onError Error callback, that get an error message. + */ + cleanup( + onSuccess: () => void, + onError: (message: string) => void): void; + /** + * Takes a photo using the camera, or retrieves a photo from the device's image gallery. + * @param cameraSuccess Success callback, that get the image + * as a base64-encoded String, or as the URI for the image file. + * @param cameraError Error callback, that get an error message. + * @param cameraOptions Optional parameters to customize the camera settings. + */ + getPicture( + cameraSuccess: (data: string) => void, + cameraError: (message: string) => void, + cameraOptions?: CameraOptions): void; + // Next will work only on iOS + //getPicture( + // cameraSuccess: (data: string) => void, + // cameraError: (message: string) => void, + // cameraOptions?: CameraOptions): CameraPopoverHandle; +} + +interface CameraOptions { + /** Picture quality in range 0-100. Default is 50 */ + quality?: number; + /** + * Choose the format of the return value. + * Defined in navigator.camera.DestinationType. Default is FILE_URI. + * DATA_URL : 0, Return image as base64-encoded string + * FILE_URI : 1, Return image file URI + * NATIVE_URI : 2 Return image native URI + * (e.g., assets-library:// on iOS or content:// on Android) + */ + destinationType?: number; + /** + * Set the source of the picture. + * Defined in navigator.camera.PictureSourceType. Default is CAMERA. + * PHOTOLIBRARY : 0, + * CAMERA : 1, + * SAVEDPHOTOALBUM : 2 + */ + sourceType?: number; + /** Allow simple editing of image before selection. */ + allowEdit?: boolean; + /** + * Choose the returned image file's encoding. + * Defined in navigator.camera.EncodingType. Default is JPEG + * JPEG : 0 Return JPEG encoded image + * PNG : 1 Return PNG encoded image + */ + encodingType?: number; + /** + * Width in pixels to scale image. Must be used with targetHeight. + * Aspect ratio remains constant. + */ + targetWidth?: number; + /** + * Height in pixels to scale image. Must be used with targetWidth. + * Aspect ratio remains constant. + */ + targetHeight?: number; + /** + * Set the type of media to select from. Only works when PictureSourceType + * is PHOTOLIBRARY or SAVEDPHOTOALBUM. Defined in nagivator.camera.MediaType + * PICTURE: 0 allow selection of still pictures only. DEFAULT. + * Will return format specified via DestinationType + * VIDEO: 1 allow selection of video only, WILL ALWAYS RETURN FILE_URI + * ALLMEDIA : 2 allow selection from all media types + */ + mediaType?: number; + /** Rotate the image to correct for the orientation of the device during capture. */ + correctOrientation?: boolean; + /** Save the image to the photo album on the device after capture. */ + saveToPhotoAlbum?: boolean; + /** + * Choose the camera to use (front- or back-facing). + * Defined in navigator.camera.Direction. Default is BACK. + * FRONT: 0 + * BACK: 1 + */ + cameraDirection?: number; + /** iOS-only options that specify popover location in iPad. Defined in CameraPopoverOptions. */ + popoverOptions?: CameraPopoverOptions; +} + +/** + * A handle to the popover dialog created by navigator.camera.getPicture. Used on iOS only. + */ +interface CameraPopoverHandle { + /** + * Set the position of the popover. + * @param popoverOptions the CameraPopoverOptions that specify the new position. + */ + setPosition(popoverOptions: CameraPopoverOptions): void; +} + +/** + * iOS-only parameters that specify the anchor element location and arrow direction + * of the popover when selecting images from an iPad's library or album. + */ +interface CameraPopoverOptions { + x: number; + y: number; + width: number; + height: number; + /** + * Direction the arrow on the popover should point. Defined in Camera.PopoverArrowDirection + * Matches iOS UIPopoverArrowDirection constants. + * ARROW_UP : 1, + * ARROW_DOWN : 2, + * ARROW_LEFT : 4, + * ARROW_RIGHT : 8, + * ARROW_ANY : 15 + */ + arrowDir : number; +} + +declare var Camera: { + // Camera constants, defined in Camera plugin + DestinationType: { + DATA_URL: number; + FILE_URI: number; + NATIVE_URI: number + } + Direction: { + BACK: number; + FRONT: number; + } + EncodingType: { + JPEG: number; + PNG: number; + } + MediaType: { + PICTURE: number; + VIDEO: number; + ALLMEDIA: number; + } + PictureSourceType: { + PHOTOLIBRARY: number; + CAMERA: number; + SAVEDPHOTOALBUM: number; + } + // Used only on iOS + PopoverArrowDirection: { + ARROW_UP: number; + ARROW_DOWN: number; + ARROW_LEFT: number; + ARROW_RIGHT: number; + ARROW_ANY: number; + } +}; \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/Contacts.d.ts b/scripts/typings/cordova/plugins/Contacts.d.ts new file mode 100644 index 0000000..29a9a59 --- /dev/null +++ b/scripts/typings/cordova/plugins/Contacts.d.ts @@ -0,0 +1,273 @@ +// Type definitions for Apache Cordova Contacts plugin. +// Project: https://github.com/apache/cordova-plugin-contacts +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Navigator { + /** Provides access to the device contacts database. */ + contacts: Contacts; +} + +interface Contacts { + /** + * The navigator.contacts.create method is synchronous, and returns a new Contact object. + * This method does not retain the Contact object in the device contacts database, + * for which you need to invoke the Contact.save method. + * @param properties Object with contact fields + */ + create(properties?: ContactProperties): Contact; + /** + * The navigator.contacts.find method executes asynchronously, querying the device contacts database + * and returning an array of Contact objects. The resulting objects are passed to the onSuccess + * callback function specified by the onSuccess parameter. + * @param fields The fields parameter specifies the fields to be used as a search qualifier, + * and only those results are passed to the onSuccess callback function. A zero-length fields parameter + * is invalid and results in ContactError.INVALID_ARGUMENT_ERROR. A contactFields value of "*" returns all contact fields. + * @param onSuccess Success callback function invoked with the array of Contact objects returned from the database + * @param onError Error callback function, invoked when an error occurs. + * @param options Search options to filter navigator.contacts. + */ + find(fields: string[], + onSuccess: (contacts: Contact[]) => void, + onError: (error: ContactError) => void, + options?: ContactFindOptions): void; + /** + * The navigator.contacts.pickContact method launches the Contact Picker to select a single contact. + * The resulting object is passed to the contactSuccess callback function specified by the contactSuccess parameter. + * @param onSuccess Success callback function invoked with the array of Contact objects returned from the database + * @param onError Error callback function, invoked when an error occurs. + */ + pickContact(onSuccess: (contact: Contact) => void, + onError: (error: ContactError) => void): void +} + +interface ContactProperties { + /** A globally unique identifier. */ + id?: string; + /** The name of this Contact, suitable for display to end users. */ + displayName?: string; + /** An object containing all components of a persons name. */ + name?: ContactName; + /** A casual name by which to address the contact. */ + nickname?: string; + /** An array of all the contact's phone numbers. */ + phoneNumbers?: ContactField[]; + /** An array of all the contact's email addresses. */ + emails?: ContactField[]; + /** An array of all the contact's addresses. */ + addresses?: ContactAddress[]; + /** An array of all the contact's IM addresses. */ + ims?: ContactField[]; + /** An array of all the contact's organizations. */ + organizations?: ContactOrganization[]; + /** The birthday of the contact. */ + birthday?: Date; + /** A note about the contact. */ + note?: string; + /** An array of the contact's photos. */ + photos?: ContactField[]; + /** An array of all the user-defined categories associated with the contact. */ + categories?: ContactField[]; + /** An array of web pages associated with the contact. */ + urls?: ContactField[]; +} + +/** + * The Contact object represents a user's contact. Contacts can be created, stored, or removed + * from the device contacts database. Contacts can also be retrieved (individually or in bulk) + * from the database by invoking the navigator.contacts.find method. + */ +interface Contact extends ContactProperties { + /** + * Returns a new Contact object that is a deep copy of the calling object, with the id property set to null + */ + clone(): Contact; + /** + * Removes the contact from the device contacts database, otherwise executes an error callback with a ContactError object. + * @param onSuccess Success callback function invoked on success operation. + * @param onError Error callback function, invoked when an error occurs. + */ + remove( + onSuccess: () => void, + onError: (error: Error) => void): void; + /** + * Saves a new contact to the device contacts database, or updates an existing contact if a contact with the same id already exists. + * @param onSuccess Success callback function invoked on success operation with che Contact object. + * @param onError Error callback function, invoked when an error occurs. + */ + save( + onSuccess: (contact: Contact) => void, + onError: (error: Error) => void): void; +} + +declare var Contact: { + /** Constructor of Contact object */ + new(id?: string, + displayName?: string, + name?: ContactName, + nickname?: string, + phoneNumbers?: ContactField[], + emails?: ContactField[], + addresses?: ContactAddress[], + ims?: ContactField[], + organizations?: ContactOrganization[], + birthday?: Date, + note?: string, + photos?: ContactField[], + categories?: ContactField, + urls?: ContactField[]): Contact +}; + +/** The ContactError object is returned to the user through the contactError callback function when an error occurs. */ +interface ContactError { + /** Error code */ + code: number; + /** Error message */ + message: string; +} + +declare var ContactError: { + new(code: number): ContactError; + UNKNOWN_ERROR: number; + INVALID_ARGUMENT_ERROR: number; + TIMEOUT_ERROR: number; + PENDING_OPERATION_ERROR: number; + IO_ERROR: number; + NOT_SUPPORTED_ERROR: number; + PERMISSION_DENIED_ERROR: number +}; + +/** Contains different kinds of information about a Contact object's name. */ +interface ContactName { + /** The complete name of the contact. */ + formatted?: string; + /** The contact's family name. */ + familyName?: string; + /** The contact's given name. */ + givenName?: string; + /** The contact's middle name. */ + middleName?: string; + /** The contact's prefix (example Mr. or Dr.) */ + honorificPrefix?: string; + /** The contact's suffix (example Esq.). */ + honorificSuffix?: string; +} + +declare var ContactName: { + /** Constructor for ContactName object */ + new(formatted?: string, + familyName?: string, + givenName?: string, + middleName?: string, + honorificPrefix?: string, + honorificSuffix?: string): ContactName +}; + +/** + * The ContactField object is a reusable component that represents contact fields generically. + * Each ContactField object contains a value, type, and pref property. A Contact object stores + * several properties in ContactField[] arrays, such as phone numbers and email addresses. + * + * In most instances, there are no pre-determined values for a ContactField object's type attribute. + * For example, a phone number can specify type values of home, work, mobile, iPhone, + * or any other value that is supported by a particular device platform's contact database. + * However, for the Contact photos field, the type field indicates the format of the returned image: + * url when the value attribute contains a URL to the photo image, or base64 when the value + * contains a base64-encoded image string. + */ +interface ContactField { + /** A string that indicates what type of field this is, home for example. */ + type: string; + /** The value of the field, such as a phone number or email address. */ + value: string; + /** Set to true if this ContactField contains the user's preferred value. */ + pref: boolean; +} + +declare var ContactField: { + /** Constructor for ContactField object */ + new(type?: string, + value?: string, + pref?: boolean): ContactField +}; + +/** + * The ContactAddress object stores the properties of a single address of a contact. + * A Contact object may include more than one address in a ContactAddress[] array. + */ +interface ContactAddress { + /** Set to true if this ContactAddress contains the user's preferred value. */ + pref?: boolean; + /** A string indicating what type of field this is, home for example. */ + type?: string; + /** The full address formatted for display. */ + formatted?: string; + /** The full street address. */ + streetAddress?: string; + /** The city or locality. */ + locality?: string; + /** The state or region. */ + region?: string; + /** The zip code or postal code. */ + postalCode?: string; + /** The country name. */ + country?: string; +} + +declare var ContactAddress: { + /** Constructor of ContactAddress object */ + new(pref?: boolean, + type?: string, + formatted?: string, + streetAddress?: string, + locality?: string, + region?: string, + postalCode?: string, + country?: string): ContactAddress +}; + +/** + * The ContactOrganization object stores a contact's organization properties. A Contact object stores + * one or more ContactOrganization objects in an array. + */ +interface ContactOrganization { + /** Set to true if this ContactOrganization contains the user's preferred value. */ + pref?: boolean; + /** A string that indicates what type of field this is, home for example. */ + type?: string; + /** The name of the organization. */ + name?: string; + /** The department the contract works for. */ + department?: string; + /** The contact's title at the organization. */ + title?: string; +} + +declare var ContactOrganization: { + /** Constructor for ContactOrganization object */ + new(pref?: boolean, + type?: string, + name?: string, + department?: string, + title?: string): ContactOrganization +}; + +/** Search options to filter navigator.contacts. */ +interface ContactFindOptions { + /** The search string used to find navigator.contacts. */ + filter?: string; + /** Determines if the find operation returns multiple navigator.contacts. */ + multiple?: boolean; + /* Contact fields to be returned back. If specified, the resulting Contact object only features values for these fields. */ + desiredFields?: string[]; +} + +declare var ContactFindOptions: { + /** Constructor for ContactFindOptions object */ + new(filter?: string, + multiple?: boolean, + desiredFields?: string[]): ContactFindOptions +}; \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/Device.d.ts b/scripts/typings/cordova/plugins/Device.d.ts new file mode 100644 index 0000000..283406c --- /dev/null +++ b/scripts/typings/cordova/plugins/Device.d.ts @@ -0,0 +1,29 @@ +// Type definitions for Apache Cordova Device plugin. +// Project: https://github.com/apache/cordova-plugin-device +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +/** + * This plugin defines a global device object, which describes the device's hardware and software. + * Although the object is in the global scope, it is not available until after the deviceready event. + */ +interface Device { + /** Get the version of Cordova running on the device. */ + cordova: string; + /** + * The device.model returns the name of the device's model or product. The value is set + * by the device manufacturer and may be different across versions of the same product. + */ + model: string; + /** Get the device's operating system name. */ + platform: string; + /** Get the device's Universally Unique Identifier (UUID). */ + uuid: string; + /** Get the operating system version. */ + version: string; +} + +declare var device: Device; \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/DeviceMotion.d.ts b/scripts/typings/cordova/plugins/DeviceMotion.d.ts new file mode 100644 index 0000000..a0e8908 --- /dev/null +++ b/scripts/typings/cordova/plugins/DeviceMotion.d.ts @@ -0,0 +1,77 @@ +// Type definitions for Apache Cordova Device Motion plugin. +// Project: https://github.com/apache/cordova-plugin-device-motion +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Navigator { + /** + * This plugin provides access to the device's accelerometer. The accelerometer is a motion sensor + * that detects the change (delta) in movement relative to the current device orientation, + * in three dimensions along the x, y, and z axis. + */ + accelerometer: Accelerometer; +} + +/** + * This plugin provides access to the device's accelerometer. The accelerometer is a motion sensor + * that detects the change (delta) in movement relative to the current device orientation, + * in three dimensions along the x, y, and z axis. + */ +interface Accelerometer { + /** + * Stop watching the Acceleration referenced by the watchID parameter. + * @param watchID The ID returned by navigator.accelerometer.watchAcceleration. + */ + clearWatch(watchID: WatchHandle): void; + /** + * Get the current acceleration along the x, y, and z axes. + * These acceleration values are returned to the accelerometerSuccess callback function. + * @param accelerometerSuccess Success callback that gets the Acceleration object. + * @param accelerometerError Success callback + */ + getCurrentAcceleration( + accelerometerSuccess: (acceleration: Acceleration) => void, + accelerometerError: () => void): void; + /** + * Retrieves the device's current Acceleration at a regular interval, executing the + * accelerometerSuccess callback function each time. Specify the interval in milliseconds + * via the acceleratorOptions object's frequency parameter. + * The returned watch ID references the accelerometer's watch interval, and can be used + * with navigator.accelerometer.clearWatch to stop watching the accelerometer. + * @param accelerometerSuccess Callback, that called at every time interval and passes an Acceleration object. + * @param accelerometerError Error callback. + * @param accelerometerOptions Object with options for watchAcceleration + */ + watchAcceleration( + accelerometerSuccess: (acceleration: Acceleration) => void, + accelerometerError: () => void, + accelerometerOptions?: AccelerometerOptions): WatchHandle; +} + +/** + * Contains Accelerometer data captured at a specific point in time. Acceleration values include + * the effect of gravity (9.81 m/s^2), so that when a device lies flat and facing up, x, y, and z + * values returned should be 0, 0, and 9.81. + */ +interface Acceleration { + /** Amount of acceleration on the x-axis. (in m/s^2) */ + x: number; + /** Amount of acceleration on the y-axis. (in m/s^2) */ + y: number; + /** Amount of acceleration on the z-axis. (in m/s^2) */ + z: number; + /** Creation timestamp in milliseconds. */ + timestamp: number; +} + +/** Object with options for watchAcceleration */ +interface AccelerometerOptions { + /** How often to retrieve the Acceleration in milliseconds. (Default: 10000) */ + frequency?: number; +} + +/** Abstract type for watch IDs used by Accelerometer. Values of these type are actually `number` at runtime.*/ +interface WatchHandle { } \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/DeviceOrientation.d.ts b/scripts/typings/cordova/plugins/DeviceOrientation.d.ts new file mode 100644 index 0000000..effbc06 --- /dev/null +++ b/scripts/typings/cordova/plugins/DeviceOrientation.d.ts @@ -0,0 +1,86 @@ +// Type definitions for Apache Cordova Device Orientation plugin. +// Project: https://github.com/apache/cordova-plugin-device-orientation +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Navigator { + /** + * This plugin provides access to the device's compass. The compass is a sensor that detects + * the direction or heading that the device is pointed, typically from the top of the device. + * It measures the heading in degrees from 0 to 359.99, where 0 is north. + */ + compass: Compass; +} + +/** + * This plugin provides access to the device's compass. The compass is a sensor that detects + * the direction or heading that the device is pointed, typically from the top of the device. + * It measures the heading in degrees from 0 to 359.99, where 0 is north. + */ +interface Compass { + /** + * Get the current compass heading. The compass heading is returned via a CompassHeading + * object using the onSuccess callback function. + * @param onSuccess Success callback that passes CompassHeading object. + * @param onError Error callback that passes CompassError object. + */ + getCurrentHeading( + onSuccess: (heading: CompassHeading) => void, + onError: (error: CompassError) => void, + options?: CompassOptions): void; + /** + * Gets the device's current heading at a regular interval. Each time the heading is retrieved, + * the headingSuccess callback function is executed. The returned watch ID references the compass + * watch interval. The watch ID can be used with navigator.compass.clearWatch to stop watching + * the navigator.compass. + * @param onSuccess Success callback that passes CompassHeading object. + * @param onError Error callback that passes CompassError object. + * @param options CompassOptions object + */ + watchHeading( + onSuccess: (heading: CompassHeading) => void, + onError: (error: CompassError) => void, + options?: CompassOptions): number; + /** + * Stop watching the compass referenced by the watch ID parameter. + * @param id The ID returned by navigator.compass.watchHeading. + */ + clearWatch(id: number): void; +} + +/** A CompassHeading object is returned to the compassSuccess callback function. */ +interface CompassHeading { + /** The heading in degrees from 0-359.99 at a single moment in time. */ + magneticHeading: number; + /** The heading relative to the geographic North Pole in degrees 0-359.99 at a single moment in time. A negative value indicates that the true heading can't be determined. */ + trueHeading: number; + /** The deviation in degrees between the reported heading and the true heading. */ + headingAccuracy: number; + /** The time at which this heading was determined. */ + timestamp: number; +} + +interface CompassOptions { + filter?: number; + frequency?: number; +} + +/** A CompassError object is returned to the onError callback function when an error occurs. */ +interface CompassError { + /** + * One of the predefined error codes + * CompassError.COMPASS_INTERNAL_ERR + * CompassError.COMPASS_NOT_SUPPORTED + */ + code: number; +} + +declare var CompassError: { + /** Constructor for CompassError object */ + new(code: number): CompassError; + COMPASS_INTERNAL_ERR: number; + COMPASS_NOT_SUPPORTED: number +} \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/Dialogs.d.ts b/scripts/typings/cordova/plugins/Dialogs.d.ts new file mode 100644 index 0000000..6d86c62 --- /dev/null +++ b/scripts/typings/cordova/plugins/Dialogs.d.ts @@ -0,0 +1,69 @@ +// Type definitions for Apache Cordova Dialogs plugin. +// Project: https://github.com/apache/cordova-plugin-dialogs +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Navigator { + /** This plugin provides access to some native dialog UI elements. */ + notification: Notification +} + +/** This plugin provides access to some native dialog UI elements. */ +interface Notification { + /** + * Shows a custom alert or dialog box. Most Cordova implementations use a native dialog box for this feature, + * but some platforms use the browser's alert function, which is typically less customizable. + * @param message Dialog message. + * @param alertCallback Callback to invoke when alert dialog is dismissed. + * @param title Dialog title, defaults to 'Alert'. + * @param buttonName Button name, defaults to OK. + */ + alert(message: string, + alertCallback: () => void, + title?: string, + buttonName?: string): void; + /** + * The device plays a beep sound. + * @param times The number of times to repeat the beep. + */ + beep(times: number): void; + /** + * Displays a customizable confirmation dialog box. + * @param message Dialog message. + * @param confirmCallback Callback to invoke with index of button pressed (1, 2, or 3) + * or when the dialog is dismissed without a button press (0). + * @param title Dialog title, defaults to Confirm. + * @param buttonLabels Array of strings specifying button labels, defaults to [OK,Cancel]. + */ + confirm(message: string, + confirmCallback: (choice: number) => void, + title?: string, + buttonLabels?: string[]): void; + /** + * Displays a native dialog box that is more customizable than the browser's prompt function. + * @param message Dialog message. + * @param promptCallback Callback to invoke when a button is pressed. + * @param title Dialog title, defaults to "Prompt". + * @param buttonLabels Array of strings specifying button labels, defaults to ["OK","Cancel"]. + * @param defaultText Default textbox input value, default: "". + */ + prompt(message: string, + promptCallback: (result: NotificationPromptResult) => void, + title?: string, + buttonLabels?: string[], + defaultText?: string): void; +} + +/** Object, passed to promptCallback */ +interface NotificationPromptResult { + /** + * The index of the pressed button. Note that the index uses one-based indexing, so the value is 1, 2, 3, etc. + * 0 is the result when the dialog is dismissed without a button press. + */ + buttonIndex: number; + /** The text entered in the prompt dialog box. */ + input1: string; +} \ No newline at end of file diff --git a/scripts/typings/cordova/plugins/FileSystem.d.ts b/scripts/typings/cordova/plugins/FileSystem.d.ts new file mode 100644 index 0000000..1e1476b --- /dev/null +++ b/scripts/typings/cordova/plugins/FileSystem.d.ts @@ -0,0 +1,364 @@ +// Type definitions for Apache Cordova File System plugin. +// Project: https://github.com/apache/cordova-plugin-file +// Definitions by: Microsoft Open Technologies, Inc. +// Definitions: https://github.com/borisyankov/DefinitelyTyped +// +// Copyright (c) Microsoft Open Technologies, Inc. +// Licensed under the MIT license. + +interface Window { + /** + * Requests a filesystem in which to store application data. + * @param type Whether the filesystem requested should be persistent, as defined above. Use one of TEMPORARY or PERSISTENT. + * @param size This is an indicator of how much storage space, in bytes, the application expects to need. + * @param successCallback The callback that is called when the user agent provides a filesystem. + * @param errorCallback A callback that is called when errors happen, or when the request to obtain the filesystem is denied. + */ + requestFileSystem( + type: number, + size: number, + successCallback: (fileSystem: FileSystem) => void, + errorCallback?: (fileError: FileError) => void): void; + /** + * Look up file system Entry referred to by local URI. + * @param string uri URI referring to a local file or directory + * @param successCallback invoked with Entry object corresponding to URI + * @param errorCallback invoked if error occurs retrieving file system entry + */ + resolveLocalFileSystemURI(uri: string, + successCallback: (entry: Entry) => void, + errorCallback?: (error: FileError) => void): void; + TEMPORARY: number; + PERSISTENT: number; +} + +/** This interface represents a file system. */ +interface FileSystem { + /* The name of the file system, unique across the list of exposed file systems. */ + name: string; + /** The root directory of the file system. */ + root: DirectoryEntry; +} + +/** + * An abstract interface representing entries in a file system, + * each of which may be a File or DirectoryEntry. + */ +interface Entry { + /** Entry is a file. */ + isFile: boolean; + /** Entry is a directory. */ + isDirectory: boolean; + /** The name of the entry, excluding the path leading to it. */ + name: string; + /** The full absolute path from the root to the entry. */ + fullPath: string; + /** The file system on which the entry resides. */ + fileSystem: FileSystem; + nativeURL: string; + /** + * Look up metadata about this entry. + * @param successCallback A callback that is called with the time of the last modification. + * @param errorCallback A callback that is called when errors happen. + */ + getMetadata( + successCallback: (metadata: Metadata) => void, + errorCallback?: (error: FileError) => void): void; + /** + * Move an entry to a different location on the file system. It is an error to try to: + * move a directory inside itself or to any child at any depth;move an entry into its parent if a name different from its current one isn't provided; + * move a file to a path occupied by a directory; + * move a directory to a path occupied by a file; + * move any element to a path occupied by a directory which is not empty. + * A move of a file on top of an existing file must attempt to delete and replace that file. + * A move of a directory on top of an existing empty directory must attempt to delete and replace that directory. + * @param parent The directory to which to move the entry. + * @param newName The new name of the entry. Defaults to the Entry's current name if unspecified. + * @param successCallback A callback that is called with the Entry for the new location. + * @param errorCallback A callback that is called when errors happen. + */ + moveTo(parent: DirectoryEntry, + newName?: string, + successCallback?: (entry: Entry) => void, + errorCallback?: (error: FileError) => void): void; + /** + * Copy an entry to a different location on the file system. It is an error to try to: + * copy a directory inside itself or to any child at any depth; + * copy an entry into its parent if a name different from its current one isn't provided; + * copy a file to a path occupied by a directory; + * copy a directory to a path occupied by a file; + * copy any element to a path occupied by a directory which is not empty. + * A copy of a file on top of an existing file must attempt to delete and replace that file. + * A copy of a directory on top of an existing empty directory must attempt to delete and replace that directory. + * Directory copies are always recursive--that is, they copy all contents of the directory. + * @param parent The directory to which to move the entry. + * @param newName The new name of the entry. Defaults to the Entry's current name if unspecified. + * @param successCallback A callback that is called with the Entry for the new object. + * @param errorCallback A callback that is called when errors happen. + */ + copyTo(parent: DirectoryEntry, + newName?: string, + successCallback?: (entry: Entry) => void, + errorCallback?: (error: FileError) => void): void; + /** + * Returns a URL that can be used as the src attribute of a