1 /*global loadScript, Configuration */
8 * This class provides unified way to access available themes, detection of theme changes and method of updating selected theme. This component is usually initialized by
9 * {{#crossLink "Bootstrap"}}{{/crossLink}} class and can be later accessed using {{#crossLink "Bootstrap/themeEngine:property"}}{{/crossLink}} object. Component uses
10 * {{#crossLink "Configuration"}}{{/crossLink}} class to persist selected theme in key specified by {{#crossLink "ThemeEngine/selectedThemeKey:property"}}{{/crossLink}}.
12 * List of available themes is stored in {{#crossLink "ThemeEngine/_themes:property"}}{{/crossLink}} property; new theme can be set using
13 * {{#crossLink "ThemeEngine/setUserTheme:method"}}{{/crossLink}} method.
15 * To attach to signal indicating update of currencly selected theme use {{#crossLink "ThemeEngine/addStatusListener:method"}}{{/crossLink}} method, e.g.:
17 * var listenerId = bootstrap.themeEngine.addStatusListener(function(themeId) {
18 * // Process theme update
25 var ThemeEngine = (function() {
27 function ThemeEngine() {
28 console.info("Starting up service ThemeEngine");
32 * Defines configuration property storing currently selected theme.
33 * @property selectedThemeKey
36 ThemeEngine.prototype.selectedThemeKey = "selectedTheme";
39 * Contains array of attached callbacks.
40 * @property _reloadCallbacks
44 ThemeEngine.prototype._reloadCallbacks = [];
47 * Contains array of available themes.
52 ThemeEngine.prototype._themes = [
54 "id": "http://com.intel.tizen/blue",
57 "version": "0.5.1354227499444",
60 "iconUrl": "./css/user/blue/icon.png",
63 "id": "http://com.intel.tizen/green",
64 "name": "Green theme",
68 "iconUrl": "./css/user/green/icon.png",
74 * This method initialize theme engine from configuration object and loads default theme.
76 * @param callback {function(error)} Callback function called after method is finished. Parameter `error` will contain any error that was intercepted.
78 ThemeEngine.prototype.init = function(aCallback) {
81 loadScript('./css/car/components/configuration/configuration.js', function (path, status) {
82 if (status === "ok") {
83 var storedTheme = Configuration.get("selectedTheme");
84 self._injectHeaders(storedTheme, function() {
85 self._updateSelectedTheme();
87 Configuration.addUpdateListener(function() {
88 var id = Configuration.get("selectedTheme");
89 var selectedTheme = self.getSelectedTheme();
90 if (!selectedTheme || selectedTheme.id !== id) {
91 self._injectHeaders(id, function() {
92 self._updateSelectedTheme();
94 $(self._reloadCallbacks).each(function() {
110 * Method adds update listener which is fired after theme is changed.
111 * @method addStatusListener
112 * @param callback {function()} Callback to be invoked after theme is changed.
113 * @return {Integer} ID that can be used for removal of status listener.
115 ThemeEngine.prototype.addStatusListener = function(callback) {
116 this._reloadCallbacks.push(callback);
119 ThemeEngine.prototype._updateSelectedTheme = function () {
120 var selectedTheme = Configuration.get(this.selectedThemeKey);
122 for(var i = 0; i < this._themes.length; i++) {
123 this._themes[i].selected = this._themes[i].id === Configuration.get(this.selectedThemeKey);
128 * Method executes callback method with array of available themes as parameter.
129 * @method getUserThemes
130 * @param callback {function(themes)} Callback with array of available themes.
132 ThemeEngine.prototype.getUserThemes = function(callback) {
134 window.setTimeout(function() {
135 callback(self._themes);
140 * Method sets new user theme identified by theme ID in case that this theme isn't currently selected.
141 * @method setUserTheme
142 * @param id {String} ID of theme that should be set.
144 ThemeEngine.prototype.setUserTheme = function(id) {
145 var prevTheme = Configuration.get("selectedTheme");
146 id = id || prevTheme;
147 id = id || "http://com.intel.tizen/blue";
149 if(prevTheme !== id) {
150 Configuration.set(this.selectedThemeKey, id);
155 * Method returns information about one user theme identified by theme ID.
156 * @method getSelectedTheme
157 * @param id {String} ID of theme that should be set.
159 ThemeEngine.prototype.getSelectedTheme = function() {
160 for(var i = 0; i < this._themes.length; ++i) {
161 if (this._themes[i].selected) {
162 return this._themes[i];
168 ThemeEngine.prototype._injectHeaders = function(id, callback) {
169 callback = callback || function() {};
172 $(this._themes).each(function() {
174 //remove all previous theme .js
175 $('script[src="./css/user/' + theme._dir + '/user.js"]').remove();
177 if (theme.id === id) {
178 $("head > *").each(function() {
179 if ($(this).data("theme") === "user") {
184 $('<link data-theme="user" rel="stylesheet" href="./css/user/' + theme._dir + '/user.css" />').appendTo("head");
186 loadScript('./css/user/' + theme._dir + '/user.js', function(aPath, aStatus) {
187 if (aStatus === "ok") {
195 window.__themeengine = undefined === window.__themeengine ? new ThemeEngine() : window.__themeengine;
196 return window.__themeengine;