blob: cc5ff253355b92e43672e7dbf6e2f025a7ae2a78 [file] [log] [blame]
// 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('oobe-screen', (function() {
/** @const */ var CALLBACK_USER_ACTED = 'userActed';
function doNothing() {};
return {
/**
* The login.Screen which is hosting |this|.
*/
screen_: null,
/**
* Dictionary of context observers that are methods of |this| bound to
* |this|.
*/
contextObservers_: null,
/**
* login.ScreenContext 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.
* TODO(dzhioev): make binding two-way.
*/
C: null,
/**
* Called when the screen is beeing registered.
*/
initialize: doNothing,
ready: function() {
if (this.decorate_) {
this.initialize();
} else {
this.ready_ = true;
}
},
userActed: function(_, _, source) {
this.send(CALLBACK_USER_ACTED, source.getAttribute('action'));
},
i18n: function(args) {
if (!(args instanceof Array))
args = [args];
args[0] = 'login_' + this.name + '_' + args[0];
return loadTimeData.getStringF.apply(loadTimeData, args);
},
/**
* Called by login.Screen when the screen is beeing registered.
*/
decorate: function(screen) {
this.screen_ = screen;
screen.initialize();
this.context = screen.screenContext_;
this.C = this.context.storage_;
this.contextObservers_ = {};
var self = this;
if (this.ready_) {
this.initialize();
} else {
this.decorate_ = true;
}
},
/**
* @final
*/
send: function() {
return this.sendImpl_.apply(this, arguments);
},
/**
* @final
*/
addContextObserver: function() {
return this.addContextObserverImpl_.apply(this, arguments);
},
/**
* @final
*/
removeContextObserver: function() {
return this.removeContextObserverImpl_.apply(this, arguments);
},
/**
* @final
*/
commitContextChanges: function() {
return this.commitContextChangesImpl_.apply(this, arguments);
},
/**
* @override
* @final
*/
querySelector: function() {
return this.querySelectorImpl_.apply(this, arguments);
},
/**
* @override
* @final
*/
querySelectorAll: function() {
return this.querySelectorAllImpl_.apply(this, arguments);
},
/**
* See login.Screen.send.
* @private
*/
sendImpl_: function() {
return this.screen_.send.apply(this.screen_, arguments);
},
/**
* 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_);
* ...
* this.removeContextObserver('key', this.onKeyChanged_);
* @private
*/
addContextObserverImpl_: 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
*/
removeContextObserverImpl_: 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);
},
/**
* See login.Screen.commitContextChanges.
* @private
*/
commitContextChangesImpl_: function() {
return this.screen_.commitContextChanges.apply(this.screen_, arguments);
},
/**
* Calls |querySelector| method of the shadow dom and returns the result.
* @private
*/
querySelectorImpl_: function(selector) {
return this.shadowRoot.querySelector(selector);
},
/**
* Calls standart |querySelectorAll| method of the shadow dom and returns
* the result converted to Array.
* @private
*/
querySelectorAllImpl_: function(selector) {
var list = this.shadowRoot.querySelectorAll(selector);
return Array.prototype.slice.call(list);
},
/**
* 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 '';
}
};
})());