width || el.scrollHeight > height))
- {
- width = el.scrollWidth;
- height = el.scrollHeight;
- }
-
- return {width: width, height: height};
- },
-
- getWindowScrollPosition: function()
- {
- var top=0, left=0, el;
-
- if(typeof this.window.pageYOffset == "number")
- {
- top = this.window.pageYOffset;
- left = this.window.pageXOffset;
- }
- else if((el=this.document.body) && (el.scrollTop || el.scrollLeft))
- {
- top = el.scrollTop;
- left = el.scrollLeft;
- }
- else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft))
- {
- top = el.scrollTop;
- left = el.scrollLeft;
- }
-
- return {top:top, left:left};
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Element Methods
-
- getElementFromPoint: function(x, y)
- {
- if (shouldFixElementFromPoint)
- {
- var scroll = this.getWindowScrollPosition();
- return this.document.elementFromPoint(x + scroll.left, y + scroll.top);
- }
- else
- return this.document.elementFromPoint(x, y);
- },
-
- getElementPosition: function(el)
- {
- var left = 0
- var top = 0;
-
- do
- {
- left += el.offsetLeft;
- top += el.offsetTop;
- }
- while (el = el.offsetParent);
-
- return {left:left, top:top};
- },
-
- getElementBox: function(el)
- {
- var result = {};
-
- if (el.getBoundingClientRect)
- {
- var rect = el.getBoundingClientRect();
-
- // fix IE problem with offset when not in fullscreen mode
- var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0;
-
- var scroll = this.getWindowScrollPosition();
-
- result.top = Math.round(rect.top - offset + scroll.top);
- result.left = Math.round(rect.left - offset + scroll.left);
- result.height = Math.round(rect.bottom - rect.top);
- result.width = Math.round(rect.right - rect.left);
- }
- else
- {
- var position = this.getElementPosition(el);
-
- result.top = position.top;
- result.left = position.left;
- result.height = el.offsetHeight;
- result.width = el.offsetWidth;
- }
-
- return result;
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Measurement Methods
-
- getMeasurement: function(el, name)
- {
- var result = {value: 0, unit: "px"};
-
- var cssValue = this.getStyle(el, name);
-
- if (!cssValue) return result;
- if (cssValue.toLowerCase() == "auto") return result;
-
- var reMeasure = /(\d+\.?\d*)(.*)/;
- var m = cssValue.match(reMeasure);
-
- if (m)
- {
- result.value = m[1]-0;
- result.unit = m[2].toLowerCase();
- }
-
- return result;
- },
-
- getMeasurementInPixels: function(el, name)
- {
- if (!el) return null;
-
- var m = this.getMeasurement(el, name);
- var value = m.value;
- var unit = m.unit;
-
- if (unit == "px")
- return value;
-
- else if (unit == "pt")
- return this.pointsToPixels(name, value);
-
- if (unit == "em")
- return this.emToPixels(el, value);
-
- else if (unit == "%")
- return this.percentToPixels(el, value);
- },
-
- getMeasurementBox1: function(el, name)
- {
- var sufixes = ["Top", "Left", "Bottom", "Right"];
- var result = [];
-
- for(var i=0, sufix; sufix=sufixes[i]; i++)
- result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix));
-
- return {top:result[0], left:result[1], bottom:result[2], right:result[3]};
- },
-
- getMeasurementBox: function(el, name)
- {
- var result = [];
- var sufixes = name == "border" ?
- ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] :
- ["Top", "Left", "Bottom", "Right"];
-
- if (isIE)
- {
- var propName, cssValue;
- var autoMargin = null;
-
- for(var i=0, sufix; sufix=sufixes[i]; i++)
- {
- propName = name + sufix;
-
- cssValue = el.currentStyle[propName] || el.style[propName];
-
- if (cssValue == "auto")
- {
- if (!autoMargin)
- autoMargin = this.getCSSAutoMarginBox(el);
-
- result[i] = autoMargin[sufix.toLowerCase()];
- }
- else
- result[i] = this.getMeasurementInPixels(el, propName);
-
- }
-
- }
- else
- {
- for(var i=0, sufix; sufix=sufixes[i]; i++)
- result[i] = this.getMeasurementInPixels(el, name + sufix);
- }
-
- return {top:result[0], left:result[1], bottom:result[2], right:result[3]};
- },
-
- getCSSAutoMarginBox: function(el)
- {
- if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1)
- return {top:0, left:0, bottom:0, right:0};
- /**/
-
- if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1)
- return {top:0, left:0, bottom:0, right:0};
- /**/
-
- var offsetTop = 0;
- if (false && isIEStantandMode)
- {
- var scrollSize = Firebug.browser.getWindowScrollSize();
- offsetTop = scrollSize.height;
- }
-
- var box = this.document.createElement("div");
- //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;";
- box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;";
-
- var clone = el.cloneNode(false);
- var text = this.document.createTextNode(" ");
- clone.appendChild(text);
-
- box.appendChild(clone);
-
- this.document.body.appendChild(box);
-
- var marginTop = clone.offsetTop - box.offsetTop - 1;
- var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop;
-
- var marginLeft = clone.offsetLeft - box.offsetLeft - 1;
- var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft;
-
- this.document.body.removeChild(box);
-
- return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight};
- },
-
- getFontSizeInPixels: function(el)
- {
- var size = this.getMeasurement(el, "fontSize");
-
- if (size.unit == "px") return size.value;
-
- // get font size, the dirty way
- var computeDirtyFontSize = function(el, calibration)
- {
- var div = this.document.createElement("div");
- var divStyle = offscreenStyle;
-
- if (calibration)
- divStyle += " font-size:"+calibration+"px;";
-
- div.style.cssText = divStyle;
- div.innerHTML = "A";
- el.appendChild(div);
-
- var value = div.offsetHeight;
- el.removeChild(div);
- return value;
- }
-
- /*
- var calibrationBase = 200;
- var calibrationValue = computeDirtyFontSize(el, calibrationBase);
- var rate = calibrationBase / calibrationValue;
- /**/
-
- // the "dirty technique" fails in some environments, so we're using a static value
- // based in some tests.
- var rate = 200 / 225;
-
- var value = computeDirtyFontSize(el);
-
- return value * rate;
- },
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Unit Funtions
-
- pointsToPixels: function(name, value, returnFloat)
- {
- var axis = /Top$|Bottom$/.test(name) ? "y" : "x";
-
- var result = value * pixelsPerInch[axis] / 72;
-
- return returnFloat ? result : Math.round(result);
- },
-
- emToPixels: function(el, value)
- {
- if (!el) return null;
-
- var fontSize = this.getFontSizeInPixels(el);
-
- return Math.round(value * fontSize);
- },
-
- exToPixels: function(el, value)
- {
- if (!el) return null;
-
- // get ex value, the dirty way
- var div = this.document.createElement("div");
- div.style.cssText = offscreenStyle + "width:"+value + "ex;";
-
- el.appendChild(div);
- var value = div.offsetWidth;
- el.removeChild(div);
-
- return value;
- },
-
- percentToPixels: function(el, value)
- {
- if (!el) return null;
-
- // get % value, the dirty way
- var div = this.document.createElement("div");
- div.style.cssText = offscreenStyle + "width:"+value + "%;";
-
- el.appendChild(div);
- var value = div.offsetWidth;
- el.removeChild(div);
-
- return value;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getStyle: isIE ? function(el, name)
- {
- return el.currentStyle[name] || el.style[name] || undefined;
- }
- : function(el, name)
- {
- return this.document.defaultView.getComputedStyle(el,null)[name]
- || el.style[name] || undefined;
- }
-
-};
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) {
-// ************************************************************************************************
-
-// ************************************************************************************************
-// Globals
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Window Options
-
-var WindowDefaultOptions =
- {
- type: "frame",
- id: "FirebugUI",
- height: 250
- },
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Instantiated objects
-
- commandLine,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Interface Elements Cache
-
- fbTop,
- fbContent,
- fbContentStyle,
- fbBottom,
- fbBtnInspect,
-
- fbToolbar,
-
- fbPanelBox1,
- fbPanelBox1Style,
- fbPanelBox2,
- fbPanelBox2Style,
- fbPanelBar2Box,
- fbPanelBar2BoxStyle,
-
- fbHSplitter,
- fbVSplitter,
- fbVSplitterStyle,
-
- fbPanel1,
- fbPanel1Style,
- fbPanel2,
- fbPanel2Style,
-
- fbConsole,
- fbConsoleStyle,
- fbHTML,
-
- fbCommandLine,
- fbLargeCommandLine,
- fbLargeCommandButtons,
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// Cached size values
-
- topHeight,
- topPartialHeight,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- lastSelectedPanelName,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- focusCommandLineState = 0,
- lastFocusedPanelName,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- lastHSplitterMouseMove = 0,
- onHSplitterMouseMoveBuffer = null,
- onHSplitterMouseMoveTimer = null,
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- lastVSplitterMouseMove = 0;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-
-// ************************************************************************************************
-// FirebugChrome
-
-/**@namespace*/
-FBL.FirebugChrome =
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- isOpen: false,
- height: 250,
- sidePanelWidth: 350,
-
- selectedPanelName: "Console",
- selectedHTMLElementId: null,
-
- chromeMap: {},
-
- htmlSelectionStack: [],
- consoleMessageQueue: [],
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- create: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window");
-
- createChromeWindow();
- },
-
- initialize: function()
- {
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window");
-
- if (Env.chrome.type == "frame" || Env.chrome.type == "div")
- ChromeMini.create(Env.chrome);
-
- var chrome = Firebug.chrome = new Chrome(Env.chrome);
- FirebugChrome.chromeMap[chrome.type] = chrome;
-
- addGlobalEvent("keydown", onGlobalKeyDown);
-
- if (Env.Options.enablePersistent && chrome.type == "popup")
- {
- // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode
- var frame = FirebugChrome.chromeMap.frame;
- if (frame)
- frame.close();
-
- //chrome.reattach(frame, chrome);
- //TODO: xxxpedro persist synchronize?
- chrome.initialize();
- }
- },
-
- clone: function(FBChrome)
- {
- for (var name in FBChrome)
- {
- var prop = FBChrome[name];
- if (FBChrome.hasOwnProperty(name) && !isFunction(prop))
- {
- this[name] = prop;
- }
- }
- }
-};
-
-
-
-// ************************************************************************************************
-// Chrome Window Creation
-
-var createChromeWindow = function(options)
-{
- options = extend(WindowDefaultOptions, options || {});
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Locals
-
- var chrome = {},
-
- context = options.context || Env.browser,
-
- type = chrome.type = Env.Options.enablePersistent ?
- "popup" :
- options.type,
-
- isChromeFrame = type == "frame",
-
- useLocalSkin = Env.useLocalSkin,
-
- url = useLocalSkin ?
- Env.Location.skin :
- "about:blank",
-
- // document.body not available in XML+XSL documents in Firefox
- body = context.document.getElementsByTagName("body")[0],
-
- formatNode = function(node)
- {
- if (!Env.isDebugMode)
- {
- node.firebugIgnore = true;
- }
-
- node.style.border = "0";
- node.style.visibility = "hidden";
- node.style.zIndex = "2147483647"; // MAX z-index = 2147483647
- node.style.position = noFixedPosition ? "absolute" : "fixed";
- node.style.width = "100%"; // "102%"; IE auto margin bug
- node.style.left = "0";
- node.style.bottom = noFixedPosition ? "-1px" : "0";
- node.style.height = options.height + "px";
-
- // avoid flickering during chrome rendering
- if (isFirefox)
- node.style.display = "none";
- },
-
- createChromeDiv = function()
- {
- //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed.");
-
- var node = chrome.node = createGlobalElement("div"),
- style = createGlobalElement("style"),
-
- css = FirebugChrome.Skin.CSS
- /*
- .replace(/;/g, " !important;")
- .replace(/!important\s!important/g, "!important")
- .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/,
-
- // reset some styles to minimize interference from the main page's style
- rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" +
- // load the chrome styles
- css +
- // adjust some remaining styles
- ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}";
- /*
- if (isIE)
- {
- // IE7 CSS bug (FbChrome table bigger than its parent div)
- rules += ".fbBody table.fbChrome{position: static !important;}";
- }/**/
-
- style.type = "text/css";
-
- if (style.styleSheet)
- style.styleSheet.cssText = rules;
- else
- style.appendChild(context.document.createTextNode(rules));
-
- document.getElementsByTagName("head")[0].appendChild(style);
-
- node.className = "fbBody";
- node.style.overflow = "hidden";
- node.innerHTML = getChromeDivTemplate();
-
- if (isIE)
- {
- // IE7 CSS bug (FbChrome table bigger than its parent div)
- setTimeout(function(){
- node.firstChild.style.height = "1px";
- node.firstChild.style.position = "static";
- },0);
- /**/
- }
-
- formatNode(node);
-
- body.appendChild(node);
-
- chrome.window = window;
- chrome.document = document;
- onChromeLoad(chrome);
- };
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- try
- {
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create the Chrome as a "div" (windowless mode)
- if (type == "div")
- {
- createChromeDiv();
- return;
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // cretate the Chrome as an "iframe"
- else if (isChromeFrame)
- {
- // Create the Chrome Frame
- var node = chrome.node = createGlobalElement("iframe");
- node.setAttribute("src", url);
- node.setAttribute("frameBorder", "0");
-
- formatNode(node);
-
- body.appendChild(node);
-
- // must set the id after appending to the document, otherwise will cause an
- // strange error in IE, making the iframe load the page in which the bookmarklet
- // was created (like getfirebug.com), before loading the injected UI HTML,
- // generating an "Access Denied" error.
- node.id = options.id;
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create the Chrome as a "popup"
- else
- {
- var height = FirebugChrome.height || options.height,
-
- options = [
- "true,top=",
- Math.max(screen.availHeight - height - 61 /* Google Chrome bug */, 0),
- ",left=0,height=",
- height,
- ",width=",
- screen.availWidth-10, // Opera opens popup in a new tab if it's too big!
- ",resizable"
- ].join(""),
-
- node = chrome.node = context.window.open(
- url,
- "popup",
- options
- );
-
- if (node)
- {
- try
- {
- node.focus();
- }
- catch(E)
- {
- alert("Firebug Error: Firebug popup was blocked.");
- return;
- }
- }
- else
- {
- alert("Firebug Error: Firebug popup was blocked.");
- return;
- }
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Inject the interface HTML if it is not using the local skin
-
- if (!useLocalSkin)
- {
- var tpl = getChromeTemplate(!isChromeFrame),
- doc = isChromeFrame ? node.contentWindow.document : node.document;
-
- doc.write(tpl);
- doc.close();
- }
-
- //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Wait the Window to be loaded
-
- var win,
-
- waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100,
-
- waitForWindow = function()
- {
- if ( // Frame loaded... OR
- isChromeFrame && (win=node.contentWindow) &&
- node.contentWindow.document.getElementById("fbCommandLine") ||
-
- // Popup loaded
- !isChromeFrame && (win=node.window) && node.document &&
- node.document.getElementById("fbCommandLine") )
- {
- chrome.window = win.window;
- chrome.document = win.document;
-
- // Prevent getting the wrong chrome height in FF when opening a popup
- setTimeout(function(){
- onChromeLoad(chrome);
- }, useLocalSkin ? 200 : 0);
- }
- else
- setTimeout(waitForWindow, waitDelay);
- };
-
- waitForWindow();
- }
- catch(e)
- {
- var msg = e.message || e;
-
- if (/access/i.test(msg))
- {
- // Firebug Lite could not create a window for its Graphical User Interface due to
- // a access restriction. This happens in some pages, when loading via bookmarklet.
- // In such cases, the only way is to load the GUI in a "windowless mode".
-
- if (isChromeFrame)
- body.removeChild(node);
- else if(type == "popup")
- node.close();
-
- // Load the GUI in a "windowless mode"
- createChromeDiv();
- }
- else
- {
- alert("Firebug Error: Firebug GUI could not be created.");
- }
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var onChromeLoad = function onChromeLoad(chrome)
-{
- Env.chrome = chrome;
-
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded");
-
- if (Env.Options.enablePersistent)
- {
- // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode
- Env.FirebugChrome = FirebugChrome;
-
- chrome.window.Firebug = chrome.window.Firebug || {};
- chrome.window.Firebug.SharedEnv = Env;
-
- if (Env.isDevelopmentMode)
- {
- Env.browser.window.FBDev.loadChromeApplication(chrome);
- }
- else
- {
- var doc = chrome.document;
- var script = doc.createElement("script");
- script.src = Env.Location.app + "#remote,persist";
- doc.getElementsByTagName("head")[0].appendChild(script);
- }
- }
- else
- {
- if (chrome.type == "frame" || chrome.type == "div")
- {
- // initialize the chrome application
- setTimeout(function(){
- FBL.Firebug.initialize();
- },0);
- }
- else if (chrome.type == "popup")
- {
- var oldChrome = FirebugChrome.chromeMap.frame;
-
- var newChrome = new Chrome(chrome);
-
- // TODO: xxxpedro sync detach reattach attach
- dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]);
-
- if (oldChrome)
- oldChrome.close();
-
- newChrome.reattach(oldChrome, newChrome);
- }
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var getChromeDivTemplate = function()
-{
- return FirebugChrome.Skin.HTML;
-};
-
-var getChromeTemplate = function(isPopup)
-{
- var tpl = FirebugChrome.Skin;
- var r = [], i = -1;
-
- r[++i] = '';
- r[++i] = '';
- r[++i] = Firebug.version;
-
- /*
- r[++i] = '';
- /**/
-
- r[++i] = '';
- /**/
-
- r[++i] = '';
- r[++i] = tpl.HTML;
- r[++i] = '';
-
- return r.join("");
-};
-
-
-// ************************************************************************************************
-// Chrome Class
-
-/**@class*/
-var Chrome = function Chrome(chrome)
-{
- var type = chrome.type;
- var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase;
-
- append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase)
- append(this, chrome); // inherit chrome window properties
- append(this, new Context(chrome.window)); // inherit from Context class
-
- FirebugChrome.chromeMap[type] = this;
- Firebug.chrome = this;
- Env.chrome = chrome.window;
-
- this.commandLineVisible = false;
- this.sidePanelVisible = false;
-
- this.create();
-
- return this;
-};
-
-// ************************************************************************************************
-// ChromeBase
-
-/**
- * @namespace
- * @extends FBL.Controller
- * @extends FBL.PanelBar
- **/
-var ChromeBase = {};
-append(ChromeBase, Controller);
-append(ChromeBase, PanelBar);
-append(ChromeBase,
-/**@extend ns-chrome-ChromeBase*/
-{
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // inherited properties
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // inherited from createChrome function
-
- node: null,
- type: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // inherited from Context.prototype
-
- document: null,
- window: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // value properties
-
- sidePanelVisible: false,
- commandLineVisible: false,
- largeCommandLineVisible: false,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // object properties
-
- inspectButton: null,
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- create: function()
- {
- PanelBar.create.call(this);
-
- if (Firebug.Inspector)
- this.inspectButton = new Button({
- type: "toggle",
- element: $("fbChrome_btInspect"),
- owner: Firebug.Inspector,
-
- onPress: Firebug.Inspector.startInspecting,
- onUnpress: Firebug.Inspector.stopInspecting
- });
- },
-
- destroy: function()
- {
- if(Firebug.Inspector)
- this.inspectButton.destroy();
-
- PanelBar.destroy.call(this);
-
- this.shutdown();
- },
-
- testMenu: function()
- {
- var firebugMenu = new Menu(
- {
- id: "fbFirebugMenu",
-
- items:
- [
- {
- label: "Open Firebug",
- type: "shortcut",
- key: isFirefox ? "Shift+F12" : "F12",
- checked: true,
- command: "toggleChrome"
- },
- {
- label: "Open Firebug in New Window",
- type: "shortcut",
- key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12",
- command: "openPopup"
- },
- {
- label: "Inspect Element",
- type: "shortcut",
- key: "Ctrl+Shift+C",
- command: "toggleInspect"
- },
- {
- label: "Command Line",
- type: "shortcut",
- key: "Ctrl+Shift+L",
- command: "focusCommandLine"
- },
- "-",
- {
- label: "Options",
- type: "group",
- child: "fbFirebugOptionsMenu"
- },
- "-",
- {
- label: "Firebug Lite Website...",
- command: "visitWebsite"
- },
- {
- label: "Discussion Group...",
- command: "visitDiscussionGroup"
- },
- {
- label: "Issue Tracker...",
- command: "visitIssueTracker"
- }
- ],
-
- onHide: function()
- {
- iconButton.restore();
- },
-
- toggleChrome: function()
- {
- Firebug.chrome.toggle();
- },
-
- openPopup: function()
- {
- Firebug.chrome.toggle(true, true);
- },
-
- toggleInspect: function()
- {
- Firebug.Inspector.toggleInspect();
- },
-
- focusCommandLine: function()
- {
- Firebug.chrome.focusCommandLine();
- },
-
- visitWebsite: function()
- {
- this.visit("http://getfirebug.com/lite.html");
- },
-
- visitDiscussionGroup: function()
- {
- this.visit("http://groups.google.com/group/firebug");
- },
-
- visitIssueTracker: function()
- {
- this.visit("http://code.google.com/p/fbug/issues/list");
- },
-
- visit: function(url)
- {
- window.open(url);
- }
-
- });
-
- /**@private*/
- var firebugOptionsMenu =
- {
- id: "fbFirebugOptionsMenu",
-
- getItems: function()
- {
- var cookiesDisabled = !Firebug.saveCookies;
-
- return [
- {
- label: "Save Options in Cookies",
- type: "checkbox",
- value: "saveCookies",
- checked: Firebug.saveCookies,
- command: "saveOptions"
- },
- "-",
- {
- label: "Start Opened",
- type: "checkbox",
- value: "startOpened",
- checked: Firebug.startOpened,
- disabled: cookiesDisabled
- },
- {
- label: "Start in New Window",
- type: "checkbox",
- value: "startInNewWindow",
- checked: Firebug.startInNewWindow,
- disabled: cookiesDisabled
- },
- {
- label: "Show Icon When Hidden",
- type: "checkbox",
- value: "showIconWhenHidden",
- checked: Firebug.showIconWhenHidden,
- disabled: cookiesDisabled
- },
- {
- label: "Override Console Object",
- type: "checkbox",
- value: "overrideConsole",
- checked: Firebug.overrideConsole,
- disabled: cookiesDisabled
- },
- {
- label: "Ignore Firebug Elements",
- type: "checkbox",
- value: "ignoreFirebugElements",
- checked: Firebug.ignoreFirebugElements,
- disabled: cookiesDisabled
- },
- {
- label: "Disable When Firebug Active",
- type: "checkbox",
- value: "disableWhenFirebugActive",
- checked: Firebug.disableWhenFirebugActive,
- disabled: cookiesDisabled
- },
- {
- label: "Disable XHR Listener",
- type: "checkbox",
- value: "disableXHRListener",
- checked: Firebug.disableXHRListener,
- disabled: cookiesDisabled
- },
- {
- label: "Enable Trace Mode",
- type: "checkbox",
- value: "enableTrace",
- checked: Firebug.enableTrace,
- disabled: cookiesDisabled
- },
- {
- label: "Enable Persistent Mode (experimental)",
- type: "checkbox",
- value: "enablePersistent",
- checked: Firebug.enablePersistent,
- disabled: cookiesDisabled
- },
- "-",
- {
- label: "Reset All Firebug Options",
- command: "restorePrefs",
- disabled: cookiesDisabled
- }
- ];
- },
-
- onCheck: function(target, value, checked)
- {
- Firebug.setPref(value, checked);
- },
-
- saveOptions: function(target)
- {
- var saveEnabled = target.getAttribute("checked");
-
- if (!saveEnabled) this.restorePrefs();
-
- this.updateMenu(target);
-
- return false;
- },
-
- restorePrefs: function(target)
- {
- Firebug.restorePrefs();
-
- if(Firebug.saveCookies)
- Firebug.savePrefs();
- else
- Firebug.erasePrefs();
-
- if (target)
- this.updateMenu(target);
-
- return false;
- },
-
- updateMenu: function(target)
- {
- var options = getElementsByClass(target.parentNode, "fbMenuOption");
-
- var firstOption = options[0];
- var enabled = Firebug.saveCookies;
- if (enabled)
- Menu.check(firstOption);
- else
- Menu.uncheck(firstOption);
-
- if (enabled)
- Menu.check(options[0]);
- else
- Menu.uncheck(options[0]);
-
- for (var i = 1, length = options.length; i < length; i++)
- {
- var option = options[i];
-
- var value = option.getAttribute("value");
- var pref = Firebug[value];
-
- if (pref)
- Menu.check(option);
- else
- Menu.uncheck(option);
-
- if (enabled)
- Menu.enable(option);
- else
- Menu.disable(option);
- }
- }
- };
-
- Menu.register(firebugOptionsMenu);
-
- var menu = firebugMenu;
-
- var testMenuClick = function(event)
- {
- //console.log("testMenuClick");
- cancelEvent(event, true);
-
- var target = event.target || event.srcElement;
-
- if (menu.isVisible)
- menu.hide();
- else
- {
- var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position
-
- chrome = Firebug.chrome,
-
- box = chrome.getElementBox(target),
-
- offset = chrome.type == "div" ?
- chrome.getElementPosition(chrome.node) :
- {top: 0, left: 0};
-
- menu.show(
- box.left + offsetLeft - offset.left,
- box.top + box.height -5 - offset.top
- );
- }
-
- return false;
- };
-
- var iconButton = new IconButton({
- type: "toggle",
- element: $("fbFirebugButton"),
-
- onClick: testMenuClick
- });
-
- iconButton.initialize();
-
- //addEvent($("fbToolbarIcon"), "click", testMenuClick);
- },
-
- initialize: function()
- {
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (Env.bookmarkletOutdated)
- Firebug.Console.logFormatted([
- "A new bookmarklet version is available. " +
- "Please visit http://getfirebug.com/firebuglite#Install and update it."
- ], Firebug.context, "warn");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (Firebug.Console)
- Firebug.Console.flush();
-
- if (Firebug.Trace)
- FBTrace.flush(Firebug.Trace);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // initialize inherited classes
- Controller.initialize.call(this);
- PanelBar.initialize.call(this);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // create the interface elements cache
-
- fbTop = $("fbTop");
- fbContent = $("fbContent");
- fbContentStyle = fbContent.style;
- fbBottom = $("fbBottom");
- fbBtnInspect = $("fbBtnInspect");
-
- fbToolbar = $("fbToolbar");
-
- fbPanelBox1 = $("fbPanelBox1");
- fbPanelBox1Style = fbPanelBox1.style;
- fbPanelBox2 = $("fbPanelBox2");
- fbPanelBox2Style = fbPanelBox2.style;
- fbPanelBar2Box = $("fbPanelBar2Box");
- fbPanelBar2BoxStyle = fbPanelBar2Box.style;
-
- fbHSplitter = $("fbHSplitter");
- fbVSplitter = $("fbVSplitter");
- fbVSplitterStyle = fbVSplitter.style;
-
- fbPanel1 = $("fbPanel1");
- fbPanel1Style = fbPanel1.style;
- fbPanel2 = $("fbPanel2");
- fbPanel2Style = fbPanel2.style;
-
- fbConsole = $("fbConsole");
- fbConsoleStyle = fbConsole.style;
- fbHTML = $("fbHTML");
-
- fbCommandLine = $("fbCommandLine");
- fbLargeCommandLine = $("fbLargeCommandLine");
- fbLargeCommandButtons = $("fbLargeCommandButtons");
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // static values cache
- topHeight = fbTop.offsetHeight;
- topPartialHeight = fbToolbar.offsetHeight;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- disableTextSelection($("fbToolbar"));
- disableTextSelection($("fbPanelBarBox"));
- disableTextSelection($("fbPanelBar1"));
- disableTextSelection($("fbPanelBar2"));
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6
- if (isIE6 && Firebug.Selector)
- {
- // TODO: xxxpedro change to getElementsByClass
- var as = $$(".fbHover");
- for (var i=0, a; a=as[i]; i++)
- {
- a.setAttribute("href", "javascript:void(0)");
- }
- }
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // initialize all panels
- /*
- var panelMap = Firebug.panelTypes;
- for (var i=0, p; p=panelMap[i]; i++)
- {
- if (!p.parentPanel)
- {
- this.addPanel(p.prototype.name);
- }
- }
- /**/
-
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- if(Firebug.Inspector)
- this.inspectButton.initialize();
-
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- this.addController(
- [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine]
- );
-
- // ************************************************************************************************
-
- // Select the first registered panel
- // TODO: BUG IE7
- var self = this;
- setTimeout(function(){
- self.selectPanel(FirebugChrome.selectedPanelName);
-
- if (FirebugChrome.selectedPanelName == "Console" && Firebug.CommandLine)
- Firebug.chrome.focusCommandLine();
- },0);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- //this.draw();
-
-
-
-
-
-
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- var onPanelMouseDown = function onPanelMouseDown(event)
- {
- //console.log("onPanelMouseDown", event.target || event.srcElement, event);
-
- var target = event.target || event.srcElement;
-
- if (FBL.isLeftClick(event))
- {
- var editable = FBL.getAncestorByClass(target, "editable");
-
- // if an editable element has been clicked then start editing
- if (editable)
- {
- Firebug.Editor.startEditing(editable);
- FBL.cancelEvent(event);
- }
- // if any other element has been clicked then stop editing
- else
- {
- if (!hasClass(target, "textEditorInner"))
- Firebug.Editor.stopEditing();
- }
- }
- else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target))
- {
- // Prevent auto-scroll when middle-clicking a rep object
- FBL.cancelEvent(event);
- }
- };
-
- Firebug.getElementPanel = function(element)
- {
- var panelNode = getAncestorByClass(element, "fbPanel");
- var id = panelNode.id.substr(2);
-
- var panel = Firebug.chrome.panelMap[id];
-
- if (!panel)
- {
- if (Firebug.chrome.selectedPanel.sidePanelBar)
- panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id];
- }
-
- return panel;
- };
-
-
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // TODO: xxxpedro port to Firebug
-
- // Improved window key code event listener. Only one "keydown" event will be attached
- // to the window, and the onKeyCodeListen() function will delegate which listeners
- // should be called according to the event.keyCode fired.
- var onKeyCodeListenersMap = [];
- var onKeyCodeListen = function(event)
- {
- for (var keyCode in onKeyCodeListenersMap)
- {
- var listeners = onKeyCodeListenersMap[keyCode];
-
- for (var i = 0, listener; listener = listeners[i]; i++)
- {
- var filter = listener.filter || FBL.noKeyModifiers;
-
- if (event.keyCode == keyCode && (!filter || filter(event)))
- {
- listener.listener();
- FBL.cancelEvent(event, true);
- return false;
- }
- }
- }
- };
-
- addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen);
-
- /**
- * @name keyCodeListen
- * @memberOf FBL.FirebugChrome
- */
- Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
- {
- var keyCode = KeyEvent["DOM_VK_"+key];
-
- if (!onKeyCodeListenersMap[keyCode])
- onKeyCodeListenersMap[keyCode] = [];
-
- onKeyCodeListenersMap[keyCode].push({
- filter: filter,
- listener: listener
- });
-
- return keyCode;
- };
-
- /**
- * @name keyIgnore
- * @memberOf FBL.FirebugChrome
- */
- Firebug.chrome.keyIgnore = function(keyCode)
- {
- onKeyCodeListenersMap[keyCode] = null;
- delete onKeyCodeListenersMap[keyCode];
- };
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- /**/
- // move to shutdown
- //removeEvent(Firebug.chrome.document, "keydown", listener[0]);
-
-
- /*
- Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
- {
- if (!filter)
- filter = FBL.noKeyModifiers;
-
- var keyCode = KeyEvent["DOM_VK_"+key];
-
- var fn = function fn(event)
- {
- if (event.keyCode == keyCode && (!filter || filter(event)))
- {
- listener();
- FBL.cancelEvent(event, true);
- return false;
- }
- }
-
- addEvent(Firebug.chrome.document, "keydown", fn);
-
- return [fn, capture];
- };
-
- Firebug.chrome.keyIgnore = function(listener)
- {
- removeEvent(Firebug.chrome.document, "keydown", listener[0]);
- };
- /**/
-
-
- this.addController(
- [fbPanel1, "mousedown", onPanelMouseDown],
- [fbPanel2, "mousedown", onPanelMouseDown]
- );
-/**/
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-
- // menus can be used without domplate
- if (FBL.domplate)
- this.testMenu();
- /**/
-
- //test XHR
- /*
- setTimeout(function(){
-
- FBL.Ajax.request({url: "../content/firebug/boot.js"});
- FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"});
-
- },1000);
- /**/
- },
-
- shutdown: function()
- {
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- if(Firebug.Inspector)
- this.inspectButton.shutdown();
-
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
- // ************************************************************************************************
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- // remove disableTextSelection event handlers
- restoreTextSelection($("fbToolbar"));
- restoreTextSelection($("fbPanelBarBox"));
- restoreTextSelection($("fbPanelBar1"));
- restoreTextSelection($("fbPanelBar2"));
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // shutdown inherited classes
- Controller.shutdown.call(this);
- PanelBar.shutdown.call(this);
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Remove the interface elements cache (this must happen after calling
- // the shutdown method of all dependent components to avoid errors)
-
- fbTop = null;
- fbContent = null;
- fbContentStyle = null;
- fbBottom = null;
- fbBtnInspect = null;
-
- fbToolbar = null;
-
- fbPanelBox1 = null;
- fbPanelBox1Style = null;
- fbPanelBox2 = null;
- fbPanelBox2Style = null;
- fbPanelBar2Box = null;
- fbPanelBar2BoxStyle = null;
-
- fbHSplitter = null;
- fbVSplitter = null;
- fbVSplitterStyle = null;
-
- fbPanel1 = null;
- fbPanel1Style = null;
- fbPanel2 = null;
-
- fbConsole = null;
- fbConsoleStyle = null;
- fbHTML = null;
-
- fbCommandLine = null;
- fbLargeCommandLine = null;
- fbLargeCommandButtons = null;
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // static values cache
-
- topHeight = null;
- topPartialHeight = null;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- toggle: function(forceOpen, popup)
- {
- if(popup)
- {
- this.detach();
- }
- else
- {
- if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed)
- {
- var frame = FirebugChrome.chromeMap.frame;
- frame.reattach();
-
- FirebugChrome.chromeMap.popup = null;
-
- frame.open();
-
- return;
- }
-
- // If the context is a popup, ignores the toggle process
- if (Firebug.chrome.type == "popup") return;
-
- var shouldOpen = forceOpen || !FirebugChrome.isOpen;
-
- if(shouldOpen)
- this.open();
- else
- this.close();
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- detach: function()
- {
- if(!FirebugChrome.chromeMap.popup)
- {
- createChromeWindow({type: "popup"});
- }
- },
-
- reattach: function(oldChrome, newChrome)
- {
- Firebug.browser.window.Firebug = Firebug;
-
- // chrome synchronization
- var newPanelMap = newChrome.panelMap;
- var oldPanelMap = oldChrome.panelMap;
-
- var panel;
- for(var name in newPanelMap)
- {
- // TODO: xxxpedro innerHTML
- panel = newPanelMap[name];
- if (panel.options.innerHTMLSync)
- panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML;
- }
-
- Firebug.chrome = newChrome;
-
- // TODO: xxxpedro sync detach reattach attach
- //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]);
-
- if (newChrome.type == "popup")
- {
- newChrome.initialize();
- //dispatch(Firebug.modules, "initialize", []);
- }
- else
- {
- // TODO: xxxpedro only needed in persistent
- // should use FirebugChrome.clone, but popup FBChrome
- // isn't acessible
- FirebugChrome.selectedPanelName = oldChrome.selectedPanel.name;
- }
-
- dispatch(newPanelMap, "reattach", [oldChrome, newChrome]);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- draw: function()
- {
- var size = this.getSize();
-
- // Height related values
- var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0,
-
- y = Math.max(size.height /* chrome height */, topHeight),
-
- heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0),
-
- height = heightValue + "px",
-
- // Width related values
- sideWidthValue = Firebug.chrome.sidePanelVisible ? FirebugChrome.sidePanelWidth : 0,
-
- width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px";
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Height related rendering
- fbPanelBox1Style.height = height;
- fbPanel1Style.height = height;
-
- if (isIE || isOpera)
- {
- // Fix IE and Opera problems with auto resizing the verticall splitter
- fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px";
- }
- //xxxpedro FF2 only?
- /*
- else if (isFirefox)
- {
- // Fix Firefox problem with table rows with 100% height (fit height)
- fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px";
- }/**/
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Width related rendering
- fbPanelBox1Style.width = width;
- fbPanel1Style.width = width;
-
- // SidePanel rendering
- if (Firebug.chrome.sidePanelVisible)
- {
- sideWidthValue = Math.max(sideWidthValue - 6, 0);
-
- var sideWidth = sideWidthValue + "px";
-
- fbPanelBox2Style.width = sideWidth;
-
- fbVSplitterStyle.right = sideWidth;
-
- if (Firebug.chrome.largeCommandLineVisible)
- {
- fbLargeCommandLine = $("fbLargeCommandLine");
-
- fbLargeCommandLine.style.height = heightValue - 4 + "px";
- fbLargeCommandLine.style.width = sideWidthValue - 2 + "px";
-
- fbLargeCommandButtons = $("fbLargeCommandButtons");
- fbLargeCommandButtons.style.width = sideWidth;
- }
- else
- {
- fbPanel2Style.height = height;
- fbPanel2Style.width = sideWidth;
-
- fbPanelBar2BoxStyle.width = sideWidth;
- }
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- getSize: function()
- {
- return this.type == "div" ?
- {
- height: this.node.offsetHeight,
- width: this.node.offsetWidth
- }
- :
- this.getWindowSize();
- },
-
- resize: function()
- {
- var self = this;
-
- // avoid partial resize when maximizing window
- setTimeout(function(){
- self.draw();
-
- if (noFixedPosition && (self.type == "frame" || self.type == "div"))
- self.fixIEPosition();
- }, 0);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- layout: function(panel)
- {
- if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", "");
-
- var options = panel.options;
-
- changeCommandLineVisibility(options.hasCommandLine);
- changeSidePanelVisibility(panel.hasSidePanel);
-
- Firebug.chrome.draw();
- },
-
- showLargeCommandLine: function(hideToggleIcon)
- {
- var chrome = Firebug.chrome;
-
- if (!chrome.largeCommandLineVisible)
- {
- chrome.largeCommandLineVisible = true;
-
- if (chrome.selectedPanel.options.hasCommandLine)
- {
- if (Firebug.CommandLine)
- Firebug.CommandLine.blur();
-
- changeCommandLineVisibility(false);
- }
-
- changeSidePanelVisibility(true);
-
- fbLargeCommandLine.style.display = "block";
- fbLargeCommandButtons.style.display = "block";
-
- fbPanel2Style.display = "none";
- fbPanelBar2BoxStyle.display = "none";
-
- chrome.draw();
-
- fbLargeCommandLine.focus();
-
- if (Firebug.CommandLine)
- Firebug.CommandLine.setMultiLine(true);
- }
- },
-
- hideLargeCommandLine: function()
- {
- if (Firebug.chrome.largeCommandLineVisible)
- {
- Firebug.chrome.largeCommandLineVisible = false;
-
- if (Firebug.CommandLine)
- Firebug.CommandLine.setMultiLine(false);
-
- fbLargeCommandLine.blur();
-
- fbPanel2Style.display = "block";
- fbPanelBar2BoxStyle.display = "block";
-
- fbLargeCommandLine.style.display = "none";
- fbLargeCommandButtons.style.display = "none";
-
- changeSidePanelVisibility(false);
-
- if (Firebug.chrome.selectedPanel.options.hasCommandLine)
- changeCommandLineVisibility(true);
-
- Firebug.chrome.draw();
-
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- focusCommandLine: function()
- {
- var selectedPanelName = this.selectedPanel.name, panelToSelect;
-
- if (focusCommandLineState == 0 || selectedPanelName != "Console")
- {
- focusCommandLineState = 0;
- lastFocusedPanelName = selectedPanelName;
-
- panelToSelect = "Console";
- }
- if (focusCommandLineState == 1)
- {
- panelToSelect = lastFocusedPanelName;
- }
-
- this.selectPanel(panelToSelect);
-
- try
- {
- if (Firebug.CommandLine)
- {
- if (panelToSelect == "Console")
- Firebug.CommandLine.focus();
- else
- Firebug.CommandLine.blur();
- }
- }
- catch(e)
- {
- //TODO: xxxpedro trace error
- }
-
- focusCommandLineState = ++focusCommandLineState % 2;
- }
-
-});
-
-// ************************************************************************************************
-// ChromeFrameBase
-
-/**
- * @namespace
- * @extends ns-chrome-ChromeBase
- */
-var ChromeFrameBase = extend(ChromeBase,
-/**@extend ns-chrome-ChromeFrameBase*/
-{
- create: function()
- {
- ChromeBase.create.call(this);
-
- // restore display for the anti-flicker trick
- if (isFirefox)
- this.node.style.display = "block";
-
- if (Env.Options.startInNewWindow)
- {
- this.close();
- this.toggle(true, true);
- return;
- }
-
- if (Env.Options.startOpened)
- this.open();
- else
- this.close();
- },
-
- destroy: function()
- {
- removeGlobalEvent("keydown", onGlobalKeyDown);
-
- ChromeBase.destroy.call(this);
-
- this.document = null;
- delete this.document;
-
- this.window = null;
- delete this.window;
-
- this.node.parentNode.removeChild(this.node);
- this.node = null;
- delete this.node;
- },
-
- initialize: function()
- {
- //FBTrace.sysout("Frame", "initialize();")
- ChromeBase.initialize.call(this);
-
- this.addController(
- [Firebug.browser.window, "resize", this.resize],
- [$("fbWindow_btClose"), "click", this.close],
- [$("fbWindow_btDetach"), "click", this.detach],
- [$("fbWindow_btDeactivate"), "click", this.deactivate]
- );
-
- if (!Env.Options.enablePersistent)
- this.addController([Firebug.browser.window, "unload", Firebug.shutdown]);
-
- if (noFixedPosition)
- {
- this.addController(
- [Firebug.browser.window, "scroll", this.fixIEPosition]
- );
- }
-
- fbVSplitter.onmousedown = onVSplitterMouseDown;
- fbHSplitter.onmousedown = onHSplitterMouseDown;
-
- this.isInitialized = true;
- },
-
- shutdown: function()
- {
- fbVSplitter.onmousedown = null;
- fbHSplitter.onmousedown = null;
-
- ChromeBase.shutdown.apply(this);
-
- this.isInitialized = false;
- },
-
- reattach: function()
- {
- var frame = FirebugChrome.chromeMap.frame;
-
- ChromeBase.reattach(FirebugChrome.chromeMap.popup, this);
- },
-
- open: function()
- {
- if (!FirebugChrome.isOpen)
- {
- FirebugChrome.isOpen = true;
-
- if (Env.isChromeExtension)
- localStorage.setItem("Firebug", "1,1");
-
- var node = this.node;
-
- node.style.visibility = "hidden"; // Avoid flickering
-
- if (Firebug.showIconWhenHidden)
- {
- if (ChromeMini.isInitialized)
- {
- ChromeMini.shutdown();
- }
-
- }
- else
- node.style.display = "block";
-
- var main = $("fbChrome");
-
- // IE6 throws an error when setting this property! why?
- //main.style.display = "table";
- main.style.display = "";
-
- var self = this;
- /// TODO: xxxpedro FOUC
- node.style.visibility = "visible";
- setTimeout(function(){
- ///node.style.visibility = "visible";
-
- //dispatch(Firebug.modules, "initialize", []);
- self.initialize();
-
- if (noFixedPosition)
- self.fixIEPosition();
-
- self.draw();
-
- }, 10);
- }
- },
-
- close: function()
- {
- if (FirebugChrome.isOpen || !this.isInitialized)
- {
- if (this.isInitialized)
- {
- //dispatch(Firebug.modules, "shutdown", []);
- this.shutdown();
- }
-
- FirebugChrome.isOpen = false;
-
- if (Env.isChromeExtension)
- localStorage.setItem("Firebug", "1,0");
-
- var node = this.node;
-
- if (Firebug.showIconWhenHidden)
- {
- node.style.visibility = "hidden"; // Avoid flickering
-
- // TODO: xxxpedro - persist IE fixed?
- var main = $("fbChrome", FirebugChrome.chromeMap.frame.document);
- main.style.display = "none";
-
- ChromeMini.initialize();
-
- node.style.visibility = "visible";
- }
- else
- node.style.display = "none";
- }
- },
-
- deactivate: function()
- {
- // if it is running as a Chrome extension, dispatch a message to the extension signaling
- // that Firebug should be deactivated for the current tab
- if (Env.isChromeExtension)
- {
- localStorage.removeItem("Firebug");
- Firebug.GoogleChrome.dispatch("FB_deactivate");
-
- // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole
- // app, otherwise it won't be able to be reactivated without reloading the page.
- // but we need to stop listening global keys, otherwise the key activation won't work.
- Firebug.chrome.close();
- }
- else
- {
- Firebug.shutdown();
- }
- },
-
- fixIEPosition: function()
- {
- // fix IE problem with offset when not in fullscreen mode
- var doc = this.document;
- var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0;
-
- var size = Firebug.browser.getWindowSize();
- var scroll = Firebug.browser.getWindowScrollPosition();
- var maxHeight = size.height;
- var height = this.node.offsetHeight;
-
- var bodyStyle = doc.body.currentStyle;
-
- this.node.style.top = maxHeight - height + scroll.top + "px";
-
- if ((this.type == "frame" || this.type == "div") &&
- (bodyStyle.marginLeft || bodyStyle.marginRight))
- {
- this.node.style.width = size.width + "px";
- }
-
- if (fbVSplitterStyle)
- fbVSplitterStyle.right = FirebugChrome.sidePanelWidth + "px";
-
- this.draw();
- }
-
-});
-
-
-// ************************************************************************************************
-// ChromeMini
-
-/**
- * @namespace
- * @extends FBL.Controller
- */
-var ChromeMini = extend(Controller,
-/**@extend ns-chrome-ChromeMini*/
-{
- create: function(chrome)
- {
- append(this, chrome);
- this.type = "mini";
- },
-
- initialize: function()
- {
- Controller.initialize.apply(this);
-
- var doc = FirebugChrome.chromeMap.frame.document;
-
- var mini = $("fbMiniChrome", doc);
- mini.style.display = "block";
-
- var miniIcon = $("fbMiniIcon", doc);
- var width = miniIcon.offsetWidth + 10;
- miniIcon.title = "Open " + Firebug.version;
-
- var errors = $("fbMiniErrors", doc);
- if (errors.offsetWidth)
- width += errors.offsetWidth + 10;
-
- var node = this.node;
- node.style.height = "27px";
- node.style.width = width + "px";
- node.style.left = "";
- node.style.right = 0;
-
- if (this.node.nodeName.toLowerCase() == "iframe")
- {
- node.setAttribute("allowTransparency", "true");
- this.document.body.style.backgroundColor = "transparent";
- }
- else
- node.style.background = "transparent";
-
- if (noFixedPosition)
- this.fixIEPosition();
-
- this.addController(
- [$("fbMiniIcon", doc), "click", onMiniIconClick]
- );
-
- if (noFixedPosition)
- {
- this.addController(
- [Firebug.browser.window, "scroll", this.fixIEPosition]
- );
- }
-
- this.isInitialized = true;
- },
-
- shutdown: function()
- {
- var node = this.node;
- node.style.height = FirebugChrome.height + "px";
- node.style.width = "100%";
- node.style.left = 0;
- node.style.right = "";
-
- if (this.node.nodeName.toLowerCase() == "iframe")
- {
- node.setAttribute("allowTransparency", "false");
- this.document.body.style.backgroundColor = "#fff";
- }
- else
- node.style.background = "#fff";
-
- if (noFixedPosition)
- this.fixIEPosition();
-
- var doc = FirebugChrome.chromeMap.frame.document;
-
- var mini = $("fbMiniChrome", doc);
- mini.style.display = "none";
-
- Controller.shutdown.apply(this);
-
- this.isInitialized = false;
- },
-
- draw: function()
- {
-
- },
-
- fixIEPosition: ChromeFrameBase.fixIEPosition
-
-});
-
-
-// ************************************************************************************************
-// ChromePopupBase
-
-/**
- * @namespace
- * @extends ns-chrome-ChromeBase
- */
-var ChromePopupBase = extend(ChromeBase,
-/**@extend ns-chrome-ChromePopupBase*/
-{
-
- initialize: function()
- {
- setClass(this.document.body, "FirebugPopup");
-
- ChromeBase.initialize.call(this);
-
- this.addController(
- [Firebug.chrome.window, "resize", this.resize],
- [Firebug.chrome.window, "unload", this.destroy]
- );
-
- if (Env.Options.enablePersistent)
- {
- this.persist = bind(this.persist, this);
- addEvent(Firebug.browser.window, "unload", this.persist);
- }
- else
- this.addController(
- [Firebug.browser.window, "unload", this.close]
- );
-
- fbVSplitter.onmousedown = onVSplitterMouseDown;
- },
-
- destroy: function()
- {
- // TODO: xxxpedro sync detach reattach attach
- var frame = FirebugChrome.chromeMap.frame;
-
- if(frame)
- {
- dispatch(frame.panelMap, "detach", [this, frame]);
-
- frame.reattach(this, frame);
- }
-
- if (Env.Options.enablePersistent)
- {
- removeEvent(Firebug.browser.window, "unload", this.persist);
- }
-
- ChromeBase.destroy.apply(this);
-
- FirebugChrome.chromeMap.popup = null;
-
- this.node.close();
- },
-
- persist: function()
- {
- persistTimeStart = new Date().getTime();
-
- removeEvent(Firebug.browser.window, "unload", this.persist);
-
- Firebug.Inspector.destroy();
- Firebug.browser.window.FirebugOldBrowser = true;
-
- var persistTimeStart = new Date().getTime();
-
- var waitMainWindow = function()
- {
- var doc, head;
-
- try
- {
- if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* &&
- doc.documentElement && (head = doc.documentElement.firstChild)*/)
- {
-
- try
- {
- // exposes the FBL to the global namespace when in debug mode
- if (Env.isDebugMode)
- {
- window.FBL = FBL;
- }
-
- window.Firebug = Firebug;
- window.opener.Firebug = Firebug;
-
- Env.browser = window.opener;
- Firebug.browser = Firebug.context = new Context(Env.browser);
-
- registerConsole();
-
- // the delay time should be calculated right after registering the
- // console, once right after the console registration, call log messages
- // will be properly handled
- var persistDelay = new Date().getTime() - persistTimeStart;
-
- var chrome = Firebug.chrome;
- addEvent(Firebug.browser.window, "unload", chrome.persist);
-
- FBL.cacheDocument();
- Firebug.Inspector.create();
-
- var htmlPanel = chrome.getPanel("HTML");
- htmlPanel.createUI();
-
- Firebug.Console.logFormatted(
- ["Firebug could not capture console calls during " +
- persistDelay + "ms"],
- Firebug.context,
- "info"
- );
- }
- catch(pE)
- {
- alert("persist error: " + (pE.message || pE));
- }
-
- }
- else
- {
- window.setTimeout(waitMainWindow, 0);
- }
-
- } catch (E) {
- window.close();
- }
- };
-
- waitMainWindow();
- },
-
- close: function()
- {
- this.destroy();
- }
-
-});
-
-
-//************************************************************************************************
-// UI helpers
-
-var changeCommandLineVisibility = function changeCommandLineVisibility(visibility)
-{
- var last = Firebug.chrome.commandLineVisible;
- var visible = Firebug.chrome.commandLineVisible =
- typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible;
-
- if (visible != last)
- {
- if (visible)
- {
- fbBottom.className = "";
-
- if (Firebug.CommandLine)
- Firebug.CommandLine.activate();
- }
- else
- {
- if (Firebug.CommandLine)
- Firebug.CommandLine.deactivate();
-
- fbBottom.className = "hide";
- }
- }
-};
-
-var changeSidePanelVisibility = function changeSidePanelVisibility(visibility)
-{
- var last = Firebug.chrome.sidePanelVisible;
- Firebug.chrome.sidePanelVisible =
- typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible;
-
- if (Firebug.chrome.sidePanelVisible != last)
- {
- fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
- fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
- }
-};
-
-
-// ************************************************************************************************
-// F12 Handler
-
-var onGlobalKeyDown = function onGlobalKeyDown(event)
-{
- var keyCode = event.keyCode;
- var shiftKey = event.shiftKey;
- var ctrlKey = event.ctrlKey;
-
- if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox))
- {
- Firebug.chrome.toggle(false, ctrlKey);
- cancelEvent(event, true);
-
- // TODO: xxxpedro replace with a better solution. we're doing this
- // to allow reactivating with the F12 key after being deactivated
- if (Env.isChromeExtension)
- {
- Firebug.GoogleChrome.dispatch("FB_enableIcon");
- }
- }
- else if (keyCode == 67 /* C */ && ctrlKey && shiftKey)
- {
- Firebug.Inspector.toggleInspect();
- cancelEvent(event, true);
- }
- else if (keyCode == 76 /* L */ && ctrlKey && shiftKey)
- {
- Firebug.chrome.focusCommandLine();
- cancelEvent(event, true);
- }
-};
-
-var onMiniIconClick = function onMiniIconClick(event)
-{
- Firebug.chrome.toggle(false, event.ctrlKey);
- cancelEvent(event, true);
-};
-
-
-// ************************************************************************************************
-// Horizontal Splitter Handling
-
-var onHSplitterMouseDown = function onHSplitterMouseDown(event)
-{
- addGlobalEvent("mousemove", onHSplitterMouseMove);
- addGlobalEvent("mouseup", onHSplitterMouseUp);
-
- if (isIE)
- addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
-
- fbHSplitter.className = "fbOnMovingHSplitter";
-
- return false;
-};
-
-var onHSplitterMouseMove = function onHSplitterMouseMove(event)
-{
- cancelEvent(event, true);
-
- var clientY = event.clientY;
- var win = isIE
- ? event.srcElement.ownerDocument.parentWindow
- : event.target.ownerDocument && event.target.ownerDocument.defaultView;
-
- if (!win)
- return;
-
- if (win != win.parent)
- {
- var frameElement = win.frameElement;
- if (frameElement)
- {
- var framePos = Firebug.browser.getElementPosition(frameElement).top;
- clientY += framePos;
-
- if (frameElement.style.position != "fixed")
- clientY -= Firebug.browser.getWindowScrollPosition().top;
- }
- }
-
- if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI")
- {
- clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY;
- }
- /*
- console.log(
- typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome",
- //win.frameElement.id,
- event.target,
- clientY
- );/**/
-
- onHSplitterMouseMoveBuffer = clientY; // buffer
-
- if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
- {
- lastHSplitterMouseMove = new Date().getTime();
- handleHSplitterMouseMove();
- }
- else
- if (!onHSplitterMouseMoveTimer)
- onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate);
-
- // improving the resizing performance by canceling the mouse event.
- // canceling events will prevent the page to receive such events, which would imply
- // in more processing being expended.
- cancelEvent(event, true);
- return false;
-};
-
-var handleHSplitterMouseMove = function()
-{
- if (onHSplitterMouseMoveTimer)
- {
- clearTimeout(onHSplitterMouseMoveTimer);
- onHSplitterMouseMoveTimer = null;
- }
-
- var clientY = onHSplitterMouseMoveBuffer;
-
- var windowSize = Firebug.browser.getWindowSize();
- var scrollSize = Firebug.browser.getWindowScrollSize();
-
- // compute chrome fixed size (top bar and command line)
- var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0;
- var fixedHeight = topHeight + commandLineHeight;
- var chromeNode = Firebug.chrome.node;
-
- var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0;
-
- //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height;
- var height = windowSize.height;
-
- // compute the min and max size of the chrome
- var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight);
- chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize);
-
- FirebugChrome.height = chromeHeight;
- chromeNode.style.height = chromeHeight + "px";
-
- if (noFixedPosition)
- Firebug.chrome.fixIEPosition();
-
- Firebug.chrome.draw();
-};
-
-var onHSplitterMouseUp = function onHSplitterMouseUp(event)
-{
- removeGlobalEvent("mousemove", onHSplitterMouseMove);
- removeGlobalEvent("mouseup", onHSplitterMouseUp);
-
- if (isIE)
- removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
-
- fbHSplitter.className = "";
-
- Firebug.chrome.draw();
-
- // avoid text selection in IE when returning to the document
- // after the mouse leaves the document during the resizing
- return false;
-};
-
-
-// ************************************************************************************************
-// Vertical Splitter Handling
-
-var onVSplitterMouseDown = function onVSplitterMouseDown(event)
-{
- addGlobalEvent("mousemove", onVSplitterMouseMove);
- addGlobalEvent("mouseup", onVSplitterMouseUp);
-
- return false;
-};
-
-var onVSplitterMouseMove = function onVSplitterMouseMove(event)
-{
- if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
- {
- var target = event.target || event.srcElement;
- if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome
- {
- var clientX = event.clientX;
- var win = document.all
- ? event.srcElement.ownerDocument.parentWindow
- : event.target.ownerDocument.defaultView;
-
- if (win != win.parent)
- clientX += win.frameElement ? win.frameElement.offsetLeft : 0;
-
- var size = Firebug.chrome.getSize();
- var x = Math.max(size.width - clientX + 3, 6);
-
- FirebugChrome.sidePanelWidth = x;
- Firebug.chrome.draw();
- }
-
- lastVSplitterMouseMove = new Date().getTime();
- }
-
- cancelEvent(event, true);
- return false;
-};
-
-var onVSplitterMouseUp = function onVSplitterMouseUp(event)
-{
- removeGlobalEvent("mousemove", onVSplitterMouseMove);
- removeGlobalEvent("mouseup", onVSplitterMouseUp);
-
- Firebug.chrome.draw();
-};
-
-
-// ************************************************************************************************
-}});
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite =
-{
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-
-Firebug.Lite.Browser = function(window)
-{
- this.contentWindow = window;
- this.contentDocument = window.document;
- this.currentURI =
- {
- spec: window.location.href
- };
-};
-
-Firebug.Lite.Browser.prototype =
-{
- toString: function()
- {
- return "Firebug.Lite.Browser";
- }
-};
-
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite.Cache =
-{
- ID: "firebug-" + new Date().getTime()
-};
-
-// ************************************************************************************************
-
-/**
- * TODO: if a cached element is cloned, the expando property will be cloned too in IE
- * which will result in a bug. Firebug Lite will think the new cloned node is the old
- * one.
- *
- * TODO: Investigate a possibility of cache validation, to be customized by each
- * kind of cache. For ElementCache it should validate if the element still is
- * inserted at the DOM.
- */
-var cacheUID = 0;
-var createCache = function()
-{
- var map = {};
- var data = {};
-
- var CID = Firebug.Lite.Cache.ID;
-
- // better detection
- var supportsDeleteExpando = !document.all;
-
- var cacheFunction = function(element)
- {
- return cacheAPI.set(element);
- };
-
- var cacheAPI =
- {
- get: function(key)
- {
- return map.hasOwnProperty(key) ?
- map[key] :
- null;
- },
-
- set: function(element)
- {
- var id = getValidatedKey(element);
-
- if (!id)
- {
- id = ++cacheUID;
- element[CID] = id;
- }
-
- if (!map.hasOwnProperty(id))
- {
- map[id] = element;
- data[id] = {};
- }
-
- return id;
- },
-
- unset: function(element)
- {
- var id = getValidatedKey(element);
-
- if (!id) return;
-
- if (supportsDeleteExpando)
- {
- delete element[CID];
- }
- else if (element.removeAttribute)
- {
- element.removeAttribute(CID);
- }
-
- delete map[id];
- delete data[id];
-
- },
-
- key: function(element)
- {
- return getValidatedKey(element);
- },
-
- has: function(element)
- {
- var id = getValidatedKey(element);
- return id && map.hasOwnProperty(id);
- },
-
- each: function(callback)
- {
- for (var key in map)
- {
- if (map.hasOwnProperty(key))
- {
- callback(key, map[key]);
- }
- }
- },
-
- data: function(element, name, value)
- {
- // set data
- if (value)
- {
- if (!name) return null;
-
- var id = cacheAPI.set(element);
-
- return data[id][name] = value;
- }
- // get data
- else
- {
- var id = cacheAPI.key(element);
-
- return data.hasOwnProperty(id) && data[id].hasOwnProperty(name) ?
- data[id][name] :
- null;
- }
- },
-
- clear: function()
- {
- for (var id in map)
- {
- var element = map[id];
- cacheAPI.unset(element);
- }
- }
- };
-
- var getValidatedKey = function(element)
- {
- var id = element[CID];
-
- // If a cached element is cloned in IE, the expando property CID will be also
- // cloned (differently than other browsers) resulting in a bug: Firebug Lite
- // will think the new cloned node is the old one. To prevent this problem we're
- // checking if the cached element matches the given element.
- if (
- !supportsDeleteExpando && // the problem happens when supportsDeleteExpando is false
- id && // the element has the expando property
- map.hasOwnProperty(id) && // there is a cached element with the same id
- map[id] != element // but it is a different element than the current one
- )
- {
- // remove the problematic property
- element.removeAttribute(CID);
-
- id = null;
- }
-
- return id;
- }
-
- FBL.append(cacheFunction, cacheAPI);
-
- return cacheFunction;
-};
-
-// ************************************************************************************************
-
-// TODO: xxxpedro : check if we need really this on FBL scope
-Firebug.Lite.Cache.StyleSheet = createCache();
-Firebug.Lite.Cache.Element = createCache();
-
-// TODO: xxxpedro
-Firebug.Lite.Cache.Event = createCache();
-
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-
-Firebug.Lite.Proxy =
-{
- // jsonp callbacks
- _callbacks: {},
-
- /**
- * Load a resource, either locally (directly) or externally (via proxy) using
- * synchronous XHR calls. Loading external resources requires the proxy plugin to
- * be installed and configured (see /plugin/proxy/proxy.php).
- */
- load: function(url)
- {
- var resourceDomain = getDomain(url);
- var isLocalResource =
- // empty domain means local URL
- !resourceDomain ||
- // same domain means local too
- resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context
-
- return isLocalResource ? fetchResource(url) : fetchProxyResource(url);
- },
-
- /**
- * Load a resource using JSONP technique.
- */
- loadJSONP: function(url, callback)
- {
- var script = createGlobalElement("script"),
- doc = Firebug.context.document,
-
- uid = "" + new Date().getTime(),
- callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid,
-
- jsonpURL = url.indexOf("?") != -1 ?
- url + "&" + callbackName :
- url + "?" + callbackName;
-
- Firebug.Lite.Proxy._callbacks[uid] = function(data)
- {
- if (callback)
- callback(data);
-
- script.parentNode.removeChild(script);
- delete Firebug.Lite.Proxy._callbacks[uid];
- };
-
- script.src = jsonpURL;
-
- if (doc.documentElement)
- doc.documentElement.appendChild(script);
- },
-
- /**
- * Load a resource using YQL (not reliable).
- */
- YQL: function(url, callback)
- {
- var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" +
- encodeURIComponent(url) + "%22&format=xml";
-
- this.loadJSONP(yql, function(data)
- {
- var source = data.results[0];
-
- // clean up YQL bogus elements
- var match = /\s+([\s\S]+)<\/p>\s+<\/body>$/.exec(source);
- if (match)
- source = match[1];
-
- console.log(source);
- });
- }
-};
-
-// ************************************************************************************************
-
-var fetchResource = function(url)
-{
- var xhr = FBL.Ajax.getXHRObject();
- xhr.open("get", url, false);
- xhr.send();
-
- return xhr.responseText;
-};
-
-var fetchProxyResource = function(url)
-{
- var proxyURL = Env.Location.baseDir + "plugin/proxy/proxy.php?url=" + encodeURIComponent(url);
- var response = fetchResource(proxyURL);
-
- try
- {
- var data = eval("(" + response + ")");
- }
- catch(E)
- {
- return "ERROR: Firebug Lite Proxy plugin returned an invalid response.";
- }
-
- return data ? data.contents : "";
-};
-
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite.Script = function(window)
-{
- this.fileName = null;
- this.isValid = null;
- this.baseLineNumber = null;
- this.lineExtent = null;
- this.tag = null;
-
- this.functionName = null;
- this.functionSource = null;
-};
-
-Firebug.Lite.Script.prototype =
-{
- isLineExecutable: function(){},
- pcToLine: function(){},
- lineToPc: function(){},
-
- toString: function()
- {
- return "Firebug.Lite.Script";
- }
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns(function() { with (FBL) {
-// ************************************************************************************************
-
-Firebug.Lite.Style =
-{
-};
-
-// ************************************************************************************************
-}});
-
-
-/* See license.txt for terms of usage */
-
-FBL.ns( /**@scope s_selector*/ function() { with (FBL) {
-// ************************************************************************************************
-
-/*
- * Sizzle CSS Selector Engine - v1.0
- * Copyright 2009, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- * More information: http://sizzlejs.com/
- */
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
- done = 0,
- toString = Object.prototype.toString,
- hasDuplicate = false,
- baseHasDuplicate = true;
-
-// Here we check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-// Thus far that includes Google Chrome.
-[0, 0].sort(function(){
- baseHasDuplicate = false;
- return 0;
-});
-
-/**
- * @name Firebug.Selector
- * @namespace
- */
-
-/**
- * @exports Sizzle as Firebug.Selector
- */
-var Sizzle = function(selector, context, results, seed) {
- results = results || [];
- var origContext = context = context || document;
-
- if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
- soFar = selector;
-
- // Reset the position of the chunker regexp (start from head)
- while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
- soFar = m[3];
-
- parts.push( m[1] );
-
- if ( m[2] ) {
- extra = m[3];
- break;
- }
- }
-
- if ( parts.length > 1 && origPOS.exec( selector ) ) {
- if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
- set = posProcess( parts[0] + parts[1], context );
- } else {
- set = Expr.relative[ parts[0] ] ?
- [ context ] :
- Sizzle( parts.shift(), context );
-
- while ( parts.length ) {
- selector = parts.shift();
-
- if ( Expr.relative[ selector ] )
- selector += parts.shift();
-
- set = posProcess( selector, set );
- }
- }
- } else {
- // Take a shortcut and set the context if the root selector is an ID
- // (but not if it'll be faster if the inner selector is an ID)
- if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
- var ret = Sizzle.find( parts.shift(), context, contextXML );
- context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
- }
-
- if ( context ) {
- var ret = seed ?
- { expr: parts.pop(), set: makeArray(seed) } :
- Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
- set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
-
- if ( parts.length > 0 ) {
- checkSet = makeArray(set);
- } else {
- prune = false;
- }
-
- while ( parts.length ) {
- var cur = parts.pop(), pop = cur;
-
- if ( !Expr.relative[ cur ] ) {
- cur = "";
- } else {
- pop = parts.pop();
- }
-
- if ( pop == null ) {
- pop = context;
- }
-
- Expr.relative[ cur ]( checkSet, pop, contextXML );
- }
- } else {
- checkSet = parts = [];
- }
- }
-
- if ( !checkSet ) {
- checkSet = set;
- }
-
- if ( !checkSet ) {
- throw "Syntax error, unrecognized expression: " + (cur || selector);
- }
-
- if ( toString.call(checkSet) === "[object Array]" ) {
- if ( !prune ) {
- results.push.apply( results, checkSet );
- } else if ( context && context.nodeType === 1 ) {
- for ( var i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
- results.push( set[i] );
- }
- }
- } else {
- for ( var i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
- results.push( set[i] );
- }
- }
- }
- } else {
- makeArray( checkSet, results );
- }
-
- if ( extra ) {
- Sizzle( extra, origContext, results, seed );
- Sizzle.uniqueSort( results );
- }
-
- return results;
-};
-
-Sizzle.uniqueSort = function(results){
- if ( sortOrder ) {
- hasDuplicate = baseHasDuplicate;
- results.sort(sortOrder);
-
- if ( hasDuplicate ) {
- for ( var i = 1; i < results.length; i++ ) {
- if ( results[i] === results[i-1] ) {
- results.splice(i--, 1);
- }
- }
- }
- }
-
- return results;
-};
-
-Sizzle.matches = function(expr, set){
- return Sizzle(expr, null, null, set);
-};
-
-Sizzle.find = function(expr, context, isXML){
- var set, match;
-
- if ( !expr ) {
- return [];
- }
-
- for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
- var type = Expr.order[i], match;
-
- if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
- var left = match[1];
- match.splice(1,1);
-
- if ( left.substr( left.length - 1 ) !== "\\" ) {
- match[1] = (match[1] || "").replace(/\\/g, "");
- set = Expr.find[ type ]( match, context, isXML );
- if ( set != null ) {
- expr = expr.replace( Expr.match[ type ], "" );
- break;
- }
- }
- }
- }
-
- if ( !set ) {
- set = context.getElementsByTagName("*");
- }
-
- return {set: set, expr: expr};
-};
-
-Sizzle.filter = function(expr, set, inplace, not){
- var old = expr, result = [], curLoop = set, match, anyFound,
- isXMLFilter = set && set[0] && isXML(set[0]);
-
- while ( expr && set.length ) {
- for ( var type in Expr.filter ) {
- if ( (match = Expr.match[ type ].exec( expr )) != null ) {
- var filter = Expr.filter[ type ], found, item;
- anyFound = false;
-
- if ( curLoop == result ) {
- result = [];
- }
-
- if ( Expr.preFilter[ type ] ) {
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
- if ( !match ) {
- anyFound = found = true;
- } else if ( match === true ) {
- continue;
- }
- }
-
- if ( match ) {
- for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
- if ( item ) {
- found = filter( item, match, i, curLoop );
- var pass = not ^ !!found;
-
- if ( inplace && found != null ) {
- if ( pass ) {
- anyFound = true;
- } else {
- curLoop[i] = false;
- }
- } else if ( pass ) {
- result.push( item );
- anyFound = true;
- }
- }
- }
- }
-
- if ( found !== undefined ) {
- if ( !inplace ) {
- curLoop = result;
- }
-
- expr = expr.replace( Expr.match[ type ], "" );
-
- if ( !anyFound ) {
- return [];
- }
-
- break;
- }
- }
- }
-
- // Improper expression
- if ( expr == old ) {
- if ( anyFound == null ) {
- throw "Syntax error, unrecognized expression: " + expr;
- } else {
- break;
- }
- }
-
- old = expr;
- }
-
- return curLoop;
-};
-
-/**#@+ @ignore */
-var Expr = Sizzle.selectors = {
- order: [ "ID", "NAME", "TAG" ],
- match: {
- ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
- CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
- TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
- CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
- PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
- },
- leftMatch: {},
- attrMap: {
- "class": "className",
- "for": "htmlFor"
- },
- attrHandle: {
- href: function(elem){
- return elem.getAttribute("href");
- }
- },
- relative: {
- "+": function(checkSet, part, isXML){
- var isPartStr = typeof part === "string",
- isTag = isPartStr && !/\W/.test(part),
- isPartStrNotTag = isPartStr && !isTag;
-
- if ( isTag && !isXML ) {
- part = part.toUpperCase();
- }
-
- for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
- if ( (elem = checkSet[i]) ) {
- while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
- elem || false :
- elem === part;
- }
- }
-
- if ( isPartStrNotTag ) {
- Sizzle.filter( part, checkSet, true );
- }
- },
- ">": function(checkSet, part, isXML){
- var isPartStr = typeof part === "string";
-
- if ( isPartStr && !/\W/.test(part) ) {
- part = isXML ? part : part.toUpperCase();
-
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- var parent = elem.parentNode;
- checkSet[i] = parent.nodeName === part ? parent : false;
- }
- }
- } else {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- checkSet[i] = isPartStr ?
- elem.parentNode :
- elem.parentNode === part;
- }
- }
-
- if ( isPartStr ) {
- Sizzle.filter( part, checkSet, true );
- }
- }
- },
- "": function(checkSet, part, isXML){
- var doneName = done++, checkFn = dirCheck;
-
- if ( !/\W/.test(part) ) {
- var nodeCheck = part = isXML ? part : part.toUpperCase();
- checkFn = dirNodeCheck;
- }
-
- checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
- },
- "~": function(checkSet, part, isXML){
- var doneName = done++, checkFn = dirCheck;
-
- if ( typeof part === "string" && !/\W/.test(part) ) {
- var nodeCheck = part = isXML ? part : part.toUpperCase();
- checkFn = dirNodeCheck;
- }
-
- checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
- }
- },
- find: {
- ID: function(match, context, isXML){
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- return m ? [m] : [];
- }
- },
- NAME: function(match, context, isXML){
- if ( typeof context.getElementsByName !== "undefined" ) {
- var ret = [], results = context.getElementsByName(match[1]);
-
- for ( var i = 0, l = results.length; i < l; i++ ) {
- if ( results[i].getAttribute("name") === match[1] ) {
- ret.push( results[i] );
- }
- }
-
- return ret.length === 0 ? null : ret;
- }
- },
- TAG: function(match, context){
- return context.getElementsByTagName(match[1]);
- }
- },
- preFilter: {
- CLASS: function(match, curLoop, inplace, result, not, isXML){
- match = " " + match[1].replace(/\\/g, "") + " ";
-
- if ( isXML ) {
- return match;
- }
-
- for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
- if ( elem ) {
- if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
- if ( !inplace )
- result.push( elem );
- } else if ( inplace ) {
- curLoop[i] = false;
- }
- }
- }
-
- return false;
- },
- ID: function(match){
- return match[1].replace(/\\/g, "");
- },
- TAG: function(match, curLoop){
- for ( var i = 0; curLoop[i] === false; i++ ){}
- return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
- },
- CHILD: function(match){
- if ( match[1] == "nth" ) {
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
- var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
- match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
- !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
- // calculate the numbers (first)n+(last) including if they are negative
- match[2] = (test[1] + (test[2] || 1)) - 0;
- match[3] = test[3] - 0;
- }
-
- // TODO: Move to normal caching system
- match[0] = done++;
-
- return match;
- },
- ATTR: function(match, curLoop, inplace, result, not, isXML){
- var name = match[1].replace(/\\/g, "");
-
- if ( !isXML && Expr.attrMap[name] ) {
- match[1] = Expr.attrMap[name];
- }
-
- if ( match[2] === "~=" ) {
- match[4] = " " + match[4] + " ";
- }
-
- return match;
- },
- PSEUDO: function(match, curLoop, inplace, result, not){
- if ( match[1] === "not" ) {
- // If we're dealing with a complex expression, or a simple one
- if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
- match[3] = Sizzle(match[3], null, null, curLoop);
- } else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
- if ( !inplace ) {
- result.push.apply( result, ret );
- }
- return false;
- }
- } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
- return true;
- }
-
- return match;
- },
- POS: function(match){
- match.unshift( true );
- return match;
- }
- },
- filters: {
- enabled: function(elem){
- return elem.disabled === false && elem.type !== "hidden";
- },
- disabled: function(elem){
- return elem.disabled === true;
- },
- checked: function(elem){
- return elem.checked === true;
- },
- selected: function(elem){
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- elem.parentNode.selectedIndex;
- return elem.selected === true;
- },
- parent: function(elem){
- return !!elem.firstChild;
- },
- empty: function(elem){
- return !elem.firstChild;
- },
- has: function(elem, i, match){
- return !!Sizzle( match[3], elem ).length;
- },
- header: function(elem){
- return /h\d/i.test( elem.nodeName );
- },
- text: function(elem){
- return "text" === elem.type;
- },
- radio: function(elem){
- return "radio" === elem.type;
- },
- checkbox: function(elem){
- return "checkbox" === elem.type;
- },
- file: function(elem){
- return "file" === elem.type;
- },
- password: function(elem){
- return "password" === elem.type;
- },
- submit: function(elem){
- return "submit" === elem.type;
- },
- image: function(elem){
- return "image" === elem.type;
- },
- reset: function(elem){
- return "reset" === elem.type;
- },
- button: function(elem){
- return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
- },
- input: function(elem){
- return /input|select|textarea|button/i.test(elem.nodeName);
- }
- },
- setFilters: {
- first: function(elem, i){
- return i === 0;
- },
- last: function(elem, i, match, array){
- return i === array.length - 1;
- },
- even: function(elem, i){
- return i % 2 === 0;
- },
- odd: function(elem, i){
- return i % 2 === 1;
- },
- lt: function(elem, i, match){
- return i < match[3] - 0;
- },
- gt: function(elem, i, match){
- return i > match[3] - 0;
- },
- nth: function(elem, i, match){
- return match[3] - 0 == i;
- },
- eq: function(elem, i, match){
- return match[3] - 0 == i;
- }
- },
- filter: {
- PSEUDO: function(elem, match, i, array){
- var name = match[1], filter = Expr.filters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- } else if ( name === "contains" ) {
- return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
- } else if ( name === "not" ) {
- var not = match[3];
-
- for ( var i = 0, l = not.length; i < l; i++ ) {
- if ( not[i] === elem ) {
- return false;
- }
- }
-
- return true;
- }
- },
- CHILD: function(elem, match){
- var type = match[1], node = elem;
- switch (type) {
- case 'only':
- case 'first':
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) return false;
- }
- if ( type == 'first') return true;
- node = elem;
- case 'last':
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) return false;
- }
- return true;
- case 'nth':
- var first = match[2], last = match[3];
-
- if ( first == 1 && last == 0 ) {
- return true;
- }
-
- var doneName = match[0],
- parent = elem.parentNode;
-
- if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
- var count = 0;
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.nodeIndex = ++count;
- }
- }
- parent.sizcache = doneName;
- }
-
- var diff = elem.nodeIndex - last;
- if ( first == 0 ) {
- return diff == 0;
- } else {
- return ( diff % first == 0 && diff / first >= 0 );
- }
- }
- },
- ID: function(elem, match){
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
- },
- TAG: function(elem, match){
- return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
- },
- CLASS: function(elem, match){
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
- .indexOf( match ) > -1;
- },
- ATTR: function(elem, match){
- var name = match[1],
- result = Expr.attrHandle[ name ] ?
- Expr.attrHandle[ name ]( elem ) :
- elem[ name ] != null ?
- elem[ name ] :
- elem.getAttribute( name ),
- value = result + "",
- type = match[2],
- check = match[4];
-
- return result == null ?
- type === "!=" :
- type === "=" ?
- value === check :
- type === "*=" ?
- value.indexOf(check) >= 0 :
- type === "~=" ?
- (" " + value + " ").indexOf(check) >= 0 :
- !check ?
- value && result !== false :
- type === "!=" ?
- value != check :
- type === "^=" ?
- value.indexOf(check) === 0 :
- type === "$=" ?
- value.substr(value.length - check.length) === check :
- type === "|=" ?
- value === check || value.substr(0, check.length + 1) === check + "-" :
- false;
- },
- POS: function(elem, match, i, array){
- var name = match[2], filter = Expr.setFilters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- }
- }
- }
-};
-
-var origPOS = Expr.match.POS;
-
-for ( var type in Expr.match ) {
- Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
- Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
-}
-
-var makeArray = function(array, results) {
- array = Array.prototype.slice.call( array, 0 );
-
- if ( results ) {
- results.push.apply( results, array );
- return results;
- }
-
- return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-try {
- Array.prototype.slice.call( document.documentElement.childNodes, 0 );
-
-// Provide a fallback method if it does not work
-} catch(e){
- makeArray = function(array, results) {
- var ret = results || [];
-
- if ( toString.call(array) === "[object Array]" ) {
- Array.prototype.push.apply( ret, array );
- } else {
- if ( typeof array.length === "number" ) {
- for ( var i = 0, l = array.length; i < l; i++ ) {
- ret.push( array[i] );
- }
- } else {
- for ( var i = 0; array[i]; i++ ) {
- ret.push( array[i] );
- }
- }
- }
-
- return ret;
- };
-}
-
-var sortOrder;
-
-if ( document.documentElement.compareDocumentPosition ) {
- sortOrder = function( a, b ) {
- if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return 0;
- }
-
- var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-} else if ( "sourceIndex" in document.documentElement ) {
- sortOrder = function( a, b ) {
- if ( !a.sourceIndex || !b.sourceIndex ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return 0;
- }
-
- var ret = a.sourceIndex - b.sourceIndex;
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-} else if ( document.createRange ) {
- sortOrder = function( a, b ) {
- if ( !a.ownerDocument || !b.ownerDocument ) {
- if ( a == b ) {
- hasDuplicate = true;
- }
- return 0;
- }
-
- var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
- aRange.setStart(a, 0);
- aRange.setEnd(a, 0);
- bRange.setStart(b, 0);
- bRange.setEnd(b, 0);
- var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
- if ( ret === 0 ) {
- hasDuplicate = true;
- }
- return ret;
- };
-}
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
- // We're going to inject a fake input element with a specified name
- var form = document.createElement("div"),
- id = "script" + (new Date).getTime();
- form.innerHTML = "";
-
- // Inject it into the root element, check its status, and remove it quickly
- var root = document.documentElement;
- root.insertBefore( form, root.firstChild );
-
- // The workaround has to do additional checks after a getElementById
- // Which slows things down for other browsers (hence the branching)
- if ( !!document.getElementById( id ) ) {
- Expr.find.ID = function(match, context, isXML){
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
- }
- };
-
- Expr.filter.ID = function(elem, match){
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
- return elem.nodeType === 1 && node && node.nodeValue === match;
- };
- }
-
- root.removeChild( form );
- root = form = null; // release memory in IE
-})();
-
-(function(){
- // Check to see if the browser returns only elements
- // when doing getElementsByTagName("*")
-
- // Create a fake element
- var div = document.createElement("div");
- div.appendChild( document.createComment("") );
-
- // Make sure no comments are found
- if ( div.getElementsByTagName("*").length > 0 ) {
- Expr.find.TAG = function(match, context){
- var results = context.getElementsByTagName(match[1]);
-
- // Filter out possible comments
- if ( match[1] === "*" ) {
- var tmp = [];
-
- for ( var i = 0; results[i]; i++ ) {
- if ( results[i].nodeType === 1 ) {
- tmp.push( results[i] );
- }
- }
-
- results = tmp;
- }
-
- return results;
- };
- }
-
- // Check to see if an attribute returns normalized href attributes
- div.innerHTML = "";
- if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
- div.firstChild.getAttribute("href") !== "#" ) {
- Expr.attrHandle.href = function(elem){
- return elem.getAttribute("href", 2);
- };
- }
-
- div = null; // release memory in IE
-})();
-
-if ( document.querySelectorAll ) (function(){
- var oldSizzle = Sizzle, div = document.createElement("div");
- div.innerHTML = "
";
-
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode.
- if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
- return;
- }
-
- Sizzle = function(query, context, extra, seed){
- context = context || document;
-
- // Only use querySelectorAll on non-XML documents
- // (ID selectors don't work in non-HTML documents)
- if ( !seed && context.nodeType === 9 && !isXML(context) ) {
- try {
- return makeArray( context.querySelectorAll(query), extra );
- } catch(e){}
- }
-
- return oldSizzle(query, context, extra, seed);
- };
-
- for ( var prop in oldSizzle ) {
- Sizzle[ prop ] = oldSizzle[ prop ];
- }
-
- div = null; // release memory in IE
-})();
-
-if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
- var div = document.createElement("div");
- div.innerHTML = "";
-
- // Opera can't find a second classname (in 9.6)
- if ( div.getElementsByClassName("e").length === 0 )
- return;
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
-
- if ( div.getElementsByClassName("e").length === 1 )
- return;
-
- Expr.order.splice(1, 0, "CLASS");
- Expr.find.CLASS = function(match, context, isXML) {
- if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
- return context.getElementsByClassName(match[1]);
- }
- };
-
- div = null; // release memory in IE
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- var sibDir = dir == "previousSibling" && !isXML;
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- if ( sibDir && elem.nodeType === 1 ){
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- elem = elem[dir];
- var match = false;
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 && !isXML ){
- elem.sizcache = doneName;
- elem.sizset = i;
- }
-
- if ( elem.nodeName === cur ) {
- match = elem;
- break;
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- var sibDir = dir == "previousSibling" && !isXML;
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
- if ( elem ) {
- if ( sibDir && elem.nodeType === 1 ) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- elem = elem[dir];
- var match = false;
-
- while ( elem ) {
- if ( elem.sizcache === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 ) {
- if ( !isXML ) {
- elem.sizcache = doneName;
- elem.sizset = i;
- }
- if ( typeof cur !== "string" ) {
- if ( elem === cur ) {
- match = true;
- break;
- }
-
- } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
- match = elem;
- break;
- }
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-var contains = document.compareDocumentPosition ? function(a, b){
- return a.compareDocumentPosition(b) & 16;
-} : function(a, b){
- return a !== b && (a.contains ? a.contains(b) : true);
-};
-
-var isXML = function(elem){
- return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
- !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
-};
-
-var posProcess = function(selector, context){
- var tmpSet = [], later = "", match,
- root = context.nodeType ? [context] : context;
-
- // Position selectors must be done after the filter
- // And so must :not(positional) so we move all PSEUDOs to the end
- while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
- later += match[0];
- selector = selector.replace( Expr.match.PSEUDO, "" );
- }
-
- selector = Expr.relative[selector] ? selector + "*" : selector;
-
- for ( var i = 0, l = root.length; i < l; i++ ) {
- Sizzle( selector, root[i], tmpSet );
- }
-
- return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-
-Firebug.Selector = Sizzle;
-
-/**#@-*/
-
-// ************************************************************************************************
-}});
-
-// Problems in IE
-// FIXED - eval return
-// FIXED - addEventListener problem in IE
-// FIXED doc.createRange?
-//
-// class reserved word
-// test all honza examples in IE6 and IE7
-
-
-/* See license.txt for terms of usage */
-
-( /** @scope s_domplate */ function() {
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/** @class */
-FBL.DomplateTag = function DomplateTag(tagName)
-{
- this.tagName = tagName;
-};
-
-/**
- * @class
- * @extends FBL.DomplateTag
- */
-FBL.DomplateEmbed = function DomplateEmbed()
-{
-};
-
-/**
- * @class
- * @extends FBL.DomplateTag
- */
-FBL.DomplateLoop = function DomplateLoop()
-{
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var DomplateTag = FBL.DomplateTag;
-var DomplateEmbed = FBL.DomplateEmbed;
-var DomplateLoop = FBL.DomplateLoop;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-var womb = null;
-
-FBL.domplate = function()
-{
- var lastSubject;
- for (var i = 0; i < arguments.length; ++i)
- lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i];
-
- for (var name in lastSubject)
- {
- var val = lastSubject[name];
- if (isTag(val))
- val.tag.subject = lastSubject;
- }
-
- return lastSubject;
-};
-
-var domplate = FBL.domplate;
-
-FBL.domplate.context = function(context, fn)
-{
- var lastContext = domplate.lastContext;
- domplate.topContext = context;
- fn.apply(context);
- domplate.topContext = lastContext;
-};
-
-FBL.TAG = function()
-{
- var embed = new DomplateEmbed();
- return embed.merge(arguments);
-};
-
-FBL.FOR = function()
-{
- var loop = new DomplateLoop();
- return loop.merge(arguments);
-};
-
-FBL.DomplateTag.prototype =
-{
- merge: function(args, oldTag)
- {
- if (oldTag)
- this.tagName = oldTag.tagName;
-
- this.context = oldTag ? oldTag.context : null;
- this.subject = oldTag ? oldTag.subject : null;
- this.attrs = oldTag ? copyObject(oldTag.attrs) : {};
- this.classes = oldTag ? copyObject(oldTag.classes) : {};
- this.props = oldTag ? copyObject(oldTag.props) : null;
- this.listeners = oldTag ? copyArray(oldTag.listeners) : null;
- this.children = oldTag ? copyArray(oldTag.children) : [];
- this.vars = oldTag ? copyArray(oldTag.vars) : [];
-
- var attrs = args.length ? args[0] : null;
- var hasAttrs = typeof(attrs) == "object" && !isTag(attrs);
-
- this.children = [];
-
- if (domplate.topContext)
- this.context = domplate.topContext;
-
- if (args.length)
- parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children);
-
- if (hasAttrs)
- this.parseAttrs(attrs);
-
- return creator(this, DomplateTag);
- },
-
- parseAttrs: function(args)
- {
- for (var name in args)
- {
- var val = parseValue(args[name]);
- readPartNames(val, this.vars);
-
- if (name.indexOf("on") == 0)
- {
- var eventName = name.substr(2);
- if (!this.listeners)
- this.listeners = [];
- this.listeners.push(eventName, val);
- }
- else if (name.indexOf("_") == 0)
- {
- var propName = name.substr(1);
- if (!this.props)
- this.props = {};
- this.props[propName] = val;
- }
- else if (name.indexOf("$") == 0)
- {
- var className = name.substr(1);
- if (!this.classes)
- this.classes = {};
- this.classes[className] = val;
- }
- else
- {
- if (name == "class" && this.attrs.hasOwnProperty(name) )
- this.attrs[name] += " " + val;
- else
- this.attrs[name] = val;
- }
- }
- },
-
- compile: function()
- {
- if (this.renderMarkup)
- return;
-
- this.compileMarkup();
- this.compileDOM();
-
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs);
- },
-
- compileMarkup: function()
- {
- this.markupArgs = [];
- var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0};
-
- this.generateMarkup(topBlock, topOuts, blocks, info);
- this.addCode(topBlock, topOuts, blocks);
-
- var fnBlock = ['r=(function (__code__, __context__, __in__, __out__'];
- for (var i = 0; i < info.argIndex; ++i)
- fnBlock.push(', s', i);
- fnBlock.push(') {');
-
- if (this.subject)
- fnBlock.push('with (this) {');
- if (this.context)
- fnBlock.push('with (__context__) {');
- fnBlock.push('with (__in__) {');
-
- fnBlock.push.apply(fnBlock, blocks);
-
- if (this.subject)
- fnBlock.push('}');
- if (this.context)
- fnBlock.push('}');
-
- fnBlock.push('}})');
-
- function __link__(tag, code, outputs, args)
- {
- if (!tag || !tag.tag)
- return;
-
- tag.tag.compile();
-
- var tagOutputs = [];
- var markupArgs = [code, tag.tag.context, args, tagOutputs];
- markupArgs.push.apply(markupArgs, tag.tag.markupArgs);
- tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs);
-
- outputs.push(tag);
- outputs.push(tagOutputs);
- }
-
- function __escape__(value)
- {
- function replaceChars(ch)
- {
- switch (ch)
- {
- case "<":
- return "<";
- case ">":
- return ">";
- case "&":
- return "&";
- case "'":
- return "'";
- case '"':
- return """;
- }
- return "?";
- };
- return String(value).replace(/[<>&"']/g, replaceChars);
- }
-
- function __loop__(iter, outputs, fn)
- {
- var iterOuts = [];
- outputs.push(iterOuts);
-
- if (iter instanceof Array)
- iter = new ArrayIterator(iter);
-
- try
- {
- while (1)
- {
- var value = iter.next();
- var itemOuts = [0,0];
- iterOuts.push(itemOuts);
- fn.apply(this, [value, itemOuts]);
- }
- }
- catch (exc)
- {
- if (exc != StopIteration)
- throw exc;
- }
- }
-
- var js = fnBlock.join("");
- var r = null;
- eval(js);
- this.renderMarkup = r;
- },
-
- getVarNames: function(args)
- {
- if (this.vars)
- args.push.apply(args, this.vars);
-
- for (var i = 0; i < this.children.length; ++i)
- {
- var child = this.children[i];
- if (isTag(child))
- child.tag.getVarNames(args);
- else if (child instanceof Parts)
- {
- for (var i = 0; i < child.parts.length; ++i)
- {
- if (child.parts[i] instanceof Variable)
- {
- var name = child.parts[i].name;
- var names = name.split(".");
- args.push(names[0]);
- }
- }
- }
- }
- },
-
- generateMarkup: function(topBlock, topOuts, blocks, info)
- {
- topBlock.push(',"<', this.tagName, '"');
-
- for (var name in this.attrs)
- {
- if (name != "class")
- {
- var val = this.attrs[name];
- topBlock.push(', " ', name, '=\\""');
- addParts(val, ',', topBlock, info, true);
- topBlock.push(', "\\""');
- }
- }
-
- if (this.listeners)
- {
- for (var i = 0; i < this.listeners.length; i += 2)
- readPartNames(this.listeners[i+1], topOuts);
- }
-
- if (this.props)
- {
- for (var name in this.props)
- readPartNames(this.props[name], topOuts);
- }
-
- if ( this.attrs.hasOwnProperty("class") || this.classes)
- {
- topBlock.push(', " class=\\""');
- if (this.attrs.hasOwnProperty("class"))
- addParts(this.attrs["class"], ',', topBlock, info, true);
- topBlock.push(', " "');
- for (var name in this.classes)
- {
- topBlock.push(', (');
- addParts(this.classes[name], '', topBlock, info);
- topBlock.push(' ? "', name, '" + " " : "")');
- }
- topBlock.push(', "\\""');
- }
- topBlock.push(',">"');
-
- this.generateChildMarkup(topBlock, topOuts, blocks, info);
- topBlock.push(',"', this.tagName, '>"');
- },
-
- generateChildMarkup: function(topBlock, topOuts, blocks, info)
- {
- for (var i = 0; i < this.children.length; ++i)
- {
- var child = this.children[i];
- if (isTag(child))
- child.tag.generateMarkup(topBlock, topOuts, blocks, info);
- else
- addParts(child, ',', topBlock, info, true);
- }
- },
-
- addCode: function(topBlock, topOuts, blocks)
- {
- if (topBlock.length)
- blocks.push('__code__.push(""', topBlock.join(""), ');');
- if (topOuts.length)
- blocks.push('__out__.push(', topOuts.join(","), ');');
- topBlock.splice(0, topBlock.length);
- topOuts.splice(0, topOuts.length);
- },
-
- addLocals: function(blocks)
- {
- var varNames = [];
- this.getVarNames(varNames);
-
- var map = {};
- for (var i = 0; i < varNames.length; ++i)
- {
- var name = varNames[i];
- if ( map.hasOwnProperty(name) )
- continue;
-
- map[name] = 1;
- var names = name.split(".");
- blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';');
- }
- },
-
- compileDOM: function()
- {
- var path = [];
- var blocks = [];
- this.domArgs = [];
- path.embedIndex = 0;
- path.loopIndex = 0;
- path.staticIndex = 0;
- path.renderIndex = 0;
- var nodeCount = this.generateDOM(path, blocks, this.domArgs);
-
- var fnBlock = ['r=(function (root, context, o'];
-
- for (var i = 0; i < path.staticIndex; ++i)
- fnBlock.push(', ', 's'+i);
-
- for (var i = 0; i < path.renderIndex; ++i)
- fnBlock.push(', ', 'd'+i);
-
- fnBlock.push(') {');
- for (var i = 0; i < path.loopIndex; ++i)
- fnBlock.push('var l', i, ' = 0;');
- for (var i = 0; i < path.embedIndex; ++i)
- fnBlock.push('var e', i, ' = 0;');
-
- if (this.subject)
- fnBlock.push('with (this) {');
- if (this.context)
- fnBlock.push('with (context) {');
-
- fnBlock.push(blocks.join(""));
-
- if (this.subject)
- fnBlock.push('}');
- if (this.context)
- fnBlock.push('}');
-
- fnBlock.push('return ', nodeCount, ';');
- fnBlock.push('})');
-
- function __bind__(object, fn)
- {
- return function(event) { return fn.apply(object, [event]); };
- }
-
- function __link__(node, tag, args)
- {
- if (!tag || !tag.tag)
- return;
-
- tag.tag.compile();
-
- var domArgs = [node, tag.tag.context, 0];
- domArgs.push.apply(domArgs, tag.tag.domArgs);
- domArgs.push.apply(domArgs, args);
- //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs);
- return tag.tag.renderDOM.apply(tag.tag.subject, domArgs);
- }
-
- var self = this;
- function __loop__(iter, fn)
- {
- var nodeCount = 0;
- for (var i = 0; i < iter.length; ++i)
- {
- iter[i][0] = i;
- iter[i][1] = nodeCount;
- nodeCount += fn.apply(this, iter[i]);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount);
- }
- return nodeCount;
- }
-
- function __path__(parent, offset)
- {
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n");
- var root = parent;
-
- for (var i = 2; i < arguments.length; ++i)
- {
- var index = arguments[i];
- if (i == 3)
- index += offset;
-
- if (index == -1)
- parent = parent.parentNode;
- else
- parent = parent.childNodes[index];
- }
-
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n");
- return parent;
- }
-
- var js = fnBlock.join("");
- //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n"));
- var r = null;
- eval(js);
- this.renderDOM = r;
- },
-
- generateDOM: function(path, blocks, args)
- {
- if (this.listeners || this.props)
- this.generateNodePath(path, blocks);
-
- if (this.listeners)
- {
- for (var i = 0; i < this.listeners.length; i += 2)
- {
- var val = this.listeners[i+1];
- var arg = generateArg(val, path, args);
- //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);');
- blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);');
- }
- }
-
- if (this.props)
- {
- for (var name in this.props)
- {
- var val = this.props[name];
- var arg = generateArg(val, path, args);
- blocks.push('node.', name, ' = ', arg, ';');
- }
- }
-
- this.generateChildDOM(path, blocks, args);
- return 1;
- },
-
- generateNodePath: function(path, blocks)
- {
- blocks.push("var node = __path__(root, o");
- for (var i = 0; i < path.length; ++i)
- blocks.push(",", path[i]);
- blocks.push(");");
- },
-
- generateChildDOM: function(path, blocks, args)
- {
- path.push(0);
- for (var i = 0; i < this.children.length; ++i)
- {
- var child = this.children[i];
- if (isTag(child))
- path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args);
- else
- path[path.length-1] += '+1';
- }
- path.pop();
- }
-};
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-FBL.DomplateEmbed.prototype = copyObject(FBL.DomplateTag.prototype,
-/** @lends FBL.DomplateEmbed.prototype */
-{
- merge: function(args, oldTag)
- {
- this.value = oldTag ? oldTag.value : parseValue(args[0]);
- this.attrs = oldTag ? oldTag.attrs : {};
- this.vars = oldTag ? copyArray(oldTag.vars) : [];
-
- var attrs = args[1];
- for (var name in attrs)
- {
- var val = parseValue(attrs[name]);
- this.attrs[name] = val;
- readPartNames(val, this.vars);
- }
-
- return creator(this, DomplateEmbed);
- },
-
- getVarNames: function(names)
- {
- if (this.value instanceof Parts)
- names.push(this.value.parts[0].name);
-
- if (this.vars)
- names.push.apply(names, this.vars);
- },
-
- generateMarkup: function(topBlock, topOuts, blocks, info)
- {
- this.addCode(topBlock, topOuts, blocks);
-
- blocks.push('__link__(');
- addParts(this.value, '', blocks, info);
- blocks.push(', __code__, __out__, {');
-
- var lastName = null;
- for (var name in this.attrs)
- {
- if (lastName)
- blocks.push(',');
- lastName = name;
-
- var val = this.attrs[name];
- blocks.push('"', name, '":');
- addParts(val, '', blocks, info);
- }
-
- blocks.push('});');
- //this.generateChildMarkup(topBlock, topOuts, blocks, info);
- },
-
- generateDOM: function(path, blocks, args)
- {
- var embedName = 'e'+path.embedIndex++;
-
- this.generateNodePath(path, blocks);
-
- var valueName = 'd' + path.renderIndex++;
- var argsName = 'd' + path.renderIndex++;
- blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');');
-
- return embedName;
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-FBL.DomplateLoop.prototype = copyObject(FBL.DomplateTag.prototype,
-/** @lends FBL.DomplateLoop.prototype */
-{
- merge: function(args, oldTag)
- {
- this.varName = oldTag ? oldTag.varName : args[0];
- this.iter = oldTag ? oldTag.iter : parseValue(args[1]);
- this.vars = [];
-
- this.children = oldTag ? copyArray(oldTag.children) : [];
-
- var offset = Math.min(args.length, 2);
- parseChildren(args, offset, this.vars, this.children);
-
- return creator(this, DomplateLoop);
- },
-
- getVarNames: function(names)
- {
- if (this.iter instanceof Parts)
- names.push(this.iter.parts[0].name);
-
- DomplateTag.prototype.getVarNames.apply(this, [names]);
- },
-
- generateMarkup: function(topBlock, topOuts, blocks, info)
- {
- this.addCode(topBlock, topOuts, blocks);
-
- var iterName;
- if (this.iter instanceof Parts)
- {
- var part = this.iter.parts[0];
- iterName = part.name;
-
- if (part.format)
- {
- for (var i = 0; i < part.format.length; ++i)
- iterName = part.format[i] + "(" + iterName + ")";
- }
- }
- else
- iterName = this.iter;
-
- blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {');
- this.generateChildMarkup(topBlock, topOuts, blocks, info);
- this.addCode(topBlock, topOuts, blocks);
- blocks.push('}]);');
- },
-
- generateDOM: function(path, blocks, args)
- {
- var iterName = 'd'+path.renderIndex++;
- var counterName = 'i'+path.loopIndex;
- var loopName = 'l'+path.loopIndex++;
-
- if (!path.length)
- path.push(-1, 0);
-
- var preIndex = path.renderIndex;
- path.renderIndex = 0;
-
- var nodeCount = 0;
-
- var subBlocks = [];
- var basePath = path[path.length-1];
- for (var i = 0; i < this.children.length; ++i)
- {
- path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount;
-
- var child = this.children[i];
- if (isTag(child))
- nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args);
- else
- nodeCount += '+1';
- }
-
- path[path.length-1] = basePath+'+'+loopName;
-
- blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName);
- for (var i = 0; i < path.renderIndex; ++i)
- blocks.push(',d'+i);
- blocks.push(') {');
- blocks.push(subBlocks.join(""));
- blocks.push('return ', nodeCount, ';');
- blocks.push('}]);');
-
- path.renderIndex = preIndex;
-
- return loopName;
- }
-});
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/** @class */
-function Variable(name, format)
-{
- this.name = name;
- this.format = format;
-}
-
-/** @class */
-function Parts(parts)
-{
- this.parts = parts;
-}
-
-// ************************************************************************************************
-
-function parseParts(str)
-{
- var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g;
- var index = 0;
- var parts = [];
-
- var m;
- while (m = re.exec(str))
- {
- var pre = str.substr(index, (re.lastIndex-m[0].length)-index);
- if (pre)
- parts.push(pre);
-
- var expr = m[1].split("|");
- parts.push(new Variable(expr[0], expr.slice(1)));
- index = re.lastIndex;
- }
-
- if (!index)
- return str;
-
- var post = str.substr(index);
- if (post)
- parts.push(post);
-
- return new Parts(parts);
-}
-
-function parseValue(val)
-{
- return typeof(val) == 'string' ? parseParts(val) : val;
-}
-
-function parseChildren(args, offset, vars, children)
-{
- for (var i = offset; i < args.length; ++i)
- {
- var val = parseValue(args[i]);
- children.push(val);
- readPartNames(val, vars);
- }
-}
-
-function readPartNames(val, vars)
-{
- if (val instanceof Parts)
- {
- for (var i = 0; i < val.parts.length; ++i)
- {
- var part = val.parts[i];
- if (part instanceof Variable)
- vars.push(part.name);
- }
- }
-}
-
-function generateArg(val, path, args)
-{
- if (val instanceof Parts)
- {
- var vals = [];
- for (var i = 0; i < val.parts.length; ++i)
- {
- var part = val.parts[i];
- if (part instanceof Variable)
- {
- var varName = 'd'+path.renderIndex++;
- if (part.format)
- {
- for (var j = 0; j < part.format.length; ++j)
- varName = part.format[j] + '(' + varName + ')';
- }
-
- vals.push(varName);
- }
- else
- vals.push('"'+part.replace(/"/g, '\\"')+'"');
- }
-
- return vals.join('+');
- }
- else
- {
- args.push(val);
- return 's' + path.staticIndex++;
- }
-}
-
-function addParts(val, delim, block, info, escapeIt)
-{
- var vals = [];
- if (val instanceof Parts)
- {
- for (var i = 0; i < val.parts.length; ++i)
- {
- var part = val.parts[i];
- if (part instanceof Variable)
- {
- var partName = part.name;
- if (part.format)
- {
- for (var j = 0; j < part.format.length; ++j)
- partName = part.format[j] + "(" + partName + ")";
- }
-
- if (escapeIt)
- vals.push("__escape__(" + partName + ")");
- else
- vals.push(partName);
- }
- else
- vals.push('"'+ part + '"');
- }
- }
- else if (isTag(val))
- {
- info.args.push(val);
- vals.push('s'+info.argIndex++);
- }
- else
- vals.push('"'+ val + '"');
-
- var parts = vals.join(delim);
- if (parts)
- block.push(delim, parts);
-}
-
-function isTag(obj)
-{
- return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag;
-}
-
-function creator(tag, cons)
-{
- var fn = new Function(
- "var tag = arguments.callee.tag;" +
- "var cons = arguments.callee.cons;" +
- "var newTag = new cons();" +
- "return newTag.merge(arguments, tag);");
-
- fn.tag = tag;
- fn.cons = cons;
- extend(fn, Renderer);
-
- return fn;
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-function copyArray(oldArray)
-{
- var ary = [];
- if (oldArray)
- for (var i = 0; i < oldArray.length; ++i)
- ary.push(oldArray[i]);
- return ary;
-}
-
-function copyObject(l, r)
-{
- var m = {};
- extend(m, l);
- extend(m, r);
- return m;
-}
-
-function extend(l, r)
-{
- for (var n in r)
- l[n] = r[n];
-}
-
-function addEvent(object, name, handler)
-{
- if (document.all)
- object.attachEvent("on"+name, handler);
- else
- object.addEventListener(name, handler, false);
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
-/** @class */
-function ArrayIterator(array)
-{
- var index = -1;
-
- this.next = function()
- {
- if (++index >= array.length)
- throw StopIteration;
-
- return array[index];
- };
-}
-
-/** @class */
-function StopIteration() {}
-
-FBL.$break = function()
-{
- throw StopIteration;
-};
-
-// ************************************************************************************************
-
-/** @namespace */
-var Renderer =
-{
- renderHTML: function(args, outputs, self)
- {
- var code = [];
- var markupArgs = [code, this.tag.context, args, outputs];
- markupArgs.push.apply(markupArgs, this.tag.markupArgs);
- this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs);
- return code.join("");
- },
-
- insertRows: function(args, before, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- var doc = before.ownerDocument;
- var div = doc.createElement("div");
- div.innerHTML = "";
-
- var tbody = div.firstChild.firstChild;
- var parent = before.tagName == "TR" ? before.parentNode : before;
- var after = before.tagName == "TR" ? before.nextSibling : null;
-
- var firstRow = tbody.firstChild, lastRow;
- while (tbody.firstChild)
- {
- lastRow = tbody.firstChild;
- if (after)
- parent.insertBefore(lastRow, after);
- else
- parent.appendChild(lastRow);
- }
-
- var offset = 0;
- if (before.tagName == "TR")
- {
- var node = firstRow.parentNode.firstChild;
- for (; node && node != firstRow; node = node.nextSibling)
- ++offset;
- }
-
- var domArgs = [firstRow, this.tag.context, offset];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
- return [firstRow, lastRow];
- },
-
- insertBefore: function(args, before, self)
- {
- return this.insertNode(args, before.ownerDocument, before, false, self);
- },
-
- insertAfter: function(args, after, self)
- {
- return this.insertNode(args, after.ownerDocument, after, true, self);
- },
-
- insertNode: function(args, doc, element, isAfter, self)
- {
- if (!args)
- args = {};
-
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- //if (FBTrace.DBG_DOM)
- // FBTrace.sysout("domplate.insertNode html: "+html+"\n");
-
- var doc = element.ownerDocument;
- if (!womb || womb.ownerDocument != doc)
- womb = doc.createElement("div");
-
- womb.innerHTML = html;
-
- var root = womb.firstChild;
- if (isAfter)
- {
- while (womb.firstChild)
- if (element.nextSibling)
- element.parentNode.insertBefore(womb.firstChild, element.nextSibling);
- else
- element.parentNode.appendChild(womb.firstChild);
- }
- else
- {
- while (womb.lastChild)
- element.parentNode.insertBefore(womb.lastChild, element);
- }
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- //if (FBTrace.DBG_DOM)
- // FBTrace.sysout("domplate.insertNode domArgs:", domArgs);
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
-
- return root;
- },
- /**/
-
- /*
- insertAfter: function(args, before, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- var doc = before.ownerDocument;
- if (!womb || womb.ownerDocument != doc)
- womb = doc.createElement("div");
-
- womb.innerHTML = html;
-
- var root = womb.firstChild;
- while (womb.firstChild)
- if (before.nextSibling)
- before.parentNode.insertBefore(womb.firstChild, before.nextSibling);
- else
- before.parentNode.appendChild(womb.firstChild);
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null),
- domArgs);
-
- return root;
- },
- /**/
-
- replace: function(args, parent, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
-
- var root;
- if (parent.nodeType == 1)
- {
- parent.innerHTML = html;
- root = parent.firstChild;
- }
- else
- {
- if (!parent || parent.nodeType != 9)
- parent = document;
-
- if (!womb || womb.ownerDocument != parent)
- womb = parent.createElement("div");
- womb.innerHTML = html;
-
- root = womb.firstChild;
- //womb.removeChild(root);
- }
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
-
- return root;
- },
-
- append: function(args, parent, self)
- {
- this.tag.compile();
-
- var outputs = [];
- var html = this.renderHTML(args, outputs, self);
- //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n");
-
- if (!womb || womb.ownerDocument != parent.ownerDocument)
- womb = parent.ownerDocument.createElement("div");
- womb.innerHTML = html;
-
- // TODO: xxxpedro domplate port to Firebug
- var root = womb.firstChild;
- while (womb.firstChild)
- parent.appendChild(womb.firstChild);
-
- // clearing element reference to avoid reference error in IE8 when switching contexts
- womb = null;
-
- var domArgs = [root, this.tag.context, 0];
- domArgs.push.apply(domArgs, this.tag.domArgs);
- domArgs.push.apply(domArgs, outputs);
-
- //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs);
- this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
-
- return root;
- }
-};
-
-// ************************************************************************************************
-
-function defineTags()
-{
- for (var i = 0; i < arguments.length; ++i)
- {
- var tagName = arguments[i];
- var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);");
- fn.DomplateTag = DomplateTag;
-
- var fnName = tagName.toUpperCase();
- FBL[fnName] = fn;
- }
-}
-
-defineTags(
- "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr",
- "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select",
- "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe"
-);
-
-})();
-
-
-/* See license.txt for terms of usage */
-
-var FirebugReps = FBL.ns(function() { with (FBL) {
-
-
-// ************************************************************************************************
-// Common Tags
-
-var OBJECTBOX = this.OBJECTBOX =
- SPAN({"class": "objectBox objectBox-$className"});
-
-var OBJECTBLOCK = this.OBJECTBLOCK =
- DIV({"class": "objectBox objectBox-$className"});
-
-var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation
- A({
- "class": "objectLink objectLink-$className a11yFocus",
- href: "javascript:void(0)",
- // workaround to show XPath (a better approach would use the tooltip on mouseover,
- // so the XPath information would be calculated dynamically, but we need to create
- // a tooltip class/wrapper around Menu or InfoTip)
- title: "$object|FBL.getElementXPath",
- _repObject: "$object"
- })
- : // Other browsers
- A({
- "class": "objectLink objectLink-$className a11yFocus",
- // workaround to show XPath (a better approach would use the tooltip on mouseover,
- // so the XPath information would be calculated dynamically, but we need to create
- // a tooltip class/wrapper around Menu or InfoTip)
- title: "$object|FBL.getElementXPath",
- _repObject: "$object"
- });
-
-
-// ************************************************************************************************
-
-this.Undefined = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("undefined"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "undefined",
-
- supportsObject: function(object, type)
- {
- return type == "undefined";
- }
-});
-
-// ************************************************************************************************
-
-this.Null = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("null"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "null",
-
- supportsObject: function(object, type)
- {
- return object == null;
- }
-});
-
-// ************************************************************************************************
-
-this.Nada = domplate(Firebug.Rep,
-{
- tag: SPAN(""),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "nada"
-});
-
-// ************************************************************************************************
-
-this.Number = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("$object"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "number",
-
- supportsObject: function(object, type)
- {
- return type == "boolean" || type == "number";
- }
-});
-
-// ************************************************************************************************
-
-this.String = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX(""$object""),
-
- shortTag: OBJECTBOX(""$object|cropString""),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "string",
-
- supportsObject: function(object, type)
- {
- return type == "string";
- }
-});
-
-// ************************************************************************************************
-
-this.Text = domplate(Firebug.Rep,
-{
- tag: OBJECTBOX("$object"),
-
- shortTag: OBJECTBOX("$object|cropString"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "text"
-});
-
-// ************************************************************************************************
-
-this.Caption = domplate(Firebug.Rep,
-{
- tag: SPAN({"class": "caption"}, "$object")
-});
-
-// ************************************************************************************************
-
-this.Warning = domplate(Firebug.Rep,
-{
- tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR")
-});
-
-// ************************************************************************************************
-
-this.Func = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK("$object|summarizeFunction"),
-
- summarizeFunction: function(fn)
- {
- var fnRegex = /function ([^(]+\([^)]*\)) \{/;
- var fnText = safeToString(fn);
-
- var m = fnRegex.exec(fnText);
- return m ? m[1] : "function()";
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- copySource: function(fn)
- {
- copyToClipboard(safeToString(fn));
- },
-
- monitor: function(fn, script, monitored)
- {
- if (monitored)
- Firebug.Debugger.unmonitorScript(fn, script, "monitor");
- else
- Firebug.Debugger.monitorScript(fn, script, "monitor");
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "function",
-
- supportsObject: function(object, type)
- {
- return isFunction(object);
- },
-
- inspectObject: function(fn, context)
- {
- var sourceLink = findSourceForFunction(fn, context);
- if (sourceLink)
- Firebug.chrome.select(sourceLink);
- if (FBTrace.DBG_FUNCTION_NAME)
- FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink);
- },
-
- getTooltip: function(fn, context)
- {
- var script = findScriptForFunctionInContext(context, fn);
- if (script)
- return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]);
- else
- if (fn.toString)
- return fn.toString();
- },
-
- getTitle: function(fn, context)
- {
- var name = fn.name ? fn.name : "function";
- return name + "()";
- },
-
- getContextMenuItems: function(fn, target, context, script)
- {
- if (!script)
- script = findScriptForFunctionInContext(context, fn);
- if (!script)
- return;
-
- var scriptInfo = getSourceFileAndLineByScript(context, script);
- var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
-
- var name = script ? getFunctionName(script, context) : fn.name;
- return [
- {label: "CopySource", command: bindFixed(this.copySource, this, fn) },
- "-",
- {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
- type: "checkbox", checked: monitored,
- command: bindFixed(this.monitor, this, fn, script, monitored) }
- ];
- }
-});
-
-// ************************************************************************************************
-/*
-this.jsdScript = domplate(Firebug.Rep,
-{
- copySource: function(script)
- {
- var fn = script.functionObject.getWrappedValue();
- return FirebugReps.Func.copySource(fn);
- },
-
- monitor: function(fn, script, monitored)
- {
- fn = script.functionObject.getWrappedValue();
- return FirebugReps.Func.monitor(fn, script, monitored);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "jsdScript",
- inspectable: false,
-
- supportsObject: function(object, type)
- {
- return object instanceof jsdIScript;
- },
-
- inspectObject: function(script, context)
- {
- var sourceLink = getSourceLinkForScript(script, context);
- if (sourceLink)
- Firebug.chrome.select(sourceLink);
- },
-
- getRealObject: function(script, context)
- {
- return script;
- },
-
- getTooltip: function(script)
- {
- return $STRF("jsdIScript", [script.tag]);
- },
-
- getTitle: function(script, context)
- {
- var fn = script.functionObject.getWrappedValue();
- return FirebugReps.Func.getTitle(fn, context);
- },
-
- getContextMenuItems: function(script, target, context)
- {
- var fn = script.functionObject.getWrappedValue();
-
- var scriptInfo = getSourceFileAndLineByScript(context, script);
- var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
-
- var name = getFunctionName(script, context);
-
- return [
- {label: "CopySource", command: bindFixed(this.copySource, this, script) },
- "-",
- {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
- type: "checkbox", checked: monitored,
- command: bindFixed(this.monitor, this, fn, script, monitored) }
- ];
- }
-});
-/**/
-//************************************************************************************************
-
-this.Obj = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK(
- SPAN({"class": "objectTitle"}, "$object|getTitle "),
-
- SPAN({"class": "objectProps"},
- SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"),
- FOR("prop", "$object|propIterator",
- SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"),
- SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"),
- TAG("$prop.tag", {object: "$prop.object"}),
- SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim")
- ),
- SPAN({"class": "objectRightBrace"}, "}")
- )
- ),
-
- propNumberTag:
- SPAN({"class": "objectProp-number"}, "$object"),
-
- propStringTag:
- SPAN({"class": "objectProp-string"}, ""$object""),
-
- propObjectTag:
- SPAN({"class": "objectProp-object"}, "$object"),
-
- propIterator: function (object)
- {
- ///Firebug.ObjectShortIteratorMax;
- var maxLength = 55; // default max length for long representation
-
- if (!object)
- return [];
-
- var props = [];
- var length = 0;
-
- var numProperties = 0;
- var numPropertiesShown = 0;
- var maxLengthReached = false;
-
- var lib = this;
-
- var propRepsMap =
- {
- "boolean": this.propNumberTag,
- "number": this.propNumberTag,
- "string": this.propStringTag,
- "object": this.propObjectTag
- };
-
- try
- {
- var title = Firebug.Rep.getTitle(object);
- length += title.length;
-
- for (var name in object)
- {
- var value;
- try
- {
- value = object[name];
- }
- catch (exc)
- {
- continue;
- }
-
- var type = typeof(value);
- if (type == "boolean" ||
- type == "number" ||
- (type == "string" && value) ||
- (type == "object" && value && value.toString))
- {
- var tag = propRepsMap[type];
-
- var value = (type == "object") ?
- Firebug.getRep(value).getTitle(value) :
- value + "";
-
- length += name.length + value.length + 4;
-
- if (length <= maxLength)
- {
- props.push({
- tag: tag,
- name: name,
- object: value,
- equal: "=",
- delim: ", "
- });
-
- numPropertiesShown++;
- }
- else
- maxLengthReached = true;
-
- }
-
- numProperties++;
-
- if (maxLengthReached && numProperties > numPropertiesShown)
- break;
- }
-
- if (numProperties > numPropertiesShown)
- {
- props.push({
- object: "...", //xxxHonza localization
- tag: FirebugReps.Caption.tag,
- name: "",
- equal:"",
- delim:""
- });
- }
- else if (props.length > 0)
- {
- props[props.length-1].delim = '';
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions when trying to read from certain objects, like
- // StorageList, but don't let that gum up the works
- // XXXjjb also History.previous fails because object is a web-page object which does not have
- // permission to read the history
- }
- return props;
- },
-
- fb_1_6_propIterator: function (object, max)
- {
- max = max || 3;
- if (!object)
- return [];
-
- var props = [];
- var len = 0, count = 0;
-
- try
- {
- for (var name in object)
- {
- var value;
- try
- {
- value = object[name];
- }
- catch (exc)
- {
- continue;
- }
-
- var t = typeof(value);
- if (t == "boolean" || t == "number" || (t == "string" && value)
- || (t == "object" && value && value.toString))
- {
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag || rep.tag;
- if (t == "object")
- {
- value = rep.getTitle(value);
- tag = rep.titleTag;
- }
- count++;
- if (count <= max)
- props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "});
- else
- break;
- }
- }
- if (count > max)
- {
- props[Math.max(1,max-1)] = {
- object: "more...", //xxxHonza localization
- tag: FirebugReps.Caption.tag,
- name: "",
- equal:"",
- delim:""
- };
- }
- else if (props.length > 0)
- {
- props[props.length-1].delim = '';
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions when trying to read from certain objects, like
- // StorageList, but don't let that gum up the works
- // XXXjjb also History.previous fails because object is a web-page object which does not have
- // permission to read the history
- }
- return props;
- },
-
- /*
- propIterator: function (object)
- {
- if (!object)
- return [];
-
- var props = [];
- var len = 0;
-
- try
- {
- for (var name in object)
- {
- var val;
- try
- {
- val = object[name];
- }
- catch (exc)
- {
- continue;
- }
-
- var t = typeof val;
- if (t == "boolean" || t == "number" || (t == "string" && val)
- || (t == "object" && !isFunction(val) && val && val.toString))
- {
- var title = (t == "object")
- ? Firebug.getRep(val).getTitle(val)
- : val+"";
-
- len += name.length + title.length + 1;
- if (len < 50)
- props.push({name: name, value: title});
- else
- break;
- }
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions when trying to read from certain objects, like
- // StorageList, but don't let that gum up the works
- // XXXjjb also History.previous fails because object is a web-page object which does not have
- // permission to read the history
- }
-
- return props;
- },
- /**/
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "object",
-
- supportsObject: function(object, type)
- {
- return true;
- }
-});
-
-
-// ************************************************************************************************
-
-this.Arr = domplate(Firebug.Rep,
-{
- tag:
- OBJECTBOX({_repObject: "$object"},
- SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
- FOR("item", "$object|arrayIterator",
- TAG("$item.tag", {object: "$item.object"}),
- SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
- ),
- SPAN({"class": "arrayRightBracket", role : "presentation"}, "]")
- ),
-
- shortTag:
- OBJECTBOX({_repObject: "$object"},
- SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
- FOR("item", "$object|shortArrayIterator",
- TAG("$item.tag", {object: "$item.object"}),
- SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
- ),
- // TODO: xxxpedro - confirm this on Firebug
- //FOR("prop", "$object|shortPropIterator",
- // " $prop.name=",
- // SPAN({"class": "objectPropValue"}, "$prop.value|cropString")
- //),
- SPAN({"class": "arrayRightBracket"}, "]")
- ),
-
- arrayIterator: function(array)
- {
- var items = [];
- for (var i = 0; i < array.length; ++i)
- {
- var value = array[i];
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag ? rep.shortTag : rep.tag;
- var delim = (i == array.length-1 ? "" : ", ");
-
- items.push({object: value, tag: tag, delim: delim});
- }
-
- return items;
- },
-
- shortArrayIterator: function(array)
- {
- var items = [];
- for (var i = 0; i < array.length && i < 3; ++i)
- {
- var value = array[i];
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag ? rep.shortTag : rep.tag;
- var delim = (i == array.length-1 ? "" : ", ");
-
- items.push({object: value, tag: tag, delim: delim});
- }
-
- if (array.length > 3)
- items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""});
-
- return items;
- },
-
- shortPropIterator: this.Obj.propIterator,
-
- getItemIndex: function(child)
- {
- var arrayIndex = 0;
- for (child = child.previousSibling; child; child = child.previousSibling)
- {
- if (child.repObject)
- ++arrayIndex;
- }
- return arrayIndex;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "array",
-
- supportsObject: function(object)
- {
- return this.isArray(object);
- },
-
- // http://code.google.com/p/fbug/issues/detail?id=874
- // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007
- isArray: function(obj) {
- try {
- if (!obj)
- return false;
- else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8)
- return true;
- else if (isFinite(obj.length) && isFunction(obj.splice))
- return true;
- else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments
- return true;
- else if (instanceOf(obj, "HTMLCollection"))
- return true;
- else if (instanceOf(obj, "NodeList"))
- return true;
- else
- return false;
- }
- catch(exc)
- {
- if (FBTrace.DBG_ERRORS)
- {
- FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */
- FBTrace.sysout("isArray Fails on obj", obj);
- }
- }
-
- return false;
- },
- // END Yahoo BSD SOURCE See license below.
-
- getTitle: function(object, context)
- {
- return "[" + object.length + "]";
- }
-});
-
-// ************************************************************************************************
-
-this.Property = domplate(Firebug.Rep,
-{
- supportsObject: function(object)
- {
- return object instanceof Property;
- },
-
- getRealObject: function(prop, context)
- {
- return prop.object[prop.name];
- },
-
- getTitle: function(prop, context)
- {
- return prop.name;
- }
-});
-
-// ************************************************************************************************
-
-this.NetFile = domplate(this.Obj,
-{
- supportsObject: function(object)
- {
- return object instanceof Firebug.NetFile;
- },
-
- browseObject: function(file, context)
- {
- openNewTab(file.href);
- return true;
- },
-
- getRealObject: function(file, context)
- {
- return null;
- }
-});
-
-// ************************************************************************************************
-
-this.Except = domplate(Firebug.Rep,
-{
- tag:
- OBJECTBOX({_repObject: "$object"}, "$object.message"),
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-
- className: "exception",
-
- supportsObject: function(object)
- {
- return object instanceof ErrorCopy;
- }
-});
-
-
-// ************************************************************************************************
-
-this.Element = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK(
- "<",
- SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"),
- FOR("attr", "$object|attrIterator",
- " $attr.nodeName="", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), """
- ),
- ">"
- ),
-
- shortTag:
- OBJECTLINK(
- SPAN({"class": "$object|getVisible"},
- SPAN({"class": "selectorTag"}, "$object|getSelectorTag"),
- SPAN({"class": "selectorId"}, "$object|getSelectorId"),
- SPAN({"class": "selectorClass"}, "$object|getSelectorClass"),
- SPAN({"class": "selectorValue"}, "$object|getValue")
- )
- ),
-
- getVisible: function(elt)
- {
- return isVisible(elt) ? "" : "selectorHidden";
- },
-
- getSelectorTag: function(elt)
- {
- return elt.nodeName.toLowerCase();
- },
-
- getSelectorId: function(elt)
- {
- return elt.id ? "#" + elt.id : "";
- },
-
- getSelectorClass: function(elt)
- {
- return elt.className ? "." + elt.className.split(" ")[0] : "";
- },
-
- getValue: function(elt)
- {
- // TODO: xxxpedro
- return "";
- var value;
- if (elt instanceof HTMLImageElement)
- value = getFileName(elt.src);
- else if (elt instanceof HTMLAnchorElement)
- value = getFileName(elt.href);
- else if (elt instanceof HTMLInputElement)
- value = elt.value;
- else if (elt instanceof HTMLFormElement)
- value = getFileName(elt.action);
- else if (elt instanceof HTMLScriptElement)
- value = getFileName(elt.src);
-
- return value ? " " + cropString(value, 20) : "";
- },
-
- attrIterator: function(elt)
- {
- var attrs = [];
- var idAttr, classAttr;
- if (elt.attributes)
- {
- for (var i = 0; i < elt.attributes.length; ++i)
- {
- var attr = elt.attributes[i];
-
- // we must check if the attribute is specified otherwise IE will show them
- if (!attr.specified || attr.nodeName && attr.nodeName.indexOf("firebug-") != -1)
- continue;
- else if (attr.nodeName == "id")
- idAttr = attr;
- else if (attr.nodeName == "class")
- classAttr = attr;
- else if (attr.nodeName == "style")
- attrs.push({
- nodeName: attr.nodeName,
- nodeValue: attr.nodeValue ||
- // IE won't recognize the attr.nodeValue of ';
+ /**/
+
+ r[++i] = '';
+ r[++i] = tpl.HTML;
+ r[++i] = '';
+
+ return r.join("");
+ };
+
+
+ // ************************************************************************************************
+ // Chrome Class
+
+ /**@class*/
+ var Chrome = function Chrome(chrome)
+ {
+ var type = chrome.type;
+ var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase;
+
+ append(this, Base); // inherit from base class (ChromeFrameBase or ChromePopupBase)
+ append(this, chrome); // inherit chrome window properties
+ append(this, new Context(chrome.window)); // inherit from Context class
+
+ FirebugChrome.chromeMap[type] = this;
+ Firebug.chrome = this;
+ Env.chrome = chrome.window;
+
+ this.commandLineVisible = false;
+ this.sidePanelVisible = false;
+
+ this.create();
+
+ return this;
+ };
+
+ // ************************************************************************************************
+ // ChromeBase
+
+ /**
+ * @namespace
+ * @extends FBL.Controller
+ * @extends FBL.PanelBar
+ **/
+ var ChromeBase = {};
+ append(ChromeBase, Controller);
+ append(ChromeBase, PanelBar);
+ append(ChromeBase,
+ /**@extend ns-chrome-ChromeBase*/
+ {
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // inherited properties
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // inherited from createChrome function
+
+ node: null,
+ type: null,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // inherited from Context.prototype
+
+ document: null,
+ window: null,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // value properties
+
+ sidePanelVisible: false,
+ commandLineVisible: false,
+ largeCommandLineVisible: false,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // object properties
+
+ inspectButton: null,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ create: function()
+ {
+ PanelBar.create.call(this);
+
+ if (Firebug.Inspector)
+ this.inspectButton = new Button({
+ type: "toggle",
+ element: $("fbChrome_btInspect"),
+ owner: Firebug.Inspector,
+
+ onPress: Firebug.Inspector.startInspecting,
+ onUnpress: Firebug.Inspector.stopInspecting
+ });
+ },
+
+ destroy: function()
+ {
+ if(Firebug.Inspector)
+ this.inspectButton.destroy();
+
+ PanelBar.destroy.call(this);
+
+ this.shutdown();
+ },
+
+ testMenu: function()
+ {
+ var firebugMenu = new Menu(
+ {
+ id: "fbFirebugMenu",
+
+ items:
+ [
+ {
+ label: "Open Firebug",
+ type: "shortcut",
+ key: isFirefox ? "Shift+F12" : "F12",
+ checked: true,
+ command: "toggleChrome"
+ },
+ {
+ label: "Open Firebug in New Window",
+ type: "shortcut",
+ key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12",
+ command: "openPopup"
+ },
+ {
+ label: "Inspect Element",
+ type: "shortcut",
+ key: "Ctrl+Shift+C",
+ command: "toggleInspect"
+ },
+ {
+ label: "Command Line",
+ type: "shortcut",
+ key: "Ctrl+Shift+L",
+ command: "focusCommandLine"
+ },
+ "-",
+ {
+ label: "Options",
+ type: "group",
+ child: "fbFirebugOptionsMenu"
+ },
+ "-",
+ {
+ label: "Firebug Lite Website...",
+ command: "visitWebsite"
+ },
+ {
+ label: "Discussion Group...",
+ command: "visitDiscussionGroup"
+ },
+ {
+ label: "Issue Tracker...",
+ command: "visitIssueTracker"
+ }
+ ],
+
+ onHide: function()
+ {
+ iconButton.restore();
+ },
+
+ toggleChrome: function()
+ {
+ Firebug.chrome.toggle();
+ },
+
+ openPopup: function()
+ {
+ Firebug.chrome.toggle(true, true);
+ },
+
+ toggleInspect: function()
+ {
+ Firebug.Inspector.toggleInspect();
+ },
+
+ focusCommandLine: function()
+ {
+ Firebug.chrome.focusCommandLine();
+ },
+
+ visitWebsite: function()
+ {
+ this.visit("http://getfirebug.com/lite.html");
+ },
+
+ visitDiscussionGroup: function()
+ {
+ this.visit("http://groups.google.com/group/firebug");
+ },
+
+ visitIssueTracker: function()
+ {
+ this.visit("http://code.google.com/p/fbug/issues/list");
+ },
+
+ visit: function(url)
+ {
+ window.open(url);
+ }
+
+ });
+
+ /**@private*/
+ var firebugOptionsMenu =
+ {
+ id: "fbFirebugOptionsMenu",
+
+ getItems: function()
+ {
+ var cookiesDisabled = !Firebug.saveCookies;
+
+ return [
+ {
+ label: "Save Options in Cookies",
+ type: "checkbox",
+ value: "saveCookies",
+ checked: Firebug.saveCookies,
+ command: "saveOptions"
+ },
+ "-",
+ {
+ label: "Start Opened",
+ type: "checkbox",
+ value: "startOpened",
+ checked: Firebug.startOpened,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Start in New Window",
+ type: "checkbox",
+ value: "startInNewWindow",
+ checked: Firebug.startInNewWindow,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Show Icon When Hidden",
+ type: "checkbox",
+ value: "showIconWhenHidden",
+ checked: Firebug.showIconWhenHidden,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Override Console Object",
+ type: "checkbox",
+ value: "overrideConsole",
+ checked: Firebug.overrideConsole,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Ignore Firebug Elements",
+ type: "checkbox",
+ value: "ignoreFirebugElements",
+ checked: Firebug.ignoreFirebugElements,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Disable When Firebug Active",
+ type: "checkbox",
+ value: "disableWhenFirebugActive",
+ checked: Firebug.disableWhenFirebugActive,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Disable XHR Listener",
+ type: "checkbox",
+ value: "disableXHRListener",
+ checked: Firebug.disableXHRListener,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Enable Trace Mode",
+ type: "checkbox",
+ value: "enableTrace",
+ checked: Firebug.enableTrace,
+ disabled: cookiesDisabled
+ },
+ {
+ label: "Enable Persistent Mode (experimental)",
+ type: "checkbox",
+ value: "enablePersistent",
+ checked: Firebug.enablePersistent,
+ disabled: cookiesDisabled
+ },
+ "-",
+ {
+ label: "Reset All Firebug Options",
+ command: "restorePrefs",
+ disabled: cookiesDisabled
+ }
+ ];
+ },
+
+ onCheck: function(target, value, checked)
+ {
+ Firebug.setPref(value, checked);
+ },
+
+ saveOptions: function(target)
+ {
+ var saveEnabled = target.getAttribute("checked");
+
+ if (!saveEnabled) this.restorePrefs();
+
+ this.updateMenu(target);
+
+ return false;
+ },
+
+ restorePrefs: function(target)
+ {
+ Firebug.restorePrefs();
+
+ if(Firebug.saveCookies)
+ Firebug.savePrefs();
+ else
+ Firebug.erasePrefs();
+
+ if (target)
+ this.updateMenu(target);
+
+ return false;
+ },
+
+ updateMenu: function(target)
+ {
+ var options = getElementsByClass(target.parentNode, "fbMenuOption");
+
+ var firstOption = options[0];
+ var enabled = Firebug.saveCookies;
+ if (enabled)
+ Menu.check(firstOption);
+ else
+ Menu.uncheck(firstOption);
+
+ if (enabled)
+ Menu.check(options[0]);
+ else
+ Menu.uncheck(options[0]);
+
+ for (var i = 1, length = options.length; i < length; i++)
+ {
+ var option = options[i];
+
+ var value = option.getAttribute("value");
+ var pref = Firebug[value];
+
+ if (pref)
+ Menu.check(option);
+ else
+ Menu.uncheck(option);
+
+ if (enabled)
+ Menu.enable(option);
+ else
+ Menu.disable(option);
+ }
+ }
+ };
+
+ Menu.register(firebugOptionsMenu);
+
+ var menu = firebugMenu;
+
+ var testMenuClick = function(event)
+ {
+ //console.log("testMenuClick");
+ cancelEvent(event, true);
+
+ var target = event.target || event.srcElement;
+
+ if (menu.isVisible)
+ menu.hide();
+ else
+ {
+ var offsetLeft = isIE6 ? 1 : -4, // IE6 problem with fixed position
+
+ chrome = Firebug.chrome,
+
+ box = chrome.getElementBox(target),
+
+ offset = chrome.type == "div" ?
+ chrome.getElementPosition(chrome.node) :
+ {top: 0, left: 0};
+
+ menu.show(
+ box.left + offsetLeft - offset.left,
+ box.top + box.height -5 - offset.top
+ );
+ }
+
+ return false;
+ };
+
+ var iconButton = new IconButton({
+ type: "toggle",
+ element: $("fbFirebugButton"),
+
+ onClick: testMenuClick
+ });
+
+ iconButton.initialize();
+
+ //addEvent($("fbToolbarIcon"), "click", testMenuClick);
+ },
+
+ initialize: function()
+ {
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ if (Env.bookmarkletOutdated)
+ Firebug.Console.logFormatted([
+ "A new bookmarklet version is available. " +
+ "Please visit http://getfirebug.com/firebuglite#Install and update it."
+ ], Firebug.context, "warn");
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ if (Firebug.Console)
+ Firebug.Console.flush();
+
+ if (Firebug.Trace)
+ FBTrace.flush(Firebug.Trace);
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application");
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // initialize inherited classes
+ Controller.initialize.call(this);
+ PanelBar.initialize.call(this);
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // create the interface elements cache
+
+ fbTop = $("fbTop");
+ fbContent = $("fbContent");
+ fbContentStyle = fbContent.style;
+ fbBottom = $("fbBottom");
+ fbBtnInspect = $("fbBtnInspect");
+
+ fbToolbar = $("fbToolbar");
+
+ fbPanelBox1 = $("fbPanelBox1");
+ fbPanelBox1Style = fbPanelBox1.style;
+ fbPanelBox2 = $("fbPanelBox2");
+ fbPanelBox2Style = fbPanelBox2.style;
+ fbPanelBar2Box = $("fbPanelBar2Box");
+ fbPanelBar2BoxStyle = fbPanelBar2Box.style;
+
+ fbHSplitter = $("fbHSplitter");
+ fbVSplitter = $("fbVSplitter");
+ fbVSplitterStyle = fbVSplitter.style;
+
+ fbPanel1 = $("fbPanel1");
+ fbPanel1Style = fbPanel1.style;
+ fbPanel2 = $("fbPanel2");
+ fbPanel2Style = fbPanel2.style;
+
+ fbConsole = $("fbConsole");
+ fbConsoleStyle = fbConsole.style;
+ fbHTML = $("fbHTML");
+
+ fbCommandLine = $("fbCommandLine");
+ fbLargeCommandLine = $("fbLargeCommandLine");
+ fbLargeCommandButtons = $("fbLargeCommandButtons");
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // static values cache
+ topHeight = fbTop.offsetHeight;
+ topPartialHeight = fbToolbar.offsetHeight;
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ disableTextSelection($("fbToolbar"));
+ disableTextSelection($("fbPanelBarBox"));
+ disableTextSelection($("fbPanelBar1"));
+ disableTextSelection($("fbPanelBar2"));
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6
+ if (isIE6 && Firebug.Selector)
+ {
+ // TODO: xxxpedro change to getElementsByClass
+ var as = $$(".fbHover");
+ for (var i=0, a; a=as[i]; i++)
+ {
+ a.setAttribute("href", "javascript:void(0)");
+ }
+ }
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // initialize all panels
+ /*
+ var panelMap = Firebug.panelTypes;
+ for (var i=0, p; p=panelMap[i]; i++)
+ {
+ if (!p.parentPanel)
+ {
+ this.addPanel(p.prototype.name);
+ }
+ }
+ /**/
+
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+
+ if(Firebug.Inspector)
+ this.inspectButton.initialize();
+
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+
+ this.addController(
+ [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine]
+ );
+
+ // ************************************************************************************************
+
+ // Select the first registered panel
+ // TODO: BUG IE7
+ var self = this;
+ setTimeout(function(){
+ self.selectPanel(FirebugChrome.selectedPanelName);
+
+ if (FirebugChrome.selectedPanelName == "Console" && Firebug.CommandLine)
+ Firebug.chrome.focusCommandLine();
+ },0);
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ //this.draw();
+
+
+
+
+
+
+
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ var onPanelMouseDown = function onPanelMouseDown(event)
+ {
+ //console.log("onPanelMouseDown", event.target || event.srcElement, event);
+
+ var target = event.target || event.srcElement;
+
+ if (FBL.isLeftClick(event))
+ {
+ var editable = FBL.getAncestorByClass(target, "editable");
+
+ // if an editable element has been clicked then start editing
+ if (editable)
+ {
+ Firebug.Editor.startEditing(editable);
+ FBL.cancelEvent(event);
+ }
+ // if any other element has been clicked then stop editing
+ else
+ {
+ if (!hasClass(target, "textEditorInner"))
+ Firebug.Editor.stopEditing();
+ }
+ }
+ else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target))
+ {
+ // Prevent auto-scroll when middle-clicking a rep object
+ FBL.cancelEvent(event);
+ }
+ };
+
+ Firebug.getElementPanel = function(element)
+ {
+ var panelNode = getAncestorByClass(element, "fbPanel");
+ var id = panelNode.id.substr(2);
+
+ var panel = Firebug.chrome.panelMap[id];
+
+ if (!panel)
+ {
+ if (Firebug.chrome.selectedPanel.sidePanelBar)
+ panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id];
+ }
+
+ return panel;
+ };
+
+
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ // TODO: xxxpedro port to Firebug
+
+ // Improved window key code event listener. Only one "keydown" event will be attached
+ // to the window, and the onKeyCodeListen() function will delegate which listeners
+ // should be called according to the event.keyCode fired.
+ var onKeyCodeListenersMap = [];
+ var onKeyCodeListen = function(event)
+ {
+ for (var keyCode in onKeyCodeListenersMap)
+ {
+ var listeners = onKeyCodeListenersMap[keyCode];
+
+ for (var i = 0, listener; listener = listeners[i]; i++)
+ {
+ var filter = listener.filter || FBL.noKeyModifiers;
+
+ if (event.keyCode == keyCode && (!filter || filter(event)))
+ {
+ listener.listener();
+ FBL.cancelEvent(event, true);
+ return false;
+ }
+ }
+ }
+ };
+
+ addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen);
+
+ /**
+ * @name keyCodeListen
+ * @memberOf FBL.FirebugChrome
+ */
+ Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
+ {
+ var keyCode = KeyEvent["DOM_VK_"+key];
+
+ if (!onKeyCodeListenersMap[keyCode])
+ onKeyCodeListenersMap[keyCode] = [];
+
+ onKeyCodeListenersMap[keyCode].push({
+ filter: filter,
+ listener: listener
+ });
+
+ return keyCode;
+ };
+
+ /**
+ * @name keyIgnore
+ * @memberOf FBL.FirebugChrome
+ */
+ Firebug.chrome.keyIgnore = function(keyCode)
+ {
+ onKeyCodeListenersMap[keyCode] = null;
+ delete onKeyCodeListenersMap[keyCode];
+ };
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ /**/
+ // move to shutdown
+ //removeEvent(Firebug.chrome.document, "keydown", listener[0]);
+
+
+ /*
+ Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
+ {
+ if (!filter)
+ filter = FBL.noKeyModifiers;
+
+ var keyCode = KeyEvent["DOM_VK_"+key];
+
+ var fn = function fn(event)
+ {
+ if (event.keyCode == keyCode && (!filter || filter(event)))
+ {
+ listener();
+ FBL.cancelEvent(event, true);
+ return false;
+ }
+ }
+
+ addEvent(Firebug.chrome.document, "keydown", fn);
+
+ return [fn, capture];
+ };
+
+ Firebug.chrome.keyIgnore = function(listener)
+ {
+ removeEvent(Firebug.chrome.document, "keydown", listener[0]);
+ };
+ /**/
+
+
+ this.addController(
+ [fbPanel1, "mousedown", onPanelMouseDown],
+ [fbPanel2, "mousedown", onPanelMouseDown]
+ );
+ /**/
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+
+ // menus can be used without domplate
+ if (FBL.domplate)
+ this.testMenu();
+ /**/
+
+ //test XHR
+ /*
+ setTimeout(function(){
+
+ FBL.Ajax.request({url: "../content/firebug/boot.js"});
+ FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"});
+
+ },1000);
+ /**/
+ },
+
+ shutdown: function()
+ {
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+
+ if(Firebug.Inspector)
+ this.inspectButton.shutdown();
+
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+ // ************************************************************************************************
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ // remove disableTextSelection event handlers
+ restoreTextSelection($("fbToolbar"));
+ restoreTextSelection($("fbPanelBarBox"));
+ restoreTextSelection($("fbPanelBar1"));
+ restoreTextSelection($("fbPanelBar2"));
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // shutdown inherited classes
+ Controller.shutdown.call(this);
+ PanelBar.shutdown.call(this);
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // Remove the interface elements cache (this must happen after calling
+ // the shutdown method of all dependent components to avoid errors)
+
+ fbTop = null;
+ fbContent = null;
+ fbContentStyle = null;
+ fbBottom = null;
+ fbBtnInspect = null;
+
+ fbToolbar = null;
+
+ fbPanelBox1 = null;
+ fbPanelBox1Style = null;
+ fbPanelBox2 = null;
+ fbPanelBox2Style = null;
+ fbPanelBar2Box = null;
+ fbPanelBar2BoxStyle = null;
+
+ fbHSplitter = null;
+ fbVSplitter = null;
+ fbVSplitterStyle = null;
+
+ fbPanel1 = null;
+ fbPanel1Style = null;
+ fbPanel2 = null;
+
+ fbConsole = null;
+ fbConsoleStyle = null;
+ fbHTML = null;
+
+ fbCommandLine = null;
+ fbLargeCommandLine = null;
+ fbLargeCommandButtons = null;
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // static values cache
+
+ topHeight = null;
+ topPartialHeight = null;
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ toggle: function(forceOpen, popup)
+ {
+ if(popup)
+ {
+ this.detach();
+ }
+ else
+ {
+ if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed)
+ {
+ var frame = FirebugChrome.chromeMap.frame;
+ frame.reattach();
+
+ FirebugChrome.chromeMap.popup = null;
+
+ frame.open();
+
+ return;
+ }
+
+ // If the context is a popup, ignores the toggle process
+ if (Firebug.chrome.type == "popup") return;
+
+ var shouldOpen = forceOpen || !FirebugChrome.isOpen;
+
+ if(shouldOpen)
+ this.open();
+ else
+ this.close();
+ }
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ detach: function()
+ {
+ if(!FirebugChrome.chromeMap.popup)
+ {
+ createChromeWindow({type: "popup"});
+ }
+ },
+
+ reattach: function(oldChrome, newChrome)
+ {
+ Firebug.browser.window.Firebug = Firebug;
+
+ // chrome synchronization
+ var newPanelMap = newChrome.panelMap;
+ var oldPanelMap = oldChrome.panelMap;
+
+ var panel;
+ for(var name in newPanelMap)
+ {
+ // TODO: xxxpedro innerHTML
+ panel = newPanelMap[name];
+ if (panel.options.innerHTMLSync)
+ panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML;
+ }
+
+ Firebug.chrome = newChrome;
+
+ // TODO: xxxpedro sync detach reattach attach
+ //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]);
+
+ if (newChrome.type == "popup")
+ {
+ newChrome.initialize();
+ //dispatch(Firebug.modules, "initialize", []);
+ }
+ else
+ {
+ // TODO: xxxpedro only needed in persistent
+ // should use FirebugChrome.clone, but popup FBChrome
+ // isn't acessible
+ FirebugChrome.selectedPanelName = oldChrome.selectedPanel.name;
+ }
+
+ dispatch(newPanelMap, "reattach", [oldChrome, newChrome]);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ draw: function()
+ {
+ var size = this.getSize();
+
+ // Height related values
+ var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0,
+
+ y = Math.max(size.height /* chrome height */, topHeight),
+
+ heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0),
+
+ height = heightValue + "px",
+
+ // Width related values
+ sideWidthValue = Firebug.chrome.sidePanelVisible ? FirebugChrome.sidePanelWidth : 0,
+
+ width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px";
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // Height related rendering
+ fbPanelBox1Style.height = height;
+ fbPanel1Style.height = height;
+
+ if (isIE || isOpera)
+ {
+ // Fix IE and Opera problems with auto resizing the verticall splitter
+ fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px";
+ }
+ //xxxpedro FF2 only?
+ /*
+ else if (isFirefox)
+ {
+ // Fix Firefox problem with table rows with 100% height (fit height)
+ fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px";
+ }/**/
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ // Width related rendering
+ fbPanelBox1Style.width = width;
+ fbPanel1Style.width = width;
+
+ // SidePanel rendering
+ if (Firebug.chrome.sidePanelVisible)
+ {
+ sideWidthValue = Math.max(sideWidthValue - 6, 0);
+
+ var sideWidth = sideWidthValue + "px";
+
+ fbPanelBox2Style.width = sideWidth;
+
+ fbVSplitterStyle.right = sideWidth;
+
+ if (Firebug.chrome.largeCommandLineVisible)
+ {
+ fbLargeCommandLine = $("fbLargeCommandLine");
+
+ fbLargeCommandLine.style.height = heightValue - 4 + "px";
+ fbLargeCommandLine.style.width = sideWidthValue - 2 + "px";
+
+ fbLargeCommandButtons = $("fbLargeCommandButtons");
+ fbLargeCommandButtons.style.width = sideWidth;
+ }
+ else
+ {
+ fbPanel2Style.height = height;
+ fbPanel2Style.width = sideWidth;
+
+ fbPanelBar2BoxStyle.width = sideWidth;
+ }
+ }
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ getSize: function()
+ {
+ return this.type == "div" ?
+ {
+ height: this.node.offsetHeight,
+ width: this.node.offsetWidth
+ }
+ :
+ this.getWindowSize();
+ },
+
+ resize: function()
+ {
+ var self = this;
+
+ // avoid partial resize when maximizing window
+ setTimeout(function(){
+ self.draw();
+
+ if (noFixedPosition && (self.type == "frame" || self.type == "div"))
+ self.fixIEPosition();
+ }, 0);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ layout: function(panel)
+ {
+ if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", "");
+
+ var options = panel.options;
+
+ changeCommandLineVisibility(options.hasCommandLine);
+ changeSidePanelVisibility(panel.hasSidePanel);
+
+ Firebug.chrome.draw();
+ },
+
+ showLargeCommandLine: function(hideToggleIcon)
+ {
+ var chrome = Firebug.chrome;
+
+ if (!chrome.largeCommandLineVisible)
+ {
+ chrome.largeCommandLineVisible = true;
+
+ if (chrome.selectedPanel.options.hasCommandLine)
+ {
+ if (Firebug.CommandLine)
+ Firebug.CommandLine.blur();
+
+ changeCommandLineVisibility(false);
+ }
+
+ changeSidePanelVisibility(true);
+
+ fbLargeCommandLine.style.display = "block";
+ fbLargeCommandButtons.style.display = "block";
+
+ fbPanel2Style.display = "none";
+ fbPanelBar2BoxStyle.display = "none";
+
+ chrome.draw();
+
+ fbLargeCommandLine.focus();
+
+ if (Firebug.CommandLine)
+ Firebug.CommandLine.setMultiLine(true);
+ }
+ },
+
+ hideLargeCommandLine: function()
+ {
+ if (Firebug.chrome.largeCommandLineVisible)
+ {
+ Firebug.chrome.largeCommandLineVisible = false;
+
+ if (Firebug.CommandLine)
+ Firebug.CommandLine.setMultiLine(false);
+
+ fbLargeCommandLine.blur();
+
+ fbPanel2Style.display = "block";
+ fbPanelBar2BoxStyle.display = "block";
+
+ fbLargeCommandLine.style.display = "none";
+ fbLargeCommandButtons.style.display = "none";
+
+ changeSidePanelVisibility(false);
+
+ if (Firebug.chrome.selectedPanel.options.hasCommandLine)
+ changeCommandLineVisibility(true);
+
+ Firebug.chrome.draw();
+
+ }
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ focusCommandLine: function()
+ {
+ var selectedPanelName = this.selectedPanel.name, panelToSelect;
+
+ if (focusCommandLineState == 0 || selectedPanelName != "Console")
+ {
+ focusCommandLineState = 0;
+ lastFocusedPanelName = selectedPanelName;
+
+ panelToSelect = "Console";
+ }
+ if (focusCommandLineState == 1)
+ {
+ panelToSelect = lastFocusedPanelName;
+ }
+
+ this.selectPanel(panelToSelect);
+
+ try
+ {
+ if (Firebug.CommandLine)
+ {
+ if (panelToSelect == "Console")
+ Firebug.CommandLine.focus();
+ else
+ Firebug.CommandLine.blur();
+ }
+ }
+ catch(e)
+ {
+ //TODO: xxxpedro trace error
+ }
+
+ focusCommandLineState = ++focusCommandLineState % 2;
+ }
+
+ });
+
+ // ************************************************************************************************
+ // ChromeFrameBase
+
+ /**
+ * @namespace
+ * @extends ns-chrome-ChromeBase
+ */
+ var ChromeFrameBase = extend(ChromeBase,
+ /**@extend ns-chrome-ChromeFrameBase*/
+ {
+ create: function()
+ {
+ ChromeBase.create.call(this);
+
+ // restore display for the anti-flicker trick
+ if (isFirefox)
+ this.node.style.display = "block";
+
+ if (Env.Options.startInNewWindow)
+ {
+ this.close();
+ this.toggle(true, true);
+ return;
+ }
+
+ if (Env.Options.startOpened)
+ this.open();
+ else
+ this.close();
+ },
+
+ destroy: function()
+ {
+ removeGlobalEvent("keydown", onGlobalKeyDown);
+
+ ChromeBase.destroy.call(this);
+
+ this.document = null;
+ delete this.document;
+
+ this.window = null;
+ delete this.window;
+
+ this.node.parentNode.removeChild(this.node);
+ this.node = null;
+ delete this.node;
+ },
+
+ initialize: function()
+ {
+ //FBTrace.sysout("Frame", "initialize();")
+ ChromeBase.initialize.call(this);
+
+ this.addController(
+ [Firebug.browser.window, "resize", this.resize],
+ [$("fbWindow_btClose"), "click", this.close],
+ [$("fbWindow_btDetach"), "click", this.detach],
+ [$("fbWindow_btDeactivate"), "click", this.deactivate]
+ );
+
+ if (!Env.Options.enablePersistent)
+ this.addController([Firebug.browser.window, "unload", Firebug.shutdown]);
+
+ if (noFixedPosition)
+ {
+ this.addController(
+ [Firebug.browser.window, "scroll", this.fixIEPosition]
+ );
+ }
+
+ fbVSplitter.onmousedown = onVSplitterMouseDown;
+ fbHSplitter.onmousedown = onHSplitterMouseDown;
+
+ this.isInitialized = true;
+ },
+
+ shutdown: function()
+ {
+ fbVSplitter.onmousedown = null;
+ fbHSplitter.onmousedown = null;
+
+ ChromeBase.shutdown.apply(this);
+
+ this.isInitialized = false;
+ },
+
+ reattach: function()
+ {
+ var frame = FirebugChrome.chromeMap.frame;
+
+ ChromeBase.reattach(FirebugChrome.chromeMap.popup, this);
+ },
+
+ open: function()
+ {
+ if (!FirebugChrome.isOpen)
+ {
+ FirebugChrome.isOpen = true;
+
+ if (Env.isChromeExtension)
+ localStorage.setItem("Firebug", "1,1");
+
+ var node = this.node;
+
+ node.style.visibility = "hidden"; // Avoid flickering
+
+ if (Firebug.showIconWhenHidden)
+ {
+ if (ChromeMini.isInitialized)
+ {
+ ChromeMini.shutdown();
+ }
+
+ }
+ else
+ node.style.display = "block";
+
+ var main = $("fbChrome");
+
+ // IE6 throws an error when setting this property! why?
+ //main.style.display = "table";
+ main.style.display = "";
+
+ var self = this;
+ /// TODO: xxxpedro FOUC
+ node.style.visibility = "visible";
+ setTimeout(function(){
+ ///node.style.visibility = "visible";
+
+ //dispatch(Firebug.modules, "initialize", []);
+ self.initialize();
+
+ if (noFixedPosition)
+ self.fixIEPosition();
+
+ self.draw();
+
+ }, 10);
+ }
+ },
+
+ close: function()
+ {
+ if (FirebugChrome.isOpen || !this.isInitialized)
+ {
+ if (this.isInitialized)
+ {
+ //dispatch(Firebug.modules, "shutdown", []);
+ this.shutdown();
+ }
+
+ FirebugChrome.isOpen = false;
+
+ if (Env.isChromeExtension)
+ localStorage.setItem("Firebug", "1,0");
+
+ var node = this.node;
+
+ if (Firebug.showIconWhenHidden)
+ {
+ node.style.visibility = "hidden"; // Avoid flickering
+
+ // TODO: xxxpedro - persist IE fixed?
+ var main = $("fbChrome", FirebugChrome.chromeMap.frame.document);
+ main.style.display = "none";
+
+ ChromeMini.initialize();
+
+ node.style.visibility = "visible";
+ }
+ else
+ node.style.display = "none";
+ }
+ },
+
+ deactivate: function()
+ {
+ // if it is running as a Chrome extension, dispatch a message to the extension signaling
+ // that Firebug should be deactivated for the current tab
+ if (Env.isChromeExtension)
+ {
+ localStorage.removeItem("Firebug");
+ Firebug.GoogleChrome.dispatch("FB_deactivate");
+
+ // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole
+ // app, otherwise it won't be able to be reactivated without reloading the page.
+ // but we need to stop listening global keys, otherwise the key activation won't work.
+ Firebug.chrome.close();
+ }
+ else
+ {
+ Firebug.shutdown();
+ }
+ },
+
+ fixIEPosition: function()
+ {
+ // fix IE problem with offset when not in fullscreen mode
+ var doc = this.document;
+ var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0;
+
+ var size = Firebug.browser.getWindowSize();
+ var scroll = Firebug.browser.getWindowScrollPosition();
+ var maxHeight = size.height;
+ var height = this.node.offsetHeight;
+
+ var bodyStyle = doc.body.currentStyle;
+
+ this.node.style.top = maxHeight - height + scroll.top + "px";
+
+ if ((this.type == "frame" || this.type == "div") &&
+ (bodyStyle.marginLeft || bodyStyle.marginRight))
+ {
+ this.node.style.width = size.width + "px";
+ }
+
+ if (fbVSplitterStyle)
+ fbVSplitterStyle.right = FirebugChrome.sidePanelWidth + "px";
+
+ this.draw();
+ }
+
+ });
+
+
+ // ************************************************************************************************
+ // ChromeMini
+
+ /**
+ * @namespace
+ * @extends FBL.Controller
+ */
+ var ChromeMini = extend(Controller,
+ /**@extend ns-chrome-ChromeMini*/
+ {
+ create: function(chrome)
+ {
+ append(this, chrome);
+ this.type = "mini";
+ },
+
+ initialize: function()
+ {
+ Controller.initialize.apply(this);
+
+ var doc = FirebugChrome.chromeMap.frame.document;
+
+ var mini = $("fbMiniChrome", doc);
+ mini.style.display = "block";
+
+ var miniIcon = $("fbMiniIcon", doc);
+ var width = miniIcon.offsetWidth + 10;
+ miniIcon.title = "Open " + Firebug.version;
+
+ var errors = $("fbMiniErrors", doc);
+ if (errors.offsetWidth)
+ width += errors.offsetWidth + 10;
+
+ var node = this.node;
+ node.style.height = "27px";
+ node.style.width = width + "px";
+ node.style.left = "";
+ node.style.right = 0;
+
+ if (this.node.nodeName.toLowerCase() == "iframe")
+ {
+ node.setAttribute("allowTransparency", "true");
+ this.document.body.style.backgroundColor = "transparent";
+ }
+ else
+ node.style.background = "transparent";
+
+ if (noFixedPosition)
+ this.fixIEPosition();
+
+ this.addController(
+ [$("fbMiniIcon", doc), "click", onMiniIconClick]
+ );
+
+ if (noFixedPosition)
+ {
+ this.addController(
+ [Firebug.browser.window, "scroll", this.fixIEPosition]
+ );
+ }
+
+ this.isInitialized = true;
+ },
+
+ shutdown: function()
+ {
+ var node = this.node;
+ node.style.height = FirebugChrome.height + "px";
+ node.style.width = "100%";
+ node.style.left = 0;
+ node.style.right = "";
+
+ if (this.node.nodeName.toLowerCase() == "iframe")
+ {
+ node.setAttribute("allowTransparency", "false");
+ this.document.body.style.backgroundColor = "#fff";
+ }
+ else
+ node.style.background = "#fff";
+
+ if (noFixedPosition)
+ this.fixIEPosition();
+
+ var doc = FirebugChrome.chromeMap.frame.document;
+
+ var mini = $("fbMiniChrome", doc);
+ mini.style.display = "none";
+
+ Controller.shutdown.apply(this);
+
+ this.isInitialized = false;
+ },
+
+ draw: function()
+ {
+
+ },
+
+ fixIEPosition: ChromeFrameBase.fixIEPosition
+
+ });
+
+
+ // ************************************************************************************************
+ // ChromePopupBase
+
+ /**
+ * @namespace
+ * @extends ns-chrome-ChromeBase
+ */
+ var ChromePopupBase = extend(ChromeBase,
+ /**@extend ns-chrome-ChromePopupBase*/
+ {
+
+ initialize: function()
+ {
+ setClass(this.document.body, "FirebugPopup");
+
+ ChromeBase.initialize.call(this);
+
+ this.addController(
+ [Firebug.chrome.window, "resize", this.resize],
+ [Firebug.chrome.window, "unload", this.destroy]
+ );
+
+ if (Env.Options.enablePersistent)
+ {
+ this.persist = bind(this.persist, this);
+ addEvent(Firebug.browser.window, "unload", this.persist);
+ }
+ else
+ this.addController(
+ [Firebug.browser.window, "unload", this.close]
+ );
+
+ fbVSplitter.onmousedown = onVSplitterMouseDown;
+ },
+
+ destroy: function()
+ {
+ // TODO: xxxpedro sync detach reattach attach
+ var frame = FirebugChrome.chromeMap.frame;
+
+ if(frame)
+ {
+ dispatch(frame.panelMap, "detach", [this, frame]);
+
+ frame.reattach(this, frame);
+ }
+
+ if (Env.Options.enablePersistent)
+ {
+ removeEvent(Firebug.browser.window, "unload", this.persist);
+ }
+
+ ChromeBase.destroy.apply(this);
+
+ FirebugChrome.chromeMap.popup = null;
+
+ this.node.close();
+ },
+
+ persist: function()
+ {
+ persistTimeStart = new Date().getTime();
+
+ removeEvent(Firebug.browser.window, "unload", this.persist);
+
+ Firebug.Inspector.destroy();
+ Firebug.browser.window.FirebugOldBrowser = true;
+
+ var persistTimeStart = new Date().getTime();
+
+ var waitMainWindow = function()
+ {
+ var doc, head;
+
+ try
+ {
+ if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* &&
+ doc.documentElement && (head = doc.documentElement.firstChild)*/)
+ {
+
+ try
+ {
+ // exposes the FBL to the global namespace when in debug mode
+ if (Env.isDebugMode)
+ {
+ window.FBL = FBL;
+ }
+
+ window.Firebug = Firebug;
+ window.opener.Firebug = Firebug;
+
+ Env.browser = window.opener;
+ Firebug.browser = Firebug.context = new Context(Env.browser);
+
+ registerConsole();
+
+ // the delay time should be calculated right after registering the
+ // console, once right after the console registration, call log messages
+ // will be properly handled
+ var persistDelay = new Date().getTime() - persistTimeStart;
+
+ var chrome = Firebug.chrome;
+ addEvent(Firebug.browser.window, "unload", chrome.persist);
+
+ FBL.cacheDocument();
+ Firebug.Inspector.create();
+
+ var htmlPanel = chrome.getPanel("HTML");
+ htmlPanel.createUI();
+
+ Firebug.Console.logFormatted(
+ ["Firebug could not capture console calls during " +
+ persistDelay + "ms"],
+ Firebug.context,
+ "info"
+ );
+ }
+ catch(pE)
+ {
+ alert("persist error: " + (pE.message || pE));
+ }
+
+ }
+ else
+ {
+ window.setTimeout(waitMainWindow, 0);
+ }
+
+ } catch (E) {
+ window.close();
+ }
+ };
+
+ waitMainWindow();
+ },
+
+ close: function()
+ {
+ this.destroy();
+ }
+
+ });
+
+
+ //************************************************************************************************
+ // UI helpers
+
+ var changeCommandLineVisibility = function changeCommandLineVisibility(visibility)
+ {
+ var last = Firebug.chrome.commandLineVisible;
+ var visible = Firebug.chrome.commandLineVisible =
+ typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible;
+
+ if (visible != last)
+ {
+ if (visible)
+ {
+ fbBottom.className = "";
+
+ if (Firebug.CommandLine)
+ Firebug.CommandLine.activate();
+ }
+ else
+ {
+ if (Firebug.CommandLine)
+ Firebug.CommandLine.deactivate();
+
+ fbBottom.className = "hide";
+ }
+ }
+ };
+
+ var changeSidePanelVisibility = function changeSidePanelVisibility(visibility)
+ {
+ var last = Firebug.chrome.sidePanelVisible;
+ Firebug.chrome.sidePanelVisible =
+ typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible;
+
+ if (Firebug.chrome.sidePanelVisible != last)
+ {
+ fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
+ fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
+ }
+ };
+
+
+ // ************************************************************************************************
+ // F12 Handler
+
+ var onGlobalKeyDown = function onGlobalKeyDown(event)
+ {
+ var keyCode = event.keyCode;
+ var shiftKey = event.shiftKey;
+ var ctrlKey = event.ctrlKey;
+
+ if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox))
+ {
+ Firebug.chrome.toggle(false, ctrlKey);
+ cancelEvent(event, true);
+
+ // TODO: xxxpedro replace with a better solution. we're doing this
+ // to allow reactivating with the F12 key after being deactivated
+ if (Env.isChromeExtension)
+ {
+ Firebug.GoogleChrome.dispatch("FB_enableIcon");
+ }
+ }
+ else if (keyCode == 67 /* C */ && ctrlKey && shiftKey)
+ {
+ Firebug.Inspector.toggleInspect();
+ cancelEvent(event, true);
+ }
+ else if (keyCode == 76 /* L */ && ctrlKey && shiftKey)
+ {
+ Firebug.chrome.focusCommandLine();
+ cancelEvent(event, true);
+ }
+ };
+
+ var onMiniIconClick = function onMiniIconClick(event)
+ {
+ Firebug.chrome.toggle(false, event.ctrlKey);
+ cancelEvent(event, true);
+ };
+
+
+ // ************************************************************************************************
+ // Horizontal Splitter Handling
+
+ var onHSplitterMouseDown = function onHSplitterMouseDown(event)
+ {
+ addGlobalEvent("mousemove", onHSplitterMouseMove);
+ addGlobalEvent("mouseup", onHSplitterMouseUp);
+
+ if (isIE)
+ addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
+
+ fbHSplitter.className = "fbOnMovingHSplitter";
+
+ return false;
+ };
+
+ var onHSplitterMouseMove = function onHSplitterMouseMove(event)
+ {
+ cancelEvent(event, true);
+
+ var clientY = event.clientY;
+ var win = isIE
+ ? event.srcElement.ownerDocument.parentWindow
+ : event.target.ownerDocument && event.target.ownerDocument.defaultView;
+
+ if (!win)
+ return;
+
+ if (win != win.parent)
+ {
+ var frameElement = win.frameElement;
+ if (frameElement)
+ {
+ var framePos = Firebug.browser.getElementPosition(frameElement).top;
+ clientY += framePos;
+
+ if (frameElement.style.position != "fixed")
+ clientY -= Firebug.browser.getWindowScrollPosition().top;
+ }
+ }
+
+ if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI")
+ {
+ clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY;
+ }
+ /*
+ console.log(
+ typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome",
+ //win.frameElement.id,
+ event.target,
+ clientY
+ );/**/
+
+ onHSplitterMouseMoveBuffer = clientY; // buffer
+
+ if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
+ {
+ lastHSplitterMouseMove = new Date().getTime();
+ handleHSplitterMouseMove();
+ }
+ else
+ if (!onHSplitterMouseMoveTimer)
+ onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate);
+
+ // improving the resizing performance by canceling the mouse event.
+ // canceling events will prevent the page to receive such events, which would imply
+ // in more processing being expended.
+ cancelEvent(event, true);
+ return false;
+ };
+
+ var handleHSplitterMouseMove = function()
+ {
+ if (onHSplitterMouseMoveTimer)
+ {
+ clearTimeout(onHSplitterMouseMoveTimer);
+ onHSplitterMouseMoveTimer = null;
+ }
+
+ var clientY = onHSplitterMouseMoveBuffer;
+
+ var windowSize = Firebug.browser.getWindowSize();
+ var scrollSize = Firebug.browser.getWindowScrollSize();
+
+ // compute chrome fixed size (top bar and command line)
+ var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0;
+ var fixedHeight = topHeight + commandLineHeight;
+ var chromeNode = Firebug.chrome.node;
+
+ var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0;
+
+ //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height;
+ var height = windowSize.height;
+
+ // compute the min and max size of the chrome
+ var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight);
+ chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize);
+
+ FirebugChrome.height = chromeHeight;
+ chromeNode.style.height = chromeHeight + "px";
+
+ if (noFixedPosition)
+ Firebug.chrome.fixIEPosition();
+
+ Firebug.chrome.draw();
+ };
+
+ var onHSplitterMouseUp = function onHSplitterMouseUp(event)
+ {
+ removeGlobalEvent("mousemove", onHSplitterMouseMove);
+ removeGlobalEvent("mouseup", onHSplitterMouseUp);
+
+ if (isIE)
+ removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
+
+ fbHSplitter.className = "";
+
+ Firebug.chrome.draw();
+
+ // avoid text selection in IE when returning to the document
+ // after the mouse leaves the document during the resizing
+ return false;
+ };
+
+
+ // ************************************************************************************************
+ // Vertical Splitter Handling
+
+ var onVSplitterMouseDown = function onVSplitterMouseDown(event)
+ {
+ addGlobalEvent("mousemove", onVSplitterMouseMove);
+ addGlobalEvent("mouseup", onVSplitterMouseUp);
+
+ return false;
+ };
+
+ var onVSplitterMouseMove = function onVSplitterMouseMove(event)
+ {
+ if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
+ {
+ var target = event.target || event.srcElement;
+ if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome
+ {
+ var clientX = event.clientX;
+ var win = document.all
+ ? event.srcElement.ownerDocument.parentWindow
+ : event.target.ownerDocument.defaultView;
+
+ if (win != win.parent)
+ clientX += win.frameElement ? win.frameElement.offsetLeft : 0;
+
+ var size = Firebug.chrome.getSize();
+ var x = Math.max(size.width - clientX + 3, 6);
+
+ FirebugChrome.sidePanelWidth = x;
+ Firebug.chrome.draw();
+ }
+
+ lastVSplitterMouseMove = new Date().getTime();
+ }
+
+ cancelEvent(event, true);
+ return false;
+ };
+
+ var onVSplitterMouseUp = function onVSplitterMouseUp(event)
+ {
+ removeGlobalEvent("mousemove", onVSplitterMouseMove);
+ removeGlobalEvent("mouseup", onVSplitterMouseUp);
+
+ Firebug.chrome.draw();
+ };
+
+
+ // ************************************************************************************************
+ }});
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns(function() { with (FBL) {
+ // ************************************************************************************************
+
+ Firebug.Lite =
+ {
+ };
+
+ // ************************************************************************************************
+ }});
+
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns(function() { with (FBL) {
+ // ************************************************************************************************
+
+
+ Firebug.Lite.Browser = function(window)
+ {
+ this.contentWindow = window;
+ this.contentDocument = window.document;
+ this.currentURI =
+ {
+ spec: window.location.href
+ };
+ };
+
+ Firebug.Lite.Browser.prototype =
+ {
+ toString: function()
+ {
+ return "Firebug.Lite.Browser";
+ }
+ };
+
+
+ // ************************************************************************************************
+ }});
+
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns(function() { with (FBL) {
+ // ************************************************************************************************
+
+ Firebug.Lite.Cache =
+ {
+ ID: "firebug-" + new Date().getTime()
+ };
+
+ // ************************************************************************************************
+
+ /**
+ * TODO: if a cached element is cloned, the expando property will be cloned too in IE
+ * which will result in a bug. Firebug Lite will think the new cloned node is the old
+ * one.
+ *
+ * TODO: Investigate a possibility of cache validation, to be customized by each
+ * kind of cache. For ElementCache it should validate if the element still is
+ * inserted at the DOM.
+ */
+ var cacheUID = 0;
+ var createCache = function()
+ {
+ var map = {};
+ var data = {};
+
+ var CID = Firebug.Lite.Cache.ID;
+
+ // better detection
+ var supportsDeleteExpando = !document.all;
+
+ var cacheFunction = function(element)
+ {
+ return cacheAPI.set(element);
+ };
+
+ var cacheAPI =
+ {
+ get: function(key)
+ {
+ return map.hasOwnProperty(key) ?
+ map[key] :
+ null;
+ },
+
+ set: function(element)
+ {
+ var id = getValidatedKey(element);
+
+ if (!id)
+ {
+ id = ++cacheUID;
+ element[CID] = id;
+ }
+
+ if (!map.hasOwnProperty(id))
+ {
+ map[id] = element;
+ data[id] = {};
+ }
+
+ return id;
+ },
+
+ unset: function(element)
+ {
+ var id = getValidatedKey(element);
+
+ if (!id) return;
+
+ if (supportsDeleteExpando)
+ {
+ delete element[CID];
+ }
+ else if (element.removeAttribute)
+ {
+ element.removeAttribute(CID);
+ }
+
+ delete map[id];
+ delete data[id];
+
+ },
+
+ key: function(element)
+ {
+ return getValidatedKey(element);
+ },
+
+ has: function(element)
+ {
+ var id = getValidatedKey(element);
+ return id && map.hasOwnProperty(id);
+ },
+
+ each: function(callback)
+ {
+ for (var key in map)
+ {
+ if (map.hasOwnProperty(key))
+ {
+ callback(key, map[key]);
+ }
+ }
+ },
+
+ data: function(element, name, value)
+ {
+ // set data
+ if (value)
+ {
+ if (!name) return null;
+
+ var id = cacheAPI.set(element);
+
+ return data[id][name] = value;
+ }
+ // get data
+ else
+ {
+ var id = cacheAPI.key(element);
+
+ return data.hasOwnProperty(id) && data[id].hasOwnProperty(name) ?
+ data[id][name] :
+ null;
+ }
+ },
+
+ clear: function()
+ {
+ for (var id in map)
+ {
+ var element = map[id];
+ cacheAPI.unset(element);
+ }
+ }
+ };
+
+ var getValidatedKey = function(element)
+ {
+ var id = element[CID];
+
+ // If a cached element is cloned in IE, the expando property CID will be also
+ // cloned (differently than other browsers) resulting in a bug: Firebug Lite
+ // will think the new cloned node is the old one. To prevent this problem we're
+ // checking if the cached element matches the given element.
+ if (
+ !supportsDeleteExpando && // the problem happens when supportsDeleteExpando is false
+ id && // the element has the expando property
+ map.hasOwnProperty(id) && // there is a cached element with the same id
+ map[id] != element // but it is a different element than the current one
+ )
+ {
+ // remove the problematic property
+ element.removeAttribute(CID);
+
+ id = null;
+ }
+
+ return id;
+ }
+
+ FBL.append(cacheFunction, cacheAPI);
+
+ return cacheFunction;
+ };
+
+ // ************************************************************************************************
+
+ // TODO: xxxpedro : check if we need really this on FBL scope
+ Firebug.Lite.Cache.StyleSheet = createCache();
+ Firebug.Lite.Cache.Element = createCache();
+
+ // TODO: xxxpedro
+ Firebug.Lite.Cache.Event = createCache();
+
+
+ // ************************************************************************************************
+ }});
+
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns(function() { with (FBL) {
+ // ************************************************************************************************
+
+
+ Firebug.Lite.Proxy =
+ {
+ // jsonp callbacks
+ _callbacks: {},
+
+ /**
+ * Load a resource, either locally (directly) or externally (via proxy) using
+ * synchronous XHR calls. Loading external resources requires the proxy plugin to
+ * be installed and configured (see /plugin/proxy/proxy.php).
+ */
+ load: function(url)
+ {
+ var resourceDomain = getDomain(url);
+ var isLocalResource =
+ // empty domain means local URL
+ !resourceDomain ||
+ // same domain means local too
+ resourceDomain == Firebug.context.window.location.host; // TODO: xxxpedro context
+
+ return isLocalResource ? fetchResource(url) : fetchProxyResource(url);
+ },
+
+ /**
+ * Load a resource using JSONP technique.
+ */
+ loadJSONP: function(url, callback)
+ {
+ var script = createGlobalElement("script"),
+ doc = Firebug.context.document,
+
+ uid = "" + new Date().getTime(),
+ callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid,
+
+ jsonpURL = url.indexOf("?") != -1 ?
+ url + "&" + callbackName :
+ url + "?" + callbackName;
+
+ Firebug.Lite.Proxy._callbacks[uid] = function(data)
+ {
+ if (callback)
+ callback(data);
+
+ script.parentNode.removeChild(script);
+ delete Firebug.Lite.Proxy._callbacks[uid];
+ };
+
+ script.src = jsonpURL;
+
+ if (doc.documentElement)
+ doc.documentElement.appendChild(script);
+ },
+
+ /**
+ * Load a resource using YQL (not reliable).
+ */
+ YQL: function(url, callback)
+ {
+ var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" +
+ encodeURIComponent(url) + "%22&format=xml";
+
+ this.loadJSONP(yql, function(data)
+ {
+ var source = data.results[0];
+
+ // clean up YQL bogus elements
+ var match = /\s+([\s\S]+)<\/p>\s+<\/body>$/.exec(source);
+ if (match)
+ source = match[1];
+
+ console.log(source);
+ });
+ }
+ };
+
+ // ************************************************************************************************
+
+ var fetchResource = function(url)
+ {
+ var xhr = FBL.Ajax.getXHRObject();
+ xhr.open("get", url, false);
+ xhr.send();
+
+ return xhr.responseText;
+ };
+
+ var fetchProxyResource = function(url)
+ {
+ var proxyURL = Env.Location.baseDir + "plugin/proxy/proxy.php?url=" + encodeURIComponent(url);
+ var response = fetchResource(proxyURL);
+
+ try
+ {
+ var data = eval("(" + response + ")");
+ }
+ catch(E)
+ {
+ return "ERROR: Firebug Lite Proxy plugin returned an invalid response.";
+ }
+
+ return data ? data.contents : "";
+ };
+
+
+ // ************************************************************************************************
+ }});
+
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns(function() { with (FBL) {
+ // ************************************************************************************************
+
+ Firebug.Lite.Script = function(window)
+ {
+ this.fileName = null;
+ this.isValid = null;
+ this.baseLineNumber = null;
+ this.lineExtent = null;
+ this.tag = null;
+
+ this.functionName = null;
+ this.functionSource = null;
+ };
+
+ Firebug.Lite.Script.prototype =
+ {
+ isLineExecutable: function(){},
+ pcToLine: function(){},
+ lineToPc: function(){},
+
+ toString: function()
+ {
+ return "Firebug.Lite.Script";
+ }
+ };
+
+ // ************************************************************************************************
+ }});
+
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns(function() { with (FBL) {
+ // ************************************************************************************************
+
+ Firebug.Lite.Style =
+ {
+ };
+
+ // ************************************************************************************************
+ }});
+
+
+ /* See license.txt for terms of usage */
+
+ FBL.ns( /**@scope s_selector*/ function() { with (FBL) {
+ // ************************************************************************************************
+
+ /*
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+ // Here we check if the JavaScript engine is using some sort of
+ // optimization where it does not always call our comparision
+ // function. If that is the case, discard the hasDuplicate value.
+ // Thus far that includes Google Chrome.
+ [0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+ });
+
+ /**
+ * @name Firebug.Selector
+ * @namespace
+ */
+
+ /**
+ * @exports Sizzle as Firebug.Selector
+ */
+ var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+ };
+
+ Sizzle.uniqueSort = function(results){
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+ };
+
+ Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+ };
+
+ Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+ };
+
+ Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+ };
+
+ /**#@+ @ignore */
+ var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag && !isXML ) {
+ part = part.toUpperCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( !/\W/.test(part) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ if ( type == 'first') return true;
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first == 0 ) {
+ return diff == 0;
+ } else {
+ return ( diff % first == 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+ };
+
+ var origPOS = Expr.match.POS;
+
+ for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
+ }
+
+ var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+ };
+
+ // Perform a simple check to determine if the browser is capable of
+ // converting a NodeList to an array using builtin methods.
+ try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+ // Provide a fallback method if it does not work
+ } catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+ }
+
+ var sortOrder;
+
+ if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+ } else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+ } else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+ }
+
+ // Check to see if the browser returns elements by name when
+ // querying by getElementById (and provide a workaround)
+ (function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+ root = form = null; // release memory in IE
+ })();
+
+ (function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ div = null; // release memory in IE
+ })();
+
+ if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "
";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+ })();
+
+ if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+ var div = document.createElement("div");
+ div.innerHTML = "";
+
+ // Opera can't find a second classname (in 9.6)
+ if ( div.getElementsByClassName("e").length === 0 )
+ return;
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 )
+ return;
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+ })();
+
+ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+ }
+
+ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+ }
+
+ var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+ } : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+ var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
+ };
+
+ var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+ };
+
+ // EXPOSE
+
+ Firebug.Selector = Sizzle;
+
+ /**#@-*/
+
+ // ************************************************************************************************
+ }});
+
+ // Problems in IE
+ // FIXED - eval return
+ // FIXED - addEventListener problem in IE
+ // FIXED doc.createRange?
+ //
+ // class reserved word
+ // test all honza examples in IE6 and IE7
+
+
+ /* See license.txt for terms of usage */
+
+ ( /** @scope s_domplate */ function() {
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ /** @class */
+ FBL.DomplateTag = function DomplateTag(tagName)
+ {
+ this.tagName = tagName;
+ };
+
+ /**
+ * @class
+ * @extends FBL.DomplateTag
+ */
+ FBL.DomplateEmbed = function DomplateEmbed()
+ {
+ };
+
+ /**
+ * @class
+ * @extends FBL.DomplateTag
+ */
+ FBL.DomplateLoop = function DomplateLoop()
+ {
+ };
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ var DomplateTag = FBL.DomplateTag;
+ var DomplateEmbed = FBL.DomplateEmbed;
+ var DomplateLoop = FBL.DomplateLoop;
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ var womb = null;
+
+ FBL.domplate = function()
+ {
+ var lastSubject;
+ for (var i = 0; i < arguments.length; ++i)
+ lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i];
+
+ for (var name in lastSubject)
+ {
+ var val = lastSubject[name];
+ if (isTag(val))
+ val.tag.subject = lastSubject;
+ }
+
+ return lastSubject;
+ };
+
+ var domplate = FBL.domplate;
+
+ FBL.domplate.context = function(context, fn)
+ {
+ var lastContext = domplate.lastContext;
+ domplate.topContext = context;
+ fn.apply(context);
+ domplate.topContext = lastContext;
+ };
+
+ FBL.TAG = function()
+ {
+ var embed = new DomplateEmbed();
+ return embed.merge(arguments);
+ };
+
+ FBL.FOR = function()
+ {
+ var loop = new DomplateLoop();
+ return loop.merge(arguments);
+ };
+
+ FBL.DomplateTag.prototype =
+ {
+ merge: function(args, oldTag)
+ {
+ if (oldTag)
+ this.tagName = oldTag.tagName;
+
+ this.context = oldTag ? oldTag.context : null;
+ this.subject = oldTag ? oldTag.subject : null;
+ this.attrs = oldTag ? copyObject(oldTag.attrs) : {};
+ this.classes = oldTag ? copyObject(oldTag.classes) : {};
+ this.props = oldTag ? copyObject(oldTag.props) : null;
+ this.listeners = oldTag ? copyArray(oldTag.listeners) : null;
+ this.children = oldTag ? copyArray(oldTag.children) : [];
+ this.vars = oldTag ? copyArray(oldTag.vars) : [];
+
+ var attrs = args.length ? args[0] : null;
+ var hasAttrs = typeof(attrs) == "object" && !isTag(attrs);
+
+ this.children = [];
+
+ if (domplate.topContext)
+ this.context = domplate.topContext;
+
+ if (args.length)
+ parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children);
+
+ if (hasAttrs)
+ this.parseAttrs(attrs);
+
+ return creator(this, DomplateTag);
+ },
+
+ parseAttrs: function(args)
+ {
+ for (var name in args)
+ {
+ var val = parseValue(args[name]);
+ readPartNames(val, this.vars);
+
+ if (name.indexOf("on") == 0)
+ {
+ var eventName = name.substr(2);
+ if (!this.listeners)
+ this.listeners = [];
+ this.listeners.push(eventName, val);
+ }
+ else if (name.indexOf("_") == 0)
+ {
+ var propName = name.substr(1);
+ if (!this.props)
+ this.props = {};
+ this.props[propName] = val;
+ }
+ else if (name.indexOf("$") == 0)
+ {
+ var className = name.substr(1);
+ if (!this.classes)
+ this.classes = {};
+ this.classes[className] = val;
+ }
+ else
+ {
+ if (name == "class" && this.attrs.hasOwnProperty(name) )
+ this.attrs[name] += " " + val;
+ else
+ this.attrs[name] = val;
+ }
+ }
+ },
+
+ compile: function()
+ {
+ if (this.renderMarkup)
+ return;
+
+ this.compileMarkup();
+ this.compileDOM();
+
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup);
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM);
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs);
+ },
+
+ compileMarkup: function()
+ {
+ this.markupArgs = [];
+ var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0};
+
+ this.generateMarkup(topBlock, topOuts, blocks, info);
+ this.addCode(topBlock, topOuts, blocks);
+
+ var fnBlock = ['r=(function (__code__, __context__, __in__, __out__'];
+ for (var i = 0; i < info.argIndex; ++i)
+ fnBlock.push(', s', i);
+ fnBlock.push(') {');
+
+ if (this.subject)
+ fnBlock.push('with (this) {');
+ if (this.context)
+ fnBlock.push('with (__context__) {');
+ fnBlock.push('with (__in__) {');
+
+ fnBlock.push.apply(fnBlock, blocks);
+
+ if (this.subject)
+ fnBlock.push('}');
+ if (this.context)
+ fnBlock.push('}');
+
+ fnBlock.push('}})');
+
+ function __link__(tag, code, outputs, args)
+ {
+ if (!tag || !tag.tag)
+ return;
+
+ tag.tag.compile();
+
+ var tagOutputs = [];
+ var markupArgs = [code, tag.tag.context, args, tagOutputs];
+ markupArgs.push.apply(markupArgs, tag.tag.markupArgs);
+ tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs);
+
+ outputs.push(tag);
+ outputs.push(tagOutputs);
+ }
+
+ function __escape__(value)
+ {
+ function replaceChars(ch)
+ {
+ switch (ch)
+ {
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case "&":
+ return "&";
+ case "'":
+ return "'";
+ case '"':
+ return """;
+ }
+ return "?";
+ };
+ return String(value).replace(/[<>&"']/g, replaceChars);
+ }
+
+ function __loop__(iter, outputs, fn)
+ {
+ var iterOuts = [];
+ outputs.push(iterOuts);
+
+ if (iter instanceof Array)
+ iter = new ArrayIterator(iter);
+
+ try
+ {
+ while (1)
+ {
+ var value = iter.next();
+ var itemOuts = [0,0];
+ iterOuts.push(itemOuts);
+ fn.apply(this, [value, itemOuts]);
+ }
+ }
+ catch (exc)
+ {
+ if (exc != StopIteration)
+ throw exc;
+ }
+ }
+
+ var js = fnBlock.join("");
+ var r = null;
+ eval(js);
+ this.renderMarkup = r;
+ },
+
+ getVarNames: function(args)
+ {
+ if (this.vars)
+ args.push.apply(args, this.vars);
+
+ for (var i = 0; i < this.children.length; ++i)
+ {
+ var child = this.children[i];
+ if (isTag(child))
+ child.tag.getVarNames(args);
+ else if (child instanceof Parts)
+ {
+ for (var i = 0; i < child.parts.length; ++i)
+ {
+ if (child.parts[i] instanceof Variable)
+ {
+ var name = child.parts[i].name;
+ var names = name.split(".");
+ args.push(names[0]);
+ }
+ }
+ }
+ }
+ },
+
+ generateMarkup: function(topBlock, topOuts, blocks, info)
+ {
+ topBlock.push(',"<', this.tagName, '"');
+
+ for (var name in this.attrs)
+ {
+ if (name != "class")
+ {
+ var val = this.attrs[name];
+ topBlock.push(', " ', name, '=\\""');
+ addParts(val, ',', topBlock, info, true);
+ topBlock.push(', "\\""');
+ }
+ }
+
+ if (this.listeners)
+ {
+ for (var i = 0; i < this.listeners.length; i += 2)
+ readPartNames(this.listeners[i+1], topOuts);
+ }
+
+ if (this.props)
+ {
+ for (var name in this.props)
+ readPartNames(this.props[name], topOuts);
+ }
+
+ if ( this.attrs.hasOwnProperty("class") || this.classes)
+ {
+ topBlock.push(', " class=\\""');
+ if (this.attrs.hasOwnProperty("class"))
+ addParts(this.attrs["class"], ',', topBlock, info, true);
+ topBlock.push(', " "');
+ for (var name in this.classes)
+ {
+ topBlock.push(', (');
+ addParts(this.classes[name], '', topBlock, info);
+ topBlock.push(' ? "', name, '" + " " : "")');
+ }
+ topBlock.push(', "\\""');
+ }
+ topBlock.push(',">"');
+
+ this.generateChildMarkup(topBlock, topOuts, blocks, info);
+ topBlock.push(',"', this.tagName, '>"');
+ },
+
+ generateChildMarkup: function(topBlock, topOuts, blocks, info)
+ {
+ for (var i = 0; i < this.children.length; ++i)
+ {
+ var child = this.children[i];
+ if (isTag(child))
+ child.tag.generateMarkup(topBlock, topOuts, blocks, info);
+ else
+ addParts(child, ',', topBlock, info, true);
+ }
+ },
+
+ addCode: function(topBlock, topOuts, blocks)
+ {
+ if (topBlock.length)
+ blocks.push('__code__.push(""', topBlock.join(""), ');');
+ if (topOuts.length)
+ blocks.push('__out__.push(', topOuts.join(","), ');');
+ topBlock.splice(0, topBlock.length);
+ topOuts.splice(0, topOuts.length);
+ },
+
+ addLocals: function(blocks)
+ {
+ var varNames = [];
+ this.getVarNames(varNames);
+
+ var map = {};
+ for (var i = 0; i < varNames.length; ++i)
+ {
+ var name = varNames[i];
+ if ( map.hasOwnProperty(name) )
+ continue;
+
+ map[name] = 1;
+ var names = name.split(".");
+ blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';');
+ }
+ },
+
+ compileDOM: function()
+ {
+ var path = [];
+ var blocks = [];
+ this.domArgs = [];
+ path.embedIndex = 0;
+ path.loopIndex = 0;
+ path.staticIndex = 0;
+ path.renderIndex = 0;
+ var nodeCount = this.generateDOM(path, blocks, this.domArgs);
+
+ var fnBlock = ['r=(function (root, context, o'];
+
+ for (var i = 0; i < path.staticIndex; ++i)
+ fnBlock.push(', ', 's'+i);
+
+ for (var i = 0; i < path.renderIndex; ++i)
+ fnBlock.push(', ', 'd'+i);
+
+ fnBlock.push(') {');
+ for (var i = 0; i < path.loopIndex; ++i)
+ fnBlock.push('var l', i, ' = 0;');
+ for (var i = 0; i < path.embedIndex; ++i)
+ fnBlock.push('var e', i, ' = 0;');
+
+ if (this.subject)
+ fnBlock.push('with (this) {');
+ if (this.context)
+ fnBlock.push('with (context) {');
+
+ fnBlock.push(blocks.join(""));
+
+ if (this.subject)
+ fnBlock.push('}');
+ if (this.context)
+ fnBlock.push('}');
+
+ fnBlock.push('return ', nodeCount, ';');
+ fnBlock.push('})');
+
+ function __bind__(object, fn)
+ {
+ return function(event) { return fn.apply(object, [event]); };
+ }
+
+ function __link__(node, tag, args)
+ {
+ if (!tag || !tag.tag)
+ return;
+
+ tag.tag.compile();
+
+ var domArgs = [node, tag.tag.context, 0];
+ domArgs.push.apply(domArgs, tag.tag.domArgs);
+ domArgs.push.apply(domArgs, args);
+ //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs);
+ return tag.tag.renderDOM.apply(tag.tag.subject, domArgs);
+ }
+
+ var self = this;
+ function __loop__(iter, fn)
+ {
+ var nodeCount = 0;
+ for (var i = 0; i < iter.length; ++i)
+ {
+ iter[i][0] = i;
+ iter[i][1] = nodeCount;
+ nodeCount += fn.apply(this, iter[i]);
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount);
+ }
+ return nodeCount;
+ }
+
+ function __path__(parent, offset)
+ {
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n");
+ var root = parent;
+
+ for (var i = 2; i < arguments.length; ++i)
+ {
+ var index = arguments[i];
+ if (i == 3)
+ index += offset;
+
+ if (index == -1)
+ parent = parent.parentNode;
+ else
+ parent = parent.childNodes[index];
+ }
+
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n");
+ return parent;
+ }
+
+ var js = fnBlock.join("");
+ //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n"));
+ var r = null;
+ eval(js);
+ this.renderDOM = r;
+ },
+
+ generateDOM: function(path, blocks, args)
+ {
+ if (this.listeners || this.props)
+ this.generateNodePath(path, blocks);
+
+ if (this.listeners)
+ {
+ for (var i = 0; i < this.listeners.length; i += 2)
+ {
+ var val = this.listeners[i+1];
+ var arg = generateArg(val, path, args);
+ //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);');
+ blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);');
+ }
+ }
+
+ if (this.props)
+ {
+ for (var name in this.props)
+ {
+ var val = this.props[name];
+ var arg = generateArg(val, path, args);
+ blocks.push('node.', name, ' = ', arg, ';');
+ }
+ }
+
+ this.generateChildDOM(path, blocks, args);
+ return 1;
+ },
+
+ generateNodePath: function(path, blocks)
+ {
+ blocks.push("var node = __path__(root, o");
+ for (var i = 0; i < path.length; ++i)
+ blocks.push(",", path[i]);
+ blocks.push(");");
+ },
+
+ generateChildDOM: function(path, blocks, args)
+ {
+ path.push(0);
+ for (var i = 0; i < this.children.length; ++i)
+ {
+ var child = this.children[i];
+ if (isTag(child))
+ path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args);
+ else
+ path[path.length-1] += '+1';
+ }
+ path.pop();
+ }
+ };
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ FBL.DomplateEmbed.prototype = copyObject(FBL.DomplateTag.prototype,
+ /** @lends FBL.DomplateEmbed.prototype */
+ {
+ merge: function(args, oldTag)
+ {
+ this.value = oldTag ? oldTag.value : parseValue(args[0]);
+ this.attrs = oldTag ? oldTag.attrs : {};
+ this.vars = oldTag ? copyArray(oldTag.vars) : [];
+
+ var attrs = args[1];
+ for (var name in attrs)
+ {
+ var val = parseValue(attrs[name]);
+ this.attrs[name] = val;
+ readPartNames(val, this.vars);
+ }
+
+ return creator(this, DomplateEmbed);
+ },
+
+ getVarNames: function(names)
+ {
+ if (this.value instanceof Parts)
+ names.push(this.value.parts[0].name);
+
+ if (this.vars)
+ names.push.apply(names, this.vars);
+ },
+
+ generateMarkup: function(topBlock, topOuts, blocks, info)
+ {
+ this.addCode(topBlock, topOuts, blocks);
+
+ blocks.push('__link__(');
+ addParts(this.value, '', blocks, info);
+ blocks.push(', __code__, __out__, {');
+
+ var lastName = null;
+ for (var name in this.attrs)
+ {
+ if (lastName)
+ blocks.push(',');
+ lastName = name;
+
+ var val = this.attrs[name];
+ blocks.push('"', name, '":');
+ addParts(val, '', blocks, info);
+ }
+
+ blocks.push('});');
+ //this.generateChildMarkup(topBlock, topOuts, blocks, info);
+ },
+
+ generateDOM: function(path, blocks, args)
+ {
+ var embedName = 'e'+path.embedIndex++;
+
+ this.generateNodePath(path, blocks);
+
+ var valueName = 'd' + path.renderIndex++;
+ var argsName = 'd' + path.renderIndex++;
+ blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');');
+
+ return embedName;
+ }
+ });
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ FBL.DomplateLoop.prototype = copyObject(FBL.DomplateTag.prototype,
+ /** @lends FBL.DomplateLoop.prototype */
+ {
+ merge: function(args, oldTag)
+ {
+ this.varName = oldTag ? oldTag.varName : args[0];
+ this.iter = oldTag ? oldTag.iter : parseValue(args[1]);
+ this.vars = [];
+
+ this.children = oldTag ? copyArray(oldTag.children) : [];
+
+ var offset = Math.min(args.length, 2);
+ parseChildren(args, offset, this.vars, this.children);
+
+ return creator(this, DomplateLoop);
+ },
+
+ getVarNames: function(names)
+ {
+ if (this.iter instanceof Parts)
+ names.push(this.iter.parts[0].name);
+
+ DomplateTag.prototype.getVarNames.apply(this, [names]);
+ },
+
+ generateMarkup: function(topBlock, topOuts, blocks, info)
+ {
+ this.addCode(topBlock, topOuts, blocks);
+
+ var iterName;
+ if (this.iter instanceof Parts)
+ {
+ var part = this.iter.parts[0];
+ iterName = part.name;
+
+ if (part.format)
+ {
+ for (var i = 0; i < part.format.length; ++i)
+ iterName = part.format[i] + "(" + iterName + ")";
+ }
+ }
+ else
+ iterName = this.iter;
+
+ blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {');
+ this.generateChildMarkup(topBlock, topOuts, blocks, info);
+ this.addCode(topBlock, topOuts, blocks);
+ blocks.push('}]);');
+ },
+
+ generateDOM: function(path, blocks, args)
+ {
+ var iterName = 'd'+path.renderIndex++;
+ var counterName = 'i'+path.loopIndex;
+ var loopName = 'l'+path.loopIndex++;
+
+ if (!path.length)
+ path.push(-1, 0);
+
+ var preIndex = path.renderIndex;
+ path.renderIndex = 0;
+
+ var nodeCount = 0;
+
+ var subBlocks = [];
+ var basePath = path[path.length-1];
+ for (var i = 0; i < this.children.length; ++i)
+ {
+ path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount;
+
+ var child = this.children[i];
+ if (isTag(child))
+ nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args);
+ else
+ nodeCount += '+1';
+ }
+
+ path[path.length-1] = basePath+'+'+loopName;
+
+ blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName);
+ for (var i = 0; i < path.renderIndex; ++i)
+ blocks.push(',d'+i);
+ blocks.push(') {');
+ blocks.push(subBlocks.join(""));
+ blocks.push('return ', nodeCount, ';');
+ blocks.push('}]);');
+
+ path.renderIndex = preIndex;
+
+ return loopName;
+ }
+ });
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ /** @class */
+ function Variable(name, format)
+ {
+ this.name = name;
+ this.format = format;
+ }
+
+ /** @class */
+ function Parts(parts)
+ {
+ this.parts = parts;
+ }
+
+ // ************************************************************************************************
+
+ function parseParts(str)
+ {
+ var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g;
+ var index = 0;
+ var parts = [];
+
+ var m;
+ while (m = re.exec(str))
+ {
+ var pre = str.substr(index, (re.lastIndex-m[0].length)-index);
+ if (pre)
+ parts.push(pre);
+
+ var expr = m[1].split("|");
+ parts.push(new Variable(expr[0], expr.slice(1)));
+ index = re.lastIndex;
+ }
+
+ if (!index)
+ return str;
+
+ var post = str.substr(index);
+ if (post)
+ parts.push(post);
+
+ return new Parts(parts);
+ }
+
+ function parseValue(val)
+ {
+ return typeof(val) == 'string' ? parseParts(val) : val;
+ }
+
+ function parseChildren(args, offset, vars, children)
+ {
+ for (var i = offset; i < args.length; ++i)
+ {
+ var val = parseValue(args[i]);
+ children.push(val);
+ readPartNames(val, vars);
+ }
+ }
+
+ function readPartNames(val, vars)
+ {
+ if (val instanceof Parts)
+ {
+ for (var i = 0; i < val.parts.length; ++i)
+ {
+ var part = val.parts[i];
+ if (part instanceof Variable)
+ vars.push(part.name);
+ }
+ }
+ }
+
+ function generateArg(val, path, args)
+ {
+ if (val instanceof Parts)
+ {
+ var vals = [];
+ for (var i = 0; i < val.parts.length; ++i)
+ {
+ var part = val.parts[i];
+ if (part instanceof Variable)
+ {
+ var varName = 'd'+path.renderIndex++;
+ if (part.format)
+ {
+ for (var j = 0; j < part.format.length; ++j)
+ varName = part.format[j] + '(' + varName + ')';
+ }
+
+ vals.push(varName);
+ }
+ else
+ vals.push('"'+part.replace(/"/g, '\\"')+'"');
+ }
+
+ return vals.join('+');
+ }
+ else
+ {
+ args.push(val);
+ return 's' + path.staticIndex++;
+ }
+ }
+
+ function addParts(val, delim, block, info, escapeIt)
+ {
+ var vals = [];
+ if (val instanceof Parts)
+ {
+ for (var i = 0; i < val.parts.length; ++i)
+ {
+ var part = val.parts[i];
+ if (part instanceof Variable)
+ {
+ var partName = part.name;
+ if (part.format)
+ {
+ for (var j = 0; j < part.format.length; ++j)
+ partName = part.format[j] + "(" + partName + ")";
+ }
+
+ if (escapeIt)
+ vals.push("__escape__(" + partName + ")");
+ else
+ vals.push(partName);
+ }
+ else
+ vals.push('"'+ part + '"');
+ }
+ }
+ else if (isTag(val))
+ {
+ info.args.push(val);
+ vals.push('s'+info.argIndex++);
+ }
+ else
+ vals.push('"'+ val + '"');
+
+ var parts = vals.join(delim);
+ if (parts)
+ block.push(delim, parts);
+ }
+
+ function isTag(obj)
+ {
+ return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag;
+ }
+
+ function creator(tag, cons)
+ {
+ var fn = new Function(
+ "var tag = arguments.callee.tag;" +
+ "var cons = arguments.callee.cons;" +
+ "var newTag = new cons();" +
+ "return newTag.merge(arguments, tag);");
+
+ fn.tag = tag;
+ fn.cons = cons;
+ extend(fn, Renderer);
+
+ return fn;
+ }
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ function copyArray(oldArray)
+ {
+ var ary = [];
+ if (oldArray)
+ for (var i = 0; i < oldArray.length; ++i)
+ ary.push(oldArray[i]);
+ return ary;
+ }
+
+ function copyObject(l, r)
+ {
+ var m = {};
+ extend(m, l);
+ extend(m, r);
+ return m;
+ }
+
+ function extend(l, r)
+ {
+ for (var n in r)
+ l[n] = r[n];
+ }
+
+ function addEvent(object, name, handler)
+ {
+ if (document.all)
+ object.attachEvent("on"+name, handler);
+ else
+ object.addEventListener(name, handler, false);
+ }
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ /** @class */
+ function ArrayIterator(array)
+ {
+ var index = -1;
+
+ this.next = function()
+ {
+ if (++index >= array.length)
+ throw StopIteration;
+
+ return array[index];
+ };
+ }
+
+ /** @class */
+ function StopIteration() {}
+
+ FBL.$break = function()
+ {
+ throw StopIteration;
+ };
+
+ // ************************************************************************************************
+
+ /** @namespace */
+ var Renderer =
+ {
+ renderHTML: function(args, outputs, self)
+ {
+ var code = [];
+ var markupArgs = [code, this.tag.context, args, outputs];
+ markupArgs.push.apply(markupArgs, this.tag.markupArgs);
+ this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs);
+ return code.join("");
+ },
+
+ insertRows: function(args, before, self)
+ {
+ this.tag.compile();
+
+ var outputs = [];
+ var html = this.renderHTML(args, outputs, self);
+
+ var doc = before.ownerDocument;
+ var div = doc.createElement("div");
+ div.innerHTML = "";
+
+ var tbody = div.firstChild.firstChild;
+ var parent = before.tagName == "TR" ? before.parentNode : before;
+ var after = before.tagName == "TR" ? before.nextSibling : null;
+
+ var firstRow = tbody.firstChild, lastRow;
+ while (tbody.firstChild)
+ {
+ lastRow = tbody.firstChild;
+ if (after)
+ parent.insertBefore(lastRow, after);
+ else
+ parent.appendChild(lastRow);
+ }
+
+ var offset = 0;
+ if (before.tagName == "TR")
+ {
+ var node = firstRow.parentNode.firstChild;
+ for (; node && node != firstRow; node = node.nextSibling)
+ ++offset;
+ }
+
+ var domArgs = [firstRow, this.tag.context, offset];
+ domArgs.push.apply(domArgs, this.tag.domArgs);
+ domArgs.push.apply(domArgs, outputs);
+
+ this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+ return [firstRow, lastRow];
+ },
+
+ insertBefore: function(args, before, self)
+ {
+ return this.insertNode(args, before.ownerDocument, before, false, self);
+ },
+
+ insertAfter: function(args, after, self)
+ {
+ return this.insertNode(args, after.ownerDocument, after, true, self);
+ },
+
+ insertNode: function(args, doc, element, isAfter, self)
+ {
+ if (!args)
+ args = {};
+
+ this.tag.compile();
+
+ var outputs = [];
+ var html = this.renderHTML(args, outputs, self);
+
+ //if (FBTrace.DBG_DOM)
+ // FBTrace.sysout("domplate.insertNode html: "+html+"\n");
+
+ var doc = element.ownerDocument;
+ if (!womb || womb.ownerDocument != doc)
+ womb = doc.createElement("div");
+
+ womb.innerHTML = html;
+
+ var root = womb.firstChild;
+ if (isAfter)
+ {
+ while (womb.firstChild)
+ if (element.nextSibling)
+ element.parentNode.insertBefore(womb.firstChild, element.nextSibling);
+ else
+ element.parentNode.appendChild(womb.firstChild);
+ }
+ else
+ {
+ while (womb.lastChild)
+ element.parentNode.insertBefore(womb.lastChild, element);
+ }
+
+ var domArgs = [root, this.tag.context, 0];
+ domArgs.push.apply(domArgs, this.tag.domArgs);
+ domArgs.push.apply(domArgs, outputs);
+
+ //if (FBTrace.DBG_DOM)
+ // FBTrace.sysout("domplate.insertNode domArgs:", domArgs);
+ this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+
+ return root;
+ },
+ /**/
+
+ /*
+ insertAfter: function(args, before, self)
+ {
+ this.tag.compile();
+
+ var outputs = [];
+ var html = this.renderHTML(args, outputs, self);
+
+ var doc = before.ownerDocument;
+ if (!womb || womb.ownerDocument != doc)
+ womb = doc.createElement("div");
+
+ womb.innerHTML = html;
+
+ var root = womb.firstChild;
+ while (womb.firstChild)
+ if (before.nextSibling)
+ before.parentNode.insertBefore(womb.firstChild, before.nextSibling);
+ else
+ before.parentNode.appendChild(womb.firstChild);
+
+ var domArgs = [root, this.tag.context, 0];
+ domArgs.push.apply(domArgs, this.tag.domArgs);
+ domArgs.push.apply(domArgs, outputs);
+
+ this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null),
+ domArgs);
+
+ return root;
+ },
+ /**/
+
+ replace: function(args, parent, self)
+ {
+ this.tag.compile();
+
+ var outputs = [];
+ var html = this.renderHTML(args, outputs, self);
+
+ var root;
+ if (parent.nodeType == 1)
+ {
+ parent.innerHTML = html;
+ root = parent.firstChild;
+ }
+ else
+ {
+ if (!parent || parent.nodeType != 9)
+ parent = document;
+
+ if (!womb || womb.ownerDocument != parent)
+ womb = parent.createElement("div");
+ womb.innerHTML = html;
+
+ root = womb.firstChild;
+ //womb.removeChild(root);
+ }
+
+ var domArgs = [root, this.tag.context, 0];
+ domArgs.push.apply(domArgs, this.tag.domArgs);
+ domArgs.push.apply(domArgs, outputs);
+ this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+
+ return root;
+ },
+
+ append: function(args, parent, self)
+ {
+ this.tag.compile();
+
+ var outputs = [];
+ var html = this.renderHTML(args, outputs, self);
+ //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n");
+
+ if (!womb || womb.ownerDocument != parent.ownerDocument)
+ womb = parent.ownerDocument.createElement("div");
+ womb.innerHTML = html;
+
+ // TODO: xxxpedro domplate port to Firebug
+ var root = womb.firstChild;
+ while (womb.firstChild)
+ parent.appendChild(womb.firstChild);
+
+ // clearing element reference to avoid reference error in IE8 when switching contexts
+ womb = null;
+
+ var domArgs = [root, this.tag.context, 0];
+ domArgs.push.apply(domArgs, this.tag.domArgs);
+ domArgs.push.apply(domArgs, outputs);
+
+ //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs);
+ this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+
+ return root;
+ }
+ };
+
+ // ************************************************************************************************
+
+ function defineTags()
+ {
+ for (var i = 0; i < arguments.length; ++i)
+ {
+ var tagName = arguments[i];
+ var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);");
+ fn.DomplateTag = DomplateTag;
+
+ var fnName = tagName.toUpperCase();
+ FBL[fnName] = fn;
+ }
+ }
+
+ defineTags(
+ "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr",
+ "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select",
+ "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe"
+ );
+
+ })();
+
+
+ /* See license.txt for terms of usage */
+
+ var FirebugReps = FBL.ns(function() { with (FBL) {
+
+
+ // ************************************************************************************************
+ // Common Tags
+
+ var OBJECTBOX = this.OBJECTBOX =
+ SPAN({"class": "objectBox objectBox-$className"});
+
+ var OBJECTBLOCK = this.OBJECTBLOCK =
+ DIV({"class": "objectBox objectBox-$className"});
+
+ var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation
+ A({
+ "class": "objectLink objectLink-$className a11yFocus",
+ href: "javascript:void(0)",
+ // workaround to show XPath (a better approach would use the tooltip on mouseover,
+ // so the XPath information would be calculated dynamically, but we need to create
+ // a tooltip class/wrapper around Menu or InfoTip)
+ title: "$object|FBL.getElementXPath",
+ _repObject: "$object"
+ })
+ : // Other browsers
+ A({
+ "class": "objectLink objectLink-$className a11yFocus",
+ // workaround to show XPath (a better approach would use the tooltip on mouseover,
+ // so the XPath information would be calculated dynamically, but we need to create
+ // a tooltip class/wrapper around Menu or InfoTip)
+ title: "$object|FBL.getElementXPath",
+ _repObject: "$object"
+ });
+
+
+ // ************************************************************************************************
+
+ this.Undefined = domplate(Firebug.Rep,
+ {
+ tag: OBJECTBOX("undefined"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "undefined",
+
+ supportsObject: function(object, type)
+ {
+ return type == "undefined";
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.Null = domplate(Firebug.Rep,
+ {
+ tag: OBJECTBOX("null"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "null",
+
+ supportsObject: function(object, type)
+ {
+ return object == null;
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.Nada = domplate(Firebug.Rep,
+ {
+ tag: SPAN(""),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "nada"
+ });
+
+ // ************************************************************************************************
+
+ this.Number = domplate(Firebug.Rep,
+ {
+ tag: OBJECTBOX("$object"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "number",
+
+ supportsObject: function(object, type)
+ {
+ return type == "boolean" || type == "number";
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.String = domplate(Firebug.Rep,
+ {
+ tag: OBJECTBOX(""$object""),
+
+ shortTag: OBJECTBOX(""$object|cropString""),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "string",
+
+ supportsObject: function(object, type)
+ {
+ return type == "string";
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.Text = domplate(Firebug.Rep,
+ {
+ tag: OBJECTBOX("$object"),
+
+ shortTag: OBJECTBOX("$object|cropString"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "text"
+ });
+
+ // ************************************************************************************************
+
+ this.Caption = domplate(Firebug.Rep,
+ {
+ tag: SPAN({"class": "caption"}, "$object")
+ });
+
+ // ************************************************************************************************
+
+ this.Warning = domplate(Firebug.Rep,
+ {
+ tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR")
+ });
+
+ // ************************************************************************************************
+
+ this.Func = domplate(Firebug.Rep,
+ {
+ tag:
+ OBJECTLINK("$object|summarizeFunction"),
+
+ summarizeFunction: function(fn)
+ {
+ var fnRegex = /function ([^(]+\([^)]*\)) \{/;
+ var fnText = safeToString(fn);
+
+ var m = fnRegex.exec(fnText);
+ return m ? m[1] : "function()";
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ copySource: function(fn)
+ {
+ copyToClipboard(safeToString(fn));
+ },
+
+ monitor: function(fn, script, monitored)
+ {
+ if (monitored)
+ Firebug.Debugger.unmonitorScript(fn, script, "monitor");
+ else
+ Firebug.Debugger.monitorScript(fn, script, "monitor");
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "function",
+
+ supportsObject: function(object, type)
+ {
+ return isFunction(object);
+ },
+
+ inspectObject: function(fn, context)
+ {
+ var sourceLink = findSourceForFunction(fn, context);
+ if (sourceLink)
+ Firebug.chrome.select(sourceLink);
+ if (FBTrace.DBG_FUNCTION_NAME)
+ FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink);
+ },
+
+ getTooltip: function(fn, context)
+ {
+ var script = findScriptForFunctionInContext(context, fn);
+ if (script)
+ return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]);
+ else
+ if (fn.toString)
+ return fn.toString();
+ },
+
+ getTitle: function(fn, context)
+ {
+ var name = fn.name ? fn.name : "function";
+ return name + "()";
+ },
+
+ getContextMenuItems: function(fn, target, context, script)
+ {
+ if (!script)
+ script = findScriptForFunctionInContext(context, fn);
+ if (!script)
+ return;
+
+ var scriptInfo = getSourceFileAndLineByScript(context, script);
+ var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
+
+ var name = script ? getFunctionName(script, context) : fn.name;
+ return [
+ {label: "CopySource", command: bindFixed(this.copySource, this, fn) },
+ "-",
+ {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
+ type: "checkbox", checked: monitored,
+ command: bindFixed(this.monitor, this, fn, script, monitored) }
+ ];
+ }
+ });
+
+ // ************************************************************************************************
+ /*
+ this.jsdScript = domplate(Firebug.Rep,
+ {
+ copySource: function(script)
+ {
+ var fn = script.functionObject.getWrappedValue();
+ return FirebugReps.Func.copySource(fn);
+ },
+
+ monitor: function(fn, script, monitored)
+ {
+ fn = script.functionObject.getWrappedValue();
+ return FirebugReps.Func.monitor(fn, script, monitored);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "jsdScript",
+ inspectable: false,
+
+ supportsObject: function(object, type)
+ {
+ return object instanceof jsdIScript;
+ },
+
+ inspectObject: function(script, context)
+ {
+ var sourceLink = getSourceLinkForScript(script, context);
+ if (sourceLink)
+ Firebug.chrome.select(sourceLink);
+ },
+
+ getRealObject: function(script, context)
+ {
+ return script;
+ },
+
+ getTooltip: function(script)
+ {
+ return $STRF("jsdIScript", [script.tag]);
+ },
+
+ getTitle: function(script, context)
+ {
+ var fn = script.functionObject.getWrappedValue();
+ return FirebugReps.Func.getTitle(fn, context);
+ },
+
+ getContextMenuItems: function(script, target, context)
+ {
+ var fn = script.functionObject.getWrappedValue();
+
+ var scriptInfo = getSourceFileAndLineByScript(context, script);
+ var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
+
+ var name = getFunctionName(script, context);
+
+ return [
+ {label: "CopySource", command: bindFixed(this.copySource, this, script) },
+ "-",
+ {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
+ type: "checkbox", checked: monitored,
+ command: bindFixed(this.monitor, this, fn, script, monitored) }
+ ];
+ }
+ });
+ /**/
+ //************************************************************************************************
+
+ this.Obj = domplate(Firebug.Rep,
+ {
+ tag:
+ OBJECTLINK(
+ SPAN({"class": "objectTitle"}, "$object|getTitle "),
+
+ SPAN({"class": "objectProps"},
+ SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"),
+ FOR("prop", "$object|propIterator",
+ SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"),
+ SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"),
+ TAG("$prop.tag", {object: "$prop.object"}),
+ SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim")
+ ),
+ SPAN({"class": "objectRightBrace"}, "}")
+ )
+ ),
+
+ propNumberTag:
+ SPAN({"class": "objectProp-number"}, "$object"),
+
+ propStringTag:
+ SPAN({"class": "objectProp-string"}, ""$object""),
+
+ propObjectTag:
+ SPAN({"class": "objectProp-object"}, "$object"),
+
+ propIterator: function (object)
+ {
+ ///Firebug.ObjectShortIteratorMax;
+ var maxLength = 55; // default max length for long representation
+
+ if (!object)
+ return [];
+
+ var props = [];
+ var length = 0;
+
+ var numProperties = 0;
+ var numPropertiesShown = 0;
+ var maxLengthReached = false;
+
+ var lib = this;
+
+ var propRepsMap =
+ {
+ "boolean": this.propNumberTag,
+ "number": this.propNumberTag,
+ "string": this.propStringTag,
+ "object": this.propObjectTag
+ };
+
+ try
+ {
+ var title = Firebug.Rep.getTitle(object);
+ length += title.length;
+
+ for (var name in object)
+ {
+ var value;
+ try
+ {
+ value = object[name];
+ }
+ catch (exc)
+ {
+ continue;
+ }
+
+ var type = typeof(value);
+ if (type == "boolean" ||
+ type == "number" ||
+ (type == "string" && value) ||
+ (type == "object" && value && value.toString))
+ {
+ var tag = propRepsMap[type];
+
+ var value = (type == "object") ?
+ Firebug.getRep(value).getTitle(value) :
+ value + "";
+
+ length += name.length + value.length + 4;
+
+ if (length <= maxLength)
+ {
+ props.push({
+ tag: tag,
+ name: name,
+ object: value,
+ equal: "=",
+ delim: ", "
+ });
+
+ numPropertiesShown++;
+ }
+ else
+ maxLengthReached = true;
+
+ }
+
+ numProperties++;
+
+ if (maxLengthReached && numProperties > numPropertiesShown)
+ break;
+ }
+
+ if (numProperties > numPropertiesShown)
+ {
+ props.push({
+ object: "...", //xxxHonza localization
+ tag: FirebugReps.Caption.tag,
+ name: "",
+ equal:"",
+ delim:""
+ });
+ }
+ else if (props.length > 0)
+ {
+ props[props.length-1].delim = '';
+ }
+ }
+ catch (exc)
+ {
+ // Sometimes we get exceptions when trying to read from certain objects, like
+ // StorageList, but don't let that gum up the works
+ // XXXjjb also History.previous fails because object is a web-page object which does not have
+ // permission to read the history
+ }
+ return props;
+ },
+
+ fb_1_6_propIterator: function (object, max)
+ {
+ max = max || 3;
+ if (!object)
+ return [];
+
+ var props = [];
+ var len = 0, count = 0;
+
+ try
+ {
+ for (var name in object)
+ {
+ var value;
+ try
+ {
+ value = object[name];
+ }
+ catch (exc)
+ {
+ continue;
+ }
+
+ var t = typeof(value);
+ if (t == "boolean" || t == "number" || (t == "string" && value)
+ || (t == "object" && value && value.toString))
+ {
+ var rep = Firebug.getRep(value);
+ var tag = rep.shortTag || rep.tag;
+ if (t == "object")
+ {
+ value = rep.getTitle(value);
+ tag = rep.titleTag;
+ }
+ count++;
+ if (count <= max)
+ props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "});
+ else
+ break;
+ }
+ }
+ if (count > max)
+ {
+ props[Math.max(1,max-1)] = {
+ object: "more...", //xxxHonza localization
+ tag: FirebugReps.Caption.tag,
+ name: "",
+ equal:"",
+ delim:""
+ };
+ }
+ else if (props.length > 0)
+ {
+ props[props.length-1].delim = '';
+ }
+ }
+ catch (exc)
+ {
+ // Sometimes we get exceptions when trying to read from certain objects, like
+ // StorageList, but don't let that gum up the works
+ // XXXjjb also History.previous fails because object is a web-page object which does not have
+ // permission to read the history
+ }
+ return props;
+ },
+
+ /*
+ propIterator: function (object)
+ {
+ if (!object)
+ return [];
+
+ var props = [];
+ var len = 0;
+
+ try
+ {
+ for (var name in object)
+ {
+ var val;
+ try
+ {
+ val = object[name];
+ }
+ catch (exc)
+ {
+ continue;
+ }
+
+ var t = typeof val;
+ if (t == "boolean" || t == "number" || (t == "string" && val)
+ || (t == "object" && !isFunction(val) && val && val.toString))
+ {
+ var title = (t == "object")
+ ? Firebug.getRep(val).getTitle(val)
+ : val+"";
+
+ len += name.length + title.length + 1;
+ if (len < 50)
+ props.push({name: name, value: title});
+ else
+ break;
+ }
+ }
+ }
+ catch (exc)
+ {
+ // Sometimes we get exceptions when trying to read from certain objects, like
+ // StorageList, but don't let that gum up the works
+ // XXXjjb also History.previous fails because object is a web-page object which does not have
+ // permission to read the history
+ }
+
+ return props;
+ },
+ /**/
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "object",
+
+ supportsObject: function(object, type)
+ {
+ return true;
+ }
+ });
+
+
+ // ************************************************************************************************
+
+ this.Arr = domplate(Firebug.Rep,
+ {
+ tag:
+ OBJECTBOX({_repObject: "$object"},
+ SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
+ FOR("item", "$object|arrayIterator",
+ TAG("$item.tag", {object: "$item.object"}),
+ SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
+ ),
+ SPAN({"class": "arrayRightBracket", role : "presentation"}, "]")
+ ),
+
+ shortTag:
+ OBJECTBOX({_repObject: "$object"},
+ SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
+ FOR("item", "$object|shortArrayIterator",
+ TAG("$item.tag", {object: "$item.object"}),
+ SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
+ ),
+ // TODO: xxxpedro - confirm this on Firebug
+ //FOR("prop", "$object|shortPropIterator",
+ // " $prop.name=",
+ // SPAN({"class": "objectPropValue"}, "$prop.value|cropString")
+ //),
+ SPAN({"class": "arrayRightBracket"}, "]")
+ ),
+
+ arrayIterator: function(array)
+ {
+ var items = [];
+ for (var i = 0; i < array.length; ++i)
+ {
+ var value = array[i];
+ var rep = Firebug.getRep(value);
+ var tag = rep.shortTag ? rep.shortTag : rep.tag;
+ var delim = (i == array.length-1 ? "" : ", ");
+
+ items.push({object: value, tag: tag, delim: delim});
+ }
+
+ return items;
+ },
+
+ shortArrayIterator: function(array)
+ {
+ var items = [];
+ for (var i = 0; i < array.length && i < 3; ++i)
+ {
+ var value = array[i];
+ var rep = Firebug.getRep(value);
+ var tag = rep.shortTag ? rep.shortTag : rep.tag;
+ var delim = (i == array.length-1 ? "" : ", ");
+
+ items.push({object: value, tag: tag, delim: delim});
+ }
+
+ if (array.length > 3)
+ items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""});
+
+ return items;
+ },
+
+ shortPropIterator: this.Obj.propIterator,
+
+ getItemIndex: function(child)
+ {
+ var arrayIndex = 0;
+ for (child = child.previousSibling; child; child = child.previousSibling)
+ {
+ if (child.repObject)
+ ++arrayIndex;
+ }
+ return arrayIndex;
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "array",
+
+ supportsObject: function(object)
+ {
+ return this.isArray(object);
+ },
+
+ // http://code.google.com/p/fbug/issues/detail?id=874
+ // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007
+ isArray: function(obj) {
+ try {
+ if (!obj)
+ return false;
+ else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8)
+ return true;
+ else if (isFinite(obj.length) && isFunction(obj.splice))
+ return true;
+ else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments
+ return true;
+ else if (instanceOf(obj, "HTMLCollection"))
+ return true;
+ else if (instanceOf(obj, "NodeList"))
+ return true;
+ else
+ return false;
+ }
+ catch(exc)
+ {
+ if (FBTrace.DBG_ERRORS)
+ {
+ FBTrace.sysout("isArray FAILS:", exc); /* Something weird: without the try/catch, OOM, with no exception?? */
+ FBTrace.sysout("isArray Fails on obj", obj);
+ }
+ }
+
+ return false;
+ },
+ // END Yahoo BSD SOURCE See license below.
+
+ getTitle: function(object, context)
+ {
+ return "[" + object.length + "]";
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.Property = domplate(Firebug.Rep,
+ {
+ supportsObject: function(object)
+ {
+ return object instanceof Property;
+ },
+
+ getRealObject: function(prop, context)
+ {
+ return prop.object[prop.name];
+ },
+
+ getTitle: function(prop, context)
+ {
+ return prop.name;
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.NetFile = domplate(this.Obj,
+ {
+ supportsObject: function(object)
+ {
+ return object instanceof Firebug.NetFile;
+ },
+
+ browseObject: function(file, context)
+ {
+ openNewTab(file.href);
+ return true;
+ },
+
+ getRealObject: function(file, context)
+ {
+ return null;
+ }
+ });
+
+ // ************************************************************************************************
+
+ this.Except = domplate(Firebug.Rep,
+ {
+ tag:
+ OBJECTBOX({_repObject: "$object"}, "$object.message"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ className: "exception",
+
+ supportsObject: function(object)
+ {
+ return object instanceof ErrorCopy;
+ }
+ });
+
+
+ // ************************************************************************************************
+
+ this.Element = domplate(Firebug.Rep,
+ {
+ tag:
+ OBJECTLINK(
+ "<",
+ SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"),
+ FOR("attr", "$object|attrIterator",
+ " $attr.nodeName="", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), """
+ ),
+ ">"
+ ),
+
+ shortTag:
+ OBJECTLINK(
+ SPAN({"class": "$object|getVisible"},
+ SPAN({"class": "selectorTag"}, "$object|getSelectorTag"),
+ SPAN({"class": "selectorId"}, "$object|getSelectorId"),
+ SPAN({"class": "selectorClass"}, "$object|getSelectorClass"),
+ SPAN({"class": "selectorValue"}, "$object|getValue")
+ )
+ ),
+
+ getVisible: function(elt)
+ {
+ return isVisible(elt) ? "" : "selectorHidden";
+ },
+
+ getSelectorTag: function(elt)
+ {
+ return elt.nodeName.toLowerCase();
+ },
+
+ getSelectorId: function(elt)
+ {
+ return elt.id ? "#" + elt.id : "";
+ },
+
+ getSelectorClass: function(elt)
+ {
+ return elt.className ? "." + elt.className.split(" ")[0] : "";
+ },
+
+ getValue: function(elt)
+ {
+ // TODO: xxxpedro
+ return "";
+ var value;
+ if (elt instanceof HTMLImageElement)
+ value = getFileName(elt.src);
+ else if (elt instanceof HTMLAnchorElement)
+ value = getFileName(elt.href);
+ else if (elt instanceof HTMLInputElement)
+ value = elt.value;
+ else if (elt instanceof HTMLFormElement)
+ value = getFileName(elt.action);
+ else if (elt instanceof HTMLScriptElement)
+ value = getFileName(elt.src);
+
+ return value ? " " + cropString(value, 20) : "";
+ },
+
+ attrIterator: function(elt)
+ {
+ var attrs = [];
+ var idAttr, classAttr;
+ if (elt.attributes)
+ {
+ for (var i = 0; i < elt.attributes.length; ++i)
+ {
+ var attr = elt.attributes[i];
+
+ // we must check if the attribute is specified otherwise IE will show them
+ if (!attr.specified || attr.nodeName && attr.nodeName.indexOf("firebug-") != -1)
+ continue;
+ else if (attr.nodeName == "id")
+ idAttr = attr;
+ else if (attr.nodeName == "class")
+ classAttr = attr;
+ else if (attr.nodeName == "style")
+ attrs.push({
+ nodeName: attr.nodeName,
+ nodeValue: attr.nodeValue ||
+ // IE won't recognize the attr.nodeValue of