| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * A set of utilities for use with the Chrome Extension APIs. | |
| 7 * | |
| 8 * Allows for easy access to required JS objects. | |
| 9 */ | |
| 10 part of chrome; | |
| 11 | |
| 12 /** | |
| 13 * A dart object, that is convertible to JS. Used for creating objects in dart, | |
| 14 * then passing them to JS. | |
| 15 * | |
| 16 * Objects that are passable to JS need to implement this interface. | |
| 17 */ | |
| 18 abstract class ChromeObject { | |
| 19 /* | |
| 20 * Default Constructor | |
| 21 * | |
| 22 * Called by child objects during their regular construction. | |
| 23 */ | |
| 24 ChromeObject() : _jsObject = JS('var', '{}'); | |
| 25 | |
| 26 /* | |
| 27 * Internal proxy constructor | |
| 28 * | |
| 29 * Creates a new Dart object using this existing proxy. | |
| 30 */ | |
| 31 ChromeObject._proxy(this._jsObject); | |
| 32 | |
| 33 /* | |
| 34 * JS Object Representation | |
| 35 */ | |
| 36 final Object _jsObject; | |
| 37 } | |
| 38 | |
| 39 /** | |
| 40 * Useful functions for converting arguments. | |
| 41 */ | |
| 42 | |
| 43 /** | |
| 44 * Converts the given map-type argument to js-friendly format, recursively. | |
| 45 * Returns the new Map object. | |
| 46 */ | |
| 47 Object _convertMapArgument(Map argument) { | |
| 48 Map m = new Map(); | |
| 49 for (Object key in argument.keys) | |
| 50 m[key] = convertArgument(argument[key]); | |
| 51 return convertDartToNative_Dictionary(m); | |
| 52 } | |
| 53 | |
| 54 /** | |
| 55 * Converts the given list-type argument to js-friendly format, recursively. | |
| 56 * Returns the new List object. | |
| 57 */ | |
| 58 List _convertListArgument(List argument) { | |
| 59 List l = new List(); | |
| 60 for (var i = 0; i < argument.length; i ++) | |
| 61 l.add(convertArgument(argument[i])); | |
| 62 return l; | |
| 63 } | |
| 64 | |
| 65 /** | |
| 66 * Converts the given argument Object to js-friendly format, recursively. | |
| 67 * | |
| 68 * Flattens out all Chrome objects into their corresponding ._toMap() | |
| 69 * definitions, then converts them to JS objects. | |
| 70 * | |
| 71 * Returns the new argument. | |
| 72 * | |
| 73 * Cannot be used for functions. | |
| 74 */ | |
| 75 Object convertArgument(var argument) { | |
| 76 if (argument == null) | |
| 77 return argument; | |
| 78 | |
| 79 if (argument is num || argument is String || argument is bool) | |
| 80 return argument; | |
| 81 | |
| 82 if (argument is ChromeObject) | |
| 83 return argument._jsObject; | |
| 84 | |
| 85 if (argument is List) | |
| 86 return _convertListArgument(argument); | |
| 87 | |
| 88 if (argument is Map) | |
| 89 return _convertMapArgument(argument); | |
| 90 | |
| 91 if (argument is Function) | |
| 92 throw new Exception("Cannot serialize Function argument ${argument}."); | |
| 93 | |
| 94 // TODO(sashab): Try and detect whether the argument is already serialized. | |
| 95 return argument; | |
| 96 } | |
| 97 | |
| 98 /// Description of a declarative rule for handling events. | |
| 99 class Rule extends ChromeObject { | |
| 100 /* | |
| 101 * Public (Dart) constructor | |
| 102 */ | |
| 103 Rule({String id, List conditions, List actions, int priority}) { | |
| 104 this.id = id; | |
| 105 this.conditions = conditions; | |
| 106 this.actions = actions; | |
| 107 this.priority = priority; | |
| 108 } | |
| 109 | |
| 110 /* | |
| 111 * Private (JS) constructor | |
| 112 */ | |
| 113 Rule._proxy(_jsObject) : super._proxy(_jsObject); | |
| 114 | |
| 115 /* | |
| 116 * Public accessors | |
| 117 */ | |
| 118 String get id => JS('String', '#.id', this._jsObject); | |
| 119 | |
| 120 void set id(String id) { | |
| 121 JS('void', '#.id = #', this._jsObject, id); | |
| 122 } | |
| 123 | |
| 124 // TODO(sashab): Wrap these generic Lists somehow. | |
| 125 List get conditions => JS('List', '#.conditions', this._jsObject); | |
| 126 | |
| 127 void set conditions(List conditions) { | |
| 128 JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions)); | |
| 129 } | |
| 130 | |
| 131 // TODO(sashab): Wrap these generic Lists somehow. | |
| 132 List get actions => JS('List', '#.actions', this._jsObject); | |
| 133 | |
| 134 void set actions(List actions) { | |
| 135 JS('void', '#.actions = #', this._jsObject, convertArgument(actions)); | |
| 136 } | |
| 137 | |
| 138 int get priority => JS('int', '#.priority', this._jsObject); | |
| 139 | |
| 140 void set priority(int priority) { | |
| 141 JS('void', '#.priority = #', this._jsObject, priority); | |
| 142 } | |
| 143 | |
| 144 } | |
| 145 | |
| 146 /** | |
| 147 * The Event class. | |
| 148 * | |
| 149 * Chrome Event classes extend this interface. | |
| 150 * | |
| 151 * e.g. | |
| 152 * | |
| 153 * // chrome.app.runtime.onLaunched | |
| 154 * class Event_ChromeAppRuntimeOnLaunched extends Event { | |
| 155 * // constructor, passing the arity of the callback | |
| 156 * Event_ChromeAppRuntimeOnLaunched(jsObject) : | |
| 157 * super._(jsObject, 1); | |
| 158 * | |
| 159 * // methods, strengthening the Function parameter specificity | |
| 160 * void addListener(void callback(LaunchData launchData)) | |
| 161 * => super.addListener(callback); | |
| 162 * void removeListener(void callback(LaunchData launchData)) | |
| 163 * => super.removeListener(callback); | |
| 164 * bool hasListener(void callback(LaunchData launchData)) | |
| 165 * => super.hasListener(callback); | |
| 166 * } | |
| 167 * | |
| 168 */ | |
| 169 class Event { | |
| 170 /* | |
| 171 * JS Object Representation | |
| 172 */ | |
| 173 final Object _jsObject; | |
| 174 | |
| 175 /* | |
| 176 * Number of arguments the callback takes. | |
| 177 */ | |
| 178 final int _callbackArity; | |
| 179 | |
| 180 /* | |
| 181 * Private constructor | |
| 182 */ | |
| 183 Event._(this._jsObject, this._callbackArity); | |
| 184 | |
| 185 /* | |
| 186 * Methods | |
| 187 */ | |
| 188 | |
| 189 /// Registers an event listener <em>callback</em> to an event. | |
| 190 void addListener(Function callback) => | |
| 191 JS('void', | |
| 192 '#.addListener(#)', | |
| 193 this._jsObject, | |
| 194 convertDartClosureToJS(callback, this._callbackArity) | |
| 195 ); | |
| 196 | |
| 197 /// Deregisters an event listener <em>callback</em> from an event. | |
| 198 void removeListener(Function callback) => | |
| 199 JS('void', | |
| 200 '#.removeListener(#)', | |
| 201 this._jsObject, | |
| 202 convertDartClosureToJS(callback, this._callbackArity) | |
| 203 ); | |
| 204 | |
| 205 /// Returns True if <em>callback</em> is registered to the event. | |
| 206 bool hasListener(Function callback) => | |
| 207 JS('bool', | |
| 208 '#.hasListener(#)', | |
| 209 this._jsObject, | |
| 210 convertDartClosureToJS(callback, this._callbackArity) | |
| 211 ); | |
| 212 | |
| 213 /// Returns true if any event listeners are registered to the event. | |
| 214 bool hasListeners() => | |
| 215 JS('bool', | |
| 216 '#.hasListeners()', | |
| 217 this._jsObject | |
| 218 ); | |
| 219 | |
| 220 /// Registers rules to handle events. | |
| 221 /// | |
| 222 /// [eventName] is the name of the event this function affects and [rules] are | |
| 223 /// the rules to be registered. These do not replace previously registered | |
| 224 /// rules. [callback] is called with registered rules. | |
| 225 /// | |
| 226 void addRules(String eventName, List<Rule> rules, | |
| 227 [void callback(List<Rule> rules)]) { | |
| 228 // proxy the callback | |
| 229 void __proxy_callback(List rules) { | |
| 230 if (callback != null) { | |
| 231 List<Rule> __proxy_rules = new List<Rule>(); | |
| 232 | |
| 233 for (Object o in rules) | |
| 234 __proxy_rules.add(new Rule._proxy(o)); | |
| 235 | |
| 236 callback(__proxy_rules); | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 JS('void', | |
| 241 '#.addRules(#, #, #)', | |
| 242 this._jsObject, | |
| 243 convertArgument(eventName), | |
| 244 convertArgument(rules), | |
| 245 convertDartClosureToJS(__proxy_callback, 1) | |
| 246 ); | |
| 247 } | |
| 248 | |
| 249 /// Returns currently registered rules. | |
| 250 /// | |
| 251 /// [eventName] is the name of the event this function affects and, if an arra
y | |
| 252 /// is passed as [ruleIdentifiers], only rules with identifiers contained in | |
| 253 /// this array are returned. [callback] is called with registered rules. | |
| 254 /// | |
| 255 void getRules(String eventName, [List<String> ruleIdentifiers, | |
| 256 void callback(List<Rule> rules)]) { | |
| 257 // proxy the callback | |
| 258 void __proxy_callback(List rules) { | |
| 259 if (callback != null) { | |
| 260 List<Rule> __proxy_rules = new List<Rule>(); | |
| 261 | |
| 262 for (Object o in rules) | |
| 263 __proxy_rules.add(new Rule._proxy(o)); | |
| 264 | |
| 265 callback(__proxy_rules); | |
| 266 } | |
| 267 } | |
| 268 | |
| 269 JS('void', | |
| 270 '#.getRules(#, #, #)', | |
| 271 this._jsObject, | |
| 272 convertArgument(eventName), | |
| 273 convertArgument(ruleIdentifiers), | |
| 274 convertDartClosureToJS(__proxy_callback, 1) | |
| 275 ); | |
| 276 } | |
| 277 | |
| 278 /// Unregisters currently registered rules. | |
| 279 /// | |
| 280 /// [eventName] is the name of the event this function affects and, if an arra
y | |
| 281 /// is passed as [ruleIdentifiers], only rules with identifiers contained in | |
| 282 /// this array are unregistered. [callback] is called when the rules are | |
| 283 /// unregistered. | |
| 284 /// | |
| 285 void removeRules(String eventName, [List<String> ruleIdentifiers, | |
| 286 void callback()]) => | |
| 287 JS('void', | |
| 288 '#.removeRules(#, #, #)', | |
| 289 this._jsObject, | |
| 290 convertArgument(eventName), | |
| 291 convertArgument(ruleIdentifiers), | |
| 292 convertDartClosureToJS(callback, 0) | |
| 293 ); | |
| 294 } | |
| 295 | |
| OLD | NEW |