# -*- Mode: Java; tab-width: 2; c-basic-offset: 2; -*- # # ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (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.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is mozilla.org Code. # # The Initial Developer of the Original Code is # Netscape Communications Corporation. # Portions created by the Initial Developer are Copyright (C) 1998 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Ben Goodger (Original Author) # # Alternatively, the contents of this file may be used under the terms of # either the GNU General Public License Version 2 or later (the "GPL"), or # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** # ... and so it came to pass that on the 4th day of June, A.D. 2003, this file # was excised of the cruel and unfortunate brace/indentation scheme perpetrated # upon it by the same author who now writes these words, some three years and # two months after the original act. Note that while cvs blame shifts like leaves # in the autumn breeze, by and large the responsibility for this code remains # with me. var wsm; // For panels displayed inside the main dialog, this value will be the child iframe // window. For panels displayed in sub-dialogs, those launched by panels of the main // dialog, this will be the sub dialog window. var gCurrentWindow = null; function nsWidgetStateManager (aFrameID) { this.dataManager = { /** Persisted Data Hash Table * Page_ID -> Element_ID -> Property -> Value **/ pageData: { }, setPageData: function (aPageTag, aDataObject) { this.pageData[aPageTag] = aDataObject; }, getPageData: function (aPageTag) { if (!(aPageTag in this.pageData)) this.pageData[aPageTag] = { }; if (!('elementIDs' in this.pageData[aPageTag])) this.pageData[aPageTag].elementIDs = new Object(); if (!('userData' in this.pageData[aPageTag])) this.pageData[aPageTag].userData = new Object(); return this.pageData[aPageTag]; }, setItemData: function (aPageTag, aItemID, aDataObject) { if (!(aPageTag in this.pageData)) this.pageData[aPageTag] = new Object(); this.pageData[aPageTag].elementIDs[aItemID] = aDataObject; }, getItemData: function (aPageTag, aItemID) { if (!(aItemID in this.pageData[aPageTag].elementIDs)) this.pageData[aPageTag].elementIDs[aItemID] = new Object(); return this.pageData[aPageTag].elementIDs[aItemID]; } } this.contentID = aFrameID; wsm = this; /** Element Handlers * Provides default get and set handler functions for supported * widgets. Clients can override or add new widgets. **/ this.handlers = { menulist: { get: wsm.get_Menulist, set: wsm.set_Menulist }, radiogroup: { get: wsm.get_Radiogroup, set: wsm.set_Radiogroup }, checkbox: { get: wsm.get_Checkbox, set: wsm.set_Checkbox }, textbox: { get: wsm.get_Textbox, set: wsm.set_Textbox }, listitem: { get: wsm.get_Listitem, set: wsm.set_Listitem }, data: { get: wsm.get_Data, set: wsm.set_Data }, default_handler: { get: wsm.get_Default, set: wsm.set_Default } } // extra attributes to scan and save. this.attributes = []; } nsWidgetStateManager.prototype = { get contentArea () { return window.frames[this.contentID]; }, savePageData: function (aPageTag, aWindow) { gCurrentWindow = aWindow || this.contentArea; if (!(aPageTag in this.dataManager.pageData)) return; if ("GetFields" in gCurrentWindow) { // save page data based on user supplied function in content area var dataObject = gCurrentWindow.GetFields(); if (dataObject) this.dataManager.pageData[aPageTag].userData = dataObject; } // Automatic element retrieval. This is done in two ways. // 1) if an element id array is present in the document, this is // used to build a list of elements to persist. <-- performant // 2) otherwise, all elements with "wsm_persist" set to true // are persisted <-- non-performant. var elements; if ("_elementIDs" in gCurrentWindow) { elements = []; for (var i = 0; i < gCurrentWindow._elementIDs.length; i++) { var elt = gCurrentWindow.document.getElementById(gCurrentWindow._elementIDs[i]); if (elt) elements[elements.length] = elt; else { // see bug #40329. People forget this too often, and it breaks Prefs dump("*** FIX ME: '_elementIDs' in '" + gCurrentWindow.location.href.split('/').pop() + "' contains a reference to a non-existent element ID '" + gCurrentWindow._elementIDs[i] + "'.\n"); } } } else elements = gCurrentWindow.document.getElementsByAttribute("wsm_persist", "true"); for (var ii = 0; ii < elements.length; ii++) { var elementID = elements[ii].id; var elementType = elements[ii].localName; // persist attributes var get_Func = (elementType in this.handlers) ? this.handlers[elementType].get : this.handlers.default_handler.get; this.dataManager.setItemData(aPageTag, elementID, get_Func(elementID)); } }, setPageData: function (aPageTag, aWindow) { gCurrentWindow = aWindow || this.contentArea; var pageData = this.dataManager.getPageData(aPageTag); if ("SetFields" in gCurrentWindow) gCurrentWindow.SetFields(pageData.userData) if (!('elementIDs' in pageData)) return; for (var elementID in pageData.elementIDs) { var element = gCurrentWindow.document.getElementById(elementID); if (element) { var elementType = element.localName; var set_Func = (elementType in this.handlers) ? this.handlers[elementType].set : this.handlers.default_handler.set; set_Func(elementID, pageData.elementIDs[elementID]); } } }, /** Widget Get/Set Function Implementations * These can be overridden by the client. **/ generic_Set: function (aElement, aDataObject) { if (aElement) { for (var property in aDataObject) { if (property == "localname") continue; if (!aDataObject[property] && typeof aDataObject[property] == "boolean") aElement.removeAttribute(property); else aElement.setAttribute(property, aDataObject[property]); } if (!aElement.getAttribute("disabled","true")) aElement.removeAttribute("disabled"); } }, generic_Get: function (aElement) { if (aElement) { var dataObject = new Object(); var wsmAttributes = aElement.getAttribute("wsm_attributes"); var attributes = wsm.attributes; // make a copy if (wsmAttributes != "") attributes.push(wsmAttributes.split(" ")); // modify the copy for (var i = 0; i < attributes.length; i++) dataObject[attributes[i]] = aElement.getAttribute(attributes[i]); dataObject.localname = aElement.localName; return dataObject; } return null; }, // set_Menulist: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); // set all generic properties wsm.generic_Set(element, aDataObject); // set menulist specific properties if ("value" in aDataObject) { try { element.value = aDataObject.value; } catch (ex) { dump(aElementID + ", ex: " + ex + "\n"); } } }, get_Menulist: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); // retrieve all generic attributes var dataObject = wsm.generic_Get(element); // retrieve all menulist specific attributes if (dataObject) { dataObject.value = element.getAttribute("value"); return dataObject; } return null; }, // set_Radiogroup: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); wsm.generic_Set(element, aDataObject); if ("value" in aDataObject) element.value = aDataObject.value; if ("disabled" in aDataObject) element.disabled = aDataObject.disabled; }, get_Radiogroup: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); var dataObject = wsm.generic_Get(element); if (dataObject) { dataObject.value = element.getAttribute("value"); return dataObject; } return null; }, // set_Textbox: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); wsm.generic_Set(element, aDataObject); }, get_Textbox: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); var dataObject = wsm.generic_Get(element); if (dataObject) { dataObject.value = element.value; return dataObject; } return null; }, // set_Checkbox: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); // Set generic properites. wsm.generic_Set(element, aDataObject); // Handle reversed boolean values. if ("checked" in aDataObject && element.hasAttribute("reversed")) element.checked = !aDataObject.checked; }, get_Checkbox: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); var dataObject = wsm.generic_Get(element); if (dataObject) { var checked = element.checked; dataObject.checked = element.getAttribute("reversed") == "true" ? !checked : checked; return dataObject; } return null; }, // set_Listitem: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); wsm.generic_Set(element, aDataObject); }, get_Listitem: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); var dataObject = wsm.generic_Get(element); if (dataObject) { if (element.getAttribute("type") == "checkbox") dataObject.checked = element.checked; return dataObject; } return null; }, // set_Data: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); wsm.generic_Set(element, aDataObject); if ("value" in aDataObject) element.setAttribute("value", aDataObject.value); }, get_Data: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); var dataObject = wsm.generic_Get(element); if (dataObject) { dataObject.value = element.getAttribute("value"); return dataObject; } return null; }, // set_Default: function (aElementID, aDataObject) { var element = gCurrentWindow.document.getElementById(aElementID); wsm.generic_Set(element, aDataObject); }, get_Default: function (aElementID) { var element = gCurrentWindow.document.getElementById(aElementID); var dataObject = wsm.generic_Get(element); return dataObject ? dataObject : null; } } # M:tHoF Greatest Hits Section (Append one line per edit): # it will be dark soon # MANOS MADE ME PERMANENT! # there is no way out of here # [The Master is] not dead as you know it. He is with us always.. # My name is Torgo, I take care of the place while the Master is away. # The car won't start