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

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: Comments addressed. 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..606ef6a548f9808477431654d8d789d294f7fe10
--- /dev/null
+++ b/components/wug/resources/webui-view.js
@@ -0,0 +1,189 @@
+// 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
+ * 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,
+ * you should use:
+ * this.context.set(...);
+ * this.context.commitContextChanges();
+ * to send updates to the native part.
+ */
+ 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.');
+ return;
+ }
+ 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. In contrast with "wug.Context.addObserver" this method
+ * can automatically detect if observer is method of |this| and make
+ * all needed actions to make it work correctly. So there is no need in
+ * binding method to |this| before adding it. For example, if |this| has
+ * a method |onKeyChanged_|, you can do:
+ *
+ * this.addContextObserver('key', this.onKeyChanged_);
+ * ...
+ * this.removeContextObserver('key', this.onKeyChanged_);
+ *
+ * instead of:
+ *
+ * this.keyObserver_ = this.onKeyChanged_.bind(this);
+ * this.addContextObserver('key', this.keyObserver_);
+ * ...
+ * this.removeContextObserver('key', this.keyObserver_);
+ *
+ * @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. Observer could be
+ * a method of |this| (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