Index: chrome/renderer/resources/extensions/experimental.system_info_storage_custom_bindings.js |
diff --git a/chrome/renderer/resources/extensions/experimental.system_info_storage_custom_bindings.js b/chrome/renderer/resources/extensions/experimental.system_info_storage_custom_bindings.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0db72cd171bbc7bd6e828f74bbf5ef1bb0f076f7 |
--- /dev/null |
+++ b/chrome/renderer/resources/extensions/experimental.system_info_storage_custom_bindings.js |
@@ -0,0 +1,101 @@ |
+// Copyright (c) 2012 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 systemInfo.storage API. |
+ |
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); |
+var validate = require('schemaUtils').validate; |
+ |
+// The JSON schemas for extra parameters of addListener. Currently the IDL |
+// parser doesn't support extra parameter for event definitions, see |
+// http://crbug.com/163822. This is just a workaround to make the schemas |
+// validation works for extra parameter event even if no defintion is given |
+// in IDL file. |
+var extraArgJSONSchemas = |
+'{ ' + |
+' "type":"object", ' + |
+' "id":"experimental.systemInfo.storage.EventOption", ' + |
+' "properties": { ' + |
+' "id": {"type": "string", "optional": false, "name":"id"}, ' + |
+' "changeThreshold": { ' + |
+' "type": "integer", "optional": true, "name":"changeThreshold" ' + |
+' } ' + |
+' } ' + |
+'}'; |
+ |
+var EVENT_DELIMITER = '#'; |
+ |
+// StorageChangeEvent object. This is used for systemInfo.storage.onChanged |
+// event with extra parameter supporting. Each invocation of addListener |
+// creates a new named sub-event for the storage being watched. |
+// |
+// Example: |
+// chrome.experimental.systemInfo.storage.onChanged.addListener( |
+// callback, {id: <storage_id>, changeThreshold: <number>}); |
+// ^ callback will only be called for the changes happening on the specified |
+// storage and the change of free space is greater than the changeThreshold. |
+// |
+function StorageChangeEvent(eventName, argSchemas, extraArgSchemas, |
+ opt_eventOptions) { |
+ // StorageChangeEvent inherits from chrome.Event object. |
+ chrome.Event.call(this, eventName, argSchemas, opt_eventOptions); |
+ if (!extraArgSchemas) { |
+ this.extraArgSchemas_ = []; |
+ this.extraArgSchemas_.push(JSON.parse(extraArgJSONSchemas)); |
+ } |
+ else |
+ this.extraArgSchemas_ = extraArgSchemas; |
+ this.subEvents_ = {}; |
+} |
+ |
+StorageChangeEvent.prototype = new chrome.Event(); |
+ |
+StorageChangeEvent.prototype.addListener = function(cb, eventOption) { |
+ if (!this.eventOptions_.supportsListeners) |
+ throw new Error('This event does not support listeners'); |
+ validate(Array.prototype.slice.call(arguments, 1), this.extraArgSchemas_); |
+ |
+ // The format of sub-event name is "this.eventName_#<id>#changeThreshold". |
+ var subEventName = this.eventName_ + EVENT_DELIMITER + eventOption.id; |
+ // Default changeBytes is 4096 bytes. |
+ if (!eventOption.changeThreshold || eventOption.changeThreshold <= 0) |
+ eventOption.changeThreshold = 4096; |
+ subEventName += EVENT_DELIMITER + eventOption.changeThreshold; |
+ |
+ this.listeners_.push({callback: cb}); |
+ |
+ // If the event is already being listened. |
+ if (this.subEvents_[subEventName]) { |
+ var subEvent = this.subEvents_[subEventName].event; |
+ subEvent.addListener(cb); |
+ return; |
+ } |
+ |
+ // Create a new event. |
+ var subEvent = new chrome.Event(subEventName, this.argSchemas_); |
+ this.subEvents_[subEventName] = {event: subEvent, id: eventOption.id}; |
+ subEvent.addListener(cb); |
+} |
+ |
+StorageChangeEvent.prototype.removeListener = function(cb) { |
+ if (!this.eventOptions_.supportsListeners) |
+ throw new Error('This event does not support listeners'); |
+ var idx; |
+ while ((idx = this.findListener_(cb)) >= 0) { |
+ this.listeners_.splice(idx, 1); |
+ } |
+ |
+ for (var eventName in this.subEvents_) { |
+ var subEvent = this.subEvents_[eventName].event; |
+ if (subEvent.hasListener(cb)) { |
+ subEvent.removeListener(cb); |
+ if (!subEvent.hasListeners()) { |
+ delete this.subEvents_[eventName]; |
+ } |
+ } |
+ } |
+} |
+ |
+chromeHidden.registerCustomEvent('experimental.systemInfo.storage', |
+ StorageChangeEvent); |