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); |
| 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) { |
| 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 |