| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Custom bindings for the notifications API. |
| // |
| var binding = require('binding').Binding.create('notifications'); |
| |
| var sendRequest = require('sendRequest').sendRequest; |
| var exceptionHandler = require('uncaught_exception_handler'); |
| var imageUtil = require('imageUtil'); |
| var lastError = require('lastError'); |
| var notificationsPrivate = requireNative('notifications_private'); |
| |
| function imageDataSetter(context, key) { |
| var f = function(val) { |
| this[key] = val; |
| }; |
| return $Function.bind(f, context); |
| } |
| |
| // A URL Spec is an object with the following keys: |
| // path: The resource to be downloaded. |
| // width: (optional) The maximum width of the image to be downloaded in device |
| // pixels. |
| // height: (optional) The maximum height of the image to be downloaded in |
| // device pixels. |
| // callback: A function to be called when the URL is complete. It |
| // should accept an ImageData object and set the appropriate |
| // field in |notificationDetails|. |
| function getUrlSpecs(imageSizes, notificationDetails) { |
| var urlSpecs = []; |
| |
| // |iconUrl| might be optional for notification updates. |
| if (notificationDetails.iconUrl) { |
| $Array.push(urlSpecs, { |
| path: notificationDetails.iconUrl, |
| width: imageSizes.icon.width * imageSizes.scaleFactor, |
| height: imageSizes.icon.height * imageSizes.scaleFactor, |
| callback: imageDataSetter(notificationDetails, 'iconBitmap') |
| }); |
| } |
| |
| // |appIconMaskUrl| is optional. |
| if (notificationDetails.appIconMaskUrl) { |
| $Array.push(urlSpecs, { |
| path: notificationDetails.appIconMaskUrl, |
| width: imageSizes.appIconMask.width * imageSizes.scaleFactor, |
| height: imageSizes.appIconMask.height * imageSizes.scaleFactor, |
| callback: imageDataSetter(notificationDetails, 'appIconMaskBitmap') |
| }); |
| } |
| |
| // |imageUrl| is optional. |
| if (notificationDetails.imageUrl) { |
| $Array.push(urlSpecs, { |
| path: notificationDetails.imageUrl, |
| width: imageSizes.image.width * imageSizes.scaleFactor, |
| height: imageSizes.image.height * imageSizes.scaleFactor, |
| callback: imageDataSetter(notificationDetails, 'imageBitmap') |
| }); |
| } |
| |
| // Each button has an optional icon. |
| var buttonList = notificationDetails.buttons; |
| if (buttonList && typeof buttonList.length === 'number') { |
| var numButtons = buttonList.length; |
| for (var i = 0; i < numButtons; i++) { |
| if (buttonList[i].iconUrl) { |
| $Array.push(urlSpecs, { |
| path: buttonList[i].iconUrl, |
| width: imageSizes.buttonIcon.width * imageSizes.scaleFactor, |
| height: imageSizes.buttonIcon.height * imageSizes.scaleFactor, |
| callback: imageDataSetter(buttonList[i], 'iconBitmap') |
| }); |
| } |
| } |
| } |
| |
| return urlSpecs; |
| } |
| |
| function replaceNotificationOptionURLs(notification_details, callback) { |
| var imageSizes = notificationsPrivate.GetNotificationImageSizes(); |
| var url_specs = getUrlSpecs(imageSizes, notification_details); |
| if (!url_specs.length) { |
| callback(true); |
| return; |
| } |
| |
| var errors = 0; |
| |
| imageUtil.loadAllImages(url_specs, { |
| onerror: function(index) { |
| errors++; |
| }, |
| oncomplete: function(imageData) { |
| if (errors > 0) { |
| callback(false); |
| return; |
| } |
| for (var index = 0; index < url_specs.length; index++) { |
| var url_spec = url_specs[index]; |
| url_spec.callback(imageData[index]); |
| } |
| callback(true); |
| } |
| }); |
| } |
| |
| function genHandle(name, failure_function) { |
| return function(id, input_notification_details, callback) { |
| // TODO(dewittj): Remove this hack. This is used as a way to deep |
| // copy a complex JSON object. |
| var notification_details = $JSON.parse( |
| $JSON.stringify(input_notification_details)); |
| var that = this; |
| var stack = exceptionHandler.getExtensionStackTrace(); |
| replaceNotificationOptionURLs(notification_details, function(success) { |
| if (success) { |
| sendRequest(that.name, |
| [id, notification_details, callback], |
| that.definition.parameters, {stack: stack}); |
| return; |
| } |
| lastError.run(name, |
| 'Unable to download all specified images.', |
| stack, |
| failure_function, [callback || function() {}, id]); |
| }); |
| }; |
| } |
| |
| var handleCreate = genHandle('notifications.create', |
| function(callback, id) { callback(id); }); |
| var handleUpdate = genHandle('notifications.update', |
| function(callback, id) { callback(false); }); |
| |
| var notificationsCustomHook = function(bindingsAPI, extensionId) { |
| var apiFunctions = bindingsAPI.apiFunctions; |
| apiFunctions.setHandleRequest('create', handleCreate); |
| apiFunctions.setHandleRequest('update', handleUpdate); |
| }; |
| |
| binding.registerCustomHook(notificationsCustomHook); |
| |
| exports.$set('binding', binding.generate()); |