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

Unified Diff: components/wug/resources/webui-view.js

Issue 928163002: Initial implementation of WebUI generator (WUG) toolkit. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Owners updated. Created 5 years, 10 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: components/wug/resources/webui-view.js
diff --git a/components/wug/resources/webui-view.js b/components/wug/resources/webui-view.js
new file mode 100644
index 0000000000000000000000000000000000000000..df64bce43f450f8101f6d0e7f83cad4b856398d2
--- /dev/null
+++ b/components/wug/resources/webui-view.js
@@ -0,0 +1,182 @@
+// Copyright (c) 2014 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.
+
+Polymer('webui-view', (function() {
+ /** @const */ var CALLBACK_EVENT_FIRED = 'eventFired';
+ /** @const */ var CALLBACK_CONTEXT_CHANGED = 'contextChanged';
+ /** @const */ var CALLBACK_READY = 'ready';
+
+ return {
+ /**
+ * Dictionary of context observers that are methods of |this| bound to
+ * |this|.
+ */
+ contextObservers_: null,
+
+ /**
+ * Full path to the element in views hierarchy.
+ */
+ path_: null,
+
+ /**
+ * Whether DOM is ready.
+ */
+ domReady_: false,
+
+ /**
+ * Context used for sharing data with native backend.
+ */
+ context: null,
+
+ /**
+ * Internal storage of |this.context|. Short name has been choosen for
Nikita (slow) 2015/02/24 15:22:42 nit: You can make this comment shorter since you'r
dzhioev (left Google) 2015/02/26 14:01:37 What do you mean? this.C and this.context are diff
Nikita (slow) 2015/02/26 14:18:20 I suggested removing reasoning for using short nam
dzhioev (left Google) 2015/03/02 11:02:30 Done.
+ * reason: such name doesn't take much space in HTML data bindings, which
+ * are used very often.
+ * C binded to the native part of the context, that means that all the
+ * changes in the native part appear in C automticaly. Reverse is not true,
Nikita (slow) 2015/02/26 14:18:20 nit: automatically
dzhioev (left Google) 2015/03/02 11:02:30 Done.
+ * you should use:
+ * this.context.set(...);
+ * this.context.commitContextChanges();
+ * to send updates to the native part.
+ * TODO(dzhioev): make binding two-way.
Nikita (slow) 2015/02/24 15:22:42 Since this is purely an optimization I suggest rem
dzhioev (left Google) 2015/02/26 14:01:37 Done. Removed comment.
+ */
+ C: null,
+
+ ready: function() {
+ this.context = new wug.Context;
+ this.C = this.context.storage_;
+ this.contextObservers_ = {};
+ },
+
+ /**
+ * One of element's lifecycle methods.
+ */
+ domReady: function() {
+ var id = this.getAttribute('wugid');
+ if (!id)
+ console.error('"wugid" attribute is missing.');
Nikita (slow) 2015/02/24 15:22:42 nit: Should you return here and do not initialize
dzhioev (left Google) 2015/02/26 14:01:37 Done.
+ if (id == 'WUG_ROOT') {
+ this.setPath_('WUG_ROOT');
+ }
+ this.domReady_ = true;
+ if (this.path_)
+ this.init_();
+ },
+
+ setPath_: function(path) {
+ this.path_ = path;
+ if (this.domReady_)
+ this.init_();
+ },
+
+ init_: function() {
+ this.initContext_();
+ this.initChildren_();
+ window[this.path_ + '$contextChanged'] =
+ this.onContextChanged_.bind(this);
+ this.initialize();
+ this.send(CALLBACK_READY);
+ },
+
+ fireEvent: function(_, _, source) {
+ this.send(CALLBACK_EVENT_FIRED, source.getAttribute('event'));
+ },
+
+ i18n: function(args) {
+ if (!(args instanceof Array))
+ args = [args];
+ args[0] = this.getType() + '$' + args[0];
+ return loadTimeData.getStringF.apply(loadTimeData, args);
+ },
+
+ /**
+ * Sends message to Chrome, adding needed prefix to message name. All
+ * arguments after |messageName| are packed into message parameters list.
+ *
+ * @param {string} messageName Name of message without a prefix.
+ * @param {...*} varArgs parameters for message.
+ * @private
+ */
+ send: function(messageName, varArgs) {
+ if (arguments.length == 0)
+ throw Error('Message name is not provided.');
+ var fullMessageName = this.path_ + '$' + messageName;
+ var payload = Array.prototype.slice.call(arguments, 1);
+ chrome.send(fullMessageName, payload);
+ },
+
+ /**
+ * Starts observation of property with |key| of the context attached to
+ * current screen. This method differs from "login.ScreenContext" in that
+ * it automatically detects if observer is method of |this| and make
+ * all needed actions to make it work correctly. So it's no need for client
+ * to bind methods to |this| and keep resulting callback for
+ * |removeObserver| call:
+ *
+ * this.addContextObserver('key', this.onKeyChanged_);
Nikita (slow) 2015/02/24 15:22:42 Not clear whether this example on how caller shoul
dzhioev (left Google) 2015/02/26 14:01:37 Done.
+ * ...
+ * this.removeContextObserver('key', this.onKeyChanged_);
+ * @private
+ */
+ addContextObserver: function(key, observer) {
+ var realObserver = observer;
+ var propertyName = this.getPropertyNameOf_(observer);
+ if (propertyName) {
+ if (!this.contextObservers_.hasOwnProperty(propertyName))
+ this.contextObservers_[propertyName] = observer.bind(this);
+ realObserver = this.contextObservers_[propertyName];
+ }
+ this.context.addObserver(key, realObserver);
+ },
+
+ /**
+ * Removes |observer| from the list of context observers. Supports not only
+ * regular functions but also screen methods (see comment to
+ * |addContextObserver|).
+ * @private
+ */
+ removeContextObserver: function(observer) {
+ var realObserver = observer;
+ var propertyName = this.getPropertyNameOf_(observer);
+ if (propertyName) {
+ if (!this.contextObservers_.hasOwnProperty(propertyName))
+ return;
+ realObserver = this.contextObservers_[propertyName];
+ delete this.contextObservers_[propertyName];
+ }
+ this.context.removeObserver(realObserver);
+ },
+
+ /**
+ * Sends recent context changes to C++ handler.
+ * @private
+ */
+ commitContextChanges: function() {
+ if (!this.context.hasChanges())
+ return;
+ this.send(CALLBACK_CONTEXT_CHANGED, this.context.getChangesAndReset());
+ },
+
+ /**
+ * Called when context changed on C++ side.
+ */
+ onContextChanged_: function(diff) {
+ var changedKeys = this.context.applyChanges(diff);
+ this.contextChanged(changedKeys);
+ },
+
+ /**
+ * If |value| is the value of some property of |this| returns property's
+ * name. Otherwise returns empty string.
+ * @private
+ */
+ getPropertyNameOf_: function(value) {
+ for (var key in this)
+ if (this[key] === value)
+ return key;
+ return '';
+ }
+ };
+})());
+

Powered by Google App Engine
This is Rietveld 408576698