1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/object",
  5     "firebug/firebug",
  6     "firebug/lib/domplate",
  7     "firebug/lib/locale",
  8     "firebug/lib/xpcom",
  9     "firebug/lib/css",
 10     "firebug/lib/http",
 11     "firebug/net/netUtils"
 12 ],
 13 function(Obj, Firebug, Domplate, Locale, Xpcom, Css, Http, NetUtils) {
 14 
 15 // ************************************************************************************************
 16 // Constants
 17 
 18 // List of SVG related content types.
 19 var contentTypes =
 20 [
 21     "image/svg+xml",
 22 ];
 23 
 24 // ************************************************************************************************
 25 // Model implementation
 26 
 27 /**
 28  * @module Implements viewer for SVG based network responses. In order to create a new
 29  * tab wihin network request detail, a listener is registered into
 30  * <code>Firebug.NetMonitor.NetInfoBody</code> object.
 31  */
 32 Firebug.SVGViewerModel = Obj.extend(Firebug.Module,
 33 /** lends Firebug.SVGViewerModel */
 34 {
 35     dispatchName: "svgViewer",
 36 
 37     initialize: function()
 38     {
 39         Firebug.ActivableModule.initialize.apply(this, arguments);
 40         Firebug.NetMonitor.NetInfoBody.addListener(this);
 41     },
 42 
 43     shutdown: function()
 44     {
 45         Firebug.ActivableModule.shutdown.apply(this, arguments);
 46         Firebug.NetMonitor.NetInfoBody.removeListener(this);
 47     },
 48 
 49     /**
 50      * Check response's content-type and if it's a SVG, create a new tab with SVG preview.
 51      */
 52     initTabBody: function(infoBox, file)
 53     {
 54         if (FBTrace.DBG_SVGVIEWER)
 55             FBTrace.sysout("svgviewer.initTabBody", infoBox);
 56 
 57         // If the response is SVG let's display a pretty preview.
 58         if (this.isSVG(Http.safeGetContentType(file.request)))
 59         {
 60             Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "SVG",
 61                 Locale.$STR("svgviewer.tab.SVG"));
 62 
 63             if (FBTrace.DBG_SVGVIEWER)
 64                 FBTrace.sysout("svgviewer.initTabBody; SVG response available");
 65         }
 66     },
 67 
 68     isSVG: function(contentType)
 69     {
 70         if (!contentType)
 71             return false;
 72 
 73         return NetUtils.matchesContentType(contentType, contentTypes);
 74     },
 75 
 76     /**
 77      * Parse SVG response and render pretty printed preview.
 78      */
 79     updateTabBody: function(infoBox, file, context)
 80     {
 81         var tab = infoBox.selectedTab;
 82         var tabBody = infoBox.getElementsByClassName("netInfoSVGText").item(0);
 83         if (!Css.hasClass(tab, "netInfoSVGTab") || tabBody.updated)
 84             return;
 85 
 86         tabBody.updated = true;
 87 
 88         this.insertSVG(tabBody, file.responseText);
 89     },
 90 
 91     insertSVG: function(parentNode, text)
 92     {
 93         var parser = Xpcom.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_SVGVIEWER)
109             FBTrace.sysout("svgviewer.updateTabBody; SVG response parsed", doc);
110 
111         // Override getHidden in these templates. The parsed SVG document is
112         // hidden, but we want to display it using 'visible' styling.
113         var templates = [
114             Firebug.HTMLPanel.CompleteElement,
115             Firebug.HTMLPanel.Element,
116             Firebug.HTMLPanel.TextElement,
117             Firebug.HTMLPanel.EmptyElement,
118             Firebug.HTMLPanel.XEmptyElement,
119         ];
120 
121         var originals = [];
122         for (var i=0; i<templates.length; i++)
123         {
124             originals[i] = templates[i].getHidden;
125             templates[i].getHidden = function() {
126                 return "";
127             }
128         }
129 
130         // Generate SVG preview.
131         Firebug.HTMLPanel.CompleteElement.tag.replace({object: doc.documentElement}, parentNode);
132 
133         for (var i=0; i<originals.length; i++)
134             templates[i].getHidden = originals[i];
135     }
136 });
137 
138 // ************************************************************************************************
139 // Domplate
140 
141 /**
142  * @domplate Represents a template for displaying SVG parser errors. Used by
143  * <code>Firebug.SVGViewerModel</code>.
144  */
145 with (Domplate) {
146 Firebug.SVGViewerModel.ParseError = domplate(Firebug.Rep,
147 {
148     tag:
149         DIV({"class": "svgInfoError"},
150             DIV({"class": "svgInfoErrorMsg"}, "$error.message"),
151             PRE({"class": "svgInfoErrorSource"}, "$error|getSource")
152         ),
153 
154     getSource: function(error)
155     {
156         var parts = error.source.split("\n");
157         if (parts.length != 2)
158             return error.source;
159 
160         var limit = 50;
161         var column = parts[1].length;
162         if (column >= limit) {
163             parts[0] = "..." + parts[0].substr(column - limit);
164             parts[1] = "..." + parts[1].substr(column - limit);
165         }
166 
167         if (parts[0].length > 80)
168             parts[0] = parts[0].substr(0, 80) + "...";
169 
170         return parts.join("\n");
171     }
172 })};
173 
174 // ************************************************************************************************
175 // Registration
176 
177 Firebug.registerModule(Firebug.SVGViewerModel);
178 
179 return Firebug.SVGViewerModel;
180 
181 // ************************************************************************************************
182 });
183