| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Custom bindings for the notifications API. | 5 // Custom bindings for the notifications API. |
| 6 // | 6 // |
| 7 var binding = require('binding').Binding.create('notifications'); | 7 var binding = require('binding').Binding.create('notifications'); |
| 8 | 8 |
| 9 var sendRequest = require('sendRequest').sendRequest; | 9 var sendRequest = require('sendRequest').sendRequest; |
| 10 var imageUtil = require('imageUtil'); | 10 var imageUtil = require('imageUtil'); |
| 11 var lastError = require('lastError'); | 11 var lastError = require('lastError'); |
| 12 var notificationsPrivate = requireNative('notifications_private'); | 12 var notificationsPrivate = requireNative('notifications_private'); |
| 13 | 13 |
| 14 function imageDataSetter(context, key) { | 14 function imageDataSetter(context) { |
| 15 var f = function(val) { | 15 var f = function(val) { |
| 16 this[key] = val; | 16 this.data = val; |
| 17 }; | 17 }; |
| 18 return $Function.bind(f, context); | 18 return $Function.bind(f, context); |
| 19 } | 19 } |
| 20 | 20 |
| 21 function getUrlsForBitmapList(notificationBitmapList, imageSize, scaleFactor) { |
| 22 // Returns a list of specs to be used by the image util library. |
| 23 var rv = []; |
| 24 $Array.forEach(notificationBitmapList, function(bitmap) { |
| 25 if (typeof bitmap.data === 'string' || |
| 26 bitmap.data instanceof $String.self) { |
| 27 $Array.push(rv, { |
| 28 path: bitmap.data, |
| 29 width: imageSize.width * scaleFactor, |
| 30 height: imageSize.height * scaleFactor, |
| 31 scale: bitmap.scale || 1.0, |
| 32 callback: imageDataSetter(bitmap) |
| 33 }); |
| 34 } |
| 35 }); |
| 36 return rv; |
| 37 } |
| 38 |
| 21 // A URL Spec is an object with the following keys: | 39 // A URL Spec is an object with the following keys: |
| 22 // path: The resource to be downloaded. | 40 // path: The resource to be downloaded. |
| 23 // width: (optional) The maximum width of the image to be downloaded in device | 41 // width: (optional) The maximum width of the image to be downloaded in device |
| 24 // pixels. | 42 // pixels. |
| 25 // height: (optional) The maximum height of the image to be downloaded in | 43 // height: (optional) The maximum height of the image to be downloaded in |
| 26 // device pixels. | 44 // device pixels. |
| 27 // callback: A function to be called when the URL is complete. It | 45 // callback: A function to be called when the URL is complete. It |
| 28 // should accept an ImageData object and set the appropriate | 46 // should accept an ImageData object and set the appropriate |
| 29 // field in |notificationDetails|. | 47 // field in |notificationDetails|. |
| 30 function getUrlSpecs(imageSizes, notificationDetails) { | 48 function getUrlSpecs(imageSizes, notificationDetails) { |
| 31 var urlSpecs = []; | 49 var urls = $Array.concat( |
| 32 | 50 getUrlsForBitmapList( |
| 33 // |iconUrl| might be optional for notification updates. | 51 notificationDetails.icons, |
| 34 if (notificationDetails.iconUrl) { | 52 imageSizes.icon, |
| 35 $Array.push(urlSpecs, { | 53 imageSizes.scaleFactor), |
| 36 path: notificationDetails.iconUrl, | 54 getUrlsForBitmapList( |
| 37 width: imageSizes.icon.width * imageSizes.scaleFactor, | 55 notificationDetails.images, |
| 38 height: imageSizes.icon.height * imageSizes.scaleFactor, | 56 imageSizes.image)); |
| 39 callback: imageDataSetter(notificationDetails, 'iconBitmap') | 57 for (var i = 0; i < notificationDetails.buttons.length; i++) { |
| 40 }); | 58 urls = $Array.concat( |
| 59 urls, |
| 60 getUrlsForBitmapList( |
| 61 notificationDetails.buttons[i].icons, |
| 62 imageSizes.buttonIcon)); |
| 41 } | 63 } |
| 42 | 64 |
| 43 // |imageUrl| is optional. | 65 return urls; |
| 44 if (notificationDetails.imageUrl) { | |
| 45 $Array.push(urlSpecs, { | |
| 46 path: notificationDetails.imageUrl, | |
| 47 width: imageSizes.image.width * imageSizes.scaleFactor, | |
| 48 height: imageSizes.image.height * imageSizes.scaleFactor, | |
| 49 callback: imageDataSetter(notificationDetails, 'imageBitmap') | |
| 50 }); | |
| 51 } | |
| 52 | |
| 53 // Each button has an optional icon. | |
| 54 var buttonList = notificationDetails.buttons; | |
| 55 if (buttonList && typeof buttonList.length === 'number') { | |
| 56 var numButtons = buttonList.length; | |
| 57 for (var i = 0; i < numButtons; i++) { | |
| 58 if (buttonList[i].iconUrl) { | |
| 59 $Array.push(urlSpecs, { | |
| 60 path: buttonList[i].iconUrl, | |
| 61 width: imageSizes.buttonIcon.width * imageSizes.scaleFactor, | |
| 62 height: imageSizes.buttonIcon.height * imageSizes.scaleFactor, | |
| 63 callback: imageDataSetter(buttonList[i], 'iconBitmap') | |
| 64 }); | |
| 65 } | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 return urlSpecs; | |
| 70 } | 66 } |
| 71 | 67 |
| 72 function replaceNotificationOptionURLs(notification_details, callback) { | 68 function replaceNotificationOptionURLs(notification_details, callback) { |
| 73 var imageSizes = notificationsPrivate.GetNotificationImageSizes(); | 69 var imageSizes = notificationsPrivate.GetNotificationImageSizes(); |
| 74 var url_specs = getUrlSpecs(imageSizes, notification_details); | 70 var url_specs = getUrlSpecs(imageSizes, notification_details); |
| 75 if (!url_specs.length) { | 71 if (!url_specs.length) { |
| 76 callback(true); | 72 callback(true); |
| 77 return; | 73 return; |
| 78 } | 74 } |
| 79 | 75 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 91 for (var index = 0; index < url_specs.length; index++) { | 87 for (var index = 0; index < url_specs.length; index++) { |
| 92 var url_spec = url_specs[index]; | 88 var url_spec = url_specs[index]; |
| 93 url_spec.callback(imageData[index]); | 89 url_spec.callback(imageData[index]); |
| 94 } | 90 } |
| 95 callback(true); | 91 callback(true); |
| 96 } | 92 } |
| 97 }); | 93 }); |
| 98 } | 94 } |
| 99 | 95 |
| 100 function genHandle(name, failure_function) { | 96 function genHandle(name, failure_function) { |
| 101 return function(id, input_notification_details, callback) { | 97 return function(id, notification_details, callback) { |
| 102 // TODO(dewittj): Remove this hack. This is used as a way to deep | |
| 103 // copy a complex JSON object. | |
| 104 var notification_details = JSON.parse( | |
| 105 JSON.stringify(input_notification_details)); | |
| 106 var that = this; | 98 var that = this; |
| 107 replaceNotificationOptionURLs(notification_details, function(success) { | 99 replaceNotificationOptionURLs(notification_details, function(success) { |
| 108 if (success) { | 100 if (success) { |
| 109 sendRequest(that.name, | 101 sendRequest(that.name, |
| 110 [id, notification_details, callback], | 102 [id, notification_details, callback], |
| 111 that.definition.parameters); | 103 that.definition.parameters); |
| 112 return; | 104 return; |
| 113 } | 105 } |
| 114 lastError.run(name, | 106 lastError.run(name, |
| 115 'Unable to download all specified images.', | 107 'Unable to download all specified images.', |
| 116 null, | 108 null, |
| 117 failure_function, [callback, id]) | 109 failure_function, [callback, id]); |
| 118 }); | 110 }); |
| 119 }; | 111 }; |
| 120 } | 112 } |
| 121 | 113 |
| 114 function translateBitmapUrls(id, input_options, callback) { |
| 115 var args = $Array.slice(arguments); |
| 116 |
| 117 // TODO(dewittj): Remove this hack. This is used as a way to deep |
| 118 // copy a complex JSON object. |
| 119 var options = JSON.parse(JSON.stringify(input_options)); |
| 120 |
| 121 options.icons = options.icons || []; |
| 122 if (options.iconUrl) { |
| 123 $Array.splice(options.icons, 0, 0, {scale: 1.0, data: options.iconUrl}); |
| 124 } |
| 125 |
| 126 options.images = options.images || []; |
| 127 if (options.imageUrl) { |
| 128 $Array.splice(options.images, 0, 0, {scale: 1.0, data: options.imageUrl}); |
| 129 } |
| 130 |
| 131 options.buttons = options.buttons || []; |
| 132 for (var i = 0; i < options.buttons.length; i++) { |
| 133 options.buttons[i].icons = options.buttons[i].icons || []; |
| 134 if (options.buttons[i].url) { |
| 135 $Array.splice( |
| 136 options.buttons[i].icons, |
| 137 0, |
| 138 0, |
| 139 {scale: 1.0, data: options.buttons[i].url}); |
| 140 } |
| 141 } |
| 142 |
| 143 return [id, options, callback]; |
| 144 } |
| 145 |
| 122 var handleCreate = genHandle('notifications.create', | 146 var handleCreate = genHandle('notifications.create', |
| 123 function(callback, id) { callback(id); }); | 147 function(callback, id) { callback(id); }); |
| 124 var handleUpdate = genHandle('notifications.update', | 148 var handleUpdate = genHandle('notifications.update', |
| 125 function(callback, id) { callback(false); }); | 149 function(callback, id) { callback(false); }); |
| 126 | 150 |
| 127 var notificationsCustomHook = function(bindingsAPI, extensionId) { | 151 var notificationsCustomHook = function(bindingsAPI, extensionId) { |
| 128 var apiFunctions = bindingsAPI.apiFunctions; | 152 var apiFunctions = bindingsAPI.apiFunctions; |
| 153 apiFunctions.setUpdateArgumentsPostValidate('create', translateBitmapUrls); |
| 129 apiFunctions.setHandleRequest('create', handleCreate); | 154 apiFunctions.setHandleRequest('create', handleCreate); |
| 130 apiFunctions.setHandleRequest('update', handleUpdate); | 155 apiFunctions.setHandleRequest('update', handleUpdate); |
| 131 }; | 156 }; |
| 132 | 157 |
| 133 binding.registerCustomHook(notificationsCustomHook); | 158 binding.registerCustomHook(notificationsCustomHook); |
| 134 | 159 |
| 135 exports.binding = binding.generate(); | 160 exports.binding = binding.generate(); |
| OLD | NEW |