home *** CD-ROM | disk | FTP | other *** search
- XB.UI = {
- consts: {
- STR_XUL_NS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
- STR_HTML_NS: "http://www.w3.org/1999/xhtml"
- }
- };
-
- XB.UIElementsCollection = function() {
- this._widgets = {__proto__: null};
- }
-
- XB.UIElementsCollection.prototype = {
- put: function(widgetInstanceId, elementId, comment, nodes) {
- var widget = this._widgets[widgetInstanceId] || (this._widgets[widgetInstanceId] = {__proto__: null});
- widget[elementId] = {comment: comment, nodes: nodes};
- },
-
- get: function(widgetInstanceId, elementId) {
- return this._widgets[widgetInstanceId][elementId];
- },
-
- remove: function(widgetInstanceId, elementId) {
- delete this._widgets[widgetInstanceId][elementId];
- },
-
- finalize: function() {
- for (var instance in this._widgets) {
- var widget = this._widgets[instance];
- for (var element in widget)
- delete widget[element];
- delete this._widgets[instance];
- }
- },
-
- _widgets: null
- }
-
- XB.UI.Builder = function(windowEngine, overlayController) {
- this._xid = XB._base.genXULBuilderID();
- this._logger = XB._base.application.core.Log4Moz.repository.getLogger(XB._base.loggersRoot + ".UI" + this._xid);
- this._windowEngine = windowEngine;
- this._collection = new XB.UIElementsCollection();
- this._overlayController = overlayController;
- this._fullWidgetItemIDPattern = new RegExp(XB._base.application.name + "\\.xb\\-(.+)\\-inst\\-(.+)");
- this.deaf = false;
-
- this._logger.debug("Constructing");
- }
-
- XB.UI.Builder.prototype = {
- registerExtActionsHelper: function UIBuilder_registerExtActionsHelper(handler) {
- if ( handler && (typeof handler.handleXBAction == "function") )
- this._extActionHandler = handler;
- else
- throw new TypeError("Provided helper does not support needed interface");
- },
-
- unregisterExtActionsHelper: function UIBuilder_registerExtActionsHelper(handler) {
- if (handler && this._extActionHandler === handler)
- this._extActionHandler = null;
- },
-
- build: function UIBuilder_build(element, container, widgetInstanceId) {
- try {
- var elements = element.childNodes,
- document = container.ownerDocument;
-
- var child = null;
- while (child = container.firstChild)
- container.removeChild(child);
-
- var nodes = this._constructElements(elements, document, widgetInstanceId);
- for (let i = 0; i < nodes.length; i++) {
- let node = nodes[i];
- if (node instanceof Ci.nsIDOMAttr)
- container.behaviour.setAttribute(node.localName, node.nodeValue);
- else
- container.appendChild(node);
- }
- }
- catch (e) {
- this._logger.error("Couldn't build XB element " + element.nodeName + ". " + misc.formatError(e));
- this._logger.debug(e.stack);
- }
- },
-
- finalize: function UIBuilder_finalize() {
- this._collection.finalize();
-
- },
-
- handleDataChange: function UIBuilder_handleDataChange(widgetInstanceId, elementId, value) {
- this._logger.trace("handleDataChange: " + [widgetInstanceId, elementId, value]);
-
- var item = this._collection.get(widgetInstanceId, elementId),
- nodes = item.nodes,
- comment = item.comment;
-
- for (var i = nodes.length; i--;) {
- let node = nodes[i];
- if (node) {
- /*if (node instanceof Ci.nsIDOMAttr) {
- let owner = node.ownerElement;
- if (owner) {
- owner.behaviour.setAttribute(node.localName, null);
- }
- }
- else */{
- let parent = node.parentNode;
- if (parent) {
- parent.removeChild(node);
- }
- }
- }
- }
-
- if (!comment.parentNode) {
- this.unsubscribe(widgetInstanceId, elementId);
- return;
- }
-
-
- nodes = this._constructComputedElement(widgetInstanceId, elementId, value, comment.ownerDocument);
-
- this._collection.put(widgetInstanceId, elementId, comment, nodes);
-
- for each (let node in nodes) {
- if (node instanceof Ci.nsIDOMAttr)
- comment.parentNode.behaviour.setAttribute(node.localName, node.nodeValue);
- else
- comment.parentNode.insertBefore(node, comment);
- }
- },
-
- unsubscribe: function UIBuilder_unsubscribe(widgetInstanceId, elementId) {
- this._logger.trace("Builder::unsubscribe: " + [widgetInstanceId, elementId]);
-
- this._windowEngine.valueNotNeeded(widgetInstanceId, elementId);
- this._collection.remove(widgetInstanceId, elementId);
- },
-
- dispatchCommands: function UIBuilder_dispatchCommands(WIID, commandsArray, eventInfo) {
- for each (let command in commandsArray) {
- try {
- this._windowEngine.perform(WIID, command, eventInfo);
- }
- catch (e) {
- try {
- if (e instanceof XB.WindowEngine.ENoActionHandler) {
- if (!this._extActionHandler)
- throw new XB.WindowEngine.ENoActionHandler("Extened actions handler is not registered");
- this._extActionHandler.handleXBAction(WIID, command);
- }
- else
- throw e;
- }
- catch (e) {
- this._logger.error("Error running action " + [WIID, command].join(":") + ". " +
- misc.formatError(e) );
- this._logger.debug(e.stack);
- break;
- }
- }
- }
- },
-
- cleanNode: function UIBuilder_cleanNode(node) {
- if (!node)
- return;
- var node = node.firstChild;
- while (node) {
- if ((node.nodeType == node.ELEMENT_NODE) && !node.behaviour)
- this.cleanNode(node);
- var next = node.nextSibling;
- this.removeNode(node);
- node = next;
- }
- },
-
- removeNode: function UIBuilder_removeNode(node) {
- if (node && node.parentNode)
- node.parentNode.removeChild(node);
- },
-
- resolveURI: function UIBuilder_resolveURI(spec, widgetInstanceId) {
- if (!spec)
- return "";
-
- if (!(/^http(s)?:\/\//i.test(spec) || spec.indexOf("data:image/") == 0))
- spec = this._windowEngine.getWidget(widgetInstanceId).prototype.unit.unitPackage.resolvePath(spec);
-
- var uri = sysutils.createFixupURIFromString(spec);
- return uri ? uri.spec : "";
- },
-
- get controller() {
- return this._overlayController;
- },
-
- handleEvent: function UIBuilder_handleEvent(event) {
- if (!(event instanceof Ci.nsIDOMEvent && event.isTrusted === true))
- return;
- switch (event.type) {
- case "DOMNodeInserted":
- this.onInserted(event);
- break;
- case "DOMNodeRemoved":
- this.onRemoved(event);
- break;
- }
- },
-
- _xid: undefined,
- _logger: null,
- _windowEngine: null,
- _collection: null,
- _overlayController: null,
- _fullWidgetItemIDPattern: null,
- _extActionHandler: null,
- deaf: undefined,
-
-
- _constructElements: function UIBuilder_constructElements(elements, document, widgetInstanceId) {
- var length = elements.length,
- nodes = [];
-
- for (let i = 0; i < length; i++) {
- let element = elements[i];
-
- switch (element.nodeType) {
- case element.TEXT_NODE:
- nodes = nodes.concat(this._constructTextElement(element.nodeValue, document));
- break;
-
- case element.ELEMENT_NODE:
- if (element.namespaceURI == XB._base.consts.STR_UI_NS) {
- switch (element.localName) {
- case XB._base.consts.STR_VAL_REF_ELEM_NAME: {
- let elementId = element.getUserData(XB._base.consts.STR_VAL_REF_ID_KEY_NAME);
- if (!elementId) {
- this._logger.warn("No value reference ID found @" + element.nodeName);
- this._logger.debug(XB._base.runtime.serializeXML(element));
- continue;
- }
- let value = this._windowEngine.getValue(widgetInstanceId, elementId);
- let computed = this._constructComputedElement(widgetInstanceId, elementId, value, document);
-
- nodes = nodes.concat(computed);
- let comment = document.createComment("xb.computed");
- new XB.UI.Behaviour.Computed(comment, element, widgetInstanceId, this);
-
- nodes.push(comment);
- this._collection.put(widgetInstanceId, elementId, comment, computed);
-
- this._logger.trace("Builder::subscribe: " + [widgetInstanceId, elementId, value]);
-
- break;
- }
- default:
- nodes = nodes.concat(this._constructStaticElement(element, widgetInstanceId, document));
- }
- }
- break;
- }
- }
-
- return nodes;
- },
-
- _importAttrs: function UIBuilder_importAttrs(attributesMap, document) {
- var result = [];
- for (let i = 0, len = attributesMap.length; i < len; i++) {
- result.push( document.importNode(attributesMap.item(i), false) );
- }
- return result;
- },
-
- _constructTextElement: function UIBuilder_constructTextElement(text, document) {
- if (typeof text != 'string')
- text = text.toString();
- text = sysutils.normalizeString(text);
- if (text.length > 0) {
- var node = document.createTextNode(text);
- return [node];
- } else {
- return [];
- }
- },
-
- _constructStaticElement: function UIBuilder_constructStaticElement(element, widgetInstanceId, document) {
- var role = element.localName;
- var behaviour = XB.UI.Elements[role];
- if (behaviour) {
- var comment = document.createComment("xb.static role: " + role);
- new behaviour(comment, element, widgetInstanceId, this);
- return [comment];
- }
- else
- this._logger.warn("Unknown UI element " + role);
-
- return [];
- },
-
- _constructComputedElement: function UIBuilder_constructComputedElement(widgetInstanceId, elementId, value, document) {
- var nodes = [];
- if (XB._base.runtime.isXML(value)) {
- nodes = this._constructElements(value.childNodes, document, widgetInstanceId);
- nodes = nodes.concat(this._importAttrs(value.attributes, document));
- } else {
- let text = "";
- if (XB._base.runtime.isException(value)) {
- this._logger.debug("Got exception value: " + value.toString());
- }
- else {
- try {
- text = XB._base.runtime.xToString(value);
- }
- catch (e) {
- this._logger.error("Failed converting XValue into a string. " + misc.formatError(e));
- }
- nodes = nodes.concat(this._constructTextElement(text, document));
- }
- }
-
- return nodes;
- }
- };