OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 // Custom bindings for the notification API. | |
6 | |
7 var binding = require('binding').Binding.create('experimental.notification'); | |
8 | |
9 var sendRequest = require('sendRequest').sendRequest; | |
10 var imageUtil = require('imageUtil'); | |
11 var lastError = require('lastError'); | |
12 var json = require('json'); | |
13 | |
14 function url_getter(context, key) { | |
15 var f = function() { | |
16 return this[key]; | |
17 }; | |
18 return f.bind(context); | |
19 } | |
20 | |
21 function url_setter(context, key) { | |
22 var f = function(val) { | |
23 this[key] = val; | |
24 }; | |
25 return f.bind(context); | |
26 } | |
27 | |
28 function replaceNotificationOptionURLs(notification_details, callback) { | |
29 // A URL Spec is an object with the following keys: | |
30 // path: The resource to be downloaded. | |
31 // callback: A function to be called when the URL is complete. It | |
32 // should accept an ImageData object and set the appropriate | |
33 // field in the output of create. | |
34 | |
35 // TODO(dewittj): Try to remove hard-coding. | |
36 // |iconUrl| is required. | |
37 var url_specs = [{ | |
38 path: notification_details.iconUrl, | |
39 width: 80, | |
40 height: 80, | |
41 callback: url_setter(notification_details, 'iconUrl') | |
42 }]; | |
43 | |
44 // |secondIconUrl| is optional. | |
45 if (notification_details.secondIconUrl) { | |
46 url_specs.push({ | |
47 path: notification_details.secondIconUrl, | |
48 width: 80, | |
49 height: 80, | |
50 callback: url_setter(notification_details, 'secondIconUrl') | |
51 }); | |
52 } | |
53 | |
54 // |imageUrl| is optional. | |
55 if (notification_details.imageUrl) { | |
56 url_specs.push({ | |
57 path: notification_details.imageUrl, | |
58 width: 300, | |
59 height: 300, | |
60 callback: url_setter(notification_details, 'imageUrl') | |
61 }); | |
62 } | |
63 | |
64 // Each button has an optional icon. | |
65 var button_list = notification_details.buttons; | |
66 if (button_list && typeof button_list.length === 'number') { | |
67 var num_buttons = button_list.length; | |
68 for (var i = 0; i < num_buttons; i++) { | |
69 if (button_list[i].iconUrl) { | |
70 url_specs.push({ | |
71 path: button_list[i].iconUrl, | |
72 width: 16, | |
73 height: 16, | |
74 callback: url_setter(button_list[i], 'iconUrl') | |
75 }); | |
76 } | |
77 } | |
78 } | |
79 | |
80 var errors = 0; | |
81 | |
82 imageUtil.loadAllImages(url_specs, { | |
83 onerror: function(index) { | |
84 errors++; | |
85 }, | |
86 oncomplete: function(imageData) { | |
87 if (errors > 0) { | |
88 callback(false); | |
89 return; | |
90 } | |
91 for (var index = 0; index < url_specs.length; index++) { | |
92 var url_spec = url_specs[index]; | |
93 url_spec.callback(imageData[index]); | |
94 } | |
95 callback(true); | |
96 } | |
97 }); | |
98 } | |
99 | |
100 function genHandle(failure_function) { | |
101 return function(id, input_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; | |
107 replaceNotificationOptionURLs(notification_details, function(success) { | |
108 if (success) { | |
109 sendRequest(that.name, | |
110 [id, notification_details, callback], | |
111 that.definition.parameters); | |
112 return; | |
113 } | |
114 // TODO(kalman): This is probably wrong, failure_function is created in | |
115 // this context but it should be created in the caller's context. I just | |
116 // don't know where that is. | |
117 lastError.run('Unable to download all specified images.', | |
118 failure_function, [callback, id]); | |
119 }); | |
120 }; | |
121 } | |
122 | |
123 var handleCreate = genHandle(function(callback, id) { callback(id); }); | |
124 var handleUpdate = genHandle(function(callback, id) { callback(false); }); | |
125 | |
126 var experimentalNotificationCustomHook = function(bindingsAPI, extensionId) { | |
127 var apiFunctions = bindingsAPI.apiFunctions; | |
128 apiFunctions.setHandleRequest('create', handleCreate); | |
129 apiFunctions.setHandleRequest('update', handleCreate); | |
130 }; | |
131 | |
132 binding.registerCustomHook(experimentalNotificationCustomHook); | |
133 | |
134 exports.binding = binding.generate(); | |
OLD | NEW |