1 /* See license.txt for terms of usage */
  2 
  3 FBL.ns(function() { with (FBL) {
  4 
  5 // ************************************************************************************************
  6 // Constants
  7 
  8 // List of XML related content types.
  9 var xmlContentTypes =
 10 [
 11     "text/xml",
 12     "application/xml",
 13     "application/xhtml+xml",
 14     "application/rdf+xml",
 15     "application/vnd.mozilla.xul+xml",
 16 ];
 17 
 18 // ************************************************************************************************
 19 // Model implementation
 20 
 21 /**
 22  * @module Implements viewer for XML based network responses. In order to create a new
 23  * tab wihin network request detail, a listener is registered into
 24  * <code>Firebug.NetMonitor.NetInfoBody</code> object.
 25  */
 26 Firebug.XMLViewerModel = extend(Firebug.Module,
 27 {
 28     dispatchName: "xmlViewer",
 29 
 30     initialize: function()
 31     {
 32         Firebug.ActivableModule.initialize.apply(this, arguments);
 33         Firebug.NetMonitor.NetInfoBody.addListener(this);
 34     },
 35 
 36     shutdown: function()
 37     {
 38         Firebug.ActivableModule.shutdown.apply(this, arguments);
 39         Firebug.NetMonitor.NetInfoBody.removeListener(this);
 40     },
 41 
 42     /**
 43      * Check response's content-type and if it's a XML, create a new tab with XML preview.
 44      */
 45     initTabBody: function(infoBox, file)
 46     {
 47         if (FBTrace.DBG_XMLVIEWER)
 48             FBTrace.sysout("xmlviewer.initTabBody", infoBox);
 49 
 50         // If the response is XML let's display a pretty preview.
 51         if (this.isXML(safeGetContentType(file.request)))
 52         {
 53             Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML",
 54                 $STR("xmlviewer.tab.XML"));
 55 
 56             if (FBTrace.DBG_XMLVIEWER)
 57                 FBTrace.sysout("xmlviewer.initTabBody; XML response available");
 58         }
 59     },
 60 
 61     isXML: function(contentType)
 62     {
 63         if (!contentType)
 64             return false;
 65 
 66         // Look if the response is XML based.
 67         for (var i=0; i<xmlContentTypes.length; i++)
 68         {
 69             if (contentType.indexOf(xmlContentTypes[i]) == 0)
 70                 return true;
 71         }
 72 
 73         return false;
 74     },
 75 
 76     /**
 77      * Parse XML response and render pretty printed preview.
 78      */
 79     updateTabBody: function(infoBox, file, context)
 80     {
 81         var tab = infoBox.selectedTab;
 82         var tabBody = infoBox.getElementsByClassName("netInfoXMLText").item(0);
 83         if (!hasClass(tab, "netInfoXMLTab") || tabBody.updated)
 84             return;
 85 
 86         tabBody.updated = true;
 87 
 88         this.insertXML(tabBody, file.responseText);
 89     },
 90 
 91     insertXML: function(parentNode, text)
 92     {
 93         var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
 94         var doc = parser.parseFromString(text, "text/xml");
 95         var root = doc.documentElement;
 96 
 97         // Error handling
 98         var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
 99         if (root.namespaceURI == nsURI && root.nodeName == "parsererror")
100         {
101             this.ParseError.tag.replace({error: {
102                 message: root.firstChild.nodeValue,
103                 source: root.lastChild.textContent
104             }}, parentNode);
105             return;
106         }
107 
108         if (FBTrace.DBG_XMLVIEWER)
109             FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc);
110 
111         // Generate XML preview.
112         Firebug.HTMLPanel.CompleteElement.tag.replace({object: doc.documentElement}, parentNode);
113     }
114 });
115 
116 // ************************************************************************************************
117 // Domplate
118 
119 /**
120  * @domplate Represents a template for displaying XML parser errors. Used by
121  * <code>Firebug.XMLViewerModel</code>.
122  */
123 Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep,
124 {
125     tag:
126         DIV({"class": "xmlInfoError"},
127             DIV({"class": "xmlInfoErrorMsg"}, "$error.message"),
128             PRE({"class": "xmlInfoErrorSource"}, "$error|getSource")
129         ),
130 
131     getSource: function(error)
132     {
133         var parts = error.source.split("\n");
134         if (parts.length != 2)
135             return error.source;
136 
137         var limit = 50;
138         var column = parts[1].length;
139         if (column >= limit) {
140             parts[0] = "..." + parts[0].substr(column - limit);
141             parts[1] = "..." + parts[1].substr(column - limit);
142         }
143 
144         if (parts[0].length > 80)
145             parts[0] = parts[0].substr(0, 80) + "...";
146 
147         return parts.join("\n");
148     }
149 });
150 
151 // ************************************************************************************************
152 // Registration
153 
154 Firebug.registerModule(Firebug.XMLViewerModel);
155 
156 }});
157