1 /* See license.txt for terms of usage */ 2 3 define([ 4 "firebug/lib/object", 5 "firebug/chrome/infotip", 6 "firebug/lib/domplate", 7 "firebug/js/sourceLink", 8 "firebug/lib/locale", 9 "firebug/lib/dom", 10 "firebug/lib/css", 11 "firebug/lib/string", 12 "firebug/lib/fonts" 13 ], 14 function(Obj, InfoTip, Domplate, SourceLink, Locale, Dom, Css, Str, Fonts) { 15 16 with (Domplate) { 17 18 // ********************************************************************************************* // 19 // Constants 20 21 const maxWidth = 100 22 const maxHeight = 80; 23 24 // ********************************************************************************************* // 25 26 var CSSInfoTip = Obj.extend(InfoTip, 27 { 28 dispatchName: "cssInfoTip", 29 30 tags: domplate( 31 { 32 infoTipTag: DIV({"class": "infoTip"}), 33 34 colorTag: 35 DIV({"class": "infoTipColorBox"}, 36 DIV({style: "background: $rgbValue; width: 100px; height: 40px;"}) 37 ), 38 39 imgTag: 40 DIV({"class": "infoTipImageBox infoTipLoading"}, 41 IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat", 42 onload: "$onLoadImage", onerror: "$onErrorImage"}), 43 IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}), 44 DIV({"class": "infoTipCaption"}) 45 ), 46 47 fontFamilyTag: 48 DIV({"class": "infoTipFontFamilyBox"}, 49 STYLE({"class": "infoTipFontFamilyStyle"}), 50 DIV({"class": "infoTipFontFamilySample"}, 51 FOR("fontStyle", "$fontStyles", 52 DIV({"class": "infoTipFontFace", style: "$fontStyle"}, 53 Locale.$STR("css.fontFamilyPreview")) 54 ) 55 ) 56 ), 57 58 onLoadImage: function(event) 59 { 60 var img = event.currentTarget; 61 var bgImg = img.nextSibling; 62 if (!bgImg) 63 return; // Sometimes gets called after element is dead 64 65 var caption = bgImg.nextSibling; 66 var innerBox = img.parentNode; 67 68 var w = img.naturalWidth, h = img.naturalHeight; 69 var repeat = img.getAttribute("repeat"); 70 71 if (repeat == "repeat-x" || (w == 1 && h > 1)) 72 { 73 Dom.collapse(img, true); 74 Dom.collapse(bgImg, false); 75 bgImg.style.background = "url(" + img.src + ") repeat-x"; 76 bgImg.style.width = maxWidth + "px"; 77 if (h > maxHeight) 78 bgImg.style.height = maxHeight + "px"; 79 else 80 bgImg.style.height = h + "px"; 81 } 82 else if (repeat == "repeat-y" || (h == 1 && w > 1)) 83 { 84 Dom.collapse(img, true); 85 Dom.collapse(bgImg, false); 86 bgImg.style.background = "url(" + img.src + ") repeat-y"; 87 bgImg.style.height = maxHeight + "px"; 88 if (w > maxWidth) 89 bgImg.style.width = maxWidth + "px"; 90 else 91 bgImg.style.width = w + "px"; 92 } 93 else if (repeat == "repeat" || (w == 1 && h == 1)) 94 { 95 Dom.collapse(img, true); 96 Dom.collapse(bgImg, false); 97 bgImg.style.background = "url(" + img.src + ") repeat"; 98 bgImg.style.width = maxWidth + "px"; 99 bgImg.style.height = maxHeight + "px"; 100 } 101 else 102 { 103 if (w > maxWidth || h > maxHeight) 104 { 105 if (w > h) 106 { 107 img.style.width = maxWidth + "px"; 108 img.style.height = Math.round((h / w) * maxWidth) + "px"; 109 } 110 else 111 { 112 img.style.width = Math.round((w / h) * maxHeight) + "px"; 113 img.style.height = maxHeight + "px"; 114 } 115 } 116 } 117 118 caption.textContent = Locale.$STRF("Dimensions", [w, h]); 119 120 Css.removeClass(innerBox, "infoTipLoading"); 121 }, 122 123 onErrorImage: function(event) 124 { 125 var img = event.currentTarget; 126 var bgImg = img.nextSibling; 127 if (!bgImg) 128 return; 129 130 var caption = bgImg.nextSibling; 131 132 // Display an error in the caption (instead of dimensions). 133 if (Str.hasPrefix(img.src, "moz-filedata")) 134 caption.textContent = Locale.$STR("firebug.failedToPreviewObjectURL"); 135 else 136 caption.textContent = Locale.$STR("firebug.failedToPreviewImageURL"); 137 138 var innerBox = img.parentNode; 139 Css.removeClass(innerBox, "infoTipLoading"); 140 } 141 }), 142 143 populateFontFamilyInfoTip: function(infoTip, fontName) 144 { 145 var fontStyles = [ 146 "font-size:12px;", 147 "font-weight:bold; font-size:12px;", 148 "font-style:italic; font-size:12px;", 149 "font-size:14px;", 150 "font-size:18px;" 151 ]; 152 var fontObject = Fonts.getFontInfo(null, null, 153 fontName.replace(/^(["'])?(.*?)\1$/g, "$2")); 154 155 if (FBTrace.DBG_INFOTIP) 156 { 157 FBTrace.sysout("infotip.populateFontFamilyInfoTip;", {fontName: fontName, 158 fontObject: fontObject}); 159 } 160 161 var node = this.tags.fontFamilyTag.replace({fontStyles: fontStyles, fontName: fontName, 162 fontObject: fontObject}, infoTip); 163 var styleNode = node.getElementsByClassName("infoTipFontFamilyStyle").item(0); 164 165 styleNode.textContent = getFontFaceCSS(fontObject ? fontObject : fontName); 166 return true; 167 }, 168 169 populateColorInfoTip: function(infoTip, color) 170 { 171 this.tags.colorTag.replace({rgbValue: color}, infoTip); 172 return true; 173 }, 174 175 populateImageInfoTip: function(infoTip, url, repeat) 176 { 177 if (!repeat) 178 repeat = "no-repeat"; 179 180 this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip); 181 182 return true; 183 } 184 }); 185 186 //********************************************************************************************* // 187 //Local Helpers 188 189 /** 190 * Returns the CSS for the infotip @font-face CSS 191 * 192 * @param fontObject: Font related information 193 * @return @font-face CSS 194 */ 195 function getFontFaceCSS(font) 196 { 197 var fontFaceCSS = ""; 198 var fontName = ""; 199 200 if (typeof font == "object") 201 { 202 if (font.rule) 203 fontFaceCSS = font.rule.cssText.replace(/url\(.*?\)/g, "url("+font.URI+")"); 204 fontName = font.CSSFamilyName; 205 } 206 else 207 { 208 fontName = font; 209 } 210 211 fontFaceCSS += " .infoTipFontFace {font-family: "+fontName+";}"; 212 213 return fontFaceCSS; 214 } 215 216 // ********************************************************************************************* // 217 // Registration 218 219 return CSSInfoTip; 220 221 // ********************************************************************************************* // 222 }}); 223