OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 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 downloads API. | |
6 | |
7 var downloadsNatives = requireNative('downloads'); | |
8 var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); | |
9 var sendRequest = require('sendRequest').sendRequest; | |
10 | |
11 function DownloadsEvent(eventName, opt_argSchemas, opt_extraArgSchemas, | |
12 opt_eventOptions) { | |
13 if (typeof eventName != 'string') | |
14 throw new Error('chrome.DownloadsEvent requires an event name.'); | |
15 | |
16 this.eventName_ = eventName; | |
17 this.determiningFilename_ = (eventName == 'downloads.onDeterminingFilename'); | |
18 this.argSchemas_ = opt_argSchemas; | |
19 this.extraArgSchemas_ = opt_extraArgSchemas; | |
20 this.eventOptions_ = chromeHidden.parseEventOptions(opt_eventOptions); | |
21 if (this.determiningFilename_) { | |
22 this.subEvents_ = []; | |
23 } else { | |
24 this.actualEvent_ = | |
25 new chrome.Event(eventName, opt_argSchemas, opt_eventOptions); | |
Matt Perry
2013/02/05 20:49:39
I'm not a JS expert, but I believe it's possible t
benjhayden
2013/02/05 21:12:19
Unfortunately, registerCustomEvent does 'new Downl
Matt Perry
2013/02/05 21:57:10
I know, but I think it still works. For example, t
benjhayden
2013/02/21 22:29:33
8-O
...
Done.
| |
26 } | |
27 } | |
28 | |
29 // Test if the given callback is registered for this event. | |
30 DownloadsEvent.prototype.hasListener = function(cb) { | |
31 if (!this.eventOptions_.supportsListeners) | |
32 throw new Error('This event does not support listeners.'); | |
33 return this.findListener_(cb) > -1; | |
34 }; | |
35 | |
36 // Test if any callbacks are registered for this event. | |
37 DownloadsEvent.prototype.hasListeners = function() { | |
38 if (!this.eventOptions_.supportsListeners) | |
39 throw new Error('This event does not support listeners.'); | |
40 return (this.determiningFilename_ ? (this.subEvents_.length > 0) : | |
41 this.actualEvent_.hasListeners()); | |
42 }; | |
43 | |
44 DownloadsEvent.prototype.addListener = function(cb) { | |
45 if (!this.eventOptions_.supportsListeners) | |
46 throw new Error('This event does not support listeners.'); | |
47 if (!this.determiningFilename_) { | |
48 this.actualEvent_.addListener(cb); | |
49 return; | |
50 } | |
51 var entry = {callback: cb}; | |
52 entry.determiner_id = downloadsNatives.GetFilenameDeterminerId(); | |
53 entry.subEvent = new chrome.Event( | |
54 this.eventName_ + '/' + entry.determiner_id, this.argSchemas_); | |
55 chromeHidden.internalAPIs.downloadsInternal.addFilenameDeterminer( | |
56 entry.determiner_id); | |
57 entry.subEventCallback = function() { | |
58 var download_id = arguments[0].id; | |
59 try { | |
60 var result = cb.apply(null, arguments); | |
61 if ((typeof(result) == 'object') && | |
62 result.filename && | |
63 (typeof(result.filename) == 'string') && | |
64 ((result.overwrite === undefined) || | |
65 (typeof(result.overwrite) == 'boolean'))) { | |
66 chromeHidden.internalAPIs.downloadsInternal.determineFilename( | |
67 entry.determiner_id, | |
68 download_id, | |
69 result.filename, | |
70 result.overwrite || false); | |
71 } else { | |
72 chromeHidden.internalAPIs.downloadsInternal.determineFilename( | |
73 entry.determiner_id, | |
74 download_id); | |
75 } | |
76 } catch (e) { | |
77 chromeHidden.internalAPIs.downloadsInternal.determineFilename( | |
78 entry.determiner_id, | |
79 download_id); | |
80 throw e; | |
81 } | |
82 }; | |
83 this.subEvents_.push(entry); | |
84 entry.subEvent.addListener(entry.subEventCallback); | |
85 }; | |
86 | |
87 DownloadsEvent.prototype.removeListener = function(cb) { | |
Matt Perry
2013/02/07 00:10:13
This is only called when the extension explicitly
benjhayden
2013/02/21 22:29:33
I already Observe NOTIFICATION_EXTENSION_UNLOADED.
Matt Perry
2013/02/21 23:07:49
Yes - in the case of a popup closing, for example.
benjhayden
2013/02/22 20:43:23
Done -- I assumed that I should also use OnListene
| |
88 if (!this.eventOptions_.supportsListeners) | |
89 throw new Error('This event does not support listeners.'); | |
90 if (!this.determiningFilename_) { | |
91 this.actualEvent_.removeListener(cb); | |
92 return; | |
93 } | |
94 var idx; | |
95 while ((idx = this.findListener_(cb)) >= 0) { | |
96 var e = this.subEvents_[idx]; | |
97 e.subEvent.removeListener(e.subEventCallback); | |
98 chromeHidden.internalAPIs.downloadsInternal.removeFilenameDeterminer( | |
99 e.determiner_id); | |
100 if (e.subEvent.hasListeners()) { | |
101 console.error('Internal error: subEvent has orphaned listeners.'); | |
102 } | |
103 this.subEvents_.splice(idx, 1); | |
104 } | |
105 }; | |
106 | |
107 DownloadsEvent.prototype.findListener_ = function(cb) { | |
108 if (!this.determiningFilename_) { | |
109 return this.actualEvent_.findListener(cb); | |
110 } | |
111 for (var i in this.subEvents_) { | |
112 var e = this.subEvents_[i]; | |
113 if (e.callback === cb) { | |
114 if (e.subEvent.findListener_(e.subEventCallback) > -1) | |
115 return i; | |
116 console.error('Internal error: subEvent has no callback.'); | |
117 } | |
118 } | |
119 | |
120 return -1; | |
121 }; | |
122 | |
123 DownloadsEvent.prototype.addRules = function(rules, opt_cb) { | |
124 if (!this.eventOptions_.supportsRules) | |
125 throw new Error('This event does not support rules.'); | |
126 this.eventForRules_.addRules(rules, opt_cb); | |
127 } | |
128 | |
129 DownloadsEvent.prototype.removeRules = function(ruleIdentifiers, opt_cb) { | |
130 if (!this.eventOptions_.supportsRules) | |
131 throw new Error('This event does not support rules.'); | |
132 this.eventForRules_.removeRules(ruleIdentifiers, opt_cb); | |
133 } | |
134 | |
135 DownloadsEvent.prototype.getRules = function(ruleIdentifiers, cb) { | |
136 if (!this.eventOptions_.supportsRules) | |
137 throw new Error('This event does not support rules.'); | |
138 this.eventForRules_.getRules(ruleIdentifiers, cb); | |
139 } | |
140 | |
141 chromeHidden.registerCustomEvent('downloads', DownloadsEvent); | |
OLD | NEW |