[Cosmo-dev] Re: [commits-cosmo] (travis) [5050] * Get preferences
working again
Travis Vachon
travis at osafoundation.org
Thu Jul 12 16:48:17 PDT 2007
Whoops, this was for bug 9863.
On Jul 12, 2007, at 4:34 PM, svncheckin at osafoundation.org wrote:
> Revision
> 5050
> Author
> travis
> Date
> 2007-07-12 16:34:33 -0700 (Thu, 12 Jul 2007)
> Log Message
>
> * Get preferences working again
> * Update code that uses preferences to use deferreds so we can do
> the getPreference calls asynchronously
> * Make some tweaks to the menu code to get account browser
> preference working again
> Modified Paths
>
> cosmo/trunk/cosmo/src/main/resources/PimMessageResources.properties
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/preferences.js
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/settings.js
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/translators/eim.js
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/transport/Atom.js
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/ContentBox.js
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/menu.js
> Added Paths
>
> cosmo/trunk/cosmo/src/main/webapp/js/cosmo/util/deferred.js
> Diff
>
> Modified: cosmo/trunk/cosmo/src/main/resources/
> PimMessageResources.properties (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/resources/
> PimMessageResources.properties 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/resources/
> PimMessageResources.properties 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -358,4 +358,6 @@
> Dashboard.ListEntry.TriageLater=LATER
> Dashboard.ListEntry.TriageDone=DONE
>
> +Error.Deferred=Error in Deferred:
> +Error.Rendering=Error rendering {0}
>
> Modified: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/
> preferences.js (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/
> preferences.js 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/
> preferences.js 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -28,7 +28,9 @@
>
> this.setPreference = function(key, val){
> cosmo.app.pim.serv.setPreference(key, val);
> - cosmo.topics.publish
> (cosmo.topics.PreferencesUpdatedMessage, [{key:val}])
> + var preferences = {};
> + preferences[key] = val;
> + cosmo.topics.publish
> (cosmo.topics.PreferencesUpdatedMessage, [preferences])
> };
>
> this.deletePreference = function(key){
> Modified: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/
> settings.js (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/settings.js
> 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/account/settings.js
> 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -150,39 +150,43 @@
> // -------
> tabLabel = strings.advanced;
> tabContent = _createElem('div');
> - this.advancedForm = this.getAdvancedForm();
> - tabContent.appendChild(this.advancedForm);
> - tabs.push({ label: tabLabel, content: tabContent });
> -
> - // About Cosmo tab
> - // -------
> - tabLabel = strings.about;
> - var about = dojo.widget.createWidget("cosmo:About", {}, s,
> 'last');
> - s.removeChild(about.domNode); // Detach from the throwaway
> node
> - tabContent = about;
> - originalAboutBox = about;
> - tabs.push({ label: tabLabel, content: tabContent });
> -
> - var self = this; // For callback scope
> - // Submit button and default Enter-key action
> - var f = function () { self.submitSave.apply(self); };
> -
> - var b = null; // For dialog buttons
> - var c = null; // For dialog content area
> - c = dojo.widget.createWidget("cosmo:TabContainer", {
> - tabs: tabs }, s, 'last');
> - s.removeChild(c.domNode); // Detach from the throwaway node
> - o.content = c;
> - b = new cosmo.ui.button.Button({ text:_('App.Button.Close'),
> - width:60, small: true, handleOnClick: function () {
> - cosmo.app.hideDialog(); } });
> - o.btnsLeft = [b];
> - b = new cosmo.ui.button.Button({ text:_('App.Button.Save'),
> - width:60, small: true, handleOnClick: f });
> - o.btnsRight = [b];
> - o.defaultAction = f;
> -
> - cosmo.app.showDialog(o);
> + var advancedFormDeferred = this.getAdvancedForm();
> + advancedFormDeferred.addCallback(dojo.lang.hitch(this,
> function (advancedForm){
> + this.advancedForm = advancedForm;
> + tabContent.appendChild(this.advancedForm);
> + tabs.push({ label: tabLabel, content: tabContent });
> +
> + // About Cosmo tab
> + // -------
> + tabLabel = strings.about;
> + var about = dojo.widget.createWidget("cosmo:About",
> {}, s, 'last');
> + s.removeChild(about.domNode); // Detach from the
> throwaway node
> + tabContent = about;
> + originalAboutBox = about;
> + tabs.push({ label: tabLabel, content: tabContent });
> +
> + var self = this; // For callback scope
> + // Submit button and default Enter-key action
> + var f = function () { self.submitSave.apply(self); };
> +
> + var b = null; // For dialog buttons
> + var c = null; // For dialog content area
> + c = dojo.widget.createWidget("cosmo:TabContainer", {
> + tabs: tabs }, s, 'last');
> + s.removeChild(c.domNode); // Detach from the throwaway
> node
> + o.content = c;
> + b = new cosmo.ui.button.Button({ text:_
> ('App.Button.Close'),
> + width:60, small: true, handleOnClick: function () {
> + cosmo.app.hideDialog(); } });
> + o.btnsLeft = [b];
> + b = new cosmo.ui.button.Button({ text:_
> ('App.Button.Save'),
> + width:60, small: true, handleOnClick: f });
> + o.btnsRight = [b];
> + o.defaultAction = f;
> +
> + cosmo.app.showDialog(o);
> + }));
> + return advancedFormDeferred;
> }
> /**
> * Validate the form input and submit via XHR
> @@ -194,47 +198,62 @@
> // will give you spurious submissions
> if (this.focusedField) { return false; }
>
> - // Save preferences syncronously first
> + // save preferences asynchronously
> var prefs = {};
>
> prefs[cosmo.account.preferences.SHOW_ACCOUNT_BROWSER_LINK] =
> - this.advancedForm.showAccountBrowser.checked.toString();
> + this.advancedForm.showAccountBrowser.checked;
>
> + var setPreferencesDeferred = new dojo.Deferred();
> for (var pref in prefs){
> - cosmo.account.preferences.setPreference(pref, prefs
> [pref]);
> + // create new function and call immediately to define
> scope
> + var throwAway = function (){
> + // capture preference key in scope
> + var capturedPref = pref;
> + setPreferencesDeferred.addCallback(function () {
> + return cosmo.account.preferences.setPreference
> (capturedPref,
> + prefs[capturedPref]);
> + }
> + );
> + }();
> }
> -
> - // Validate the form input using each field's
> - // attached validators
> - var fieldList = this.fieldList;
> - // Validate fields with the attached validators
> - // and display any inline err messages
> - var err = cosmo.account.validateForm(this.detailsForm,
> fieldList, false);
> -
> - // No error -- submit updated account info via CMP
> - if (!err) {
> - var self = this;
> - // Same handler for both success and error -- IE throws a
> - // freakish '1223' HTTP code when server returns a
> successful
> - // 204 'No content'. Dojo's io.bind doesn't recognize
> that as
> - // success, so we have to examine status codes manually
> - var f = function (type, data, resp) {
> - self.handleAccountSave(type, data, resp); };
> - var hand = { handle: f };
> - var account = {};
> - // Create a hash from the form field values
> - for (var i = 0; i < fieldList.length; i++) {
> - var f = fieldList[i];
> - var val = this.detailsForm[f.elemName].value;
> - // Only include fields with values -- throw out
> - // the 'confirm' field
> - if (val && (f.elemName != 'confirm')) {
> - account[f.elemName] = val;
> + // Start preferences setting
> + setPreferencesDeferred.callback();
> +
> + setPreferencesDeferred.addCallback(dojo.lang.hitch(this,
> function () {
> + // Validate the form input using each field's
> + // attached validators
> + var fieldList = this.fieldList;
> + // Validate fields with the attached validators
> + // and display any inline err messages
> + var err = cosmo.account.validateForm(this.detailsForm,
> fieldList, false);
> +
> + // No error -- submit updated account info via CMP
> + if (!err) {
> + var self = this;
> + // Same handler for both success and error -- IE
> throws a
> + // freakish '1223' HTTP code when server returns a
> successful
> + // 204 'No content'. Dojo's io.bind doesn't
> recognize that as
> + // success, so we have to examine status codes
> manually
> + var f = function (type, data, resp) {
> + self.handleAccountSave(type, data, resp); };
> + var hand = { handle: f };
> + var account = {};
> + // Create a hash from the form field values
> + for (var i = 0; i < fieldList.length; i++) {
> + var f = fieldList[i];
> + var val = this.detailsForm[f.elemName].value;
> + // Only include fields with values -- throw out
> + // the 'confirm' field
> + if (val && (f.elemName != 'confirm')) {
> + account[f.elemName] = val;
> + }
> }
> + // Hand off to CMP
> + cosmo.cmp.modifyAccount(account, hand);
> }
> - // Hand off to CMP
> - cosmo.cmp.modifyAccount(account, hand);
> - }
> + }));
> +
> };
> /**
> * Handle both success and error responses from the CMP call
> @@ -282,25 +301,28 @@
> var form = _createElem('form');
> var div = _createElem('div');
> var nbsp = function () { return cosmo.util.html.nbsp(); };
> - var prefs = cosmo.account.preferences.getPreferences();
> - var checkedDefault = (prefs
> [cosmo.account.preferences.SHOW_ACCOUNT_BROWSER_LINK] == 'true');
> - var check = cosmo.util.html.createInput({ type: 'checkbox',
> - id: 'showAccountBrowser', name: 'showAccountBrowser',
> - value: '', checked: checkedDefault });
> -
> - div.appendChild(check);
> - div.appendChild(nbsp());
> - div.appendChild(nbsp());
> - div.appendChild(_createText(strings.advancedAccountBrowser));
> - form.appendChild(div);
> -
> - // BANDAID: Hack to get the checkbox into Safari's
> - // form elements collection
> - if (navigator.userAgent.indexOf('Safari') > -1) {
> - cosmo.util.html.addInputsToForm([check], form);
> - }
> -
> - return form;
> + var prefsDeferred =
> cosmo.account.preferences.getPreferences();
> + prefsDeferred.addCallback(function(prefs){
> + var checkedDefault = (prefs
> [cosmo.account.preferences.SHOW_ACCOUNT_BROWSER_LINK] == 'true');
> + var check = cosmo.util.html.createInput({ type:
> 'checkbox',
> + id: 'showAccountBrowser', name: 'showAccountBrowser',
> + value: '', checked: checkedDefault });
> +
> + div.appendChild(check);
> + div.appendChild(nbsp());
> + div.appendChild(nbsp());
> + div.appendChild(_createText
> (strings.advancedAccountBrowser));
> + form.appendChild(div);
> +
> + // BANDAID: Hack to get the checkbox into Safari's
> + // form elements collection
> + if (navigator.userAgent.indexOf('Safari') > -1) {
> + cosmo.util.html.addInputsToForm([check], form);
> + }
> +
> + return form;
> + });
> + return prefsDeferred;
> };
>
>
> Modified: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/
> translators/eim.js (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/translators/
> eim.js 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/translators/
> eim.js 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -264,6 +264,9 @@
> var key = keyEl.firstChild.nodeValue;
> var valueEl = this.getChildrenByClassName(xml, "value")[0];
> var value = valueEl.firstChild.nodeValue;
> +
> + // A little type converting
> + if (value == "false") value = false;
> return [key,value];
> },
>
> Modified: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/
> transport/Atom.js (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/transport/
> Atom.js 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/service/transport/
> Atom.js 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -281,6 +281,7 @@
> }
> return this.bind(
> {
> + contentType: "application/atom+xml",
> url: url,
> postContent: postContent,
> method: method
> Modified: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/
> ContentBox.js (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/ContentBox.js
> 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/ContentBox.js
> 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -15,7 +15,8 @@
> */
>
> dojo.provide("cosmo.ui.ContentBox");
> -
> +dojo.require("cosmo.util.deferred");
> +dojo.require("dojo.Deferred");
> // Generic content container class
> // ==============================
> cosmo.ui.ContentBox = function (p) {
> @@ -92,13 +93,19 @@
> for (var n in params) { this[n] = params[n]; }
> };
> cosmo.ui.ContentBox.prototype.render = function () {
> + var renderDeferred;
> if (typeof this.renderSelf == 'function') {
> - this.renderSelf();
> + renderDeferred = this.renderSelf();
> };
> - var ch = this.children;
> - for (var i = 0; i < ch.length; i++) {
> - ch[i].render();
> + if (!(renderDeferred instanceof dojo.Deferred)){
> + renderDeferred = cosmo.util.deferred.getFiredDeferred
> (renderDeferred);
> }
> + renderDeferred.addCallback(dojo.lang.hitch(this, function () {
> + var ch = this.children;
> + for (var i = 0; i < ch.length; i++) {
> + ch[i].render();
> + }
> + }));
> };
> cosmo.ui.ContentBox.prototype.addChild = function (c) {
> this.children.push(c);
> Modified: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/menu.js
> (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/menu.js
> 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/ui/menu.js
> 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -29,27 +29,41 @@
> dojo.require('cosmo.account.settings');
> dojo.require('cosmo.account.create');
> dojo.require("cosmo.ui.ContentBox");
> +dojo.require("cosmo.util.deferred");
>
> cosmo.ui.menu = new function () {
> var self = this;
> - this.items = new cosmo.util.hash.Hash();
> + this.items = null;
> + // A copy of the preferences, we need to watch the
> PreferencesUpdatedMessage topic
> + // to make sure we keep this up to date
> + this.preferences = {};
> this.init = function () {
> - this.loadItems();
> + return this.loadItems();
> }
> - this.loadItems = function () {
> - var _c = cosmo.ui.menu.MenuItem;
> - var items = cosmo.ui.menu.allItems;
> - var prefs = cosmo.app.initParams.authAccess?
> - cosmo.account.preferences.getPreferences() : {};
> - // Instantiate all the items as MenuItem obj
> - for (var i = 0; i < items.length; i++) {
> - var item = items[i];
> - if (this.itemShownInDisplayMode(item,
> this.calculateDisplayMode()) &&
> - this.userHasRequiredRolesForItem(item) &&
> - this.userHasRequiredPrefForItem(item, prefs)) {
> - this.items.addItem(items[i].id, new _c(items[i]));
> + this.loadItems = function (dontReloadPrefs) {
> + var prefsDeferred = (cosmo.app.initParams.authAccess && !
> dontReloadPrefs)?
> + cosmo.account.preferences.getPreferences() :
> + cosmo.util.deferred.getFiredDeferred();
> +
> + prefsDeferred.addCallback(dojo.lang.hitch(this, function
> (prefs) {
> + if (prefs){
> + this.preferences = prefs;
> }
> - }
> + var items = cosmo.ui.menu.allItems;
> + this.items = new cosmo.util.hash.Hash();
> + // Instantiate all the items as MenuItem obj
> + for (var i = 0; i < items.length; i++) {
> + var item = items[i];
> + if (this.itemShownInDisplayMode(item,
> this.calculateDisplayMode()) &&
> + this.userHasRequiredRolesForItem(item) &&
> + this.userHasRequiredPrefForItem(item)) {
> +
> + this.items.addItem(item.id, new
> cosmo.ui.menu.MenuItem(item));
> + }
> + }
> + }));
> + cosmo.util.deferred.addStdErrback(prefsDeferred);
> + return prefsDeferred;
> };
>
> this.calculateDisplayMode = function(){
> @@ -73,10 +87,10 @@
> }
> return true;
> };
> - this.userHasRequiredPrefForItem = function (item, prefs) {
> + this.userHasRequiredPrefForItem = function (item) {
> var pref = item.requiredPref;
> if (pref) {
> - return !!(prefs[pref]);
> + return !!(this.preferences[pref]);
> }
> else {
> return true;
> @@ -132,8 +146,8 @@
> window.open(cosmo.ui.menu.urls.ACCOUNT_BROWSER);
> e.preventDefault(); },
> urlString: cosmo.ui.menu.urls.ACCOUNT_BROWSER,
> displayMode: cosmo.ui.menu.displayModes.AUTH,
> - requiredRoles: [cosmo.ui.menu.requiredRoles.USER]
> - //requiredPref:
> cosmo.account.preferences.SHOW_ACCOUNT_BROWSER_LINK
> + requiredRoles: [cosmo.ui.menu.requiredRoles.USER],
> + requiredPref:
> cosmo.account.preferences.SHOW_ACCOUNT_BROWSER_LINK
> },
> { id: 'signupMenuItem',
> displayText: _('Main.SignUp'),
> @@ -176,6 +190,8 @@
> this.displayMode = '';
> this.requiredRoles = [];
> this.requiredPref = null;
> + this.subscribeTo = {};
> + this.span = null;
> // Note that yes, there are sometimes that you want
> // *both* an onclickFunc and a urlString -- example
> // is opening something in a new window where you
> @@ -186,7 +202,12 @@
> // after exec'ing the function
> this.onclickFunc = null;
> this.urlString = '';
> + this.show = function (){this.span.style.display =
> this.divider.style.display = 'inline';};
> + this.hide = function (){this.span.style.display =
> this.divider.style.display = 'none';};
> for (var n in params) { this[n] = params[n]; }
> + for (topic in this.subscribeTo){
> + dojo.event.topic.subscribe(topic, dojo.lang.hitch(this,
> this.subscribeTo[topic]));
> + }
> };
>
> cosmo.ui.menu.MainMenu = function (p) {
> @@ -217,6 +238,7 @@
> this.appendItem = function (item, lastItem) {
> var s = this.createItem(item, lastItem);
> this.domNode.appendChild(s);
> + item.span = s;
> var s = _createElem('span');
> s.className = 'menuBarDivider';
> s.appendChild(cosmo.util.html.nbsp());
> @@ -225,27 +247,52 @@
> }
> s.appendChild(cosmo.util.html.nbsp());
> this.domNode.appendChild(s);
> + item.divider = s;
> };
> this.insertItem = function (item, referenceItem) {
>
> };
> this.renderSelf = function () {
> + var initDeferred;
> if (!this.hasBeenRendered) {
> - cosmo.ui.menu.init();
> - this.hasBeenRendered = true;
> + initDeferred = cosmo.ui.menu.init();
> + initDeferred.addCallback(
> + dojo.lang.hitch(this,
> + function () {
> + this.hasBeenRendered = true;
> + }
> + )
> +
> + );
> + } else {
> + initDeferred = cosmo.util.deferred.getFiredDeferred();
> }
> - this.clearAll();
> - // Render menu according to loaded items
> - var items = cosmo.ui.menu.items;
> - var last = (items.length - 1);
> - for (var i = 0; i < items.length; i++) {
> - var item = items.getAtPos(i);
> - var lastItem = i == last;
> - this.appendItem(item, lastItem);
> - }
> - this.setPosition();
> +
> + initDeferred.addCallback(dojo.lang.hitch(this, function () {
> + this.clearAll();
> + // Render menu according to loaded items
> + var items = cosmo.ui.menu.items;
> + var last = (items.length - 1);
> + for (var i = 0; i < items.length; i++) {
> + var item = items.getAtPos(i);
> + var lastItem = i == last;
> + this.appendItem(item, lastItem);
> + }
> + this.setPosition();
> + }));
> + cosmo.util.deferred.addStdErrback(initDeferred, _
> ("Error.Rendering", this))
> + return initDeferred;
> }
> for (var n in params) { this[n] = params[n]; }
> + dojo.event.topic.subscribe
> (cosmo.topics.PreferencesUpdatedMessage.topicName,
> + dojo.lang.hitch(this, function (message) {
> + for (var pref in message.preferences){
> + cosmo.ui.menu.preferences[pref]
> = message.preferences[pref];
> + }
> + cosmo.ui.menu.loadItems(true);
> + this.renderSelf();
> + }));
> +
> };
> cosmo.ui.menu.MainMenu.prototype =
> new cosmo.ui.ContentBox();
> Added: cosmo/trunk/cosmo/src/main/webapp/js/cosmo/util/deferred.js
> (5049 => 5050)
>
> --- cosmo/trunk/cosmo/src/main/webapp/js/cosmo/util/deferred.js
> 2007-07-12 22:33:12 UTC (rev 5049)
> +++ cosmo/trunk/cosmo/src/main/webapp/js/cosmo/util/deferred.js
> 2007-07-12 23:34:33 UTC (rev 5050)
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2007 Open Source Applications Foundation
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions
> and
> + * limitations under the License.
> + */
> +
> +dojo.provide("cosmo.util.deferred");
> +
> +cosmo.util.deferred = {
> + getFiredDeferred: function (result){
> + var d = new dojo.Deferred();
> + d.callback(result);
> + return d;
> + },
> +
> + addStdErrback: function (deferred, msg){
> + deferred.addErrback(function (e){
> + dojo.debug(msg || _("Error.Deferred"));
> + dojo.debug(e);
> + });
> + }
> +}
> \ No newline at end of file
>
> _______________________________________________
> Commits-Cosmo mailing list
> Commits-Cosmo at osafoundation.org
> http://lists.osafoundation.org/cgi-bin/mailman/listinfo/commits-cosmo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osafoundation.org/pipermail/cosmo-dev/attachments/20070712/ade48f7a/attachment.htm
More information about the cosmo-dev
mailing list