Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Unified Diff: tools/dom/src/chrome/_utils.dart

Issue 12049030: Initial commit for Chrome.* APIs in Dart (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/dom/src/chrome/_utils.dart
diff --git a/tools/dom/src/chrome/_utils.dart b/tools/dom/src/chrome/_utils.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b28f31a4dcfe076d1b303437a0f59f2bfb700c87
--- /dev/null
+++ b/tools/dom/src/chrome/_utils.dart
@@ -0,0 +1,392 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
blois 2013/01/23 02:06:12 2013
sashab 2013/01/23 04:45:34 Done.
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
blois 2013/01/23 02:06:12 Normally we don't use leading _ for file names (at
sashab 2013/01/23 04:45:34 No worries; I can fix this.
+
+/**
+ * A set of utilities for use with the Chrome Extension APIs.
+ *
+ * Allows for easy access to required JS objects.
+ */
+part of chrome;
+
+/**
+ * A dart object, that is convertible to JS. Used for creating objects in dart,
+ * then passing them to JS.
+ *
+ * Objects that are passable to JS need to implement this interface.
+ */
+abstract class ChromeObject {
+ /*
+ * Default Constructor
+ *
+ * Called by child objects during their regular construction.
+ */
+ ChromeObject() :
+ _jsObject = null;
+
+ /*
+ * Internal proxy constructor
+ *
+ * Creates a new object using this existing proxy.
+ */
+ ChromeObject._proxy(this._jsObject);
+
+ /*
+ * JS Object Representation
+ */
+ Object _jsObject;
+
+ /*
+ * Return a Map representation of this object's members, non-recursively.
+ */
+ Map _toMap();
+
+ /*
+ * Return a non-recursive serialized representation of this object.
+ *
+ * Returns a Map representation, if this object has not yet been proxied,
+ * or the existing proxy, if it has already been proxied.
+ */
+ Object _serialize() {
+ if (_jsObject == null)
+ return this._toMap();
+ return _jsObject;
+ }
+
+ /*
+ * Returns True if this object has a matching JS object, False otherwise.
+ */
+ bool _hasProxy() {
+ return this._jsObject != null;
+ }
+}
+
+/**
+ * Useful functions for converting arguments.
+ */
+
+/**
+ * Converts the given map-type argument to js-friendly format, recursively.
+ * Returns the new Map object.
+ */
+Object _convertMapArgument(Map argument) {
+ Map m = new Map();
+ for (Object key in argument.keys)
+ m[key] = convertArgument(argument[key]);
+ return convertDartToNative_Dictionary(m);
+}
+
+/*
+Map _convertMapArgument(Map argument) {
+ var object = JS('var', '{}');
+ for (Object key in argument.keys)
+ JS('void', '#[#] = #', object, key, convertArgument(argument[key]));
+ return object;
+}
+ */
+
+/**
+ * Converts the given list-type argument to js-friendly format, recursively.
+ * Returns the new List object.
+ */
+List _convertListArgument(List argument) {
+ List l = new List();
+ for (var i = 0; i < argument.length; i ++)
+ l.add(convertArgument(argument[i]));
+ return l;
+}
+
+/**
+ * Converts the given argument Object to js-friendly format, recursively.
+ *
+ * Flattens out all Chrome objects into their corresponding ._toMap()
+ * definitions, then converts them to JS objects.
+ *
+ * Returns the new argument.
+ *
+ * Cannot be used for functions.
+ */
+Object convertArgument(var argument) {
+ if (argument == null)
+ return argument;
+
+ if (argument is num || argument is String || argument is bool)
+ return argument;
+
+ if (argument is ChromeObject)
+ return convertArgument(argument._serialize());
+
+ if (argument is List)
+ return _convertListArgument(argument);
+
+ if (argument is Map)
+ return _convertMapArgument(argument);
+
+ if (argument is Function)
+ throw new Exception("Cannot serialize Function argument ${argument}.");
+
+ // TODO(sashab): Try and detect whether the argument is already serialized.
+ return argument;
+}
+
+/**
+ * Description of a declarative rule for handling events.
+ */
+class Rule extends ChromeObject {
+ String _id;
+ List _conditions;
+ List _actions;
+ int _priority;
+
+ /*
+ * Public (Dart) constructor
+ */
+ Rule({
+ String id,
+ List conditions,
+ List actions,
+ int priority
+ }) :
+ _id = id,
+ _conditions = conditions,
+ _actions = actions,
+ _priority = priority
+ ;
+
+ /*
+ * Private (JS) constructor
+ */
+ Rule._proxy(_jsObject)
+ : super._proxy(_jsObject);
+
+ /*
+ * Serialisation method
+ */
+ Map _toMap() {
+ Map m = {};
+ if (id != null) m['id'] = id;
+ if (conditions != null) m['conditions'] = conditions;
+ if (actions != null) m['actions'] = actions;
+ if (priority != null) m['priority'] = priority;
+ return m;
+ }
+
+ /*
+ * Public accessors
+ */
+ String get id {
+ if (!this._hasProxy())
+ return this._id;
+ return JS('String', '#.id', this._jsObject);
+ }
+
+ void set id(String id) {
+ if (!this._hasProxy())
+ this._id = id;
+ else
+ JS('void', '#.id = #', this._jsObject, convertArgument(id));
+ }
+
+ List get conditions {
+ if (!this._hasProxy())
+ return this._conditions;
+ return JS('List', '#.conditions', this._jsObject);
+ }
+
+ void set conditions(List conditions) {
+ if (!this._hasProxy())
+ this._conditions = conditions;
+ else
+ JS('void', '#.conditions = #', this._jsObject, convertArgument(conditions));
blois 2013/01/23 02:06:12 line length
sashab 2013/01/23 04:45:34 Done, except for the comments on Events
+ }
+
+ List get actions {
+ if (!this._hasProxy())
+ return this._actions;
+ return JS('List', '#.actions', this._jsObject);
+ }
+
+ void set actions(List actions) {
+ if (!this._hasProxy())
+ this._actions = actions;
+ else
+ JS('void', '#.actions = #', this._jsObject, convertArgument(actions));
+ }
+
+ int get priority {
+ if (!this._hasProxy())
+ return this._priority;
+ return JS('int', '#.priority', this._jsObject);
+ }
+
+ void set priority(int priority) {
+ if (!this._hasProxy())
+ this._priority = priority;
+ else
+ JS('void', '#.priority = #', this._jsObject, convertArgument(priority));
+ }
+
+}
+
+/**
+ * The Event class.
+ *
+ * Chrome Event classes extend this interface.
+ *
+ * e.g.
+ *
+ * // chrome.app.runtime.onLaunched
+ * class $Event_ChromeAppRuntimeOnLaunched extends $Event {
blois 2013/01/23 02:06:12 For DOM events, we're moving them over to streams.
sashab 2013/01/23 04:45:34 We could change these to be streams later? Are the
+ * // constructor, passing the arity of the callback
+ * $Event_ChromeAppRuntimeOnLaunched(jsObject) :
+ * super._(jsObject, 1);
+ *
+ * // methods, strengthening the Function parameter specificity
+ * void addListener(void callback(LaunchData launchData))
+ * => super.addListener(callback);
+ * void removeListener(void callback(LaunchData launchData))
+ * => super.removeListener(callback);
+ * bool hasListener(void callback(LaunchData launchData))
+ * => super.hasListener(callback);
+ * }
+ *
+ */
+class $Event {
blois 2013/01/23 02:06:12 Why the leading $?
sashab 2013/01/23 04:45:34 To distinguish it from html:Event. Should I just c
Emily Fortuna 2013/01/23 19:28:04 I made a comment on this in another version of thi
sashab 2013/01/23 22:24:53 I guess I'm just worried because I'm importing dar
+ // JS var
+ Object _jsObject;
+
+ // number of arguments the callback takes
+ int _callbackArity;
+
+ // constructor
+ $Event._(this._jsObject, this._callbackArity);
+
+ // methods
+
+ /**
+ * Registers an event listener <em>callback</em> to an event.
+ */
+ void addListener(Function callback) =>
+ JS('void',
+ '#.addListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /**
+ * Deregisters an event listener <em>callback</em> from an event.
+ */
+ void removeListener(Function callback) =>
+ JS('void',
+ '#.removeListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /**
+ * Returns True if <em>callback</em> is registered to the event.
+ */
+ bool hasListener(Function callback) =>
+ JS('bool',
+ '#.hasListener(#)',
+ this._jsObject,
+ convertDartClosureToJS(callback, this._callbackArity)
+ );
+
+ /**
+ * Returns true if any event listeners are registered to the event.
+ */
+ bool hasListeners() =>
+ JS('bool',
+ '#.hasListeners()',
+ this._jsObject
+ );
+
+ /**
+ * Registers rules to handle events.
+ *
+ * @param eventName Name of the event this function affects.
blois 2013/01/23 02:06:12 Dart doesn't use JS-style param comments.
sashab 2013/01/23 04:45:34 These were taken from events.idl. Should I just re
+ * @param rules Rules to be registered. These do not replace previously registered rules.
+ * @param callback Called with registered rules.
+ */
+ void addRules(String eventName, List<Rule> rules, [ void callback(List<Rule> rules) ]) {
blois 2013/01/23 02:06:12 Usually no space between [ and arg- rules, [void
blois 2013/01/23 02:06:12 80 char line length (and more below)
sashab 2013/01/23 04:45:34 Done.
sashab 2013/01/23 04:45:34 Done (except for Event comments).
+ // proxy the callback
+ void __proxied_callback(List rules) {};
+
+ if (callback != null)
+ void __proxied_callback(List rules) {
+ List<Rule> __proxy_rules = new List<Rule>();
+
+ for (Object o in rules)
+ __proxy_rules.add(new Rule._proxy(o));
+
+ callback(__proxy_rules);
+ }
+
+ JS('void',
+ '#.addRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(rules),
+ convertDartClosureToJS(callback, 1)
+ );
+ }
+
+ /**
+ * Returns currently registered rules.
+ *
+ * @param eventName Name of the event this function affects.
+ * @param ruleIdentifiers If an array is passed, only rules with identifiers contained in this array are returned.
+ * @param callback Called with registered rules.
+ */
+ void getRules(String eventName, [ List<String> ruleIdentifiers, void callback(List<Rule> rules) ]) {
+ // proxy the callback
+ void __proxied_callback(List rules) {};
+
+ if (callback != null)
+ void __proxied_callback(List rules) {
+ List<Rule> __proxy_rules = new List<Rule>();
+
+ for (Object o in rules)
+ __proxy_rules.add(new Rule._proxy(o));
+
+ callback(__proxy_rules);
+ }
+
+ JS('void',
+ '#.getRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(ruleIdentifiers),
+ convertDartClosureToJS(callback, 1)
+ );
+ }
+
+ /**
+ * Unregisters currently registered rules.
+ *
+ * @param eventName Name of the event this function affects.
+ * @param ruleIdentifiers If an array is passed, only rules with identifiers contained in this array are unregistered.
+ * @param callback Called when rules were unregistered.
+ */
+ void removeRules(String eventName, [ List<String> ruleIdentifiers, void callback() ]) =>
+ JS('void',
+ '#.removeRules(#, #, #)',
+ this._jsObject,
+ convertArgument(eventName),
+ convertArgument(ruleIdentifiers),
+ convertDartClosureToJS(callback, 0)
+ );
+}
+
+
+
+
+
+
+
+
+
+
+
+

Powered by Google App Engine
This is Rietveld 408576698