Chromium Code Reviews| 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() : | |
| 25 _jsObject = JS('var', '{}'); | |
| 26 | |
| 27 /* | |
| 28 * Internal proxy constructor | |
| 29 * | |
| 30 * Creates a new Dart object using this existing proxy. | |
| 31 */ | |
| 32 ChromeObject._proxy(this._jsObject); | |
| 33 | |
| 34 /* | |
| 35 * JS Object Representation | |
| 36 */ | |
| 37 Object _jsObject; | |
| 38 | |
| 39 /* | |
| 40 * Retrieves the field of the given name. | |
| 41 * | |
| 42 * Returns the base JS representation of the object. | |
| 43 */ | |
| 44 Object getMember(String type, String fieldName) { | |
| 45 return JS(type, '#[#]', this._jsObject, fieldName); | |
| 46 } | |
| 47 | |
| 48 /* | |
| 49 * Sets the field of the given name to the given value. | |
| 50 * | |
| 51 * Attempts to convert the given value to JS before assignment. | |
| 52 */ | |
| 53 void setMember(String fieldName, Object value) { | |
| 54 JS('void', '#[#] = #', this._jsObject, fieldName, convertArgument(value)); | |
| 55 } | |
|
vsm
2013/01/23 20:44:50
I'm not sure it's worth having these helper method
sashab
2013/01/23 22:24:53
Is the type strongly enforced in the method signat
sashab
2013/01/24 22:21:33
The other reason I want to have it is this:
void
| |
| 56 } | |
| 57 | |
| 58 /** | |
| 59 * Useful functions for converting arguments. | |
| 60 */ | |
| 61 | |
| 62 /** | |
| 63 * Converts the given map-type argument to js-friendly format, recursively. | |
| 64 * Returns the new Map object. | |
| 65 */ | |
| 66 Object _convertMapArgument(Map argument) { | |
| 67 Map m = new Map(); | |
| 68 for (Object key in argument.keys) | |
| 69 m[key] = convertArgument(argument[key]); | |
| 70 return convertDartToNative_Dictionary(m); | |
| 71 } | |
| 72 | |
| 73 /** | |
| 74 * Converts the given list-type argument to js-friendly format, recursively. | |
| 75 * Returns the new List object. | |
| 76 */ | |
| 77 List _convertListArgument(List argument) { | |
| 78 List l = new List(); | |
| 79 for (var i = 0; i < argument.length; i ++) | |
| 80 l.add(convertArgument(argument[i])); | |
| 81 return l; | |
| 82 } | |
| 83 | |
| 84 /** | |
| 85 * Converts the given argument Object to js-friendly format, recursively. | |
| 86 * | |
| 87 * Flattens out all Chrome objects into their corresponding ._toMap() | |
| 88 * definitions, then converts them to JS objects. | |
| 89 * | |
| 90 * Returns the new argument. | |
| 91 * | |
| 92 * Cannot be used for functions. | |
| 93 */ | |
| 94 Object convertArgument(var argument) { | |
| 95 if (argument == null) | |
| 96 return argument; | |
| 97 | |
| 98 if (argument is num || argument is String || argument is bool) | |
| 99 return argument; | |
| 100 | |
| 101 if (argument is ChromeObject) | |
| 102 return argument._jsObject; | |
| 103 | |
| 104 if (argument is List) | |
| 105 return _convertListArgument(argument); | |
| 106 | |
| 107 if (argument is Map) | |
| 108 return _convertMapArgument(argument); | |
| 109 | |
| 110 if (argument is Function) | |
| 111 throw new Exception("Cannot serialize Function argument ${argument}."); | |
| 112 | |
| 113 // TODO(sashab): Try and detect whether the argument is already serialized. | |
| 114 return argument; | |
| 115 } | |
| 116 | |
| 117 /** | |
| 118 * Description of a declarative rule for handling events. | |
| 119 */ | |
| 120 class Rule extends ChromeObject { | |
| 121 /* | |
| 122 * Public (Dart) constructor | |
| 123 */ | |
| 124 Rule({String id, List conditions, List actions, int priority}) { | |
| 125 this.id = id; | |
| 126 this.conditions = conditions; | |
| 127 this.actions = actions; | |
| 128 this.priority = priority; | |
| 129 } | |
| 130 | |
| 131 /* | |
| 132 * Private (JS) constructor | |
| 133 */ | |
| 134 Rule._proxy(_jsObject) | |
| 135 : super._proxy(_jsObject); | |
| 136 | |
| 137 /* | |
| 138 * Public accessors | |
| 139 */ | |
| 140 String get id => | |
| 141 getMember('String', 'id'); | |
| 142 | |
| 143 void set id(String id) => | |
| 144 setMember('id', id); | |
| 145 | |
| 146 // TODO(sashab): Wrap these generic Lists somehow. | |
| 147 List get conditions => | |
| 148 getMember('List', 'conditions'); | |
| 149 | |
| 150 void set conditions(List conditions) => | |
| 151 setMember('conditions', conditions); | |
| 152 | |
| 153 // TODO(sashab): Wrap these generic Lists somehow. | |
| 154 List get actions => | |
| 155 getMember('List', 'actions'); | |
| 156 | |
| 157 void set actions(List actions) => | |
| 158 setMember('actions', actions); | |
| 159 | |
| 160 int get priority => | |
| 161 getMember('int', 'priority'); | |
| 162 | |
| 163 void set priority(int priority) => | |
| 164 setMember('priority', priority); | |
| 165 | |
| 166 } | |
| 167 | |
| 168 /** | |
| 169 * The Event class. | |
| 170 * | |
| 171 * Chrome Event classes extend this interface. | |
| 172 * | |
| 173 * e.g. | |
| 174 * | |
| 175 * // chrome.app.runtime.onLaunched | |
| 176 * class $Event_ChromeAppRuntimeOnLaunched extends $Event { | |
| 177 * // constructor, passing the arity of the callback | |
| 178 * $Event_ChromeAppRuntimeOnLaunched(jsObject) : | |
| 179 * super._(jsObject, 1); | |
| 180 * | |
| 181 * // methods, strengthening the Function parameter specificity | |
| 182 * void addListener(void callback(LaunchData launchData)) | |
| 183 * => super.addListener(callback); | |
| 184 * void removeListener(void callback(LaunchData launchData)) | |
| 185 * => super.removeListener(callback); | |
| 186 * bool hasListener(void callback(LaunchData launchData)) | |
| 187 * => super.hasListener(callback); | |
| 188 * } | |
| 189 * | |
| 190 */ | |
| 191 class $Event { | |
| 192 /* | |
| 193 * JS Object Representation | |
| 194 */ | |
| 195 Object _jsObject; | |
| 196 | |
| 197 /* | |
| 198 * Number of arguments the callback takes. | |
| 199 */ | |
| 200 int _callbackArity; | |
| 201 | |
| 202 /* | |
| 203 * Private constructor | |
| 204 */ | |
| 205 $Event._(this._jsObject, this._callbackArity); | |
| 206 | |
| 207 /* | |
| 208 * Methods | |
| 209 */ | |
| 210 | |
| 211 /** | |
| 212 * Registers an event listener <em>callback</em> to an event. | |
| 213 */ | |
| 214 void addListener(Function callback) => | |
| 215 JS('void', | |
| 216 '#.addListener(#)', | |
| 217 this._jsObject, | |
| 218 convertDartClosureToJS(callback, this._callbackArity) | |
| 219 ); | |
| 220 | |
| 221 /** | |
| 222 * Deregisters an event listener <em>callback</em> from an event. | |
| 223 */ | |
| 224 void removeListener(Function callback) => | |
| 225 JS('void', | |
| 226 '#.removeListener(#)', | |
| 227 this._jsObject, | |
| 228 convertDartClosureToJS(callback, this._callbackArity) | |
| 229 ); | |
| 230 | |
| 231 /** | |
| 232 * Returns True if <em>callback</em> is registered to the event. | |
| 233 */ | |
| 234 bool hasListener(Function callback) => | |
| 235 JS('bool', | |
| 236 '#.hasListener(#)', | |
| 237 this._jsObject, | |
| 238 convertDartClosureToJS(callback, this._callbackArity) | |
| 239 ); | |
| 240 | |
| 241 /** | |
| 242 * Returns true if any event listeners are registered to the event. | |
| 243 */ | |
| 244 bool hasListeners() => | |
| 245 JS('bool', | |
| 246 '#.hasListeners()', | |
| 247 this._jsObject | |
| 248 ); | |
| 249 | |
| 250 /** | |
| 251 * Registers rules to handle events. | |
| 252 * | |
| 253 * @param eventName Name of the event this function affects. | |
| 254 * @param rules Rules to be registered. These do not replace previously regist ered rules. | |
| 255 * @param callback Called with registered rules. | |
| 256 */ | |
| 257 void addRules(String eventName, List<Rule> rules, | |
| 258 [void callback(List<Rule> rules)]) { | |
| 259 // proxy the callback | |
| 260 void __proxy_callback(List rules) { | |
| 261 if (?callback) { | |
| 262 List<Rule> __proxy_rules = new List<Rule>(); | |
| 263 | |
| 264 for (Object o in rules) | |
| 265 __proxy_rules.add(new Rule._proxy(o)); | |
| 266 | |
| 267 callback(__proxy_rules); | |
| 268 } | |
| 269 } | |
| 270 | |
| 271 JS('void', | |
| 272 '#.addRules(#, #, #)', | |
| 273 this._jsObject, | |
| 274 convertArgument(eventName), | |
| 275 convertArgument(rules), | |
| 276 convertDartClosureToJS(__proxy_callback, 1) | |
| 277 ); | |
| 278 } | |
| 279 | |
| 280 /** | |
| 281 * Returns currently registered rules. | |
| 282 * | |
| 283 * @param eventName Name of the event this function affects. | |
| 284 * @param ruleIdentifiers If an array is passed, only rules with identifiers c ontained in this array are returned. | |
| 285 * @param callback Called with registered rules. | |
| 286 */ | |
| 287 void getRules(String eventName, [List<String> ruleIdentifiers, | |
| 288 void callback(List<Rule> rules)]) { | |
| 289 // proxy the callback | |
| 290 void __proxy_callback(List rules) { | |
| 291 if (?callback) { | |
| 292 List<Rule> __proxy_rules = new List<Rule>(); | |
| 293 | |
| 294 for (Object o in rules) | |
| 295 __proxy_rules.add(new Rule._proxy(o)); | |
| 296 | |
| 297 callback(__proxy_rules); | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 JS('void', | |
| 302 '#.getRules(#, #, #)', | |
| 303 this._jsObject, | |
| 304 convertArgument(eventName), | |
| 305 convertArgument(ruleIdentifiers), | |
| 306 convertDartClosureToJS(__proxy_callback, 1) | |
| 307 ); | |
| 308 } | |
| 309 | |
| 310 /** | |
| 311 * Unregisters currently registered rules. | |
| 312 * | |
| 313 * @param eventName Name of the event this function affects. | |
| 314 * @param ruleIdentifiers If an array is passed, only rules with identifiers c ontained in this array are unregistered. | |
|
Emily Fortuna
2013/01/23 19:28:04
80 char....
sashab
2013/01/23 22:24:53
Done.
| |
| 315 * @param callback Called when rules were unregistered. | |
| 316 */ | |
| 317 void removeRules(String eventName, [List<String> ruleIdentifiers, | |
| 318 void callback()]) => | |
| 319 JS('void', | |
| 320 '#.removeRules(#, #, #)', | |
| 321 this._jsObject, | |
| 322 convertArgument(eventName), | |
| 323 convertArgument(ruleIdentifiers), | |
| 324 convertDartClosureToJS(callback, 0) | |
| 325 ); | |
| 326 } | |
| 327 | |
| OLD | NEW |