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/events", 9 "firebug/lib/dom" 10 ], 11 function(Obj, Firebug, Domplate, Locale, Events, Dom) { 12 13 // ********************************************************************************************* // 14 // Constants 15 16 const infoTipMargin = 10; 17 18 // ********************************************************************************************* // 19 20 with (Domplate) { 21 Firebug.InfoTip = Obj.extend(Firebug.Module, 22 { 23 dispatchName: "infoTip", 24 tags: domplate( 25 { 26 infoTipTag: DIV({"class": "infoTip"}), 27 }), 28 29 initializeBrowser: function(browser) 30 { 31 browser.onInfoTipMouseOut = Obj.bind(this.onMouseOut, this, browser); 32 browser.onInfoTipMouseMove = Obj.bind(this.onMouseMove, this, browser); 33 34 var doc = browser.contentDocument; 35 if (!doc) 36 return; 37 38 doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true); 39 doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true); 40 doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true); 41 42 return browser.infoTip = this.tags.infoTipTag.append({}, Dom.getBody(doc)); 43 }, 44 45 uninitializeBrowser: function(browser) 46 { 47 if (browser.infoTip) 48 { 49 var doc = browser.contentDocument; 50 doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true); 51 doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true); 52 doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true); 53 54 browser.infoTip.parentNode.removeChild(browser.infoTip); 55 delete browser.infoTip; 56 delete browser.onInfoTipMouseMove; 57 } 58 }, 59 60 showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset) 61 { 62 if (!Firebug.showInfoTips) 63 return; 64 65 var scrollParent = Dom.getOverflowParent(target); 66 var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0); 67 68 var show = panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset); 69 if (!show && this.fbListeners) 70 { 71 show = Events.dispatch2(this.fbListeners, "showInfoTip", [infoTip, target, scrollX, y, 72 rangeParent, rangeOffset]); 73 } 74 75 if (show) 76 { 77 var htmlElt = infoTip.ownerDocument.documentElement; 78 var panelWidth = htmlElt.clientWidth; 79 var panelHeight = htmlElt.clientHeight; 80 81 if (x+infoTip.offsetWidth+infoTipMargin > panelWidth) 82 { 83 infoTip.style.left = Math.max(0, panelWidth - 84 (infoTip.offsetWidth + infoTipMargin)) + "px"; 85 infoTip.style.right = "auto"; 86 } 87 else 88 { 89 infoTip.style.left = (x+infoTipMargin) + "px"; 90 infoTip.style.right = "auto"; 91 } 92 93 if (y+infoTip.offsetHeight+infoTipMargin > panelHeight) 94 { 95 infoTip.style.top = Math.max(0, panelHeight - 96 (infoTip.offsetHeight+infoTipMargin)) + "px"; 97 infoTip.style.bottom = "auto"; 98 } 99 else 100 { 101 infoTip.style.top = (y+infoTipMargin) + "px"; 102 infoTip.style.bottom = "auto"; 103 } 104 105 if (FBTrace.DBG_INFOTIP) 106 FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top + 107 ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom + 108 ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight + 109 ", offsetWidth: " + infoTip.offsetWidth + 110 ", x: " + x + ", panelWidth: " + panelWidth + 111 ", y: " + y + ", panelHeight: " + panelHeight); 112 113 infoTip.setAttribute("active", "true"); 114 } 115 else 116 { 117 this.hideInfoTip(infoTip); 118 } 119 }, 120 121 hideInfoTip: function(infoTip) 122 { 123 if (infoTip) 124 infoTip.removeAttribute("active"); 125 }, 126 127 onMouseOut: function(event, browser) 128 { 129 if (!event.relatedTarget) 130 this.hideInfoTip(browser.infoTip); 131 }, 132 133 onMouseMove: function(event, browser) 134 { 135 // Ignore if the mouse is moving over the existing info tip. 136 if (Dom.getAncestorByClass(event.target, "infoTip")) 137 return; 138 139 if (browser.currentPanel) 140 { 141 var x = event.clientX, y = event.clientY; 142 this.showInfoTip(browser.infoTip, browser.currentPanel, event.target, x, y, 143 event.rangeParent, event.rangeOffset); 144 } 145 else 146 { 147 this.hideInfoTip(browser.infoTip); 148 } 149 }, 150 151 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 152 // extends Module 153 154 disable: function() 155 { 156 // XXXjoe For each browser, call uninitializeBrowser 157 }, 158 159 showPanel: function(browser, panel) 160 { 161 if (panel) 162 { 163 var infoTip = panel.panelBrowser.infoTip; 164 if (!infoTip) 165 infoTip = this.initializeBrowser(panel.panelBrowser); 166 this.hideInfoTip(infoTip); 167 } 168 169 }, 170 171 showSidePanel: function(browser, panel) 172 { 173 this.showPanel(browser, panel); 174 } 175 })}; 176 177 // ********************************************************************************************* // 178 // Registration 179 180 Firebug.registerModule(Firebug.InfoTip); 181 182 return Firebug.InfoTip; 183 184 // ********************************************************************************************* // 185 }); 186