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