| 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 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 Object _jsObject; |
| 174 |
| 175 /* |
| 176 * Number of arguments the callback takes. |
| 177 */ |
| 178 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) { |
| 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) { |
| 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 |